incyclist-services 1.1.86 → 1.1.87

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/lib/routes/base/types/index.d.ts +3 -0
  2. package/lib/routes/list/cards/ActiveImportCard.d.ts +2 -1
  3. package/lib/routes/list/cards/FreeRideCard.d.ts +2 -1
  4. package/lib/routes/list/cards/RouteCard.d.ts +13 -3
  5. package/lib/routes/list/cards/RouteCard.js +53 -17
  6. package/lib/routes/list/cards/RouteImportCard.d.ts +2 -1
  7. package/lib/routes/list/cards/types.d.ts +0 -3
  8. package/lib/routes/list/service.d.ts +1 -1
  9. package/lib/routes/list/service.js +3 -1
  10. package/lib/workouts/base/model/Segment.d.ts +18 -0
  11. package/lib/workouts/base/model/Segment.js +139 -0
  12. package/lib/workouts/base/model/Step.d.ts +35 -0
  13. package/lib/workouts/base/model/Step.js +158 -0
  14. package/lib/workouts/base/model/Workout.d.ts +10 -0
  15. package/lib/workouts/base/model/Workout.js +42 -0
  16. package/lib/workouts/base/model/types.d.ts +44 -0
  17. package/lib/workouts/base/model/types.js +2 -0
  18. package/lib/workouts/base/parsers/Json.d.ts +12 -0
  19. package/lib/workouts/base/parsers/Json.js +73 -0
  20. package/lib/workouts/base/parsers/factory.d.ts +11 -0
  21. package/lib/workouts/base/parsers/factory.js +92 -0
  22. package/lib/workouts/base/parsers/index.d.ts +5 -0
  23. package/lib/workouts/base/parsers/index.js +51 -0
  24. package/lib/workouts/base/parsers/types.d.ts +8 -0
  25. package/lib/workouts/base/parsers/types.js +2 -0
  26. package/lib/workouts/base/parsers/zwo.d.ts +32 -0
  27. package/lib/workouts/base/parsers/zwo.js +249 -0
  28. package/lib/workouts/list/cards/WorkoutCard.d.ts +0 -0
  29. package/lib/workouts/list/cards/WorkoutCard.js +0 -0
  30. package/lib/workouts/list/cards/WorkoutImportCard.d.ts +19 -0
  31. package/lib/workouts/list/cards/WorkoutImportCard.js +40 -0
  32. package/lib/workouts/list/cards/base.d.ts +20 -0
  33. package/lib/workouts/list/cards/base.js +54 -0
  34. package/lib/workouts/list/cards/types.d.ts +19 -0
  35. package/lib/workouts/list/cards/types.js +8 -0
  36. package/lib/workouts/list/service.d.ts +4 -0
  37. package/lib/workouts/list/service.js +66 -0
  38. package/package.json +1 -1
@@ -120,3 +120,6 @@ export interface Parser<In, Out extends RouteBase> {
120
120
  supportsContent(data: In): boolean;
121
121
  getData(info: FileInfo, data?: In): Promise<In>;
122
122
  }
123
+ export interface AppStatus {
124
+ isOnline?: boolean;
125
+ }
@@ -4,7 +4,8 @@ import { ImportFilter } from "../../../base/cardlist/types";
4
4
  import { PromiseObserver } from "../../../base/types/observer";
5
5
  import { Route } from "../../base/model/route";
6
6
  import { BaseCard } from "./base";
7
- import { AppStatus, RouteCardType, ActiveImportProps } from "./types";
7
+ import { RouteCardType, ActiveImportProps } from "./types";
8
+ import { AppStatus } from "../../base/types";
8
9
  export declare class ActiveImportCard extends BaseCard implements Card<Route> {
9
10
  protected file: FileInfo;
10
11
  protected error: Error;
@@ -5,7 +5,8 @@ import { LatLng } from "../../../utils/geo";
5
5
  import { Route } from "../../base/model/route";
6
6
  import { FreeRideOption } from "../types";
7
7
  import { BaseCard } from "./base";
8
- import { AppStatus, RouteCardType } from "./types";
8
+ import { RouteCardType } from "./types";
9
+ import { AppStatus } from "../../base/types";
9
10
  export type FreeRideSettings = {
10
11
  position?: LatLng;
11
12
  options?: any;
@@ -2,9 +2,10 @@ import { Card, CardList } from "../../../base/cardlist";
2
2
  import { Observer, PromiseObserver } from "../../../base/types/observer";
3
3
  import { RouteApiDetail } from "../../base/api/types";
4
4
  import { Route } from "../../base/model/route";
5
- import { RouteInfo } from "../../base/types";
5
+ import { RouteInfo, RoutePoint } from "../../base/types";
6
6
  import { BaseCard } from "./base";
7
- import { AppStatus, RouteCardType } from "./types";
7
+ import { RouteCardType } from "./types";
8
+ import { AppStatus } from "../../base/types";
8
9
  import { RouteStartSettings } from "../types";
9
10
  import { RoutesDbLoader } from "../loaders/db";
10
11
  import { DownloadObserver } from "../../download/types";
@@ -28,8 +29,15 @@ export interface StartSettings {
28
29
  realityFactor: number;
29
30
  downloadProgress?: number;
30
31
  convertProgress?: number;
32
+ loopOverwrite?: boolean;
33
+ nextOverwrite?: boolean;
31
34
  }
32
35
  export type RouteSettings = StartSettings & RouteStartSettings;
36
+ export type RouteCardProps = {
37
+ settings: RouteSettings;
38
+ showLoopOverwrite: boolean;
39
+ showNextOverwrite: boolean;
40
+ };
33
41
  declare class ConvertObserver extends Observer {
34
42
  protected conversion: Observer;
35
43
  constructor();
@@ -65,10 +73,11 @@ export declare class RouteCard extends BaseCard implements Card<Route> {
65
73
  getCardType(): RouteCardType;
66
74
  getTitle(): string;
67
75
  getDisplayProperties(): SummaryCardDisplayProps;
76
+ getMarkers(settings?: RouteSettings): Array<RoutePoint>;
68
77
  getId(): string;
69
78
  enableDelete(enabled?: boolean): void;
70
79
  canDelete(): boolean;
71
- openSettings(): RouteSettings;
80
+ openSettings(): RouteCardProps;
72
81
  changeSettings(props: RouteSettings): void;
73
82
  save(): Promise<void>;
74
83
  delete(): PromiseObserver<boolean>;
@@ -102,5 +111,6 @@ export declare class RouteCard extends BaseCard implements Card<Route> {
102
111
  protected resetDownload(): Promise<void>;
103
112
  protected deleteRoute(): Promise<void>;
104
113
  protected logError(err: Error, fn: string): void;
114
+ protected getSettings(): RouteSettings;
105
115
  }
106
116
  export {};
@@ -22,6 +22,7 @@ const utils_1 = require("../../../utils");
22
22
  const service_2 = require("../../download/service");
23
23
  const localization_1 = require("../../base/utils/localization");
24
24
  const gd_eventlog_1 = require("gd-eventlog");
25
+ const route_1 = require("../../base/utils/route");
25
26
  class ConvertObserver extends observer_1.Observer {
26
27
  constructor() {
27
28
  super();
@@ -162,6 +163,19 @@ class RouteCard extends base_1.BaseCard {
162
163
  this.logError(err, 'getDisplayProperties');
163
164
  }
164
165
  }
166
+ getMarkers(settings) {
167
+ const markers = [];
168
+ try {
169
+ const startSettings = settings || this.getSettings();
170
+ const startDistance = startSettings.startPos || 0;
171
+ const startPos = (0, route_1.getPosition)(this.route, { distance: startDistance, nearest: true });
172
+ markers.push(startPos);
173
+ }
174
+ catch (err) {
175
+ this.logError(err, 'getMarkers');
176
+ }
177
+ return markers;
178
+ }
165
179
  getId() {
166
180
  var _a, _b;
167
181
  return (_b = (_a = this.route) === null || _a === void 0 ? void 0 : _a.description) === null || _b === void 0 ? void 0 : _b.id;
@@ -173,32 +187,29 @@ class RouteCard extends base_1.BaseCard {
173
187
  return this.deleteable;
174
188
  }
175
189
  openSettings() {
176
- this.startSettings = { startPos: 0, realityFactor: 100, type: this.getCardType() };
190
+ var _a, _b, _c, _d, _e, _f;
191
+ const settings = this.getSettings();
192
+ let showLoopOverwrite, showNextOverwrite;
177
193
  try {
178
- let migrate = false;
179
- const legacy = this.buildSettingsKey(true);
180
- const legacySettings = (0, settings_1.useUserSettings)().get(legacy, null);
181
- if (legacySettings) {
182
- this.startSettings = legacySettings;
183
- migrate = true;
184
- }
185
- const key = this.buildSettingsKey();
186
- const startSettings = (0, settings_1.useUserSettings)().get(key, null);
187
- if (startSettings) {
188
- this.startSettings = startSettings;
189
- }
190
- if (migrate) {
191
- (0, settings_1.useUserSettings)().set(key, this.startSettings);
194
+ showLoopOverwrite = (_b = (_a = this.route) === null || _a === void 0 ? void 0 : _a.description) === null || _b === void 0 ? void 0 : _b.isLoop;
195
+ showNextOverwrite = (0, valid_1.valid)((_d = (_c = this.route) === null || _c === void 0 ? void 0 : _c.description) === null || _d === void 0 ? void 0 : _d.next);
196
+ if (showNextOverwrite) {
197
+ const card = (0, service_1.getRouteList)().getCard((_f = (_e = this.route) === null || _e === void 0 ? void 0 : _e.description) === null || _f === void 0 ? void 0 : _f.next);
198
+ const route = card === null || card === void 0 ? void 0 : card.getData();
199
+ if (!route || (route.description.requiresDownload && !route.description.isDownloaded)) {
200
+ showNextOverwrite = false;
201
+ }
202
+ console.log('~~~ NEXT', route);
192
203
  }
193
204
  }
194
205
  catch (err) {
195
206
  this.logError(err, 'openSettings');
196
207
  }
197
- return this.startSettings;
208
+ return { settings, showLoopOverwrite, showNextOverwrite };
198
209
  }
199
210
  changeSettings(props) {
200
211
  try {
201
- this.startSettings = props;
212
+ this.startSettings = Object.assign({}, props);
202
213
  const userSettings = (0, settings_1.useUserSettings)();
203
214
  const key = this.buildSettingsKey();
204
215
  userSettings.set(key, props, true);
@@ -275,6 +286,7 @@ class RouteCard extends base_1.BaseCard {
275
286
  start() {
276
287
  try {
277
288
  const service = (0, service_1.getRouteList)();
289
+ console.log('~~~ start', this.startSettings);
278
290
  service.select(this.route);
279
291
  service.setStartSettings(Object.assign({ type: this.getCardType() }, this.startSettings));
280
292
  this.route.description.tsLastStart = Date.now();
@@ -519,5 +531,29 @@ class RouteCard extends base_1.BaseCard {
519
531
  logError(err, fn) {
520
532
  this.logger.logEvent({ message: 'error', error: err.message, fn, stack: err.stack });
521
533
  }
534
+ getSettings() {
535
+ this.startSettings = { startPos: 0, realityFactor: 100, type: this.getCardType() };
536
+ try {
537
+ let migrate = false;
538
+ const legacy = this.buildSettingsKey(true);
539
+ const legacySettings = (0, settings_1.useUserSettings)().get(legacy, null);
540
+ if (legacySettings) {
541
+ this.startSettings = legacySettings;
542
+ migrate = true;
543
+ }
544
+ const key = this.buildSettingsKey();
545
+ const startSettings = (0, settings_1.useUserSettings)().get(key, null);
546
+ if (startSettings) {
547
+ this.startSettings = startSettings;
548
+ }
549
+ if (migrate) {
550
+ (0, settings_1.useUserSettings)().set(key, this.startSettings);
551
+ }
552
+ }
553
+ catch (err) {
554
+ this.logError(err, 'getSettings');
555
+ }
556
+ return this.startSettings;
557
+ }
522
558
  }
523
559
  exports.RouteCard = RouteCard;
@@ -3,7 +3,8 @@ import { ImportFilter } from "../../../base/cardlist/types";
3
3
  import { PromiseObserver } from "../../../base/types/observer";
4
4
  import { Route } from "../../base/model/route";
5
5
  import { BaseCard } from "./base";
6
- import { AppStatus, RouteCardType, RouteImportProps } from "./types";
6
+ import { RouteCardType, RouteImportProps } from "./types";
7
+ import { AppStatus } from "../../base/types";
7
8
  export declare class RouteImportCard extends BaseCard implements Card<Route> {
8
9
  setVisible(): void;
9
10
  canStart(status: AppStatus): boolean;
@@ -17,6 +17,3 @@ export interface ActiveImportProps {
17
17
  visible: boolean;
18
18
  observer: Observer;
19
19
  }
20
- export interface AppStatus {
21
- isOnline?: boolean;
22
- }
@@ -61,7 +61,7 @@ export declare class RouteListService extends IncyclistService {
61
61
  onCarouselUpdated(list: any, item: any, itemsInSlide: any): void;
62
62
  preload(): PromiseObserver<void>;
63
63
  getLists(forUi?: boolean): Array<CardList<Route>>;
64
- getRouteDetails(id: string): Promise<RouteApiDetail>;
64
+ getRouteDetails(id: string, expectLocal?: boolean): Promise<RouteApiDetail>;
65
65
  getSelectedRouteDetails(): Promise<RouteApiDetail>;
66
66
  unselect(): void;
67
67
  select(route: Route): void;
@@ -300,11 +300,13 @@ let RouteListService = (() => {
300
300
  return [this.myRoutes];
301
301
  }
302
302
  }
303
- getRouteDetails(id) {
303
+ getRouteDetails(id, expectLocal = false) {
304
304
  return __awaiter(this, void 0, void 0, function* () {
305
305
  try {
306
306
  const route = this.routes.find(r => r.description.id === id);
307
307
  if (route) {
308
+ if (expectLocal && route.description.requiresDownload && !route.description.isDownloaded)
309
+ return;
308
310
  if (route.details)
309
311
  return route.details;
310
312
  route.details = yield this.db.getDetails(id);
@@ -0,0 +1,18 @@
1
+ import Step from './Step';
2
+ import { CurrentStep, SegmentDefinition, StepDefinition } from './types';
3
+ export default class Segment extends Step implements SegmentDefinition {
4
+ steps: Array<Step>;
5
+ repeat: number;
6
+ constructor(opts?: SegmentDefinition, ignoreValidate?: boolean);
7
+ protected init(opts: SegmentDefinition, ignoreValidate: boolean): void;
8
+ validate(): void;
9
+ validateTiming(): boolean;
10
+ prepareNext(json: StepDefinition | SegmentDefinition): void;
11
+ push(s: any): void;
12
+ getDuration(): number;
13
+ getSingleDuration(): number;
14
+ getStart(): number;
15
+ getEnd(): number;
16
+ getStep(ts: number): Step;
17
+ getLimits(ts: any, includeStepInfo?: boolean): CurrentStep;
18
+ }
@@ -0,0 +1,139 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const valid_1 = require("../../../utils/valid");
7
+ const Step_1 = __importDefault(require("./Step"));
8
+ class Segment extends Step_1.default {
9
+ constructor(opts = null, ignoreValidate) {
10
+ super(opts, true);
11
+ this.steps = [];
12
+ this.repeat = 1;
13
+ this.type = 'segment';
14
+ if ((0, valid_1.valid)(opts)) {
15
+ this.init(opts, ignoreValidate);
16
+ if (ignoreValidate === undefined || ignoreValidate === false)
17
+ this.validate();
18
+ }
19
+ }
20
+ init(opts, ignoreValidate) {
21
+ const start = opts.start || 0;
22
+ this.start = start;
23
+ let stepStart = start;
24
+ if (opts instanceof Step_1.default) {
25
+ this.steps = [new Step_1.default(opts)];
26
+ }
27
+ else if (opts.steps !== undefined) {
28
+ if (Array.isArray(opts.steps)) {
29
+ opts.steps.forEach(step => {
30
+ if (step.start === undefined) {
31
+ step.start = stepStart;
32
+ }
33
+ const s = new Step_1.default(step);
34
+ stepStart = s.end;
35
+ this.steps.push(s);
36
+ });
37
+ }
38
+ else {
39
+ if (ignoreValidate !== true)
40
+ throw new Error(`Invalid Segment description, no steps defined`);
41
+ }
42
+ }
43
+ else {
44
+ if (ignoreValidate === undefined || ignoreValidate === false)
45
+ throw new Error(`Invalid Segment description, no steps defined`);
46
+ }
47
+ if (opts.repeat !== undefined)
48
+ this.repeat = opts.repeat;
49
+ this.duration = this.getDuration();
50
+ this.end = this.start + this.duration;
51
+ }
52
+ validate() {
53
+ this.validateTiming();
54
+ }
55
+ validateTiming() {
56
+ let prev;
57
+ this.steps.forEach(s => {
58
+ s.validateTiming();
59
+ if (prev !== undefined) {
60
+ const delta1 = Math.abs(prev.end - s.start);
61
+ if (delta1 > 0)
62
+ throw new Error(`Invalid Segment description, start & prev end not matching`);
63
+ }
64
+ prev = s;
65
+ });
66
+ return true;
67
+ }
68
+ prepareNext(json) {
69
+ if (json === undefined)
70
+ return;
71
+ const empty = this.steps.length === 0;
72
+ if (json.start === undefined && json.end === undefined) {
73
+ json.start = !empty ? this.steps[this.steps.length - 1].end : 0;
74
+ }
75
+ if (empty) {
76
+ this.start = 0;
77
+ }
78
+ }
79
+ push(s) {
80
+ if (s === undefined)
81
+ return;
82
+ this.prepareNext(s);
83
+ let step;
84
+ if (s instanceof Step_1.default || s instanceof Segment)
85
+ step = s;
86
+ else
87
+ step = new Step_1.default(s);
88
+ this.steps.push(step);
89
+ this.duration += step.getDuration();
90
+ this.end = this.start + this.duration;
91
+ this.validate();
92
+ }
93
+ getDuration() {
94
+ return this.getSingleDuration() * this.repeat;
95
+ }
96
+ getSingleDuration() {
97
+ if (this.steps.length === 0)
98
+ return 0;
99
+ return this.steps.map(s => s.duration).reduce((a, b) => a + b);
100
+ }
101
+ getStart() {
102
+ if (this.start !== undefined)
103
+ return this.start;
104
+ else {
105
+ if (this.steps.length > 0)
106
+ return this.steps[0].start;
107
+ else
108
+ return undefined;
109
+ }
110
+ }
111
+ getEnd() {
112
+ return this.getStart() + this.getDuration();
113
+ }
114
+ getStep(ts) {
115
+ if (ts >= this.getStart() && ts <= this.getEnd()) {
116
+ const segTime = ts - this.getStart();
117
+ let part = (segTime % this.getSingleDuration());
118
+ part += this.getStart();
119
+ if (part === this.getStart() && segTime > 0)
120
+ part += this.getSingleDuration();
121
+ const found = this.steps.find(s => {
122
+ return (part >= s.start && part <= s.end);
123
+ });
124
+ return found;
125
+ }
126
+ }
127
+ getLimits(ts, includeStepInfo = false) {
128
+ const step = this.getStep(ts);
129
+ if (step === undefined)
130
+ return undefined;
131
+ const segTime = ts - this.getStart();
132
+ let part = (segTime % this.getSingleDuration());
133
+ part += this.getStart();
134
+ if (part === this.getStart() && segTime > 0)
135
+ part += this.getSingleDuration();
136
+ return step.getLimits(part, includeStepInfo);
137
+ }
138
+ }
139
+ exports.default = Segment;
@@ -0,0 +1,35 @@
1
+ import { CurrentStep, Limit, PowerLimit, StepDefinition } from "./types";
2
+ export declare const STEP_TYPE: {
3
+ STEP: string;
4
+ SEGMENT: string;
5
+ };
6
+ export declare const POWER_TYPE: {
7
+ WATT: string;
8
+ PCT: string;
9
+ };
10
+ export default class Step implements StepDefinition {
11
+ type: 'step' | 'segment';
12
+ start?: number;
13
+ end?: number;
14
+ duration: number;
15
+ power?: PowerLimit;
16
+ cadence?: Limit;
17
+ hrm?: Limit;
18
+ text: string;
19
+ work: boolean;
20
+ steady: boolean;
21
+ cooldown: boolean;
22
+ constructor(opts?: any, ignoreValidate?: boolean);
23
+ validate(): void;
24
+ getDuration(): number;
25
+ getStart(): number;
26
+ getEnd(): number;
27
+ validateTiming(): boolean;
28
+ validateLimit(p: Limit, name: string): boolean;
29
+ validatePower(): boolean;
30
+ validateCadence(): boolean;
31
+ validateHrm(): boolean;
32
+ getLimits(ts: number, includeStepInfo?: boolean): CurrentStep;
33
+ getRemainder(limits: CurrentStep, includeStepInfo?: boolean): CurrentStep;
34
+ calc(ts: any, limit: any, includeStepInfo: boolean, isPower?: boolean): {};
35
+ }
@@ -0,0 +1,158 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.POWER_TYPE = exports.STEP_TYPE = void 0;
7
+ const clone_1 = __importDefault(require("../../../utils/clone"));
8
+ const valid_1 = require("../../../utils/valid");
9
+ exports.STEP_TYPE = {
10
+ STEP: 'step',
11
+ SEGMENT: 'segment'
12
+ };
13
+ exports.POWER_TYPE = {
14
+ WATT: 'watt',
15
+ PCT: 'pct of FTP'
16
+ };
17
+ class Step {
18
+ constructor(opts, ignoreValidate) {
19
+ const { start, end, duration, power, cadence, hrm, text, work, steady, cooldown } = opts || {};
20
+ const numVal = (s) => typeof (s) === 'string' ? Number(s) : s;
21
+ this.type = 'step';
22
+ this.start = ((0, valid_1.valid)(start)) ? numVal(start) : undefined;
23
+ this.end = ((0, valid_1.valid)(end)) ? numVal(end) : undefined;
24
+ this.duration = ((0, valid_1.valid)(duration)) ? numVal(duration) : 0;
25
+ this.cadence = (0, valid_1.valid)(cadence) ? (0, clone_1.default)(cadence) : undefined;
26
+ this.power = (0, valid_1.valid)(power) ? (0, clone_1.default)(power) : undefined;
27
+ this.hrm = (0, valid_1.valid)(hrm) ? (0, clone_1.default)(hrm) : undefined;
28
+ this.text = text || '';
29
+ this.work = (0, valid_1.valid)(work) ? work : false;
30
+ this.steady = (0, valid_1.valid)(steady) ? steady : true;
31
+ this.cooldown = (0, valid_1.valid)(cooldown) ? cooldown : false;
32
+ if (ignoreValidate === undefined || ignoreValidate === false)
33
+ this.validate();
34
+ }
35
+ validate() {
36
+ this.validateTiming();
37
+ this.validatePower();
38
+ this.validateCadence();
39
+ this.validateHrm();
40
+ }
41
+ getDuration() { return this.duration; }
42
+ getStart() { return this.start; }
43
+ getEnd() { return this.end; }
44
+ validateTiming() {
45
+ if (this.start === undefined && this.end === undefined) {
46
+ throw new Error(`Invalid Step description, start or end needs to be provided `);
47
+ }
48
+ else if (this.start !== undefined && this.end === undefined) {
49
+ this.end = this.start + this.duration;
50
+ return true;
51
+ }
52
+ else if (this.start === undefined && this.end !== undefined) {
53
+ this.start = this.end - this.duration;
54
+ return true;
55
+ }
56
+ else if (this.start !== undefined && this.end !== undefined && this.duration === 0) {
57
+ this.duration = this.end - this.start;
58
+ if (this.duration < 0)
59
+ throw new Error(`Invalid Step description, duration:${this.duration} `);
60
+ return true;
61
+ }
62
+ else {
63
+ const delta = Math.abs(this.duration - (this.end - this.start));
64
+ if (delta > 0)
65
+ throw new Error(`Invalid step description, duration does not match start and end `);
66
+ return true;
67
+ }
68
+ }
69
+ validateLimit(p, name) {
70
+ if ((0, valid_1.valid)(p)) {
71
+ if (p.min === undefined && p.max === undefined)
72
+ throw new Error(`Invalid Step description, ${name}: no values specified`);
73
+ if (p.min !== undefined && p.max !== undefined && p.min > p.max)
74
+ throw new Error(`Invalid Step description, min ${name} > max ${name}`);
75
+ if (p.min !== undefined && p.min < 0)
76
+ throw new Error(`Invalid Step description, min ${name} <0`);
77
+ if (p.max !== undefined && p.max < 0)
78
+ throw new Error(`Invalid Step description, max ${name} <0`);
79
+ }
80
+ return true;
81
+ }
82
+ validatePower() {
83
+ if ((0, valid_1.valid)(this.power)) {
84
+ const p = this.power;
85
+ if (p.type === undefined)
86
+ p.type = 'watt';
87
+ return this.validateLimit(p, 'power');
88
+ }
89
+ return true;
90
+ }
91
+ validateCadence() {
92
+ return this.validateLimit(this.cadence, 'cadence');
93
+ }
94
+ validateHrm() {
95
+ return this.validateLimit(this.hrm, 'hrm');
96
+ }
97
+ getLimits(ts, includeStepInfo = false) {
98
+ const rv = (limits) => this.getRemainder(limits, includeStepInfo);
99
+ if (ts >= this.start && ts <= this.end) {
100
+ const duration = this.duration;
101
+ const remaining = this.end - ts;
102
+ if (this.steady) {
103
+ const { power, cadence, hrm, text, work } = this;
104
+ return rv({ power, cadence, hrm, text, work, duration, remaining });
105
+ }
106
+ else {
107
+ const { text, work } = this;
108
+ const power = this.calc(ts, this.power, includeStepInfo, true);
109
+ const cadence = this.calc(ts, this.cadence, includeStepInfo);
110
+ const hrm = this.calc(ts, this.hrm, includeStepInfo);
111
+ return rv({ power, cadence, hrm, text, work, duration, remaining });
112
+ }
113
+ }
114
+ else {
115
+ return undefined;
116
+ }
117
+ }
118
+ getRemainder(limits, includeStepInfo = false) {
119
+ if (limits === undefined)
120
+ return;
121
+ if (includeStepInfo)
122
+ limits.step = this;
123
+ return limits;
124
+ }
125
+ calc(ts, limit, includeStepInfo, isPower = false) {
126
+ if (!limit)
127
+ return ({});
128
+ const type = isPower ? limit.type : undefined;
129
+ const rv = (limits) => this.getRemainder(isPower ? Object.assign(Object.assign({}, limits), { type }) : limits, includeStepInfo);
130
+ const part = (ts - this.start) / this.duration;
131
+ if (limit !== undefined) {
132
+ if (limit.max === undefined && limit.min === undefined) {
133
+ return rv({});
134
+ }
135
+ let min, max;
136
+ if (this.cooldown) {
137
+ if (limit.max === undefined && limit.min !== undefined) {
138
+ return rv({ min: limit.min });
139
+ }
140
+ max = limit.min !== undefined ? limit.max - part * (limit.max - limit.min) : limit.max - part * (limit.max);
141
+ min = isPower ? max : limit.min;
142
+ }
143
+ else {
144
+ if (limit.max === undefined && limit.min !== undefined) {
145
+ return rv({ min: limit.min });
146
+ }
147
+ if (limit.min === undefined && limit.max !== undefined) {
148
+ return rv({ max: limit.max });
149
+ }
150
+ max = min = limit.max !== undefined ? part * (limit.max - limit.min) + limit.min : limit.max;
151
+ min = isPower ? max : limit.min;
152
+ }
153
+ limit = { min, max };
154
+ }
155
+ return rv(limit);
156
+ }
157
+ }
158
+ exports.default = Step;
@@ -0,0 +1,10 @@
1
+ import Segment from './Segment';
2
+ import { Category, SegmentDefinition, StepDefinition, WorkoutDefinition } from './types';
3
+ export default class Workout extends Segment implements WorkoutDefinition {
4
+ name: string;
5
+ description: string;
6
+ category: Category;
7
+ constructor(opts: WorkoutDefinition);
8
+ addStep(step: StepDefinition): void;
9
+ addSegment(segment: SegmentDefinition): void;
10
+ }
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const Step_1 = __importDefault(require("./Step"));
7
+ const Segment_1 = __importDefault(require("./Segment"));
8
+ const valid_1 = require("../../../utils/valid");
9
+ class Workout extends Segment_1.default {
10
+ constructor(opts) {
11
+ super(opts, true);
12
+ this.name = opts.name || '';
13
+ this.description = opts.description || undefined;
14
+ this.category = (0, valid_1.valid)(opts.category) ? Object.assign({}, opts.category) : undefined;
15
+ this.repeat = 1;
16
+ }
17
+ addStep(step) {
18
+ if ((0, valid_1.valid)(step)) {
19
+ if (step.duration === undefined && step.start === undefined && step.end === undefined)
20
+ throw new Error(`Invalid Step description, start&end or duration needs to be provided `);
21
+ this.prepareNext(step);
22
+ if (step instanceof Step_1.default)
23
+ this.push(step);
24
+ else {
25
+ const s = new Step_1.default(step);
26
+ this.push(s);
27
+ }
28
+ }
29
+ }
30
+ addSegment(segment) {
31
+ if ((0, valid_1.valid)(segment)) {
32
+ this.prepareNext(segment);
33
+ if (segment instanceof Segment_1.default)
34
+ this.push(segment);
35
+ else {
36
+ const s = new Segment_1.default(segment);
37
+ this.push(s);
38
+ }
39
+ }
40
+ }
41
+ }
42
+ exports.default = Workout;