@kaiord/zwo 4.5.3 → 4.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/browser.d.ts CHANGED
@@ -1,6 +1,6 @@
1
+ import { Z as ZwiftValidator } from './fast-xml-parser-otyxjhMa.js';
2
+ export { a as ZwiftValidationError, b as ZwiftValidationResult, c as createFastXmlZwiftReader, d as createFastXmlZwiftWriter } from './fast-xml-parser-otyxjhMa.js';
1
3
  import { Logger, TextReader, TextWriter } from '@kaiord/core';
2
- import { Z as ZwiftValidator } from './fast-xml-parser-YgKah3Fp.js';
3
- export { d as ZwiftValidationError, b as ZwiftValidationResult, c as createFastXmlZwiftReader, a as createFastXmlZwiftWriter } from './fast-xml-parser-YgKah3Fp.js';
4
4
 
5
5
  /**
6
6
  * Creates a Zwift validator for browser environments.
package/dist/browser.js CHANGED
@@ -1,28 +1,7 @@
1
- import { createConsoleLogger, createZwiftParsingError, createZwiftValidationError, intensitySchema, targetTypeSchema, targetUnitSchema, durationTypeSchema } from '@kaiord/core';
1
+ import { createConsoleLogger, createZwiftParsingError, createZwiftValidationError, targetTypeSchema, targetUnitSchema, intensitySchema, durationTypeSchema } from '@kaiord/core';
2
2
  import { XMLParser, XMLValidator, XMLBuilder } from 'fast-xml-parser';
3
3
 
4
4
  // src/browser.ts
5
- var detectIntervalType = (step) => {
6
- if (step.target.type === targetTypeSchema.enum.open) {
7
- return "FreeRide";
8
- }
9
- if (step.target.type === targetTypeSchema.enum.power) {
10
- const powerValue = step.target.value;
11
- if (powerValue.unit === targetUnitSchema.enum.range) {
12
- if (step.intensity === intensitySchema.enum.warmup) {
13
- return "Warmup";
14
- }
15
- if (step.intensity === intensitySchema.enum.cooldown) {
16
- return "Cooldown";
17
- }
18
- return "Ramp";
19
- }
20
- if (powerValue.unit === targetUnitSchema.enum.percent_ftp || powerValue.unit === targetUnitSchema.enum.watts) {
21
- return "SteadyState";
22
- }
23
- }
24
- return "SteadyState";
25
- };
26
5
 
27
6
  // src/adapters/krd-to-zwift/text-events-encoder.ts
28
7
  var encodeTextEvents = (step) => {
@@ -348,6 +327,27 @@ var convertStepToInterval = (step, intervalType, logger) => {
348
327
  }
349
328
  return interval;
350
329
  };
330
+ var detectIntervalType = (step) => {
331
+ if (step.target.type === targetTypeSchema.enum.open) {
332
+ return "FreeRide";
333
+ }
334
+ if (step.target.type === targetTypeSchema.enum.power) {
335
+ const powerValue = step.target.value;
336
+ if (powerValue.unit === targetUnitSchema.enum.range) {
337
+ if (step.intensity === intensitySchema.enum.warmup) {
338
+ return "Warmup";
339
+ }
340
+ if (step.intensity === intensitySchema.enum.cooldown) {
341
+ return "Cooldown";
342
+ }
343
+ return "Ramp";
344
+ }
345
+ if (powerValue.unit === targetUnitSchema.enum.percent_ftp || powerValue.unit === targetUnitSchema.enum.watts) {
346
+ return "SteadyState";
347
+ }
348
+ }
349
+ return "SteadyState";
350
+ };
351
351
 
352
352
  // src/adapters/krd-to-zwift/intervals-encoder.ts
353
353
  var convertStepsToZwiftIntervals = (steps, logger) => {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/adapters/interval/interval-type-detector.ts","../src/adapters/krd-to-zwift/text-events-encoder.ts","../src/adapters/krd-to-zwift/intervals-t-encoder.ts","../src/adapters/krd-to-zwift/duration-encoder.ts","../src/adapters/krd-to-zwift/metadata-encoder.ts","../src/adapters/target/power.converter.ts","../src/adapters/target/pace-cadence.converter.ts","../src/adapters/krd-to-zwift/power-encoder.ts","../src/adapters/krd-to-zwift/target-encoder.ts","../src/adapters/krd-to-zwift/step-encoder.ts","../src/adapters/krd-to-zwift/intervals-encoder.ts","../src/adapters/krd-to-zwift/metadata-builder.ts","../src/adapters/krd-to-zwift/workout-properties.ts","../src/adapters/krd-to-zwift/workout-file-builder.ts","../src/adapters/krd-to-zwift.converter.ts","../src/adapters/xml-validator-helpers.ts","../src/adapters/zwift-to-krd/intervals-extractor.ts","../src/adapters/duration/duration.mapper.ts","../src/adapters/interval/intervals-t-helpers.ts","../src/adapters/interval/intervals-t.mapper.ts","../src/adapters/interval/hr-target-restoration.ts","../src/adapters/interval/target-restoration.ts","../src/adapters/interval/ramp-helpers.ts","../src/adapters/interval/ramp.mapper.ts","../src/adapters/interval/steady-state.mapper.ts","../src/adapters/interval/index.ts","../src/adapters/interval/free-ride.mapper.ts","../src/adapters/zwift-to-krd/intervals-processor.ts","../src/adapters/zwift-to-krd/metadata-extractor.ts","../src/adapters/zwift-to-krd.converter.ts","../src/adapters/fast-xml-parser.ts","../src/adapters/xml-well-formedness-validator.ts","../src/adapters/well-formedness-validator.ts","../src/adapters/xsd-validator-browser.ts","../src/browser.ts"],"names":["targetTypeSchema","createZwiftParsingError","intensitySchema","convertZwiftPowerRange"],"mappings":"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","file":"browser.js","sourcesContent":["import { intensitySchema } from \"@kaiord/core\";\nimport { targetTypeSchema } from \"@kaiord/core\";\nimport { targetUnitSchema } from \"@kaiord/core\";\nimport type { WorkoutStep } from \"@kaiord/core\";\n\nexport type ZwiftIntervalType =\n | \"SteadyState\"\n | \"Warmup\"\n | \"Ramp\"\n | \"Cooldown\"\n | \"FreeRide\";\n\n/**\n * Determine Zwift interval type from KRD workout step\n *\n * Rules:\n * - SteadyState: constant power target (percent_ftp or watts)\n * - Warmup: range target with intensity \"warmup\"\n * - Cooldown: range target with intensity \"cooldown\"\n * - Ramp: range target with intensity \"active\"\n * - FreeRide: open target\n */\nexport const detectIntervalType = (step: WorkoutStep): ZwiftIntervalType => {\n // FreeRide: open target\n if (step.target.type === targetTypeSchema.enum.open) {\n return \"FreeRide\";\n }\n\n // Power targets\n if (step.target.type === targetTypeSchema.enum.power) {\n const powerValue = step.target.value;\n\n // Range targets: Warmup, Ramp, or Cooldown based on intensity\n if (powerValue.unit === targetUnitSchema.enum.range) {\n if (step.intensity === intensitySchema.enum.warmup) {\n return \"Warmup\";\n }\n if (step.intensity === intensitySchema.enum.cooldown) {\n return \"Cooldown\";\n }\n // Default to Ramp for active or unspecified intensity\n return \"Ramp\";\n }\n\n // Constant power targets: SteadyState\n if (\n powerValue.unit === targetUnitSchema.enum.percent_ftp ||\n powerValue.unit === targetUnitSchema.enum.watts\n ) {\n return \"SteadyState\";\n }\n }\n\n // Default to SteadyState for other target types\n return \"SteadyState\";\n};\n","import type { WorkoutStep } from \"@kaiord/core\";\n\nexport const encodeTextEvents = (\n step: WorkoutStep\n): Array<Record<string, unknown>> | Record<string, unknown> | undefined => {\n const stepExtensions = step.extensions?.zwift as\n | Record<string, unknown>\n | undefined;\n const textEvents = stepExtensions?.textEvents as\n | Array<Record<string, unknown>>\n | undefined;\n\n if (!textEvents || textEvents.length === 0) {\n return undefined;\n }\n\n if (textEvents.length === 1) {\n const event = textEvents[0];\n const encoded: Record<string, unknown> = {\n \"@_message\": event.message,\n };\n\n if (event.timeoffset !== undefined) {\n encoded[\"@_timeoffset\"] = event.timeoffset;\n }\n if (event.distoffset !== undefined) {\n encoded[\"@_distoffset\"] = event.distoffset;\n }\n\n return encoded;\n }\n\n return textEvents.map((event) => {\n const encoded: Record<string, unknown> = {\n \"@_message\": event.message,\n };\n\n if (event.timeoffset !== undefined) {\n encoded[\"@_timeoffset\"] = event.timeoffset;\n }\n if (event.distoffset !== undefined) {\n encoded[\"@_distoffset\"] = event.distoffset;\n }\n\n return encoded;\n });\n};\n","import type { RepetitionBlock, WorkoutStep } from \"@kaiord/core\";\nimport { encodeTextEvents } from \"./text-events-encoder\";\n\nconst encodeDurations = (\n onStep: WorkoutStep,\n offStep: WorkoutStep,\n intervalsT: Record<string, unknown>\n): void => {\n if (onStep.duration.type === \"time\") {\n intervalsT[\"@_OnDuration\"] = onStep.duration.seconds;\n } else if (onStep.duration.type === \"distance\") {\n intervalsT[\"@_OnDuration\"] = onStep.duration.meters;\n }\n\n if (offStep.duration.type === \"time\") {\n intervalsT[\"@_OffDuration\"] = offStep.duration.seconds;\n } else if (offStep.duration.type === \"distance\") {\n intervalsT[\"@_OffDuration\"] = offStep.duration.meters;\n }\n};\n\nconst encodePowerTargets = (\n onStep: WorkoutStep,\n offStep: WorkoutStep,\n intervalsT: Record<string, unknown>\n): void => {\n if (\n onStep.target.type === \"power\" &&\n onStep.target.value.unit === \"percent_ftp\"\n ) {\n intervalsT[\"@_OnPower\"] = onStep.target.value.value / 100;\n }\n if (\n offStep.target.type === \"power\" &&\n offStep.target.value.unit === \"percent_ftp\"\n ) {\n intervalsT[\"@_OffPower\"] = offStep.target.value.value / 100;\n }\n};\n\nconst encodeCadenceTargets = (\n onStep: WorkoutStep,\n offStep: WorkoutStep,\n intervalsT: Record<string, unknown>\n): void => {\n if (onStep.target.type === \"cadence\" && onStep.target.value.unit === \"rpm\") {\n intervalsT[\"@_Cadence\"] = onStep.target.value.value;\n } else {\n const onStepExtensions = onStep.extensions?.zwift as\n | Record<string, unknown>\n | undefined;\n const cadence = onStepExtensions?.cadence as number | undefined;\n if (cadence !== undefined) {\n intervalsT[\"@_Cadence\"] = cadence;\n }\n }\n\n if (\n offStep.target.type === \"cadence\" &&\n offStep.target.value.unit === \"rpm\"\n ) {\n intervalsT[\"@_CadenceResting\"] = offStep.target.value.value;\n } else {\n const offStepExtensions = offStep.extensions?.zwift as\n | Record<string, unknown>\n | undefined;\n const cadenceResting = offStepExtensions?.cadence as number | undefined;\n if (cadenceResting !== undefined) {\n intervalsT[\"@_CadenceResting\"] = cadenceResting;\n }\n }\n};\n\nexport const encodeIntervalsT = (\n repetitionBlock: RepetitionBlock\n): Record<string, unknown> => {\n const onStep = repetitionBlock.steps[0];\n const offStep = repetitionBlock.steps[1];\n\n const intervalsT: Record<string, unknown> = {\n \"@_Repeat\": repetitionBlock.repeatCount,\n };\n\n encodeDurations(onStep, offStep, intervalsT);\n encodePowerTargets(onStep, offStep, intervalsT);\n encodeCadenceTargets(onStep, offStep, intervalsT);\n\n const textEvents = encodeTextEvents(onStep);\n if (textEvents) {\n intervalsT.textevent = textEvents;\n }\n\n return intervalsT;\n};\n","import type { WorkoutStep } from \"@kaiord/core\";\nimport type { Logger } from \"@kaiord/core\";\n\nexport const encodeDuration = (\n step: WorkoutStep,\n interval: Record<string, unknown>,\n logger?: Logger\n): void => {\n if (step.duration.type === \"time\") {\n interval[\"@_Duration\"] = step.duration.seconds;\n } else if (step.duration.type === \"distance\") {\n interval[\"@_Duration\"] = step.duration.meters;\n interval[\"@_kaiord:originalDurationType\"] = \"distance\";\n interval[\"@_kaiord:originalDurationMeters\"] = step.duration.meters;\n\n logger?.warn(\"Lossy conversion: distance duration converted to time\", {\n originalMeters: step.duration.meters,\n convertedSeconds: step.duration.meters,\n stepIndex: step.stepIndex,\n });\n } else if (step.duration.type === \"open\") {\n interval[\"@_Duration\"] = 0;\n } else {\n interval[\"@_Duration\"] = 300;\n interval[\"@_kaiord:originalDurationType\"] = step.duration.type;\n\n if (\"bpm\" in step.duration) {\n interval[\"@_kaiord:originalDurationBpm\"] = step.duration.bpm;\n } else if (\"watts\" in step.duration) {\n interval[\"@_kaiord:originalDurationWatts\"] = step.duration.watts;\n }\n\n logger?.warn(\"Lossy conversion: unsupported duration type\", {\n originalType: step.duration.type,\n fallbackSeconds: 300,\n stepIndex: step.stepIndex,\n });\n }\n};\n","import type { WorkoutStep } from \"@kaiord/core\";\nimport type { Logger } from \"@kaiord/core\";\n\nconst encodeHrRange = (\n step: WorkoutStep,\n interval: Record<string, unknown>,\n logger?: Logger\n): void => {\n if (step.target.type === \"heart_rate\" && step.target.value.unit === \"range\") {\n interval[\"@_kaiord:hrTargetLow\"] = step.target.value.min;\n interval[\"@_kaiord:hrTargetHigh\"] = step.target.value.max;\n logger?.warn(\"Lossy conversion: heart rate target not supported by Zwift\", {\n hrRange: { low: step.target.value.min, high: step.target.value.max },\n stepIndex: step.stepIndex,\n });\n }\n};\n\nconst encodeHrBpm = (\n step: WorkoutStep,\n interval: Record<string, unknown>,\n logger?: Logger\n): void => {\n if (step.target.type === \"heart_rate\" && step.target.value.unit === \"bpm\") {\n interval[\"@_kaiord:hrTargetBpm\"] = step.target.value.value;\n logger?.warn(\"Lossy conversion: heart rate target not supported by Zwift\", {\n hrBpm: step.target.value.value,\n stepIndex: step.stepIndex,\n });\n }\n};\n\nconst encodeHrZone = (\n step: WorkoutStep,\n interval: Record<string, unknown>,\n logger?: Logger\n): void => {\n if (step.target.type === \"heart_rate\" && step.target.value.unit === \"zone\") {\n interval[\"@_kaiord:hrTargetZone\"] = step.target.value.value;\n logger?.warn(\"Lossy conversion: heart rate target not supported by Zwift\", {\n hrZone: step.target.value.value,\n stepIndex: step.stepIndex,\n });\n }\n};\n\nconst encodeHrPercentMax = (\n step: WorkoutStep,\n interval: Record<string, unknown>,\n logger?: Logger\n): void => {\n if (\n step.target.type === \"heart_rate\" &&\n step.target.value.unit === \"percent_max\"\n ) {\n interval[\"@_kaiord:hrTargetPercentMax\"] = step.target.value.value;\n logger?.warn(\"Lossy conversion: heart rate target not supported by Zwift\", {\n hrPercentMax: step.target.value.value,\n stepIndex: step.stepIndex,\n });\n }\n};\n\nexport const encodeHeartRateTarget = (\n step: WorkoutStep,\n interval: Record<string, unknown>,\n logger?: Logger\n): void => {\n encodeHrRange(step, interval, logger);\n encodeHrBpm(step, interval, logger);\n encodeHrZone(step, interval, logger);\n encodeHrPercentMax(step, interval, logger);\n};\n\nexport const encodeMetadata = (\n step: WorkoutStep,\n interval: Record<string, unknown>\n): void => {\n if (step.name) {\n interval[\"@_kaiord:name\"] = step.name;\n }\n if (step.intensity) {\n interval[\"@_kaiord:intensity\"] = step.intensity;\n }\n if (step.equipment) {\n interval[\"@_kaiord:equipment\"] = step.equipment;\n }\n};\n","import { targetTypeSchema, type Target } from \"@kaiord/core\";\n\n/**\n * Convert Zwift power target (FTP percentage 0.0-3.0) to KRD power target\n * Zwift uses FTP percentage (e.g., 0.85 = 85% FTP)\n * KRD uses percent_ftp (e.g., 85 = 85% FTP)\n */\nexport const convertZwiftPowerTarget = (ftpPercentage: number): Target => {\n return {\n type: targetTypeSchema.enum.power,\n value: {\n unit: \"percent_ftp\",\n value: ftpPercentage * 100,\n },\n };\n};\n\n/**\n * Convert Zwift power range (PowerLow/PowerHigh) to KRD range target\n */\nexport const convertZwiftPowerRange = (\n powerLow: number,\n powerHigh: number\n): Target => {\n return {\n type: targetTypeSchema.enum.power,\n value: {\n unit: \"range\",\n min: powerLow * 100,\n max: powerHigh * 100,\n },\n };\n};\n\n/**\n * Convert KRD power target to Zwift FTP percentage\n * KRD uses percent_ftp (e.g., 85 = 85% FTP)\n * Zwift uses FTP percentage (e.g., 0.85 = 85% FTP)\n */\nexport const convertKrdPowerToZwift = (percentFtp: number): number => {\n return percentFtp / 100;\n};\n\n/**\n * Convert KRD power range to Zwift PowerLow/PowerHigh\n * Returns [PowerLow, PowerHigh] tuple\n */\nexport const convertKrdPowerRangeToZwift = (\n min: number,\n max: number\n): [number, number] => {\n return [min / 100, max / 100];\n};\n\n/**\n * Convert power zone (1-7) to percent FTP\n * Uses typical power zone definitions:\n * Zone 1 (Recovery): 55% FTP\n * Zone 2 (Endurance): 75% FTP\n * Zone 3 (Tempo): 90% FTP\n * Zone 4 (Threshold): 105% FTP\n * Zone 5 (VO2 Max): 120% FTP\n * Zone 6 (Anaerobic): 150% FTP\n * Zone 7 (Neuromuscular): 200% FTP\n */\nexport const convertPowerZoneToPercentFtp = (zone: number): number => {\n const zoneMap: Record<number, number> = {\n 1: 55,\n 2: 75,\n 3: 90,\n 4: 105,\n 5: 120,\n 6: 150,\n 7: 200,\n };\n\n return zoneMap[zone] || 100;\n};\n","import { targetTypeSchema, type Target } from \"@kaiord/core\";\n\n/**\n * Convert Zwift pace target (seconds per kilometer) to KRD pace target (meters per second)\n * Formula: m/s = 1000 / sec_per_km\n */\nexport const convertZwiftPaceTarget = (secPerKm: number): Target => {\n return {\n type: targetTypeSchema.enum.pace,\n value: {\n unit: \"mps\",\n value: 1000 / secPerKm,\n },\n };\n};\n\n/**\n * Convert Zwift cadence target to KRD cadence target.\n *\n * Cycling: RPM stays as RPM (crank revolutions per minute)\n * Running: SPM (steps per minute) is converted to RPM.\n *\n * Running cadence conversion rationale:\n * - Zwift and most running apps use SPM (steps per minute)\n * - KRD standardizes on RPM (revolutions/strides per minute)\n * - One stride (revolution) = two steps (left + right foot)\n * - Therefore: RPM = SPM / 2\n *\n * Example: 180 SPM = 90 RPM (90 full strides per minute)\n */\nexport const convertZwiftCadenceTarget = (\n cadence: number,\n isRunning = false\n): Target => {\n // Convert SPM to RPM for running (SPM = 2 * RPM, so RPM = SPM / 2)\n const rpm = isRunning ? cadence / 2 : cadence;\n\n return {\n type: targetTypeSchema.enum.cadence,\n value: {\n unit: \"rpm\",\n value: rpm,\n },\n };\n};\n\n/**\n * Convert KRD pace target to Zwift pace (seconds per kilometer)\n * KRD uses meters per second (m/s)\n * Zwift uses seconds per kilometer (sec/km)\n * Formula: sec/km = 1000 / m/s\n */\nexport const convertKrdPaceToZwift = (metersPerSecond: number): number => {\n return 1000 / metersPerSecond;\n};\n\n/**\n * Convert KRD cadence target to Zwift cadence.\n *\n * KRD uses RPM (revolutions/strides per minute) for all sports.\n * Zwift uses RPM for cycling, SPM (steps per minute) for running.\n *\n * Running conversion: SPM = RPM * 2\n * (One stride = two steps, so multiply RPM by 2 to get SPM)\n *\n * Example: 90 RPM = 180 SPM\n */\nexport const convertKrdCadenceToZwift = (\n rpm: number,\n isRunning = false\n): number => {\n // Convert RPM to SPM for running (SPM = 2 * RPM)\n return isRunning ? rpm * 2 : rpm;\n};\n","import type { WorkoutStep } from \"@kaiord/core\";\nimport type { Logger } from \"@kaiord/core\";\nimport { convertPowerZoneToPercentFtp } from \"../target/target.converter\";\n\nexport const encodeSteadyStatePowerTarget = (\n step: WorkoutStep,\n interval: Record<string, unknown>\n): void => {\n if (step.target.type !== \"power\") return;\n\n if (step.target.value.unit === \"percent_ftp\") {\n interval[\"@_kaiord:powerUnit\"] = \"percent_ftp\";\n interval[\"@_Power\"] = step.target.value.value / 100;\n } else if (step.target.value.unit === \"zone\") {\n interval[\"@_kaiord:powerUnit\"] = \"zone\";\n interval[\"@_kaiord:powerZone\"] = step.target.value.value;\n\n const percentFtp = convertPowerZoneToPercentFtp(step.target.value.value);\n interval[\"@_Power\"] = percentFtp / 100;\n } else if (step.target.value.unit === \"watts\") {\n interval[\"@_kaiord:powerUnit\"] = \"watts\";\n interval[\"@_kaiord:originalWatts\"] = step.target.value.value;\n\n const assumedFtp = 250;\n interval[\"@_kaiord:assumedFtp\"] = assumedFtp;\n const percentFtp = (step.target.value.value / assumedFtp) * 100;\n interval[\"@_Power\"] = percentFtp / 100;\n }\n};\n\nexport const encodeRampPowerTarget = (\n step: WorkoutStep,\n interval: Record<string, unknown>,\n logger?: Logger\n): void => {\n if (step.target.type !== \"power\") return;\n\n if (step.target.value.unit === \"range\") {\n let powerLow = step.target.value.min;\n let powerHigh = step.target.value.max;\n\n interval[\"@_kaiord:powerUnit\"] = \"watts\";\n\n const assumedFtp = 250;\n const originalLow = powerLow;\n const originalHigh = powerHigh;\n powerLow = (powerLow / assumedFtp) * 100;\n powerHigh = (powerHigh / assumedFtp) * 100;\n\n interval[\"@_kaiord:originalWattsLow\"] = originalLow;\n interval[\"@_kaiord:originalWattsHigh\"] = originalHigh;\n interval[\"@_kaiord:assumedFtp\"] = assumedFtp;\n\n logger?.warn(\"Lossy conversion: watts converted to percent FTP\", {\n originalWatts: { low: originalLow, high: originalHigh },\n assumedFtp,\n convertedPercentFtp: { low: powerLow, high: powerHigh },\n stepIndex: step.stepIndex,\n });\n\n interval[\"@_PowerLow\"] = powerLow / 100;\n interval[\"@_PowerHigh\"] = powerHigh / 100;\n } else if (step.target.value.unit === \"zone\") {\n interval[\"@_kaiord:powerUnit\"] = \"zone\";\n interval[\"@_kaiord:powerZone\"] = step.target.value.value;\n\n const percentFtp = convertPowerZoneToPercentFtp(step.target.value.value);\n interval[\"@_PowerLow\"] = percentFtp / 100;\n interval[\"@_PowerHigh\"] = percentFtp / 100;\n } else if (step.target.value.unit === \"percent_ftp\") {\n interval[\"@_kaiord:powerUnit\"] = \"percent_ftp\";\n\n interval[\"@_PowerLow\"] = step.target.value.value / 100;\n interval[\"@_PowerHigh\"] = step.target.value.value / 100;\n }\n};\n","import type { WorkoutStep } from \"@kaiord/core\";\nimport type { Logger } from \"@kaiord/core\";\nimport {\n encodeRampPowerTarget,\n encodeSteadyStatePowerTarget,\n} from \"./power-encoder\";\n\nexport const encodeSteadyStateTargets = (\n step: WorkoutStep,\n interval: Record<string, unknown>\n): void => {\n encodeSteadyStatePowerTarget(step, interval);\n\n if (step.target.type === \"pace\" && step.target.value.unit === \"mps\") {\n interval[\"@_pace\"] = 1000 / step.target.value.value;\n }\n};\n\nexport const encodeRampTargets = (\n step: WorkoutStep,\n interval: Record<string, unknown>,\n logger?: Logger\n): void => {\n encodeRampPowerTarget(step, interval, logger);\n\n if (step.target.type === \"pace\" && step.target.value.unit === \"range\") {\n interval[\"@_paceLow\"] = 1000 / step.target.value.max;\n interval[\"@_paceHigh\"] = 1000 / step.target.value.min;\n }\n};\n\nexport const encodeFreeRideTargets = (\n step: WorkoutStep,\n interval: Record<string, unknown>\n): void => {\n const stepExtensions = step.extensions?.zwift as\n | Record<string, unknown>\n | undefined;\n const flatRoad = (stepExtensions?.flatRoad || stepExtensions?.FlatRoad) as\n | number\n | undefined;\n if (flatRoad !== undefined) {\n interval[\"@_FlatRoad\"] = flatRoad;\n }\n};\n\nexport const encodeTargets = (\n step: WorkoutStep,\n intervalType: string,\n interval: Record<string, unknown>,\n logger?: Logger\n): void => {\n if (intervalType === \"SteadyState\") {\n encodeSteadyStateTargets(step, interval);\n } else if (\n intervalType === \"Warmup\" ||\n intervalType === \"Ramp\" ||\n intervalType === \"Cooldown\"\n ) {\n encodeRampTargets(step, interval, logger);\n } else if (intervalType === \"FreeRide\") {\n encodeFreeRideTargets(step, interval);\n }\n};\n\nexport const encodeCadence = (\n step: WorkoutStep,\n interval: Record<string, unknown>\n): void => {\n if (step.target.type === \"cadence\" && step.target.value.unit === \"rpm\") {\n interval[\"@_Cadence\"] = step.target.value.value;\n }\n};\n","import type { WorkoutStep } from \"@kaiord/core\";\nimport type { Logger } from \"@kaiord/core\";\nimport { encodeDuration } from \"./duration-encoder\";\nimport { encodeHeartRateTarget, encodeMetadata } from \"./metadata-encoder\";\nimport { encodeCadence, encodeTargets } from \"./target-encoder\";\nimport { encodeTextEvents } from \"./text-events-encoder\";\n\nexport const convertStepToInterval = (\n step: WorkoutStep,\n intervalType: string,\n logger?: Logger\n): Record<string, unknown> => {\n const interval: Record<string, unknown> = {};\n\n encodeDuration(step, interval, logger);\n encodeTargets(step, intervalType, interval, logger);\n encodeCadence(step, interval);\n encodeHeartRateTarget(step, interval, logger);\n encodeMetadata(step, interval);\n\n const textEvents = encodeTextEvents(step);\n if (textEvents) {\n interval.textevent = textEvents;\n }\n\n return interval;\n};\n","import type { RepetitionBlock, WorkoutStep } from \"@kaiord/core\";\nimport type { Logger } from \"@kaiord/core\";\nimport { detectIntervalType } from \"../interval/interval-type-detector\";\nimport { encodeIntervalsT } from \"./intervals-t-encoder\";\nimport { convertStepToInterval } from \"./step-encoder\";\n\nexport const convertStepsToZwiftIntervals = (\n steps: Array<WorkoutStep | RepetitionBlock>,\n logger?: Logger\n): Record<string, unknown> => {\n const intervals: Record<string, Array<Record<string, unknown>>> = {};\n\n for (const step of steps) {\n if (\"repeatCount\" in step) {\n const repetitionBlock = step as RepetitionBlock;\n if (repetitionBlock.steps.length === 2) {\n const intervalsT = encodeIntervalsT(repetitionBlock);\n\n if (!intervals.IntervalsT) {\n intervals.IntervalsT = [];\n }\n intervals.IntervalsT.push(intervalsT);\n }\n } else {\n const workoutStep = step as WorkoutStep;\n const intervalType = detectIntervalType(workoutStep);\n const interval = convertStepToInterval(workoutStep, intervalType, logger);\n\n if (!intervals[intervalType]) {\n intervals[intervalType] = [];\n }\n intervals[intervalType].push(interval);\n }\n }\n\n return intervals;\n};\n","import type { KRDMetadata } from \"@kaiord/core\";\n\ntype FitExtensions = Record<string, unknown>;\n\nexport const addKrdMetadata = (\n workoutFile: Record<string, unknown>,\n metadata: KRDMetadata,\n fitExtensions?: FitExtensions\n): void => {\n if (metadata.created) {\n workoutFile[\"@_kaiord:timeCreated\"] = metadata.created;\n }\n if (metadata.manufacturer) {\n workoutFile[\"@_kaiord:manufacturer\"] = metadata.manufacturer;\n }\n if (metadata.product) {\n workoutFile[\"@_kaiord:product\"] = metadata.product;\n }\n if (metadata.serialNumber) {\n workoutFile[\"@_kaiord:serialNumber\"] = metadata.serialNumber;\n }\n\n if (fitExtensions) {\n if (fitExtensions.type) {\n workoutFile[\"@_kaiord:fitType\"] = fitExtensions.type;\n }\n if (fitExtensions.hrm_fit_single_byte_product_id) {\n workoutFile[\"@_kaiord:hrmFitProductId\"] =\n fitExtensions.hrm_fit_single_byte_product_id;\n }\n }\n};\n","type ZwiftExtensions = Record<string, unknown>;\n\nexport const addWorkoutProperties = (\n workoutFile: Record<string, unknown>,\n workoutName: string | undefined,\n zwiftExtensions: ZwiftExtensions\n): void => {\n if (zwiftExtensions.author) {\n workoutFile.author = zwiftExtensions.author;\n }\n if (workoutName) {\n workoutFile.name = workoutName;\n }\n if (zwiftExtensions.description) {\n workoutFile.description = zwiftExtensions.description;\n }\n if (zwiftExtensions.thresholdSecPerKm !== undefined) {\n workoutFile.thresholdSecPerKm = zwiftExtensions.thresholdSecPerKm;\n }\n\n const tags = zwiftExtensions.tags as Array<string> | undefined;\n if (tags && tags.length > 0) {\n workoutFile.tags = {\n tag: tags.map((name) => ({ \"@_name\": name })).filter((t) => t[\"@_name\"]),\n };\n }\n};\n\nexport const mapSportType = (sport?: string): string => {\n return sport === \"cycling\" ? \"bike\" : sport === \"running\" ? \"run\" : \"bike\";\n};\n","import type { KRDMetadata } from \"@kaiord/core\";\nimport type { RepetitionBlock, WorkoutStep } from \"@kaiord/core\";\nimport type { Logger } from \"@kaiord/core\";\nimport { convertStepsToZwiftIntervals } from \"./intervals-encoder\";\nimport { addKrdMetadata } from \"./metadata-builder\";\nimport { addWorkoutProperties, mapSportType } from \"./workout-properties\";\n\ntype WorkoutData = {\n name?: string;\n sport?: string;\n steps?: Array<WorkoutStep | RepetitionBlock>;\n};\n\ntype ZwiftExtensions = Record<string, unknown>;\ntype FitExtensions = Record<string, unknown>;\n\nexport const buildWorkoutFile = (\n workoutData: WorkoutData,\n zwiftExtensions: ZwiftExtensions,\n metadata: KRDMetadata,\n fitExtensions?: FitExtensions,\n logger?: Logger\n): Record<string, unknown> => {\n const workoutFile: Record<string, unknown> = {};\n\n // Add author and name first (XSD requires this order)\n addWorkoutProperties(workoutFile, workoutData.name, zwiftExtensions);\n // Then sportType\n workoutFile.sportType = mapSportType(workoutData.sport);\n\n const intervals = convertStepsToZwiftIntervals(\n workoutData.steps || [],\n logger\n );\n workoutFile.workout = intervals;\n\n addKrdMetadata(workoutFile, metadata, fitExtensions);\n\n return workoutFile;\n};\n","import { XMLBuilder } from \"fast-xml-parser\";\nimport type { KRD } from \"@kaiord/core\";\nimport type { RepetitionBlock, WorkoutStep } from \"@kaiord/core\";\nimport { createZwiftParsingError } from \"@kaiord/core\";\nimport type { Logger } from \"@kaiord/core\";\nimport { buildWorkoutFile } from \"./krd-to-zwift/workout-file-builder\";\n\nconst extractWorkoutData = (krd: KRD) => {\n const workout = krd.extensions?.structured_workout;\n if (!workout || typeof workout !== \"object\") {\n throw createZwiftParsingError(\"KRD missing workout in extensions\");\n }\n\n return workout as {\n name?: string;\n sport?: string;\n steps?: Array<WorkoutStep | RepetitionBlock>;\n };\n};\n\nconst buildXmlString = (workoutFile: Record<string, unknown>): string => {\n const builder = new XMLBuilder({\n ignoreAttributes: false,\n attributeNamePrefix: \"@_\",\n format: true,\n indentBy: \" \",\n });\n\n // Add kaiord namespace for round-trip data preservation\n const workoutFileWithNamespace = {\n \"@_xmlns:kaiord\": \"http://kaiord.dev/zwift-extensions/1.0\",\n ...workoutFile,\n };\n\n const xmlObj = {\n \"?xml\": {\n \"@_version\": \"1.0\",\n \"@_encoding\": \"UTF-8\",\n },\n workout_file: workoutFileWithNamespace,\n };\n\n return builder.build(xmlObj) as string;\n};\n\nexport const convertKRDToZwift = (krd: KRD, logger: Logger): string => {\n logger.debug(\"Building Zwift workout structure from KRD\");\n\n const workoutData = extractWorkoutData(krd);\n const zwiftExtensions = (krd.extensions?.zwift || {}) as Record<\n string,\n unknown\n >;\n\n const workoutFile = buildWorkoutFile(\n workoutData,\n zwiftExtensions,\n krd.metadata,\n krd.extensions?.fit as Record<string, unknown> | undefined,\n logger\n );\n const xmlString = buildXmlString(workoutFile);\n\n logger.debug(\"Zwift XML structure built successfully\");\n return xmlString;\n};\n","import {\n createZwiftParsingError,\n createZwiftValidationError,\n} from \"@kaiord/core\";\nimport type { Logger } from \"@kaiord/core\";\nimport type { ZwiftValidator } from \"../types\";\n\nexport const validateInputZwiftXml = async (\n xmlString: string,\n validator: ZwiftValidator,\n logger: Logger\n): Promise<void> => {\n logger.debug(\"Validating Zwift file against XSD\", {\n xmlLength: xmlString.length,\n });\n\n const validationResult = await validator(xmlString);\n if (!validationResult.valid) {\n logger.error(\"Zwift file does not conform to XSD schema\", {\n errors: validationResult.errors,\n });\n throw createZwiftValidationError(\n \"Zwift file does not conform to XSD schema\",\n validationResult.errors\n );\n }\n};\n\nexport const validateGeneratedZwiftXml = async (\n xmlString: string,\n validator: ZwiftValidator,\n logger: Logger\n): Promise<void> => {\n logger.debug(\"Validating generated Zwift XML against XSD\", {\n xmlLength: xmlString.length,\n });\n\n const validationResult = await validator(xmlString);\n if (!validationResult.valid) {\n logger.error(\"Generated Zwift XML does not conform to XSD schema\", {\n errors: validationResult.errors,\n });\n throw createZwiftValidationError(\n \"Generated Zwift XML does not conform to XSD schema\",\n validationResult.errors\n );\n }\n};\n\nexport const validateZwiftStructure = (\n zwiftData: unknown,\n logger: Logger\n): void => {\n if (\n !zwiftData ||\n typeof zwiftData !== \"object\" ||\n !(\"workout_file\" in zwiftData)\n ) {\n const error = createZwiftParsingError(\n \"Invalid Zwift format: missing workout_file element\"\n );\n logger.error(\"Invalid Zwift structure\", { error });\n throw error;\n }\n};\n","type ZwiftWorkout = {\n SteadyState?: unknown;\n Warmup?: unknown;\n Ramp?: unknown;\n Cooldown?: unknown;\n IntervalsT?: unknown;\n FreeRide?: unknown;\n};\n\nexport const extractIntervals = (\n workout: ZwiftWorkout | undefined\n): Array<{ type: string; data: Record<string, unknown> }> => {\n if (!workout) return [];\n\n const intervals: Array<{ type: string; data: Record<string, unknown> }> = [];\n const intervalTypes = [\n \"SteadyState\",\n \"Warmup\",\n \"Ramp\",\n \"Cooldown\",\n \"IntervalsT\",\n \"FreeRide\",\n ];\n\n for (const type of intervalTypes) {\n const data = workout[type as keyof typeof workout];\n if (data) {\n if (Array.isArray(data)) {\n for (const item of data) {\n intervals.push({ type, data: item as Record<string, unknown> });\n }\n } else {\n intervals.push({ type, data: data as Record<string, unknown> });\n }\n }\n }\n\n return intervals;\n};\n\nexport const extractTags = (\n tags: { tag?: Array<{ \"@_name\": string }> | { \"@_name\": string } } | undefined\n): Array<string> => {\n if (!tags || !tags.tag) return [];\n\n const tagArray = Array.isArray(tags.tag) ? tags.tag : [tags.tag];\n return tagArray.map((t) => t[\"@_name\"]);\n};\n","import { durationTypeSchema, type Duration } from \"@kaiord/core\";\n\nexport type ZwiftDurationData = {\n Duration?: number;\n durationType?: \"time\" | \"distance\";\n // Kaiord round-trip attributes\n \"kaiord:originalDurationType\"?: string;\n \"kaiord:originalDurationMeters\"?: number;\n \"kaiord:originalDurationBpm\"?: number;\n \"kaiord:originalDurationWatts\"?: number;\n};\n\nexport const mapZwiftDuration = (data: ZwiftDurationData): Duration => {\n // Restore original duration type if available\n if (data[\"kaiord:originalDurationType\"] === \"distance\") {\n return {\n type: durationTypeSchema.enum.distance,\n meters: data[\"kaiord:originalDurationMeters\"] || data.Duration || 0,\n };\n }\n\n if (data[\"kaiord:originalDurationType\"] === \"heart_rate_less_than\") {\n return {\n type: durationTypeSchema.enum.heart_rate_less_than,\n bpm: data[\"kaiord:originalDurationBpm\"] || 0,\n };\n }\n\n if (data[\"kaiord:originalDurationType\"] === \"power_less_than\") {\n return {\n type: durationTypeSchema.enum.power_less_than,\n watts: data[\"kaiord:originalDurationWatts\"] || 0,\n };\n }\n\n // Standard Zwift duration handling\n if (data.Duration === undefined || data.Duration <= 0) {\n return { type: durationTypeSchema.enum.open };\n }\n\n if (data.durationType === \"distance\") {\n return {\n type: durationTypeSchema.enum.distance,\n meters: data.Duration,\n };\n }\n\n return {\n type: durationTypeSchema.enum.time,\n seconds: data.Duration,\n };\n};\n\n// KRD → Zwift mappers\nexport const mapKrdTimeDurationToZwift = (seconds: number): number => {\n return seconds;\n};\n\nexport const mapKrdDistanceDurationToZwift = (meters: number): number => {\n return meters;\n};\n","import { intensitySchema } from \"@kaiord/core\";\nimport { targetTypeSchema, type Target } from \"@kaiord/core\";\nimport type { WorkoutStep } from \"@kaiord/core\";\nimport type { ZwiftDurationData } from \"../duration/duration.mapper\";\nimport { mapZwiftDuration } from \"../duration/duration.mapper\";\nimport {\n convertZwiftCadenceTarget,\n convertZwiftPowerTarget,\n} from \"../target/target.converter\";\nimport { extractTextEvents, type ZwiftTextEvent } from \"./index\";\n\nexport type ZwiftIntervalsTData = {\n Repeat: number;\n OnDuration?: number;\n OnPower?: number;\n OffDuration?: number;\n OffPower?: number;\n Cadence?: number;\n CadenceResting?: number;\n durationType?: \"time\" | \"distance\";\n stepIndex: number;\n textevent?: ZwiftTextEvent | Array<ZwiftTextEvent>;\n};\n\nexport const createOnStep = (data: ZwiftIntervalsTData): WorkoutStep => {\n const onDurationData: ZwiftDurationData = {\n Duration: data.OnDuration,\n durationType: data.durationType,\n };\n const onDuration = mapZwiftDuration(onDurationData);\n\n let onTarget: Target;\n if (data.OnPower !== undefined) {\n onTarget = convertZwiftPowerTarget(data.OnPower);\n } else if (data.Cadence !== undefined) {\n onTarget = convertZwiftCadenceTarget(data.Cadence);\n } else {\n onTarget = { type: targetTypeSchema.enum.open };\n }\n\n const textEventData = extractTextEvents(data.textevent);\n\n const onStep: WorkoutStep = {\n stepIndex: data.stepIndex,\n durationType: onDuration.type,\n duration: onDuration,\n targetType: onTarget.type,\n target: onTarget,\n intensity: intensitySchema.enum.active,\n ...textEventData,\n };\n\n if (data.OnPower !== undefined && data.Cadence !== undefined) {\n onStep.extensions = {\n zwift: {\n cadence: data.Cadence,\n },\n };\n }\n\n return onStep;\n};\n\nexport const createOffStep = (data: ZwiftIntervalsTData): WorkoutStep => {\n const offDurationData: ZwiftDurationData = {\n Duration: data.OffDuration,\n durationType: data.durationType,\n };\n const offDuration = mapZwiftDuration(offDurationData);\n\n let offTarget: Target;\n if (data.OffPower !== undefined) {\n offTarget = convertZwiftPowerTarget(data.OffPower);\n } else if (data.CadenceResting !== undefined) {\n offTarget = convertZwiftCadenceTarget(data.CadenceResting);\n } else {\n offTarget = { type: targetTypeSchema.enum.open };\n }\n\n const offStep: WorkoutStep = {\n stepIndex: data.stepIndex + 1,\n durationType: offDuration.type,\n duration: offDuration,\n targetType: offTarget.type,\n target: offTarget,\n intensity: intensitySchema.enum.recovery,\n };\n\n if (data.OffPower !== undefined && data.CadenceResting !== undefined) {\n offStep.extensions = {\n zwift: {\n cadence: data.CadenceResting,\n },\n };\n }\n\n return offStep;\n};\n","import type { RepetitionBlock } from \"@kaiord/core\";\nimport {\n createOffStep,\n createOnStep,\n type ZwiftIntervalsTData,\n} from \"./intervals-t-helpers\";\n\nexport type { ZwiftIntervalsTData };\n\n/**\n * Map Zwift IntervalsT to KRD repetition block with 2 steps (on/off)\n * IntervalsT represents repeated intervals with distinct \"on\" and \"off\" phases\n */\nexport const mapIntervalsTToKrd = (\n data: ZwiftIntervalsTData\n): RepetitionBlock => {\n return {\n repeatCount: data.Repeat,\n steps: [createOnStep(data), createOffStep(data)],\n };\n};\n","import { targetTypeSchema, type Target } from \"@kaiord/core\";\n\ntype KaiordHrAttributes = {\n \"kaiord:hrTargetLow\"?: number;\n \"kaiord:hrTargetHigh\"?: number;\n \"kaiord:hrTargetBpm\"?: number;\n \"kaiord:hrTargetZone\"?: number;\n \"kaiord:hrTargetPercentMax\"?: number;\n};\n\nconst restoreHrRange = (data: KaiordHrAttributes): Target | null => {\n if (\n data[\"kaiord:hrTargetLow\"] !== undefined &&\n data[\"kaiord:hrTargetHigh\"] !== undefined\n ) {\n return {\n type: targetTypeSchema.enum.heart_rate,\n value: {\n unit: \"range\",\n min: data[\"kaiord:hrTargetLow\"],\n max: data[\"kaiord:hrTargetHigh\"],\n },\n };\n }\n return null;\n};\n\nconst restoreHrBpm = (data: KaiordHrAttributes): Target | null => {\n if (data[\"kaiord:hrTargetBpm\"] !== undefined) {\n return {\n type: targetTypeSchema.enum.heart_rate,\n value: {\n unit: \"bpm\",\n value: data[\"kaiord:hrTargetBpm\"],\n },\n };\n }\n return null;\n};\n\nconst restoreHrZone = (data: KaiordHrAttributes): Target | null => {\n if (data[\"kaiord:hrTargetZone\"] !== undefined) {\n return {\n type: targetTypeSchema.enum.heart_rate,\n value: {\n unit: \"zone\",\n value: data[\"kaiord:hrTargetZone\"],\n },\n };\n }\n return null;\n};\n\nconst restoreHrPercentMax = (data: KaiordHrAttributes): Target | null => {\n if (data[\"kaiord:hrTargetPercentMax\"] !== undefined) {\n return {\n type: targetTypeSchema.enum.heart_rate,\n value: {\n unit: \"percent_max\",\n value: data[\"kaiord:hrTargetPercentMax\"],\n },\n };\n }\n return null;\n};\n\nexport const restoreHeartRateTarget = (\n data: KaiordHrAttributes\n): Target | null => {\n return (\n restoreHrRange(data) ||\n restoreHrBpm(data) ||\n restoreHrZone(data) ||\n restoreHrPercentMax(data) ||\n null\n );\n};\n","import { targetTypeSchema, type Target } from \"@kaiord/core\";\n\ntype KaiordTargetAttributes = {\n \"kaiord:powerUnit\"?: \"watts\" | \"percent_ftp\" | \"zone\";\n \"kaiord:originalWattsLow\"?: number;\n \"kaiord:originalWattsHigh\"?: number;\n \"kaiord:powerZone\"?: number;\n \"kaiord:hrTargetLow\"?: number;\n \"kaiord:hrTargetHigh\"?: number;\n \"kaiord:hrTargetBpm\"?: number;\n \"kaiord:hrTargetZone\"?: number;\n \"kaiord:hrTargetPercentMax\"?: number;\n};\n\nconst restoreWattsTarget = (data: KaiordTargetAttributes): Target | null => {\n if (\n data[\"kaiord:powerUnit\"] === \"watts\" &&\n data[\"kaiord:originalWattsLow\"] !== undefined &&\n data[\"kaiord:originalWattsHigh\"] !== undefined\n ) {\n return {\n type: targetTypeSchema.enum.power,\n value: {\n unit: \"range\",\n min: data[\"kaiord:originalWattsLow\"],\n max: data[\"kaiord:originalWattsHigh\"],\n },\n };\n }\n return null;\n};\n\nconst restoreZoneTarget = (data: KaiordTargetAttributes): Target | null => {\n if (\n data[\"kaiord:powerUnit\"] === \"zone\" &&\n data[\"kaiord:powerZone\"] !== undefined\n ) {\n return {\n type: targetTypeSchema.enum.power,\n value: {\n unit: \"zone\",\n value: data[\"kaiord:powerZone\"],\n },\n };\n }\n return null;\n};\n\nexport const restorePowerTarget = (\n data: KaiordTargetAttributes,\n powerLow?: number,\n powerHigh?: number,\n convertZwiftPowerRange?: (low: number, high: number) => Target\n): Target | null => {\n const wattsTarget = restoreWattsTarget(data);\n if (wattsTarget) return wattsTarget;\n\n const zoneTarget = restoreZoneTarget(data);\n if (zoneTarget) return zoneTarget;\n\n if (\n powerLow !== undefined &&\n powerHigh !== undefined &&\n convertZwiftPowerRange\n ) {\n return convertZwiftPowerRange(powerLow, powerHigh);\n }\n\n return null;\n};\n\nexport { restoreHeartRateTarget } from \"./hr-target-restoration\";\n","import type { Intensity } from \"@kaiord/core\";\nimport type { Target } from \"@kaiord/core\";\nimport { targetTypeSchema } from \"@kaiord/core\";\nimport type { WorkoutStep } from \"@kaiord/core\";\nimport type { ZwiftDurationData } from \"../duration/duration.mapper\";\nimport { convertZwiftPowerRange } from \"../target/target.converter\";\nimport {\n restoreHeartRateTarget,\n restorePowerTarget,\n} from \"./target-restoration\";\n\nexport type ZwiftRampData = {\n Duration?: number;\n durationType?: \"time\" | \"distance\";\n PowerLow?: number;\n PowerHigh?: number;\n Cadence?: number;\n stepIndex: number;\n textevent?: unknown;\n \"kaiord:name\"?: string;\n \"kaiord:intensity\"?: string;\n \"kaiord:equipment\"?: string;\n \"kaiord:originalDurationType\"?: string;\n \"kaiord:originalDurationMeters\"?: number;\n \"kaiord:originalDurationBpm\"?: number;\n \"kaiord:originalDurationWatts\"?: number;\n \"kaiord:originalWattsLow\"?: number;\n \"kaiord:originalWattsHigh\"?: number;\n \"kaiord:assumedFtp\"?: number;\n \"kaiord:hrTargetLow\"?: number;\n \"kaiord:hrTargetHigh\"?: number;\n \"kaiord:hrTargetBpm\"?: number;\n \"kaiord:hrTargetZone\"?: number;\n \"kaiord:hrTargetPercentMax\"?: number;\n \"kaiord:powerUnit\"?: \"watts\" | \"percent_ftp\" | \"zone\";\n \"kaiord:powerZone\"?: number;\n};\n\nexport const buildRampDurationData = (\n data: ZwiftRampData\n): ZwiftDurationData => ({\n Duration: data.Duration,\n durationType: data.durationType,\n \"kaiord:originalDurationType\": data[\"kaiord:originalDurationType\"],\n \"kaiord:originalDurationMeters\": data[\"kaiord:originalDurationMeters\"],\n \"kaiord:originalDurationBpm\": data[\"kaiord:originalDurationBpm\"],\n \"kaiord:originalDurationWatts\": data[\"kaiord:originalDurationWatts\"],\n});\n\nexport const resolveRampTarget = (data: ZwiftRampData): Target => {\n const powerTarget = restorePowerTarget(\n data,\n data.PowerLow,\n data.PowerHigh,\n convertZwiftPowerRange\n );\n const hrTarget = restoreHeartRateTarget(data);\n return powerTarget || hrTarget || { type: targetTypeSchema.enum.open };\n};\n\nexport const resolveIntensity = (\n data: ZwiftRampData,\n defaultIntensity: Intensity\n): Intensity => {\n return (\n (data[\"kaiord:intensity\"] as Intensity | undefined) || defaultIntensity\n );\n};\n\nexport const addRampMetadata = (\n step: WorkoutStep,\n data: ZwiftRampData\n): void => {\n if (data[\"kaiord:name\"]) step.name = data[\"kaiord:name\"];\n if (data[\"kaiord:equipment\"]) {\n step.equipment = data[\"kaiord:equipment\"] as WorkoutStep[\"equipment\"];\n }\n};\n","import { intensitySchema, type Intensity } from \"@kaiord/core\";\nimport type { WorkoutStep } from \"@kaiord/core\";\nimport { mapZwiftDuration } from \"../duration/duration.mapper\";\nimport { extractTextEvents, type ZwiftTextEvent } from \"./index\";\nimport {\n addRampMetadata,\n buildRampDurationData,\n resolveIntensity,\n resolveRampTarget,\n type ZwiftRampData,\n} from \"./ramp-helpers\";\n\nexport type { ZwiftRampData };\n\n/**\n * Map Zwift Warmup interval to KRD step\n * Warmup intervals ramp from low to high power with \"warmup\" intensity\n */\nexport const mapWarmupToKrd = (data: ZwiftRampData): WorkoutStep => {\n return mapRampToKrd(data, intensitySchema.enum.warmup);\n};\n\n/**\n * Map Zwift Ramp interval to KRD step\n * Ramp intervals progress between two power values with \"active\" intensity\n */\nexport const mapRampToKrd = (\n data: ZwiftRampData,\n intensity: Intensity = intensitySchema.enum.active\n): WorkoutStep => {\n const duration = mapZwiftDuration(buildRampDurationData(data));\n const target = resolveRampTarget(data);\n const textEventData = extractTextEvents(\n data.textevent as ZwiftTextEvent | Array<ZwiftTextEvent> | undefined\n );\n\n const step: WorkoutStep = {\n stepIndex: data.stepIndex,\n durationType: duration.type,\n duration,\n targetType: target.type,\n target,\n intensity: resolveIntensity(data, intensity),\n ...textEventData,\n };\n\n addRampMetadata(step, data);\n return step;\n};\n\n/**\n * Map Zwift Cooldown interval to KRD step\n * Cooldown intervals ramp from high to low power with \"cooldown\" intensity\n */\nexport const mapCooldownToKrd = (data: ZwiftRampData): WorkoutStep => {\n return mapRampToKrd(data, intensitySchema.enum.cooldown);\n};\n","import { intensitySchema } from \"@kaiord/core\";\nimport { targetTypeSchema, type Target } from \"@kaiord/core\";\nimport type { WorkoutStep } from \"@kaiord/core\";\nimport type { ZwiftDurationData } from \"../duration/duration.mapper\";\nimport { mapZwiftDuration } from \"../duration/duration.mapper\";\nimport { convertZwiftPowerTarget } from \"../target/target.converter\";\nimport { extractTextEvents, type ZwiftTextEvent } from \"./index\";\nimport { restoreHeartRateTarget } from \"./target-restoration\";\n\nexport type ZwiftSteadyStateData = {\n Duration?: number;\n durationType?: \"time\" | \"distance\";\n Power?: number;\n Cadence?: number;\n stepIndex: number;\n textevent?: ZwiftTextEvent | Array<ZwiftTextEvent>;\n // Kaiord round-trip attributes\n \"kaiord:name\"?: string;\n \"kaiord:intensity\"?: string;\n \"kaiord:equipment\"?: string;\n \"kaiord:originalDurationType\"?: string;\n \"kaiord:originalDurationMeters\"?: number;\n \"kaiord:originalDurationBpm\"?: number;\n \"kaiord:originalDurationWatts\"?: number;\n \"kaiord:hrTargetLow\"?: number;\n \"kaiord:hrTargetHigh\"?: number;\n \"kaiord:hrTargetBpm\"?: number;\n \"kaiord:hrTargetZone\"?: number;\n \"kaiord:hrTargetPercentMax\"?: number;\n \"kaiord:powerUnit\"?: \"watts\" | \"percent_ftp\" | \"zone\";\n \"kaiord:originalWatts\"?: number;\n \"kaiord:powerZone\"?: number;\n \"kaiord:assumedFtp\"?: number;\n};\n\nconst restoreSteadyStateTarget = (data: ZwiftSteadyStateData): Target => {\n if (data[\"kaiord:powerUnit\"] === \"watts\" && data[\"kaiord:originalWatts\"]) {\n return {\n type: targetTypeSchema.enum.power,\n value: {\n unit: \"watts\",\n value: data[\"kaiord:originalWatts\"],\n },\n };\n }\n\n if (data[\"kaiord:powerUnit\"] === \"zone\" && data[\"kaiord:powerZone\"]) {\n return {\n type: targetTypeSchema.enum.power,\n value: {\n unit: \"zone\",\n value: data[\"kaiord:powerZone\"],\n },\n };\n }\n\n if (data.Power !== undefined) {\n return convertZwiftPowerTarget(data.Power);\n }\n\n const hrTarget = restoreHeartRateTarget(data);\n return hrTarget || { type: targetTypeSchema.enum.open };\n};\n\nexport const mapSteadyStateToKrd = (\n data: ZwiftSteadyStateData\n): WorkoutStep => {\n const durationData: ZwiftDurationData = {\n Duration: data.Duration,\n durationType: data.durationType,\n \"kaiord:originalDurationType\": data[\"kaiord:originalDurationType\"],\n \"kaiord:originalDurationMeters\": data[\"kaiord:originalDurationMeters\"],\n \"kaiord:originalDurationBpm\": data[\"kaiord:originalDurationBpm\"],\n \"kaiord:originalDurationWatts\": data[\"kaiord:originalDurationWatts\"],\n };\n\n const duration = mapZwiftDuration(durationData);\n const target = restoreSteadyStateTarget(data);\n const textEventData = extractTextEvents(data.textevent);\n\n const step: WorkoutStep = {\n stepIndex: data.stepIndex,\n durationType: duration.type,\n duration,\n targetType: target.type,\n target,\n intensity:\n (data[\"kaiord:intensity\"] as\n | \"warmup\"\n | \"active\"\n | \"cooldown\"\n | \"rest\"\n | undefined) || intensitySchema.enum.active,\n ...textEventData,\n };\n\n if (data[\"kaiord:name\"]) {\n step.name = data[\"kaiord:name\"];\n }\n if (data[\"kaiord:equipment\"]) {\n step.equipment = data[\"kaiord:equipment\"] as WorkoutStep[\"equipment\"];\n }\n\n return step;\n};\n","export type ZwiftTextEvent = {\n message?: string;\n timeoffset?: number;\n distoffset?: number;\n};\n\nexport const extractTextEvents = (\n textevent?: ZwiftTextEvent | Array<ZwiftTextEvent>\n): {\n notes?: string;\n extensions?: { zwift: { textEvents: Array<ZwiftTextEvent> } };\n} => {\n if (!textevent) {\n return {};\n }\n\n const events = Array.isArray(textevent) ? textevent : [textevent];\n\n if (events.length === 0) {\n return {};\n }\n\n const primaryMessage = events[0].message;\n const result: {\n notes?: string;\n extensions?: { zwift: { textEvents: Array<ZwiftTextEvent> } };\n } = {};\n\n if (primaryMessage) {\n result.notes = primaryMessage;\n }\n\n if (events.length > 0) {\n result.extensions = {\n zwift: {\n textEvents: events,\n },\n };\n }\n\n return result;\n};\n\nexport { mapFreeRideToKrd } from \"./free-ride.mapper\";\nexport { mapIntervalsTToKrd } from \"./intervals-t.mapper\";\nexport { mapCooldownToKrd, mapRampToKrd, mapWarmupToKrd } from \"./ramp.mapper\";\nexport { mapSteadyStateToKrd } from \"./steady-state.mapper\";\n","import { intensitySchema } from \"@kaiord/core\";\nimport { targetTypeSchema } from \"@kaiord/core\";\nimport type { WorkoutStep } from \"@kaiord/core\";\nimport type { ZwiftDurationData } from \"../duration/duration.mapper\";\nimport { mapZwiftDuration } from \"../duration/duration.mapper\";\nimport { extractTextEvents, type ZwiftTextEvent } from \"./index\";\n\nexport type ZwiftFreeRideData = {\n Duration?: number;\n durationType?: \"time\" | \"distance\";\n Cadence?: number;\n FlatRoad?: number;\n \"@_FlatRoad\"?: number;\n stepIndex: number;\n textevent?: ZwiftTextEvent | Array<ZwiftTextEvent>;\n};\n\n/**\n * Map Zwift FreeRide interval to KRD step with open target\n * FreeRide intervals allow the user to ride at their own pace\n */\nexport const mapFreeRideToKrd = (data: ZwiftFreeRideData): WorkoutStep => {\n const durationData: ZwiftDurationData = {\n Duration: data.Duration,\n durationType: data.durationType,\n };\n\n const duration = mapZwiftDuration(durationData);\n\n const textEventData = extractTextEvents(data.textevent);\n\n const step: WorkoutStep = {\n stepIndex: data.stepIndex,\n durationType: duration.type,\n duration,\n targetType: targetTypeSchema.enum.open,\n target: { type: targetTypeSchema.enum.open },\n intensity: intensitySchema.enum.active,\n ...textEventData,\n };\n\n // Store FlatRoad attribute in extensions for round-trip preservation\n const flatRoad = data[\"@_FlatRoad\"] ?? data.FlatRoad;\n if (flatRoad !== undefined) {\n step.extensions = {\n ...step.extensions,\n zwift: {\n ...((step.extensions?.zwift as Record<string, unknown>) || {}),\n FlatRoad: flatRoad,\n },\n };\n }\n\n return step;\n};\n","import type { RepetitionBlock, WorkoutStep } from \"@kaiord/core\";\nimport { mapFreeRideToKrd } from \"../interval/free-ride.mapper\";\nimport { mapIntervalsTToKrd } from \"../interval/intervals-t.mapper\";\nimport {\n mapCooldownToKrd,\n mapRampToKrd,\n mapWarmupToKrd,\n} from \"../interval/ramp.mapper\";\nimport { mapSteadyStateToKrd } from \"../interval/steady-state.mapper\";\n\ntype IntervalData = { type: string; data: Record<string, unknown> };\ntype ProcessResult = {\n step: WorkoutStep | RepetitionBlock;\n indexIncrement: number;\n};\n\nconst normalizeAttributeNames = (\n data: Record<string, unknown>\n): Record<string, unknown> => {\n const normalized: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(data)) {\n // Remove @_ prefix from attribute names\n const normalizedKey = key.startsWith(\"@_\") ? key.substring(2) : key;\n normalized[normalizedKey] = value;\n }\n return normalized;\n};\n\nconst processSingleStep = (\n interval: IntervalData,\n stepIndex: number,\n durationType: \"time\" | \"distance\"\n): ProcessResult => {\n const normalizedData = normalizeAttributeNames(interval.data);\n const data = { ...normalizedData, stepIndex, durationType };\n\n if (interval.type === \"SteadyState\") {\n return { step: mapSteadyStateToKrd(data), indexIncrement: 1 };\n } else if (interval.type === \"Warmup\") {\n return { step: mapWarmupToKrd(data), indexIncrement: 1 };\n } else if (interval.type === \"Ramp\") {\n return { step: mapRampToKrd(data), indexIncrement: 1 };\n } else if (interval.type === \"Cooldown\") {\n return { step: mapCooldownToKrd(data), indexIncrement: 1 };\n } else if (interval.type === \"FreeRide\") {\n return { step: mapFreeRideToKrd(data), indexIncrement: 1 };\n }\n\n throw new Error(`Unknown interval type: ${interval.type}`);\n};\n\nconst processInterval = (\n interval: IntervalData,\n stepIndex: number,\n durationType: \"time\" | \"distance\"\n): ProcessResult => {\n if (interval.type === \"IntervalsT\") {\n const normalizedData = normalizeAttributeNames(interval.data);\n const repetitionBlock = mapIntervalsTToKrd({\n ...normalizedData,\n stepIndex,\n durationType,\n } as Parameters<typeof mapIntervalsTToKrd>[0]);\n return {\n step: repetitionBlock,\n indexIncrement: repetitionBlock.steps.length,\n };\n }\n\n return processSingleStep(interval, stepIndex, durationType);\n};\n\nexport const processIntervals = (\n intervals: Array<IntervalData>,\n durationType: \"time\" | \"distance\"\n): Array<WorkoutStep | RepetitionBlock> => {\n const steps: Array<WorkoutStep | RepetitionBlock> = [];\n let stepIndex = 0;\n\n for (const interval of intervals) {\n const result = processInterval(interval, stepIndex, durationType);\n steps.push(result.step);\n stepIndex += result.indexIncrement;\n }\n\n return steps;\n};\n","import type { KRDMetadata } from \"@kaiord/core\";\n\ntype ZwiftWorkoutFile = {\n sportType?: string;\n \"@_kaiord:timeCreated\"?: string;\n \"@_kaiord:manufacturer\"?: string;\n \"@_kaiord:product\"?: string;\n \"@_kaiord:serialNumber\"?: string;\n \"@_kaiord:fitType\"?: string;\n \"@_kaiord:hrmFitProductId\"?: number;\n};\n\nexport const extractMetadata = (\n workoutFile: ZwiftWorkoutFile,\n sport: string\n): KRDMetadata => ({\n created: workoutFile[\"@_kaiord:timeCreated\"] || new Date().toISOString(),\n sport,\n manufacturer: workoutFile[\"@_kaiord:manufacturer\"],\n product: workoutFile[\"@_kaiord:product\"],\n serialNumber: workoutFile[\"@_kaiord:serialNumber\"],\n});\n\nexport const extractFitExtensions = (\n workoutFile: ZwiftWorkoutFile\n): Record<string, unknown> | undefined => {\n if (\n workoutFile[\"@_kaiord:fitType\"] ||\n workoutFile[\"@_kaiord:hrmFitProductId\"]\n ) {\n return {\n type: workoutFile[\"@_kaiord:fitType\"],\n hrm_fit_single_byte_product_id: workoutFile[\"@_kaiord:hrmFitProductId\"],\n };\n }\n return undefined;\n};\n","import type { KRD } from \"@kaiord/core\";\nimport type { Logger } from \"@kaiord/core\";\nimport {\n extractIntervals,\n extractTags,\n} from \"./zwift-to-krd/intervals-extractor\";\nimport { processIntervals } from \"./zwift-to-krd/intervals-processor\";\nimport {\n extractFitExtensions,\n extractMetadata,\n} from \"./zwift-to-krd/metadata-extractor\";\n\ntype ZwiftWorkoutFile = {\n author?: string;\n name?: string;\n description?: string;\n sportType?: string;\n durationType?: string;\n thresholdSecPerKm?: number;\n tags?: { tag?: Array<{ \"@_name\": string }> | { \"@_name\": string } };\n workout?: {\n SteadyState?: unknown;\n Warmup?: unknown;\n Ramp?: unknown;\n Cooldown?: unknown;\n IntervalsT?: unknown;\n FreeRide?: unknown;\n };\n // Kaiord round-trip attributes\n \"@_kaiord:timeCreated\"?: string;\n \"@_kaiord:manufacturer\"?: string;\n \"@_kaiord:product\"?: string;\n \"@_kaiord:serialNumber\"?: string;\n \"@_kaiord:fitType\"?: string;\n \"@_kaiord:hrmFitProductId\"?: number;\n};\n\nexport const convertZwiftToKRD = (zwiftData: unknown, logger: Logger): KRD => {\n logger.debug(\"Converting Zwift to KRD\");\n\n const workoutFile = (zwiftData as { workout_file: unknown })\n .workout_file as ZwiftWorkoutFile;\n\n const sport =\n workoutFile.sportType === \"bike\"\n ? \"cycling\"\n : workoutFile.sportType === \"run\"\n ? \"running\"\n : \"generic\";\n\n const durationType: \"time\" | \"distance\" =\n workoutFile.durationType === \"distance\" ? \"distance\" : \"time\";\n\n const intervals = extractIntervals(workoutFile.workout);\n const steps = processIntervals(intervals, durationType);\n\n const metadata = extractMetadata(workoutFile, sport);\n const fitExtensions = extractFitExtensions(workoutFile);\n\n const extensions: Record<string, unknown> = {\n structured_workout: {\n name: workoutFile.name,\n sport,\n steps,\n },\n zwift: {\n author: workoutFile.author,\n description: workoutFile.description,\n durationType,\n thresholdSecPerKm: workoutFile.thresholdSecPerKm,\n tags: extractTags(workoutFile.tags),\n },\n };\n\n if (fitExtensions) {\n extensions.fit = fitExtensions;\n }\n\n return {\n version: \"1.0\",\n type: \"structured_workout\",\n metadata,\n extensions,\n };\n};\n","import { XMLParser } from \"fast-xml-parser\";\nimport type { KRD, Logger, TextReader, TextWriter } from \"@kaiord/core\";\nimport { createZwiftParsingError } from \"@kaiord/core\";\nimport type { ZwiftValidator } from \"../types\";\nimport { convertKRDToZwift } from \"./krd-to-zwift.converter\";\nimport {\n validateGeneratedZwiftXml,\n validateInputZwiftXml,\n validateZwiftStructure,\n} from \"./xml-validator-helpers\";\nimport { convertZwiftToKRD } from \"./zwift-to-krd.converter\";\n\nconst parseZwiftXml = (xmlString: string, logger: Logger): unknown => {\n logger.debug(\"Parsing Zwift file\");\n\n try {\n const parser = new XMLParser({\n ignoreAttributes: false,\n attributeNamePrefix: \"@_\",\n parseAttributeValue: true,\n });\n\n return parser.parse(xmlString);\n } catch (error) {\n logger.error(\"Failed to parse Zwift XML\", { error });\n throw createZwiftParsingError(\"Failed to parse Zwift file\", error);\n }\n};\n\nexport const createFastXmlZwiftReader =\n (logger: Logger, validator: ZwiftValidator): TextReader =>\n async (xmlString: string): Promise<KRD> => {\n await validateInputZwiftXml(xmlString, validator, logger);\n const zwiftData = parseZwiftXml(xmlString, logger);\n validateZwiftStructure(zwiftData, logger);\n\n logger.info(\"Zwift file parsed successfully\");\n return convertZwiftToKRD(zwiftData, logger);\n };\n\nexport const createFastXmlZwiftWriter =\n (logger: Logger, validator: ZwiftValidator): TextWriter =>\n async (krd: KRD): Promise<string> => {\n logger.debug(\"Converting KRD to Zwift format\");\n\n let xmlString: string;\n try {\n xmlString = convertKRDToZwift(krd, logger);\n } catch (error) {\n logger.error(\"Failed to convert KRD to Zwift\", { error });\n throw createZwiftParsingError(\"Failed to convert KRD to Zwift\", error);\n }\n\n await validateGeneratedZwiftXml(xmlString, validator, logger);\n\n logger.info(\"KRD to Zwift conversion successful\");\n return xmlString;\n };\n","import { XMLValidator } from \"fast-xml-parser\";\nimport type { Logger } from \"@kaiord/core\";\nimport type { ZwiftValidationResult } from \"../types\";\n\nexport const validateXmlWellFormedness = (\n xmlString: string,\n logger: Logger\n): ZwiftValidationResult | null => {\n const xmlValidation = XMLValidator.validate(xmlString, {\n allowBooleanAttributes: true,\n });\n\n if (xmlValidation !== true) {\n logger.warn(\"Zwift XML well-formedness validation failed\", {\n error: xmlValidation.err,\n });\n\n return {\n valid: false,\n errors: [\n {\n field: `line ${xmlValidation.err.line}`,\n message: `XML validation failed: ${xmlValidation.err.msg}`,\n },\n ],\n };\n }\n\n return null;\n};\n","import type { Logger } from \"@kaiord/core\";\nimport type { ZwiftValidationResult, ZwiftValidator } from \"../types\";\nimport { validateXmlWellFormedness } from \"./xml-well-formedness-validator\";\n\n/**\n * Creates a Zwift validator that only validates XML well-formedness.\n * This is suitable for browser environments where XSD validation is not available.\n *\n * Well-formedness validation catches 95% of XML issues:\n * - Proper XML declaration\n * - Balanced opening/closing tags\n * - Valid attribute syntax\n * - Proper character encoding\n *\n * @param logger - Logger instance for diagnostic messages\n * @returns ZwiftValidator function that validates XML structure\n */\nexport const createWellFormednessValidator =\n (logger: Logger): ZwiftValidator =>\n async (xmlString: string): Promise<ZwiftValidationResult> => {\n try {\n logger.debug(\"Validating Zwift XML well-formedness (browser mode)\");\n\n const wellFormednessError = validateXmlWellFormedness(xmlString, logger);\n if (wellFormednessError) {\n return wellFormednessError;\n }\n\n logger.info(\n \"Zwift XML validated successfully (well-formedness only, XSD validation skipped in browser)\"\n );\n return { valid: true, errors: [] };\n } catch (error) {\n logger.error(\"Zwift well-formedness validation failed\", { error });\n\n return {\n valid: false,\n errors: [\n {\n field: \"root\",\n message: error instanceof Error ? error.message : \"Unknown error\",\n },\n ],\n };\n }\n };\n","import type { Logger } from \"@kaiord/core\";\nimport type { ZwiftValidator } from \"../types\";\nimport { createWellFormednessValidator } from \"./well-formedness-validator\";\n\n/**\n * Creates a Zwift validator for browser environments.\n * Only performs XML well-formedness validation (XSD validation not available in browsers).\n *\n * @param logger - Logger instance for diagnostic messages\n * @returns ZwiftValidator function\n */\nexport const createZwiftValidator = (logger: Logger): ZwiftValidator => {\n logger.info(\n \"Browser environment detected, using well-formedness validation for Zwift XML (XSD validation not available)\"\n );\n return createWellFormednessValidator(logger);\n};\n","/**\n * Browser-specific entry point for @kaiord/zwo\n * Uses well-formedness validation only (no Node.js XSD validation)\n */\n\nimport type { Logger, TextReader, TextWriter } from \"@kaiord/core\";\nimport { createConsoleLogger } from \"@kaiord/core\";\nimport {\n createFastXmlZwiftReader,\n createFastXmlZwiftWriter,\n} from \"./adapters/fast-xml-parser\";\nimport { createZwiftValidator } from \"./adapters/xsd-validator-browser\";\n\nexport const createZwiftReader = (logger?: Logger): TextReader => {\n const log = logger || createConsoleLogger();\n const validator = createZwiftValidator(log);\n return createFastXmlZwiftReader(log, validator);\n};\n\nexport const createZwiftWriter = (logger?: Logger): TextWriter => {\n const log = logger || createConsoleLogger();\n const validator = createZwiftValidator(log);\n return createFastXmlZwiftWriter(log, validator);\n};\n\nexport const zwiftReader: TextReader = createZwiftReader();\nexport const zwiftWriter: TextWriter = createZwiftWriter();\n\nexport { createFastXmlZwiftReader, createFastXmlZwiftWriter };\nexport { createZwiftValidator };\nexport type {\n ZwiftValidator,\n ZwiftValidationResult,\n ZwiftValidationError,\n} from \"./types\";\n"]}
1
+ {"version":3,"sources":["../src/adapters/krd-to-zwift/text-events-encoder.ts","../src/adapters/krd-to-zwift/intervals-t-encoder.ts","../src/adapters/krd-to-zwift/duration-encoder.ts","../src/adapters/krd-to-zwift/metadata-encoder.ts","../src/adapters/target/power.converter.ts","../src/adapters/target/pace-cadence.converter.ts","../src/adapters/krd-to-zwift/power-encoder.ts","../src/adapters/krd-to-zwift/target-encoder.ts","../src/adapters/krd-to-zwift/step-encoder.ts","../src/adapters/interval/interval-type-detector.ts","../src/adapters/krd-to-zwift/intervals-encoder.ts","../src/adapters/krd-to-zwift/metadata-builder.ts","../src/adapters/krd-to-zwift/workout-properties.ts","../src/adapters/krd-to-zwift/workout-file-builder.ts","../src/adapters/krd-to-zwift.converter.ts","../src/adapters/xml-validator-helpers.ts","../src/adapters/zwift-to-krd/intervals-extractor.ts","../src/adapters/duration/duration.mapper.ts","../src/adapters/interval/intervals-t-helpers.ts","../src/adapters/interval/intervals-t.mapper.ts","../src/adapters/interval/hr-target-restoration.ts","../src/adapters/interval/target-restoration.ts","../src/adapters/interval/ramp-helpers.ts","../src/adapters/interval/ramp.mapper.ts","../src/adapters/interval/steady-state.mapper.ts","../src/adapters/interval/index.ts","../src/adapters/interval/free-ride.mapper.ts","../src/adapters/zwift-to-krd/intervals-processor.ts","../src/adapters/zwift-to-krd/metadata-extractor.ts","../src/adapters/zwift-to-krd.converter.ts","../src/adapters/fast-xml-parser.ts","../src/adapters/xml-well-formedness-validator.ts","../src/adapters/well-formedness-validator.ts","../src/adapters/xsd-validator-browser.ts","../src/browser.ts"],"names":["targetTypeSchema","createZwiftParsingError","intensitySchema","convertZwiftPowerRange"],"mappings":"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","file":"browser.js","sourcesContent":["import type { WorkoutStep } from \"@kaiord/core\";\n\nexport const encodeTextEvents = (\n step: WorkoutStep\n): Array<Record<string, unknown>> | Record<string, unknown> | undefined => {\n const stepExtensions = step.extensions?.zwift as\n | Record<string, unknown>\n | undefined;\n const textEvents = stepExtensions?.textEvents as\n | Array<Record<string, unknown>>\n | undefined;\n\n if (!textEvents || textEvents.length === 0) {\n return undefined;\n }\n\n if (textEvents.length === 1) {\n const event = textEvents[0];\n const encoded: Record<string, unknown> = {\n \"@_message\": event.message,\n };\n\n if (event.timeoffset !== undefined) {\n encoded[\"@_timeoffset\"] = event.timeoffset;\n }\n if (event.distoffset !== undefined) {\n encoded[\"@_distoffset\"] = event.distoffset;\n }\n\n return encoded;\n }\n\n return textEvents.map((event) => {\n const encoded: Record<string, unknown> = {\n \"@_message\": event.message,\n };\n\n if (event.timeoffset !== undefined) {\n encoded[\"@_timeoffset\"] = event.timeoffset;\n }\n if (event.distoffset !== undefined) {\n encoded[\"@_distoffset\"] = event.distoffset;\n }\n\n return encoded;\n });\n};\n","import { encodeTextEvents } from \"./text-events-encoder\";\nimport type { RepetitionBlock, WorkoutStep } from \"@kaiord/core\";\n\nconst encodeDurations = (\n onStep: WorkoutStep,\n offStep: WorkoutStep,\n intervalsT: Record<string, unknown>\n): void => {\n if (onStep.duration.type === \"time\") {\n intervalsT[\"@_OnDuration\"] = onStep.duration.seconds;\n } else if (onStep.duration.type === \"distance\") {\n intervalsT[\"@_OnDuration\"] = onStep.duration.meters;\n }\n\n if (offStep.duration.type === \"time\") {\n intervalsT[\"@_OffDuration\"] = offStep.duration.seconds;\n } else if (offStep.duration.type === \"distance\") {\n intervalsT[\"@_OffDuration\"] = offStep.duration.meters;\n }\n};\n\nconst encodePowerTargets = (\n onStep: WorkoutStep,\n offStep: WorkoutStep,\n intervalsT: Record<string, unknown>\n): void => {\n if (\n onStep.target.type === \"power\" &&\n onStep.target.value.unit === \"percent_ftp\"\n ) {\n intervalsT[\"@_OnPower\"] = onStep.target.value.value / 100;\n }\n if (\n offStep.target.type === \"power\" &&\n offStep.target.value.unit === \"percent_ftp\"\n ) {\n intervalsT[\"@_OffPower\"] = offStep.target.value.value / 100;\n }\n};\n\nconst encodeCadenceTargets = (\n onStep: WorkoutStep,\n offStep: WorkoutStep,\n intervalsT: Record<string, unknown>\n): void => {\n if (onStep.target.type === \"cadence\" && onStep.target.value.unit === \"rpm\") {\n intervalsT[\"@_Cadence\"] = onStep.target.value.value;\n } else {\n const onStepExtensions = onStep.extensions?.zwift as\n | Record<string, unknown>\n | undefined;\n const cadence = onStepExtensions?.cadence as number | undefined;\n if (cadence !== undefined) {\n intervalsT[\"@_Cadence\"] = cadence;\n }\n }\n\n if (\n offStep.target.type === \"cadence\" &&\n offStep.target.value.unit === \"rpm\"\n ) {\n intervalsT[\"@_CadenceResting\"] = offStep.target.value.value;\n } else {\n const offStepExtensions = offStep.extensions?.zwift as\n | Record<string, unknown>\n | undefined;\n const cadenceResting = offStepExtensions?.cadence as number | undefined;\n if (cadenceResting !== undefined) {\n intervalsT[\"@_CadenceResting\"] = cadenceResting;\n }\n }\n};\n\nexport const encodeIntervalsT = (\n repetitionBlock: RepetitionBlock\n): Record<string, unknown> => {\n const onStep = repetitionBlock.steps[0];\n const offStep = repetitionBlock.steps[1];\n\n const intervalsT: Record<string, unknown> = {\n \"@_Repeat\": repetitionBlock.repeatCount,\n };\n\n encodeDurations(onStep, offStep, intervalsT);\n encodePowerTargets(onStep, offStep, intervalsT);\n encodeCadenceTargets(onStep, offStep, intervalsT);\n\n const textEvents = encodeTextEvents(onStep);\n if (textEvents) {\n intervalsT.textevent = textEvents;\n }\n\n return intervalsT;\n};\n","import type { WorkoutStep } from \"@kaiord/core\";\nimport type { Logger } from \"@kaiord/core\";\n\nexport const encodeDuration = (\n step: WorkoutStep,\n interval: Record<string, unknown>,\n logger?: Logger\n): void => {\n if (step.duration.type === \"time\") {\n interval[\"@_Duration\"] = step.duration.seconds;\n } else if (step.duration.type === \"distance\") {\n interval[\"@_Duration\"] = step.duration.meters;\n interval[\"@_kaiord:originalDurationType\"] = \"distance\";\n interval[\"@_kaiord:originalDurationMeters\"] = step.duration.meters;\n\n logger?.warn(\"Lossy conversion: distance duration converted to time\", {\n originalMeters: step.duration.meters,\n convertedSeconds: step.duration.meters,\n stepIndex: step.stepIndex,\n });\n } else if (step.duration.type === \"open\") {\n interval[\"@_Duration\"] = 0;\n } else {\n interval[\"@_Duration\"] = 300;\n interval[\"@_kaiord:originalDurationType\"] = step.duration.type;\n\n if (\"bpm\" in step.duration) {\n interval[\"@_kaiord:originalDurationBpm\"] = step.duration.bpm;\n } else if (\"watts\" in step.duration) {\n interval[\"@_kaiord:originalDurationWatts\"] = step.duration.watts;\n }\n\n logger?.warn(\"Lossy conversion: unsupported duration type\", {\n originalType: step.duration.type,\n fallbackSeconds: 300,\n stepIndex: step.stepIndex,\n });\n }\n};\n","import type { WorkoutStep } from \"@kaiord/core\";\nimport type { Logger } from \"@kaiord/core\";\n\nconst encodeHrRange = (\n step: WorkoutStep,\n interval: Record<string, unknown>,\n logger?: Logger\n): void => {\n if (step.target.type === \"heart_rate\" && step.target.value.unit === \"range\") {\n interval[\"@_kaiord:hrTargetLow\"] = step.target.value.min;\n interval[\"@_kaiord:hrTargetHigh\"] = step.target.value.max;\n logger?.warn(\"Lossy conversion: heart rate target not supported by Zwift\", {\n hrRange: { low: step.target.value.min, high: step.target.value.max },\n stepIndex: step.stepIndex,\n });\n }\n};\n\nconst encodeHrBpm = (\n step: WorkoutStep,\n interval: Record<string, unknown>,\n logger?: Logger\n): void => {\n if (step.target.type === \"heart_rate\" && step.target.value.unit === \"bpm\") {\n interval[\"@_kaiord:hrTargetBpm\"] = step.target.value.value;\n logger?.warn(\"Lossy conversion: heart rate target not supported by Zwift\", {\n hrBpm: step.target.value.value,\n stepIndex: step.stepIndex,\n });\n }\n};\n\nconst encodeHrZone = (\n step: WorkoutStep,\n interval: Record<string, unknown>,\n logger?: Logger\n): void => {\n if (step.target.type === \"heart_rate\" && step.target.value.unit === \"zone\") {\n interval[\"@_kaiord:hrTargetZone\"] = step.target.value.value;\n logger?.warn(\"Lossy conversion: heart rate target not supported by Zwift\", {\n hrZone: step.target.value.value,\n stepIndex: step.stepIndex,\n });\n }\n};\n\nconst encodeHrPercentMax = (\n step: WorkoutStep,\n interval: Record<string, unknown>,\n logger?: Logger\n): void => {\n if (\n step.target.type === \"heart_rate\" &&\n step.target.value.unit === \"percent_max\"\n ) {\n interval[\"@_kaiord:hrTargetPercentMax\"] = step.target.value.value;\n logger?.warn(\"Lossy conversion: heart rate target not supported by Zwift\", {\n hrPercentMax: step.target.value.value,\n stepIndex: step.stepIndex,\n });\n }\n};\n\nexport const encodeHeartRateTarget = (\n step: WorkoutStep,\n interval: Record<string, unknown>,\n logger?: Logger\n): void => {\n encodeHrRange(step, interval, logger);\n encodeHrBpm(step, interval, logger);\n encodeHrZone(step, interval, logger);\n encodeHrPercentMax(step, interval, logger);\n};\n\nexport const encodeMetadata = (\n step: WorkoutStep,\n interval: Record<string, unknown>\n): void => {\n if (step.name) {\n interval[\"@_kaiord:name\"] = step.name;\n }\n if (step.intensity) {\n interval[\"@_kaiord:intensity\"] = step.intensity;\n }\n if (step.equipment) {\n interval[\"@_kaiord:equipment\"] = step.equipment;\n }\n};\n","import { targetTypeSchema, type Target } from \"@kaiord/core\";\n\n/**\n * Convert Zwift power target (FTP percentage 0.0-3.0) to KRD power target\n * Zwift uses FTP percentage (e.g., 0.85 = 85% FTP)\n * KRD uses percent_ftp (e.g., 85 = 85% FTP)\n */\nexport const convertZwiftPowerTarget = (ftpPercentage: number): Target => {\n return {\n type: targetTypeSchema.enum.power,\n value: {\n unit: \"percent_ftp\",\n value: ftpPercentage * 100,\n },\n };\n};\n\n/**\n * Convert Zwift power range (PowerLow/PowerHigh) to KRD range target\n */\nexport const convertZwiftPowerRange = (\n powerLow: number,\n powerHigh: number\n): Target => {\n return {\n type: targetTypeSchema.enum.power,\n value: {\n unit: \"range\",\n min: powerLow * 100,\n max: powerHigh * 100,\n },\n };\n};\n\n/**\n * Convert KRD power target to Zwift FTP percentage\n * KRD uses percent_ftp (e.g., 85 = 85% FTP)\n * Zwift uses FTP percentage (e.g., 0.85 = 85% FTP)\n */\nexport const convertKrdPowerToZwift = (percentFtp: number): number => {\n return percentFtp / 100;\n};\n\n/**\n * Convert KRD power range to Zwift PowerLow/PowerHigh\n * Returns [PowerLow, PowerHigh] tuple\n */\nexport const convertKrdPowerRangeToZwift = (\n min: number,\n max: number\n): [number, number] => {\n return [min / 100, max / 100];\n};\n\n/**\n * Convert power zone (1-7) to percent FTP\n * Uses typical power zone definitions:\n * Zone 1 (Recovery): 55% FTP\n * Zone 2 (Endurance): 75% FTP\n * Zone 3 (Tempo): 90% FTP\n * Zone 4 (Threshold): 105% FTP\n * Zone 5 (VO2 Max): 120% FTP\n * Zone 6 (Anaerobic): 150% FTP\n * Zone 7 (Neuromuscular): 200% FTP\n */\nexport const convertPowerZoneToPercentFtp = (zone: number): number => {\n const zoneMap: Record<number, number> = {\n 1: 55,\n 2: 75,\n 3: 90,\n 4: 105,\n 5: 120,\n 6: 150,\n 7: 200,\n };\n\n return zoneMap[zone] || 100;\n};\n","import { targetTypeSchema, type Target } from \"@kaiord/core\";\n\n/**\n * Convert Zwift pace target (seconds per kilometer) to KRD pace target (meters per second)\n * Formula: m/s = 1000 / sec_per_km\n */\nexport const convertZwiftPaceTarget = (secPerKm: number): Target => {\n return {\n type: targetTypeSchema.enum.pace,\n value: {\n unit: \"mps\",\n value: 1000 / secPerKm,\n },\n };\n};\n\n/**\n * Convert Zwift cadence target to KRD cadence target.\n *\n * Cycling: RPM stays as RPM (crank revolutions per minute)\n * Running: SPM (steps per minute) is converted to RPM.\n *\n * Running cadence conversion rationale:\n * - Zwift and most running apps use SPM (steps per minute)\n * - KRD standardizes on RPM (revolutions/strides per minute)\n * - One stride (revolution) = two steps (left + right foot)\n * - Therefore: RPM = SPM / 2\n *\n * Example: 180 SPM = 90 RPM (90 full strides per minute)\n */\nexport const convertZwiftCadenceTarget = (\n cadence: number,\n isRunning = false\n): Target => {\n // Convert SPM to RPM for running (SPM = 2 * RPM, so RPM = SPM / 2)\n const rpm = isRunning ? cadence / 2 : cadence;\n\n return {\n type: targetTypeSchema.enum.cadence,\n value: {\n unit: \"rpm\",\n value: rpm,\n },\n };\n};\n\n/**\n * Convert KRD pace target to Zwift pace (seconds per kilometer)\n * KRD uses meters per second (m/s)\n * Zwift uses seconds per kilometer (sec/km)\n * Formula: sec/km = 1000 / m/s\n */\nexport const convertKrdPaceToZwift = (metersPerSecond: number): number => {\n return 1000 / metersPerSecond;\n};\n\n/**\n * Convert KRD cadence target to Zwift cadence.\n *\n * KRD uses RPM (revolutions/strides per minute) for all sports.\n * Zwift uses RPM for cycling, SPM (steps per minute) for running.\n *\n * Running conversion: SPM = RPM * 2\n * (One stride = two steps, so multiply RPM by 2 to get SPM)\n *\n * Example: 90 RPM = 180 SPM\n */\nexport const convertKrdCadenceToZwift = (\n rpm: number,\n isRunning = false\n): number => {\n // Convert RPM to SPM for running (SPM = 2 * RPM)\n return isRunning ? rpm * 2 : rpm;\n};\n","import { convertPowerZoneToPercentFtp } from \"../target/target.converter\";\nimport type { Logger, WorkoutStep } from \"@kaiord/core\";\n\nexport const encodeSteadyStatePowerTarget = (\n step: WorkoutStep,\n interval: Record<string, unknown>\n): void => {\n if (step.target.type !== \"power\") return;\n\n if (step.target.value.unit === \"percent_ftp\") {\n interval[\"@_kaiord:powerUnit\"] = \"percent_ftp\";\n interval[\"@_Power\"] = step.target.value.value / 100;\n } else if (step.target.value.unit === \"zone\") {\n interval[\"@_kaiord:powerUnit\"] = \"zone\";\n interval[\"@_kaiord:powerZone\"] = step.target.value.value;\n\n const percentFtp = convertPowerZoneToPercentFtp(step.target.value.value);\n interval[\"@_Power\"] = percentFtp / 100;\n } else if (step.target.value.unit === \"watts\") {\n interval[\"@_kaiord:powerUnit\"] = \"watts\";\n interval[\"@_kaiord:originalWatts\"] = step.target.value.value;\n\n const assumedFtp = 250;\n interval[\"@_kaiord:assumedFtp\"] = assumedFtp;\n const percentFtp = (step.target.value.value / assumedFtp) * 100;\n interval[\"@_Power\"] = percentFtp / 100;\n }\n};\n\nexport const encodeRampPowerTarget = (\n step: WorkoutStep,\n interval: Record<string, unknown>,\n logger?: Logger\n): void => {\n if (step.target.type !== \"power\") return;\n\n if (step.target.value.unit === \"range\") {\n let powerLow = step.target.value.min;\n let powerHigh = step.target.value.max;\n\n interval[\"@_kaiord:powerUnit\"] = \"watts\";\n\n const assumedFtp = 250;\n const originalLow = powerLow;\n const originalHigh = powerHigh;\n powerLow = (powerLow / assumedFtp) * 100;\n powerHigh = (powerHigh / assumedFtp) * 100;\n\n interval[\"@_kaiord:originalWattsLow\"] = originalLow;\n interval[\"@_kaiord:originalWattsHigh\"] = originalHigh;\n interval[\"@_kaiord:assumedFtp\"] = assumedFtp;\n\n logger?.warn(\"Lossy conversion: watts converted to percent FTP\", {\n originalWatts: { low: originalLow, high: originalHigh },\n assumedFtp,\n convertedPercentFtp: { low: powerLow, high: powerHigh },\n stepIndex: step.stepIndex,\n });\n\n interval[\"@_PowerLow\"] = powerLow / 100;\n interval[\"@_PowerHigh\"] = powerHigh / 100;\n } else if (step.target.value.unit === \"zone\") {\n interval[\"@_kaiord:powerUnit\"] = \"zone\";\n interval[\"@_kaiord:powerZone\"] = step.target.value.value;\n\n const percentFtp = convertPowerZoneToPercentFtp(step.target.value.value);\n interval[\"@_PowerLow\"] = percentFtp / 100;\n interval[\"@_PowerHigh\"] = percentFtp / 100;\n } else if (step.target.value.unit === \"percent_ftp\") {\n interval[\"@_kaiord:powerUnit\"] = \"percent_ftp\";\n\n interval[\"@_PowerLow\"] = step.target.value.value / 100;\n interval[\"@_PowerHigh\"] = step.target.value.value / 100;\n }\n};\n","import {\n encodeRampPowerTarget,\n encodeSteadyStatePowerTarget,\n} from \"./power-encoder\";\nimport type { Logger, WorkoutStep } from \"@kaiord/core\";\n\nexport const encodeSteadyStateTargets = (\n step: WorkoutStep,\n interval: Record<string, unknown>\n): void => {\n encodeSteadyStatePowerTarget(step, interval);\n\n if (step.target.type === \"pace\" && step.target.value.unit === \"mps\") {\n interval[\"@_pace\"] = 1000 / step.target.value.value;\n }\n};\n\nexport const encodeRampTargets = (\n step: WorkoutStep,\n interval: Record<string, unknown>,\n logger?: Logger\n): void => {\n encodeRampPowerTarget(step, interval, logger);\n\n if (step.target.type === \"pace\" && step.target.value.unit === \"range\") {\n interval[\"@_paceLow\"] = 1000 / step.target.value.max;\n interval[\"@_paceHigh\"] = 1000 / step.target.value.min;\n }\n};\n\nexport const encodeFreeRideTargets = (\n step: WorkoutStep,\n interval: Record<string, unknown>\n): void => {\n const stepExtensions = step.extensions?.zwift as\n | Record<string, unknown>\n | undefined;\n const flatRoad = (stepExtensions?.flatRoad || stepExtensions?.FlatRoad) as\n | number\n | undefined;\n if (flatRoad !== undefined) {\n interval[\"@_FlatRoad\"] = flatRoad;\n }\n};\n\nexport const encodeTargets = (\n step: WorkoutStep,\n intervalType: string,\n interval: Record<string, unknown>,\n logger?: Logger\n): void => {\n if (intervalType === \"SteadyState\") {\n encodeSteadyStateTargets(step, interval);\n } else if (\n intervalType === \"Warmup\" ||\n intervalType === \"Ramp\" ||\n intervalType === \"Cooldown\"\n ) {\n encodeRampTargets(step, interval, logger);\n } else if (intervalType === \"FreeRide\") {\n encodeFreeRideTargets(step, interval);\n }\n};\n\nexport const encodeCadence = (\n step: WorkoutStep,\n interval: Record<string, unknown>\n): void => {\n if (step.target.type === \"cadence\" && step.target.value.unit === \"rpm\") {\n interval[\"@_Cadence\"] = step.target.value.value;\n }\n};\n","import { encodeDuration } from \"./duration-encoder\";\nimport { encodeHeartRateTarget, encodeMetadata } from \"./metadata-encoder\";\nimport { encodeCadence, encodeTargets } from \"./target-encoder\";\nimport { encodeTextEvents } from \"./text-events-encoder\";\nimport type { Logger, WorkoutStep } from \"@kaiord/core\";\n\nexport const convertStepToInterval = (\n step: WorkoutStep,\n intervalType: string,\n logger?: Logger\n): Record<string, unknown> => {\n const interval: Record<string, unknown> = {};\n\n encodeDuration(step, interval, logger);\n encodeTargets(step, intervalType, interval, logger);\n encodeCadence(step, interval);\n encodeHeartRateTarget(step, interval, logger);\n encodeMetadata(step, interval);\n\n const textEvents = encodeTextEvents(step);\n if (textEvents) {\n interval.textevent = textEvents;\n }\n\n return interval;\n};\n","import { intensitySchema } from \"@kaiord/core\";\nimport { targetTypeSchema } from \"@kaiord/core\";\nimport { targetUnitSchema } from \"@kaiord/core\";\nimport type { WorkoutStep } from \"@kaiord/core\";\n\nexport type ZwiftIntervalType =\n | \"SteadyState\"\n | \"Warmup\"\n | \"Ramp\"\n | \"Cooldown\"\n | \"FreeRide\";\n\n/**\n * Determine Zwift interval type from KRD workout step\n *\n * Rules:\n * - SteadyState: constant power target (percent_ftp or watts)\n * - Warmup: range target with intensity \"warmup\"\n * - Cooldown: range target with intensity \"cooldown\"\n * - Ramp: range target with intensity \"active\"\n * - FreeRide: open target\n */\nexport const detectIntervalType = (step: WorkoutStep): ZwiftIntervalType => {\n // FreeRide: open target\n if (step.target.type === targetTypeSchema.enum.open) {\n return \"FreeRide\";\n }\n\n // Power targets\n if (step.target.type === targetTypeSchema.enum.power) {\n const powerValue = step.target.value;\n\n // Range targets: Warmup, Ramp, or Cooldown based on intensity\n if (powerValue.unit === targetUnitSchema.enum.range) {\n if (step.intensity === intensitySchema.enum.warmup) {\n return \"Warmup\";\n }\n if (step.intensity === intensitySchema.enum.cooldown) {\n return \"Cooldown\";\n }\n // Default to Ramp for active or unspecified intensity\n return \"Ramp\";\n }\n\n // Constant power targets: SteadyState\n if (\n powerValue.unit === targetUnitSchema.enum.percent_ftp ||\n powerValue.unit === targetUnitSchema.enum.watts\n ) {\n return \"SteadyState\";\n }\n }\n\n // Default to SteadyState for other target types\n return \"SteadyState\";\n};\n","import { encodeIntervalsT } from \"./intervals-t-encoder\";\nimport { convertStepToInterval } from \"./step-encoder\";\nimport { detectIntervalType } from \"../interval/interval-type-detector\";\nimport type { Logger, RepetitionBlock, WorkoutStep } from \"@kaiord/core\";\n\nexport const convertStepsToZwiftIntervals = (\n steps: Array<WorkoutStep | RepetitionBlock>,\n logger?: Logger\n): Record<string, unknown> => {\n const intervals: Record<string, Array<Record<string, unknown>>> = {};\n\n for (const step of steps) {\n if (\"repeatCount\" in step) {\n const repetitionBlock = step as RepetitionBlock;\n if (repetitionBlock.steps.length === 2) {\n const intervalsT = encodeIntervalsT(repetitionBlock);\n\n if (!intervals.IntervalsT) {\n intervals.IntervalsT = [];\n }\n intervals.IntervalsT.push(intervalsT);\n }\n } else {\n const workoutStep = step as WorkoutStep;\n const intervalType = detectIntervalType(workoutStep);\n const interval = convertStepToInterval(workoutStep, intervalType, logger);\n\n if (!intervals[intervalType]) {\n intervals[intervalType] = [];\n }\n intervals[intervalType].push(interval);\n }\n }\n\n return intervals;\n};\n","import type { KRDMetadata } from \"@kaiord/core\";\n\ntype FitExtensions = Record<string, unknown>;\n\nexport const addKrdMetadata = (\n workoutFile: Record<string, unknown>,\n metadata: KRDMetadata,\n fitExtensions?: FitExtensions\n): void => {\n if (metadata.created) {\n workoutFile[\"@_kaiord:timeCreated\"] = metadata.created;\n }\n if (metadata.manufacturer) {\n workoutFile[\"@_kaiord:manufacturer\"] = metadata.manufacturer;\n }\n if (metadata.product) {\n workoutFile[\"@_kaiord:product\"] = metadata.product;\n }\n if (metadata.serialNumber) {\n workoutFile[\"@_kaiord:serialNumber\"] = metadata.serialNumber;\n }\n\n if (fitExtensions) {\n if (fitExtensions.type) {\n workoutFile[\"@_kaiord:fitType\"] = fitExtensions.type;\n }\n if (fitExtensions.hrm_fit_single_byte_product_id) {\n workoutFile[\"@_kaiord:hrmFitProductId\"] =\n fitExtensions.hrm_fit_single_byte_product_id;\n }\n }\n};\n","type ZwiftExtensions = Record<string, unknown>;\n\nexport const addWorkoutProperties = (\n workoutFile: Record<string, unknown>,\n workoutName: string | undefined,\n zwiftExtensions: ZwiftExtensions\n): void => {\n if (zwiftExtensions.author) {\n workoutFile.author = zwiftExtensions.author;\n }\n if (workoutName) {\n workoutFile.name = workoutName;\n }\n if (zwiftExtensions.description) {\n workoutFile.description = zwiftExtensions.description;\n }\n if (zwiftExtensions.thresholdSecPerKm !== undefined) {\n workoutFile.thresholdSecPerKm = zwiftExtensions.thresholdSecPerKm;\n }\n\n const tags = zwiftExtensions.tags as Array<string> | undefined;\n if (tags && tags.length > 0) {\n workoutFile.tags = {\n tag: tags.map((name) => ({ \"@_name\": name })).filter((t) => t[\"@_name\"]),\n };\n }\n};\n\nexport const mapSportType = (sport?: string): string => {\n return sport === \"cycling\" ? \"bike\" : sport === \"running\" ? \"run\" : \"bike\";\n};\n","import { convertStepsToZwiftIntervals } from \"./intervals-encoder\";\nimport { addKrdMetadata } from \"./metadata-builder\";\nimport { addWorkoutProperties, mapSportType } from \"./workout-properties\";\nimport type {\n KRDMetadata,\n Logger,\n RepetitionBlock,\n WorkoutStep,\n} from \"@kaiord/core\";\n\ntype WorkoutData = {\n name?: string;\n sport?: string;\n steps?: Array<WorkoutStep | RepetitionBlock>;\n};\n\ntype ZwiftExtensions = Record<string, unknown>;\ntype FitExtensions = Record<string, unknown>;\n\nexport const buildWorkoutFile = (\n workoutData: WorkoutData,\n zwiftExtensions: ZwiftExtensions,\n metadata: KRDMetadata,\n fitExtensions?: FitExtensions,\n logger?: Logger\n): Record<string, unknown> => {\n const workoutFile: Record<string, unknown> = {};\n\n // Add author and name first (XSD requires this order)\n addWorkoutProperties(workoutFile, workoutData.name, zwiftExtensions);\n // Then sportType\n workoutFile.sportType = mapSportType(workoutData.sport);\n\n const intervals = convertStepsToZwiftIntervals(\n workoutData.steps || [],\n logger\n );\n workoutFile.workout = intervals;\n\n addKrdMetadata(workoutFile, metadata, fitExtensions);\n\n return workoutFile;\n};\n","import { createZwiftParsingError } from \"@kaiord/core\";\nimport { XMLBuilder } from \"fast-xml-parser\";\nimport { buildWorkoutFile } from \"./krd-to-zwift/workout-file-builder\";\nimport type { KRD, Logger, RepetitionBlock, WorkoutStep } from \"@kaiord/core\";\n\nconst extractWorkoutData = (krd: KRD) => {\n const workout = krd.extensions?.structured_workout;\n if (!workout || typeof workout !== \"object\") {\n throw createZwiftParsingError(\"KRD missing workout in extensions\");\n }\n\n return workout as {\n name?: string;\n sport?: string;\n steps?: Array<WorkoutStep | RepetitionBlock>;\n };\n};\n\nconst buildXmlString = (workoutFile: Record<string, unknown>): string => {\n const builder = new XMLBuilder({\n ignoreAttributes: false,\n attributeNamePrefix: \"@_\",\n format: true,\n indentBy: \" \",\n });\n\n // Add kaiord namespace for round-trip data preservation\n const workoutFileWithNamespace = {\n \"@_xmlns:kaiord\": \"http://kaiord.dev/zwift-extensions/1.0\",\n ...workoutFile,\n };\n\n const xmlObj = {\n \"?xml\": {\n \"@_version\": \"1.0\",\n \"@_encoding\": \"UTF-8\",\n },\n workout_file: workoutFileWithNamespace,\n };\n\n return builder.build(xmlObj) as string;\n};\n\nexport const convertKRDToZwift = (krd: KRD, logger: Logger): string => {\n logger.debug(\"Building Zwift workout structure from KRD\");\n\n const workoutData = extractWorkoutData(krd);\n const zwiftExtensions = (krd.extensions?.zwift || {}) as Record<\n string,\n unknown\n >;\n\n const workoutFile = buildWorkoutFile(\n workoutData,\n zwiftExtensions,\n krd.metadata,\n krd.extensions?.fit as Record<string, unknown> | undefined,\n logger\n );\n const xmlString = buildXmlString(workoutFile);\n\n logger.debug(\"Zwift XML structure built successfully\");\n return xmlString;\n};\n","import {\n createZwiftParsingError,\n createZwiftValidationError,\n} from \"@kaiord/core\";\nimport type { ZwiftValidator } from \"../types\";\nimport type { Logger } from \"@kaiord/core\";\n\nexport const validateInputZwiftXml = async (\n xmlString: string,\n validator: ZwiftValidator,\n logger: Logger\n): Promise<void> => {\n logger.debug(\"Validating Zwift file against XSD\", {\n xmlLength: xmlString.length,\n });\n\n const validationResult = await validator(xmlString);\n if (!validationResult.valid) {\n logger.error(\"Zwift file does not conform to XSD schema\", {\n errors: validationResult.errors,\n });\n throw createZwiftValidationError(\n \"Zwift file does not conform to XSD schema\",\n validationResult.errors\n );\n }\n};\n\nexport const validateGeneratedZwiftXml = async (\n xmlString: string,\n validator: ZwiftValidator,\n logger: Logger\n): Promise<void> => {\n logger.debug(\"Validating generated Zwift XML against XSD\", {\n xmlLength: xmlString.length,\n });\n\n const validationResult = await validator(xmlString);\n if (!validationResult.valid) {\n logger.error(\"Generated Zwift XML does not conform to XSD schema\", {\n errors: validationResult.errors,\n });\n throw createZwiftValidationError(\n \"Generated Zwift XML does not conform to XSD schema\",\n validationResult.errors\n );\n }\n};\n\nexport const validateZwiftStructure = (\n zwiftData: unknown,\n logger: Logger\n): void => {\n if (\n !zwiftData ||\n typeof zwiftData !== \"object\" ||\n !(\"workout_file\" in zwiftData)\n ) {\n const error = createZwiftParsingError(\n \"Invalid Zwift format: missing workout_file element\"\n );\n logger.error(\"Invalid Zwift structure\", { error });\n throw error;\n }\n};\n","type ZwiftWorkout = {\n SteadyState?: unknown;\n Warmup?: unknown;\n Ramp?: unknown;\n Cooldown?: unknown;\n IntervalsT?: unknown;\n FreeRide?: unknown;\n};\n\nexport const extractIntervals = (\n workout: ZwiftWorkout | undefined\n): Array<{ type: string; data: Record<string, unknown> }> => {\n if (!workout) return [];\n\n const intervals: Array<{ type: string; data: Record<string, unknown> }> = [];\n const intervalTypes = [\n \"SteadyState\",\n \"Warmup\",\n \"Ramp\",\n \"Cooldown\",\n \"IntervalsT\",\n \"FreeRide\",\n ];\n\n for (const type of intervalTypes) {\n const data = workout[type as keyof typeof workout];\n if (data) {\n if (Array.isArray(data)) {\n for (const item of data) {\n intervals.push({ type, data: item as Record<string, unknown> });\n }\n } else {\n intervals.push({ type, data: data as Record<string, unknown> });\n }\n }\n }\n\n return intervals;\n};\n\nexport const extractTags = (\n tags: { tag?: Array<{ \"@_name\": string }> | { \"@_name\": string } } | undefined\n): Array<string> => {\n if (!tags || !tags.tag) return [];\n\n const tagArray = Array.isArray(tags.tag) ? tags.tag : [tags.tag];\n return tagArray.map((t) => t[\"@_name\"]);\n};\n","import { durationTypeSchema, type Duration } from \"@kaiord/core\";\n\nexport type ZwiftDurationData = {\n Duration?: number;\n durationType?: \"time\" | \"distance\";\n // Kaiord round-trip attributes\n \"kaiord:originalDurationType\"?: string;\n \"kaiord:originalDurationMeters\"?: number;\n \"kaiord:originalDurationBpm\"?: number;\n \"kaiord:originalDurationWatts\"?: number;\n};\n\nexport const mapZwiftDuration = (data: ZwiftDurationData): Duration => {\n // Restore original duration type if available\n if (data[\"kaiord:originalDurationType\"] === \"distance\") {\n return {\n type: durationTypeSchema.enum.distance,\n meters: data[\"kaiord:originalDurationMeters\"] || data.Duration || 0,\n };\n }\n\n if (data[\"kaiord:originalDurationType\"] === \"heart_rate_less_than\") {\n return {\n type: durationTypeSchema.enum.heart_rate_less_than,\n bpm: data[\"kaiord:originalDurationBpm\"] || 0,\n };\n }\n\n if (data[\"kaiord:originalDurationType\"] === \"power_less_than\") {\n return {\n type: durationTypeSchema.enum.power_less_than,\n watts: data[\"kaiord:originalDurationWatts\"] || 0,\n };\n }\n\n // Standard Zwift duration handling\n if (data.Duration === undefined || data.Duration <= 0) {\n return { type: durationTypeSchema.enum.open };\n }\n\n if (data.durationType === \"distance\") {\n return {\n type: durationTypeSchema.enum.distance,\n meters: data.Duration,\n };\n }\n\n return {\n type: durationTypeSchema.enum.time,\n seconds: data.Duration,\n };\n};\n\n// KRD → Zwift mappers\nexport const mapKrdTimeDurationToZwift = (seconds: number): number => {\n return seconds;\n};\n\nexport const mapKrdDistanceDurationToZwift = (meters: number): number => {\n return meters;\n};\n","import { intensitySchema, targetTypeSchema } from \"@kaiord/core\";\nimport { mapZwiftDuration } from \"../duration/duration.mapper\";\nimport {\n convertZwiftCadenceTarget,\n convertZwiftPowerTarget,\n} from \"../target/target.converter\";\nimport { extractTextEvents } from \"./index\";\nimport type { ZwiftTextEvent } from \"./index\";\nimport type { ZwiftDurationData } from \"../duration/duration.mapper\";\nimport type { Target, WorkoutStep } from \"@kaiord/core\";\n\nexport type ZwiftIntervalsTData = {\n Repeat: number;\n OnDuration?: number;\n OnPower?: number;\n OffDuration?: number;\n OffPower?: number;\n Cadence?: number;\n CadenceResting?: number;\n durationType?: \"time\" | \"distance\";\n stepIndex: number;\n textevent?: ZwiftTextEvent | Array<ZwiftTextEvent>;\n};\n\nexport const createOnStep = (data: ZwiftIntervalsTData): WorkoutStep => {\n const onDurationData: ZwiftDurationData = {\n Duration: data.OnDuration,\n durationType: data.durationType,\n };\n const onDuration = mapZwiftDuration(onDurationData);\n\n let onTarget: Target;\n if (data.OnPower !== undefined) {\n onTarget = convertZwiftPowerTarget(data.OnPower);\n } else if (data.Cadence !== undefined) {\n onTarget = convertZwiftCadenceTarget(data.Cadence);\n } else {\n onTarget = { type: targetTypeSchema.enum.open };\n }\n\n const textEventData = extractTextEvents(data.textevent);\n\n const onStep: WorkoutStep = {\n stepIndex: data.stepIndex,\n durationType: onDuration.type,\n duration: onDuration,\n targetType: onTarget.type,\n target: onTarget,\n intensity: intensitySchema.enum.active,\n ...textEventData,\n };\n\n if (data.OnPower !== undefined && data.Cadence !== undefined) {\n onStep.extensions = {\n zwift: {\n cadence: data.Cadence,\n },\n };\n }\n\n return onStep;\n};\n\nexport const createOffStep = (data: ZwiftIntervalsTData): WorkoutStep => {\n const offDurationData: ZwiftDurationData = {\n Duration: data.OffDuration,\n durationType: data.durationType,\n };\n const offDuration = mapZwiftDuration(offDurationData);\n\n let offTarget: Target;\n if (data.OffPower !== undefined) {\n offTarget = convertZwiftPowerTarget(data.OffPower);\n } else if (data.CadenceResting !== undefined) {\n offTarget = convertZwiftCadenceTarget(data.CadenceResting);\n } else {\n offTarget = { type: targetTypeSchema.enum.open };\n }\n\n const offStep: WorkoutStep = {\n stepIndex: data.stepIndex + 1,\n durationType: offDuration.type,\n duration: offDuration,\n targetType: offTarget.type,\n target: offTarget,\n intensity: intensitySchema.enum.recovery,\n };\n\n if (data.OffPower !== undefined && data.CadenceResting !== undefined) {\n offStep.extensions = {\n zwift: {\n cadence: data.CadenceResting,\n },\n };\n }\n\n return offStep;\n};\n","import { createOffStep, createOnStep } from \"./intervals-t-helpers\";\nimport type { ZwiftIntervalsTData } from \"./intervals-t-helpers\";\nimport type { RepetitionBlock } from \"@kaiord/core\";\n\nexport type { ZwiftIntervalsTData };\n\n/**\n * Map Zwift IntervalsT to KRD repetition block with 2 steps (on/off)\n * IntervalsT represents repeated intervals with distinct \"on\" and \"off\" phases\n */\nexport const mapIntervalsTToKrd = (\n data: ZwiftIntervalsTData\n): RepetitionBlock => {\n return {\n repeatCount: data.Repeat,\n steps: [createOnStep(data), createOffStep(data)],\n };\n};\n","import { targetTypeSchema, type Target } from \"@kaiord/core\";\n\ntype KaiordHrAttributes = {\n \"kaiord:hrTargetLow\"?: number;\n \"kaiord:hrTargetHigh\"?: number;\n \"kaiord:hrTargetBpm\"?: number;\n \"kaiord:hrTargetZone\"?: number;\n \"kaiord:hrTargetPercentMax\"?: number;\n};\n\nconst restoreHrRange = (data: KaiordHrAttributes): Target | null => {\n if (\n data[\"kaiord:hrTargetLow\"] !== undefined &&\n data[\"kaiord:hrTargetHigh\"] !== undefined\n ) {\n return {\n type: targetTypeSchema.enum.heart_rate,\n value: {\n unit: \"range\",\n min: data[\"kaiord:hrTargetLow\"],\n max: data[\"kaiord:hrTargetHigh\"],\n },\n };\n }\n return null;\n};\n\nconst restoreHrBpm = (data: KaiordHrAttributes): Target | null => {\n if (data[\"kaiord:hrTargetBpm\"] !== undefined) {\n return {\n type: targetTypeSchema.enum.heart_rate,\n value: {\n unit: \"bpm\",\n value: data[\"kaiord:hrTargetBpm\"],\n },\n };\n }\n return null;\n};\n\nconst restoreHrZone = (data: KaiordHrAttributes): Target | null => {\n if (data[\"kaiord:hrTargetZone\"] !== undefined) {\n return {\n type: targetTypeSchema.enum.heart_rate,\n value: {\n unit: \"zone\",\n value: data[\"kaiord:hrTargetZone\"],\n },\n };\n }\n return null;\n};\n\nconst restoreHrPercentMax = (data: KaiordHrAttributes): Target | null => {\n if (data[\"kaiord:hrTargetPercentMax\"] !== undefined) {\n return {\n type: targetTypeSchema.enum.heart_rate,\n value: {\n unit: \"percent_max\",\n value: data[\"kaiord:hrTargetPercentMax\"],\n },\n };\n }\n return null;\n};\n\nexport const restoreHeartRateTarget = (\n data: KaiordHrAttributes\n): Target | null => {\n return (\n restoreHrRange(data) ||\n restoreHrBpm(data) ||\n restoreHrZone(data) ||\n restoreHrPercentMax(data) ||\n null\n );\n};\n","import { targetTypeSchema, type Target } from \"@kaiord/core\";\n\ntype KaiordTargetAttributes = {\n \"kaiord:powerUnit\"?: \"watts\" | \"percent_ftp\" | \"zone\";\n \"kaiord:originalWattsLow\"?: number;\n \"kaiord:originalWattsHigh\"?: number;\n \"kaiord:powerZone\"?: number;\n \"kaiord:hrTargetLow\"?: number;\n \"kaiord:hrTargetHigh\"?: number;\n \"kaiord:hrTargetBpm\"?: number;\n \"kaiord:hrTargetZone\"?: number;\n \"kaiord:hrTargetPercentMax\"?: number;\n};\n\nconst restoreWattsTarget = (data: KaiordTargetAttributes): Target | null => {\n if (\n data[\"kaiord:powerUnit\"] === \"watts\" &&\n data[\"kaiord:originalWattsLow\"] !== undefined &&\n data[\"kaiord:originalWattsHigh\"] !== undefined\n ) {\n return {\n type: targetTypeSchema.enum.power,\n value: {\n unit: \"range\",\n min: data[\"kaiord:originalWattsLow\"],\n max: data[\"kaiord:originalWattsHigh\"],\n },\n };\n }\n return null;\n};\n\nconst restoreZoneTarget = (data: KaiordTargetAttributes): Target | null => {\n if (\n data[\"kaiord:powerUnit\"] === \"zone\" &&\n data[\"kaiord:powerZone\"] !== undefined\n ) {\n return {\n type: targetTypeSchema.enum.power,\n value: {\n unit: \"zone\",\n value: data[\"kaiord:powerZone\"],\n },\n };\n }\n return null;\n};\n\nexport const restorePowerTarget = (\n data: KaiordTargetAttributes,\n powerLow?: number,\n powerHigh?: number,\n convertZwiftPowerRange?: (low: number, high: number) => Target\n): Target | null => {\n const wattsTarget = restoreWattsTarget(data);\n if (wattsTarget) return wattsTarget;\n\n const zoneTarget = restoreZoneTarget(data);\n if (zoneTarget) return zoneTarget;\n\n if (\n powerLow !== undefined &&\n powerHigh !== undefined &&\n convertZwiftPowerRange\n ) {\n return convertZwiftPowerRange(powerLow, powerHigh);\n }\n\n return null;\n};\n\nexport { restoreHeartRateTarget } from \"./hr-target-restoration\";\n","import { targetTypeSchema } from \"@kaiord/core\";\nimport {\n restoreHeartRateTarget,\n restorePowerTarget,\n} from \"./target-restoration\";\nimport { convertZwiftPowerRange } from \"../target/target.converter\";\nimport type { ZwiftDurationData } from \"../duration/duration.mapper\";\nimport type { Intensity, Target, WorkoutStep } from \"@kaiord/core\";\n\nexport type ZwiftRampData = {\n Duration?: number;\n durationType?: \"time\" | \"distance\";\n PowerLow?: number;\n PowerHigh?: number;\n Cadence?: number;\n stepIndex: number;\n textevent?: unknown;\n \"kaiord:name\"?: string;\n \"kaiord:intensity\"?: string;\n \"kaiord:equipment\"?: string;\n \"kaiord:originalDurationType\"?: string;\n \"kaiord:originalDurationMeters\"?: number;\n \"kaiord:originalDurationBpm\"?: number;\n \"kaiord:originalDurationWatts\"?: number;\n \"kaiord:originalWattsLow\"?: number;\n \"kaiord:originalWattsHigh\"?: number;\n \"kaiord:assumedFtp\"?: number;\n \"kaiord:hrTargetLow\"?: number;\n \"kaiord:hrTargetHigh\"?: number;\n \"kaiord:hrTargetBpm\"?: number;\n \"kaiord:hrTargetZone\"?: number;\n \"kaiord:hrTargetPercentMax\"?: number;\n \"kaiord:powerUnit\"?: \"watts\" | \"percent_ftp\" | \"zone\";\n \"kaiord:powerZone\"?: number;\n};\n\nexport const buildRampDurationData = (\n data: ZwiftRampData\n): ZwiftDurationData => ({\n Duration: data.Duration,\n durationType: data.durationType,\n \"kaiord:originalDurationType\": data[\"kaiord:originalDurationType\"],\n \"kaiord:originalDurationMeters\": data[\"kaiord:originalDurationMeters\"],\n \"kaiord:originalDurationBpm\": data[\"kaiord:originalDurationBpm\"],\n \"kaiord:originalDurationWatts\": data[\"kaiord:originalDurationWatts\"],\n});\n\nexport const resolveRampTarget = (data: ZwiftRampData): Target => {\n const powerTarget = restorePowerTarget(\n data,\n data.PowerLow,\n data.PowerHigh,\n convertZwiftPowerRange\n );\n const hrTarget = restoreHeartRateTarget(data);\n return powerTarget || hrTarget || { type: targetTypeSchema.enum.open };\n};\n\nexport const resolveIntensity = (\n data: ZwiftRampData,\n defaultIntensity: Intensity\n): Intensity => {\n return (\n (data[\"kaiord:intensity\"] as Intensity | undefined) || defaultIntensity\n );\n};\n\nexport const addRampMetadata = (\n step: WorkoutStep,\n data: ZwiftRampData\n): void => {\n if (data[\"kaiord:name\"]) step.name = data[\"kaiord:name\"];\n if (data[\"kaiord:equipment\"]) {\n step.equipment = data[\"kaiord:equipment\"] as WorkoutStep[\"equipment\"];\n }\n};\n","import { intensitySchema } from \"@kaiord/core\";\nimport {\n addRampMetadata,\n buildRampDurationData,\n resolveIntensity,\n resolveRampTarget,\n} from \"./ramp-helpers\";\nimport { mapZwiftDuration } from \"../duration/duration.mapper\";\nimport { extractTextEvents } from \"./index\";\nimport type { ZwiftTextEvent } from \"./index\";\nimport type { ZwiftRampData } from \"./ramp-helpers\";\nimport type { Intensity, WorkoutStep } from \"@kaiord/core\";\n\nexport type { ZwiftRampData };\n\n/**\n * Map Zwift Warmup interval to KRD step\n * Warmup intervals ramp from low to high power with \"warmup\" intensity\n */\nexport const mapWarmupToKrd = (data: ZwiftRampData): WorkoutStep => {\n return mapRampToKrd(data, intensitySchema.enum.warmup);\n};\n\n/**\n * Map Zwift Ramp interval to KRD step\n * Ramp intervals progress between two power values with \"active\" intensity\n */\nexport const mapRampToKrd = (\n data: ZwiftRampData,\n intensity: Intensity = intensitySchema.enum.active\n): WorkoutStep => {\n const duration = mapZwiftDuration(buildRampDurationData(data));\n const target = resolveRampTarget(data);\n const textEventData = extractTextEvents(\n data.textevent as ZwiftTextEvent | Array<ZwiftTextEvent> | undefined\n );\n\n const step: WorkoutStep = {\n stepIndex: data.stepIndex,\n durationType: duration.type,\n duration,\n targetType: target.type,\n target,\n intensity: resolveIntensity(data, intensity),\n ...textEventData,\n };\n\n addRampMetadata(step, data);\n return step;\n};\n\n/**\n * Map Zwift Cooldown interval to KRD step\n * Cooldown intervals ramp from high to low power with \"cooldown\" intensity\n */\nexport const mapCooldownToKrd = (data: ZwiftRampData): WorkoutStep => {\n return mapRampToKrd(data, intensitySchema.enum.cooldown);\n};\n","import { intensitySchema, targetTypeSchema } from \"@kaiord/core\";\nimport { restoreHeartRateTarget } from \"./target-restoration\";\nimport { mapZwiftDuration } from \"../duration/duration.mapper\";\nimport { convertZwiftPowerTarget } from \"../target/target.converter\";\nimport { extractTextEvents } from \"./index\";\nimport type { ZwiftTextEvent } from \"./index\";\nimport type { ZwiftDurationData } from \"../duration/duration.mapper\";\nimport type { Target, WorkoutStep } from \"@kaiord/core\";\n\nexport type ZwiftSteadyStateData = {\n Duration?: number;\n durationType?: \"time\" | \"distance\";\n Power?: number;\n Cadence?: number;\n stepIndex: number;\n textevent?: ZwiftTextEvent | Array<ZwiftTextEvent>;\n // Kaiord round-trip attributes\n \"kaiord:name\"?: string;\n \"kaiord:intensity\"?: string;\n \"kaiord:equipment\"?: string;\n \"kaiord:originalDurationType\"?: string;\n \"kaiord:originalDurationMeters\"?: number;\n \"kaiord:originalDurationBpm\"?: number;\n \"kaiord:originalDurationWatts\"?: number;\n \"kaiord:hrTargetLow\"?: number;\n \"kaiord:hrTargetHigh\"?: number;\n \"kaiord:hrTargetBpm\"?: number;\n \"kaiord:hrTargetZone\"?: number;\n \"kaiord:hrTargetPercentMax\"?: number;\n \"kaiord:powerUnit\"?: \"watts\" | \"percent_ftp\" | \"zone\";\n \"kaiord:originalWatts\"?: number;\n \"kaiord:powerZone\"?: number;\n \"kaiord:assumedFtp\"?: number;\n};\n\nconst restoreSteadyStateTarget = (data: ZwiftSteadyStateData): Target => {\n if (data[\"kaiord:powerUnit\"] === \"watts\" && data[\"kaiord:originalWatts\"]) {\n return {\n type: targetTypeSchema.enum.power,\n value: {\n unit: \"watts\",\n value: data[\"kaiord:originalWatts\"],\n },\n };\n }\n\n if (data[\"kaiord:powerUnit\"] === \"zone\" && data[\"kaiord:powerZone\"]) {\n return {\n type: targetTypeSchema.enum.power,\n value: {\n unit: \"zone\",\n value: data[\"kaiord:powerZone\"],\n },\n };\n }\n\n if (data.Power !== undefined) {\n return convertZwiftPowerTarget(data.Power);\n }\n\n const hrTarget = restoreHeartRateTarget(data);\n return hrTarget || { type: targetTypeSchema.enum.open };\n};\n\nexport const mapSteadyStateToKrd = (\n data: ZwiftSteadyStateData\n): WorkoutStep => {\n const durationData: ZwiftDurationData = {\n Duration: data.Duration,\n durationType: data.durationType,\n \"kaiord:originalDurationType\": data[\"kaiord:originalDurationType\"],\n \"kaiord:originalDurationMeters\": data[\"kaiord:originalDurationMeters\"],\n \"kaiord:originalDurationBpm\": data[\"kaiord:originalDurationBpm\"],\n \"kaiord:originalDurationWatts\": data[\"kaiord:originalDurationWatts\"],\n };\n\n const duration = mapZwiftDuration(durationData);\n const target = restoreSteadyStateTarget(data);\n const textEventData = extractTextEvents(data.textevent);\n\n const step: WorkoutStep = {\n stepIndex: data.stepIndex,\n durationType: duration.type,\n duration,\n targetType: target.type,\n target,\n intensity:\n (data[\"kaiord:intensity\"] as\n | \"warmup\"\n | \"active\"\n | \"cooldown\"\n | \"rest\"\n | undefined) || intensitySchema.enum.active,\n ...textEventData,\n };\n\n if (data[\"kaiord:name\"]) {\n step.name = data[\"kaiord:name\"];\n }\n if (data[\"kaiord:equipment\"]) {\n step.equipment = data[\"kaiord:equipment\"] as WorkoutStep[\"equipment\"];\n }\n\n return step;\n};\n","export type ZwiftTextEvent = {\n message?: string;\n timeoffset?: number;\n distoffset?: number;\n};\n\nexport const extractTextEvents = (\n textevent?: ZwiftTextEvent | Array<ZwiftTextEvent>\n): {\n notes?: string;\n extensions?: { zwift: { textEvents: Array<ZwiftTextEvent> } };\n} => {\n if (!textevent) {\n return {};\n }\n\n const events = Array.isArray(textevent) ? textevent : [textevent];\n\n if (events.length === 0) {\n return {};\n }\n\n const primaryMessage = events[0].message;\n const result: {\n notes?: string;\n extensions?: { zwift: { textEvents: Array<ZwiftTextEvent> } };\n } = {};\n\n if (primaryMessage) {\n result.notes = primaryMessage;\n }\n\n if (events.length > 0) {\n result.extensions = {\n zwift: {\n textEvents: events,\n },\n };\n }\n\n return result;\n};\n\nexport { mapFreeRideToKrd } from \"./free-ride.mapper\";\nexport { mapIntervalsTToKrd } from \"./intervals-t.mapper\";\nexport { mapCooldownToKrd, mapRampToKrd, mapWarmupToKrd } from \"./ramp.mapper\";\nexport { mapSteadyStateToKrd } from \"./steady-state.mapper\";\n","import { intensitySchema, targetTypeSchema } from \"@kaiord/core\";\nimport { mapZwiftDuration } from \"../duration/duration.mapper\";\nimport { extractTextEvents } from \"./index\";\nimport type { ZwiftTextEvent } from \"./index\";\nimport type { ZwiftDurationData } from \"../duration/duration.mapper\";\nimport type { WorkoutStep } from \"@kaiord/core\";\n\nexport type ZwiftFreeRideData = {\n Duration?: number;\n durationType?: \"time\" | \"distance\";\n Cadence?: number;\n FlatRoad?: number;\n \"@_FlatRoad\"?: number;\n stepIndex: number;\n textevent?: ZwiftTextEvent | Array<ZwiftTextEvent>;\n};\n\n/**\n * Map Zwift FreeRide interval to KRD step with open target\n * FreeRide intervals allow the user to ride at their own pace\n */\nexport const mapFreeRideToKrd = (data: ZwiftFreeRideData): WorkoutStep => {\n const durationData: ZwiftDurationData = {\n Duration: data.Duration,\n durationType: data.durationType,\n };\n\n const duration = mapZwiftDuration(durationData);\n\n const textEventData = extractTextEvents(data.textevent);\n\n const step: WorkoutStep = {\n stepIndex: data.stepIndex,\n durationType: duration.type,\n duration,\n targetType: targetTypeSchema.enum.open,\n target: { type: targetTypeSchema.enum.open },\n intensity: intensitySchema.enum.active,\n ...textEventData,\n };\n\n // Store FlatRoad attribute in extensions for round-trip preservation\n const flatRoad = data[\"@_FlatRoad\"] ?? data.FlatRoad;\n if (flatRoad !== undefined) {\n step.extensions = {\n ...step.extensions,\n zwift: {\n ...((step.extensions?.zwift as Record<string, unknown>) || {}),\n FlatRoad: flatRoad,\n },\n };\n }\n\n return step;\n};\n","import { mapFreeRideToKrd } from \"../interval/free-ride.mapper\";\nimport { mapIntervalsTToKrd } from \"../interval/intervals-t.mapper\";\nimport {\n mapCooldownToKrd,\n mapRampToKrd,\n mapWarmupToKrd,\n} from \"../interval/ramp.mapper\";\nimport { mapSteadyStateToKrd } from \"../interval/steady-state.mapper\";\nimport type { RepetitionBlock, WorkoutStep } from \"@kaiord/core\";\n\ntype IntervalData = { type: string; data: Record<string, unknown> };\ntype ProcessResult = {\n step: WorkoutStep | RepetitionBlock;\n indexIncrement: number;\n};\n\nconst normalizeAttributeNames = (\n data: Record<string, unknown>\n): Record<string, unknown> => {\n const normalized: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(data)) {\n // Remove @_ prefix from attribute names\n const normalizedKey = key.startsWith(\"@_\") ? key.substring(2) : key;\n normalized[normalizedKey] = value;\n }\n return normalized;\n};\n\nconst processSingleStep = (\n interval: IntervalData,\n stepIndex: number,\n durationType: \"time\" | \"distance\"\n): ProcessResult => {\n const normalizedData = normalizeAttributeNames(interval.data);\n const data = { ...normalizedData, stepIndex, durationType };\n\n if (interval.type === \"SteadyState\") {\n return { step: mapSteadyStateToKrd(data), indexIncrement: 1 };\n } else if (interval.type === \"Warmup\") {\n return { step: mapWarmupToKrd(data), indexIncrement: 1 };\n } else if (interval.type === \"Ramp\") {\n return { step: mapRampToKrd(data), indexIncrement: 1 };\n } else if (interval.type === \"Cooldown\") {\n return { step: mapCooldownToKrd(data), indexIncrement: 1 };\n } else if (interval.type === \"FreeRide\") {\n return { step: mapFreeRideToKrd(data), indexIncrement: 1 };\n }\n\n throw new Error(`Unknown interval type: ${interval.type}`);\n};\n\nconst processInterval = (\n interval: IntervalData,\n stepIndex: number,\n durationType: \"time\" | \"distance\"\n): ProcessResult => {\n if (interval.type === \"IntervalsT\") {\n const normalizedData = normalizeAttributeNames(interval.data);\n const repetitionBlock = mapIntervalsTToKrd({\n ...normalizedData,\n stepIndex,\n durationType,\n } as Parameters<typeof mapIntervalsTToKrd>[0]);\n return {\n step: repetitionBlock,\n indexIncrement: repetitionBlock.steps.length,\n };\n }\n\n return processSingleStep(interval, stepIndex, durationType);\n};\n\nexport const processIntervals = (\n intervals: Array<IntervalData>,\n durationType: \"time\" | \"distance\"\n): Array<WorkoutStep | RepetitionBlock> => {\n const steps: Array<WorkoutStep | RepetitionBlock> = [];\n let stepIndex = 0;\n\n for (const interval of intervals) {\n const result = processInterval(interval, stepIndex, durationType);\n steps.push(result.step);\n stepIndex += result.indexIncrement;\n }\n\n return steps;\n};\n","import type { KRDMetadata } from \"@kaiord/core\";\n\ntype ZwiftWorkoutFile = {\n sportType?: string;\n \"@_kaiord:timeCreated\"?: string;\n \"@_kaiord:manufacturer\"?: string;\n \"@_kaiord:product\"?: string;\n \"@_kaiord:serialNumber\"?: string;\n \"@_kaiord:fitType\"?: string;\n \"@_kaiord:hrmFitProductId\"?: number;\n};\n\nexport const extractMetadata = (\n workoutFile: ZwiftWorkoutFile,\n sport: string\n): KRDMetadata => ({\n created: workoutFile[\"@_kaiord:timeCreated\"] || new Date().toISOString(),\n sport,\n manufacturer: workoutFile[\"@_kaiord:manufacturer\"],\n product: workoutFile[\"@_kaiord:product\"],\n serialNumber: workoutFile[\"@_kaiord:serialNumber\"],\n});\n\nexport const extractFitExtensions = (\n workoutFile: ZwiftWorkoutFile\n): Record<string, unknown> | undefined => {\n if (\n workoutFile[\"@_kaiord:fitType\"] ||\n workoutFile[\"@_kaiord:hrmFitProductId\"]\n ) {\n return {\n type: workoutFile[\"@_kaiord:fitType\"],\n hrm_fit_single_byte_product_id: workoutFile[\"@_kaiord:hrmFitProductId\"],\n };\n }\n return undefined;\n};\n","import {\n extractIntervals,\n extractTags,\n} from \"./zwift-to-krd/intervals-extractor\";\nimport { processIntervals } from \"./zwift-to-krd/intervals-processor\";\nimport {\n extractFitExtensions,\n extractMetadata,\n} from \"./zwift-to-krd/metadata-extractor\";\nimport type { KRD, Logger } from \"@kaiord/core\";\n\ntype ZwiftWorkoutFile = {\n author?: string;\n name?: string;\n description?: string;\n sportType?: string;\n durationType?: string;\n thresholdSecPerKm?: number;\n tags?: { tag?: Array<{ \"@_name\": string }> | { \"@_name\": string } };\n workout?: {\n SteadyState?: unknown;\n Warmup?: unknown;\n Ramp?: unknown;\n Cooldown?: unknown;\n IntervalsT?: unknown;\n FreeRide?: unknown;\n };\n // Kaiord round-trip attributes\n \"@_kaiord:timeCreated\"?: string;\n \"@_kaiord:manufacturer\"?: string;\n \"@_kaiord:product\"?: string;\n \"@_kaiord:serialNumber\"?: string;\n \"@_kaiord:fitType\"?: string;\n \"@_kaiord:hrmFitProductId\"?: number;\n};\n\nexport const convertZwiftToKRD = (zwiftData: unknown, logger: Logger): KRD => {\n logger.debug(\"Converting Zwift to KRD\");\n\n const workoutFile = (zwiftData as { workout_file: unknown })\n .workout_file as ZwiftWorkoutFile;\n\n const sport =\n workoutFile.sportType === \"bike\"\n ? \"cycling\"\n : workoutFile.sportType === \"run\"\n ? \"running\"\n : \"generic\";\n\n const durationType: \"time\" | \"distance\" =\n workoutFile.durationType === \"distance\" ? \"distance\" : \"time\";\n\n const intervals = extractIntervals(workoutFile.workout);\n const steps = processIntervals(intervals, durationType);\n\n const metadata = extractMetadata(workoutFile, sport);\n const fitExtensions = extractFitExtensions(workoutFile);\n\n const extensions: Record<string, unknown> = {\n structured_workout: {\n name: workoutFile.name,\n sport,\n steps,\n },\n zwift: {\n author: workoutFile.author,\n description: workoutFile.description,\n durationType,\n thresholdSecPerKm: workoutFile.thresholdSecPerKm,\n tags: extractTags(workoutFile.tags),\n },\n };\n\n if (fitExtensions) {\n extensions.fit = fitExtensions;\n }\n\n return {\n version: \"1.0\",\n type: \"structured_workout\",\n metadata,\n extensions,\n };\n};\n","import { createZwiftParsingError } from \"@kaiord/core\";\nimport { XMLParser } from \"fast-xml-parser\";\nimport { convertKRDToZwift } from \"./krd-to-zwift.converter\";\nimport {\n validateGeneratedZwiftXml,\n validateInputZwiftXml,\n validateZwiftStructure,\n} from \"./xml-validator-helpers\";\nimport { convertZwiftToKRD } from \"./zwift-to-krd.converter\";\nimport type { ZwiftValidator } from \"../types\";\nimport type { KRD, Logger, TextReader, TextWriter } from \"@kaiord/core\";\n\nconst parseZwiftXml = (xmlString: string, logger: Logger): unknown => {\n logger.debug(\"Parsing Zwift file\");\n\n try {\n const parser = new XMLParser({\n ignoreAttributes: false,\n attributeNamePrefix: \"@_\",\n parseAttributeValue: true,\n });\n\n return parser.parse(xmlString);\n } catch (error) {\n logger.error(\"Failed to parse Zwift XML\", { error });\n throw createZwiftParsingError(\"Failed to parse Zwift file\", error);\n }\n};\n\nexport const createFastXmlZwiftReader =\n (logger: Logger, validator: ZwiftValidator): TextReader =>\n async (xmlString: string): Promise<KRD> => {\n await validateInputZwiftXml(xmlString, validator, logger);\n const zwiftData = parseZwiftXml(xmlString, logger);\n validateZwiftStructure(zwiftData, logger);\n\n logger.info(\"Zwift file parsed successfully\");\n return convertZwiftToKRD(zwiftData, logger);\n };\n\nexport const createFastXmlZwiftWriter =\n (logger: Logger, validator: ZwiftValidator): TextWriter =>\n async (krd: KRD): Promise<string> => {\n logger.debug(\"Converting KRD to Zwift format\");\n\n let xmlString: string;\n try {\n xmlString = convertKRDToZwift(krd, logger);\n } catch (error) {\n logger.error(\"Failed to convert KRD to Zwift\", { error });\n throw createZwiftParsingError(\"Failed to convert KRD to Zwift\", error);\n }\n\n await validateGeneratedZwiftXml(xmlString, validator, logger);\n\n logger.info(\"KRD to Zwift conversion successful\");\n return xmlString;\n };\n","import { XMLValidator } from \"fast-xml-parser\";\nimport type { ZwiftValidationResult } from \"../types\";\nimport type { Logger } from \"@kaiord/core\";\n\nexport const validateXmlWellFormedness = (\n xmlString: string,\n logger: Logger\n): ZwiftValidationResult | null => {\n const xmlValidation = XMLValidator.validate(xmlString, {\n allowBooleanAttributes: true,\n });\n\n if (xmlValidation !== true) {\n logger.warn(\"Zwift XML well-formedness validation failed\", {\n error: xmlValidation.err,\n });\n\n return {\n valid: false,\n errors: [\n {\n field: `line ${xmlValidation.err.line}`,\n message: `XML validation failed: ${xmlValidation.err.msg}`,\n },\n ],\n };\n }\n\n return null;\n};\n","import { validateXmlWellFormedness } from \"./xml-well-formedness-validator\";\nimport type { ZwiftValidationResult, ZwiftValidator } from \"../types\";\nimport type { Logger } from \"@kaiord/core\";\n\n/**\n * Creates a Zwift validator that only validates XML well-formedness.\n * This is suitable for browser environments where XSD validation is not available.\n *\n * Well-formedness validation catches 95% of XML issues:\n * - Proper XML declaration\n * - Balanced opening/closing tags\n * - Valid attribute syntax\n * - Proper character encoding\n *\n * @param logger - Logger instance for diagnostic messages\n * @returns ZwiftValidator function that validates XML structure\n */\nexport const createWellFormednessValidator =\n (logger: Logger): ZwiftValidator =>\n async (xmlString: string): Promise<ZwiftValidationResult> => {\n try {\n logger.debug(\"Validating Zwift XML well-formedness (browser mode)\");\n\n const wellFormednessError = validateXmlWellFormedness(xmlString, logger);\n if (wellFormednessError) {\n return wellFormednessError;\n }\n\n logger.info(\n \"Zwift XML validated successfully (well-formedness only, XSD validation skipped in browser)\"\n );\n return { valid: true, errors: [] };\n } catch (error) {\n logger.error(\"Zwift well-formedness validation failed\", { error });\n\n return {\n valid: false,\n errors: [\n {\n field: \"root\",\n message: error instanceof Error ? error.message : \"Unknown error\",\n },\n ],\n };\n }\n };\n","import { createWellFormednessValidator } from \"./well-formedness-validator\";\nimport type { ZwiftValidator } from \"../types\";\nimport type { Logger } from \"@kaiord/core\";\n\n/**\n * Creates a Zwift validator for browser environments.\n * Only performs XML well-formedness validation (XSD validation not available in browsers).\n *\n * @param logger - Logger instance for diagnostic messages\n * @returns ZwiftValidator function\n */\nexport const createZwiftValidator = (logger: Logger): ZwiftValidator => {\n logger.info(\n \"Browser environment detected, using well-formedness validation for Zwift XML (XSD validation not available)\"\n );\n return createWellFormednessValidator(logger);\n};\n","/**\n * Browser-specific entry point for @kaiord/zwo\n * Uses well-formedness validation only (no Node.js XSD validation)\n */\n\nimport { createConsoleLogger } from \"@kaiord/core\";\nimport {\n createFastXmlZwiftReader,\n createFastXmlZwiftWriter,\n} from \"./adapters/fast-xml-parser\";\nimport { createZwiftValidator } from \"./adapters/xsd-validator-browser\";\nimport type { Logger, TextReader, TextWriter } from \"@kaiord/core\";\n\nexport const createZwiftReader = (logger?: Logger): TextReader => {\n const log = logger || createConsoleLogger();\n const validator = createZwiftValidator(log);\n return createFastXmlZwiftReader(log, validator);\n};\n\nexport const createZwiftWriter = (logger?: Logger): TextWriter => {\n const log = logger || createConsoleLogger();\n const validator = createZwiftValidator(log);\n return createFastXmlZwiftWriter(log, validator);\n};\n\nexport const zwiftReader: TextReader = createZwiftReader();\nexport const zwiftWriter: TextWriter = createZwiftWriter();\n\nexport { createFastXmlZwiftReader, createFastXmlZwiftWriter };\nexport { createZwiftValidator };\nexport type {\n ZwiftValidator,\n ZwiftValidationResult,\n ZwiftValidationError,\n} from \"./types\";\n"]}
@@ -13,4 +13,4 @@ type ZwiftValidator = (xmlString: string) => Promise<ZwiftValidationResult>;
13
13
  declare const createFastXmlZwiftReader: (logger: Logger, validator: ZwiftValidator) => TextReader;
14
14
  declare const createFastXmlZwiftWriter: (logger: Logger, validator: ZwiftValidator) => TextWriter;
15
15
 
16
- export { type ZwiftValidator as Z, createFastXmlZwiftWriter as a, type ZwiftValidationResult as b, createFastXmlZwiftReader as c, type ZwiftValidationError as d };
16
+ export { type ZwiftValidator as Z, type ZwiftValidationError as a, type ZwiftValidationResult as b, createFastXmlZwiftReader as c, createFastXmlZwiftWriter as d };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
+ import { Z as ZwiftValidator } from './fast-xml-parser-otyxjhMa.js';
2
+ export { a as ZwiftValidationError, b as ZwiftValidationResult, c as createFastXmlZwiftReader, d as createFastXmlZwiftWriter } from './fast-xml-parser-otyxjhMa.js';
1
3
  import { Logger, TextReader, TextWriter } from '@kaiord/core';
2
- import { Z as ZwiftValidator } from './fast-xml-parser-YgKah3Fp.js';
3
- export { d as ZwiftValidationError, b as ZwiftValidationResult, c as createFastXmlZwiftReader, a as createFastXmlZwiftWriter } from './fast-xml-parser-YgKah3Fp.js';
4
4
 
5
5
  /**
6
6
  * Creates a Zwift validator that automatically chooses the appropriate validation strategy: