{"count":37,"calculators":[{"slug":"pace-calculator","math":{"href":"https://www.tracktoolspro.com/api/calculators/pace-calculator","jsonPointer":"/calculator/math","version":"2026-10-21.1","implementationVersion":"b5a8aca7b85361476e0321a08b7fa5f516fc9535","scope":"Canonical HTTP function and documented corresponding mounted-form math. This is public inspectable documentation, not access control or independent empirical validation.","unitNotation":"Input paths use [] and *; output paths are JSON Pointers with * (one segment) and ** (descendants). Empty output path denotes scalar result. Units apply to numeric quantities or explicitly described numeric strings; labels/statuses/booleans are dimensionless. More specific units, including count/index exceptions, override broad patterns.","interfaceNotes":["HTTP input is described by the adjacent inputSchema. The original handlers may accept numeric strings; this metadata adds no validation.","Mounted forms accept displayed clock/unit strings and enforce their own limits. Mounted tools limit strings to 200 characters and numeric parts to magnitude 1000000. Do not assume mounted/API input interchangeability.","Some legacy extreme/invalid tuples can produce null/empty results or nonfinite numbers serialized as null. Those are unavailable answers, not exact numerical predictions. Per-calculator domain describes the intended mathematical inputs."],"kind":"arithmetic","implementationFiles":["lib/formulas/pace.ts","lib/calc-utils.ts","components/calculators/inline/utils/constants.js"],"equations":["p = totalSeconds / distanceMeters (seconds per meter); paces.per400m = 400*p; paces.per1k = 1000*p; paces.perMile = 1609.34*p.","For each split distance x, cumulativeTime = p*x; splitTime = current cumulativeTime - preceding cumulativeTime. Preserve the exact finish distance, including a partial interval.","Mounted time/distance modes invert the same relation: finish = paceSeconds*distanceMeters/paceUnitMeters; distance = totalSeconds*paceUnitMeters/paceSeconds.","Mounted training heuristic: T10k = totalSeconds*(10000/distanceMeters)^1.06; zone mile pace = (zoneFactor/283)*(T10k/6.22) - (T10k-1760)/85."],"inputUnits":{"totalSeconds":"s","distanceMeters":"m","splitMeters":"m","includeSplits":"boolean"},"outputUnits":{"/paces/*":"s per stated distance","/splits/*/distance":"m","/splits/*/splitTime":"s","/splits/*/cumulativeTime":"s","/splits/*/remainderMeters":"m","/splits/*/index":"dimensionless index/count"},"domain":["Positive time/distance for paces; otherwise paces=null. Split interval must be positive; nonfinite or >10000 full intervals returns no split rows. includeSplits=false returns []."],"rounding":["Raw IEEE-754 numbers; the mounted page formats clocks separately."],"assumptions":["Uses the entered values and the selected convention; this documentation does not strengthen existing validation."],"limitations":["Constant speed, not a race forecast. Training-zone factors are unvalidated coaching heuristics, not prescribed intensities. The legacy 1609.34m mile convention is retained."],"mountedPageNotes":["Milestones merge within <5m of existing split rows and are sorted; HTTP defaults omit milestones. Pace-band display retains Finish beyond its 30-mile checkpoint cap. Training zones and dated benchmark comparisons are mounted-page extras, not HTTP result fields."],"workedExamples":[{"input":{"totalSeconds":1200,"distanceMeters":5000,"splitMeters":1000},"expected":{"/paces/per400m":96,"/paces/per1k":240},"absoluteTolerance":1e-8,"note":"Illustrative canonical-handler result; not independent validation of an empirical model."}],"constantsAndTables":{"metersPerMile":1609.34,"trainingZoneFactors":{"recovery":436.5,"easy":393,"moderate":357,"tempo":321,"threshold":300,"cv":286,"aerobicPower":274,"vo2Max":265},"visibleTrainingZones":[{"id":"easy","label":"Easy","description":"Recovery runs","color":"success","factor":393},{"id":"moderate","label":"Moderate","description":"Steady state","color":"success","factor":357},{"id":"tempo","label":"Tempo","description":"Threshold effort","color":"warning","factor":321},{"id":"threshold","label":"Threshold","description":"Race simulation","color":"warning","factor":300},{"id":"cv","label":"CV","description":"10K effort","color":"error","factor":286},{"id":"vo2Max","label":"VO2max","description":"3K-5K effort","color":"error","factor":265}],"milestones":[{"meters":1609.34,"label":"1 Mile"},{"meters":3218.69,"label":"2 Mile"},{"meters":5000,"label":"5K"},{"meters":10000,"label":"10K"},{"meters":15000,"label":"15K"},{"meters":16093.4,"label":"10 Mile"},{"meters":20000,"label":"20K"},{"meters":21097.5,"label":"Half"},{"meters":25000,"label":"25K"},{"meters":30000,"label":"30K"},{"meters":32186.9,"label":"20 Mile"},{"meters":35000,"label":"35K"},{"meters":40000,"label":"40K"}],"trainingBaselineSeconds":283,"tenKConversionMiles":6.22,"trainingOffsetSeconds":1760,"trainingOffsetDivisor":85},"sources":[{"title":"Canonical HTTP binding at the documented implementation revision","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/calculator-functions.ts","note":"Existing calculation handler; math metadata is additive."},{"title":"lib/formulas/pace.ts","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/formulas/pace.ts","note":"Primary implementation source for these equations/tables, not a claim of scientific calibration."},{"title":"lib/calc-utils.ts","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/calc-utils.ts","note":"Primary implementation source for these equations/tables, not a claim of scientific calibration."},{"title":"components/calculators/inline/utils/constants.js","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/components/calculators/inline/utils/constants.js","note":"Primary implementation source for these equations/tables, not a claim of scientific calibration."}]},"annotations":{"readOnlyHint":true,"consequentialHint":false},"name":"Pace Calculator","description":"Use this free running pace calculator for track or road races. This track pace calculator accepts any distance, including 400m, 800m, or 1500m, and a finish time, then calculates race pace per 400m lap, kilometer, and mile.","category":"Pace & Time","method":"POST","endpoint":"/api/calculators/pace-calculator","page":"/calculators/pace-calculator","inputSchema":{"type":"object","required":["totalSeconds","distanceMeters"],"properties":{"totalSeconds":{"type":"number","description":"Race or workout total time in seconds.","minimum":0},"distanceMeters":{"type":"number","description":"Race or workout distance in meters.","minimum":0},"splitMeters":{"type":"number","description":"Optional split chart interval in meters.","minimum":0,"default":400},"includeSplits":{"type":"boolean","description":"Whether to return an even split table.","default":true}}},"example":{"totalSeconds":1200,"distanceMeters":5000,"splitMeters":1000}},{"slug":"lap-split-calculator","math":{"href":"https://www.tracktoolspro.com/api/calculators/lap-split-calculator","jsonPointer":"/calculator/math","version":"2026-10-21.1","implementationVersion":"b5a8aca7b85361476e0321a08b7fa5f516fc9535","scope":"Canonical HTTP function and documented corresponding mounted-form math. This is public inspectable documentation, not access control or independent empirical validation.","unitNotation":"Input paths use [] and *; output paths are JSON Pointers with * (one segment) and ** (descendants). Empty output path denotes scalar result. Units apply to numeric quantities or explicitly described numeric strings; labels/statuses/booleans are dimensionless. More specific units, including count/index exceptions, override broad patterns.","interfaceNotes":["HTTP input is described by the adjacent inputSchema. The original handlers may accept numeric strings; this metadata adds no validation.","Mounted forms accept displayed clock/unit strings and enforce their own limits. Mounted tools limit strings to 200 characters and numeric parts to magnitude 1000000. Do not assume mounted/API input interchangeability.","Some legacy extreme/invalid tuples can produce null/empty results or nonfinite numbers serialized as null. Those are unavailable answers, not exact numerical predictions. Per-calculator domain describes the intended mathematical inputs."],"kind":"arithmetic","implementationFiles":["lib/formulas/splits.ts"],"equations":["Cumulative(x) = totalSeconds*(x/distanceMeters); lapTime = Cumulative(x)-Cumulative(previous x); averageSplitSeconds = totalSeconds*(splitMeters/distanceMeters).","Emit full intervals, then exact finish. Within 8*EPSILON*max(distanceMeters,splitMeters), absorb floating error into the final checkpoint. Retry multiplication grouping when an intermediate over/underflows."],"inputUnits":{"totalSeconds":"s","distanceMeters":"m","splitMeters":"m"},"outputUnits":{"/averageSplitSeconds":"s","/splits/*/distance":"m","/splits/*/cumulativeTime":"s","/splits/*/lapTime":"s"},"domain":["Positive finite time/distances; distanceMeters/splitMeters <=10000, otherwise splits=[]. Average may be null when unrepresentable."],"rounding":["Raw IEEE-754 numbers; the mounted page formats clocks separately."],"assumptions":["Uses the entered values and the selected convention; this documentation does not strengthen existing validation."],"limitations":["Even-speed arithmetic, with no fatigue or pacing model."],"mountedPageNotes":["Whole-second clock is the default; optional tenths round total ticks before splitting hours/minutes/seconds."],"workedExamples":[{"input":{"totalSeconds":130,"distanceMeters":800,"splitMeters":200},"expected":{"/averageSplitSeconds":32.5,"/splits/3/cumulativeTime":130},"absoluteTolerance":1e-8,"note":"Illustrative canonical-handler result; not independent validation of an empirical model."}],"constantsAndTables":{"fullIntervalLimit":10000,"finishToleranceEpsilonMultiple":8},"sources":[{"title":"Canonical HTTP binding at the documented implementation revision","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/calculator-functions.ts","note":"Existing calculation handler; math metadata is additive."},{"title":"lib/formulas/splits.ts","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/formulas/splits.ts","note":"Primary implementation source for these equations/tables, not a claim of scientific calibration."}]},"annotations":{"readOnlyHint":true,"consequentialHint":false},"name":"Lap Split Calculator","description":"This lap split calculator turns a goal time into exact 200m, 400m, or custom checkpoint targets for the 800m, 1500m, mile, 3200m, 5K, and longer races. Use it as a track lap calculator, mile split calculator, lap split calc, or track splits calculator when coaches need race plans, workout pacing, and track-side checkpoint cues instead of rough mental math.","category":"Pace & Time","method":"POST","endpoint":"/api/calculators/lap-split-calculator","page":"/calculators/lap-split-calculator","inputSchema":{"type":"object","required":["totalSeconds","distanceMeters","splitMeters"],"properties":{"totalSeconds":{"type":"number","description":"Goal time in seconds.","minimum":0},"distanceMeters":{"type":"number","description":"Race distance in meters.","minimum":0},"splitMeters":{"type":"number","description":"Split interval in meters.","minimum":0}}},"example":{"totalSeconds":130,"distanceMeters":800,"splitMeters":200}},{"slug":"finish-time-predictor","math":{"href":"https://www.tracktoolspro.com/api/calculators/finish-time-predictor","jsonPointer":"/calculator/math","version":"2026-10-21.1","implementationVersion":"b5a8aca7b85361476e0321a08b7fa5f516fc9535","scope":"Canonical HTTP function and documented corresponding mounted-form math. This is public inspectable documentation, not access control or independent empirical validation.","unitNotation":"Input paths use [] and *; output paths are JSON Pointers with * (one segment) and ** (descendants). Empty output path denotes scalar result. Units apply to numeric quantities or explicitly described numeric strings; labels/statuses/booleans are dimensionless. More specific units, including count/index exceptions, override broad patterns.","interfaceNotes":["HTTP input is described by the adjacent inputSchema. The original handlers may accept numeric strings; this metadata adds no validation.","Mounted forms accept displayed clock/unit strings and enforce their own limits. Mounted tools limit strings to 200 characters and numeric parts to magnitude 1000000. Do not assume mounted/API input interchangeability.","Some legacy extreme/invalid tuples can produce null/empty results or nonfinite numbers serialized as null. Those are unavailable answers, not exact numerical predictions. Per-calculator domain describes the intended mathematical inputs."],"kind":"arithmetic","implementationFiles":["lib/formulas/pace.ts"],"equations":["pacePerMeter = splitSeconds/splitMeters; projectedSeconds = pacePerMeter*raceMeters; percentComplete = min(100,100*splitMeters/raceMeters)."],"inputUnits":{"splitSeconds":"s","splitMeters":"m","raceMeters":"m"},"outputUnits":{"/projectedSeconds":"s","/pacePerMeter":"s/m","/percentComplete":"%"},"domain":["Positive finite tuple and representable positive time/pace; invalid values return null."],"rounding":["Raw IEEE-754 numbers; the mounted page formats clocks separately."],"assumptions":["Uses the entered values and the selected convention; this documentation does not strengthen existing validation."],"limitations":["Linear extrapolation only. PercentComplete is capped, but a split beyond race distance is not rejected and projection still follows the equation."],"mountedPageNotes":[],"workedExamples":[{"input":{"splitSeconds":300,"splitMeters":1600,"raceMeters":5000},"expected":{"/projectedSeconds":937.5},"absoluteTolerance":1e-8,"note":"Illustrative canonical-handler result; not independent validation of an empirical model."}],"constantsAndTables":{"completionPercentCap":100},"sources":[{"title":"Canonical HTTP binding at the documented implementation revision","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/calculator-functions.ts","note":"Existing calculation handler; math metadata is additive."},{"title":"lib/formulas/pace.ts","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/formulas/pace.ts","note":"Primary implementation source for these equations/tables, not a claim of scientific calibration."}]},"annotations":{"readOnlyHint":true,"consequentialHint":false},"name":"Race Finish Time Predictor","description":"Predict your race finish time based on your time at any split checkpoint. Enter your split and see your projected finish assuming even pacing throughout the race.","category":"Pace & Time","method":"POST","endpoint":"/api/calculators/finish-time-predictor","page":"/calculators/finish-time-predictor","inputSchema":{"type":"object","required":["splitSeconds","splitMeters","raceMeters"],"properties":{"splitSeconds":{"type":"number","description":"Elapsed split time in seconds.","minimum":0},"splitMeters":{"type":"number","description":"Distance already covered in meters.","minimum":0},"raceMeters":{"type":"number","description":"Full race distance in meters.","minimum":0}}},"example":{"splitSeconds":300,"splitMeters":1600,"raceMeters":5000}},{"slug":"effort-calculator","math":{"href":"https://www.tracktoolspro.com/api/calculators/effort-calculator","jsonPointer":"/calculator/math","version":"2026-10-21.1","implementationVersion":"b5a8aca7b85361476e0321a08b7fa5f516fc9535","scope":"Canonical HTTP function and documented corresponding mounted-form math. This is public inspectable documentation, not access control or independent empirical validation.","unitNotation":"Input paths use [] and *; output paths are JSON Pointers with * (one segment) and ** (descendants). Empty output path denotes scalar result. Units apply to numeric quantities or explicitly described numeric strings; labels/statuses/booleans are dimensionless. More specific units, including count/index exceptions, override broad patterns.","interfaceNotes":["HTTP input is described by the adjacent inputSchema. The original handlers may accept numeric strings; this metadata adds no validation.","Mounted forms accept displayed clock/unit strings and enforce their own limits. Mounted tools limit strings to 200 characters and numeric parts to magnitude 1000000. Do not assume mounted/API input interchangeability.","Some legacy extreme/invalid tuples can produce null/empty results or nonfinite numbers serialized as null. Those are unavailable answers, not exact numerical predictions. Per-calculator domain describes the intended mathematical inputs."],"kind":"heuristic","implementationFiles":["lib/formulas/effort.ts"],"equations":["p=totalSeconds/refDistanceMeters; adjustedPace=p*100/effortPercentage; adjustedTime=adjustedPace*targetDistanceMeters; refPacePerMile=p*1609.34; adjustedPacePerMile=adjustedPace*1609.34."],"inputUnits":{"totalSeconds":"s","refDistanceMeters":"m","targetDistanceMeters":"m","effortPercentage":"% reference speed"},"outputUnits":{"/adjustedTime":"s","/refPacePerMile":"s/mile","/adjustedPacePerMile":"s/mile"},"domain":["Positive finite inputs; API effortPercentage >=1; return null if derived numbers are not finite/positive."],"rounding":["Raw IEEE-754 numbers; the mounted page formats clocks separately."],"assumptions":["Uses the entered values and the selected convention; this documentation does not strengthen existing validation."],"limitations":["An entered speed ratio is not measured effort, RPE, HR, oxygen consumption or race equivalency. Values above100 remain possible in the HTTP contract."],"mountedPageNotes":[],"workedExamples":[{"input":{"totalSeconds":1200,"refDistanceMeters":5000,"targetDistanceMeters":5000,"effortPercentage":85},"expected":{"/adjustedTime":1411.764705882353},"absoluteTolerance":1e-8,"note":"Illustrative canonical-handler result; not independent validation of an empirical model."}],"constantsAndTables":{"metersPerMile":1609.34},"sources":[{"title":"Canonical HTTP binding at the documented implementation revision","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/calculator-functions.ts","note":"Existing calculation handler; math metadata is additive."},{"title":"lib/formulas/effort.ts","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/formulas/effort.ts","note":"Primary implementation source for these equations/tables, not a claim of scientific calibration."}]},"annotations":{"readOnlyHint":true,"consequentialHint":false},"name":"Running Effort Calculator","description":"Estimate target time from a reference performance and percentage of its speed. The calculation scales time inversely with the selected percentage and linearly with target distance.","category":"Pace & Time","method":"POST","endpoint":"/api/calculators/effort-calculator","page":"/calculators/effort-calculator","inputSchema":{"type":"object","required":["totalSeconds","refDistanceMeters","targetDistanceMeters","effortPercentage"],"properties":{"totalSeconds":{"type":"number","description":"Reference effort time in seconds.","minimum":0},"refDistanceMeters":{"type":"number","description":"Reference effort distance in meters.","minimum":0},"targetDistanceMeters":{"type":"number","description":"Target distance in meters.","minimum":0},"effortPercentage":{"type":"number","description":"Effort percentage, where 100 is the reference effort.","minimum":1}}},"example":{"totalSeconds":1200,"refDistanceMeters":5000,"targetDistanceMeters":5000,"effortPercentage":85}},{"slug":"treadmill-pace-converter","math":{"href":"https://www.tracktoolspro.com/api/calculators/treadmill-pace-converter","jsonPointer":"/calculator/math","version":"2026-10-21.1","implementationVersion":"b5a8aca7b85361476e0321a08b7fa5f516fc9535","scope":"Canonical HTTP function and documented corresponding mounted-form math. This is public inspectable documentation, not access control or independent empirical validation.","unitNotation":"Input paths use [] and *; output paths are JSON Pointers with * (one segment) and ** (descendants). Empty output path denotes scalar result. Units apply to numeric quantities or explicitly described numeric strings; labels/statuses/booleans are dimensionless. More specific units, including count/index exceptions, override broad patterns.","interfaceNotes":["HTTP input is described by the adjacent inputSchema. The original handlers may accept numeric strings; this metadata adds no validation.","Mounted forms accept displayed clock/unit strings and enforce their own limits. Mounted tools limit strings to 200 characters and numeric parts to magnitude 1000000. Do not assume mounted/API input interchangeability.","Some legacy extreme/invalid tuples can produce null/empty results or nonfinite numbers serialized as null. Those are unavailable answers, not exact numerical predictions. Per-calculator domain describes the intended mathematical inputs."],"kind":"arithmetic","implementationFiles":["lib/formulas/treadmill.ts"],"equations":["perMile=3600/mph; perKm=perMile/1.60934; per400m=perMile/4.02336; kph=mph*1.60934."],"inputUnits":{"mph":"mile/h"},"outputUnits":{"/perMile":"s/mile","/perKm":"s/km","/per400m":"s/400m","/kph":"km/h"},"domain":["Positive speed required; zero returns null."],"rounding":["Raw IEEE-754 numbers; the mounted page formats clocks separately."],"assumptions":["Uses the entered values and the selected convention; this documentation does not strengthen existing validation."],"limitations":["Pace conversion, not terrain/drag equivalence. The retained km/mile constant1609.34m differs from 4.02336*400=1609.344m."],"mountedPageNotes":[],"workedExamples":[{"input":{"mph":10},"expected":{"/perMile":360,"/kph":16.0934},"absoluteTolerance":1e-8,"note":"Illustrative canonical-handler result; not independent validation of an empirical model."}],"constantsAndTables":{"kilometersPerMile":1.60934,"laps400mPerMile":4.02336},"sources":[{"title":"Canonical HTTP binding at the documented implementation revision","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/calculator-functions.ts","note":"Existing calculation handler; math metadata is additive."},{"title":"lib/formulas/treadmill.ts","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/formulas/treadmill.ts","note":"Primary implementation source for these equations/tables, not a claim of scientific calibration."}]},"annotations":{"readOnlyHint":true,"consequentialHint":false},"name":"Treadmill Pace Converter","description":"Easily convert treadmill speeds in miles per hour (MPH) to pace per mile or pace per kilometer. Know exactly what pace you're running on the treadmill compared to outdoor running.","category":"Treadmill & Training","method":"POST","endpoint":"/api/calculators/treadmill-pace-converter","page":"/calculators/treadmill-pace-converter","inputSchema":{"type":"object","required":["mph"],"properties":{"mph":{"type":"number","description":"Treadmill speed in miles per hour.","minimum":0}}},"example":{"mph":10}},{"slug":"incline-calculator","math":{"href":"https://www.tracktoolspro.com/api/calculators/incline-calculator","jsonPointer":"/calculator/math","version":"2026-10-21.1","implementationVersion":"b5a8aca7b85361476e0321a08b7fa5f516fc9535","scope":"Canonical HTTP function and documented corresponding mounted-form math. This is public inspectable documentation, not access control or independent empirical validation.","unitNotation":"Input paths use [] and *; output paths are JSON Pointers with * (one segment) and ** (descendants). Empty output path denotes scalar result. Units apply to numeric quantities or explicitly described numeric strings; labels/statuses/booleans are dimensionless. More specific units, including count/index exceptions, override broad patterns.","interfaceNotes":["HTTP input is described by the adjacent inputSchema. The original handlers may accept numeric strings; this metadata adds no validation.","Mounted forms accept displayed clock/unit strings and enforce their own limits. Mounted tools limit strings to 200 characters and numeric parts to magnitude 1000000. Do not assume mounted/API input interchangeability.","Some legacy extreme/invalid tuples can produce null/empty results or nonfinite numbers serialized as null. Those are unavailable answers, not exact numerical predictions. Per-calculator domain describes the intended mathematical inputs."],"kind":"empirical-model","implementationFiles":["lib/formulas/incline.ts"],"equations":["inclinePercent = (targetSpeed-baseSpeed)/(A*exp(B*baseSpeed)); A=0.228887; B=0.013333."],"inputUnits":{"baseSpeed":"mph","targetSpeed":"mph"},"outputUnits":{"":"% incline"},"domain":["Nonzero speeds and targetSpeed>baseSpeed; otherwise null. API accepts finite nonnegative speeds; the function clamps nonpositive computed incline to 0."],"rounding":["Raw IEEE-754 numbers; the mounted page formats clocks separately."],"assumptions":["Uses the entered values and the selected convention; this documentation does not strengthen existing validation."],"limitations":["Proprietary empirical curve fit; no independent calibration or physiological equivalence established. No wind, surface or treadmill calibration is inferred."],"mountedPageNotes":[],"workedExamples":[{"input":{"baseSpeed":10,"targetSpeed":10.5},"expected":{"":1.9118085262426576},"absoluteTolerance":1e-8,"note":"Illustrative canonical-handler result; not independent validation of an empirical model."}],"constantsAndTables":{"A":0.228887,"B":0.013333},"sources":[{"title":"Canonical HTTP binding at the documented implementation revision","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/calculator-functions.ts","note":"Existing calculation handler; math metadata is additive."},{"title":"lib/formulas/incline.ts","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/formulas/incline.ts","note":"Primary implementation source for these equations/tables, not a claim of scientific calibration."}]},"annotations":{"readOnlyHint":true,"consequentialHint":false},"name":"Treadmill Incline Calculator","description":"Calculate how treadmill incline or outdoor hills affect your effort and equivalent pace. Understand the true training benefit of hill workouts and adjust your target paces accordingly.","category":"Treadmill & Training","method":"POST","endpoint":"/api/calculators/incline-calculator","page":"/calculators/incline-calculator","inputSchema":{"type":"object","required":["baseSpeed","targetSpeed"],"properties":{"baseSpeed":{"type":"number","description":"Current treadmill speed in mph.","minimum":0},"targetSpeed":{"type":"number","description":"Outdoor-equivalent target speed in mph.","minimum":0}}},"example":{"baseSpeed":10,"targetSpeed":10.5}},{"slug":"distance-equivalency-calculator","math":{"href":"https://www.tracktoolspro.com/api/calculators/distance-equivalency-calculator","jsonPointer":"/calculator/math","version":"2026-10-21.1","implementationVersion":"b5a8aca7b85361476e0321a08b7fa5f516fc9535","scope":"Canonical HTTP function and documented corresponding mounted-form math. This is public inspectable documentation, not access control or independent empirical validation.","unitNotation":"Input paths use [] and *; output paths are JSON Pointers with * (one segment) and ** (descendants). Empty output path denotes scalar result. Units apply to numeric quantities or explicitly described numeric strings; labels/statuses/booleans are dimensionless. More specific units, including count/index exceptions, override broad patterns.","interfaceNotes":["HTTP input is described by the adjacent inputSchema. The original handlers may accept numeric strings; this metadata adds no validation.","Mounted forms accept displayed clock/unit strings and enforce their own limits. Mounted tools limit strings to 200 characters and numeric parts to magnitude 1000000. Do not assume mounted/API input interchangeability.","Some legacy extreme/invalid tuples can produce null/empty results or nonfinite numbers serialized as null. Those are unavailable answers, not exact numerical predictions. Per-calculator domain describes the intended mathematical inputs."],"kind":"empirical-model","implementationFiles":["lib/formulas/vdot.ts"],"equations":["t=timeSeconds/60 (minutes); v=distanceMeters/t (m/min).","fraction(t)=0.8+0.1894393*exp(-0.012778*t)+0.2989558*exp(-0.1932605*t); oxygen(v)=-4.6+0.182258*v+0.000104*v^2; VDOT=oxygen(v)/fraction(t).","For each output distance, invert the positive-VDOT equation: upper=max(1,distance/100), double up to 1024 times until score<=VDOT, then bisect up to 1100 iterations; stop at relative bracket width<=1e-12 or floating-point stagnation. Return midpoint in minutes."],"inputUnits":{"distanceMeters":"m","timeSeconds":"s"},"outputUnits":{"/vdot":"dimensionless performance index","/predictionsMinutes/*":"min"},"domain":["Positive reference distance/time and positive finite VDOT; invalid/unrepresentable results return {vdot:null,predictionsMinutes:{}}."],"rounding":["Raw IEEE-754 numbers; the mounted page formats clocks separately."],"assumptions":["Uses the entered values and the selected convention; this documentation does not strengthen existing validation."],"limitations":["Daniels-Gilbert performance model, not laboratory VO2 or guaranteed race performance. Long-duration numerical inversion is not independent validation of physiology."],"mountedPageNotes":[],"workedExamples":[{"input":{"distanceMeters":5000,"timeSeconds":1200},"expected":{"/vdot":49.806233428066335,"/predictionsMinutes/5K":19.999999999998863},"absoluteTolerance":1e-8,"note":"Illustrative canonical-handler result; not independent validation of an empirical model."}],"constantsAndTables":{"commonDistancesMeters":{"100m":100,"200m":200,"400m":400,"800m":800,"1500m":1500,"Mile":1609.34,"3000m":3000,"3200m":3200,"5K":5000,"8K":8000,"10K":10000,"15K":15000,"Half Marathon":21097.5,"Marathon":42195},"vdotTimeUnit":"minutes","vdotVelocityUnit":"m/min","inverseRelativeTolerance":1e-12,"maxBracketExpansions":1024,"maxBisections":1100},"sources":[{"title":"Canonical HTTP binding at the documented implementation revision","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/calculator-functions.ts","note":"Existing calculation handler; math metadata is additive."},{"title":"lib/formulas/vdot.ts","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/formulas/vdot.ts","note":"Primary implementation source for these equations/tables, not a claim of scientific calibration."},{"title":"VDOT creator’s FAQ","url":"https://support.vdoto2.com/v-o2-faq/","note":"First-party explanation distinguishes VDOT from measured VO2max. Equation coefficients are documented from the canonical implementation, not derived from this FAQ. FAQ rechecked 2026-10-21."}]},"annotations":{"readOnlyHint":true,"consequentialHint":false},"name":"Race Equivalency Calculator","description":"Compare a reference performance with modeled equivalent times from 800m through the marathon using the Daniels–Gilbert VDOT equation. These comparisons depend on preparation and race conditions.","category":"Training & Fitness","method":"POST","endpoint":"/api/calculators/distance-equivalency-calculator","page":"/calculators/distance-equivalency-calculator","inputSchema":{"type":"object","required":["distanceMeters","timeSeconds"],"properties":{"distanceMeters":{"type":"number","description":"Known performance distance in meters.","minimum":0},"timeSeconds":{"type":"number","description":"Known performance time in seconds.","minimum":0}}},"example":{"distanceMeters":5000,"timeSeconds":1200}},{"slug":"altitude-adjustment-calculator","math":{"href":"https://www.tracktoolspro.com/api/calculators/altitude-adjustment-calculator","jsonPointer":"/calculator/math","version":"2026-10-21.1","implementationVersion":"b5a8aca7b85361476e0321a08b7fa5f516fc9535","scope":"Canonical HTTP function and documented corresponding mounted-form math. This is public inspectable documentation, not access control or independent empirical validation.","unitNotation":"Input paths use [] and *; output paths are JSON Pointers with * (one segment) and ** (descendants). Empty output path denotes scalar result. Units apply to numeric quantities or explicitly described numeric strings; labels/statuses/booleans are dimensionless. More specific units, including count/index exceptions, override broad patterns.","interfaceNotes":["HTTP input is described by the adjacent inputSchema. The original handlers may accept numeric strings; this metadata adds no validation.","Mounted forms accept displayed clock/unit strings and enforce their own limits. Mounted tools limit strings to 200 characters and numeric parts to magnitude 1000000. Do not assume mounted/API input interchangeability.","Some legacy extreme/invalid tuples can produce null/empty results or nonfinite numbers serialized as null. Those are unavailable answers, not exact numerical predictions. Per-calculator domain describes the intended mathematical inputs."],"kind":"empirical-model","implementationFiles":["lib/formulas/altitude.ts"],"equations":["For altitudeMeters<=750, F=1. Otherwise h=ln(altitudeMeters), d=ln(distanceMeters).","A(h)=0.0194294334323786*h^4-0.58204012227*h^3+6.53099074887773*h^2-32.4795428772407*h+61.3421201263799.","B(h)=-0.285467149404212*h^4+8.55856793339852*h^3-96.1580193931405*h^2+478.077054822298*h-892.151236317125.","F=(ln(altitudeMeters*distanceMeters)*A(h)+B(h))/ln(distanceMeters); convertedSeconds=timeSeconds/F; timeDiff=timeSeconds-convertedSeconds; percentImpact=100*(F-1)."],"inputUnits":{"timeSeconds":"s","altitudeMeters":"m","distanceMeters":"m"},"outputUnits":{"/originalSeconds":"s","/convertedSeconds":"s","/timeDiff":"s","/percentImpact":"%","/adjustmentFactor":"dimensionless"},"domain":["Finite nonnegative altitude/time and positive distance; API rejects nonfinite model outputs, including distance 1m logarithmic singularity above threshold. Zero time/altitude finite identities remain."],"rounding":["Raw IEEE-754 numbers; the mounted page formats clocks separately."],"assumptions":["Uses the entered values and the selected convention; this documentation does not strengthen existing validation."],"limitations":["Product-specific polynomial, not an official altitude qualification adjustment or a published universal physiological law. No independent calibration range established."],"mountedPageNotes":[],"workedExamples":[{"input":{"timeSeconds":1200,"altitudeMeters":1609,"distanceMeters":5000},"expected":{"/convertedSeconds":1186.3668179002848,"/adjustmentFactor":1.0114915403010378},"absoluteTolerance":1e-8,"note":"Illustrative canonical-handler result; not independent validation of an empirical model."}],"constantsAndTables":{"thresholdMeters":750,"polynomialCoefficients":"Full retained coefficients are in the equations and linked implementation; no published calibration is claimed."},"sources":[{"title":"Canonical HTTP binding at the documented implementation revision","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/calculator-functions.ts","note":"Existing calculation handler; math metadata is additive."},{"title":"lib/formulas/altitude.ts","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/formulas/altitude.ts","note":"Primary implementation source for these equations/tables, not a claim of scientific calibration."}]},"annotations":{"readOnlyHint":true,"consequentialHint":false},"name":"Altitude Adjustment Calculator","description":"Calculate how altitude affects your running performance. Convert times between sea level and high altitude venues. Essential for track and field athletes competing at venues like Albuquerque, Flagstaff, Boulder, or Mexico City.","category":"Conversions & Adjustments","method":"POST","endpoint":"/api/calculators/altitude-adjustment-calculator","page":"/calculators/altitude-adjustment-calculator","inputSchema":{"type":"object","required":["timeSeconds","altitudeMeters","distanceMeters"],"properties":{"timeSeconds":{"type":"number","description":"Race time at altitude in seconds.","minimum":0},"altitudeMeters":{"type":"number","description":"Venue altitude in meters.","minimum":0},"distanceMeters":{"type":"number","description":"Race distance in meters.","minimum":5e-324}}},"example":{"timeSeconds":1200,"altitudeMeters":1609,"distanceMeters":5000}},{"slug":"super-shoe-calculator","math":{"href":"https://www.tracktoolspro.com/api/calculators/super-shoe-calculator","jsonPointer":"/calculator/math","version":"2026-10-21.1","implementationVersion":"b5a8aca7b85361476e0321a08b7fa5f516fc9535","scope":"Canonical HTTP function and documented corresponding mounted-form math. This is public inspectable documentation, not access control or independent empirical validation.","unitNotation":"Input paths use [] and *; output paths are JSON Pointers with * (one segment) and ** (descendants). Empty output path denotes scalar result. Units apply to numeric quantities or explicitly described numeric strings; labels/statuses/booleans are dimensionless. More specific units, including count/index exceptions, override broad patterns.","interfaceNotes":["HTTP input is described by the adjacent inputSchema. The original handlers may accept numeric strings; this metadata adds no validation.","Mounted forms accept displayed clock/unit strings and enforce their own limits. Mounted tools limit strings to 200 characters and numeric parts to magnitude 1000000. Do not assume mounted/API input interchangeability.","Some legacy extreme/invalid tuples can produce null/empty results or nonfinite numbers serialized as null. Those are unavailable answers, not exact numerical predictions. Per-calculator domain describes the intended mathematical inputs."],"kind":"scenario","implementationFiles":["lib/formulas/super-shoe.ts"],"equations":["toSuper: convertedSeconds=totalSeconds*(100-improvementRate)/100; toRegular: convertedSeconds=totalSeconds*100/(100-improvementRate)."],"inputUnits":{"totalSeconds":"s","improvementRate":"%","direction":"enum/string (dimensionless)","presets[]":"enum/string (dimensionless)"},"outputUnits":{"/convertedSeconds":"s","/improvementRate":"%"},"domain":["Finite totalSeconds>=0; rate0..20; overflow produces API error. The presets schema field does not affect the handler calculation."],"rounding":["Raw IEEE-754 numbers; the mounted page formats clocks separately."],"assumptions":["Uses the entered values and the selected convention; this documentation does not strengthen existing validation."],"limitations":["Entered/preset time reductions are scenarios, not measured benefit. A percent running-economy improvement is not automatically the same percent finish-time improvement."],"mountedPageNotes":[],"workedExamples":[{"input":{"totalSeconds":900,"improvementRate":2.5,"direction":"toSuper"},"expected":{"/convertedSeconds":877.5},"absoluteTolerance":1e-8,"note":"Illustrative canonical-handler result; not independent validation of an empirical model."}],"constantsAndTables":{"editorialRatePresets":[{"id":"track-mid","label":"Track 800-1500m","rate":2},{"id":"track-dist","label":"Track 3K-10K","rate":2.5},{"id":"road-short","label":"Road 5K-10K","rate":3},{"id":"half","label":"Half Marathon","rate":3.5},{"id":"marathon","label":"Marathon","rate":4}]},"sources":[{"title":"Canonical HTTP binding at the documented implementation revision","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/calculator-functions.ts","note":"Existing calculation handler; math metadata is additive."},{"title":"lib/formulas/super-shoe.ts","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/formulas/super-shoe.ts","note":"Primary implementation source for these equations/tables, not a claim of scientific calibration."}]},"annotations":{"readOnlyHint":true,"consequentialHint":false},"name":"Super Shoe Calculator","description":"Calculate the performance benefit of carbon-plated super shoes like the Nike Vaporfly, Adidas Adizero, and other advanced racing shoes. Based on scientific research showing 2-4% improvements in running economy.","category":"Conversions & Adjustments","method":"POST","endpoint":"/api/calculators/super-shoe-calculator","page":"/calculators/super-shoe-calculator","inputSchema":{"type":"object","required":["totalSeconds","improvementRate","direction"],"properties":{"totalSeconds":{"type":"number","description":"Input race time in seconds.","minimum":0},"improvementRate":{"type":"number","description":"Estimated improvement rate as a percent.","minimum":0,"maximum":20},"direction":{"type":"string","description":"Conversion direction.","enum":["toSuper","toRegular"],"default":"toSuper"},"presets":{"type":"array","description":"Available event-rate presets.","items":{"type":"string","description":"Preset ids: track-mid, track-dist, road-short, half, marathon"}}}},"example":{"totalSeconds":900,"improvementRate":2.5,"direction":"toSuper"}},{"slug":"wind-adjustment-calculator","math":{"href":"https://www.tracktoolspro.com/api/calculators/wind-adjustment-calculator","jsonPointer":"/calculator/math","version":"2026-10-21.1","implementationVersion":"b5a8aca7b85361476e0321a08b7fa5f516fc9535","scope":"Canonical HTTP function and documented corresponding mounted-form math. This is public inspectable documentation, not access control or independent empirical validation.","unitNotation":"Input paths use [] and *; output paths are JSON Pointers with * (one segment) and ** (descendants). Empty output path denotes scalar result. Units apply to numeric quantities or explicitly described numeric strings; labels/statuses/booleans are dimensionless. More specific units, including count/index exceptions, override broad patterns.","interfaceNotes":["HTTP input is described by the adjacent inputSchema. The original handlers may accept numeric strings; this metadata adds no validation.","Mounted forms accept displayed clock/unit strings and enforce their own limits. Mounted tools limit strings to 200 characters and numeric parts to magnitude 1000000. Do not assume mounted/API input interchangeability.","Some legacy extreme/invalid tuples can produce null/empty results or nonfinite numbers serialized as null. Those are unavailable answers, not exact numerical predictions. Per-calculator domain describes the intended mathematical inputs."],"kind":"empirical-model","implementationFiles":["lib/formulas/wind.ts","lib/formulas/track-utilities.ts"],"equations":["benefit=c0*wind+c1*wind*mark+c2*wind^2, from the selected canonical coefficient row.","Track: neutral=mark+benefit (seconds). Horizontal jumps: neutral=mark-benefit (meters).","Round neutral and neutral-timeSeconds to 0.001s separately; legalWind=(windSpeed<=2.0), isHeadwind=(windSpeed<0)."],"inputUnits":{"timeSeconds":"s","windSpeed":"m/s (positive tailwind)","distance":"m"},"outputUnits":{"/actualTime":"s","/adjustedTime":"s","/timeDifference":"s","/windSpeed":"m/s"},"domain":["100m or 200m; positive recorded time and finite wind; unavailable/nonpositive corrected result returns null."],"rounding":["Adjusted time and difference use Math.round(x*1000)/1000."],"assumptions":["Uses the entered values and the selected convention; this documentation does not strengthen existing validation."],"limitations":["Data-driven still-air estimate. legalWind tests only the entered wind threshold; it does not certify a ratifiable mark."],"mountedPageNotes":[],"workedExamples":[{"input":{"timeSeconds":10,"windSpeed":2,"distance":100},"expected":{"/adjustedTime":10.083},"absoluteTolerance":1e-8,"note":"Illustrative canonical-handler result; not independent validation of an empirical model."}],"constantsAndTables":{"coefficients":{"100m":[-0.0449,0.009459,-0.0042],"200m":[0.09,0,-0.01],"100mH":[0.093,0,-0.01],"110mH":[0.093,0,-0.01],"Long Jump":[0.029,0,0],"Triple Jump":[0.069,0,-0.009]},"coefficientOrder":["c0","c1","c2"],"legalThresholdMetersPerSecond":2},"sources":[{"title":"Canonical HTTP binding at the documented implementation revision","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/calculator-functions.ts","note":"Existing calculation handler; math metadata is additive."},{"title":"lib/formulas/wind.ts","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/formulas/wind.ts","note":"Primary implementation source for these equations/tables, not a claim of scientific calibration."},{"title":"lib/formulas/track-utilities.ts","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/formulas/track-utilities.ts","note":"Primary implementation source for these equations/tables, not a claim of scientific calibration."},{"title":"Moinat, Fabius & Emanuel, 2018","url":"https://onlinelibrary.wiley.com/doi/full/10.1080/17461391.2018.1480062","note":"Moinat, Fabius, Emanuel 2018 empirical wind model. Does not validate the separate practice-split 100m regression."}]},"annotations":{"readOnlyHint":true,"consequentialHint":false},"name":"Wind Adjustment Calculator","description":"Convert wind-aided or wind-affected sprint times to equivalent still-air performances. Essential for comparing 100m and 200m performances run under different wind conditions, using a peer-reviewed statistical wind model (Moinat et al. 2018).","category":"Sprints & Hurdles","method":"POST","endpoint":"/api/calculators/wind-adjustment-calculator","page":"/calculators/wind-adjustment-calculator","inputSchema":{"type":"object","required":["timeSeconds","windSpeed","distance"],"properties":{"timeSeconds":{"type":"number","description":"Recorded sprint time in seconds.","minimum":0},"windSpeed":{"type":"number","description":"Wind reading in m/s. Positive is tailwind."},"distance":{"type":"integer","description":"Sprint distance in meters.","enum":[100,200],"default":100}}},"example":{"timeSeconds":10,"windSpeed":2,"distance":100}},{"slug":"100m-predictor","math":{"href":"https://www.tracktoolspro.com/api/calculators/100m-predictor","jsonPointer":"/calculator/math","version":"2026-10-21.1","implementationVersion":"b5a8aca7b85361476e0321a08b7fa5f516fc9535","scope":"Canonical HTTP function and documented corresponding mounted-form math. This is public inspectable documentation, not access control or independent empirical validation.","unitNotation":"Input paths use [] and *; output paths are JSON Pointers with * (one segment) and ** (descendants). Empty output path denotes scalar result. Units apply to numeric quantities or explicitly described numeric strings; labels/statuses/booleans are dimensionless. More specific units, including count/index exceptions, override broad patterns.","interfaceNotes":["HTTP input is described by the adjacent inputSchema. The original handlers may accept numeric strings; this metadata adds no validation.","Mounted forms accept displayed clock/unit strings and enforce their own limits. Mounted tools limit strings to 200 characters and numeric parts to magnitude 1000000. Do not assume mounted/API input interchangeability.","Some legacy extreme/invalid tuples can produce null/empty results or nonfinite numbers serialized as null. Those are unavailable answers, not exact numerical predictions. Per-calculator domain describes the intended mathematical inputs."],"kind":"empirical-model","implementationFiles":["lib/formulas/track-utilities.ts"],"equations":["base=exp(c0+c1*block30+c2*(10/fly10)); windAdjustment=w0*wind+w1*wind*base+w2*wind^2; predictedSeconds=base-windAdjustment+reaction."],"inputUnits":{"block30":"s","fly10":"s","wind":"m/s (positive tailwind)","reaction":"s"},"outputUnits":{"/predictedSeconds":"s"},"domain":["Positive block30/fly10; API reaction>=0; finite positive predicted result required or predictedSeconds=null."],"rounding":["Raw IEEE-754 numbers; the mounted page formats clocks separately."],"assumptions":["Uses the entered values and the selected convention; this documentation does not strengthen existing validation."],"limitations":["Unvalidated practice-split regression. The published wind model does not validate the practice regression or start/reaction timing convention. Input timing origin must be consistent."],"mountedPageNotes":[],"workedExamples":[{"input":{"block30":4,"fly10":1,"wind":0,"reaction":0.149},"expected":{"/predictedSeconds":11.221161948458294},"absoluteTolerance":1e-8,"note":"Illustrative canonical-handler result; not independent validation of an empirical model."}],"constantsAndTables":{"practiceRegression":[2.2441850962837124,0.14735859276138946,-0.042918544171317706],"coefficientOrder":["intercept","block30","10/fly10"],"windCoefficients":[-0.0449,0.009459,-0.0042],"defaultReactionSeconds":0.149},"sources":[{"title":"Canonical HTTP binding at the documented implementation revision","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/calculator-functions.ts","note":"Existing calculation handler; math metadata is additive."},{"title":"lib/formulas/track-utilities.ts","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/formulas/track-utilities.ts","note":"Primary implementation source for these equations/tables, not a claim of scientific calibration."},{"title":"Moinat, Fabius & Emanuel, 2018","url":"https://onlinelibrary.wiley.com/doi/full/10.1080/17461391.2018.1480062","note":"Moinat, Fabius, Emanuel 2018 empirical wind model. Does not validate the separate practice-split 100m regression."}]},"annotations":{"readOnlyHint":true,"consequentialHint":false},"name":"100m Predictor","description":"This 100m predictor estimates race performance from a block 30m split and a flying 10m split, with optional wind and reaction-time adjustments. Use it to translate practice timing into a realistic 100m projection.","category":"Sprints & Hurdles","method":"POST","endpoint":"/api/calculators/100m-predictor","page":"/calculators/100m-predictor","inputSchema":{"type":"object","required":["block30","fly10"],"properties":{"block30":{"type":"number","description":"Block or first-movement 30m split in seconds.","minimum":0},"fly10":{"type":"number","description":"Flying 10m split in seconds.","minimum":0},"wind":{"type":"number","description":"Wind in m/s. Positive is tailwind.","default":0},"reaction":{"type":"number","description":"Reaction time in seconds.","default":0.149,"minimum":0}}},"example":{"block30":4,"fly10":1,"wind":0,"reaction":0.149}},{"slug":"200m-lane-draw-converter","math":{"href":"https://www.tracktoolspro.com/api/calculators/200m-lane-draw-converter","jsonPointer":"/calculator/math","version":"2026-10-21.1","implementationVersion":"b5a8aca7b85361476e0321a08b7fa5f516fc9535","scope":"Canonical HTTP function and documented corresponding mounted-form math. This is public inspectable documentation, not access control or independent empirical validation.","unitNotation":"Input paths use [] and *; output paths are JSON Pointers with * (one segment) and ** (descendants). Empty output path denotes scalar result. Units apply to numeric quantities or explicitly described numeric strings; labels/statuses/booleans are dimensionless. More specific units, including count/index exceptions, override broad patterns.","interfaceNotes":["HTTP input is described by the adjacent inputSchema. The original handlers may accept numeric strings; this metadata adds no validation.","Mounted forms accept displayed clock/unit strings and enforce their own limits. Mounted tools limit strings to 200 characters and numeric parts to magnitude 1000000. Do not assume mounted/API input interchangeability.","Some legacy extreme/invalid tuples can produce null/empty results or nonfinite numbers serialized as null. Those are unavailable answers, not exact numerical predictions. Per-calculator domain describes the intended mathematical inputs."],"kind":"heuristic","implementationFiles":["lib/formulas/track-utilities.ts"],"equations":["convertedSeconds=timeSeconds+0.018*(currentLane-targetLane)."],"inputUnits":{"timeSeconds":"s","currentLane":"dimensionless index/count","targetLane":"dimensionless index/count"},"outputUnits":{"/convertedSeconds":"s"},"domain":["API lane integers1..9 and nonnegative time; positive finite converted time required, otherwise null."],"rounding":["Raw IEEE-754 numbers; the mounted page formats clocks separately."],"assumptions":["Uses the entered values and the selected convention; this documentation does not strengthen existing validation."],"limitations":["Fixed outdoor lane adjustment heuristic, not a geometric stagger correction or independently calibrated performance law."],"mountedPageNotes":[],"workedExamples":[{"input":{"timeSeconds":21.4,"currentLane":8,"targetLane":4},"expected":{"/convertedSeconds":21.471999999999998},"absoluteTolerance":1e-8,"note":"Illustrative canonical-handler result; not independent validation of an empirical model."}],"constantsAndTables":{"secondsPerLane":0.018},"sources":[{"title":"Canonical HTTP binding at the documented implementation revision","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/calculator-functions.ts","note":"Existing calculation handler; math metadata is additive."},{"title":"lib/formulas/track-utilities.ts","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/formulas/track-utilities.ts","note":"Primary implementation source for these equations/tables, not a claim of scientific calibration."}]},"annotations":{"readOnlyHint":true,"consequentialHint":false},"name":"200m Lane Draw Converter","description":"This 200m lane draw converter adjusts outdoor 200m times between lane assignments using a 0.018 second per-lane estimate for outside-lane advantage.","category":"Sprints & Hurdles","method":"POST","endpoint":"/api/calculators/200m-lane-draw-converter","page":"/calculators/200m-lane-draw-converter","inputSchema":{"type":"object","required":["timeSeconds","currentLane","targetLane"],"properties":{"timeSeconds":{"type":"number","description":"Recorded outdoor 200m time in seconds.","minimum":0},"currentLane":{"type":"integer","description":"Lane the mark was run in.","minimum":1,"maximum":9},"targetLane":{"type":"integer","description":"Lane to convert the mark to.","minimum":1,"maximum":9}}},"example":{"timeSeconds":21.4,"currentLane":8,"targetLane":4}},{"slug":"world-athletics-points-calculator","math":{"href":"https://www.tracktoolspro.com/api/calculators/world-athletics-points-calculator","jsonPointer":"/calculator/math","version":"2026-10-21.1","implementationVersion":"b5a8aca7b85361476e0321a08b7fa5f516fc9535","scope":"Canonical HTTP function and documented corresponding mounted-form math. This is public inspectable documentation, not access control or independent empirical validation.","unitNotation":"Input paths use [] and *; output paths are JSON Pointers with * (one segment) and ** (descendants). Empty output path denotes scalar result. Units apply to numeric quantities or explicitly described numeric strings; labels/statuses/booleans are dimensionless. More specific units, including count/index exceptions, override broad patterns.","interfaceNotes":["HTTP input is described by the adjacent inputSchema. The original handlers may accept numeric strings; this metadata adds no validation.","Mounted forms accept displayed clock/unit strings and enforce their own limits. Mounted tools limit strings to 200 characters and numeric parts to magnitude 1000000. Do not assume mounted/API input interchangeability.","Some legacy extreme/invalid tuples can produce null/empty results or nonfinite numbers serialized as null. Those are unavailable answers, not exact numerical predictions. Per-calculator domain describes the intended mathematical inputs."],"kind":"table-fit","implementationFiles":["lib/formulas/wa-points.ts"],"equations":["Select gender/event coefficients and mark type from the canonical stored data; category limits selectable events. Parse time to seconds, distance to meters or combined-event score to integer points.","Three coefficients: q=a*mark^2+b*mark+c; points=Math.round(q), only on the monotonic valid branch and 0..1400. Two coefficients: points=a*mark+b, without extra integer rounding.","Inverse linear: mark=(points-b)/a. Inverse quadratic: discriminant=b^2-4*a*(c-points); try (-b-sqrt(discriminant))/(2*a), rounded to 0.01; if negative use plus root. Format by mark type."],"inputUnits":{"category":"enum/string (dimensionless)","gender":"enum/string (dimensionless)","event":"enum/string (dimensionless)","mark":"time:s/clock; distance:m; combined-event score:points","points":"integer scoring points (string)"},"outputUnits":{"/mark":"seconds/clock, meters or combined-event points per markType","/points":"scoring points (string)"},"domain":["Select known category/gender/event. Inverse integer points 0..1400. Nonpositive/malformed marks, wrong branch or out-of-fit domain return empty mark/points strings; unavailable event errors."],"rounding":["Quadratic points round nearest integer; linear rows retain raw numeric string. Inverse distance/time mark rounds0.01 and clock formatting carries total hundredths."],"assumptions":["Uses the entered values and the selected convention; this documentation does not strengthen existing validation."],"limitations":["Fitted approximation, not an official-table lookup. The retained audit found scored values within 1 point across checked marks and a Road 3kmW boundary blank. Inverse rounding need not round-trip exactly."],"mountedPageNotes":[],"workedExamples":[{"input":{"category":"outdoor","gender":"men","event":"100m","mark":"10.00"},"expected":{"/points":"1206"},"absoluteTolerance":1e-8,"note":"Illustrative canonical-handler result; not independent validation of an empirical model."}],"constantsAndTables":{"storedFitsAndSelectors":{"markTypes":{"50m":"time","50mH":"time","55m":"time","55mH":"time","60m":"time","60mH":"time","200m":"time","200m sh":"time","300m":"time","300m sh":"time","400m":"time","400m sh":"time","500m":"time","500m sh":"time","600m":"time","600m sh":"time","800m":"time","800m sh":"time","1000m":"time","1000m sh":"time","1500m":"time","1500m sh":"time","Mile":"time","Mile sh":"time","2000m":"time","2000m sh":"time","3000m":"time","3000m sh":"time","2 Miles":"time","2 Miles sh":"time","5000m":"time","5000m sh":"time","4x200m":"time","4x200m sh":"time","4x400m":"time","4x400m sh":"time","4x400mix":"time","4x400mix sh":"time","LJ":"distance","TJ":"distance","HJ":"distance","PV":"distance","SP":"distance","Hept.":"points","3000mW":"time","5000mW":"time","10,000mW":"time","Pent. sh":"points","Hept. sh":"points","100m":"time","110mH":"time","400mH":"time","2000m SC":"time","3000m SC":"time","10000m":"time","Road Mile":"time","Road 5 km":"time","Road 10 km":"time","Road 10 Miles":"time","Road 15 km":"time","Road 20 km":"time","Road HM":"time","Road 25 km":"time","Road 30 km":"time","Road Marathon":"time","Road 100 km":"time","4x100m":"time","DT":"distance","JT":"distance","HT":"distance","Dec.":"points","15,000mW":"time","20,000mW":"time","30,000mW":"time","35,000mW":"time","50,000mW":"time","100mH":"time","Road 3kmW":"time","Road 5kmW":"time","Road 10kmW":"time","Road 15kmW":"time","Road 20kmW":"time","Road 30kmW":"time","Road 35kmW":"time","Road 50kmW":"time"},"categories":{"outdoor":["100m","100mH","110mH","200m","300m","400m","400mH","500m","600m","800m","1000m","1500m","Mile","2000m","2000m SC","3000m","3000m SC","2 Miles","5000m","10000m","HJ","PV","LJ","TJ","SP","DT","HT","JT","Pent. sh","Hept.","Dec.","Road Marathon","Road HM","Road Mile","Road 5 km","Road 10 km","Road 15 km","Road 20 km","Road 25 km","Road 30 km","Road 100 km","3000mW","5000mW","10,000mW","15,000mW","20,000mW","30,000mW","35,000mW","50,000mW","Road 3kmW","Road 5kmW","Road 10kmW","Road 15kmW","Road 20kmW","Road 30kmW","Road 35kmW","Road 50kmW","4x100m","4x200m","4x400m","4x400mix"],"indoor":["50m","55m","60m","50mH","55mH","60mH","200m sh","300m sh","400m sh","500m sh","600m sh","800m sh","1000m sh","1500m sh","Mile sh","2000m sh","3000m sh","2 Miles sh","5000m sh","HJ","PV","LJ","TJ","SP","Pent. sh","Hept. sh","4x200m sh","4x400m sh","4x400mix sh"]},"labels":{"TJ":"Triple jump","Road 20kmW":"20km race walk (road)","Road HM":"Half marathon (road)","5000m":"5000m","300m":"300m","200m":"200m","55mH":"55m hurdles","60mH":"60m hurdles","4x400m":"4x400m relay","50mH":"50m hurdles","400m":"400m","Mile sh":"Mile (indoor)","600m":"600m","10000m":"10000m","Hept.":"Heptathlon","20,000mW":"20000m race walk","3000m sh":"3000m (indoor)","800m sh":"800m (indoor)","Road 3kmW":"3km race walk (road)","5000mW":"5000m race walk","4x200m sh":"4x200m relay (indoor)","50m":"50m","500m":"500m","15,000mW":"15000m race walk","Road 10 Miles":"10 mile (road)","100m":"100m","4x100m":"4x100m relay","Road 15 km":"15km (road)","500m sh":"500m (indoor)","110mH":"110m hurdles","10,000mW":"10000m race walk","35,000mW":"35000m race walk","Road 100 km":"100km (road)","400mH":"400m hurdles","HJ":"High jump","300m sh":"300m (indoor)","4x400mix":"4x400m mixed relay","Road 30kmW":"30km race walk (road)","2 Miles":"2 mile","2000m SC":"2000m steeplechase","PV":"Pole vault","400m sh":"400m (indoor)","HT":"Hammer throw","3000m SC":"3000m steeplechase","30,000mW":"30000m race walk","1500m":"1500m","4x400mix sh":"4x400m mixed relay (indoor)","JT":"Javelin throw","Road 50kmW":"50km race walk (road)","Road 30 km":"30km (road)","55m":"55m","4x200m":"4x200m relay","1500m sh":"1500m (indoor)","3000m":"3000m","LJ":"Long jump","Road 5kmW":"5km race walk (road)","Road 5 km":"5km road","3000mW":"3000m race walk","Road 15kmW":"15km race walk (road)","50,000mW":"50000m race walk","60m":"60m","1000m sh":"1000m (indoor)","Road 35kmW":"35km race walk (road)","800m":"800m","1000m":"1000m","Road 10kmW":"10km race walk (road)","DT":"Discus throw","100mH":"100m hurdles","4x400m sh":"4x400m Relay (indoor)","Dec.":"Decathlon","Road 20 km":"20km (road)","200m sh":"200m (indoor)","Road Marathon":"Marathon (road)","2000m":"2000m","5000m sh":"5000m (indoor)","Mile":"Mile","2000m sh":"2000m (indoor)","SP":"Shot put","Road 10 km":"10km (road)","Road 25 km":"25km (road)","600m sh":"600m (indoor)","2 Miles sh":"2 mile (indoor)","Road Mile":"Mile (road)","Pent. sh":"Pentathlon (indoor)","Hept. sh":"Heptathlon (indoor)"},"coeffs":{"men":{"TJ":[0.4603666024030417,90.96978768056579,-514.9946082626993],"Road 20kmW":[0.00002735041573859393,-0.623559717833615,3554.1219906366896],"Road HM":[0.00009469710951061014,-1.3521892901331114,4827.020676429092],"Hept. sh":[0.0000017511052939828738,0.18632999798127692,-46.18002211678322],"5000m":[0.002777997945427213,-8.000608112196687,5760.418712362531],"300m":[1.8296570247447335,-209.30430382250051,5985.805789959268],"200m":[5.083329625804254,-360.8260380705033,6403.154333221377],"55mH":[30.085307708674918,-803.1373763838637,5359.772393310966],"60mH":[23.916231718984818,-698.1937268964539,5095.479315056291],"4x400m":[0.05050072203675704,-33.73384421285573,5633.448990227305],"50mH":[34.21237722424106,-844.9430290468159,5216.591321673945],"400m":[1.0210130425695638,-161.3092238081408,6371.289298935095],"Mile sh":[0.036900007414912395,-30.626657725760197,6354.958031052956],"600m":[0.3856992283143512,-99.89240864996827,6467.788691627793],"10000m":[0.0005239994429364625,-3.3011925260043427,5199.371486475808],"20,000mW":[0.000027350002531860776,-0.6235797774588789,3554.403148578058],"3000m sh":[0.00832191917227365,-13.980775520668885,5871.90250552597],"800m sh":[0.19739256108073278,-72.63927638712084,6682.6879602972185],"Road 3kmW":[0.0013188638764620175,-4.232300411919454,3395.3467675125576],"5000mW":[0.0004669995672369684,-2.5217935388764374,3404.4156502809637],"4x200m sh":[0.3119896689477031,-89.85075766433874,6469.076514942455],"50m":[95.82235385745662,-1763.0165325322305,8108.971505376976],"500m":[0.585027774798931,-121.67863906127604,6326.92802974442],"15,000mW":[0.00004979999739458674,-0.8396274711976517,3539.02770275042],"Road 10 Miles":[0.00018524985210266465,-1.9447905029914807,5104.302716247388],"100m":[24.642211664166098,-837.7135408530303,7119.3125116789015],"4x100m":[1.2360320753572864,-171.79529610507234,5969.431205180357],"Road 15 km":[0.00021619813224982992,-2.104692144502337,5122.29998515785],"500m sh":[0.5649713205833109,-119.76970949143652,6347.5570185079705],"110mH":[7.6652061275597365,-395.4176696527282,5099.522552244605],"10,000mW":[0.00011370001341616184,-1.2620689961606075,3502.2382226384216],"35,000mW":[0.00000613999967058812,-0.27998393156747703,3191.8161623578926],"Road 100 km":[0.0000017649869023559175,-0.17155533952055002,4168.759475629777],"400mH":[0.5459888468067362,-104.2787780128183,4979.068748674414],"HJ":[32.14570816360356,745.3746826150164,-705.259733494051],"300m sh":[1.802963929735995,-209.12735993028036,6064.19838705298],"4x400mix":[0.027319971572494772,-21.855722774421338,4371.091344809567],"Road 30kmW":[0.000008929872357660252,-0.3412926057870429,3260.9773729436565],"2 Miles":[0.007029988518363783,-12.721403001585259,5755.13271902001],"2000m SC":[0.010229985822021836,-13.503484790678613,4456.117711582512],"PV":[3.0457199208785823,239.612026696057,-280.5412229935755],"400m sh":[0.9810285010226494,-158.13093544779986,6372.245446830289],"HT":[0.0028444950947790204,15.081627308136717,-21.68901198504136],"3000m SC":[0.0043159973458793965,-8.804593368752649,4490.321079731511],"30,000mW":[0.000008929998959835068,-0.3413044839752075,3261.1635900282854],"1500m":[0.04065992529984008,-31.307736299477256,6026.662254345021],"4x400mix sh":[0.026880251011740075,-21.772687901858262,4408.906997824612],"JT":[0.0024031524897170087,13.841186813175682,-21.05825095349428],"Road 50kmW":[0.000002123989730853351,-0.15802293332546835,2939.1902791610046],"Road 30 km":[0.000041899103628650555,-0.8882236041678482,4707.383289585705],"55m":[78.9227608844667,-1578.3239369830117,7890.637076645042],"4x200m":[0.2976775548102779,-85.72750621619343,6172.13094653259],"1500m sh":[0.041999988506264074,-32.423575703958704,6257.669581143418],"3000m":[0.008150049932713843,-13.691983542337312,5750.59246378555],"LJ":[1.931092872960562,186.73134733641928,-479.70640445759636],"Road 5kmW":[0.0004673316170291028,-2.522675135297817,3404.498836055718],"Road 5 km":[0.0027791125913787518,-8.002589936962636,5760.829724426498],"3000mW":[0.0013179978841543205,-4.2307618788757395,3395.177055106571],"Road 15kmW":[0.000049801244751997674,-0.8395916226980376,3538.6471161143127],"50,000mW":[0.000002123999976233037,-0.15802557747075685,2939.2753526763263],"60m":[68.62032200155772,-1468.376079820242,7854.923996115336],"1000m sh":[0.11389778654137217,-54.670029751952825,6560.289996561711],"Road 35kmW":[0.0000061400669292650464,-0.2799797053730302,3191.6897468937095],"800m":[0.1980049254166545,-72.07136038821409,6558.28160300618],"1000m":[0.11229987246056083,-53.34129687676432,6334.142779359594],"Road 10kmW":[0.00011369880949837693,-1.2619474331455365,3501.5994292710093],"DT":[0.00400631290161968,17.8920605010303,-27.18777464602681],"4x400m sh":[0.04890033030582153,-33.25166827913472,5652.691308940412],"Dec.":[9.772168523991976e-7,0.139129643801148,-48.958602564753164],"Road 20 km":[0.00010849945387967144,-1.4544357631051241,4874.178186156554],"200m sh":[5.0428984333116205,-363.0051678271411,6532.672628951492],"Road Marathon":[0.000020101186255287035,-0.6150659606552438,4705.042285787989],"2000m":[0.02181003181267993,-23.03116782160032,6080.168871850823],"5000m sh":[0.002900003148620267,-8.351976844926412,6013.40053571912],"Mile":[0.035099677603458446,-29.132456259137143,6044.924547011615],"2000m sh":[0.022600003526984658,-23.865373073726005,6300.3976437979145],"SP":[0.04234614355526389,57.99966265925241,-55.823610246186945],"Road 10 km":[0.0005243835511893474,-3.302659028227424,5200.274036400777],"Road 25 km":[0.00006380128595110182,-1.102413160310192,4762.120081442874],"600m sh":[0.3899861152610953,-102.17335025475768,6692.146447579609],"2 Miles sh":[0.007209969187584653,-13.078823619347986,5931.217870712513],"Road Mile":[0.035099677603458446,-29.132456259137143,6044.924547011615]},"women":{"TJ":[0.4296645887350792,90.3430418780863,-231.6675825305283],"Road 20kmW":[0.00001869988372757989,-0.493658647842274,3258.0265828920237],"Road HM":[0.000025960366893742386,-0.5606107770831628,3026.587224518895],"5000m":[0.0008079992470730324,-3.3935897885437782,3563.2616780022654],"300m":[0.6999743364017235,-107.79032021608691,4149.692833384965],"200m":[2.2422237149162925,-204.01464451534775,4640.727341804304],"55mH":[13.198221547797402,-443.3395456766666,3722.9474163894774],"60mH":[11.16828188896136,-406.39148481091615,3696.9522386075114],"4x400m":[0.015620076884804046,-14.995086303404946,3598.7788204069657],"50mH":[16.212665326054548,-495.9578685610686,3792.827532194031],"400m":[0.3350059758445596,-73.6974469594461,4053.1545244171575],"Mile sh":[0.011540015186639607,-13.513232952897397,3955.963356088527],"600m":[0.1290024817337887,-46.439367295225566,4179.4139537496085],"10000m":[0.0001712000450308747,-1.5407985033832432,3466.7925173026015],"Hept.":[0.0000015806071811915508,0.17704089212065277,-43.84270064775592],"20,000mW":[0.000018699999291954365,-0.4936798059331515,3258.285541488556],"3000m sh":[0.002590000537161685,-6.215973858107134,3729.5683351015323],"800m sh":[0.05719995663858857,-30.201001015322618,3986.4574604244845],"Road 3kmW":[0.0009235372677025705,-3.4012984886514914,3131.6220206810976],"5000mW":[0.0003246000429020235,-2.0384849417822863,3200.416166438328],"4x200m sh":[0.0825999217407336,-35.02153700840836,3712.1957862451673],"50m":[33.046243452504314,-799.5823293340509,4836.413712938258],"500m":[0.1875992157997608,-54.58957565931178,3971.259245572466],"15,000mW":[0.000033869995586716106,-0.6627677511465961,3242.2582453516807],"Road 10 Miles":[0.000050161458530027705,-0.7928929030433878,3133.291096993169],"100m":[9.927426450685289,-436.6751262119069,4802.020943877404],"4x100m":[0.38950036063393156,-76.3380579665054,3740.3711316947592],"Road 15 km":[0.00005950169956620444,-0.8673501034970386,3160.8202295460505],"500m sh":[0.17139835836097816,-51.58928019804989,3881.97389184442],"10,000mW":[0.00007849989817173327,-1.0079383485714501,3235.480591699248],"35,000mW":[0.000004930000111613025,-0.25083835488906914,3190.663239908332],"Road 100 km":[8.73997733214654e-7,-0.10697653743886448,3273.457442281433],"400mH":[0.20856495718486912,-54.2249062108549,3524.488878249118],"HJ":[39.557908744493034,831.3655724464043,-601.5063267494843],"300m sh":[0.6595068053519668,-104.1948510278562,4115.419602857961],"4x400mix":[0.027319971572494772,-21.855722774421338,4371.091344809567],"Road 30kmW":[0.00000689002999299383,-0.2943343933311784,3143.4127356701356],"2 Miles":[0.0021569982582902714,-5.592213856668138,3624.5803229979647],"Pent. sh":[0.0000029452123778365286,0.24163567137421538,-42.43645722704241],"2000m SC":[0.003635987799696705,-6.777453730493733,3158.2797230951983],"PV":[3.9325797501069246,275.48968329946365,-205.1216924619548],"400m sh":[0.32239778088712256,-72.2140857003651,4043.8163995789655],"HT":[0.0030967239667614166,15.730166876520684,-22.699498543297523],"3000m SC":[0.0013229981350130343,-3.99544233512367,3016.5498521791887],"30,000mW":[0.000006890001039170008,-0.29434075898247514,3143.558449914548],"1500m":[0.01339999627048627,-14.471861176560651,3907.3655835949467],"4x400mix sh":[0.026880251011740075,-21.772687901858262,4408.906997824612],"JT":[0.004072274456476066,18.042616052881158,-18.842904339435336],"Road 50kmW":[0.000001990012802723643,-0.15665146940138275,3082.856899531209],"Road 30 km":[0.000011779975715341595,-0.3760051889530356,3000.427789900161],"55m":[27.69222698350768,-728.2024319005941,4786.948624048266],"4x200m":[0.07949854657189448,-33.70677533008393,3572.84874624628],"1500m sh":[0.013649954143477805,-14.741826462372728,3980.259331609617],"3000m":[0.0025389974609562604,-6.09357042856243,3656.127933666052],"LJ":[1.958114032649064,193.69548254413166,-233.98988652729167],"Road 5kmW":[0.0003247214016910971,-2.03870460612589,3199.987032004472],"Road 5 km":[0.0008086109772535849,-3.394979088225057,3563.519547606804],"3000mW":[0.0009230001724518933,-3.4003232245366064,3131.689052976566],"Road 15kmW":[0.00003387067634299081,-0.6627433846042905,3241.956113495311],"50,000mW":[0.0000019900000562662976,-0.15665278293489848,3082.9263533053163],"60m":[24.91177544269476,-697.4127036580539,4880.84062414919],"1000m sh":[0.034730273669098644,-23.643965410011788,4024.137096635415],"Road 35kmW":[0.00000492991338066893,-0.250830552043384,3190.5165854229563],"800m":[0.06879989341997295,-34.399261916380055,4299.822125108796],"1000m":[0.038199708533426247,-25.211487793783817,4159.840558573429],"Road 10kmW":[0.00007850131933358987,-1.0078686324185995,3234.987258339839],"DT":[0.0040284238096806035,17.94169538353276,-19.210748193687323],"100mH":[3.982296326194273,-238.8619577729478,3581.9054393060505],"4x400m sh":[0.015500027842040298,-15.003873478513015,3630.8991499322874],"Road 20 km":[0.000029561167921593728,-0.6002903493061389,3047.491516400696],"200m sh":[1.9617476310046413,-186.35304547847045,4425.540362004947],"Road Marathon":[0.000005389966906974475,-0.25224574933865895,2951.2162982728405],"2000m":[0.006766010458436056,-10.148946030704451,3805.8288250550686],"5000m sh":[0.00082499992965758,-3.464991324219369,3638.23229190876],"Mile":[0.011649998601839462,-13.513881163102496,3918.992004961794],"2000m sh":[0.006849999624836789,-10.305069946577078,3875.710937557713],"SP":[0.046214387641356325,60.75503111383068,-25.931941888942674],"Road 10 km":[0.00017119892280619345,-1.540623663798911,3466.0215817096905],"Road 25 km":[0.000017820078937803765,-0.4640160886376883,3020.6229502419883],"600m sh":[0.10630096102938147,-40.4675585171226,3851.3911703779886],"2 Miles sh":[0.0022019917299053726,-5.708869030298274,3700.1929170416843],"Road Mile":[0.011649998601839462,-13.513881163102496,3918.992004961794]}},"menBlocked":["Hept. sh","Dec.","110mH"],"womenBlocked":["Pent. sh","100mH","Hept."]},"maxPoints":1400,"version":"Retained fits; men's 50mH/110mH refit against 23 April 2025 tables. Approximation, not exact table lookup."},"sources":[{"title":"Canonical HTTP binding at the documented implementation revision","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/calculator-functions.ts","note":"Existing calculation handler; math metadata is additive."},{"title":"lib/formulas/wa-points.ts","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/formulas/wa-points.ts","note":"Primary implementation source for these equations/tables, not a claim of scientific calibration."},{"title":"World Athletics scoring tables, 2025 edition (updated 23 Apr 2025)","url":"https://worldathletics.org/download/download?filename=4f77dcb3-2945-4c58-ad8b-955a999b13e8.pdf&urlslug=World+Athletics+Scoring+Tables+of+Athletics","note":"2025 edition, updated 23 April 2025. Stored fits approximate the table; not a certified lookup."}]},"annotations":{"readOnlyHint":true,"consequentialHint":false},"name":"World Athletics Points Calculator","description":"This World Athletics points calculator converts athletics marks to points and points back to marks using fitted scoring-table equations for common indoor, outdoor, road, race walk, relay, and field events.","category":"Conversions & Adjustments","method":"POST","endpoint":"/api/calculators/world-athletics-points-calculator","page":"/calculators/world-athletics-points-calculator","inputSchema":{"type":"object","required":["category","gender","event"],"properties":{"category":{"type":"string","description":"World Athletics category.","enum":["outdoor","indoor"],"default":"outdoor"},"gender":{"type":"string","description":"Gender table.","enum":["men","women"],"default":"men"},"event":{"type":"string","description":"World Athletics event key, such as 100m, 800m, SP, or LJ."},"mark":{"type":"string","description":"Mark to convert to points. Time marks may be SS.xx, M:SS.xx, or H:MM:SS.xx."},"points":{"type":"string","description":"Points to reverse-convert to a mark."}}},"example":{"category":"outdoor","gender":"men","event":"100m","mark":"10.00"}},{"slug":"wind-correction-calculator","math":{"href":"https://www.tracktoolspro.com/api/calculators/wind-correction-calculator","jsonPointer":"/calculator/math","version":"2026-10-21.1","implementationVersion":"b5a8aca7b85361476e0321a08b7fa5f516fc9535","scope":"Canonical HTTP function and documented corresponding mounted-form math. This is public inspectable documentation, not access control or independent empirical validation.","unitNotation":"Input paths use [] and *; output paths are JSON Pointers with * (one segment) and ** (descendants). Empty output path denotes scalar result. Units apply to numeric quantities or explicitly described numeric strings; labels/statuses/booleans are dimensionless. More specific units, including count/index exceptions, override broad patterns.","interfaceNotes":["HTTP input is described by the adjacent inputSchema. The original handlers may accept numeric strings; this metadata adds no validation.","Mounted forms accept displayed clock/unit strings and enforce their own limits. Mounted tools limit strings to 200 characters and numeric parts to magnitude 1000000. Do not assume mounted/API input interchangeability.","Some legacy extreme/invalid tuples can produce null/empty results or nonfinite numbers serialized as null. Those are unavailable answers, not exact numerical predictions. Per-calculator domain describes the intended mathematical inputs."],"kind":"empirical-model","implementationFiles":["lib/formulas/track-utilities.ts"],"equations":["benefit=c0*wind+c1*wind*mark+c2*wind^2, from the selected canonical coefficient row.","Track: neutral=mark+benefit (seconds). Horizontal jumps: neutral=mark-benefit (meters).","100m legal(+2) mark=(neutral-2*c0-4*c2)/(1+2*c1). Other rows: legal=2*neutral-correctWind(event,neutral,2); their c1=0 makes this the additive inverse."],"inputUnits":{"event":"enum/string (dimensionless)","mark":"s for track, m for jumps","wind":"m/s (positive tailwind)"},"outputUnits":{"/neutral":"s or m per unit","/legal":"s or m per unit"},"domain":["Positive finite mark and finite wind in a supported event; invalid scenarios return {neutral:null,legal:null,unit}."],"rounding":["Raw IEEE-754 numbers; the mounted page formats clocks separately."],"assumptions":["Uses the entered values and the selected convention; this documentation does not strengthen existing validation."],"limitations":["Scenario at+2m/s is not a legal-mark certification. Empirical coefficients, not exact aerodynamics."],"mountedPageNotes":[],"workedExamples":[{"input":{"event":"100m","mark":9.58,"wind":0.9},"expected":{"/neutral":9.617743498,"/legal":9.543794003050294},"absoluteTolerance":1e-8,"note":"Illustrative canonical-handler result; not independent validation of an empirical model."}],"constantsAndTables":{"coefficients":{"100m":[-0.0449,0.009459,-0.0042],"200m":[0.09,0,-0.01],"100mH":[0.093,0,-0.01],"110mH":[0.093,0,-0.01],"Long Jump":[0.029,0,0],"Triple Jump":[0.069,0,-0.009]},"coefficientOrder":["c0","c1","c2"],"scenarioWindMetersPerSecond":2},"sources":[{"title":"Canonical HTTP binding at the documented implementation revision","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/calculator-functions.ts","note":"Existing calculation handler; math metadata is additive."},{"title":"lib/formulas/track-utilities.ts","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/formulas/track-utilities.ts","note":"Primary implementation source for these equations/tables, not a claim of scientific calibration."},{"title":"Moinat, Fabius & Emanuel, 2018","url":"https://onlinelibrary.wiley.com/doi/full/10.1080/17461391.2018.1480062","note":"Moinat, Fabius, Emanuel 2018 empirical wind model. Does not validate the separate practice-split 100m regression."}]},"annotations":{"readOnlyHint":true,"consequentialHint":false},"name":"Wind Correction Calculator","description":"This wind correction calculator adjusts sprint, hurdle, long jump, and triple jump marks for wind using event-specific coefficients. Convert a recorded mark to neutral +0.0 m/s and estimated legal +2.0 m/s conditions.","category":"Sprints & Hurdles","method":"POST","endpoint":"/api/calculators/wind-correction-calculator","page":"/calculators/wind-correction-calculator","inputSchema":{"type":"object","required":["event","mark","wind"],"properties":{"event":{"type":"string","description":"Event name.","enum":["100m","200m","100mH","110mH","Long Jump","Triple Jump"],"default":"100m"},"mark":{"type":"number","description":"Recorded time in seconds or jump mark in meters.","minimum":0},"wind":{"type":"number","description":"Wind in m/s. Positive is tailwind."}}},"example":{"event":"100m","mark":9.58,"wind":0.9}},{"slug":"fat-hand-time-converter","math":{"href":"https://www.tracktoolspro.com/api/calculators/fat-hand-time-converter","jsonPointer":"/calculator/math","version":"2026-10-21.1","implementationVersion":"b5a8aca7b85361476e0321a08b7fa5f516fc9535","scope":"Canonical HTTP function and documented corresponding mounted-form math. This is public inspectable documentation, not access control or independent empirical validation.","unitNotation":"Input paths use [] and *; output paths are JSON Pointers with * (one segment) and ** (descendants). Empty output path denotes scalar result. Units apply to numeric quantities or explicitly described numeric strings; labels/statuses/booleans are dimensionless. More specific units, including count/index exceptions, override broad patterns.","interfaceNotes":["HTTP input is described by the adjacent inputSchema. The original handlers may accept numeric strings; this metadata adds no validation.","Mounted forms accept displayed clock/unit strings and enforce their own limits. Mounted tools limit strings to 200 characters and numeric parts to magnitude 1000000. Do not assume mounted/API input interchangeability.","Some legacy extreme/invalid tuples can produce null/empty results or nonfinite numbers serialized as null. Those are unavailable answers, not exact numerical predictions. Per-calculator domain describes the intended mathematical inputs."],"kind":"rule-convention","implementationFiles":["lib/formulas/fat-hand-time.ts"],"equations":["NFHS offset=0.24s for all retained categories; WA combined offsets: sprint(<400m)=0.24, middle(400m)=0.14, long(>400m)=0.","handToFat: upward round manual time to the next tenth only if not already exactly at a tenth, then add offset and round nearest hundredth. fatToHand: subtract offset, then round nearest hundredth."],"inputUnits":{"timeSeconds":"s","direction":"enum/string (dimensionless)","eventCategory":"enum/string (dimensionless)","convention":"enum/string (dimensionless)"},"outputUnits":{"/originalTime":"s","/convertedTime":"s","/factor":"s","/roundedHandTime":"s"},"domain":["Positive finite input and positive converted result; otherwise null. convention defaults to nfhs."],"rounding":["Forward manual ceil-to-tenth with binary guard, then Math.round(x*100)/100. Reverse only nearest0.01."],"assumptions":["Uses the entered values and the selected convention; this documentation does not strengthen existing validation."],"limitations":["Reverse is an estimate: it cannot recover the original manual reading after upward rounding. These named conventions are not universal record conversions."],"mountedPageNotes":[],"workedExamples":[{"input":{"timeSeconds":10.8,"direction":"handToFat","eventCategory":"sprint"},"expected":{"/convertedTime":11.04},"absoluteTolerance":1e-8,"note":"Illustrative canonical-handler result; not independent validation of an empirical model."}],"constantsAndTables":{"nfhsOffsetSeconds":0.24,"waCombinedOffsetsSeconds":{"sprint":0.24,"middle":0.14,"long":0}},"sources":[{"title":"Canonical HTTP binding at the documented implementation revision","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/calculator-functions.ts","note":"Existing calculation handler; math metadata is additive."},{"title":"lib/formulas/fat-hand-time.ts","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/formulas/fat-hand-time.ts","note":"Primary implementation source for these equations/tables, not a claim of scientific calibration."},{"title":"NFHS: Converting Times—Manual to FAT and English to Metric, 18 Dec 2014","url":"https://www.nfhs.org/resources/sports/converting-times-manual-to-fat-and-from-english-to-metric-distances","note":"Public NFHS conversion convention reference, not a claim that every governing body applies it."},{"title":"World Athletics / IAAF Combined Events Scoring Tables","url":"https://worldathletics.org/download/download?filename=53f7d332-be0c-434c-8467-1d9078966147.pdf&urlslug=IAAF+Scoring+Tables+for+Combined+Events","note":"1984 combined-event coefficient system; formula units and event-wise floor. Distinct from general 2025 athletics points."}]},"annotations":{"readOnlyHint":true,"consequentialHint":false},"name":"FAT vs Hand Time Converter","description":"Compare Fully Automatic Timing (FAT) and manual times using explicitly named NFHS seeding or World Athletics combined-event conventions. Forward conversion rounds manual times upward; reverse conversion is an estimate.","category":"Conversions & Adjustments","method":"POST","endpoint":"/api/calculators/fat-hand-time-converter","page":"/calculators/fat-hand-time-converter","inputSchema":{"type":"object","required":["timeSeconds","direction","eventCategory"],"properties":{"timeSeconds":{"type":"number","description":"Input time in seconds.","minimum":0},"direction":{"type":"string","description":"Convert hand time to FAT or FAT to hand.","enum":["handToFat","fatToHand"],"default":"handToFat"},"eventCategory":{"type":"string","description":"WA combined-event group: sprint below400m, middle400m, long above400m. NFHS uses0.24 for every group.","enum":["sprint","middle","long"],"default":"sprint"},"convention":{"type":"string","description":"Named conversion convention; reverse subtraction is an estimate, not recovered manual timing.","enum":["nfhs","waCombined"],"default":"nfhs"}}},"example":{"timeSeconds":10.8,"direction":"handToFat","eventCategory":"sprint"}},{"slug":"xc-team-score-calculator","math":{"href":"https://www.tracktoolspro.com/api/calculators/xc-team-score-calculator","jsonPointer":"/calculator/math","version":"2026-10-21.1","implementationVersion":"b5a8aca7b85361476e0321a08b7fa5f516fc9535","scope":"Canonical HTTP function and documented corresponding mounted-form math. This is public inspectable documentation, not access control or independent empirical validation.","unitNotation":"Input paths use [] and *; output paths are JSON Pointers with * (one segment) and ** (descendants). Empty output path denotes scalar result. Units apply to numeric quantities or explicitly described numeric strings; labels/statuses/booleans are dimensionless. More specific units, including count/index exceptions, override broad patterns.","interfaceNotes":["HTTP input is described by the adjacent inputSchema. The original handlers may accept numeric strings; this metadata adds no validation.","Mounted forms accept displayed clock/unit strings and enforce their own limits. Mounted tools limit strings to 200 characters and numeric parts to magnitude 1000000. Do not assume mounted/API input interchangeability.","Some legacy extreme/invalid tuples can produce null/empty results or nonfinite numbers serialized as null. Those are unavailable answers, not exact numerical predictions. Per-calculator domain describes the intended mathematical inputs."],"kind":"scoring-algorithm","implementationFiles":["lib/formulas/xc-scoring.ts"],"equations":["Validate distinct positive scoring places, skip completely blank rows, sort by adjusted place; first 5 score and rows 6/7 are listed displacers. teamScore=sum(first 5 places).","When all 5 scorer clocks exist: packTime=fifth-first; averageTime=sum(first 5 times)/5. Editorial pack thresholds <=30/60/90/120s, then Spread Out."],"inputUnits":{"runners[].place":"adjusted whole scoring place","runners[].time":"M:SS clock (s)"},"outputUnits":{"/teamScore":"points (place sum)","/scoringRunners/*/position":"dimensionless index/count","/scoringRunners/*/place":"scoring place","/scoringRunners/*/time":"s","/displacers/*/position":"dimensionless index/count","/displacers/*/place":"scoring place","/displacers/*/time":"s","/packTime":"s","/averageTime":"s"},"domain":["At least 5 distinct places, optional strict positive M:SS clocks, monotonic times by place and safe numeric totals; invalid collection returns null. Missing scorer clocks leave pack statistics null."],"rounding":["Raw IEEE-754 numbers; the mounted page formats clocks separately."],"assumptions":["Uses the entered values and the selected convention; this documentation does not strengthen existing validation."],"limitations":["One already-adjusted team, not complete meet scoring. Does not remove incomplete teams, resolve opponent displacement, dead heats or team ties. Pack labels are editorial."],"mountedPageNotes":[],"workedExamples":[{"input":{"runners":[{"place":"1","time":"15:10"},{"place":"5","time":"15:40"},{"place":"10","time":"16:05"},{"place":"16","time":"16:30"},{"place":"22","time":"16:50"}]},"expected":{"/teamScore":54,"/packTime":100},"absoluteTolerance":1e-8,"note":"Illustrative canonical-handler result; not independent validation of an empirical model."}],"constantsAndTables":{"scorers":5,"listedDisplacers":2,"packThresholdsSeconds":[30,60,90,120]},"sources":[{"title":"Canonical HTTP binding at the documented implementation revision","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/calculator-functions.ts","note":"Existing calculation handler; math metadata is additive."},{"title":"lib/formulas/xc-scoring.ts","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/formulas/xc-scoring.ts","note":"Primary implementation source for these equations/tables, not a claim of scientific calibration."}]},"annotations":{"readOnlyHint":true,"consequentialHint":false},"name":"XC Team Score Calculator","description":"Calculate one cross country team’s score from already-adjusted scoring places. Read the first-five time spread and mean, and list sixth and seventh runners. Full meet exclusions, opponent displacement, dead heats and team tiebreaks require the applicable meet rules and results.","category":"Cross Country","method":"POST","endpoint":"/api/calculators/xc-team-score-calculator","page":"/calculators/xc-team-score-calculator","inputSchema":{"type":"object","required":["runners"],"properties":{"runners":{"type":"array","description":"Runner rows with place and optional MM:SS time.","items":{"type":"object","description":"Runner input.","required":["place"],"properties":{"place":{"type":"string","description":"Finishing place."},"time":{"type":"string","description":"Optional race time as MM:SS.s."}}}}}},"example":{"runners":[{"place":"1","time":"15:10"},{"place":"5","time":"15:40"},{"place":"10","time":"16:05"},{"place":"16","time":"16:30"},{"place":"22","time":"16:50"}]}},{"slug":"vo2-max-estimator","math":{"href":"https://www.tracktoolspro.com/api/calculators/vo2-max-estimator","jsonPointer":"/calculator/math","version":"2026-10-21.1","implementationVersion":"b5a8aca7b85361476e0321a08b7fa5f516fc9535","scope":"Canonical HTTP function and documented corresponding mounted-form math. This is public inspectable documentation, not access control or independent empirical validation.","unitNotation":"Input paths use [] and *; output paths are JSON Pointers with * (one segment) and ** (descendants). Empty output path denotes scalar result. Units apply to numeric quantities or explicitly described numeric strings; labels/statuses/booleans are dimensionless. More specific units, including count/index exceptions, override broad patterns.","interfaceNotes":["HTTP input is described by the adjacent inputSchema. The original handlers may accept numeric strings; this metadata adds no validation.","Mounted forms accept displayed clock/unit strings and enforce their own limits. Mounted tools limit strings to 200 characters and numeric parts to magnitude 1000000. Do not assume mounted/API input interchangeability.","Some legacy extreme/invalid tuples can produce null/empty results or nonfinite numbers serialized as null. Those are unavailable answers, not exact numerical predictions. Per-calculator domain describes the intended mathematical inputs."],"kind":"empirical-model","implementationFiles":["lib/formulas/vdot.ts"],"equations":["t=timeSeconds/60 (minutes); v=distanceMeters/t (m/min).","fraction(t)=0.8+0.1894393*exp(-0.012778*t)+0.2989558*exp(-0.1932605*t); oxygen(v)=-4.6+0.182258*v+0.000104*v^2; VDOT=oxygen(v)/fraction(t).","vo2max=round(VDOT*10)/10; classification is selected from the canonical gender bands using UNROUNDED VDOT.","equivalentTimes[j].time=timeSeconds*(targetDistanceMeters/distanceMeters)^1.06 (separate Riegel predictions, not VDOT inversion)."],"inputUnits":{"distanceMeters":"m","timeSeconds":"s","gender":"enum/string (dimensionless)"},"outputUnits":{"/vo2max":"VDOT performance index (conventional oxygen-cost scale)","/classification/min":"VDOT index threshold","/equivalentTimes/*/value":"m","/equivalentTimes/*/time":"s"},"domain":["Positive race distance/time and 10<=rawVDOT<=100; otherwise null."],"rounding":["VDOT field rounds to 0.1; comparisons are raw seconds; classification uses pre-round value."],"assumptions":["Uses the entered values and the selected convention; this documentation does not strengthen existing validation."],"limitations":["Race-derived index, not measured VO2max. Classification ignores age and individual physiology. No personalized training paces are returned."],"mountedPageNotes":[],"workedExamples":[{"input":{"distanceMeters":5000,"timeSeconds":1200,"gender":"male"},"expected":{"/vo2max":49.8},"absoluteTolerance":1e-8,"note":"Illustrative canonical-handler result; not independent validation of an empirical model."}],"constantsAndTables":{"classificationBands":{"male":[{"min":60,"label":"Elite","color":"success"},{"min":52,"label":"Excellent","color":"primary"},{"min":47,"label":"Good","color":"info"},{"min":42,"label":"Above Average","color":"info"},{"min":37,"label":"Average","color":"warning"},{"min":30,"label":"Below Average","color":"warning"},{"min":0,"label":"Poor","color":"error"}],"female":[{"min":54,"label":"Elite","color":"success"},{"min":47,"label":"Excellent","color":"primary"},{"min":42,"label":"Good","color":"info"},{"min":37,"label":"Above Average","color":"info"},{"min":32,"label":"Average","color":"warning"},{"min":25,"label":"Below Average","color":"warning"},{"min":0,"label":"Poor","color":"error"}]},"riegelExponent":1.06},"sources":[{"title":"Canonical HTTP binding at the documented implementation revision","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/calculator-functions.ts","note":"Existing calculation handler; math metadata is additive."},{"title":"lib/formulas/vdot.ts","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/formulas/vdot.ts","note":"Primary implementation source for these equations/tables, not a claim of scientific calibration."},{"title":"VDOT creator’s FAQ","url":"https://support.vdoto2.com/v-o2-faq/","note":"First-party explanation distinguishes VDOT from measured VO2max. Equation coefficients are documented from the canonical implementation, not derived from this FAQ. FAQ rechecked 2026-10-21."},{"title":"Riegel, Athletic Records and Human Endurance,1981","url":"https://rrtc.net/Articles/ARHE.pdf","note":"Riegel 1981 primary article; fitted exponents vary. Product default 1.06 is an explicit convention, not a universal accuracy claim. Retained source reviewed 2026-10-16."}]},"annotations":{"readOnlyHint":true,"consequentialHint":false},"name":"VO2 Max Estimator","description":"Estimate a race-derived VDOT fitness index, read its fitness classification, and compare Riegel-predicted race times. This is not a measured VO2 max or a personalized training-pace prescription.","category":"Training & Fitness","method":"POST","endpoint":"/api/calculators/vo2-max-estimator","page":"/calculators/vo2-max-estimator","inputSchema":{"type":"object","required":["distanceMeters","timeSeconds"],"properties":{"distanceMeters":{"type":"number","description":"Race distance in meters.","minimum":0},"timeSeconds":{"type":"number","description":"Race time in seconds.","minimum":0},"gender":{"type":"string","description":"Classification table.","enum":["male","female"],"default":"male"}}},"example":{"distanceMeters":5000,"timeSeconds":1200,"gender":"male"}},{"slug":"throws-distance-calculator","math":{"href":"https://www.tracktoolspro.com/api/calculators/throws-distance-calculator","jsonPointer":"/calculator/math","version":"2026-10-21.1","implementationVersion":"b5a8aca7b85361476e0321a08b7fa5f516fc9535","scope":"Canonical HTTP function and documented corresponding mounted-form math. This is public inspectable documentation, not access control or independent empirical validation.","unitNotation":"Input paths use [] and *; output paths are JSON Pointers with * (one segment) and ** (descendants). Empty output path denotes scalar result. Units apply to numeric quantities or explicitly described numeric strings; labels/statuses/booleans are dimensionless. More specific units, including count/index exceptions, override broad patterns.","interfaceNotes":["HTTP input is described by the adjacent inputSchema. The original handlers may accept numeric strings; this metadata adds no validation.","Mounted forms accept displayed clock/unit strings and enforce their own limits. Mounted tools limit strings to 200 characters and numeric parts to magnitude 1000000. Do not assume mounted/API input interchangeability.","Some legacy extreme/invalid tuples can produce null/empty results or nonfinite numbers serialized as null. Those are unavailable answers, not exact numerical predictions. Per-calculator domain describes the intended mathematical inputs."],"kind":"idealized-physics","implementationFiles":["lib/formulas/projectile.ts"],"equations":["theta=angleDeg*pi/180; vx=velocity*cos(theta); vy=velocity*sin(theta); t=(vy+sqrt(vy^2+2*g*releaseHeight))/g.","distance=vx*t; maxHeight=releaseHeight+vy^2/(2*g); optimalAngle=atan(velocity/sqrt(velocity^2+2*g*releaseHeight))*180/pi (zero velocity convention:0).","optimalDistance=projectileDistance at optimalAngle; distanceDiff=optimalDistance-distance, using raw ranges before rounding."],"inputUnits":{"velocity":"m/s","angleDeg":"degree","releaseHeight":"m"},"outputUnits":{"/distance":"m","/timeOfFlight":"s","/maxHeight":"m","/optimalAngle":"degree","/optimalDistance":"m","/distanceDiff":"m"},"domain":["API finite velocity/height>=0, angle0..90deg."],"rounding":["Distances/time0.01; optimalAngle0.1degree; Math.round."],"assumptions":["Uses the entered values and the selected convention; this documentation does not strengthen existing validation."],"limitations":["Ideal gravity-only point projectile. No drag, lift, spin, landing geometry or release-speed/angle coupling; not a prediction of official implement distance."],"mountedPageNotes":[],"workedExamples":[{"input":{"velocity":14,"angleDeg":38,"releaseHeight":2},"expected":{"/distance":21.68,"/optimalAngle":42.4},"absoluteTolerance":1e-8,"note":"Illustrative canonical-handler result; not independent validation of an empirical model."}],"constantsAndTables":{"gravityMetersPerSecondSquared":9.81},"sources":[{"title":"Canonical HTTP binding at the documented implementation revision","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/calculator-functions.ts","note":"Existing calculation handler; math metadata is additive."},{"title":"lib/formulas/projectile.ts","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/formulas/projectile.ts","note":"Primary implementation source for these equations/tables, not a claim of scientific calibration."}]},"annotations":{"readOnlyHint":true,"consequentialHint":false},"name":"Throws Distance Calculator","description":"Physics-based calculator for shot put, discus, javelin, and hammer throw. Analyze release angle, velocity, and height to optimize throwing technique and calculate potential distance gains.","category":"Field Events","method":"POST","endpoint":"/api/calculators/throws-distance-calculator","page":"/calculators/throws-distance-calculator","inputSchema":{"type":"object","required":["velocity","angleDeg","releaseHeight"],"properties":{"velocity":{"type":"number","description":"Release velocity in meters per second.","minimum":0},"angleDeg":{"type":"number","description":"Release angle in degrees.","minimum":0,"maximum":90},"releaseHeight":{"type":"number","description":"Release height above landing surface in meters.","minimum":0}}},"example":{"velocity":14,"angleDeg":38,"releaseHeight":2}},{"slug":"hurdle-spacing-calculator","math":{"href":"https://www.tracktoolspro.com/api/calculators/hurdle-spacing-calculator","jsonPointer":"/calculator/math","version":"2026-10-21.1","implementationVersion":"b5a8aca7b85361476e0321a08b7fa5f516fc9535","scope":"Canonical HTTP function and documented corresponding mounted-form math. This is public inspectable documentation, not access control or independent empirical validation.","unitNotation":"Input paths use [] and *; output paths are JSON Pointers with * (one segment) and ** (descendants). Empty output path denotes scalar result. Units apply to numeric quantities or explicitly described numeric strings; labels/statuses/booleans are dimensionless. More specific units, including count/index exceptions, override broad patterns.","interfaceNotes":["HTTP input is described by the adjacent inputSchema. The original handlers may accept numeric strings; this metadata adds no validation.","Mounted forms accept displayed clock/unit strings and enforce their own limits. Mounted tools limit strings to 200 characters and numeric parts to magnitude 1000000. Do not assume mounted/API input interchangeability.","Some legacy extreme/invalid tuples can produce null/empty results or nonfinite numbers serialized as null. Those are unavailable answers, not exact numerical predictions. Per-calculator domain describes the intended mathematical inputs."],"kind":"lookup-and-arithmetic","implementationFiles":["lib/formulas/hurdles.ts"],"equations":["requiredStrideToFirst=spec.startToFirst/stepsToFirst; requiredStrideBetween=spec.betweenHurdles/stepsBetween.","If entered strideLength>0, checkMarks[i]=strideLength*i for i=1,2,3; stride differences subtract the RAW gap/step averages, then round."],"inputUnits":{"eventKey":"enum/string (dimensionless)","strideLength":"m","stepsToFirst":"step count","stepsBetween":"step count"},"outputUnits":{"/specs/totalDistance":"m","/specs/startToFirst":"m","/specs/betweenHurdles":"m","/specs/lastToFinish":"m","/specs/numHurdles":"dimensionless index/count","/specs/heights/*/meters":"m","/specs/heights/*/inches":"in","/specs/defaultStepsToFirst":"dimensionless index/count","/specs/defaultStepsBetween":"dimensionless index/count","/requiredStrideToFirst":"m/step","/requiredStrideBetween":"m/rhythm unit","/checkMarks/*/distance":"m","/athleteStride":"m","/strideDiffFirst":"m","/strideDiffBetween":"m"},"domain":["Known event; API whole step counts positive, optional complete nonnegative stride string; blank/zero stride means unspecified."],"rounding":["Average stride/differences0.01m; check-mark multiples retain raw multiplication."],"assumptions":["Uses the entered values and the selected convention; this documentation does not strengthen existing validation."],"limitations":["Spacing per rhythm unit includes flight; it is not a measured ground stride. Retained US HS300mH has8hurdles, WA300mH has7; check local age/state rules."],"mountedPageNotes":[],"workedExamples":[{"input":{"eventKey":"110mH","strideLength":"1.9"},"expected":{"/requiredStrideBetween":3.05},"absoluteTolerance":1e-8,"note":"Illustrative canonical-handler result; not independent validation of an empirical model."}],"constantsAndTables":{"layouts":{"110mH":{"label":"110m Hurdles (Men)","totalDistance":110,"startToFirst":13.72,"betweenHurdles":9.14,"lastToFinish":14.02,"numHurdles":10,"heights":[{"group":"Men","meters":1.067,"inches":42}],"defaultStepsToFirst":8,"defaultStepsBetween":3},"100mH":{"label":"100m Hurdles (Women)","totalDistance":100,"startToFirst":13,"betweenHurdles":8.5,"lastToFinish":10.5,"numHurdles":10,"heights":[{"group":"Women","meters":0.838,"inches":33}],"defaultStepsToFirst":8,"defaultStepsBetween":3},"400mH":{"label":"400m Hurdles","totalDistance":400,"startToFirst":45,"betweenHurdles":35,"lastToFinish":40,"numHurdles":10,"heights":[{"group":"Men","meters":0.914,"inches":36},{"group":"Women","meters":0.762,"inches":30}],"defaultStepsToFirst":22,"defaultStepsBetween":15},"300mH":{"label":"300m Hurdles (HS)","totalDistance":300,"startToFirst":45,"betweenHurdles":35,"lastToFinish":10,"numHurdles":8,"heights":[{"group":"Boys","meters":0.914,"inches":36},{"group":"Girls","meters":0.762,"inches":30}],"defaultStepsToFirst":22,"defaultStepsBetween":15}},"references":"WA layouts plus retained NFHS-style 8-hurdle 300m layout; verify governing rules."},"sources":[{"title":"Canonical HTTP binding at the documented implementation revision","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/calculator-functions.ts","note":"Existing calculation handler; math metadata is additive."},{"title":"lib/formulas/hurdles.ts","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/formulas/hurdles.ts","note":"Primary implementation source for these equations/tables, not a claim of scientific calibration."},{"title":"NFHS 2021 Track and Field Pre-Meet Notes","url":"https://assets.nfhs.org/umbraco/media/4295114/nfhs-track-and-field-pre-meet-notes_1-2021.pdf","note":"Public 2021pre-meet notes support retained US HS 300m 8-hurdle layout. Not a claim of obtaining the current paid rulebook."}]},"annotations":{"readOnlyHint":true,"consequentialHint":false},"name":"Hurdle Spacing Calculator","description":"Calculate steps to first hurdle, steps between hurdles, and check mark distances for 100mH, 110mH, 300mH, and 400mH events. Includes official specifications and personalized stride analysis.","category":"Sprints & Hurdles","method":"POST","endpoint":"/api/calculators/hurdle-spacing-calculator","page":"/calculators/hurdle-spacing-calculator","inputSchema":{"type":"object","required":["eventKey"],"properties":{"eventKey":{"type":"string","description":"Hurdle event key.","enum":["110mH","100mH","400mH","300mH"],"default":"110mH"},"strideLength":{"type":"string","description":"Optional athlete stride length in meters."},"stepsToFirst":{"type":"integer","description":"Steps from start to first hurdle. Defaults to event standard."},"stepsBetween":{"type":"integer","description":"Steps between hurdles. Defaults to event standard."}}},"example":{"eventKey":"110mH","strideLength":"1.9"}},{"slug":"heart-rate-zone-calculator","math":{"href":"https://www.tracktoolspro.com/api/calculators/heart-rate-zone-calculator","jsonPointer":"/calculator/math","version":"2026-10-21.1","implementationVersion":"b5a8aca7b85361476e0321a08b7fa5f516fc9535","scope":"Canonical HTTP function and documented corresponding mounted-form math. This is public inspectable documentation, not access control or independent empirical validation.","unitNotation":"Input paths use [] and *; output paths are JSON Pointers with * (one segment) and ** (descendants). Empty output path denotes scalar result. Units apply to numeric quantities or explicitly described numeric strings; labels/statuses/booleans are dimensionless. More specific units, including count/index exceptions, override broad patterns.","interfaceNotes":["HTTP input is described by the adjacent inputSchema. The original handlers may accept numeric strings; this metadata adds no validation.","Mounted forms accept displayed clock/unit strings and enforce their own limits. Mounted tools limit strings to 200 characters and numeric parts to magnitude 1000000. Do not assume mounted/API input interchangeability.","Some legacy extreme/invalid tuples can produce null/empty results or nonfinite numbers serialized as null. Those are unavailable answers, not exact numerical predictions. Per-calculator domain describes the intended mathematical inputs."],"kind":"percentage-model","implementationFiles":["lib/formulas/heart-rate.ts"],"equations":["maxHR: BPM=round(maxHR*pct/100). Karvonen: BPM=round(restingHR+(maxHR-restingHR)*pct/100). threshold: BPM=round(thresholdHR*pct/100).","Apply each selected canonical zone min/max percentage; shared endpoints are inclusive displayed boundaries, not a disjoint time-in-zone classifier."],"inputUnits":{"method":"enum/string (dimensionless)","maxHR":"bpm","restingHR":"bpm","thresholdHR":"bpm"},"outputUnits":{"/*/zone":"dimensionless index/count","/*/min":"%","/*/max":"%","/*/minBPM":"bpm","/*/maxBPM":"bpm"},"domain":["maxHR100..220; restingHR30..100 for Karvonen; thresholdHR100..200 for threshold. Invalid method inputs yield null."],"rounding":["Nearest whole bpm with Math.round."],"assumptions":["Uses the entered values and the selected convention; this documentation does not strengthen existing validation."],"limitations":["Conventional coaching bands, not measured lactate thresholds or individualized physiology. No weekly distribution recommendation."],"mountedPageNotes":[],"workedExamples":[{"input":{"method":"maxHR","maxHR":190},"expected":{"/0/minBPM":95,"/4/maxBPM":190},"absoluteTolerance":1e-8,"note":"Illustrative canonical-handler result; not independent validation of an empirical model."}],"constantsAndTables":{"zonePercentageTables":{"maxHR":[{"zone":1,"name":"Recovery","min":50,"max":60,"color":"#4CAF50","purpose":"Active recovery, warm-up"},{"zone":2,"name":"Aerobic Base","min":60,"max":70,"color":"#8BC34A","purpose":"Base building, fat burning"},{"zone":3,"name":"Tempo","min":70,"max":80,"color":"#FFC107","purpose":"Aerobic endurance"},{"zone":4,"name":"Threshold","min":80,"max":90,"color":"#FF9800","purpose":"Lactate threshold work"},{"zone":5,"name":"VO2 Max","min":90,"max":100,"color":"#F44336","purpose":"Maximum performance"}],"karvonen":[{"zone":1,"name":"Recovery","min":50,"max":60,"color":"#4CAF50","purpose":"Active recovery, warm-up"},{"zone":2,"name":"Aerobic Base","min":60,"max":70,"color":"#8BC34A","purpose":"Base building, endurance"},{"zone":3,"name":"Tempo","min":70,"max":80,"color":"#FFC107","purpose":"Aerobic fitness"},{"zone":4,"name":"Threshold","min":80,"max":90,"color":"#FF9800","purpose":"Lactate threshold"},{"zone":5,"name":"VO2 Max","min":90,"max":100,"color":"#F44336","purpose":"Maximum effort"}],"threshold":[{"zone":1,"name":"Recovery","min":65,"max":75,"color":"#4CAF50","purpose":"Easy running, recovery"},{"zone":2,"name":"Aerobic","min":75,"max":85,"color":"#8BC34A","purpose":"Base building"},{"zone":3,"name":"Tempo","min":85,"max":92,"color":"#FFC107","purpose":"Tempo runs, steady state"},{"zone":4,"name":"SubThreshold","min":92,"max":98,"color":"#FF9800","purpose":"Threshold workouts"},{"zone":5,"name":"VO2 Max","min":98,"max":105,"color":"#F44336","purpose":"Intervals, racing"}]}},"sources":[{"title":"Canonical HTTP binding at the documented implementation revision","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/calculator-functions.ts","note":"Existing calculation handler; math metadata is additive."},{"title":"lib/formulas/heart-rate.ts","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/formulas/heart-rate.ts","note":"Primary implementation source for these equations/tables, not a claim of scientific calibration."},{"title":"Karvonen et al., 1957","url":"https://pubmed.ncbi.nlm.nih.gov/13470504/","note":"Karvonen 1957 bibliographic reference. Does not establish the product five-zone cutoffs; no new full-text verification claim."}]},"annotations":{"readOnlyHint":true,"consequentialHint":false},"name":"Heart Rate Zone Calculator","description":"Calculate five heart rate bands in bpm using percentage of max HR, Karvonen heart rate reserve, or threshold percentages. These percentage-derived bands do not prescribe a weekly training distribution.","category":"Training & Fitness","method":"POST","endpoint":"/api/calculators/heart-rate-zone-calculator","page":"/calculators/heart-rate-zone-calculator","inputSchema":{"type":"object","required":["method"],"properties":{"method":{"type":"string","description":"Zone method.","enum":["maxHR","karvonen","threshold"],"default":"maxHR"},"maxHR":{"type":"integer","description":"Maximum heart rate in bpm.","minimum":100,"maximum":220},"restingHR":{"type":"integer","description":"Resting heart rate in bpm; required for Karvonen.","minimum":30,"maximum":100},"thresholdHR":{"type":"integer","description":"Threshold heart rate in bpm; required for threshold method.","minimum":100,"maximum":200}}},"example":{"method":"maxHR","maxHR":190}},{"slug":"sprint-splits-calculator","math":{"href":"https://www.tracktoolspro.com/api/calculators/sprint-splits-calculator","jsonPointer":"/calculator/math","version":"2026-10-21.1","implementationVersion":"b5a8aca7b85361476e0321a08b7fa5f516fc9535","scope":"Canonical HTTP function and documented corresponding mounted-form math. This is public inspectable documentation, not access control or independent empirical validation.","unitNotation":"Input paths use [] and *; output paths are JSON Pointers with * (one segment) and ** (descendants). Empty output path denotes scalar result. Units apply to numeric quantities or explicitly described numeric strings; labels/statuses/booleans are dimensionless. More specific units, including count/index exceptions, override broad patterns.","interfaceNotes":["HTTP input is described by the adjacent inputSchema. The original handlers may accept numeric strings; this metadata adds no validation.","Mounted forms accept displayed clock/unit strings and enforce their own limits. Mounted tools limit strings to 200 characters and numeric parts to magnitude 1000000. Do not assume mounted/API input interchangeability.","Some legacy extreme/invalid tuples can produce null/empty results or nonfinite numbers serialized as null. Those are unavailable answers, not exact numerical predictions. Per-calculator domain describes the intended mathematical inputs."],"kind":"heuristic","implementationFiles":["lib/formulas/sprint-splits.ts"],"equations":["100m: vAvg=100/targetTime, vMax=1.15*vAvg; begin cumulative clock at0.15s reaction. For each10m: factor=0.7+(distance/30)*0.3 through30m,0.98 through60m,1 through80m; final factor negative/even/realistic=0.96/0.94/0.92. Segment time=segmentDistance/(vMax*factor).","100m: round initial moving segments/cumulative times0.001s, then scale by targetTime/unroundedRawTotal; cumulative rounds0.01s, splitTime0.001s. Recompute speed=segmentDistance/roundedNormalizedSplitTime, round0.01m/s. Reaction is in cumulative time, not first moving segment.","200m: first 100=targetTime*1.03/2, second100=targetTime-first 100; negative uses first-half50m weights[.52,.48], second[.48,.52]; otherwise first[.48,.52], second[.5,.5].","400m: multiply targetTime by canonical100m distributions: negative[.265,.255,.245,.235], even[.24,.25,.255,.255], realistic[.23,.24,.26,.27]; accumulate in order; velocity=100/unroundedSplitTime."],"inputUnits":{"event":"m","targetTime":"s","strategy":"enum/string (dimensionless)"},"outputUnits":{"/*/distance":"m","/*/cumulativeTime":"s","/*/splitTime":"s","/*/velocity":"m/s"},"domain":["Event100/200/400; positive finite target and representable positive rows, else []."],"rounding":["100m rounding order is part of algorithm;200m raw numbers;400m times/speed0.01."],"assumptions":["Uses the entered values and the selected convention; this documentation does not strengthen existing validation."],"limitations":["Heuristic phase templates, not measured biomechanics or an elite-pattern law. The even label retains slight fade weights; negative/even labels do not make the100/200 model a fitted athlete-specific plan."],"mountedPageNotes":[],"workedExamples":[{"input":{"event":400,"targetTime":52,"strategy":"realistic"},"expected":{"/3/cumulativeTime":52},"absoluteTolerance":1e-8,"note":"Illustrative canonical-handler result; not independent validation of an empirical model."}],"constantsAndTables":{"events":{"100":{"label":"100m","splits":[10,20,30,40,50,60,70,80,90,100],"phases":[{"name":"Drive Phase","start":0,"end":30},{"name":"Transition","start":30,"end":50},{"name":"Max Velocity","start":50,"end":80},{"name":"Deceleration","start":80,"end":100}]},"200":{"label":"200m","splits":[50,100,150,200],"phases":[{"name":"Curve","start":0,"end":100},{"name":"Straight","start":100,"end":200}]},"400":{"label":"400m","splits":[100,200,300,400],"phases":[{"name":"First 100","start":0,"end":100},{"name":"Float (100-200)","start":100,"end":200},{"name":"Maintain (200-300)","start":200,"end":300},{"name":"Finish (300-400)","start":300,"end":400}]}},"reactionSeconds100m":0.15,"peakAverageVelocityRatio":1.15,"acceleration":[0.7,0.3],"nearPeakRatio":0.98,"decelerationRatios":{"negative":0.96,"even":0.94,"realistic":0.92},"curveRatio200m":1.03,"distributions400m":{"negative":[0.265,0.255,0.245,0.235],"even":[0.24,0.25,0.255,0.255],"realistic":[0.23,0.24,0.26,0.27]}},"sources":[{"title":"Canonical HTTP binding at the documented implementation revision","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/calculator-functions.ts","note":"Existing calculation handler; math metadata is additive."},{"title":"lib/formulas/sprint-splits.ts","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/formulas/sprint-splits.ts","note":"Primary implementation source for these equations/tables, not a claim of scientific calibration."}]},"annotations":{"readOnlyHint":true,"consequentialHint":false},"name":"Sprint Splits Calculator","description":"This sprint splits calculator turns a goal time into realistic 100m, 200m, and 300m checkpoints for the open 100m, 200m, and 400m. Use it as a 400m split calculator when you need a phase-by-phase race model — drive, float, maintain, finish — with even, negative, or realistic fade patterns instead of distance-race lap targets.","category":"Sprints & Hurdles","method":"POST","endpoint":"/api/calculators/sprint-splits-calculator","page":"/calculators/sprint-splits-calculator","inputSchema":{"type":"object","required":["event","targetTime"],"properties":{"event":{"type":"integer","description":"Sprint event distance.","enum":[100,200,400],"default":400},"targetTime":{"type":"number","description":"Target finish time in seconds.","minimum":0},"strategy":{"type":"string","description":"Pacing strategy.","enum":["realistic","even","negative"],"default":"realistic"}}},"example":{"event":400,"targetTime":52,"strategy":"realistic"}},{"slug":"implement-weight-lookup","math":{"href":"https://www.tracktoolspro.com/api/calculators/implement-weight-lookup","jsonPointer":"/calculator/math","version":"2026-10-21.1","implementationVersion":"b5a8aca7b85361476e0321a08b7fa5f516fc9535","scope":"Canonical HTTP function and documented corresponding mounted-form math. This is public inspectable documentation, not access control or independent empirical validation.","unitNotation":"Input paths use [] and *; output paths are JSON Pointers with * (one segment) and ** (descendants). Empty output path denotes scalar result. Units apply to numeric quantities or explicitly described numeric strings; labels/statuses/booleans are dimensionless. More specific units, including count/index exceptions, override broad patterns.","interfaceNotes":["HTTP input is described by the adjacent inputSchema. The original handlers may accept numeric strings; this metadata adds no validation.","Mounted forms accept displayed clock/unit strings and enforce their own limits. Mounted tools limit strings to 200 characters and numeric parts to magnitude 1000000. Do not assume mounted/API input interchangeability.","Some legacy extreme/invalid tuples can produce null/empty results or nonfinite numbers serialized as null. Those are unavailable answers, not exact numerical predictions. Per-calculator domain describes the intended mathematical inputs."],"kind":"lookup","implementationFiles":["lib/formulas/implement-weights.ts"],"equations":["Select IMPLEMENTS[implement].specs[gender], senior row by exact ageGroup=\"Senior\", and HS_WEIGHTS[gender][implement] override. No equation generates the weights."],"inputUnits":{"implement":"enum/string (dimensionless)","gender":"enum/string (dimensionless)"},"outputUnits":{"/specs/*/weight":"kg except javelin:g (see result.unit)","/senior/weight":"kg except javelin:g","/highSchool/weight":"see highSchool.unit (kg or g)"},"domain":["Known implement and male/female reference table. No age input in HTTP: it returns the full stored table."],"rounding":["Raw IEEE-754 numbers; the mounted page formats clocks separately."],"assumptions":["Uses the entered values and the selected convention; this documentation does not strengthen existing validation."],"limitations":["Stored age-group reference specifications, not universal youth/state eligibility. HS overrides are separate. Women70–74/75 thresholds are represented by retained rows. No standards refresh is implied by a calculation."],"mountedPageNotes":[],"workedExamples":[{"input":{"implement":"shotPut","gender":"male"},"expected":{"/senior/weight":7.26},"absoluteTolerance":1e-8,"note":"Illustrative canonical-handler result; not independent validation of an empirical model."}],"constantsAndTables":{"implementTables":{"shotPut":{"name":"Shot Put","unit":"kg","specs":{"male":[{"ageGroup":"Youth (U14)","weight":3},{"ageGroup":"Youth (U16)","weight":4},{"ageGroup":"Youth (U18)","weight":5},{"ageGroup":"Junior (U20)","weight":6},{"ageGroup":"Senior","weight":7.26},{"ageGroup":"Masters 50+","weight":6},{"ageGroup":"Masters 60+","weight":5},{"ageGroup":"Masters 70+","weight":4},{"ageGroup":"Masters 80+","weight":3}],"female":[{"ageGroup":"Youth (U14)","weight":2},{"ageGroup":"Youth (U16)","weight":3},{"ageGroup":"Youth (U18)","weight":3},{"ageGroup":"Junior (U20)","weight":4},{"ageGroup":"Senior","weight":4},{"ageGroup":"Masters 50+","weight":3},{"ageGroup":"Masters 60+","weight":3},{"ageGroup":"Masters 70+","weight":3},{"ageGroup":"Masters 75+","weight":2},{"ageGroup":"Masters 80+","weight":2}]}},"discus":{"name":"Discus","unit":"kg","specs":{"male":[{"ageGroup":"Youth (U14)","weight":1},{"ageGroup":"Youth (U16)","weight":1},{"ageGroup":"Youth (U18)","weight":1.5},{"ageGroup":"Junior (U20)","weight":1.75},{"ageGroup":"Senior","weight":2},{"ageGroup":"Masters 50+","weight":1.5},{"ageGroup":"Masters 60+","weight":1},{"ageGroup":"Masters 70+","weight":1},{"ageGroup":"Masters 80+","weight":1}],"female":[{"ageGroup":"Youth (U14)","weight":0.75},{"ageGroup":"Youth (U16)","weight":0.75},{"ageGroup":"Youth (U18)","weight":1},{"ageGroup":"Junior (U20)","weight":1},{"ageGroup":"Senior","weight":1},{"ageGroup":"Masters 50+","weight":1},{"ageGroup":"Masters 60+","weight":1},{"ageGroup":"Masters 70+","weight":1},{"ageGroup":"Masters 75+","weight":0.75},{"ageGroup":"Masters 80+","weight":0.75}]}},"javelin":{"name":"Javelin","unit":"g","specs":{"male":[{"ageGroup":"Youth (U14)","weight":400},{"ageGroup":"Youth (U16)","weight":600},{"ageGroup":"Youth (U18)","weight":700},{"ageGroup":"Junior (U20)","weight":800},{"ageGroup":"Senior","weight":800},{"ageGroup":"Masters 50+","weight":700},{"ageGroup":"Masters 60+","weight":600},{"ageGroup":"Masters 70+","weight":500},{"ageGroup":"Masters 80+","weight":400}],"female":[{"ageGroup":"Youth (U14)","weight":400},{"ageGroup":"Youth (U16)","weight":400},{"ageGroup":"Youth (U18)","weight":500},{"ageGroup":"Junior (U20)","weight":600},{"ageGroup":"Senior","weight":600},{"ageGroup":"Masters 50+","weight":500},{"ageGroup":"Masters 60+","weight":500},{"ageGroup":"Masters 70+","weight":500},{"ageGroup":"Masters 75+","weight":400},{"ageGroup":"Masters 80+","weight":400}]}},"hammer":{"name":"Hammer","unit":"kg","specs":{"male":[{"ageGroup":"Youth (U14)","weight":3},{"ageGroup":"Youth (U16)","weight":4},{"ageGroup":"Youth (U18)","weight":5},{"ageGroup":"Junior (U20)","weight":6},{"ageGroup":"Senior","weight":7.26},{"ageGroup":"Masters 50+","weight":6},{"ageGroup":"Masters 60+","weight":5},{"ageGroup":"Masters 70+","weight":4},{"ageGroup":"Masters 80+","weight":3}],"female":[{"ageGroup":"Youth (U14)","weight":2},{"ageGroup":"Youth (U16)","weight":3},{"ageGroup":"Youth (U18)","weight":3},{"ageGroup":"Junior (U20)","weight":4},{"ageGroup":"Senior","weight":4},{"ageGroup":"Masters 50+","weight":3},{"ageGroup":"Masters 60+","weight":3},{"ageGroup":"Masters 70+","weight":3},{"ageGroup":"Masters 75+","weight":2},{"ageGroup":"Masters 80+","weight":2}]}},"weightThrow":{"name":"Weight Throw","unit":"kg","specs":{"male":[{"ageGroup":"Youth (U18)","weight":7.26},{"ageGroup":"Junior (U20)","weight":11.34},{"ageGroup":"Senior","weight":15.88},{"ageGroup":"Masters 50+","weight":11.34},{"ageGroup":"Masters 60+","weight":9.08},{"ageGroup":"Masters 70+","weight":7.26},{"ageGroup":"Masters 80+","weight":5.45}],"female":[{"ageGroup":"Youth (U18)","weight":4},{"ageGroup":"Junior (U20)","weight":9.08},{"ageGroup":"Senior","weight":9.08},{"ageGroup":"Masters 50+","weight":7.26},{"ageGroup":"Masters 60+","weight":5.45},{"ageGroup":"Masters 70+","weight":5.45},{"ageGroup":"Masters 75+","weight":4},{"ageGroup":"Masters 80+","weight":4}]}}},"highSchoolOverrides":{"male":{"shotPut":{"weight":5.44,"unit":"kg","note":"12 lbs"},"discus":{"weight":1.6,"unit":"kg","note":"3 lbs 8.5 oz"},"javelin":{"weight":800,"unit":"g","note":"Standard"}},"female":{"shotPut":{"weight":4,"unit":"kg","note":"8.8 lbs"},"discus":{"weight":1,"unit":"kg","note":"2 lbs 3.3 oz"},"javelin":{"weight":600,"unit":"g","note":"Standard"}}},"ruleReference":{"title":"World Athletics Competition and Technical Rules (official index: 1 July 2026)","url":"https://worldathletics.org/download/download?filename=0ed43077-8e08-492b-a4b3-267f27c18d0b.pdf&urlslug=C1.1%20%26%20C2.1%20-%20Competition%20Rules%20%26%20Technical%20Rules","checkedOn":"2026-10-15"}},"sources":[{"title":"Canonical HTTP binding at the documented implementation revision","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/calculator-functions.ts","note":"Existing calculation handler; math metadata is additive."},{"title":"lib/formulas/implement-weights.ts","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/formulas/implement-weights.ts","note":"Primary implementation source for these equations/tables, not a claim of scientific calibration."},{"title":"WMA Competition and Technical Rules, October 2026","url":"https://world-masters-athletics.org/wp-content/uploads/2026/10/WMA-Competition-and-Technical-Rules-FINAL-October-2026.pdf","note":"October 2026 WMA reference used for retained masters boundary checks. Local youth/high-school specifications may differ."}]},"annotations":{"readOnlyHint":true,"consequentialHint":false},"name":"Implement Weight Lookup","description":"Complete reference for shot put, discus, javelin, hammer, and weight throw specifications across all age groups from youth to masters, for both male and female athletes.","category":"Field Events","method":"POST","endpoint":"/api/calculators/implement-weight-lookup","page":"/calculators/implement-weight-lookup","inputSchema":{"type":"object","required":[],"properties":{"implement":{"type":"string","description":"Implement key.","enum":["shotPut","discus","javelin","hammer","weightThrow"],"default":"shotPut"},"gender":{"type":"string","description":"Gender table.","enum":["male","female"],"default":"male"}}},"example":{"implement":"shotPut","gender":"male"}},{"slug":"combined-events-calculator","math":{"href":"https://www.tracktoolspro.com/api/calculators/combined-events-calculator","jsonPointer":"/calculator/math","version":"2026-10-21.1","implementationVersion":"b5a8aca7b85361476e0321a08b7fa5f516fc9535","scope":"Canonical HTTP function and documented corresponding mounted-form math. This is public inspectable documentation, not access control or independent empirical validation.","unitNotation":"Input paths use [] and *; output paths are JSON Pointers with * (one segment) and ** (descendants). Empty output path denotes scalar result. Units apply to numeric quantities or explicitly described numeric strings; labels/statuses/booleans are dimensionless. More specific units, including count/index exceptions, override broad patterns.","interfaceNotes":["HTTP input is described by the adjacent inputSchema. The original handlers may accept numeric strings; this metadata adds no validation.","Mounted forms accept displayed clock/unit strings and enforce their own limits. Mounted tools limit strings to 200 characters and numeric parts to magnitude 1000000. Do not assume mounted/API input interchangeability.","Some legacy extreme/invalid tuples can produce null/empty results or nonfinite numbers serialized as null. Those are unavailable answers, not exact numerical predictions. Per-calculator domain describes the intended mathematical inputs."],"kind":"scoring-formula","implementationFiles":["lib/formulas/combined-events.ts"],"equations":["Track: points=floor(A*(B-P)^C), P in seconds. Jumps: convert entered meters to centimeters, then points=floor(A*(P-B)^C). Throws: meters, points=floor(A*(P-B)^C).","A mark not beating the selected B threshold scores0. Floor each event before total=sum(eventScores). Blank/null/missing marks are unentered with0points; malformed entered marks produce event-specific errors, never numeric-prefix scores."],"inputUnits":{"eventType":"enum/string (dimensionless)","performances.*":"track:s or M:SS.xx; jumps/throws:m"},"outputUnits":{"/total":"integer scoring points","/eventScores/*":"integer scoring points"},"domain":["Decathlon/heptathlon; strict positive track time or complete nonnegative decimal field mark; finite numeric marks accepted directly. Reject bad clocks, trailing text, negative/unsupported values and nonfinite scored results. Unknown event keys are ignored."],"rounding":["Each event Math.floor before sum. Meter-to-centimeter conversion for jumps only."],"assumptions":["Uses the entered values and the selected convention; this documentation does not strengthen existing validation."],"limitations":["Retained coefficients and entered partial/complete total only. No forecast of missing marks, qualification guarantee or training recommendation."],"mountedPageNotes":[],"workedExamples":[{"input":{"eventType":"decathlon","performances":{"100m":"10.55","longJump":"7.80","shotPut":"15.00"}},"expected":{"/total":2763,"/eventScores/longJump":1010},"absoluteTolerance":1e-8,"note":"Illustrative canonical-handler result; not independent validation of an empirical model."}],"constantsAndTables":{"scoringCoefficients":{"decathlon":{"100m":{"A":25.4347,"B":18,"C":1.81,"type":"track"},"longJump":{"A":0.14354,"B":220,"C":1.4,"type":"jump"},"shotPut":{"A":51.39,"B":1.5,"C":1.05,"type":"throw"},"highJump":{"A":0.8465,"B":75,"C":1.42,"type":"jump"},"400m":{"A":1.53775,"B":82,"C":1.81,"type":"track"},"110mH":{"A":5.74352,"B":28.5,"C":1.92,"type":"track"},"discus":{"A":12.91,"B":4,"C":1.1,"type":"throw"},"poleVault":{"A":0.2797,"B":100,"C":1.35,"type":"jump"},"javelin":{"A":10.14,"B":7,"C":1.08,"type":"throw"},"1500m":{"A":0.03768,"B":480,"C":1.85,"type":"track"}},"heptathlon":{"100mH":{"A":9.23076,"B":26.7,"C":1.835,"type":"track"},"highJump":{"A":1.84523,"B":75,"C":1.348,"type":"jump"},"shotPut":{"A":56.0211,"B":1.5,"C":1.05,"type":"throw"},"200m":{"A":4.99087,"B":42.5,"C":1.81,"type":"track"},"longJump":{"A":0.188807,"B":210,"C":1.41,"type":"jump"},"javelin":{"A":15.9803,"B":3.8,"C":1.04,"type":"throw"},"800m":{"A":0.11193,"B":254,"C":1.88,"type":"track"}}},"sourceEdition":"1984 combined-event coefficient system, retained by product; distinct from 2025 general athletics tables."},"sources":[{"title":"Canonical HTTP binding at the documented implementation revision","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/calculator-functions.ts","note":"Existing calculation handler; math metadata is additive."},{"title":"lib/formulas/combined-events.ts","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/formulas/combined-events.ts","note":"Primary implementation source for these equations/tables, not a claim of scientific calibration."},{"title":"World Athletics / IAAF Combined Events Scoring Tables","url":"https://worldathletics.org/download/download?filename=53f7d332-be0c-434c-8467-1d9078966147.pdf&urlslug=IAAF+Scoring+Tables+for+Combined+Events","note":"1984 combined-event coefficient system; formula units and event-wise floor. Distinct from general 2025 athletics points."}]},"annotations":{"readOnlyHint":true,"consequentialHint":false},"name":"Combined Events Calculator","description":"Score entered decathlon or heptathlon marks using the retained World Athletics combined-event coefficients. Read integer event points and their partial or complete total; blank events are unentered. This does not predict missing marks or recommend training priorities.","category":"Field Events","method":"POST","endpoint":"/api/calculators/combined-events-calculator","page":"/calculators/combined-events-calculator","inputSchema":{"type":"object","required":["eventType","performances"],"properties":{"eventType":{"type":"string","description":"Combined event type.","enum":["decathlon","heptathlon"],"default":"decathlon"},"performances":{"type":"object","description":"Event performances keyed by event id. Track marks are positive seconds or M:SS.xx with clock seconds below 60; jumps and throws are nonnegative meters. Blank events are unentered. Malformed entered marks are rejected."}}},"example":{"eventType":"decathlon","performances":{"100m":"10.55","longJump":"7.80","shotPut":"15.00"}}},{"slug":"relay-split-calculator","math":{"href":"https://www.tracktoolspro.com/api/calculators/relay-split-calculator","jsonPointer":"/calculator/math","version":"2026-10-21.1","implementationVersion":"b5a8aca7b85361476e0321a08b7fa5f516fc9535","scope":"Canonical HTTP function and documented corresponding mounted-form math. This is public inspectable documentation, not access control or independent empirical validation.","unitNotation":"Input paths use [] and *; output paths are JSON Pointers with * (one segment) and ** (descendants). Empty output path denotes scalar result. Units apply to numeric quantities or explicitly described numeric strings; labels/statuses/booleans are dimensionless. More specific units, including count/index exceptions, override broad patterns.","interfaceNotes":["HTTP input is described by the adjacent inputSchema. The original handlers may accept numeric strings; this metadata adds no validation.","Mounted forms accept displayed clock/unit strings and enforce their own limits. Mounted tools limit strings to 200 characters and numeric parts to magnitude 1000000. Do not assume mounted/API input interchangeability.","Some legacy extreme/invalid tuples can produce null/empty results or nonfinite numbers serialized as null. Those are unavailable answers, not exact numerical predictions. Per-calculator domain describes the intended mathematical inputs."],"kind":"heuristic","implementationFiles":["lib/formulas/relay-splits.ts"],"equations":["Goal mode: flying=(goalSeconds-leadoffOffset)/4; leadoff=flying+leadoffOffset; legs2..4=flying; cumulative=sum preceding targets.","If nonempty legSeconds is supplied, sum exactly 4 positive leg times instead; this takes precedence over goalSeconds."],"inputUnits":{"event":"enum/string (dimensionless)","goalSeconds":"s","legSeconds[]":"s"},"outputUnits":{"/totalSeconds":"s","/leadoffOffsetSeconds":"s","/legs/*/leg":"dimensionless index/count","/legs/*/targetTime":"s","/legs/*/cumulativeTime":"s"},"domain":["Known 4-leg event; goal>event offset or exactly 4 positive finite splits. Invalid tuples produce API errors."],"rounding":["Raw IEEE-754 numbers; the mounted page formats clocks separately."],"assumptions":["Uses the entered values and the selected convention; this documentation does not strengthen existing validation."],"limitations":["Offsets are coaching conventions, not measured exchange savings. Arithmetic totals are exact within floating-point precision, but equal flying legs do not select an actual relay team."],"mountedPageNotes":[],"workedExamples":[{"input":{"event":"4x400","goalSeconds":200},"expected":{"/legs/0/targetTime":50.75,"/legs/3/cumulativeTime":200},"absoluteTolerance":1e-8,"note":"Illustrative canonical-handler result; not independent validation of an empirical model."}],"constantsAndTables":{"events":{"4x100":{"label":"4x100m","legMeters":100,"totalMeters":400,"leadoffOffset":0.5},"4x200":{"label":"4x200m","legMeters":200,"totalMeters":800,"leadoffOffset":0.8},"4x400":{"label":"4x400m","legMeters":400,"totalMeters":1600,"leadoffOffset":1},"4x800":{"label":"4x800m","legMeters":800,"totalMeters":3200,"leadoffOffset":1}}},"sources":[{"title":"Canonical HTTP binding at the documented implementation revision","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/calculator-functions.ts","note":"Existing calculation handler; math metadata is additive."},{"title":"lib/formulas/relay-splits.ts","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/formulas/relay-splits.ts","note":"Primary implementation source for these equations/tables, not a claim of scientific calibration."}]},"annotations":{"readOnlyHint":true,"consequentialHint":false},"name":"Relay Split Calculator","description":"This relay split calculator turns a team goal time into per-leg targets for the 4x100, 4x200, 4x400, and 4x800. The leadoff leg is modeled slower than the flying legs because leg 1 starts from blocks or a standing start while legs 2–4 receive the baton at speed. It also works in reverse as a 4x4 time calculator: enter four leg splits and get the team total. Every result shows the cumulative time at each exchange — the number a coach actually reads off the stopwatch.","category":"Pace & Time","method":"POST","endpoint":"/api/calculators/relay-split-calculator","page":"/calculators/relay-split-calculator","inputSchema":{"type":"object","required":["event"],"properties":{"event":{"type":"string","description":"Relay event.","enum":["4x100","4x200","4x400","4x800"],"default":"4x400"},"goalSeconds":{"type":"number","description":"Team goal time in seconds (goal-to-splits mode).","minimum":0},"legSeconds":{"type":"array","description":"Four leg splits in seconds, leadoff first (legs-to-total mode).","items":{"type":"number","description":"Leg split in seconds.","minimum":0}}}},"example":{"event":"4x400","goalSeconds":200}},{"slug":"dmr-split-calculator","math":{"href":"https://www.tracktoolspro.com/api/calculators/dmr-split-calculator","jsonPointer":"/calculator/math","version":"2026-10-21.1","implementationVersion":"b5a8aca7b85361476e0321a08b7fa5f516fc9535","scope":"Canonical HTTP function and documented corresponding mounted-form math. This is public inspectable documentation, not access control or independent empirical validation.","unitNotation":"Input paths use [] and *; output paths are JSON Pointers with * (one segment) and ** (descendants). Empty output path denotes scalar result. Units apply to numeric quantities or explicitly described numeric strings; labels/statuses/booleans are dimensionless. More specific units, including count/index exceptions, override broad patterns.","interfaceNotes":["HTTP input is described by the adjacent inputSchema. The original handlers may accept numeric strings; this metadata adds no validation.","Mounted forms accept displayed clock/unit strings and enforce their own limits. Mounted tools limit strings to 200 characters and numeric parts to magnitude 1000000. Do not assume mounted/API input interchangeability.","Some legacy extreme/invalid tuples can produce null/empty results or nonfinite numbers serialized as null. Those are unavailable answers, not exact numerical predictions. Per-calculator domain describes the intended mathematical inputs."],"kind":"heuristic","implementationFiles":["lib/formulas/dmr-splits.ts","lib/formulas/track-size-conversion.ts"],"equations":["weight[i]=legMeters[i]^1.06 for[1200,400,800,1600]; targetTime[i]=goalSeconds*weight[i]/sum(weights); pacePer400=targetTime[i]*400/legMeters[i]; cumulative=sum(targetTime[0..i]).","Nonempty legSeconds takes precedence: sum exactly 4 positive times in the stated order. Mounted track-size comparison reuses convertTrackTime(event=\"dmr\")."],"inputUnits":{"goalSeconds":"s","legSeconds[]":"s"},"outputUnits":{"/totalSeconds":"s","/legs/*/leg":"dimensionless index/count","/legs/*/meters":"m","/legs/*/targetTime":"s","/legs/*/cumulativeTime":"s","/legs/*/pacePer400":"s/400m"},"domain":["Positive finite goal, or 4 positive finite leg splits."],"rounding":["Raw IEEE-754 numbers; the mounted page formats clocks separately."],"assumptions":["Uses the entered values and the selected convention; this documentation does not strengthen existing validation."],"limitations":["Riegel weighting is a pacing convention, not proof of equal physiological effort for4different runners. No independently observed official DMR rounding comparison."],"mountedPageNotes":["HTTP returns splits or summed total; mounted facility comparison uses the separately documented indoor factors/rounding."],"workedExamples":[{"input":{"goalSeconds":600},"expected":{"/legs/3/cumulativeTime":600.0000000000001},"absoluteTolerance":1e-8,"note":"Illustrative canonical-handler result; not independent validation of an empirical model."}],"constantsAndTables":{"legs":[{"leg":1,"meters":1200,"label":"1200m"},{"leg":2,"meters":400,"label":"400m"},{"leg":3,"meters":800,"label":"800m"},{"leg":4,"meters":1600,"label":"1600m"}],"exponent":1.06,"mountedFacilityFactors":{"men":{"undersizedToFlat":0.9931,"bankedToFlat":1.0136,"undersizedToBanked":0.9798,"flatToBanked":0.9866},"women":{"undersizedToFlat":0.9959,"bankedToFlat":1.0107,"undersizedToBanked":0.9853,"flatToBanked":0.9894}}},"sources":[{"title":"Canonical HTTP binding at the documented implementation revision","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/calculator-functions.ts","note":"Existing calculation handler; math metadata is additive."},{"title":"lib/formulas/dmr-splits.ts","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/formulas/dmr-splits.ts","note":"Primary implementation source for these equations/tables, not a claim of scientific calibration."},{"title":"lib/formulas/track-size-conversion.ts","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/formulas/track-size-conversion.ts","note":"Primary implementation source for these equations/tables, not a claim of scientific calibration."},{"title":"Riegel, Athletic Records and Human Endurance,1981","url":"https://rrtc.net/Articles/ARHE.pdf","note":"Riegel 1981 primary article; fitted exponents vary. Product default 1.06 is an explicit convention, not a universal accuracy claim. Retained source reviewed 2026-10-16."},{"title":"USTFCCCA NCAA indoor conversion charts, 29 Jan 2024","url":"https://www.ustfccca.org/assets/NCAA-Indoor-Track-Size-Conversion-Charts.pdf?DB_OEM_ID=27900","note":"29January2024 factor chart. Does not establish a universal qualifying rounding rule. Product uses nearest-hundredth comparison; observed TFRRS difference remains disclosed."}]},"annotations":{"readOnlyHint":true,"consequentialHint":false},"name":"DMR Split Calculator","description":"This DMR split calculator turns a distance medley relay goal time into targets for the standard 1200m, 400m, 800m, and 1600m legs. Because the legs are different distances run by different athletes, even pace is the wrong model — instead each leg is weighted for equal effort using the same Riegel exponent (1.06) behind common race-equivalency tools, so the 400m leg is targeted at the fastest pace per 400 and the 1600m leg the slowest. It shows the cumulative time at each exchange, adds four leg splits into a team total, and converts goals between flat 200m and banked tracks with the official NCAA DMR conversion factors.","category":"Pace & Time","method":"POST","endpoint":"/api/calculators/dmr-split-calculator","page":"/calculators/dmr-split-calculator","inputSchema":{"type":"object","required":[],"properties":{"goalSeconds":{"type":"number","description":"Team DMR goal time in seconds (goal-to-splits mode).","minimum":0},"legSeconds":{"type":"array","description":"Four leg splits in seconds in 1200-400-800-1600 order (legs-to-total mode).","items":{"type":"number","description":"Leg split in seconds.","minimum":0}}}},"example":{"goalSeconds":600}},{"slug":"race-time-predictor","math":{"href":"https://www.tracktoolspro.com/api/calculators/race-time-predictor","jsonPointer":"/calculator/math","version":"2026-10-21.1","implementationVersion":"b5a8aca7b85361476e0321a08b7fa5f516fc9535","scope":"Canonical HTTP function and documented corresponding mounted-form math. This is public inspectable documentation, not access control or independent empirical validation.","unitNotation":"Input paths use [] and *; output paths are JSON Pointers with * (one segment) and ** (descendants). Empty output path denotes scalar result. Units apply to numeric quantities or explicitly described numeric strings; labels/statuses/booleans are dimensionless. More specific units, including count/index exceptions, override broad patterns.","interfaceNotes":["HTTP input is described by the adjacent inputSchema. The original handlers may accept numeric strings; this metadata adds no validation.","Mounted forms accept displayed clock/unit strings and enforce their own limits. Mounted tools limit strings to 200 characters and numeric parts to magnitude 1000000. Do not assume mounted/API input interchangeability.","Some legacy extreme/invalid tuples can produce null/empty results or nonfinite numbers serialized as null. Those are unavailable answers, not exact numerical predictions. Per-calculator domain describes the intended mathematical inputs."],"kind":"empirical-model","implementationFiles":["lib/formulas/riegel.ts"],"equations":["prediction.seconds=timeSeconds*(targetMeters/distanceMeters)^exponent; pacePerMileSeconds=prediction.seconds*1609.34/targetMeters; pacePerKmSeconds=prediction.seconds*1000/targetMeters."],"inputUnits":{"timeSeconds":"s","distanceMeters":"m","exponent":"dimensionless fatigue exponent"},"outputUnits":{"/*/meters":"m","/*/seconds":"s","/*/pacePerMileSeconds":"s/mile","/*/pacePerKmSeconds":"s/km"},"domain":["Positive finite distance/time; API exponent1.02..1.12 (default 1.06).","Legacy invalid reference values may return arrays of NaN-valued predictions; JSON serializes those numbers as null. They are unavailable results, not valid race times."],"rounding":["Raw IEEE-754 numbers; the mounted page formats clocks separately."],"assumptions":["Uses the entered values and the selected convention; this documentation does not strengthen existing validation."],"limitations":["Power-law extrapolation, not universal prediction accuracy or a validated athlete classification. The default exponent is a convention."],"mountedPageNotes":[],"workedExamples":[{"input":{"timeSeconds":1200,"distanceMeters":5000,"exponent":1.06},"expected":{"/0/seconds":172.00791345301917},"absoluteTolerance":1e-8,"note":"Illustrative canonical-handler result; not independent validation of an empirical model."}],"constantsAndTables":{"defaultExponent":1.06,"exponentPresets":[{"value":1.05,"label":"Less slowing","description":"Less slowing for targets longer than the reference"},{"value":1.06,"label":"Standard","description":"Existing comparison default"},{"value":1.08,"label":"More slowing","description":"More slowing for targets longer than the reference"}],"outputDistances":[{"id":"800m","label":"800m","meters":800},{"id":"1500m","label":"1500m","meters":1500},{"id":"mile","label":"Mile","meters":1609.34},{"id":"1600m","label":"1600m","meters":1600},{"id":"3000m","label":"3000m","meters":3000},{"id":"3200m","label":"3200m","meters":3200},{"id":"2mile","label":"2 Mile","meters":3218.69},{"id":"5k","label":"5K","meters":5000},{"id":"6k","label":"6K","meters":6000},{"id":"8k","label":"8K","meters":8000},{"id":"10k","label":"10K","meters":10000},{"id":"half","label":"Half Marathon","meters":21097.5},{"id":"marathon","label":"Marathon","meters":42195}],"metersPerMile":1609.34},"sources":[{"title":"Canonical HTTP binding at the documented implementation revision","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/calculator-functions.ts","note":"Existing calculation handler; math metadata is additive."},{"title":"lib/formulas/riegel.ts","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/formulas/riegel.ts","note":"Primary implementation source for these equations/tables, not a claim of scientific calibration."},{"title":"Riegel, Athletic Records and Human Endurance,1981","url":"https://rrtc.net/Articles/ARHE.pdf","note":"Riegel 1981 primary article; fitted exponents vary. Product default 1.06 is an explicit convention, not a universal accuracy claim. Retained source reviewed 2026-10-16."}]},"annotations":{"readOnlyHint":true,"consequentialHint":false},"name":"Riegel Race Time Predictor","description":"This race time predictor uses the classic Riegel formula — T2 = T1 × (D2 ÷ D1)^1.06 — to turn one recent race into predicted times at 800m through the marathon, with pace per mile and per kilometer. Unlike black-box race equivalency calculators, the formula is shown on the page and the fatigue exponent is adjustable (1.02–1.12), so speed-type and endurance-type runners can tune predictions to match how they actually race.","category":"Pace & Time","method":"POST","endpoint":"/api/calculators/race-time-predictor","page":"/calculators/race-time-predictor","inputSchema":{"type":"object","required":["timeSeconds","distanceMeters"],"properties":{"timeSeconds":{"type":"number","description":"Known race time in seconds.","minimum":0},"distanceMeters":{"type":"number","description":"Known race distance in meters.","minimum":0},"exponent":{"type":"number","description":"Riegel exponent.","default":1.06,"minimum":1.02,"maximum":1.12}}},"example":{"timeSeconds":1200,"distanceMeters":5000,"exponent":1.06}},{"slug":"track-event-conversion","math":{"href":"https://www.tracktoolspro.com/api/calculators/track-event-conversion","jsonPointer":"/calculator/math","version":"2026-10-21.1","implementationVersion":"b5a8aca7b85361476e0321a08b7fa5f516fc9535","scope":"Canonical HTTP function and documented corresponding mounted-form math. This is public inspectable documentation, not access control or independent empirical validation.","unitNotation":"Input paths use [] and *; output paths are JSON Pointers with * (one segment) and ** (descendants). Empty output path denotes scalar result. Units apply to numeric quantities or explicitly described numeric strings; labels/statuses/booleans are dimensionless. More specific units, including count/index exceptions, override broad patterns.","interfaceNotes":["HTTP input is described by the adjacent inputSchema. The original handlers may accept numeric strings; this metadata adds no validation.","Mounted forms accept displayed clock/unit strings and enforce their own limits. Mounted tools limit strings to 200 characters and numeric parts to magnitude 1000000. Do not assume mounted/API input interchangeability.","Some legacy extreme/invalid tuples can produce null/empty results or nonfinite numbers serialized as null. Those are unavailable answers, not exact numerical predictions. Per-calculator domain describes the intended mathematical inputs."],"kind":"mixed-conventions","implementationFiles":["lib/formulas/event-conversion.ts"],"equations":["Factor rows: convertedSeconds=round(timeSeconds*factor) using the selected gender where applicable. NCAA rows round upward to 0.01; statistician/Riegel/derived/coaching rows round nearest0.01.","Range rows: low/high are min/max(timeSeconds+addMin,timeSeconds+addMax); mid=timeSeconds+addMid; each rounds nearest0.01.","Exact distance-ratio rows use 1609.344m/mile; Riegel rows use(toMeters/fromMeters)^1.06. Source/provenance is returned per row."],"inputUnits":{"timeSeconds":"s","conversionId":"enum/string (dimensionless)","gender":"enum/string (dimensionless)"},"outputUnits":{"/originalSeconds":"s","/convertedSeconds":"s","/lowSeconds":"s","/midSeconds":"s","/highSeconds":"s","/factor":"dimensionless","/addMin":"s","/addMid":"s","/addMax":"s"},"domain":["Known conversion/gender and positive finite time; invalid input returns null. Very short input plus negative coaching offset may retain a nonpositive raw range; no new guard is added."],"rounding":["NCAA: ceil(round(x*1e6)/1e4)/100; others: round(round(x*1e6)/1e4)/100."],"assumptions":["Uses the entered values and the selected convention; this documentation does not strengthen existing validation."],"limitations":["NCAA factors, exact ratios, reciprocal estimates and coaching offsets have different provenance. Only the applicable NCAA conversion convention uses prescribed round-up; eligibility still requires actual meet rules."],"mountedPageNotes":[],"workedExamples":[{"input":{"timeSeconds":229.71,"conversionId":"1500-to-mile","gender":"men"},"expected":{"/convertedSeconds":248.09,"/factor":1.08},"absoluteTolerance":1e-8,"note":"Illustrative canonical-handler result; not independent validation of an empirical model."}],"constantsAndTables":{"conversionsWithProvenance":[{"id":"mile-to-1500","kind":"factor","fromLabel":"Mile","toLabel":"1500m","provenance":"ncaa","factor":0.9259,"note":"NCAA Standardized Track Event Conversion Factors (outdoor table)."},{"id":"1500-to-mile","kind":"factor","fromLabel":"1500m","toLabel":"Mile","provenance":"ncaa","factor":1.08,"note":"x1.08 per the worked example in the NCAA event-conversion document (3:49.71 -> 4:08.09)."},{"id":"55-to-60","kind":"factor","fromLabel":"55m","toLabel":"60m","provenance":"ncaa","factor":{"men":1.0749,"women":1.0771},"note":"NCAA indoor table; gender-specific factors."},{"id":"60-to-55","kind":"factor","fromLabel":"60m","toLabel":"55m","provenance":"derived","factor":{"men":0.9303190994511118,"women":0.9284189026088572},"note":"Reciprocal of the NCAA 55m -> 60m factor; the NCAA publishes only the 55 -> 60 direction."},{"id":"55h-to-60h","kind":"factor","fromLabel":"55m Hurdles","toLabel":"60m Hurdles","provenance":"ncaa","factor":{"men":1.0766,"women":1.0755},"note":"NCAA indoor table; gender-specific factors."},{"id":"60h-to-55h","kind":"factor","fromLabel":"60m Hurdles","toLabel":"55m Hurdles","provenance":"derived","factor":{"men":0.9288500835965076,"women":0.9298000929800094},"note":"Reciprocal of the NCAA 55H -> 60H factor; the NCAA publishes only the 55H -> 60H direction."},{"id":"mile-relay-to-4x400","kind":"factor","fromLabel":"Mile Relay (4x440y)","toLabel":"4x400m Relay","provenance":"ncaa","factor":0.9942,"note":"NCAA table (indoor and outdoor)."},{"id":"4x110y-to-4x100","kind":"factor","fromLabel":"4x110y Relay","toLabel":"4x100m Relay","provenance":"ncaa","factor":0.9942,"note":"NCAA outdoor table."},{"id":"dmr-yards-to-metric","kind":"factor","fromLabel":"DMR (yards)","toLabel":"DMR (metric)","provenance":"ncaa","factor":0.9942,"note":"NCAA indoor table."},{"id":"1600-to-mile","kind":"factor","fromLabel":"1600m","toLabel":"Mile","provenance":"statistician","factor":1.00584,"note":"Exact distance ratio 1609.344/1600. A mile is 9.344m longer than a 1600."},{"id":"mile-to-1600","kind":"factor","fromLabel":"Mile","toLabel":"1600m","provenance":"statistician","factor":0.9941939075797344,"note":"Exact distance ratio 1600/1609.344."},{"id":"3200-to-2mile","kind":"factor","fromLabel":"3200m","toLabel":"2 Mile","provenance":"statistician","factor":1.00584,"note":"Exact distance ratio 3218.688/3200. Two miles is 18.688m longer than a 3200."},{"id":"2mile-to-3200","kind":"factor","fromLabel":"2 Mile","toLabel":"3200m","provenance":"statistician","factor":0.9941939075797344,"note":"Exact distance ratio 3200/3218.688."},{"id":"1500-to-1600","kind":"factor","fromLabel":"1500m","toLabel":"1600m","provenance":"riegel","factor":1.0708051395758162,"note":"Riegel scaling (1600/1500)^1.06. Estimate; the NCAA publishes no 1500 <-> 1600 factor."},{"id":"1600-to-1500","kind":"factor","fromLabel":"1600m","toLabel":"1500m","provenance":"riegel","factor":0.9338767279321569,"note":"Riegel scaling (1500/1600)^1.06. Estimate."},{"id":"3000-to-3200","kind":"factor","fromLabel":"3000m","toLabel":"3200m","provenance":"riegel","factor":1.0708051395758162,"note":"Riegel scaling (3200/3000)^1.06. Estimate; the NCAA publishes no 3000 <-> 3200 factor."},{"id":"3200-to-3000","kind":"factor","fromLabel":"3200m","toLabel":"3000m","provenance":"riegel","factor":0.9338767279321569,"note":"Riegel scaling (3000/3200)^1.06. Estimate."},{"id":"600-to-800","kind":"factor","fromLabel":"600m","toLabel":"800m","provenance":"coaching","factor":1.41,"note":"Classic middle-distance predictor: 800m potential = 600m time x 1.41."},{"id":"relay-split-to-open-400","kind":"range","fromLabel":"4x400 Relay Split","toLabel":"Open 400m","provenance":"coaching","addMin":0.5,"addMid":0.75,"addMax":1,"note":"A flying relay split typically runs 0.5-1.0s faster than an open 400 (no blocks, rolling exchange)."},{"id":"open-400-to-relay-split","kind":"range","fromLabel":"Open 400m","toLabel":"4x400 Relay Split","provenance":"coaching","addMin":-1,"addMid":-0.75,"addMax":-0.5,"note":"Expect a relay leg 0.5-1.0s quicker than the athlete's open 400."}]},"sources":[{"title":"Canonical HTTP binding at the documented implementation revision","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/calculator-functions.ts","note":"Existing calculation handler; math metadata is additive."},{"title":"lib/formulas/event-conversion.ts","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/formulas/event-conversion.ts","note":"Primary implementation source for these equations/tables, not a claim of scientific calibration."},{"title":"NCAA event conversion factors","url":"https://ncaaorg.s3.amazonaws.com/championships/sports/crosstrack/common/XTF_EventConversions.pdf","note":"Multiplicative factors and final round-up convention; rechecked 2026-10-21. Product non-NCAA rows have separate provenance."}]},"annotations":{"readOnlyHint":true,"consequentialHint":false},"name":"Track Event Conversion Calculator","description":"This track conversion calculator converts times between metric and imperial near-equivalent events using official NCAA conversion factors (mile↔1500m, 55m↔60m, 55H↔60H, mile relay↔4x400, 4x110y↔4x100), exact distance-ratio statistician conventions (1600↔mile, 3200↔2 mile), Riegel-based estimates where no official factor exists (1500↔1600, 3000↔3200), and settled coaching rules of thumb (600m→800m, relay split↔open 400). Every result shows the factor or rule applied and clearly labels whether it is NCAA official, an exact ratio, an estimate, or a coaching convention — so you always know which numbers a governing body will actually accept.","category":"Conversions & Adjustments","method":"POST","endpoint":"/api/calculators/track-event-conversion","page":"/calculators/track-event-conversion","inputSchema":{"type":"object","required":["timeSeconds","conversionId"],"properties":{"timeSeconds":{"type":"number","description":"Input time in seconds.","minimum":0},"conversionId":{"type":"string","description":"Registered conversion id.","enum":["mile-to-1500","1500-to-mile","55-to-60","60-to-55","55h-to-60h","60h-to-55h","mile-relay-to-4x400","4x110y-to-4x100","dmr-yards-to-metric","1600-to-mile","mile-to-1600","3200-to-2mile","2mile-to-3200","1500-to-1600","1600-to-1500","3000-to-3200","3200-to-3000","600-to-800","relay-split-to-open-400","open-400-to-relay-split"]},"gender":{"type":"string","description":"Gender for gender-specific conversion factors.","enum":["men","women"],"default":"men"}}},"example":{"timeSeconds":229.71,"conversionId":"1500-to-mile","gender":"men"}},{"slug":"indoor-track-conversion","math":{"href":"https://www.tracktoolspro.com/api/calculators/indoor-track-conversion","jsonPointer":"/calculator/math","version":"2026-10-21.1","implementationVersion":"b5a8aca7b85361476e0321a08b7fa5f516fc9535","scope":"Canonical HTTP function and documented corresponding mounted-form math. This is public inspectable documentation, not access control or independent empirical validation.","unitNotation":"Input paths use [] and *; output paths are JSON Pointers with * (one segment) and ** (descendants). Empty output path denotes scalar result. Units apply to numeric quantities or explicitly described numeric strings; labels/statuses/booleans are dimensionless. More specific units, including count/index exceptions, override broad patterns.","interfaceNotes":["HTTP input is described by the adjacent inputSchema. The original handlers may accept numeric strings; this metadata adds no validation.","Mounted forms accept displayed clock/unit strings and enforce their own limits. Mounted tools limit strings to 200 characters and numeric parts to magnitude 1000000. Do not assume mounted/API input interchangeability.","Some legacy extreme/invalid tuples can produce null/empty results or nonfinite numbers serialized as null. Those are unavailable answers, not exact numerical predictions. Per-calculator domain describes the intended mathematical inputs."],"kind":"lookup-and-arithmetic","implementationFiles":["lib/formulas/track-size-conversion.ts"],"equations":["Select factor by gender,event,and one of undersizedToFlat,bankedToFlat,undersizedToBanked,flatToBanked; same type uses 1.","convertedSeconds=roundHalfUp(timeSeconds*factor). Unpublished directions return null; do not manufacture reciprocals."],"inputUnits":{"timeSeconds":"s","event":"enum/string (dimensionless)","gender":"enum/string (dimensionless)","fromType":"enum/string (dimensionless)","toType":"enum/string (dimensionless)"},"outputUnits":{"/originalSeconds":"s","/convertedSeconds":"s","/factor":"dimensionless"},"domain":["Positive finite time, known event/gender and published direction or identity."],"rounding":["round(round(x*1e6)/1e4)/100 (half-up0.01s). Chart itself does not specify this rounding rule."],"assumptions":["Uses the entered values and the selected convention; this documentation does not strengthen existing validation."],"limitations":["104stored chart factors; comparison output is not a verified qualifying mark. Observed men mile300.40s flat-to-banked: local296.61, official TFRRS296.62. This single case establishes no universal rounding rule."],"mountedPageNotes":[],"workedExamples":[{"input":{"timeSeconds":300,"event":"mile","gender":"men","fromType":"flat","toType":"banked"},"expected":{"/convertedSeconds":296.22},"absoluteTolerance":1e-8,"note":"Illustrative canonical-handler result; not independent validation of an empirical model."}],"constantsAndTables":{"facilityFactors":{"men":{"200m":{"undersizedToFlat":0.9872,"bankedToFlat":1.0179,"undersizedToBanked":0.9698,"flatToBanked":0.9824},"400m":{"undersizedToFlat":0.9901,"bankedToFlat":1.016,"undersizedToBanked":0.9746,"flatToBanked":0.9843},"500m":{"undersizedToFlat":0.9909,"bankedToFlat":1.0154,"undersizedToBanked":0.9758,"flatToBanked":0.9848},"600y":{"undersizedToFlat":0.9912,"bankedToFlat":1.0152,"undersizedToBanked":0.9763,"flatToBanked":0.985},"600m":{"undersizedToFlat":0.9915,"bankedToFlat":1.015,"undersizedToBanked":0.9768,"flatToBanked":0.9852},"800m":{"undersizedToFlat":0.9923,"bankedToFlat":1.0143,"undersizedToBanked":0.9783,"flatToBanked":0.9859},"1000m":{"undersizedToFlat":0.9929,"bankedToFlat":1.0138,"undersizedToBanked":0.9794,"flatToBanked":0.9864},"mile":{"undersizedToFlat":0.9941,"bankedToFlat":1.0128,"undersizedToBanked":0.9816,"flatToBanked":0.9874},"3000m":{"undersizedToFlat":0.9953,"bankedToFlat":1.0116,"undersizedToBanked":0.9839,"flatToBanked":0.9885},"5000m":{"undersizedToFlat":0.9961,"bankedToFlat":1.0107,"undersizedToBanked":0.9855,"flatToBanked":0.9894},"4x400":{"undersizedToFlat":0.9901,"bankedToFlat":1.016,"undersizedToBanked":0.9746,"flatToBanked":0.9843},"4x800":{"undersizedToFlat":0.9923,"bankedToFlat":1.0143,"undersizedToBanked":0.9783,"flatToBanked":0.9859},"dmr":{"undersizedToFlat":0.9931,"bankedToFlat":1.0136,"undersizedToBanked":0.9798,"flatToBanked":0.9866}},"women":{"200m":{"undersizedToFlat":0.99,"bankedToFlat":1.0155,"undersizedToBanked":0.9749,"flatToBanked":0.9847},"400m":{"undersizedToFlat":0.9929,"bankedToFlat":1.0133,"undersizedToBanked":0.9799,"flatToBanked":0.9869},"500m":{"undersizedToFlat":0.9937,"bankedToFlat":1.0127,"undersizedToBanked":0.9812,"flatToBanked":0.9874},"600y":{"undersizedToFlat":0.994,"bankedToFlat":1.0125,"undersizedToBanked":0.9818,"flatToBanked":0.9877},"600m":{"undersizedToFlat":0.9943,"bankedToFlat":1.0122,"undersizedToBanked":0.9823,"flatToBanked":0.9879},"800m":{"undersizedToFlat":0.9951,"bankedToFlat":1.0115,"undersizedToBanked":0.9838,"flatToBanked":0.9886},"1000m":{"undersizedToFlat":0.9958,"bankedToFlat":1.0109,"undersizedToBanked":0.985,"flatToBanked":0.9892},"mile":{"undersizedToFlat":0.9969,"bankedToFlat":1.0099,"undersizedToBanked":0.9871,"flatToBanked":0.9902},"3000m":{"undersizedToFlat":0.9981,"bankedToFlat":1.0086,"undersizedToBanked":0.9896,"flatToBanked":0.9915},"5000m":{"undersizedToFlat":0.9989,"bankedToFlat":1.0077,"undersizedToBanked":0.9913,"flatToBanked":0.9924},"4x400":{"undersizedToFlat":0.9929,"bankedToFlat":1.0133,"undersizedToBanked":0.9799,"flatToBanked":0.9869},"4x800":{"undersizedToFlat":0.9951,"bankedToFlat":1.0115,"undersizedToBanked":0.9838,"flatToBanked":0.9886},"dmr":{"undersizedToFlat":0.9959,"bankedToFlat":1.0107,"undersizedToBanked":0.9853,"flatToBanked":0.9894}}},"chartEdition":"USTFCCCA 29 January 2024; 104 published factors; product uses half-up comparisons."},"sources":[{"title":"Canonical HTTP binding at the documented implementation revision","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/calculator-functions.ts","note":"Existing calculation handler; math metadata is additive."},{"title":"lib/formulas/track-size-conversion.ts","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/formulas/track-size-conversion.ts","note":"Primary implementation source for these equations/tables, not a claim of scientific calibration."},{"title":"USTFCCCA NCAA indoor conversion charts, 29 Jan 2024","url":"https://www.ustfccca.org/assets/NCAA-Indoor-Track-Size-Conversion-Charts.pdf?DB_OEM_ID=27900","note":"29January2024 factor chart. Does not establish a universal qualifying rounding rule. Product uses nearest-hundredth comparison; observed TFRRS difference remains disclosed."}]},"annotations":{"readOnlyHint":true,"consequentialHint":false},"name":"NCAA Indoor Track Size Converter","description":"Compare indoor times across flat 200m, banked/oversized and undersized facilities using published NCAA factors for 13 events and two tables. The displayed comparison rounds half-up to a hundredth; it is not a verified TFRRS qualifying mark. Check the official converter and current meet requirements before entering or qualifying an athlete.","category":"Conversions & Adjustments","method":"POST","endpoint":"/api/calculators/indoor-track-conversion","page":"/calculators/indoor-track-conversion","inputSchema":{"type":"object","required":["timeSeconds","event","gender","fromType","toType"],"properties":{"timeSeconds":{"type":"number","description":"Input indoor mark in seconds.","minimum":0},"event":{"type":"string","description":"Indoor event key.","enum":["200m","400m","500m","600y","600m","800m","1000m","mile","3000m","5000m","4x400","4x800","dmr"]},"gender":{"type":"string","description":"Gender table.","enum":["men","women"],"default":"men"},"fromType":{"type":"string","description":"Source track type.","enum":["flat","banked","undersized"]},"toType":{"type":"string","description":"Target track type.","enum":["flat","banked","undersized"]}}},"example":{"timeSeconds":300,"event":"mile","gender":"men","fromType":"flat","toType":"banked"}},{"slug":"xc-track-converter","math":{"href":"https://www.tracktoolspro.com/api/calculators/xc-track-converter","jsonPointer":"/calculator/math","version":"2026-10-21.1","implementationVersion":"b5a8aca7b85361476e0321a08b7fa5f516fc9535","scope":"Canonical HTTP function and documented corresponding mounted-form math. This is public inspectable documentation, not access control or independent empirical validation.","unitNotation":"Input paths use [] and *; output paths are JSON Pointers with * (one segment) and ** (descendants). Empty output path denotes scalar result. Units apply to numeric quantities or explicitly described numeric strings; labels/statuses/booleans are dimensionless. More specific units, including count/index exceptions, override broad patterns.","interfaceNotes":["HTTP input is described by the adjacent inputSchema. The original handlers may accept numeric strings; this metadata adds no validation.","Mounted forms accept displayed clock/unit strings and enforce their own limits. Mounted tools limit strings to 200 characters and numeric parts to magnitude 1000000. Do not assume mounted/API input interchangeability.","Some legacy extreme/invalid tuples can produce null/empty results or nonfinite numbers serialized as null. Those are unavailable answers, not exact numerical predictions. Per-calculator domain describes the intended mathematical inputs."],"kind":"heuristic","implementationFiles":["lib/formulas/xc-conversion.ts","lib/formulas/riegel.ts"],"equations":["trackToXc: flatEquivalentSeconds=seconds*(toMeters/fromMeters)^exponent (identity at same distance); convertedSeconds=flatEquivalentSeconds*courseFactor.","xcToTrack: flatEquivalentSeconds=seconds/courseFactor at source distance; convertedSeconds=flatEquivalentSeconds*(toMeters/fromMeters)^exponent.","courseDeltaSeconds is the course-only difference; perMileDeltaSeconds=courseDeltaSeconds*1609.34/(toMeters in forward, fromMeters in reverse)."],"inputUnits":{"seconds":"s","fromMeters":"m","toMeters":"m","direction":"enum/string (dimensionless)","course":"enum/string (dimensionless)","exponent":"dimensionless"},"outputUnits":{"/inputSeconds":"s","/convertedSeconds":"s","/factor":"dimensionless","/courseDeltaSeconds":"s","/perMileDeltaSeconds":"s/mile","/flatEquivalentSeconds":"s"},"domain":["Positive finite time/distances and known course/direction; HTTP exponent>=1, default 1.06; invalid tuples return null."],"rounding":["Raw IEEE-754 numbers; the mounted page formats clocks separately."],"assumptions":["Uses the entered values and the selected convention; this documentation does not strengthen existing validation."],"limitations":["Course multipliers1.03/1.06/1.08/1.10 are coaching heuristics, not independent course calibration. Fast/flat is not identity. No qualification equivalent."],"mountedPageNotes":[],"workedExamples":[{"input":{"seconds":900,"fromMeters":5000,"toMeters":5000,"direction":"trackToXc","course":"average"},"expected":{"/convertedSeconds":954},"absoluteTolerance":1e-8,"note":"Illustrative canonical-handler result; not independent validation of an empirical model."}],"constantsAndTables":{"courseFactors":{"fast":1.03,"average":1.06,"hilly":1.08,"championship":1.1},"defaultExponent":1.06,"metersPerMile":1609.34},"sources":[{"title":"Canonical HTTP binding at the documented implementation revision","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/calculator-functions.ts","note":"Existing calculation handler; math metadata is additive."},{"title":"lib/formulas/xc-conversion.ts","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/formulas/xc-conversion.ts","note":"Primary implementation source for these equations/tables, not a claim of scientific calibration."},{"title":"lib/formulas/riegel.ts","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/formulas/riegel.ts","note":"Primary implementation source for these equations/tables, not a claim of scientific calibration."},{"title":"Riegel, Athletic Records and Human Endurance,1981","url":"https://rrtc.net/Articles/ARHE.pdf","note":"Riegel 1981 primary article; fitted exponents vary. Product default 1.06 is an explicit convention, not a universal accuracy claim. Retained source reviewed 2026-10-16."}]},"annotations":{"readOnlyHint":true,"consequentialHint":false},"name":"XC to Track Time Converter","description":"This XC to track conversion tool uses the settled coaching conventions: track to XC multiplies by a course factor (×1.03 fast and flat, ×1.06 average, ×1.08 hilly, ×1.10 muddy championship courses), and XC to track divides by the same factor so the conversion is a true inverse. Distance changes — like track 5K to XC 8K — are combined with the Riegel formula. Every result shows the seconds-added equivalent and per-mile delta, because terrain, footing, and weather make every cross country estimate approximate.","category":"Cross Country","method":"POST","endpoint":"/api/calculators/xc-track-converter","page":"/calculators/xc-track-converter","inputSchema":{"type":"object","required":["seconds","fromMeters","toMeters","direction","course"],"properties":{"seconds":{"type":"number","description":"Input time in seconds.","minimum":0},"fromMeters":{"type":"number","description":"Input distance in meters.","minimum":0},"toMeters":{"type":"number","description":"Output distance in meters.","minimum":0},"direction":{"type":"string","description":"Conversion direction.","enum":["trackToXc","xcToTrack"],"default":"trackToXc"},"course":{"type":"string","description":"XC course difficulty.","enum":["fast","average","hilly","championship"],"default":"average"},"exponent":{"type":"number","description":"Optional Riegel exponent.","default":1.06}}},"example":{"seconds":900,"fromMeters":5000,"toMeters":5000,"direction":"trackToXc","course":"average"}},{"slug":"critical-velocity-calculator","math":{"href":"https://www.tracktoolspro.com/api/calculators/critical-velocity-calculator","jsonPointer":"/calculator/math","version":"2026-10-21.1","implementationVersion":"b5a8aca7b85361476e0321a08b7fa5f516fc9535","scope":"Canonical HTTP function and documented corresponding mounted-form math. This is public inspectable documentation, not access control or independent empirical validation.","unitNotation":"Input paths use [] and *; output paths are JSON Pointers with * (one segment) and ** (descendants). Empty output path denotes scalar result. Units apply to numeric quantities or explicitly described numeric strings; labels/statuses/booleans are dimensionless. More specific units, including count/index exceptions, override broad patterns.","interfaceNotes":["HTTP input is described by the adjacent inputSchema. The original handlers may accept numeric strings; this metadata adds no validation.","Mounted forms accept displayed clock/unit strings and enforce their own limits. Mounted tools limit strings to 200 characters and numeric parts to magnitude 1000000. Do not assume mounted/API input interchangeability.","Some legacy extreme/invalid tuples can produce null/empty results or nonfinite numbers serialized as null. Those are unavailable answers, not exact numerical predictions. Per-calculator domain describes the intended mathematical inputs."],"kind":"model-fit","implementationFiles":["lib/formulas/critical-velocity.ts"],"equations":["Normalize two efforts by duration. cs=(d2-d1)/(t2-t1); dPrime=d1-cs*t1; pacePerMile=1609.34/cs, perKm=1000/cs, per400=400/cs.","Optional predictedSeconds=(targetDistanceMeters-dPrime)/cs; predictedDistanceMeters=dPrime+cs*targetTimeSeconds.","Tinman mode: cvVelocity=(5000/fiveKSeconds)*0.9533; CV pace=unitMeters/cvVelocity; fiveK pace=fiveKSeconds*unitMeters/5000."],"inputUnits":{"mode":"enum/string (dimensionless)","d1Meters":"m","t1Seconds":"s","d2Meters":"m","t2Seconds":"s","targetDistanceMeters":"m","targetTimeSeconds":"s","fiveKSeconds":"s"},"outputUnits":{"/cs":"m/s","/dPrime":"m","/pacePerMileSeconds":"s/mile","/pacePerKmSeconds":"s/km","/pacePer400mSeconds":"s/400m","/predictedSeconds":"s","/predictedDistanceMeters":"m","/cvVelocity":"m/s","/cvPacePerMileSeconds":"s/mile","/cvPacePerKmSeconds":"s/km","/fiveKPacePerMileSeconds":"s/mile","/fiveKPacePerKmSeconds":"s/km"},"domain":["Positive finite efforts, distinct increasing duration/distance and dPrime>=0; otherwise null. Prediction requires distance>dPrime or positive target duration; missing predictions are null."],"rounding":["Raw IEEE-754 numbers; the mounted page formats clocks separately."],"assumptions":["Uses the entered values and the selected convention; this documentation does not strengthen existing validation."],"limitations":["Two-point line has no fit-error estimate; D-prime is not measured anaerobic capacity. Tinman0.9533 is a heuristic, not validated across athletes."],"mountedPageNotes":[],"workedExamples":[{"input":{"mode":"twoPoint","d1Meters":1600,"t1Seconds":300,"d2Meters":3200,"t2Seconds":650,"targetDistanceMeters":5000},"expected":{"/cs":4.571428571428571,"/dPrime":228.57142857142867},"absoluteTolerance":1e-8,"note":"Illustrative canonical-handler result; not independent validation of an empirical model."}],"constantsAndTables":{"tinmanFactor":0.9533,"metersPerMile":1609.34},"sources":[{"title":"Canonical HTTP binding at the documented implementation revision","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/calculator-functions.ts","note":"Existing calculation handler; math metadata is additive."},{"title":"lib/formulas/critical-velocity.ts","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/formulas/critical-velocity.ts","note":"Primary implementation source for these equations/tables, not a claim of scientific calibration."}]},"annotations":{"readOnlyHint":true,"consequentialHint":false},"name":"Critical Velocity Calculator","description":"This critical velocity calculator implements two models side by side. The two-point critical speed model is the physiology standard: from two all-out efforts it computes CS = (D2 − D1) ÷ (T2 − T1) and D′ (anaerobic distance capacity) = D1 − CS × T1, then predicts time for any distance via T = (D − D′) ÷ CS, valid for roughly 2–30 minute efforts. The Tinman/Schwartz estimate is the popular single-race shortcut: CV velocity = 5K velocity × 0.9533, i.e. CV pace is your 5K pace divided by 0.9533 — a slightly slower pace used for CV repeats.","category":"Training & Fitness","method":"POST","endpoint":"/api/calculators/critical-velocity-calculator","page":"/calculators/critical-velocity-calculator","inputSchema":{"type":"object","required":["mode"],"properties":{"mode":{"type":"string","description":"Calculation mode.","enum":["twoPoint","tinman"],"default":"twoPoint"},"d1Meters":{"type":"number","description":"First effort distance in meters.","minimum":0},"t1Seconds":{"type":"number","description":"First effort time in seconds.","minimum":0},"d2Meters":{"type":"number","description":"Second effort distance in meters.","minimum":0},"t2Seconds":{"type":"number","description":"Second effort time in seconds.","minimum":0},"targetDistanceMeters":{"type":"number","description":"Optional distance to predict from the CS model.","minimum":0},"targetTimeSeconds":{"type":"number","description":"Optional time to predict distance from the CS model.","minimum":0},"fiveKSeconds":{"type":"number","description":"5K time in seconds for Tinman mode.","minimum":0}}},"example":{"mode":"twoPoint","d1Meters":1600,"t1Seconds":300,"d2Meters":3200,"t2Seconds":650,"targetDistanceMeters":5000}},{"slug":"age-grading-calculator","math":{"href":"https://www.tracktoolspro.com/api/calculators/age-grading-calculator","jsonPointer":"/calculator/math","version":"2026-10-21.1","implementationVersion":"b5a8aca7b85361476e0321a08b7fa5f516fc9535","scope":"Canonical HTTP function and documented corresponding mounted-form math. This is public inspectable documentation, not access control or independent empirical validation.","unitNotation":"Input paths use [] and *; output paths are JSON Pointers with * (one segment) and ** (descendants). Empty output path denotes scalar result. Units apply to numeric quantities or explicitly described numeric strings; labels/statuses/booleans are dimensionless. More specific units, including count/index exceptions, override broad patterns.","interfaceNotes":["HTTP input is described by the adjacent inputSchema. The original handlers may accept numeric strings; this metadata adds no validation.","Mounted forms accept displayed clock/unit strings and enforce their own limits. Mounted tools limit strings to 200 characters and numeric parts to magnitude 1000000. Do not assume mounted/API input interchangeability.","Some legacy extreme/invalid tuples can produce null/empty results or nonfinite numbers serialized as null. Those are unavailable answers, not exact numerical predictions. Per-calculator domain describes the intended mathematical inputs."],"kind":"table-model","implementationFiles":["lib/formulas/age-grading.ts","lib/formulas/age-grading-data.ts"],"equations":["factor=selected event/sex factors[age-25]; openStandardSeconds=stored sex/event standard. No interpolation.","ageStandardSeconds=openStandardSeconds/factor; percent=100*openStandardSeconds/(factor*actualSeconds); equivalentOpenSeconds=actualSeconds*factor; tier is first descending percent threshold met."],"inputUnits":{"sex":"enum/string (dimensionless)","age":"whole years","eventKey":"enum/string (dimensionless)","actualSeconds":"s"},"outputUnits":{"/percent":"%","/equivalentOpenSeconds":"s","/ageStandardSeconds":"s","/openStandardSeconds":"s","/factor":"dimensionless"},"domain":["API ages25..90 integer, supported event/sex, positive actual time for percent/equivalent; unsupported table selection errors, invalid time may produce null score fields."],"rounding":["Raw IEEE-754 numbers; the mounted page formats clocks separately."],"assumptions":["Uses the entered values and the selected convention; this documentation does not strengthen existing validation."],"limitations":["Reference tables, not current world records or eligibility. Stored2015 track naming has unresolved edition provenance;2025 road label identifies the stored author table. Statistical sex/age bands are not physiology measurements."],"mountedPageNotes":[],"workedExamples":[{"input":{"sex":"M","age":50,"eventKey":"5k","actualSeconds":1350},"expected":{"/percent":64.9150575076501,"/factor":0.8775},"absoluteTolerance":1e-8,"note":"Illustrative canonical-handler result; not independent validation of an empirical model."}],"constantsAndTables":{"ageMin":25,"ageMax":90,"eventTables":[{"key":"100m","label":"100m","surface":"track","edition":"WMA 2015 track factors (Howard Grubb)","standards":{"M":9.79,"F":10.49},"factors":{"M":[1,1,1,1,1,1,1,1,1,0.9968,0.9893,0.9823,0.9754,0.9684,0.9615,0.9545,0.948,0.9415,0.935,0.9285,0.922,0.9159,0.9099,0.9038,0.8978,0.8917,0.886,0.8803,0.8747,0.869,0.8633,0.858,0.8527,0.8473,0.842,0.8367,0.8317,0.8267,0.8217,0.8167,0.8117,0.807,0.8023,0.7975,0.7928,0.7881,0.7788,0.7695,0.7603,0.751,0.7417,0.7312,0.7208,0.7103,0.6999,0.6894,0.6778,0.6663,0.6547,0.6432,0.6316,0.6205,0.6093,0.5982,0.587,0.5759],"F":[1,1,1,1,1,1,1,1,1,1,1,1,0.9899,0.9781,0.9663,0.9545,0.944,0.9335,0.923,0.9125,0.902,0.8926,0.8832,0.8739,0.8645,0.8551,0.8466,0.8381,0.8297,0.8212,0.8127,0.805,0.7974,0.7897,0.7821,0.7744,0.7674,0.7604,0.7535,0.7465,0.7395,0.7331,0.7267,0.7204,0.714,0.7076,0.6983,0.689,0.6798,0.6705,0.6612,0.6538,0.6465,0.6391,0.6318,0.6244,0.6071,0.5898,0.5725,0.5552,0.5379,0.5215,0.5052,0.4888,0.4725,0.4561]}},{"key":"200m","label":"200m","surface":"track","edition":"WMA 2015 track factors (Howard Grubb)","standards":{"M":19.32,"F":21.34},"factors":{"M":[1,1,1,1,1,1,0.9959,0.9879,0.98,0.972,0.9641,0.9568,0.9494,0.9421,0.9347,0.9274,0.9206,0.9138,0.9071,0.9003,0.8935,0.8872,0.8809,0.8745,0.8682,0.8619,0.856,0.8501,0.8443,0.8384,0.8325,0.827,0.8215,0.816,0.8105,0.805,0.7999,0.7947,0.7896,0.7844,0.7793,0.7732,0.7671,0.761,0.7549,0.7488,0.7375,0.7263,0.715,0.7038,0.6925,0.6811,0.6697,0.6583,0.6469,0.6355,0.622,0.6086,0.5951,0.5817,0.5682,0.5488,0.5294,0.51,0.4906,0.4712],"F":[1,1,1,1,1,1,1,1,1,1,1,0.994,0.9813,0.9687,0.956,0.9434,0.9323,0.9211,0.91,0.8988,0.8877,0.8778,0.8679,0.858,0.8481,0.8382,0.8293,0.8205,0.8116,0.8028,0.7939,0.7859,0.7779,0.77,0.762,0.754,0.7468,0.7396,0.7324,0.7252,0.718,0.7114,0.7049,0.6983,0.6918,0.6852,0.6792,0.6732,0.6673,0.6613,0.6553,0.6428,0.6303,0.6178,0.6053,0.5928,0.5759,0.5589,0.542,0.525,0.5081,0.4886,0.469,0.4495,0.4299,0.4104]}},{"key":"400m","label":"400m","surface":"track","edition":"WMA 2015 track factors (Howard Grubb)","standards":{"M":43.18,"F":47.6},"factors":{"M":[1,1,1,1,1,1,1,0.9929,0.9854,0.9778,0.9702,0.9632,0.9561,0.9491,0.942,0.935,0.9285,0.9219,0.9154,0.9088,0.9023,0.8962,0.8901,0.884,0.8779,0.8718,0.8661,0.8604,0.8547,0.849,0.8433,0.838,0.8326,0.8273,0.8219,0.8166,0.8116,0.8066,0.8016,0.7966,0.7916,0.7797,0.7677,0.7558,0.7438,0.7319,0.7184,0.7049,0.6913,0.6778,0.6643,0.6531,0.6419,0.6306,0.6194,0.6082,0.5919,0.5756,0.5592,0.5429,0.5266,0.5085,0.4904,0.4724,0.4543,0.4362],"F":[1,1,1,1,1,1,1,0.9927,0.9811,0.9696,0.958,0.9477,0.9374,0.9271,0.9168,0.9065,0.8972,0.888,0.8787,0.8695,0.8602,0.8518,0.8435,0.8351,0.8268,0.8184,0.8108,0.8032,0.7957,0.7881,0.7805,0.7736,0.7667,0.7598,0.7529,0.746,0.7397,0.7333,0.727,0.7206,0.7143,0.7037,0.693,0.6824,0.6717,0.6611,0.6464,0.6317,0.6171,0.6024,0.5877,0.5759,0.5642,0.5524,0.5407,0.5289,0.5155,0.5022,0.4888,0.4755,0.4621,0.449,0.4359,0.4229,0.4098,0.3967]}},{"key":"800m","label":"800m","surface":"track","edition":"WMA 2015 track factors (Howard Grubb)","standards":{"M":101.11,"F":113.28},"factors":{"M":[1,1,1,1,1,1,1,1,1,1,0.9971,0.9878,0.9785,0.9691,0.9598,0.9505,0.942,0.9335,0.9251,0.9166,0.9081,0.9003,0.8926,0.8848,0.8771,0.8693,0.8622,0.855,0.8479,0.8407,0.8336,0.827,0.8205,0.8139,0.8074,0.8008,0.7947,0.7887,0.7826,0.7766,0.7705,0.7624,0.7543,0.7462,0.7381,0.73,0.7191,0.7082,0.6972,0.6863,0.6754,0.6644,0.6534,0.6423,0.6313,0.6203,0.6038,0.5873,0.5708,0.5543,0.5378,0.5159,0.494,0.4722,0.4503,0.4284],"F":[1,1,1,1,1,1,1,1,1,1,1,1,0.9997,0.9906,0.9814,0.9722,0.9638,0.9554,0.9471,0.9387,0.9303,0.9226,0.9149,0.9072,0.8995,0.8918,0.8806,0.8693,0.8581,0.8468,0.8356,0.8239,0.8121,0.8004,0.7886,0.7769,0.7621,0.7473,0.7324,0.7176,0.7028,0.6893,0.6759,0.6624,0.649,0.6355,0.6205,0.6054,0.5904,0.5753,0.5603,0.547,0.5336,0.5203,0.5069,0.4936,0.4808,0.468,0.4552,0.4424,0.4296,0.4172,0.4048,0.3925,0.3801,0.3677]}},{"key":"1500m","label":"1500m","surface":"track","edition":"WMA 2015 track factors (Howard Grubb)","standards":{"M":205.8,"F":232.47},"factors":{"M":[1,1,1,0.9999,0.9991,0.9975,0.9952,0.9922,0.9885,0.984,0.9788,0.9729,0.9662,0.9592,0.9521,0.9451,0.938,0.931,0.924,0.9169,0.9099,0.9028,0.8958,0.8888,0.8817,0.8747,0.8676,0.8606,0.8536,0.8465,0.8395,0.8324,0.8254,0.8184,0.8113,0.8043,0.7972,0.7902,0.7832,0.7761,0.7691,0.762,0.755,0.7479,0.7402,0.7319,0.723,0.7134,0.7031,0.6923,0.6808,0.6687,0.6559,0.6425,0.6285,0.6138,0.5985,0.5825,0.566,0.5488,0.5309,0.5124,0.4933,0.4735,0.4531,0.4321],"F":[1,1,1,1,0.9998,0.9989,0.9971,0.9946,0.9913,0.9871,0.9822,0.9765,0.9701,0.9628,0.9547,0.9459,0.9362,0.9258,0.9151,0.9044,0.8937,0.8831,0.8724,0.8617,0.851,0.8403,0.8297,0.819,0.8083,0.7976,0.7869,0.7763,0.7656,0.7549,0.7442,0.7335,0.7229,0.7122,0.7015,0.6908,0.6801,0.6695,0.6588,0.6481,0.6374,0.6267,0.6161,0.6054,0.5947,0.584,0.5733,0.5627,0.552,0.5413,0.5306,0.5199,0.5087,0.4962,0.4825,0.4676,0.4515,0.4343,0.4158,0.3961,0.3752,0.3531]}},{"key":"mile","label":"Mile","surface":"track","edition":"WMA 2015 track factors (Howard Grubb)","standards":{"M":222.6,"F":251.6},"factors":{"M":[1,1,1,0.9999,0.9991,0.9975,0.9952,0.9922,0.9885,0.984,0.9788,0.9729,0.9662,0.9592,0.9521,0.9451,0.938,0.931,0.924,0.9169,0.9099,0.9028,0.8958,0.8888,0.8817,0.8747,0.8676,0.8606,0.8536,0.8465,0.8395,0.8324,0.8254,0.8184,0.8113,0.8043,0.7972,0.7902,0.7832,0.7761,0.7691,0.762,0.755,0.7479,0.7402,0.7319,0.723,0.7134,0.7031,0.6923,0.6808,0.6687,0.6559,0.6425,0.6285,0.6138,0.5985,0.5825,0.566,0.5488,0.5309,0.5124,0.4933,0.4735,0.4531,0.4321],"F":[1,1,1,1,0.9998,0.9989,0.9972,0.9948,0.9915,0.9875,0.9827,0.9771,0.9707,0.9636,0.9557,0.9469,0.9375,0.9272,0.9165,0.9058,0.8951,0.8844,0.8737,0.863,0.8523,0.8416,0.8309,0.8202,0.8095,0.7988,0.7881,0.7774,0.7667,0.756,0.7453,0.7346,0.7239,0.7132,0.7025,0.6918,0.6811,0.6704,0.6597,0.649,0.6383,0.6276,0.6169,0.6062,0.5955,0.5848,0.5741,0.5634,0.5527,0.542,0.5313,0.5206,0.5091,0.4965,0.4827,0.4678,0.4516,0.4343,0.4158,0.3961,0.3752,0.3532]}},{"key":"3000m","label":"3000m","surface":"track","edition":"WMA 2015 track factors (Howard Grubb)","standards":{"M":440,"F":501.42},"factors":{"M":[1,1,1,0.9999,0.9991,0.9975,0.9952,0.9922,0.9885,0.984,0.9788,0.9729,0.9662,0.9592,0.9521,0.9451,0.938,0.931,0.924,0.9169,0.9099,0.9028,0.8958,0.8888,0.8817,0.8747,0.8676,0.8606,0.8536,0.8465,0.8395,0.8324,0.8254,0.8184,0.8113,0.8043,0.7972,0.7902,0.7832,0.7761,0.7691,0.762,0.755,0.7479,0.7402,0.7319,0.723,0.7134,0.7031,0.6923,0.6808,0.6687,0.6559,0.6425,0.6285,0.6138,0.5985,0.5825,0.566,0.5488,0.5309,0.5124,0.4933,0.4735,0.4531,0.4321],"F":[1,1,1,1,1,0.9994,0.9981,0.9962,0.9935,0.9902,0.9861,0.9813,0.9759,0.9697,0.9628,0.9553,0.947,0.938,0.9283,0.918,0.9071,0.8962,0.8854,0.8745,0.8636,0.8527,0.8419,0.831,0.8201,0.8092,0.7984,0.7875,0.7766,0.7657,0.7549,0.744,0.7331,0.7222,0.7114,0.7005,0.6896,0.6787,0.6678,0.657,0.6461,0.6352,0.6243,0.6135,0.6026,0.5917,0.5808,0.57,0.5591,0.5482,0.5373,0.5257,0.5131,0.4993,0.4845,0.4686,0.4517,0.4336,0.4145,0.3942,0.3729,0.3506]}},{"key":"5k","label":"5,000m / 5K Road","surface":"road","edition":"WMA/USATF 2025 road factors (Lytton-Jones)","standards":{"M":769,"F":834},"factors":{"M":[1,1,1,1,1,0.9999,0.9988,0.9965,0.993,0.9883,0.9824,0.9755,0.9685,0.9615,0.9545,0.9475,0.9405,0.9335,0.9265,0.9195,0.9125,0.9055,0.8985,0.8915,0.8845,0.8775,0.8705,0.8635,0.8565,0.8495,0.8425,0.8355,0.8285,0.8215,0.8145,0.8075,0.8005,0.7935,0.7865,0.7795,0.7725,0.7655,0.7585,0.7514,0.7436,0.7353,0.7264,0.7169,0.7068,0.696,0.6847,0.6728,0.6603,0.6472,0.6334,0.6191,0.6042,0.5887,0.5726,0.5558,0.5385,0.5206,0.5021,0.483,0.4632,0.4429],"F":[1,1,0.9997,0.999,0.9977,0.9959,0.9936,0.9908,0.9875,0.9836,0.9793,0.9744,0.9691,0.9632,0.9568,0.9499,0.9425,0.9346,0.9262,0.9172,0.9078,0.898,0.8883,0.8786,0.8689,0.8592,0.8495,0.8398,0.8301,0.8204,0.8107,0.8009,0.7912,0.7815,0.7718,0.7621,0.7524,0.7427,0.733,0.7233,0.7136,0.7038,0.6941,0.6844,0.6747,0.665,0.6553,0.6456,0.6359,0.6262,0.6165,0.6067,0.597,0.5868,0.5758,0.564,0.5515,0.5382,0.5242,0.5094,0.4938,0.4775,0.4604,0.4426,0.424,0.4046]}},{"key":"10k","label":"10,000m / 10K Road","surface":"road","edition":"WMA/USATF 2025 road factors (Lytton-Jones)","standards":{"M":1584,"F":1726},"factors":{"M":[1,1,1,1,1,1,0.9996,0.9985,0.9967,0.9942,0.9909,0.9869,0.9822,0.9767,0.9705,0.9636,0.9561,0.9486,0.9411,0.9336,0.9261,0.9186,0.9111,0.9036,0.8961,0.8886,0.8811,0.8736,0.8661,0.8586,0.8511,0.8436,0.8361,0.8286,0.8211,0.8136,0.8061,0.7986,0.7911,0.7836,0.7761,0.7686,0.7611,0.7536,0.7461,0.7386,0.7308,0.7223,0.7131,0.7033,0.6928,0.6816,0.6697,0.6572,0.644,0.6301,0.6156,0.6004,0.5845,0.568,0.5508,0.5329,0.5143,0.4951,0.4752,0.4546],"F":[1,1,1,0.9998,0.9991,0.998,0.9964,0.9944,0.992,0.9891,0.9857,0.9819,0.9777,0.973,0.9679,0.9623,0.9563,0.9499,0.9429,0.9356,0.9278,0.9195,0.9109,0.9017,0.8921,0.8822,0.8723,0.8623,0.8524,0.8425,0.8325,0.8226,0.8126,0.8027,0.7928,0.7828,0.7729,0.7629,0.753,0.7431,0.7331,0.7232,0.7132,0.7033,0.6934,0.6834,0.6735,0.6635,0.6536,0.6437,0.6337,0.6234,0.6123,0.6005,0.5879,0.5745,0.5604,0.5455,0.5299,0.5135,0.4963,0.4784,0.4597,0.4403,0.4201,0.3991]}},{"key":"half-marathon","label":"Half Marathon","surface":"road","edition":"WMA/USATF 2025 road factors (Lytton-Jones)","standards":{"M":3451,"F":3772},"factors":{"M":[1,1,1,1,1,1,1,0.9996,0.9982,0.996,0.9928,0.9888,0.9839,0.9781,0.9714,0.9638,0.956,0.9483,0.9405,0.9327,0.9249,0.9171,0.9094,0.9016,0.8938,0.886,0.8782,0.8705,0.8627,0.8549,0.8471,0.8393,0.8316,0.8238,0.816,0.8082,0.8004,0.7927,0.7849,0.7771,0.7693,0.7615,0.7538,0.746,0.7382,0.7304,0.7223,0.7135,0.704,0.6938,0.683,0.6715,0.6593,0.6464,0.6328,0.6185,0.6036,0.588,0.5717,0.5547,0.537,0.5186,0.4996,0.4799,0.4595,0.4384],"F":[1,1,1,0.9998,0.9991,0.9979,0.9962,0.9941,0.9915,0.9884,0.9849,0.9809,0.9764,0.9714,0.966,0.9601,0.9537,0.9468,0.9395,0.9317,0.9234,0.9147,0.9055,0.8958,0.8856,0.8753,0.8649,0.8546,0.8442,0.8339,0.8235,0.8132,0.8028,0.7925,0.7821,0.7718,0.7614,0.7511,0.7407,0.7304,0.72,0.7097,0.6993,0.689,0.6786,0.6683,0.6579,0.6476,0.6372,0.6269,0.6165,0.6059,0.5945,0.5822,0.5692,0.5554,0.5407,0.5253,0.5091,0.4921,0.4742,0.4556,0.4362,0.4159,0.3949,0.3731]}},{"key":"marathon","label":"Marathon","surface":"road","edition":"WMA/USATF 2025 road factors (Lytton-Jones)","standards":{"M":7235,"F":7796},"factors":{"M":[1,1,1,1,1,1,1,1,1,1,1,0.9999,0.9979,0.9934,0.9865,0.9783,0.9701,0.9619,0.9537,0.9455,0.9373,0.9291,0.9209,0.9127,0.9045,0.8963,0.8881,0.8799,0.8717,0.8635,0.8553,0.8471,0.8389,0.8307,0.8225,0.8143,0.8061,0.7979,0.7897,0.7815,0.7733,0.7651,0.7569,0.7487,0.7405,0.7323,0.7241,0.7155,0.7063,0.6963,0.6857,0.6743,0.6623,0.6495,0.6361,0.6219,0.6071,0.5915,0.5753,0.5583,0.5407,0.5223,0.5033,0.4835,0.4631,0.4419],"F":[0.9988,1,1,0.9998,0.9992,0.9983,0.997,0.9953,0.9932,0.9907,0.9879,0.9847,0.9811,0.9771,0.9727,0.968,0.9629,0.9574,0.9515,0.9453,0.9386,0.9316,0.9242,0.9165,0.9083,0.8998,0.8909,0.8816,0.872,0.8619,0.8515,0.8407,0.8297,0.8186,0.8076,0.7965,0.7854,0.7744,0.7633,0.7523,0.7412,0.7301,0.7191,0.708,0.697,0.6859,0.6748,0.6638,0.6527,0.6413,0.629,0.6159,0.6021,0.5874,0.572,0.5557,0.5386,0.5208,0.5021,0.4827,0.4624,0.4413,0.4195,0.3968,0.3734,0.3491]}}],"performanceTiers":[{"minPercent":100,"label":"World Record Level"},{"minPercent":90,"label":"World Class"},{"minPercent":80,"label":"National Class"},{"minPercent":70,"label":"Regional Class"},{"minPercent":60,"label":"Local Class"},{"minPercent":0,"label":"Developing"}],"provenance":"Stored edition labels are retained; track-edition naming is uncertain. Values are not refreshed from current world records."},"sources":[{"title":"Canonical HTTP binding at the documented implementation revision","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/calculator-functions.ts","note":"Existing calculation handler; math metadata is additive."},{"title":"lib/formulas/age-grading.ts","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/formulas/age-grading.ts","note":"Primary implementation source for these equations/tables, not a claim of scientific calibration."},{"title":"lib/formulas/age-grading-data.ts","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/formulas/age-grading-data.ts","note":"Primary implementation source for these equations/tables, not a claim of scientific calibration."},{"title":"Howard Grubb age-grade calculator / tables","url":"https://www.howardgrubb.co.uk/athletics/wmalookup15.html","note":"Author page rechecked 2026-10-21; its mixed track/road edition naming leaves stored track-table provenance uncertain. Not a coefficient replacement."},{"title":"Alan Lytton-Jones2025 road-table archive","url":"https://raw.githubusercontent.com/AlanLyttonJones/Age-Grade-Tables/master/2025%20Files/AgeGrade.zip","note":"Canonical author2025 road-table archive; retained source checked2026-10-16. No claim these are current world records."}]},"annotations":{"readOnlyHint":true,"consequentialHint":false},"name":"Age-Grading Calculator","description":"This age graded calculator applies published WMA (World Masters Athletics) age factors to your time and returns your age-graded percentage, performance level, and age-graded equivalent open time. It covers track events from 100m to 3000m (WMA 2015 factors) and road events from the 5K to the marathon (2025 road factors), for men and women ages 25-90, using exact per-age published factors rather than five-year approximations.","category":"Conversions & Adjustments","method":"POST","endpoint":"/api/calculators/age-grading-calculator","page":"/calculators/age-grading-calculator","inputSchema":{"type":"object","required":["sex","age","eventKey","actualSeconds"],"properties":{"sex":{"type":"string","description":"Athlete sex.","enum":["M","F"],"default":"M"},"age":{"type":"integer","description":"Athlete age.","minimum":25,"maximum":90},"eventKey":{"type":"string","description":"Age-grading event key."},"actualSeconds":{"type":"number","description":"Actual performance time in seconds.","minimum":0}}},"example":{"sex":"M","age":50,"eventKey":"5k","actualSeconds":1350}},{"slug":"triple-jump-phase-calculator","math":{"href":"https://www.tracktoolspro.com/api/calculators/triple-jump-phase-calculator","jsonPointer":"/calculator/math","version":"2026-10-21.1","implementationVersion":"b5a8aca7b85361476e0321a08b7fa5f516fc9535","scope":"Canonical HTTP function and documented corresponding mounted-form math. This is public inspectable documentation, not access control or independent empirical validation.","unitNotation":"Input paths use [] and *; output paths are JSON Pointers with * (one segment) and ** (descendants). Empty output path denotes scalar result. Units apply to numeric quantities or explicitly described numeric strings; labels/statuses/booleans are dimensionless. More specific units, including count/index exceptions, override broad patterns.","interfaceNotes":["HTTP input is described by the adjacent inputSchema. The original handlers may accept numeric strings; this metadata adds no validation.","Mounted forms accept displayed clock/unit strings and enforce their own limits. Mounted tools limit strings to 200 characters and numeric parts to magnitude 1000000. Do not assume mounted/API input interchangeability.","Some legacy extreme/invalid tuples can produce null/empty results or nonfinite numbers serialized as null. Those are unavailable answers, not exact numerical predictions. Per-calculator domain describes the intended mathematical inputs."],"kind":"heuristic","implementationFiles":["lib/formulas/triple-jump.ts"],"equations":["plan: hop=totalDistance*hopPct/100; step=totalDistance*stepPct/100; jump=totalDistance*jumpPct/100.","analyze: total=hop+step+jump; phasePct=100*phase/total; display percentages round0.1. targetHop:0.75*longJumpPR."],"inputUnits":{"mode":"enum/string (dimensionless)","totalDistance":"m","ratioModel":"enum/string (dimensionless)","hopPct":"%","stepPct":"%","jumpPct":"%","hop":"m","step":"m","jump":"m","longJumpPR":"m"},"outputUnits":{"/total":"m","/hop":"m","/step":"m","/jump":"m","/ratios/*":"%","/hopPct":"%","/stepPct":"%","/jumpPct":"%","/hopPctDisplay":"%","/stepPctDisplay":"%","/jumpPctDisplay":"%","/targetHop":"m"},"domain":["Positive finite measured distances. Ratios all positive and sum 100 within 1e-9; invalid plan/analyze returns null; invalid ratio selection may error."],"rounding":["Raw distances/percentages; analyze displayPct fields Math.round(pct*10)/10."],"assumptions":["Uses the entered values and the selected convention; this documentation does not strengthen existing validation."],"limitations":["Coaching split ratios and 0.75guide, not biomechanical optimization or a performance guarantee."],"mountedPageNotes":[],"workedExamples":[{"input":{"mode":"plan","totalDistance":15,"ratioModel":"balanced"},"expected":{"/hop":5.25,"/step":4.5,"/jump":5.25},"absoluteTolerance":1e-8,"note":"Illustrative canonical-handler result; not independent validation of an empirical model."}],"constantsAndTables":{"ratioModels":[{"key":"balanced","label":"Balanced (35:30:35)","description":"Even hop and jump phases. The most common starting point for developing jumpers.","hopPct":35,"stepPct":30,"jumpPct":35},{"key":"hop-dominated","label":"Hop-Dominated (37:30:33)","description":"Bigger hop for strong, power-based jumpers who can absorb the landing.","hopPct":37,"stepPct":30,"jumpPct":33},{"key":"jump-dominated","label":"Jump-Dominated (34:30:36)","description":"Conserves speed through the hop and step for a big final jump phase.","hopPct":34,"stepPct":30,"jumpPct":36}],"longJumpHopGuideRatio":0.75,"ratioSumTolerance":1e-9},"sources":[{"title":"Canonical HTTP binding at the documented implementation revision","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/calculator-functions.ts","note":"Existing calculation handler; math metadata is additive."},{"title":"lib/formulas/triple-jump.ts","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/formulas/triple-jump.ts","note":"Primary implementation source for these equations/tables, not a claim of scientific calibration."}]},"annotations":{"readOnlyHint":true,"consequentialHint":false},"name":"Triple Jump Phase Ratio Calculator","description":"This triple jump phase ratio calculator works in two directions. Plan mode splits a target distance into hop, step, and jump targets using a balanced (35:30:35), hop-dominated (37:30:33), jump-dominated (34:30:36), or custom ratio model. Analyze mode takes three measured phase distances and returns the total plus the athlete's actual phase percentages, so you can see which phase is leaking distance. It also includes the common coaching rule of thumb that a jumper's hop should be roughly 75% of their long jump PR.","category":"Field Events","method":"POST","endpoint":"/api/calculators/triple-jump-phase-calculator","page":"/calculators/triple-jump-phase-calculator","inputSchema":{"type":"object","required":["mode"],"properties":{"mode":{"type":"string","description":"Calculation mode.","enum":["plan","analyze","targetHop"],"default":"plan"},"totalDistance":{"type":"number","description":"Total triple-jump distance in meters for plan mode.","minimum":0},"ratioModel":{"type":"string","description":"Preset ratio model.","enum":["balanced","hop-dominated","jump-dominated"],"default":"balanced"},"hopPct":{"type":"number","description":"Custom hop percentage."},"stepPct":{"type":"number","description":"Custom step percentage."},"jumpPct":{"type":"number","description":"Custom jump percentage."},"hop":{"type":"number","description":"Measured hop phase in meters for analyze mode.","minimum":0},"step":{"type":"number","description":"Measured step phase in meters for analyze mode.","minimum":0},"jump":{"type":"number","description":"Measured jump phase in meters for analyze mode.","minimum":0},"longJumpPR":{"type":"number","description":"Long jump PR in meters for target-hop mode.","minimum":0}}},"example":{"mode":"plan","totalDistance":15,"ratioModel":"balanced"}},{"slug":"workout-totals-calculator","math":{"href":"https://www.tracktoolspro.com/api/calculators/workout-totals-calculator","jsonPointer":"/calculator/math","version":"2026-10-21.1","implementationVersion":"b5a8aca7b85361476e0321a08b7fa5f516fc9535","scope":"Canonical HTTP function and documented corresponding mounted-form math. This is public inspectable documentation, not access control or independent empirical validation.","unitNotation":"Input paths use [] and *; output paths are JSON Pointers with * (one segment) and ** (descendants). Empty output path denotes scalar result. Units apply to numeric quantities or explicitly described numeric strings; labels/statuses/booleans are dimensionless. More specific units, including count/index exceptions, override broad patterns.","interfaceNotes":["HTTP input is described by the adjacent inputSchema. The original handlers may accept numeric strings; this metadata adds no validation.","Mounted forms accept displayed clock/unit strings and enforce their own limits. Mounted tools limit strings to 200 characters and numeric parts to magnitude 1000000. Do not assume mounted/API input interchangeability.","Some legacy extreme/invalid tuples can produce null/empty results or nonfinite numbers serialized as null. Those are unavailable answers, not exact numerical predictions. Per-calculator domain describes the intended mathematical inputs."],"kind":"accounting-algorithm","implementationFiles":["lib/formulas/running-workouts.ts"],"equations":["Given meters D and pace range[fast,slow]s/km: time=[D*fast/1000,D*slow/1000]. Given seconds T: meters=[1000*T/slow,1000*T/fast]. Missing pace leaves the derived metric unknown, not zero.","Main repetitions=sets*repeats; within-set recoveries=sets*(repeats-1)+(includeFinalRecovery?1:0); inter-set standing rests=sets-1. Never automatically add a between-set rep recovery.","Sum count-weighted min/max contributions. If any positive-count contribution is unknown, min/max=null; knownMin/knownMax still report known subtotal and unknownCount counts unknown repetitions.","Jog contributes running+moving+elapsed; walk contributes moving+elapsed; standing contributes elapsed only. Warmup/cooldown contribute totals but not work metrics."],"inputUnits":{"blocks[].label":"text","blocks[].kind":"enum/string (dimensionless)","blocks[].intensity":"enum/string (dimensionless)","blocks[].distanceMeters":"m","blocks[].durationSeconds":"s","blocks[].paceSecondsPerKm":"s/km","blocks[].slowPaceSecondsPerKm":"s/km","blocks[].repeats":"dimensionless index/count","blocks[].sets":"dimensionless index/count","blocks[].includeFinalRecovery":"boolean","blocks[].betweenSetsSeconds":"s","blocks[].recovery.mode":"enum/string (dimensionless)","blocks[].recovery.intensity":"enum/string (dimensionless)","blocks[].recovery.distanceMeters":"m","blocks[].recovery.durationSeconds":"s","blocks[].recovery.paceSecondsPerKm":"s/km","blocks[].recovery.slowPaceSecondsPerKm":"s/km"},"outputUnits":{"/**/elapsedSeconds/min":"s","/**/elapsedSeconds/max":"s","/**/elapsedSeconds/knownMin":"s","/**/elapsedSeconds/knownMax":"s","/**/elapsedSeconds/unknownCount":"dimensionless index/count","/**/runningSeconds/min":"s","/**/runningSeconds/max":"s","/**/runningSeconds/knownMin":"s","/**/runningSeconds/knownMax":"s","/**/runningSeconds/unknownCount":"dimensionless index/count","/**/workSeconds/min":"s","/**/workSeconds/max":"s","/**/workSeconds/knownMin":"s","/**/workSeconds/knownMax":"s","/**/workSeconds/unknownCount":"dimensionless index/count","/**/recoverySeconds/min":"s","/**/recoverySeconds/max":"s","/**/recoverySeconds/knownMin":"s","/**/recoverySeconds/knownMax":"s","/**/recoverySeconds/unknownCount":"dimensionless index/count","/**/movingDistanceMeters/min":"m","/**/movingDistanceMeters/max":"m","/**/movingDistanceMeters/knownMin":"m","/**/movingDistanceMeters/knownMax":"m","/**/movingDistanceMeters/unknownCount":"dimensionless index/count","/**/runningDistanceMeters/min":"m","/**/runningDistanceMeters/max":"m","/**/runningDistanceMeters/knownMin":"m","/**/runningDistanceMeters/knownMax":"m","/**/runningDistanceMeters/unknownCount":"dimensionless index/count","/**/workDistanceMeters/min":"m","/**/workDistanceMeters/max":"m","/**/workDistanceMeters/knownMin":"m","/**/workDistanceMeters/knownMax":"m","/**/workDistanceMeters/unknownCount":"dimensionless index/count","/**/recoveryDistanceMeters/min":"m","/**/recoveryDistanceMeters/max":"m","/**/recoveryDistanceMeters/knownMin":"m","/**/recoveryDistanceMeters/knownMax":"m","/**/recoveryDistanceMeters/unknownCount":"dimensionless index/count","/**/repetitions":"dimensionless index/count","/**/recoveries":"dimensionless index/count"},"domain":["Strict nested schema: 1..40 blocks ; 1..100 reps and 1..20 sets; exactly one distance/time measure per item; standing requires time and no pace; schema lists exact finite bounds."],"rounding":["Raw IEEE-754 numbers; the mounted page formats clocks separately."],"assumptions":["Uses the entered values and the selected convention; this documentation does not strengthen existing validation."],"limitations":["Entered plan totals, not measured work or energy expenditure. Unknown pace is never imputed. Ranges are scenario endpoints, not statistical confidence."],"mountedPageNotes":[],"workedExamples":[{"input":{"blocks":[{"label":"Warmup","kind":"warmup","intensity":"easy","durationSeconds":600,"paceSecondsPerKm":360},{"label":"6 × 800m","kind":"work","intensity":"hard","distanceMeters":800,"paceSecondsPerKm":240,"repeats":6,"recovery":{"mode":"jog","intensity":"easy","durationSeconds":90,"paceSecondsPerKm":360}},{"label":"Cooldown","kind":"cooldown","intensity":"easy","durationSeconds":600,"paceSecondsPerKm":360}]},"expected":{"/workDistanceMeters/min":4800,"/recoverySeconds/min":450},"absoluteTolerance":1e-8,"note":"Illustrative canonical-handler result; not independent validation of an empirical model."}],"constantsAndTables":{"intensities":["easy","moderate","hard","unclassified"],"maxBlocks":40},"sources":[{"title":"Canonical HTTP binding at the documented implementation revision","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/calculator-functions.ts","note":"Existing calculation handler; math metadata is additive."},{"title":"lib/formulas/running-workouts.ts","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/formulas/running-workouts.ts","note":"Primary implementation source for these equations/tables, not a claim of scientific calibration."}]},"annotations":{"readOnlyHint":true,"consequentialHint":false},"name":"Workout Totals Calculator","description":"Build a complete distance-running session from mixed time and distance blocks. Calculate work, recovery, running and elapsed totals with optional pace ranges. Missing pace leaves derived time or distance unknown; known subtotals stay separate.","category":"Training & Fitness","method":"POST","endpoint":"/api/calculators/workout-totals-calculator","page":"/calculators/workout-totals-calculator","inputSchema":{"type":"object","additionalProperties":false,"required":["blocks"],"properties":{"blocks":{"type":"array","description":"Ordered running blocks; missing pace leaves derived metrics unknown.","minItems":1,"maxItems":40,"items":{"type":"object","description":"Running block. Within-set recoveries follow all but the last rep. Inter-set standing rest is separate.","additionalProperties":false,"required":["kind","intensity"],"oneOf":[{"required":["distanceMeters"]},{"required":["durationSeconds"]}],"properties":{"label":{"type":"string","description":"Optional block name.","maxLength":60},"kind":{"type":"string","description":"Purpose of the running block.","enum":["work","warmup","cooldown"]},"intensity":{"type":"string","description":"Entered coaching label, not a physiological measurement.","enum":["easy","moderate","hard","unclassified"]},"distanceMeters":{"type":"number","description":"Distance per repetition in meters; omit durationSeconds.","minimum":0.001,"maximum":1000000},"durationSeconds":{"type":"number","description":"Time per repetition in seconds; omit distanceMeters.","minimum":0.001,"maximum":1000000},"paceSecondsPerKm":{"type":"number","description":"Optional pace in seconds per kilometer; omit when unknown.","minimum":0.001,"maximum":3600},"slowPaceSecondsPerKm":{"type":"number","description":"Optional slower pace in seconds/km. Requires paceSecondsPerKm and must be at least that value.","minimum":0.001,"maximum":3600},"repeats":{"type":"integer","description":"Reps per set; default 1.","minimum":1,"maximum":100},"sets":{"type":"integer","description":"Sets; default 1.","minimum":1,"maximum":20},"recovery":{"type":"object","description":"Between-rep recovery. Jog is running, walk is moving, stand only adds elapsed time.","additionalProperties":false,"required":["mode","intensity"],"oneOf":[{"required":["distanceMeters"]},{"required":["durationSeconds"]}],"properties":{"distanceMeters":{"type":"number","description":"Distance per repetition in meters; omit durationSeconds.","minimum":0.001,"maximum":1000000},"durationSeconds":{"type":"number","description":"Time per repetition in seconds; omit distanceMeters.","minimum":0.001,"maximum":1000000},"paceSecondsPerKm":{"type":"number","description":"Optional pace in seconds per kilometer; omit when unknown.","minimum":0.001,"maximum":3600},"slowPaceSecondsPerKm":{"type":"number","description":"Optional slower pace in seconds/km. Requires paceSecondsPerKm and must be at least that value.","minimum":0.001,"maximum":3600},"mode":{"type":"string","description":"Standing requires durationSeconds and no pace.","enum":["jog","walk","stand"]},"intensity":{"type":"string","description":"Entered coaching label, not a physiological measurement.","enum":["easy","moderate","hard","unclassified"]}}},"includeFinalRecovery":{"type":"boolean","description":"One recovery after the final rep of the final set; default false. Requires recovery."},"betweenSetsSeconds":{"type":"number","description":"Standing rest between sets, in seconds; nonzero requires at least two sets.","minimum":0,"maximum":3600}}}}}},"example":{"blocks":[{"label":"Warmup","kind":"warmup","intensity":"easy","durationSeconds":600,"paceSecondsPerKm":360},{"label":"6 × 800m","kind":"work","intensity":"hard","distanceMeters":800,"paceSecondsPerKm":240,"repeats":6,"recovery":{"mode":"jog","intensity":"easy","durationSeconds":90,"paceSecondsPerKm":360}},{"label":"Cooldown","kind":"cooldown","intensity":"easy","durationSeconds":600,"paceSecondsPerKm":360}]}},{"slug":"outer-lane-workout-calculator","math":{"href":"https://www.tracktoolspro.com/api/calculators/outer-lane-workout-calculator","jsonPointer":"/calculator/math","version":"2026-10-21.1","implementationVersion":"b5a8aca7b85361476e0321a08b7fa5f516fc9535","scope":"Canonical HTTP function and documented corresponding mounted-form math. This is public inspectable documentation, not access control or independent empirical validation.","unitNotation":"Input paths use [] and *; output paths are JSON Pointers with * (one segment) and ** (descendants). Empty output path denotes scalar result. Units apply to numeric quantities or explicitly described numeric strings; labels/statuses/booleans are dimensionless. More specific units, including count/index exceptions, override broad patterns.","interfaceNotes":["HTTP input is described by the adjacent inputSchema. The original handlers may accept numeric strings; this metadata adds no validation.","Mounted forms accept displayed clock/unit strings and enforce their own limits. Mounted tools limit strings to 200 characters and numeric parts to magnitude 1000000. Do not assume mounted/API input interchangeability.","Some legacy extreme/invalid tuples can produce null/empty results or nonfinite numbers serialized as null. Those are unavailable answers, not exact numerical predictions. Per-calculator domain describes the intended mathematical inputs."],"kind":"geometry-and-arithmetic","implementationFiles":["lib/formulas/outer-lane.ts"],"equations":["Geometry: lapMeters=laneOneLapMeters+2*pi*((lane-1)*laneWidthMeters+outerOffsetMeters-laneOneOffsetMeters), except lane1 stays unchanged. Measured mode uses measuredLapMeters and no geometry.","q=targetDistanceMeters/lapMeters; fullLaps=floor(q), remainderMeters=targetDistanceMeters-fullLaps*lapMeters. If q is within 8*EPSILON*max(1,q) of an integer, use that integer and zero remainder.","fullLapSeconds=targetTimeSeconds*lapMeters/targetDistanceMeters; remainderSeconds=targetTimeSeconds*remainderMeters/targetDistanceMeters; pace perkm/mile uses 1000/1609.344m."],"inputUnits":{"measuredLapMeters":"m","lane":"dimensionless index/count","laneWidthMeters":"m","laneOneLapMeters":"m","laneOneOffsetMeters":"m","outerOffsetMeters":"m","targetDistanceMeters":"m","targetTimeSeconds":"s"},"outputUnits":{"/lapMeters":"m","/extraMetersPerLap":"m","/targetDistanceMeters":"m","/targetTimeSeconds":"s","/fullLaps":"dimensionless index/count","/remainderMeters":"m","/fullLapSeconds":"s","/remainderSeconds":"s","/paceSecondsPerKm":"s/km","/paceSecondsPerMile":"s/mile"},"domain":["Exactly one strict measured/geometry alternative; bounds in schema. Measured mode must omit all geometry fields. Lane1 preserves provided measurement line."],"rounding":["Raw IEEE-754 numbers; the mounted page formats clocks separately."],"assumptions":["Uses the entered values and the selected convention; this documentation does not strengthen existing validation."],"limitations":["Parallel flat outdoor offsets or an actually measured running path; no banked-track model, painted-start location or certified distance/performance."],"mountedPageNotes":[],"workedExamples":[{"input":{"lane":2,"laneWidthMeters":1.22,"laneOneLapMeters":400,"laneOneOffsetMeters":0.3,"outerOffsetMeters":0.2,"targetDistanceMeters":1600,"targetTimeSeconds":300},"expected":{"/lapMeters":407.03716754404115,"/fullLaps":3},"absoluteTolerance":1e-8,"note":"Illustrative canonical-handler result; not independent validation of an empirical model."}],"constantsAndTables":{"exactMileMeters":1609.344,"pi":3.141592653589793,"nearIntegerEpsilonMultiple":8,"ruleReference":{"title":"World Athletics Competition and Technical Rules (official index: 1 July 2026)","url":"https://worldathletics.org/download/download?filename=0ed43077-8e08-492b-a4b3-267f27c18d0b.pdf&urlslug=C1.1%20%26%20C2.1%20-%20Competition%20Rules%20%26%20Technical%20Rules","checkedOn":"2026-10-15"}},"sources":[{"title":"Canonical HTTP binding at the documented implementation revision","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/calculator-functions.ts","note":"Existing calculation handler; math metadata is additive."},{"title":"lib/formulas/outer-lane.ts","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/formulas/outer-lane.ts","note":"Primary implementation source for these equations/tables, not a claim of scientific calibration."}]},"annotations":{"readOnlyHint":true,"consequentialHint":false},"name":"Outer-Lane Pacing Calculator","description":"Calculate lap length, full laps plus a remainder, and lap pacing for distance workouts in an outer lane. Use a directly measured running-path lap or flat outdoor parallel-lane geometry with explicit lane width and measurement offsets. An exact mile is 1609.344m, not 1600m.","category":"Training & Fitness","method":"POST","endpoint":"/api/calculators/outer-lane-workout-calculator","page":"/calculators/outer-lane-workout-calculator","inputSchema":{"type":"object","additionalProperties":false,"required":["targetDistanceMeters","targetTimeSeconds"],"oneOf":[{"required":["measuredLapMeters"]},{"required":["lane","laneWidthMeters","laneOneLapMeters","laneOneOffsetMeters","outerOffsetMeters"]}],"properties":{"measuredLapMeters":{"type":"number","description":"Measured selected-path lap length in meters. Omit all geometry fields.","minimum":50,"maximum":2000},"lane":{"type":"integer","description":"Outdoor lane number; omit in measured mode.","minimum":1,"maximum":12},"laneWidthMeters":{"type":"number","description":"Uniform lane width in meters, including the right lane line.","minimum":0.5,"maximum":2},"laneOneLapMeters":{"type":"number","description":"Lane 1 lap length at laneOneOffsetMeters, in meters.","minimum":50,"maximum":2000},"laneOneOffsetMeters":{"type":"number","description":"Lane 1 offset from its inner boundary: WA kerbed 0.30m, unkerbed 0.20m.","minimum":0,"maximum":0.5},"outerOffsetMeters":{"type":"number","description":"Outer-lane measurement offset from the outer edge of its inner boundary line: WA 0.20m. Not applied to lane 1.","minimum":0,"maximum":0.5},"targetDistanceMeters":{"type":"number","description":"Target meters: exact mile=1609.344; 1600m is separate.","minimum":0.001,"maximum":1000000},"targetTimeSeconds":{"type":"number","description":"Time for the target distance in seconds; same-speed arithmetic.","minimum":0.001,"maximum":1000000}}},"example":{"lane":2,"laneWidthMeters":1.22,"laneOneLapMeters":400,"laneOneOffsetMeters":0.3,"outerOffsetMeters":0.2,"targetDistanceMeters":1600,"targetTimeSeconds":300}},{"slug":"weekly-intensity-calculator","math":{"href":"https://www.tracktoolspro.com/api/calculators/weekly-intensity-calculator","jsonPointer":"/calculator/math","version":"2026-10-21.1","implementationVersion":"b5a8aca7b85361476e0321a08b7fa5f516fc9535","scope":"Canonical HTTP function and documented corresponding mounted-form math. This is public inspectable documentation, not access control or independent empirical validation.","unitNotation":"Input paths use [] and *; output paths are JSON Pointers with * (one segment) and ** (descendants). Empty output path denotes scalar result. Units apply to numeric quantities or explicitly described numeric strings; labels/statuses/booleans are dimensionless. More specific units, including count/index exceptions, override broad patterns.","interfaceNotes":["HTTP input is described by the adjacent inputSchema. The original handlers may accept numeric strings; this metadata adds no validation.","Mounted forms accept displayed clock/unit strings and enforce their own limits. Mounted tools limit strings to 200 characters and numeric parts to magnitude 1000000. Do not assume mounted/API input interchangeability.","Some legacy extreme/invalid tuples can produce null/empty results or nonfinite numbers serialized as null. Those are unavailable answers, not exact numerical predictions. Per-calculator domain describes the intended mathematical inputs."],"kind":"accounting-algorithm","implementationFiles":["lib/formulas/running-workouts.ts"],"equations":["Given meters D and pace range[fast,slow]s/km: time=[D*fast/1000,D*slow/1000]. Given seconds T: meters=[1000*T/slow,1000*T/fast]. Missing pace leaves the derived metric unknown, not zero.","Main repetitions=sets*repeats; within-set recoveries=sets*(repeats-1)+(includeFinalRecovery?1:0); inter-set standing rests=sets-1. Never automatically add a between-set rep recovery.","Sum count-weighted min/max contributions. If any positive-count contribution is unknown, min/max=null; knownMin/knownMax still report known subtotal and unknownCount counts unknown repetitions.","Jog contributes running+moving+elapsed; walk contributes moving+elapsed; standing contributes elapsed only. Warmup/cooldown contribute totals but not work metrics.","Select running/elapsed time and running/moving distance as denominators. Recovery may retain its label or inherit parent work intensity; session goals always count each session once.","For group G and remainder R, shareMin=100*Gmin/(Gmin+Rmax), shareMax=100*Gmax/(Gmax+Rmin). This preserves numerator/denominator dependence. Unknown/zero denominator yields null percentages.","Session-goal share=100*matchingSessions/sessionCount. hardTimeDifferencePoints=hardTimeShare-targetHardPercent; target is user-entered, not recommended."],"inputUnits":{"periodLabel":"text","timeBasis":"enum/string (dimensionless)","distanceBasis":"enum/string (dimensionless)","recoveryAccounting":"enum/string (dimensionless)","targetHardPercent":"%","sessions[].label":"text","sessions[].goalIntensity":"enum/string (dimensionless)","sessions[].blocks[].label":"text","sessions[].blocks[].kind":"enum/string (dimensionless)","sessions[].blocks[].intensity":"enum/string (dimensionless)","sessions[].blocks[].distanceMeters":"m","sessions[].blocks[].durationSeconds":"s","sessions[].blocks[].paceSecondsPerKm":"s/km","sessions[].blocks[].slowPaceSecondsPerKm":"s/km","sessions[].blocks[].repeats":"dimensionless index/count","sessions[].blocks[].sets":"dimensionless index/count","sessions[].blocks[].includeFinalRecovery":"boolean","sessions[].blocks[].betweenSetsSeconds":"s","sessions[].blocks[].recovery.mode":"enum/string (dimensionless)","sessions[].blocks[].recovery.intensity":"enum/string (dimensionless)","sessions[].blocks[].recovery.distanceMeters":"m","sessions[].blocks[].recovery.durationSeconds":"s","sessions[].blocks[].recovery.paceSecondsPerKm":"s/km","sessions[].blocks[].recovery.slowPaceSecondsPerKm":"s/km"},"outputUnits":{"/**/elapsedSeconds/min":"s","/**/elapsedSeconds/max":"s","/**/elapsedSeconds/knownMin":"s","/**/elapsedSeconds/knownMax":"s","/**/elapsedSeconds/unknownCount":"dimensionless index/count","/**/runningSeconds/min":"s","/**/runningSeconds/max":"s","/**/runningSeconds/knownMin":"s","/**/runningSeconds/knownMax":"s","/**/runningSeconds/unknownCount":"dimensionless index/count","/**/workSeconds/min":"s","/**/workSeconds/max":"s","/**/workSeconds/knownMin":"s","/**/workSeconds/knownMax":"s","/**/workSeconds/unknownCount":"dimensionless index/count","/**/recoverySeconds/min":"s","/**/recoverySeconds/max":"s","/**/recoverySeconds/knownMin":"s","/**/recoverySeconds/knownMax":"s","/**/recoverySeconds/unknownCount":"dimensionless index/count","/**/movingDistanceMeters/min":"m","/**/movingDistanceMeters/max":"m","/**/movingDistanceMeters/knownMin":"m","/**/movingDistanceMeters/knownMax":"m","/**/movingDistanceMeters/unknownCount":"dimensionless index/count","/**/runningDistanceMeters/min":"m","/**/runningDistanceMeters/max":"m","/**/runningDistanceMeters/knownMin":"m","/**/runningDistanceMeters/knownMax":"m","/**/runningDistanceMeters/unknownCount":"dimensionless index/count","/**/workDistanceMeters/min":"m","/**/workDistanceMeters/max":"m","/**/workDistanceMeters/knownMin":"m","/**/workDistanceMeters/knownMax":"m","/**/workDistanceMeters/unknownCount":"dimensionless index/count","/**/recoveryDistanceMeters/min":"m","/**/recoveryDistanceMeters/max":"m","/**/recoveryDistanceMeters/knownMin":"m","/**/recoveryDistanceMeters/knownMax":"m","/**/recoveryDistanceMeters/unknownCount":"dimensionless index/count","/**/repetitions":"dimensionless index/count","/**/recoveries":"dimensionless index/count","/time/total/*":"s","/distance/total/*":"m","/time/groups/*/total/*":"s","/distance/groups/*/total/*":"m","/**/unknownCount":"dimensionless index/count","/**/percentMin":"%","/**/percentMax":"%","/sessionGoals/total":"dimensionless index/count","/sessionGoals/groups/*/count":"dimensionless index/count","/sessionGoals/groups/*/percent":"%","/targetHardPercent":"%","/hardTimeDifferencePoints/*":"percentage points","/time/total/unknownCount":"dimensionless index/count","/distance/total/unknownCount":"dimensionless index/count","/time/groups/*/total/unknownCount":"dimensionless index/count","/distance/groups/*/total/unknownCount":"dimensionless index/count"},"domain":["1..21strict sessions, each1..40 blocks; same measure/recovery bounds as Workout Totals. Target hard percent optional0..100."],"rounding":["Raw IEEE-754 numbers; the mounted page formats clocks separately."],"assumptions":["Uses the entered values and the selected convention; this documentation does not strengthen existing validation."],"limitations":["Coaching labels are not measured physiological zones. Time, distance and session denominators can disagree. No automatic date filtering or universal80/20 prescription."],"mountedPageNotes":[],"workedExamples":[{"input":{"periodLabel":"Example week","timeBasis":"running","distanceBasis":"running","recoveryAccounting":"separate","sessions":[{"label":"Easy run","goalIntensity":"easy","blocks":[{"kind":"work","intensity":"easy","durationSeconds":1800,"paceSecondsPerKm":360}]},{"label":"Track session","goalIntensity":"hard","blocks":[{"label":"Warmup","kind":"warmup","intensity":"easy","durationSeconds":600,"paceSecondsPerKm":360},{"label":"6 × 800m","kind":"work","intensity":"hard","distanceMeters":800,"paceSecondsPerKm":240,"repeats":6,"recovery":{"mode":"jog","intensity":"easy","durationSeconds":90,"paceSecondsPerKm":360}},{"label":"Cooldown","kind":"cooldown","intensity":"easy","durationSeconds":600,"paceSecondsPerKm":360}]}]},"expected":{"/sessionGoals/total":2,"/time/total/min":4602},"absoluteTolerance":1e-8,"note":"Illustrative canonical-handler result; not independent validation of an empirical model."}],"constantsAndTables":{"intensities":["easy","moderate","hard","unclassified"],"maxBlocks":40,"maxSessions":21},"sources":[{"title":"Canonical HTTP binding at the documented implementation revision","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/calculator-functions.ts","note":"Existing calculation handler; math metadata is additive."},{"title":"lib/formulas/running-workouts.ts","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/formulas/running-workouts.ts","note":"Primary implementation source for these equations/tables, not a claim of scientific calibration."}]},"annotations":{"readOnlyHint":true,"consequentialHint":false},"name":"Weekly Intensity Calculator","description":"Account for entered easy, moderate, hard and unclassified running blocks across a week. Compare time, distance and session-goal percentages with explicit recovery and movement conventions. These labels describe a plan, not measured physiological zones, and no universal 80/20 ratio is prescribed.","category":"Training & Fitness","method":"POST","endpoint":"/api/calculators/weekly-intensity-calculator","page":"/calculators/weekly-intensity-calculator","inputSchema":{"type":"object","additionalProperties":false,"required":["sessions","timeBasis","distanceBasis","recoveryAccounting"],"properties":{"periodLabel":{"type":"string","description":"Period label; no automatic date filtering.","maxLength":80},"timeBasis":{"type":"string","description":"Running time excludes walks/standing; elapsed time includes both.","enum":["running","elapsed"]},"distanceBasis":{"type":"string","description":"Running distance excludes walks; moving distance includes them.","enum":["running","moving"]},"recoveryAccounting":{"type":"string","description":"Separate recovery labels, or attribute recoveries/inter-set rests to the parent block. Session-goal counts are unchanged.","enum":["separate","workIntensity"]},"targetHardPercent":{"type":"number","description":"Optional user-chosen hard-time comparison; not a recommendation.","minimum":0,"maximum":100},"sessions":{"type":"array","description":"Each entry counts once in the session-goal denominator.","minItems":1,"maxItems":21,"items":{"type":"object","description":"One running session.","additionalProperties":false,"required":["goalIntensity","blocks"],"properties":{"label":{"type":"string","description":"Optional session name.","maxLength":60},"goalIntensity":{"type":"string","description":"Entered coaching label, not a physiological measurement.","enum":["easy","moderate","hard","unclassified"]},"blocks":{"type":"array","description":"Ordered running blocks; missing pace leaves derived metrics unknown.","minItems":1,"maxItems":40,"items":{"type":"object","description":"Running block. Within-set recoveries follow all but the last rep. Inter-set standing rest is separate.","additionalProperties":false,"required":["kind","intensity"],"oneOf":[{"required":["distanceMeters"]},{"required":["durationSeconds"]}],"properties":{"label":{"type":"string","description":"Optional block name.","maxLength":60},"kind":{"type":"string","description":"Purpose of the running block.","enum":["work","warmup","cooldown"]},"intensity":{"type":"string","description":"Entered coaching label, not a physiological measurement.","enum":["easy","moderate","hard","unclassified"]},"distanceMeters":{"type":"number","description":"Distance per repetition in meters; omit durationSeconds.","minimum":0.001,"maximum":1000000},"durationSeconds":{"type":"number","description":"Time per repetition in seconds; omit distanceMeters.","minimum":0.001,"maximum":1000000},"paceSecondsPerKm":{"type":"number","description":"Optional pace in seconds per kilometer; omit when unknown.","minimum":0.001,"maximum":3600},"slowPaceSecondsPerKm":{"type":"number","description":"Optional slower pace in seconds/km. Requires paceSecondsPerKm and must be at least that value.","minimum":0.001,"maximum":3600},"repeats":{"type":"integer","description":"Reps per set; default 1.","minimum":1,"maximum":100},"sets":{"type":"integer","description":"Sets; default 1.","minimum":1,"maximum":20},"recovery":{"type":"object","description":"Between-rep recovery. Jog is running, walk is moving, stand only adds elapsed time.","additionalProperties":false,"required":["mode","intensity"],"oneOf":[{"required":["distanceMeters"]},{"required":["durationSeconds"]}],"properties":{"distanceMeters":{"type":"number","description":"Distance per repetition in meters; omit durationSeconds.","minimum":0.001,"maximum":1000000},"durationSeconds":{"type":"number","description":"Time per repetition in seconds; omit distanceMeters.","minimum":0.001,"maximum":1000000},"paceSecondsPerKm":{"type":"number","description":"Optional pace in seconds per kilometer; omit when unknown.","minimum":0.001,"maximum":3600},"slowPaceSecondsPerKm":{"type":"number","description":"Optional slower pace in seconds/km. Requires paceSecondsPerKm and must be at least that value.","minimum":0.001,"maximum":3600},"mode":{"type":"string","description":"Standing requires durationSeconds and no pace.","enum":["jog","walk","stand"]},"intensity":{"type":"string","description":"Entered coaching label, not a physiological measurement.","enum":["easy","moderate","hard","unclassified"]}}},"includeFinalRecovery":{"type":"boolean","description":"One recovery after the final rep of the final set; default false. Requires recovery."},"betweenSetsSeconds":{"type":"number","description":"Standing rest between sets, in seconds; nonzero requires at least two sets.","minimum":0,"maximum":3600}}}}}}}}},"example":{"periodLabel":"Example week","timeBasis":"running","distanceBasis":"running","recoveryAccounting":"separate","sessions":[{"label":"Easy run","goalIntensity":"easy","blocks":[{"kind":"work","intensity":"easy","durationSeconds":1800,"paceSecondsPerKm":360}]},{"label":"Track session","goalIntensity":"hard","blocks":[{"label":"Warmup","kind":"warmup","intensity":"easy","durationSeconds":600,"paceSecondsPerKm":360},{"label":"6 × 800m","kind":"work","intensity":"hard","distanceMeters":800,"paceSecondsPerKm":240,"repeats":6,"recovery":{"mode":"jog","intensity":"easy","durationSeconds":90,"paceSecondsPerKm":360}},{"label":"Cooldown","kind":"cooldown","intensity":"easy","durationSeconds":600,"paceSecondsPerKm":360}]}]}},{"slug":"relay-check-mark-calculator","math":{"href":"https://www.tracktoolspro.com/api/calculators/relay-check-mark-calculator","jsonPointer":"/calculator/math","version":"2026-10-21.1","implementationVersion":"b5a8aca7b85361476e0321a08b7fa5f516fc9535","scope":"Canonical HTTP function and documented corresponding mounted-form math. This is public inspectable documentation, not access control or independent empirical validation.","unitNotation":"Input paths use [] and *; output paths are JSON Pointers with * (one segment) and ** (descendants). Empty output path denotes scalar result. Units apply to numeric quantities or explicitly described numeric strings; labels/statuses/booleans are dimensionless. More specific units, including count/index exceptions, override broad patterns.","interfaceNotes":["HTTP input is described by the adjacent inputSchema. The original handlers may accept numeric strings; this metadata adds no validation.","Mounted forms accept displayed clock/unit strings and enforce their own limits. Mounted tools limit strings to 200 characters and numeric parts to magnitude 1000000. Do not assume mounted/API input interchangeability.","Some legacy extreme/invalid tuples can produce null/empty results or nonfinite numbers serialized as null. Those are unavailable answers, not exact numerical predictions. Per-calculator domain describes the intended mathematical inputs."],"kind":"measured-scenario","implementationFiles":["lib/formulas/relay-check-marks.ts","lib/formulas/field-measurements.ts"],"equations":["v[i]=incomingDistance/incomingTime[i]; t[i]=outgoingCueToExchangeSeconds[i]. Summaries use arithmetic mean, sorted median, extrema and sample SD sqrt(sum((x-mean)^2)/(n-1)); one observation has null sample SD.","goCoordinate=xExchange-median(v)*median(t); behindReceiver=receiverStart-goCoordinate. Positive behindReceiver is upstream; sign is never flipped.","vBounds=[min(d/(t+u)),max(d/(t-u))]; durationBounds=[min(t-u),max(t+u)]; goBounds=[x-uX-vMax*tMax,x+uX-vMin*tMin]. Behind bounds reverse endpoint order.","Sensitivity dx/dt=-median(v), dx/dv=-median(t); additional10ms multiplies first sensitivity by0.01.","For sampled whole-baton positions, entry margin=min(back coordinates) +/-u; exit margin=30-max(front coordinates) +/-u. Compare conservative bounds with zero; legality always not_determined."],"inputUnits":{"incomingReference":"enum/string (dimensionless)","receiverStartMeters":"m","exchangeReferenceMeters":"m","referenceUncertaintyMeters":"m","incomingTrials[].distanceMeters":"m","incomingTrials[].timeSeconds":"s","incomingTrials[].uncertaintySeconds":"s","outgoingTrials[].cueToExchangeSeconds":"s","outgoingTrials[].uncertaintySeconds":"s","observedTransfers[].firstTouchBackMeters":"m","observedTransfers[].firstTouchFrontMeters":"m","observedTransfers[].releaseBackMeters":"m","observedTransfers[].releaseFrontMeters":"m","observedTransfers[].uncertaintyMeters":"m"},"outputUnits":{"/receiverStartMeters":"m","/zone/lengthMeters":"m","/incomingSpeedMetersPerSecond/**":"m/s","/outgoingCueToExchangeSeconds/**":"s","/**/count":"dimensionless index/count","/goMark/**":"m","/sensitivity/metersPerAdditionalCueSecond":"m/s","/sensitivity/metersForAdditionalCue10ms":"m","/sensitivity/metersPerAdditionalIncomingMeterPerSecond":"s","/observedTransfers/*/trial":"dimensionless index/count","/observedTransfers/*/entryMarginMeters/*":"m","/observedTransfers/*/exitMarginMeters/*":"m","/incomingSpeedMetersPerSecond/count":"dimensionless index/count","/outgoingCueToExchangeSeconds/count":"dimensionless index/count"},"domain":["Strict schema1..30incoming/outgoing trials; same measured incoming distance; each timing uncertainty<duration. Back baton coordinate<=front. Coordinate/measurement limits are explicit in schema."],"rounding":["Raw IEEE-754 numbers; the mounted page formats clocks separately."],"assumptions":["Uses the entered values and the selected convention; this documentation does not strengthen existing validation."],"limitations":["Conditional constant incoming speed, measured outgoing duration including reaction exactly once. Bounds are extrema scenarios, not confidence intervals. Receiver start/distance treated exact. Two sampled baton observations cannot certify whole-transfer/feet/lane legality."],"mountedPageNotes":[],"workedExamples":[{"input":{"incomingReference":"incoming-torso","receiverStartMeters":0.5,"exchangeReferenceMeters":24,"referenceUncertaintyMeters":0.1,"incomingTrials":[{"distanceMeters":20,"timeSeconds":2,"uncertaintySeconds":0.02},{"distanceMeters":20,"timeSeconds":2.04,"uncertaintySeconds":0.02},{"distanceMeters":20,"timeSeconds":1.98,"uncertaintySeconds":0.02}],"outgoingTrials":[{"cueToExchangeSeconds":3.2,"uncertaintySeconds":0.03},{"cueToExchangeSeconds":3.25,"uncertaintySeconds":0.03},{"cueToExchangeSeconds":3.15,"uncertaintySeconds":0.03}],"observedTransfers":[{"firstTouchBackMeters":23.7,"firstTouchFrontMeters":24,"releaseBackMeters":25,"releaseFrontMeters":25.3,"uncertaintyMeters":0.05}]},"expected":{"/goMark/coordinateMeters":-8},"absoluteTolerance":1e-8,"note":"Illustrative canonical-handler result; not independent validation of an empirical model."}],"constantsAndTables":{"zoneLengthMeters":30,"ruleReference":{"title":"World Athletics Competition and Technical Rules (official index: 1 July 2026)","url":"https://worldathletics.org/download/download?filename=0ed43077-8e08-492b-a4b3-267f27c18d0b.pdf&urlslug=C1.1%20%26%20C2.1%20-%20Competition%20Rules%20%26%20Technical%20Rules","checkedOn":"2026-10-15"},"sampleStandardDeviationDenominator":"n-1"},"sources":[{"title":"Canonical HTTP binding at the documented implementation revision","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/calculator-functions.ts","note":"Existing calculation handler; math metadata is additive."},{"title":"lib/formulas/relay-check-marks.ts","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/formulas/relay-check-marks.ts","note":"Primary implementation source for these equations/tables, not a claim of scientific calibration."},{"title":"lib/formulas/field-measurements.ts","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/formulas/field-measurements.ts","note":"Primary implementation source for these equations/tables, not a claim of scientific calibration."}]},"annotations":{"readOnlyHint":true,"consequentialHint":false},"name":"Relay Check-Mark Calculator","description":"Calibrate signed 4x100 cue marks from your measured trials, with timing sensitivity and sampled baton margins.","category":"Sprints & Hurdles","method":"POST","endpoint":"/api/calculators/relay-check-mark-calculator","page":"/calculators/relay-check-mark-calculator","inputSchema":{"type":"object","description":"Strict measured input object; units are explicit on each field.","properties":{"incomingReference":{"type":"string","enum":["incoming-torso","baton-reference"],"description":"Reference used for incoming timing and target coordinate. Match it across trials; torso position does not establish baton legality."},"receiverStartMeters":{"type":"number","description":"Receiver start coordinate in meters from the 4x100 zone entry (0). Feet and movement rules still need on-track checking.","minimum":0,"maximum":30},"exchangeReferenceMeters":{"type":"number","description":"Intended incoming reference coordinate at exchange, meters from zone entry, matched to outgoing cue-to-exchange trials.","minimum":-30,"maximum":60},"referenceUncertaintyMeters":{"type":"number","description":"Absolute bound in meters on that reference coordinate; receiver start and timed distances are treated as exact.","minimum":0,"maximum":10},"incomingTrials":{"type":"array","description":"Measured entries in the stated units and original order.","items":{"type":"object","description":"Strict measured input object; units are explicit on each field.","properties":{"distanceMeters":{"type":"number","description":"Measured late-leg section distance in meters; use the same section, reference and conditions for repeated trials.","minimum":0.1,"maximum":100},"timeSeconds":{"type":"number","description":"Elapsed time over the measured incoming section, seconds.","minimum":0.01,"maximum":120},"uncertaintySeconds":{"type":"number","description":"Absolute bound on the WHOLE elapsed split in seconds, not per timestamp.","minimum":0,"maximum":10}},"required":["distanceMeters","timeSeconds","uncertaintySeconds"],"additionalProperties":false},"minItems":1,"maxItems":30},"outgoingTrials":{"type":"array","description":"Measured entries in the stated units and original order.","items":{"type":"object","description":"Strict measured input object; units are explicit on each field.","properties":{"cueToExchangeSeconds":{"type":"number","description":"Measured seconds from visual go cue to matched exchange reference. Includes cue reaction once; do not add a generic reaction correction.","minimum":0.01,"maximum":30},"uncertaintySeconds":{"type":"number","description":"Absolute bound on the whole outgoing cue-to-exchange duration, seconds.","minimum":0,"maximum":10}},"required":["cueToExchangeSeconds","uncertaintySeconds"],"additionalProperties":false},"minItems":1,"maxItems":30},"observedTransfers":{"type":"array","description":"Measured entries in the stated units and original order.","items":{"type":"object","description":"Strict measured input object; units are explicit on each field.","properties":{"firstTouchBackMeters":{"type":"number","description":"Backmost whole-baton coordinate at first receiver touch, meters from zone entry.","minimum":-30,"maximum":60},"firstTouchFrontMeters":{"type":"number","description":"Frontmost whole-baton coordinate at first receiver touch, meters from zone entry.","minimum":-30,"maximum":60},"releaseBackMeters":{"type":"number","description":"Backmost whole-baton coordinate when only the receiver holds it, meters from zone entry.","minimum":-30,"maximum":60},"releaseFrontMeters":{"type":"number","description":"Frontmost whole-baton coordinate when only the receiver holds it, meters from zone entry.","minimum":-30,"maximum":60},"uncertaintyMeters":{"type":"number","description":"Absolute bound per observed baton coordinate, meters.","minimum":0,"maximum":10}},"required":["firstTouchBackMeters","firstTouchFrontMeters","releaseBackMeters","releaseFrontMeters","uncertaintyMeters"],"additionalProperties":false},"minItems":0,"maxItems":30}},"required":["incomingReference","receiverStartMeters","exchangeReferenceMeters","referenceUncertaintyMeters","incomingTrials","outgoingTrials"],"additionalProperties":false},"example":{"incomingReference":"incoming-torso","receiverStartMeters":0.5,"exchangeReferenceMeters":24,"referenceUncertaintyMeters":0.1,"incomingTrials":[{"distanceMeters":20,"timeSeconds":2,"uncertaintySeconds":0.02},{"distanceMeters":20,"timeSeconds":2.04,"uncertaintySeconds":0.02},{"distanceMeters":20,"timeSeconds":1.98,"uncertaintySeconds":0.02}],"outgoingTrials":[{"cueToExchangeSeconds":3.2,"uncertaintySeconds":0.03},{"cueToExchangeSeconds":3.25,"uncertaintySeconds":0.03},{"cueToExchangeSeconds":3.15,"uncertaintySeconds":0.03}],"observedTransfers":[{"firstTouchBackMeters":23.7,"firstTouchFrontMeters":24,"releaseBackMeters":25,"releaseFrontMeters":25.3,"uncertaintyMeters":0.05}]}},{"slug":"hurdle-touchdown-calculator","math":{"href":"https://www.tracktoolspro.com/api/calculators/hurdle-touchdown-calculator","jsonPointer":"/calculator/math","version":"2026-10-21.1","implementationVersion":"b5a8aca7b85361476e0321a08b7fa5f516fc9535","scope":"Canonical HTTP function and documented corresponding mounted-form math. This is public inspectable documentation, not access control or independent empirical validation.","unitNotation":"Input paths use [] and *; output paths are JSON Pointers with * (one segment) and ** (descendants). Empty output path denotes scalar result. Units apply to numeric quantities or explicitly described numeric strings; labels/statuses/booleans are dimensionless. More specific units, including count/index exceptions, override broad patterns.","interfaceNotes":["HTTP input is described by the adjacent inputSchema. The original handlers may accept numeric strings; this metadata adds no validation.","Mounted forms accept displayed clock/unit strings and enforce their own limits. Mounted tools limit strings to 200 characters and numeric parts to magnitude 1000000. Do not assume mounted/API input interchangeability.","Some legacy extreme/invalid tuples can produce null/empty results or nonfinite numbers serialized as null. Those are unavailable answers, not exact numerical predictions. Per-calculator domain describes the intended mathematical inputs."],"kind":"measured-timing","implementationFiles":["lib/formulas/hurdle-touchdown.ts","lib/formulas/field-measurements.ts"],"equations":["Timestamps: elapsed=reading-origin. Frames: elapsed=(readingFrame-originFrame)/captureFrameRate; per-endpoint u=uncertaintyFrames/captureFrameRate (or entered seconds).","Consecutive observed difference=(currentReading-previousReading)/rate. Each distinct-endpoint elapsed/interval bound adds endpoint errors: +/-2u, lower clamped at0. Origin contact itself has elapsed0 and bound0.","Target difference=observed elapsed-targetSeconds; beyondBound=abs(difference)>elapsed uncertainty. No target is generated.","Summarize only consecutive-hurdle intervals, with mean/median/min/max/sample SD. Gaps remain multi-hurdle observations. Finish/run-out exists only if observed; never substitute last contact for finish.","Reference hurdle-plane position=firstHurdleMeters+(index-1)*spacingMeters; these are not measured touchdown coordinates."],"inputUnits":{"event":"enum/string (dimensionless)","timingOrigin":"enum/string (dimensionless)","timestamps.originSeconds":"s","timestamps.uncertaintySeconds":"s","timestamps.touchdowns[].hurdle":"dimensionless index/count","timestamps.touchdowns[].reading":"s","timestamps.finishSeconds":"s","timestamps.runOutEndSeconds":"s","frames.originFrame":"capture frame index","frames.captureFrameRate":"capture frames/s","frames.constantFrameRateConfirmed":"boolean (true)","frames.uncertaintyFrames":"frames","frames.touchdowns[].hurdle":"dimensionless index/count","frames.touchdowns[].reading":"capture frame index","frames.finishFrame":"capture frame index","frames.runOutEndFrame":"capture frame index","targetTouchdownsSeconds[].hurdle":"dimensionless index/count","targetTouchdownsSeconds[].seconds":"s","targetEndSeconds":"s"},"outputUnits":{"/captureFrameRate":"capture frames/s","/endpointUncertaintySeconds":"s","/intervalUncertaintySeconds":"s","/layoutReference/count":"dimensionless index/count","/layoutReference/distanceMeters":"m","/layoutReference/firstHurdleMeters":"m","/layoutReference/spacingMeters":"m","/layoutReference/positionsMeters/*":"m","/contacts/*/hurdle":"dimensionless index/count","/contacts/*/rawReading":"s in timestamps mode; frame index in frames mode","/contacts/*/fromHurdle":"dimensionless index/count","/contacts/*/elapsed/*":"s","/contacts/*/interval/*":"s","/contacts/*/targetSeconds":"s","/contacts/*/differenceSeconds":"s","/contacts/*/differenceUncertaintySeconds":"s","/approach/*":"s","/approach/toHurdle":"dimensionless index/count","/endSegment/*":"s","/endSegment/fromHurdle":"dimensionless index/count","/endElapsed/*":"s","/consecutiveIntervalSummary/*":"s","/consecutiveIntervalSummary/count":"dimensionless index/count"},"domain":["Exactly one strict timestamps/frames mode; 1..20 ordered contacts within selected event count; strictly increasing readings and hurdle indices. Origin precedes first contact, or equals it for first-contact origin. Duration<=3600s; constant recorded fps 0.1..10000, integer frame indices; optional endpoint follows contacts and targets match observed indices."],"rounding":["Raw IEEE-754 numbers; the mounted page formats clocks separately."],"assumptions":["Uses the entered values and the selected convention; this documentation does not strengthen existing validation."],"limitations":["Lead-foot first ground contact, not hurdle-plane clearance or COM speed. Timing uncertainty is a bound, not confidence; fps exact by assumption, no capture-clock drift model. WA300mH7hurdles differs from US HS8. No inferred missing contacts, targets or endpoint."],"mountedPageNotes":[],"workedExamples":[{"input":{"event":"110mH","timingOrigin":"gun","timestamps":{"originSeconds":0,"uncertaintySeconds":0.01,"touchdowns":[{"hurdle":1,"reading":2.7},{"hurdle":2,"reading":3.85},{"hurdle":3,"reading":5},{"hurdle":4,"reading":6.16},{"hurdle":5,"reading":7.32},{"hurdle":6,"reading":8.5},{"hurdle":7,"reading":9.71},{"hurdle":8,"reading":10.94},{"hurdle":9,"reading":12.2},{"hurdle":10,"reading":13.49}],"finishSeconds":15},"targetTouchdownsSeconds":[{"hurdle":1,"seconds":2.7},{"hurdle":10,"seconds":13.3}],"targetEndSeconds":14.8},"expected":{"/contacts/9/elapsed/seconds":13.49,"/endElapsed/seconds":15},"absoluteTolerance":1e-8,"note":"Illustrative canonical-handler result; not independent validation of an empirical model."}],"constantsAndTables":{"eventLayouts":{"100mH":{"label":"100mH · World Athletics","count":10,"distanceMeters":100,"firstHurdleMeters":13,"spacingMeters":8.5},"110mH":{"label":"110mH · World Athletics","count":10,"distanceMeters":110,"firstHurdleMeters":13.72,"spacingMeters":9.14},"300mH-wa":{"label":"300mH · World Athletics (7 hurdles)","count":7,"distanceMeters":300,"firstHurdleMeters":50,"spacingMeters":35},"400mH":{"label":"400mH · World Athletics","count":10,"distanceMeters":400,"firstHurdleMeters":45,"spacingMeters":35},"custom":{"label":"Custom / discounted practice","count":20,"distanceMeters":null,"firstHurdleMeters":null,"spacingMeters":null}},"ruleReference":{"title":"World Athletics Competition and Technical Rules (official index: 1 July 2026)","url":"https://worldathletics.org/download/download?filename=0ed43077-8e08-492b-a4b3-267f27c18d0b.pdf&urlslug=C1.1%20%26%20C2.1%20-%20Competition%20Rules%20%26%20Technical%20Rules","checkedOn":"2026-10-15"},"distinctEndpointBoundMultiplier":2},"sources":[{"title":"Canonical HTTP binding at the documented implementation revision","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/calculator-functions.ts","note":"Existing calculation handler; math metadata is additive."},{"title":"lib/formulas/hurdle-touchdown.ts","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/formulas/hurdle-touchdown.ts","note":"Primary implementation source for these equations/tables, not a claim of scientific calibration."},{"title":"lib/formulas/field-measurements.ts","url":"https://github.com/wickthumb/track_tools_pro_marketing/blob/b5a8aca7b85361476e0321a08b7fa5f516fc9535/lib/formulas/field-measurements.ts","note":"Primary implementation source for these equations/tables, not a claim of scientific calibration."}]},"annotations":{"readOnlyHint":true,"consequentialHint":false},"name":"Hurdle Touchdown Calculator","description":"Measure touchdown intervals from timestamps or capture frames, compare your targets and retain timing uncertainty.","category":"Sprints & Hurdles","method":"POST","endpoint":"/api/calculators/hurdle-touchdown-calculator","page":"/calculators/hurdle-touchdown-calculator","inputSchema":{"type":"object","description":"Strict measured input object; units are explicit on each field.","properties":{"event":{"type":"string","enum":["100mH","110mH","300mH-wa","400mH","custom"],"description":"World Athletics reference layout, or custom/discounted practice. No layout is inferred from measured contact timing."},"timingOrigin":{"type":"string","enum":["gun","movement","first-observed-contact"],"description":"The observed event at origin. Movement may be a practice rep start. With first-observed-contact the origin must be the first listed reading; no start-to-contact time is inferred."},"timestamps":{"type":"object","description":"Strict measured input object; units are explicit on each field.","properties":{"originSeconds":{"type":"number","description":"Observed gun/movement origin or first observed contact, seconds on the same clock as all readings.","minimum":0,"maximum":1000000000},"uncertaintySeconds":{"type":"number","description":"Absolute bound per selected timestamp (including origin/end), seconds. Targets are treated as exact.","minimum":0,"maximum":10},"touchdowns":{"type":"array","description":"Measured entries in the stated units and original order.","items":{"type":"object","description":"Strict measured input object; units are explicit on each field.","properties":{"hurdle":{"type":"integer","minimum":1,"maximum":20,"description":"Observed hurdle number; strictly increasing. Gaps remain gaps, not invented individual intervals."},"reading":{"type":"number","description":"Observed lead-foot first ground contact after the hurdle. Seconds on one common clock, or integer capture-frame index in frame mode.","minimum":0,"maximum":1000000000}},"required":["hurdle","reading"],"additionalProperties":false},"minItems":1,"maxItems":20},"finishSeconds":{"type":"number","description":"Observed torso crossing the finish plane on the same clock; never inferred from the last contact.","minimum":0,"maximum":1000000000},"runOutEndSeconds":{"type":"number","description":"Observed practice run-out marker time on the same clock; not a race finish. Do not provide with finishSeconds.","minimum":0,"maximum":1000000000}},"required":["originSeconds","uncertaintySeconds","touchdowns"],"additionalProperties":false},"frames":{"type":"object","description":"Strict measured input object; units are explicit on each field.","properties":{"originFrame":{"type":"integer","minimum":0,"maximum":1000000000,"description":"Integer recorded capture-frame index, not slowed-playback time."},"captureFrameRate":{"type":"number","description":"Recorded constant capture frame rate in frames/second, including valid fractional rates. Not playback/export fps.","minimum":0.1,"maximum":10000},"constantFrameRateConfirmed":{"type":"boolean","enum":[true],"description":"Must confirm recorded constant frame rate. Use actual timestamps for variable-frame-rate footage."},"uncertaintyFrames":{"type":"integer","minimum":0,"maximum":1000,"description":"Absolute bound in whole frames on each selected endpoint, including origin/end."},"touchdowns":{"type":"array","description":"Measured entries in the stated units and original order.","items":{"type":"object","description":"Strict measured input object; units are explicit on each field.","properties":{"hurdle":{"type":"integer","minimum":1,"maximum":20,"description":"Observed hurdle number; strictly increasing. Gaps remain gaps, not invented individual intervals."},"reading":{"type":"integer","minimum":0,"maximum":1000000000,"description":"Observed lead-foot first ground contact after the hurdle. Seconds on one common clock, or integer capture-frame index in frame mode."}},"required":["hurdle","reading"],"additionalProperties":false},"minItems":1,"maxItems":20},"finishFrame":{"type":"integer","minimum":0,"maximum":1000000000,"description":"Integer recorded capture-frame index, not slowed-playback time."},"runOutEndFrame":{"type":"integer","minimum":0,"maximum":1000000000,"description":"Integer recorded capture-frame index, not slowed-playback time."}},"required":["originFrame","captureFrameRate","constantFrameRateConfirmed","uncertaintyFrames","touchdowns"],"additionalProperties":false},"targetTouchdownsSeconds":{"type":"array","description":"Measured entries in the stated units and original order.","items":{"type":"object","description":"Strict measured input object; units are explicit on each field.","properties":{"hurdle":{"type":"integer","minimum":1,"maximum":20,"description":"Observed hurdle number; strictly increasing. Gaps remain gaps, not invented individual intervals."},"seconds":{"type":"number","description":"Coach-entered target elapsed seconds from the SAME stated origin as actual data, not absolute video time.","minimum":0,"maximum":3600}},"required":["hurdle","seconds"],"additionalProperties":false},"minItems":1,"maxItems":20},"targetEndSeconds":{"type":"number","description":"Target elapsed seconds to the same observed finish/run-out endpoint; requires that endpoint.","minimum":0,"maximum":3600}},"required":["event","timingOrigin"],"additionalProperties":false,"oneOf":[{"required":["timestamps"]},{"required":["frames"]}]},"example":{"event":"110mH","timingOrigin":"gun","timestamps":{"originSeconds":0,"uncertaintySeconds":0.01,"touchdowns":[{"hurdle":1,"reading":2.7},{"hurdle":2,"reading":3.85},{"hurdle":3,"reading":5},{"hurdle":4,"reading":6.16},{"hurdle":5,"reading":7.32},{"hurdle":6,"reading":8.5},{"hurdle":7,"reading":9.71},{"hurdle":8,"reading":10.94},{"hurdle":9,"reading":12.2},{"hurdle":10,"reading":13.49}],"finishSeconds":15},"targetTouchdownsSeconds":[{"hurdle":1,"seconds":2.7},{"hurdle":10,"seconds":13.3}],"targetEndSeconds":14.8}}]}