diff --git a/src/Duration.ts b/src/Duration.ts new file mode 100644 index 0000000..117d501 --- /dev/null +++ b/src/Duration.ts @@ -0,0 +1,7 @@ +export class Duration { + constructor(readonly value: number) {} + + add(other: Duration): Duration { + return new Duration(this.value + other.value); + } +} diff --git a/src/Seconds.ts b/src/Seconds.ts deleted file mode 100644 index 127bb44..0000000 --- a/src/Seconds.ts +++ /dev/null @@ -1,7 +0,0 @@ -export class Seconds { - constructor(readonly value: number) {} - - add(other: Seconds): Seconds { - return new Seconds(this.value + other.value); - } -} diff --git a/src/ast.ts b/src/ast.ts index 9c57a16..9862dad 100644 --- a/src/ast.ts +++ b/src/ast.ts @@ -1,5 +1,5 @@ import { IntervalType } from "./parser/tokenizer"; -import { Seconds } from "./Seconds"; +import { Duration } from "./Duration"; export type Workout = { name: string; @@ -10,13 +10,13 @@ export type Workout = { export type Interval = { type: IntervalType; - duration: Seconds; + duration: Duration; intensity: { from: number; to: number }; cadence?: number; comments: Comment[]; }; export type Comment = { - offset: Seconds; + offset: Duration; text: string; }; diff --git a/src/detectRepeats.test.ts b/src/detectRepeats.test.ts index 0ecd29a..176e93d 100644 --- a/src/detectRepeats.test.ts +++ b/src/detectRepeats.test.ts @@ -1,6 +1,6 @@ import { Interval } from "./ast"; import { detectRepeats } from "./detectRepeats"; -import { Seconds } from "./Seconds"; +import { Duration } from "./Duration"; describe("detectRepeats()", () => { it("does nothing with empty array", () => { @@ -9,32 +9,32 @@ describe("detectRepeats()", () => { it("does nothing when no interval repeats", () => { const intervals: Interval[] = [ - { type: "Rest", duration: new Seconds(60), intensity: { from: 0.5, to: 0.5 }, comments: [] }, - { type: "Interval", duration: new Seconds(60), intensity: { from: 1, to: 1 }, comments: [] }, - { type: "Interval", duration: new Seconds(30), intensity: { from: 1.2, to: 1.2 }, comments: [] }, - { type: "Cooldown", duration: new Seconds(60), intensity: { from: 1, to: 0.5 }, comments: [] }, + { type: "Rest", duration: new Duration(60), intensity: { from: 0.5, to: 0.5 }, comments: [] }, + { type: "Interval", duration: new Duration(60), intensity: { from: 1, to: 1 }, comments: [] }, + { type: "Interval", duration: new Duration(30), intensity: { from: 1.2, to: 1.2 }, comments: [] }, + { type: "Cooldown", duration: new Duration(60), intensity: { from: 1, to: 0.5 }, comments: [] }, ]; expect(detectRepeats(intervals)).toEqual(intervals); }); it("detects whole workout consisting of repetitions", () => { const intervals: Interval[] = [ - { type: "Interval", duration: new Seconds(120), intensity: { from: 1, to: 1 }, comments: [] }, - { type: "Rest", duration: new Seconds(60), intensity: { from: 0.5, to: 0.5 }, comments: [] }, - { type: "Interval", duration: new Seconds(120), intensity: { from: 1, to: 1 }, comments: [] }, - { type: "Rest", duration: new Seconds(60), intensity: { from: 0.5, to: 0.5 }, comments: [] }, - { type: "Interval", duration: new Seconds(120), intensity: { from: 1, to: 1 }, comments: [] }, - { type: "Rest", duration: new Seconds(60), intensity: { from: 0.5, to: 0.5 }, comments: [] }, - { type: "Interval", duration: new Seconds(120), intensity: { from: 1, to: 1 }, comments: [] }, - { type: "Rest", duration: new Seconds(60), intensity: { from: 0.5, to: 0.5 }, comments: [] }, + { type: "Interval", duration: new Duration(120), intensity: { from: 1, to: 1 }, comments: [] }, + { type: "Rest", duration: new Duration(60), intensity: { from: 0.5, to: 0.5 }, comments: [] }, + { type: "Interval", duration: new Duration(120), intensity: { from: 1, to: 1 }, comments: [] }, + { type: "Rest", duration: new Duration(60), intensity: { from: 0.5, to: 0.5 }, comments: [] }, + { type: "Interval", duration: new Duration(120), intensity: { from: 1, to: 1 }, comments: [] }, + { type: "Rest", duration: new Duration(60), intensity: { from: 0.5, to: 0.5 }, comments: [] }, + { type: "Interval", duration: new Duration(120), intensity: { from: 1, to: 1 }, comments: [] }, + { type: "Rest", duration: new Duration(60), intensity: { from: 0.5, to: 0.5 }, comments: [] }, ]; expect(detectRepeats(intervals)).toEqual([ { type: "repeat", times: 4, intervals: [ - { type: "Interval", duration: new Seconds(120), intensity: { from: 1, to: 1 }, comments: [] }, - { type: "Rest", duration: new Seconds(60), intensity: { from: 0.5, to: 0.5 }, comments: [] }, + { type: "Interval", duration: new Duration(120), intensity: { from: 1, to: 1 }, comments: [] }, + { type: "Rest", duration: new Duration(60), intensity: { from: 0.5, to: 0.5 }, comments: [] }, ], comments: [], }, @@ -43,54 +43,54 @@ describe("detectRepeats()", () => { it("detects repetitions in the middle of workout", () => { const intervals: Interval[] = [ - { type: "Warmup", duration: new Seconds(60), intensity: { from: 0.5, to: 1 }, comments: [] }, - { type: "Rest", duration: new Seconds(120), intensity: { from: 0.2, to: 0.2 }, comments: [] }, - { type: "Interval", duration: new Seconds(60), intensity: { from: 1, to: 1 }, comments: [] }, - { type: "Rest", duration: new Seconds(60), intensity: { from: 0.5, to: 0.5 }, comments: [] }, - { type: "Interval", duration: new Seconds(60), intensity: { from: 1, to: 1 }, comments: [] }, - { type: "Rest", duration: new Seconds(60), intensity: { from: 0.5, to: 0.5 }, comments: [] }, - { type: "Interval", duration: new Seconds(60), intensity: { from: 1, to: 1 }, comments: [] }, - { type: "Rest", duration: new Seconds(60), intensity: { from: 0.5, to: 0.5 }, comments: [] }, - { type: "Interval", duration: new Seconds(60), intensity: { from: 1, to: 1 }, comments: [] }, - { type: "Rest", duration: new Seconds(60), intensity: { from: 0.5, to: 0.5 }, comments: [] }, - { type: "Rest", duration: new Seconds(120), intensity: { from: 0.2, to: 0.2 }, comments: [] }, - { type: "Cooldown", duration: new Seconds(60), intensity: { from: 1, to: 0.5 }, comments: [] }, + { type: "Warmup", duration: new Duration(60), intensity: { from: 0.5, to: 1 }, comments: [] }, + { type: "Rest", duration: new Duration(120), intensity: { from: 0.2, to: 0.2 }, comments: [] }, + { type: "Interval", duration: new Duration(60), intensity: { from: 1, to: 1 }, comments: [] }, + { type: "Rest", duration: new Duration(60), intensity: { from: 0.5, to: 0.5 }, comments: [] }, + { type: "Interval", duration: new Duration(60), intensity: { from: 1, to: 1 }, comments: [] }, + { type: "Rest", duration: new Duration(60), intensity: { from: 0.5, to: 0.5 }, comments: [] }, + { type: "Interval", duration: new Duration(60), intensity: { from: 1, to: 1 }, comments: [] }, + { type: "Rest", duration: new Duration(60), intensity: { from: 0.5, to: 0.5 }, comments: [] }, + { type: "Interval", duration: new Duration(60), intensity: { from: 1, to: 1 }, comments: [] }, + { type: "Rest", duration: new Duration(60), intensity: { from: 0.5, to: 0.5 }, comments: [] }, + { type: "Rest", duration: new Duration(120), intensity: { from: 0.2, to: 0.2 }, comments: [] }, + { type: "Cooldown", duration: new Duration(60), intensity: { from: 1, to: 0.5 }, comments: [] }, ]; expect(detectRepeats(intervals)).toEqual([ - { type: "Warmup", duration: new Seconds(60), intensity: { from: 0.5, to: 1 }, comments: [] }, - { type: "Rest", duration: new Seconds(120), intensity: { from: 0.2, to: 0.2 }, comments: [] }, + { type: "Warmup", duration: new Duration(60), intensity: { from: 0.5, to: 1 }, comments: [] }, + { type: "Rest", duration: new Duration(120), intensity: { from: 0.2, to: 0.2 }, comments: [] }, { type: "repeat", times: 4, intervals: [ - { type: "Interval", duration: new Seconds(60), intensity: { from: 1, to: 1 }, comments: [] }, - { type: "Rest", duration: new Seconds(60), intensity: { from: 0.5, to: 0.5 }, comments: [] }, + { type: "Interval", duration: new Duration(60), intensity: { from: 1, to: 1 }, comments: [] }, + { type: "Rest", duration: new Duration(60), intensity: { from: 0.5, to: 0.5 }, comments: [] }, ], comments: [], }, - { type: "Rest", duration: new Seconds(120), intensity: { from: 0.2, to: 0.2 }, comments: [] }, - { type: "Cooldown", duration: new Seconds(60), intensity: { from: 1, to: 0.5 }, comments: [] }, + { type: "Rest", duration: new Duration(120), intensity: { from: 0.2, to: 0.2 }, comments: [] }, + { type: "Cooldown", duration: new Duration(60), intensity: { from: 1, to: 0.5 }, comments: [] }, ]); }); it("detects multiple repetitions", () => { const intervals: Interval[] = [ - { type: "Interval", duration: new Seconds(60), intensity: { from: 1, to: 1 }, comments: [] }, - { type: "Rest", duration: new Seconds(60), intensity: { from: 0.5, to: 0.5 }, comments: [] }, - { type: "Interval", duration: new Seconds(60), intensity: { from: 1, to: 1 }, comments: [] }, - { type: "Rest", duration: new Seconds(60), intensity: { from: 0.5, to: 0.5 }, comments: [] }, - { type: "Interval", duration: new Seconds(100), intensity: { from: 1, to: 1 }, comments: [] }, - { type: "Rest", duration: new Seconds(100), intensity: { from: 0.5, to: 0.5 }, comments: [] }, - { type: "Interval", duration: new Seconds(100), intensity: { from: 1, to: 1 }, comments: [] }, - { type: "Rest", duration: new Seconds(100), intensity: { from: 0.5, to: 0.5 }, comments: [] }, + { type: "Interval", duration: new Duration(60), intensity: { from: 1, to: 1 }, comments: [] }, + { type: "Rest", duration: new Duration(60), intensity: { from: 0.5, to: 0.5 }, comments: [] }, + { type: "Interval", duration: new Duration(60), intensity: { from: 1, to: 1 }, comments: [] }, + { type: "Rest", duration: new Duration(60), intensity: { from: 0.5, to: 0.5 }, comments: [] }, + { type: "Interval", duration: new Duration(100), intensity: { from: 1, to: 1 }, comments: [] }, + { type: "Rest", duration: new Duration(100), intensity: { from: 0.5, to: 0.5 }, comments: [] }, + { type: "Interval", duration: new Duration(100), intensity: { from: 1, to: 1 }, comments: [] }, + { type: "Rest", duration: new Duration(100), intensity: { from: 0.5, to: 0.5 }, comments: [] }, ]; expect(detectRepeats(intervals)).toEqual([ { type: "repeat", times: 2, intervals: [ - { type: "Interval", duration: new Seconds(60), intensity: { from: 1, to: 1 }, comments: [] }, - { type: "Rest", duration: new Seconds(60), intensity: { from: 0.5, to: 0.5 }, comments: [] }, + { type: "Interval", duration: new Duration(60), intensity: { from: 1, to: 1 }, comments: [] }, + { type: "Rest", duration: new Duration(60), intensity: { from: 0.5, to: 0.5 }, comments: [] }, ], comments: [], }, @@ -98,8 +98,8 @@ describe("detectRepeats()", () => { type: "repeat", times: 2, intervals: [ - { type: "Interval", duration: new Seconds(100), intensity: { from: 1, to: 1 }, comments: [] }, - { type: "Rest", duration: new Seconds(100), intensity: { from: 0.5, to: 0.5 }, comments: [] }, + { type: "Interval", duration: new Duration(100), intensity: { from: 1, to: 1 }, comments: [] }, + { type: "Rest", duration: new Duration(100), intensity: { from: 0.5, to: 0.5 }, comments: [] }, ], comments: [], }, @@ -108,22 +108,22 @@ describe("detectRepeats()", () => { it("takes cadence differences into account", () => { const intervals: Interval[] = [ - { type: "Interval", duration: new Seconds(120), intensity: { from: 1, to: 1 }, comments: [] }, - { type: "Rest", duration: new Seconds(60), intensity: { from: 0.5, to: 0.5 }, comments: [] }, - { type: "Interval", duration: new Seconds(120), intensity: { from: 1, to: 1 }, cadence: 100, comments: [] }, - { type: "Rest", duration: new Seconds(60), intensity: { from: 0.5, to: 0.5 }, cadence: 80, comments: [] }, - { type: "Interval", duration: new Seconds(120), intensity: { from: 1, to: 1 }, cadence: 100, comments: [] }, - { type: "Rest", duration: new Seconds(60), intensity: { from: 0.5, to: 0.5 }, cadence: 80, comments: [] }, + { type: "Interval", duration: new Duration(120), intensity: { from: 1, to: 1 }, comments: [] }, + { type: "Rest", duration: new Duration(60), intensity: { from: 0.5, to: 0.5 }, comments: [] }, + { type: "Interval", duration: new Duration(120), intensity: { from: 1, to: 1 }, cadence: 100, comments: [] }, + { type: "Rest", duration: new Duration(60), intensity: { from: 0.5, to: 0.5 }, cadence: 80, comments: [] }, + { type: "Interval", duration: new Duration(120), intensity: { from: 1, to: 1 }, cadence: 100, comments: [] }, + { type: "Rest", duration: new Duration(60), intensity: { from: 0.5, to: 0.5 }, cadence: 80, comments: [] }, ]; expect(detectRepeats(intervals)).toEqual([ - { type: "Interval", duration: new Seconds(120), intensity: { from: 1, to: 1 }, comments: [] }, - { type: "Rest", duration: new Seconds(60), intensity: { from: 0.5, to: 0.5 }, comments: [] }, + { type: "Interval", duration: new Duration(120), intensity: { from: 1, to: 1 }, comments: [] }, + { type: "Rest", duration: new Duration(60), intensity: { from: 0.5, to: 0.5 }, comments: [] }, { type: "repeat", times: 2, intervals: [ - { type: "Interval", duration: new Seconds(120), intensity: { from: 1, to: 1 }, cadence: 100, comments: [] }, - { type: "Rest", duration: new Seconds(60), intensity: { from: 0.5, to: 0.5 }, cadence: 80, comments: [] }, + { type: "Interval", duration: new Duration(120), intensity: { from: 1, to: 1 }, cadence: 100, comments: [] }, + { type: "Rest", duration: new Duration(60), intensity: { from: 0.5, to: 0.5 }, cadence: 80, comments: [] }, ], comments: [], }, @@ -132,14 +132,14 @@ describe("detectRepeats()", () => { it("does not consider warmup/cooldown-range intervals to be repeatable", () => { const intervals: Interval[] = [ - { type: "Warmup", duration: new Seconds(60), intensity: { from: 0.1, to: 1 }, comments: [] }, - { type: "Cooldown", duration: new Seconds(120), intensity: { from: 1, to: 0.5 }, comments: [] }, - { type: "Warmup", duration: new Seconds(60), intensity: { from: 0.1, to: 1 }, comments: [] }, - { type: "Cooldown", duration: new Seconds(120), intensity: { from: 1, to: 0.5 }, comments: [] }, - { type: "Warmup", duration: new Seconds(60), intensity: { from: 0.1, to: 1 }, comments: [] }, - { type: "Cooldown", duration: new Seconds(120), intensity: { from: 1, to: 0.5 }, comments: [] }, - { type: "Warmup", duration: new Seconds(60), intensity: { from: 0.1, to: 1 }, comments: [] }, - { type: "Cooldown", duration: new Seconds(120), intensity: { from: 1, to: 0.5 }, comments: [] }, + { type: "Warmup", duration: new Duration(60), intensity: { from: 0.1, to: 1 }, comments: [] }, + { type: "Cooldown", duration: new Duration(120), intensity: { from: 1, to: 0.5 }, comments: [] }, + { type: "Warmup", duration: new Duration(60), intensity: { from: 0.1, to: 1 }, comments: [] }, + { type: "Cooldown", duration: new Duration(120), intensity: { from: 1, to: 0.5 }, comments: [] }, + { type: "Warmup", duration: new Duration(60), intensity: { from: 0.1, to: 1 }, comments: [] }, + { type: "Cooldown", duration: new Duration(120), intensity: { from: 1, to: 0.5 }, comments: [] }, + { type: "Warmup", duration: new Duration(60), intensity: { from: 0.1, to: 1 }, comments: [] }, + { type: "Cooldown", duration: new Duration(120), intensity: { from: 1, to: 0.5 }, comments: [] }, ]; expect(detectRepeats(intervals)).toEqual(intervals); }); @@ -148,41 +148,41 @@ describe("detectRepeats()", () => { const intervals: Interval[] = [ { type: "Interval", - duration: new Seconds(100), + duration: new Duration(100), intensity: { from: 1, to: 1 }, comments: [ - { offset: new Seconds(0), text: "Let's start" }, - { offset: new Seconds(20), text: "Stay strong!" }, - { offset: new Seconds(90), text: "Finish it!" }, + { offset: new Duration(0), text: "Let's start" }, + { offset: new Duration(20), text: "Stay strong!" }, + { offset: new Duration(90), text: "Finish it!" }, ], }, { type: "Rest", - duration: new Seconds(100), + duration: new Duration(100), intensity: { from: 0.5, to: 0.5 }, comments: [ - { offset: new Seconds(0), text: "Huh... have a rest" }, - { offset: new Seconds(80), text: "Ready for next?" }, + { offset: new Duration(0), text: "Huh... have a rest" }, + { offset: new Duration(80), text: "Ready for next?" }, ], }, { type: "Interval", - duration: new Seconds(100), + duration: new Duration(100), intensity: { from: 1, to: 1 }, comments: [ - { offset: new Seconds(0), text: "Bring it on again!" }, - { offset: new Seconds(50), text: "Half way" }, - { offset: new Seconds(90), text: "Almost there!" }, + { offset: new Duration(0), text: "Bring it on again!" }, + { offset: new Duration(50), text: "Half way" }, + { offset: new Duration(90), text: "Almost there!" }, ], }, { type: "Rest", - duration: new Seconds(100), + duration: new Duration(100), intensity: { from: 0.5, to: 0.5 }, comments: [ - { offset: new Seconds(30), text: "Wow... you did it!" }, - { offset: new Seconds(40), text: "Nice job." }, - { offset: new Seconds(50), text: "Until next time..." }, + { offset: new Duration(30), text: "Wow... you did it!" }, + { offset: new Duration(40), text: "Nice job." }, + { offset: new Duration(50), text: "Until next time..." }, ], }, ]; @@ -191,24 +191,24 @@ describe("detectRepeats()", () => { type: "repeat", times: 2, intervals: [ - { type: "Interval", duration: new Seconds(100), intensity: { from: 1, to: 1 }, comments: [] }, - { type: "Rest", duration: new Seconds(100), intensity: { from: 0.5, to: 0.5 }, comments: [] }, + { type: "Interval", duration: new Duration(100), intensity: { from: 1, to: 1 }, comments: [] }, + { type: "Rest", duration: new Duration(100), intensity: { from: 0.5, to: 0.5 }, comments: [] }, ], comments: [ - { offset: new Seconds(0), text: "Let's start" }, - { offset: new Seconds(20), text: "Stay strong!" }, - { offset: new Seconds(90), text: "Finish it!" }, + { offset: new Duration(0), text: "Let's start" }, + { offset: new Duration(20), text: "Stay strong!" }, + { offset: new Duration(90), text: "Finish it!" }, - { offset: new Seconds(100), text: "Huh... have a rest" }, - { offset: new Seconds(180), text: "Ready for next?" }, + { offset: new Duration(100), text: "Huh... have a rest" }, + { offset: new Duration(180), text: "Ready for next?" }, - { offset: new Seconds(200), text: "Bring it on again!" }, - { offset: new Seconds(250), text: "Half way" }, - { offset: new Seconds(290), text: "Almost there!" }, + { offset: new Duration(200), text: "Bring it on again!" }, + { offset: new Duration(250), text: "Half way" }, + { offset: new Duration(290), text: "Almost there!" }, - { offset: new Seconds(330), text: "Wow... you did it!" }, - { offset: new Seconds(340), text: "Nice job." }, - { offset: new Seconds(350), text: "Until next time..." }, + { offset: new Duration(330), text: "Wow... you did it!" }, + { offset: new Duration(340), text: "Nice job." }, + { offset: new Duration(350), text: "Until next time..." }, ], }, ]); diff --git a/src/detectRepeats.ts b/src/detectRepeats.ts index 9652c1e..3a0376a 100644 --- a/src/detectRepeats.ts +++ b/src/detectRepeats.ts @@ -1,6 +1,6 @@ import { eqProps, flatten, zip } from "ramda"; import { Interval, Comment } from "./ast"; -import { Seconds } from "./Seconds"; +import { Duration } from "./Duration"; export type RepeatedInterval = { type: "repeat"; @@ -32,7 +32,7 @@ const countRepetitions = (reference: Interval[], intervals: Interval[], startInd return repeats; }; -const offsetComments = (interval: Interval, baseOffset: Seconds): Comment[] => { +const offsetComments = (interval: Interval, baseOffset: Duration): Comment[] => { return interval.comments.map(({ offset, ...rest }) => ({ offset: baseOffset.add(offset), ...rest, @@ -40,7 +40,7 @@ const offsetComments = (interval: Interval, baseOffset: Seconds): Comment[] => { }; const collectComments = (intervals: Interval[]): Comment[] => { - let previousIntervalsDuration = new Seconds(0); + let previousIntervalsDuration = new Duration(0); return flatten( intervals.map((interval) => { const comments = offsetComments(interval, previousIntervalsDuration); diff --git a/src/parser/parser.test.ts b/src/parser/parser.test.ts index 8da3c2d..51c939e 100644 --- a/src/parser/parser.test.ts +++ b/src/parser/parser.test.ts @@ -71,7 +71,7 @@ Rest: 5:00 45% Object { "cadence": undefined, "comments": Array [], - "duration": Seconds { + "duration": Duration { "value": 300, }, "intensity": Object { @@ -83,7 +83,7 @@ Rest: 5:00 45% Object { "cadence": 90, "comments": Array [], - "duration": Seconds { + "duration": Duration { "value": 600, }, "intensity": Object { @@ -95,7 +95,7 @@ Rest: 5:00 45% Object { "cadence": undefined, "comments": Array [], - "duration": Seconds { + "duration": Duration { "value": 300, }, "intensity": Object { @@ -136,7 +136,7 @@ Interval: 5:00 50% Object { "cadence": undefined, "comments": Array [], - "duration": Seconds { + "duration": Duration { "value": 300, }, "intensity": Object { @@ -148,7 +148,7 @@ Interval: 5:00 50% Object { "cadence": undefined, "comments": Array [], - "duration": Seconds { + "duration": Duration { "value": 600, }, "intensity": Object { @@ -160,7 +160,7 @@ Interval: 5:00 50% Object { "cadence": undefined, "comments": Array [], - "duration": Seconds { + "duration": Duration { "value": 300, }, "intensity": Object { @@ -188,7 +188,7 @@ Cooldown: 5:30 70%..45% Object { "cadence": 100, "comments": Array [], - "duration": Seconds { + "duration": Duration { "value": 330, }, "intensity": Object { @@ -200,7 +200,7 @@ Cooldown: 5:30 70%..45% Object { "cadence": undefined, "comments": Array [], - "duration": Seconds { + "duration": Duration { "value": 330, }, "intensity": Object { @@ -232,7 +232,7 @@ Cooldown: 5:30 70%..45% Object { "cadence": undefined, "comments": Array [], - "duration": Seconds { + "duration": Duration { "value": 10, }, "intensity": Object { @@ -246,7 +246,7 @@ Cooldown: 5:30 70%..45% Object { "cadence": 100, "comments": Array [], - "duration": Seconds { + "duration": Duration { "value": 10, }, "intensity": Object { @@ -260,7 +260,7 @@ Cooldown: 5:30 70%..45% Object { "cadence": 100, "comments": Array [], - "duration": Seconds { + "duration": Duration { "value": 10, }, "intensity": Object { @@ -277,7 +277,7 @@ Cooldown: 5:30 70%..45% Object { "cadence": 100, "comments": Array [], - "duration": Seconds { + "duration": Duration { "value": 10, }, "intensity": Object { @@ -291,7 +291,7 @@ Cooldown: 5:30 70%..45% Object { "cadence": 100, "comments": Array [], - "duration": Seconds { + "duration": Duration { "value": 10, }, "intensity": Object { @@ -373,37 +373,37 @@ Rest: 5:00 50% "cadence": undefined, "comments": Array [ Object { - "offset": Seconds { + "offset": Duration { "value": 0, }, "text": "Find your rythm.", }, Object { - "offset": Seconds { + "offset": Duration { "value": 60, }, "text": "Try to settle in for the effort", }, Object { - "offset": Seconds { + "offset": Duration { "value": 300, }, "text": "Half way through", }, Object { - "offset": Seconds { + "offset": Duration { "value": 540, }, "text": "Almost there", }, Object { - "offset": Seconds { + "offset": Duration { "value": 570, }, "text": "Final push. YOU GOT IT!", }, ], - "duration": Seconds { + "duration": Duration { "value": 600, }, "intensity": Object { @@ -416,19 +416,19 @@ Rest: 5:00 50% "cadence": undefined, "comments": Array [ Object { - "offset": Seconds { + "offset": Duration { "value": 0, }, "text": "Great effort!", }, Object { - "offset": Seconds { + "offset": Duration { "value": 30, }, "text": "Cool down well after all of this.", }, ], - "duration": Seconds { + "duration": Duration { "value": 300, }, "intensity": Object { diff --git a/src/parser/parser.ts b/src/parser/parser.ts index ae6d871..a9a7a2a 100644 --- a/src/parser/parser.ts +++ b/src/parser/parser.ts @@ -1,5 +1,5 @@ import { Interval, Workout, Comment } from "../ast"; -import { Seconds } from "../Seconds"; +import { Duration } from "../Duration"; import { ParseError } from "./ParseError"; import { SourceLocation, Token } from "./tokenizer"; @@ -66,7 +66,7 @@ const parseIntervalComments = (tokens: Token[]): [Comment[], Token[]] => { throw new ParseError(`Expected [comment text] instead got ${tokenToString(text)}`, text?.loc || offset.loc); } comments.push({ - offset: new Seconds(offset.value), + offset: new Duration(offset.value), text: text.value, }); tokens = rest; @@ -85,7 +85,7 @@ const parseIntervalParams = (tokens: Token[], loc: SourceLocation): [IntervalDat while (tokens[0]) { const token = tokens[0]; if (token.type === "duration") { - data.duration = new Seconds(token.value); + data.duration = new Duration(token.value); tokens.shift(); } else if (token.type === "cadence") { data.cadence = token.value; diff --git a/src/stats/totalDuration.ts b/src/stats/totalDuration.ts index 284ca74..33fafe8 100644 --- a/src/stats/totalDuration.ts +++ b/src/stats/totalDuration.ts @@ -1,5 +1,5 @@ import { Interval } from "../ast"; -import { Seconds } from "../Seconds"; +import { Duration } from "../Duration"; -export const totalDuration = (intervals: Interval[]): Seconds => - intervals.reduce((total, interval) => total.add(interval.duration), new Seconds(0)); +export const totalDuration = (intervals: Interval[]): Duration => + intervals.reduce((total, interval) => total.add(interval.duration), new Duration(0)); diff --git a/src/stats/tss.ts b/src/stats/tss.ts index d795855..6cc5a76 100644 --- a/src/stats/tss.ts +++ b/src/stats/tss.ts @@ -1,5 +1,5 @@ import { Interval } from "../ast"; -import { Seconds } from "../Seconds"; +import { Duration } from "../Duration"; // Training Stress Score formula from Training and Racing with a Power Meter: // @@ -9,13 +9,13 @@ import { Seconds } from "../Seconds"; // W - power in watts // IF - intensity factor (power / FTP) -const steadyTss = (duration: Seconds, intensity: number): number => { +const steadyTss = (duration: Duration, intensity: number): number => { return ((duration.value * intensity * intensity) / 3600) * 100; }; -const rangeTss = (duration: Seconds, from: number, to: number): number => { +const rangeTss = (duration: Duration, from: number, to: number): number => { let score = 0; - const step = new Seconds(1); + const step = new Duration(1); for (let i = 0; i < duration.value; i += step.value) { const intensity = from + (to - from) * (i / duration.value); score += steadyTss(step, intensity); diff --git a/src/stats/tss2.ts b/src/stats/tss2.ts index da0802b..9d3c7b6 100644 --- a/src/stats/tss2.ts +++ b/src/stats/tss2.ts @@ -1,4 +1,4 @@ -import { Seconds } from "../Seconds"; +import { Duration } from "../Duration"; // Training Stress Score formula from Training and Racing with a Power Meter: // @@ -13,6 +13,6 @@ import { Seconds } from "../Seconds"; // TSS = (s * (FTP * IF) * IF) / (FTP * 3600) * 100 // TSS = (s * IF * IF) / 3600 * 100 -export const tss2 = (duration: Seconds, intensity: number): number => { +export const tss2 = (duration: Duration, intensity: number): number => { return ((duration.value * intensity * intensity) / 3600) * 100; };