trackswap 0.0.2 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/README.md +328 -281
  2. package/dist/FIT/base.d.ts +0 -30
  3. package/dist/FIT/decoder.d.ts +0 -48
  4. package/dist/FIT/encoder.d.ts +0 -97
  5. package/dist/FIT/mesg.d.ts +0 -3
  6. package/dist/FIT/middleware.d.ts +0 -15
  7. package/dist/FIT/plugins.d.ts +0 -9
  8. package/dist/FIT/processor.d.ts +0 -24
  9. package/dist/FIT/types/mesg_num.d.ts +102 -102
  10. package/dist/FIT/types/sport.d.ts +44 -44
  11. package/dist/FIT/types.d.ts +0 -35
  12. package/dist/GPX/base.d.ts +6 -50
  13. package/dist/GPX/converters.d.ts +0 -30
  14. package/dist/GPX/decoder.d.ts +0 -66
  15. package/dist/GPX/encoder.d.ts +0 -109
  16. package/dist/GPX/middleware.d.ts +0 -9
  17. package/dist/GPX/processor.d.ts +0 -18
  18. package/dist/GPX/types.d.ts +0 -108
  19. package/dist/TCX/base.d.ts +0 -33
  20. package/dist/TCX/converters.d.ts +0 -24
  21. package/dist/TCX/decoder.d.ts +0 -54
  22. package/dist/TCX/encoder.d.ts +0 -109
  23. package/dist/TCX/index.d.ts +4 -2
  24. package/dist/TCX/middleware.d.ts +11 -13
  25. package/dist/TCX/processor.d.ts +13 -21
  26. package/dist/TCX/types.d.ts +1 -13
  27. package/dist/TrackSwap.d.ts +37 -33
  28. package/dist/core/base.d.ts +0 -46
  29. package/dist/core/xml-utils.d.ts +0 -24
  30. package/dist/index.cjs +26 -0
  31. package/dist/index.js +26 -5
  32. package/dist/sport/base.d.ts +64 -0
  33. package/dist/sport/converters.d.ts +33 -0
  34. package/dist/sport/encoders.d.ts +34 -0
  35. package/dist/sport/index.d.ts +17 -0
  36. package/dist/sport/processor.d.ts +19 -0
  37. package/dist/types.d.ts +91 -13
  38. package/package.json +23 -5
  39. package/dist/FIT/base.js +0 -101
  40. package/dist/FIT/crc.js +0 -16
  41. package/dist/FIT/decoder.js +0 -323
  42. package/dist/FIT/encoder.js +0 -445
  43. package/dist/FIT/index.js +0 -13
  44. package/dist/FIT/mesg.js +0 -208
  45. package/dist/FIT/middleware.js +0 -206
  46. package/dist/FIT/plugins.js +0 -104
  47. package/dist/FIT/processor.js +0 -170
  48. package/dist/FIT/types/course_point.js +0 -58
  49. package/dist/FIT/types/event.js +0 -50
  50. package/dist/FIT/types/event_type.js +0 -19
  51. package/dist/FIT/types/file.js +0 -24
  52. package/dist/FIT/types/index.js +0 -297
  53. package/dist/FIT/types/mesg_num.js +0 -106
  54. package/dist/FIT/types/sport.js +0 -48
  55. package/dist/FIT/types.js +0 -1
  56. package/dist/FIT/util.js +0 -7
  57. package/dist/GPX/base.js +0 -56
  58. package/dist/GPX/converters.js +0 -352
  59. package/dist/GPX/decoder.js +0 -409
  60. package/dist/GPX/encoder.js +0 -513
  61. package/dist/GPX/extensions/index.js +0 -14
  62. package/dist/GPX/index.js +0 -11
  63. package/dist/GPX/middleware.js +0 -93
  64. package/dist/GPX/processor.js +0 -188
  65. package/dist/GPX/types.js +0 -1
  66. package/dist/GPX/util.js +0 -18
  67. package/dist/TCX/base.js +0 -62
  68. package/dist/TCX/converters.js +0 -333
  69. package/dist/TCX/decoder.js +0 -350
  70. package/dist/TCX/encoder.js +0 -513
  71. package/dist/TCX/index.js +0 -9
  72. package/dist/TCX/middleware.js +0 -93
  73. package/dist/TCX/processor.js +0 -197
  74. package/dist/TCX/types.js +0 -1
  75. package/dist/TrackSwap.js +0 -84
  76. package/dist/core/base.js +0 -138
  77. package/dist/core/decoder.d.ts +0 -66
  78. package/dist/core/decoder.js +0 -90
  79. package/dist/core/index.js +0 -4
  80. package/dist/core/processor.d.ts +0 -69
  81. package/dist/core/processor.js +0 -265
  82. package/dist/core/xml-utils.js +0 -140
  83. package/dist/types.js +0 -1
@@ -1,45 +1,49 @@
1
1
  import { GPXDecoder, GPXEncoder } from "./GPX/index.js";
2
2
  import { GPX11Type } from "./GPX/types.js";
3
- /**
4
- * GPX轨迹交换处理类
5
- * 提供GPX文件的解析和编码功能
6
- */
3
+ import { FITDecoder, FITEncoder } from "./FIT/index.js";
4
+ import { FITFileType } from "./FIT/types.js";
5
+ import { TCXDecoder, TCXEncoder } from "./TCX/index.js";
6
+ import { TCXFileType } from "./TCX/types.js";
7
+ import { SportProcessor } from "./sport/processor.js";
8
+ import { SportFileType } from "./types.js";
7
9
  export declare class TrackSwap {
8
- private decoder;
9
- private encoder;
10
+ private gpxDecoder;
11
+ private gpxEncoder;
12
+ private fitDecoder;
13
+ private fitEncoder;
14
+ private tcxDecoder;
15
+ private tcxEncoder;
16
+ private sportProcessor;
10
17
  constructor();
11
- /**
12
- * 解析GPX文件Buffer为GPX对象
13
- */
14
18
  parseGPX(buffer: Buffer): Promise<GPX11Type | undefined>;
15
- /**
16
- * 解析GPX文件字符串为GPX对象
17
- */
18
19
  parseGPXString(xmlString: string): Promise<GPX11Type | undefined>;
19
- /**
20
- * 编码GPX对象为Buffer
21
- */
22
20
  encodeGPX(gpxData: GPX11Type): Promise<Buffer>;
23
- /**
24
- * 编码GPX对象为XML字符串
25
- */
26
21
  encodeGPXString(gpxData: GPX11Type): string;
27
- /**
28
- * 获取解码器实例
29
- */
30
- getDecoder(): GPXDecoder;
31
- /**
32
- * 获取编码器实例
33
- */
34
- getEncoder(): GPXEncoder;
35
- /**
36
- * 销毁实例,清理资源
37
- */
22
+ parseFIT(buffer: Buffer): Promise<FITFileType>;
23
+ encodeFIT(fitData: FITFileType): Promise<Buffer>;
24
+ encodeFITCourse(fitData: FITFileType): Promise<Buffer>;
25
+ parseTCX(buffer: Buffer): Promise<TCXFileType>;
26
+ parseTCXString(xmlString: string): Promise<TCXFileType>;
27
+ encodeTCX(tcxData: TCXFileType): Promise<Buffer>;
28
+ encodeTCXString(tcxData: TCXFileType): Promise<string>;
29
+ convertGPXToSport(gpxData: GPX11Type): Promise<SportFileType>;
30
+ convertFITToSport(fitData: FITFileType): Promise<SportFileType>;
31
+ convertTCXToSport(tcxData: TCXFileType): Promise<SportFileType>;
32
+ convertSportToGPX(sportData: SportFileType): Promise<GPX11Type>;
33
+ convertSportToFIT(sportData: SportFileType): Promise<FITFileType>;
34
+ convertSportToTCX(sportData: SportFileType): Promise<TCXFileType>;
35
+ convertFile(sourceFile: Buffer, targetType: "gpx" | "fit" | "tcx", sourceType?: "gpx" | "fit" | "tcx"): Promise<Buffer>;
36
+ detectFormat(buffer: Buffer): "gpx" | "fit" | "tcx" | "unknown";
37
+ parseFile(buffer: Buffer, sourceType?: "gpx" | "fit" | "tcx"): Promise<GPX11Type | FITFileType | TCXFileType>;
38
+ parseToSport(buffer: Buffer, sourceType?: "gpx" | "fit" | "tcx"): Promise<SportFileType>;
39
+ getSportProcessor(): SportProcessor;
40
+ getGPXDecoder(): GPXDecoder;
41
+ getGPXEncoder(): GPXEncoder;
42
+ getFITDecoder(): FITDecoder;
43
+ getFITEncoder(): FITEncoder;
44
+ getTCXDecoder(): TCXDecoder;
45
+ getTCXEncoder(): TCXEncoder;
38
46
  destroy(): Promise<void>;
39
- /**
40
- * @deprecated 使用 encodeGPX() 替代
41
- */
42
- encoderGPX(gpx: GPX11Type): Promise<Buffer>;
43
47
  }
44
48
  declare const _default: {
45
49
  TrackSwap: typeof TrackSwap;
@@ -1,76 +1,39 @@
1
1
  import { ExtensionsType, Token, TokenAST } from "../types.js";
2
- /**
3
- * 通用插件接口
4
- */
5
2
  export interface IPlugin<TContext = any> {
6
- /** 插件名称 */
7
3
  name: string;
8
- /** 插件版本 */
9
4
  version?: string;
10
- /** 插件描述 */
11
5
  description?: string;
12
- /** 依赖的其他插件 */
13
6
  dependencies?: string[];
14
- /** 支持的标签 */
15
7
  supportedTags?: string[];
16
- /** 插件初始化 */
17
8
  initialize?(context: TContext): Promise<void> | void;
18
- /** 插件销毁 */
19
9
  destroy?(context: TContext): Promise<void> | void;
20
- /** 插件验证 */
21
10
  validate?(context: TContext): Promise<boolean> | boolean;
22
11
  }
23
- /**
24
- * 通用转换器插件接口
25
- */
26
12
  export interface IConverterPlugin<TContext = any> extends IPlugin<TContext> {
27
- /** 转换方法 */
28
13
  convert(ast: TokenAST, context: TContext): any | undefined;
29
- /** 是否支持该标签 */
30
14
  supports(tag: string): boolean;
31
- /** 优先级(数字越小优先级越高) */
32
15
  priority?: number;
33
16
  }
34
- /**
35
- * 通用中间件插件接口
36
- */
37
17
  export interface IMiddlewarePlugin<TContext = any, TResult = any> extends IPlugin<TContext> {
38
- /** 优先级(数字越小优先级越高) */
39
18
  priority?: number;
40
- /** 在tokenize阶段执行 */
41
19
  onTokenize?(tokens: Token[], context: TContext): Promise<Token[]> | Token[];
42
- /** 在AST生成阶段执行 */
43
20
  onAstGenerate?(ast: TokenAST, context: TContext): Promise<TokenAST> | TokenAST;
44
- /** 在转换阶段执行 */
45
21
  onConvert?(result: any, context: TContext): Promise<any> | any;
46
- /** 在完成阶段执行 */
47
22
  onComplete?(result: TResult, context: TContext): Promise<TResult> | TResult;
48
- /** 错误处理 */
49
23
  onError?(error: Error, context: TContext): Promise<void> | void;
50
24
  }
51
- /**
52
- * 通用处理上下文
53
- */
54
25
  export interface IProcessingContext {
55
- /** 元数据存储 */
56
26
  metadata: Map<string, any>;
57
- /** 错误列表 */
58
27
  errors: Error[];
59
- /** 警告列表 */
60
28
  warnings: string[];
61
- /** 处理统计信息 */
62
29
  stats: {
63
30
  startTime: number;
64
31
  endTime?: number;
65
32
  processedTokens: number;
66
33
  convertedElements: number;
67
34
  };
68
- /** 用户自定义数据 */
69
35
  userData?: Record<string, any>;
70
36
  }
71
- /**
72
- * 通用基础转换器抽象类
73
- */
74
37
  export declare abstract class BaseConverter<TContext extends IProcessingContext = IProcessingContext> implements IConverterPlugin<TContext> {
75
38
  abstract name: string;
76
39
  abstract supportedTags: string[];
@@ -92,18 +55,9 @@ export declare abstract class BaseConverter<TContext extends IProcessingContext
92
55
  protected getChildValue(ast: TokenAST, tag: string): string | undefined;
93
56
  protected getChildByTag(ast: TokenAST, tag: string): TokenAST | undefined;
94
57
  protected getChildrenByTag(ast: TokenAST, tag: string): TokenAST[];
95
- /**
96
- * 通用的 Extensions 处理方法
97
- */
98
58
  protected convertExtensions(extensionsAST: TokenAST): ExtensionsType;
99
- /**
100
- * 递归转换 Extensions 内容
101
- */
102
59
  protected convertExtensionContent(extension: TokenAST): any;
103
60
  }
104
- /**
105
- * 通用基础中间件抽象类
106
- */
107
61
  export declare abstract class BaseMiddleware<TContext extends IProcessingContext = IProcessingContext, TResult = any> implements IMiddlewarePlugin<TContext, TResult> {
108
62
  abstract name: string;
109
63
  version: string;
@@ -1,41 +1,17 @@
1
1
  import { Token } from "../types.js";
2
- /**
3
- * XML 解析工具类
4
- */
5
2
  export declare class XMLUtils {
6
- /**
7
- * 将 XML 内容转换为 Token 数组
8
- */
9
3
  static tokenizeXML(xmlContent: string): Token[];
10
- /**
11
- * 压缩 XML 字符串(移除多余空白)
12
- */
13
4
  static compressXML(xmlContent: string): string;
14
- /**
15
- * 格式化 XML 字符串(添加缩进)
16
- */
17
5
  static formatXML(xmlContent: string, indentSize?: number): string;
18
- /**
19
- * 验证 XML 格式
20
- */
21
6
  static validateXML(xmlContent: string): {
22
7
  isValid: boolean;
23
8
  error?: string;
24
9
  };
25
- /**
26
- * 提取 XML 声明信息
27
- */
28
10
  static extractXMLDeclaration(xmlContent: string): {
29
11
  version?: string;
30
12
  encoding?: string;
31
13
  standalone?: string;
32
14
  };
33
- /**
34
- * 转义 XML 特殊字符
35
- */
36
15
  static escapeXML(text: string): string;
37
- /**
38
- * 反转义 XML 特殊字符
39
- */
40
16
  static unescapeXML(text: string): string;
41
17
  }
package/dist/index.cjs ADDED
@@ -0,0 +1,26 @@
1
+ "use strict";var Je=Object.create;var G=Object.defineProperty;var Qe=Object.getOwnPropertyDescriptor;var et=Object.getOwnPropertyNames;var tt=Object.getPrototypeOf,rt=Object.prototype.hasOwnProperty;var nt=(p,e)=>{for(var t in e)G(p,t,{get:e[t],enumerable:!0})},Oe=(p,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of et(e))!rt.call(p,i)&&i!==t&&G(p,i,{get:()=>e[i],enumerable:!(r=Qe(e,i))||r.enumerable});return p};var h=(p,e,t)=>(t=p!=null?Je(tt(p)):{},Oe(e||!p||!p.__esModule?G(t,"default",{value:p,enumerable:!0}):t,p)),it=p=>Oe(G({},"__esModule",{value:!0}),p);var ht={};nt(ht,{GPXManager:()=>He,TrackSwap:()=>O,default:()=>gt});module.exports=it(ht);var y=class{constructor(){this.version="1.0.0";this.priority=100}supports(e){return this.supportedTags.includes(e)}async initialize(e){e.metadata.set(`plugin:${this.name}:initialized`,!0)}async destroy(e){e.metadata.delete(`plugin:${this.name}:initialized`)}async validate(e){return!0}parseFloat(e){return typeof e=="number"?e:typeof e=="string"&&parseFloat(e)||0}parseInt(e){return typeof e=="number"?Math.floor(e):typeof e=="string"&&parseInt(e,10)||0}parseString(e){return String(e||"")}parseBoolean(e){return typeof e=="boolean"?e:typeof e=="string"?e.toLowerCase()==="true":!1}parseDate(e){if(!e)return;let t=new Date(e);return isNaN(t.getTime())?void 0:t}hasRequiredAttributes(e,t){return t.every(r=>{var i;return(i=e.attributes)==null?void 0:i[r]})}extractAttributes(e,t,r){e.attributes&&Object.entries(e.attributes).forEach(([i,n])=>{let o=r[i];o&&o in t&&(t[o]=String(n||""))})}processChildren(e,t,r){var i;(i=e.children)==null||i.forEach(n=>{let o=r[n.tag];o&&o(n,t)})}getChildValue(e,t){var i;let r=(i=e.children)==null?void 0:i.find(n=>n.tag===t);return r!=null&&r.value?String(r.value):void 0}getChildByTag(e,t){var r;return(r=e.children)==null?void 0:r.find(i=>i.tag===t)}getChildrenByTag(e,t){var r;return((r=e.children)==null?void 0:r.filter(i=>i.tag===t))||[]}convertExtensions(e){var r;let t={};return(r=e.children)==null||r.forEach(i=>{t[i.tag]=this.convertExtensionContent(i)}),t}convertExtensionContent(e){var t;if((t=e.children)!=null&&t.length){let r={};return e.children.forEach(i=>{r[i.tag]=this.convertExtensionContent(i)}),r}else return e.value}},C=class{constructor(){this.version="1.0.0";this.description=""}async initialize(e){}async destroy(e){}async validate(e){return!0}async onTokenize(e,t){return e}async onAstGenerate(e,t){return e}async onConvert(e,t){return e}async onComplete(e,t){return e}async onError(e,t){}};var u=class extends y{parseCoordinate(e){let t=this.parseFloat(e);return t===0?void 0:t}parseGPXTime(e){if(!e)return;let t=new Date(e);return isNaN(t.getTime())?void 0:t}extractNumericAttributes(e,t,r){e.attributes&&Object.entries(e.attributes).forEach(([i,n])=>{let o=r[i];o&&o in t&&typeof n<"u"&&(t[o]=this.parseFloat(n))})}},_=class extends C{async onError(e,t){t.warnings.push(`Middleware ${this.name} error: ${e.message}`)}};var B=class extends u{constructor(){super(...arguments);this.name="wpt-converter";this.supportedTags=["wpt","trkpt","rtept"];this.version="1.0.0"}convert(t,r){if(!this.hasRequiredAttributes(t,["lat","lon"]))return;let i={lat:this.parseFloat(t.attributes.lat),lon:this.parseFloat(t.attributes.lon)};return this.extractAttributes(t,i,{lat:"lat",lon:"lon"}),this.processChildren(t,i,{ele:(n,o)=>o.ele=this.parseFloat(n.value),time:(n,o)=>o.time=new Date(this.parseString(n.value)),speed:(n,o)=>o.speed=this.parseFloat(n.value),course:(n,o)=>o.course=this.parseFloat(n.value),name:(n,o)=>o.name=this.parseString(n.value),cmt:(n,o)=>o.cmt=this.parseString(n.value),desc:(n,o)=>o.desc=this.parseString(n.value),src:(n,o)=>o.src=this.parseString(n.value),sym:(n,o)=>o.sym=this.parseString(n.value),type:(n,o)=>o.type=this.parseString(n.value),fix:(n,o)=>o.fix=this.parseString(n.value),sat:(n,o)=>o.sat=this.parseString(n.value),hdop:(n,o)=>o.hdop=this.parseFloat(n.value),vdop:(n,o)=>o.vdop=this.parseFloat(n.value),pdop:(n,o)=>o.pdop=this.parseFloat(n.value),ageofdgpsdata:(n,o)=>o.ageofdgpsdata=this.parseFloat(n.value),geoidheight:(n,o)=>o.geoidheight=this.parseFloat(n.value),magvar:(n,o)=>o.magvar=this.parseFloat(n.value),dgpsid:(n,o)=>o.dgpsid=this.parseFloat(n.value),extensions:(n,o)=>{let s=r.metadata.get("decoder");s&&(o.extensions=s.convertExtensions(n))},link:(n,o)=>{var c;o.link||(o.link=[]);let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("link"))==null?void 0:c.convert(n,r);a&&o.link&&o.link.push(a)}}),i}},H=class extends u{constructor(){super(...arguments);this.name="rte-converter";this.supportedTags=["rte"]}convert(t,r){let i={rtept:[]};return this.processChildren(t,i,{name:(n,o)=>o.name=this.parseString(n.value),cmt:(n,o)=>o.cmt=this.parseString(n.value),desc:(n,o)=>o.desc=this.parseString(n.value),src:(n,o)=>o.src=this.parseString(n.value),number:(n,o)=>o.number=this.parseFloat(n.value),type:(n,o)=>o.type=this.parseString(n.value),rtept:(n,o)=>{var c;let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("wpt"))==null?void 0:c.convert(n,r);a&&o.rtept&&o.rtept.push(a)},extensions:(n,o)=>{let s=r.metadata.get("decoder");s&&(o.extensions=s.convertExtensions(n))},link:(n,o)=>{var a;o.link||(o.link=[]);let s=r.metadata.get("decoder");(a=n.children)==null||a.forEach(c=>{var l;let d=(l=s==null?void 0:s.getConverter("link"))==null?void 0:l.convert(c,r);d&&o.link&&o.link.push(d)})}}),i}},z=class extends u{constructor(){super(...arguments);this.name="trk-converter";this.supportedTags=["trk"]}convert(t,r){let i={trkseg:[]};return this.processChildren(t,i,{name:(n,o)=>o.name=this.parseString(n.value),cmt:(n,o)=>o.cmt=this.parseString(n.value),desc:(n,o)=>o.desc=this.parseString(n.value),src:(n,o)=>o.src=this.parseString(n.value),number:(n,o)=>o.number=this.parseFloat(n.value),type:(n,o)=>o.type=this.parseString(n.value),trkseg:(n,o)=>{var c;let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("trkseg"))==null?void 0:c.convert(n,r);a&&o.trkseg&&o.trkseg.push(a)},extensions:(n,o)=>{let s=r.metadata.get("decoder");s&&(o.extensions=s.convertExtensions(n))},link:(n,o)=>{var a;o.link||(o.link=[]);let s=r.metadata.get("decoder");(a=n.children)==null||a.forEach(c=>{var l;let d=(l=s==null?void 0:s.getConverter("link"))==null?void 0:l.convert(c,r);d&&o.link&&o.link.push(d)})}}),i}},V=class extends u{constructor(){super(...arguments);this.name="trkseg-converter";this.supportedTags=["trkseg"]}convert(t,r){let i={trkpt:[]};return this.processChildren(t,i,{trkpt:(n,o)=>{var c;let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("wpt"))==null?void 0:c.convert(n,r);a&&o.trkpt&&o.trkpt.push(a)},extensions:(n,o)=>{let s=r.metadata.get("decoder");s&&(o.extensions=s.convertExtensions(n))}}),i}},U=class extends u{constructor(){super(...arguments);this.name="link-converter";this.supportedTags=["link"]}convert(t,r){var n;let i={};return(n=t.attributes)!=null&&n.href&&(i.href=t.attributes.href),this.processChildren(t,i,{text:(o,s)=>s.text=this.parseString(o.value),type:(o,s)=>s.type=this.parseString(o.value)}),i}},W=class extends u{constructor(){super(...arguments);this.name="metadata-converter";this.supportedTags=["metadata"]}convert(t,r){let i={};return this.processChildren(t,i,{name:(n,o)=>o.name=this.parseString(n.value),desc:(n,o)=>o.desc=this.parseString(n.value),keywords:(n,o)=>o.keywords=this.parseString(n.value),time:(n,o)=>o.time=new Date(this.parseString(n.value)),author:(n,o)=>{var a;let s=r.metadata.get("decoder");o.author=(a=s==null?void 0:s.getConverter("author"))==null?void 0:a.convert(n,r)},copyright:(n,o)=>{var a;let s=r.metadata.get("decoder");o.copyright=(a=s==null?void 0:s.getConverter("copyright"))==null?void 0:a.convert(n,r)},bounds:(n,o)=>{var a;let s=r.metadata.get("decoder");o.bounds=(a=s==null?void 0:s.getConverter("bounds"))==null?void 0:a.convert(n,r)},extensions:(n,o)=>{let s=r.metadata.get("decoder");s&&(o.extensions=s.convertExtensions(n))},link:(n,o)=>{var c;o.link||(o.link=[]);let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("link"))==null?void 0:c.convert(n,r);a&&o.link&&o.link.push(a)}}),i}},j=class extends u{constructor(){super(...arguments);this.name="person-converter";this.supportedTags=["author"]}convert(t,r){var n;let i={};return t.value&&!((n=t.children)!=null&&n.length)?(i.name=this.parseString(t.value),i):(this.processChildren(t,i,{name:(o,s)=>s.name=this.parseString(o.value),email:(o,s)=>{var c;let a=r.metadata.get("decoder");s.email=(c=a==null?void 0:a.getConverter("email"))==null?void 0:c.convert(o,r)},link:(o,s)=>{var c;let a=r.metadata.get("decoder");s.link=(c=a==null?void 0:a.getConverter("link"))==null?void 0:c.convert(o,r)}}),i)}},K=class extends u{constructor(){super(...arguments);this.name="email-converter";this.supportedTags=["email"]}convert(t,r){let i={};return this.processChildren(t,i,{id:(n,o)=>o.id=this.parseString(n.value),domain:(n,o)=>o.domain=this.parseString(n.value)}),i}},Y=class extends u{constructor(){super(...arguments);this.name="copyright-converter";this.supportedTags=["copyright"]}convert(t,r){var n;let i={};return(n=t.attributes)!=null&&n.author&&(i.author=t.attributes.author),this.processChildren(t,i,{year:(o,s)=>s.year=this.parseString(o.value),license:(o,s)=>s.license=this.parseString(o.value)}),i}},Z=class extends u{constructor(){super(...arguments);this.name="bounds-converter";this.supportedTags=["bounds"]}convert(t,r){let i={};return this.extractAttributes(t,i,{minlat:"minlat",minlon:"minlon",maxlat:"maxlat",maxlon:"maxlon"}),i}};var $e=require("htmlparser2"),ee=(i=>(i.TOKENIZE="tokenize",i.AST_GENERATE="ast_generate",i.CONVERT="convert",i.COMPLETE="complete",i))(ee||{}),q=class{constructor(){this.stage="tokenize"}async process(e){let t=Date.now();if(!e.xmlContent)throw new Error("XML content cannot be empty");let r=[],i=new $e.Parser({onopentag(n,o){r.push({type:"open",tag:n,attributes:o})},ontext(n){let o=n.replace(/\n/g,"").trim();o&&r.push({type:"text",tag:"text",value:o})},onclosetag(n){r.push({type:"close",tag:n})}},{xmlMode:!0});return i.write(e.xmlContent),i.end(),e.tokens=r,e.performance.tokenizeTime=Date.now()-t,e}},N=class{constructor(){this.stage="ast_generate"}async process(e){var o;let t=Date.now();if(!e.tokens)throw new Error("Tokens cannot be empty");let r=[],i,n=null;for(let s of e.tokens)if(s.type==="open"){let a={tag:s.tag,attributes:s.attributes||{},children:[]};i?n&&((o=n.children)==null||o.push(a)):i=a,r.push(a),n=a}else s.type==="text"&&n?n.value=s.value:s.type==="close"&&(r.pop(),n=r[r.length-1]||null);return e.ast=i,e.performance.astTime=Date.now()-t,e}},J=class{constructor(e){this.getConverter=e;this.stage="convert"}async process(e){var i;let t=Date.now();if(!e.ast)throw new Error("AST cannot be empty");let r={};return e.ast.attributes&&Object.entries(e.ast.attributes).forEach(([n,o])=>{n.startsWith("xmlns:")?r[n]=o.replace(/&#39;/g,"'"):n==="xsi:schemaLocation"?r[n]=o.replace(/&#39;/g,"'"):r[n]=o}),(i=e.ast.children)==null||i.forEach(n=>{let o=this.getConverter(n.tag);try{let s=o.convert(n,e);s&&this.assignResult(r,n.tag,s)}catch(s){e.errors.push(s)}}),e.result=r,e.performance.convertTime=Date.now()-t,e}assignResult(e,t,r){switch(t){case"metadata":e.metadata=r;break;case"wpt":e.wpt||(e.wpt=[]),e.wpt.push(r);break;case"rte":e.rte||(e.rte=[]),e.rte.push(r);break;case"trk":e.trk||(e.trk=[]),e.trk.push(r);break;case"extensions":e.extensions=r;break}}},Q=class{constructor(){this.stage="complete"}async process(e){e.performance.endTime=Date.now();let t=e.performance.endTime-e.performance.startTime;return e.metadata.set("performance",{totalTime:t,tokenizeTime:e.performance.tokenizeTime,astTime:e.performance.astTime,convertTime:e.performance.convertTime}),e}};var P=class{constructor(){this.converterPlugins=new Map;this.registeredPlugins=new Set;this.middlewarePlugins=[];this.processors=[];this.initialized=!1;this.defaultConvertersRegistered=!1;this.initializePipeline()}initializePipeline(){this.processors=[new q,new N,new J(e=>this.getConverter(e)),new Q]}async registerDefaultConverters(){var t;if(this.defaultConvertersRegistered)return;let e=[new B,new H,new z,new V,new U,new W,new j,new K,new Y,new Z];for(let r of e)(t=r.supportedTags)==null||t.forEach(i=>{this.addConverterForTag(i,r)}),this.registeredPlugins.add(r.name);this.defaultConvertersRegistered=!0}addConverterForTag(e,t){this.converterPlugins.has(e)||this.converterPlugins.set(e,[]);let r=this.converterPlugins.get(e);r.push(t),r.sort((i,n)=>(i.priority||100)-(n.priority||100))}async registerConverter(e){var r,n;if(this.registeredPlugins.has(e.name))throw new Error(`Converter plugin ${e.name} already exists`);(r=e.supportedTags)==null||r.forEach(o=>{this.addConverterForTag(o,e)}),this.registeredPlugins.add(e.name);let t=e.priority!==void 0?` (priority: ${e.priority})`:"";(n=e.supportedTags)==null||n.forEach(o=>{let a=(this.converterPlugins.get(o)||[]).map(c=>`${c.name}(${c.priority||100})`)})}async registerMiddleware(e){let t=this.middlewarePlugins.findIndex(i=>i.name===e.name);t!==-1?this.middlewarePlugins[t]=e:this.middlewarePlugins.push(e);let r=[];e.onTokenize&&r.push("onTokenize"),e.onAstGenerate&&r.push("onAstGenerate"),e.onConvert&&r.push("onConvert"),e.onComplete&&r.push("onComplete"),e.onError&&r.push("onError"),r.length>0}getConverter(e){let t=this.converterPlugins.get(e);return t&&t.length>0?t[0]:void 0}getAllConverters(e){return this.converterPlugins.get(e)||[]}unregisterConverter(e){let t;for(let[r,i]of this.converterPlugins){let n=i.findIndex(o=>o.name===e);n!==-1&&(t=i[n],i.splice(n,1),i.length===0&&this.converterPlugins.delete(r))}t&&this.registeredPlugins.delete(e)}unregisterMiddleware(e){let t=this.middlewarePlugins.findIndex(r=>r.name===e);t!==-1&&this.middlewarePlugins.splice(t,1)}listConverters(){return Array.from(this.converterPlugins.keys())}listConverterPlugins(){return Array.from(this.registeredPlugins)}listMiddlewares(){return this.middlewarePlugins.map(e=>e.name)}listProcessors(){return this.processors.map(e=>e.constructor.name)}getConverterDetails(e){let t={};if(e){let r=this.converterPlugins.get(e);r&&(t[e]=r.map(i=>({name:i.name,priority:i.priority||100})))}else for(let[r,i]of this.converterPlugins)t[r]=i.map(n=>({name:n.name,priority:n.priority||100}));return t}getMiddlewareDetails(){return this.middlewarePlugins.map(e=>{let t=[];return e.onTokenize&&t.push("onTokenize"),e.onAstGenerate&&t.push("onAstGenerate"),e.onConvert&&t.push("onConvert"),e.onComplete&&t.push("onComplete"),e.onError&&t.push("onError"),{name:e.name,hooks:t}})}async initialize(){var r;if(this.initialized)return;await this.registerDefaultConverters();let e=this.createContext(),t=[...Array.from(this.converterPlugins.values()).flat(),...this.middlewarePlugins];for(let i of t)try{await((r=i.initialize)==null?void 0:r.call(i,e))}catch{}this.initialized=!0}async destroy(){var r;if(!this.initialized)return;let e=this.createContext(),t=[...Array.from(this.converterPlugins.values()).flat(),...this.middlewarePlugins];for(let i of t)try{await((r=i.destroy)==null?void 0:r.call(i,e))}catch{}this.initialized=!1}createContext(){return{metadata:new Map,errors:[],warnings:[],stats:{startTime:Date.now(),processedTokens:0,convertedElements:0},performance:{startTime:Date.now()}}}async executeMiddlewareHook(e,t,r){var n;let i=t;for(let o of this.middlewarePlugins){let s=o[e];if(s)try{i=await s.call(o,i,r)||i}catch(a){r.errors.push(a),await((n=o.onError)==null?void 0:n.call(o,a,r))}}return i}async parserByBuffer(e){var r;await this.initialize();let t=this.createContext();t.rawData=e,t.xmlContent=e.toString("utf-8"),t.metadata.set("decoder",this);try{for(let i of this.processors)try{switch(t=await i.process(t),i.stage){case"tokenize":t.tokens&&(t.tokens=await this.executeMiddlewareHook("onTokenize",t.tokens,t));break;case"ast_generate":t.ast&&(t.ast=await this.executeMiddlewareHook("onAstGenerate",t.ast,t));break;case"convert":t.result&&(t.result=await this.executeMiddlewareHook("onConvert",t.result,t));break;case"complete":t.result&&(t.result=await this.executeMiddlewareHook("onComplete",t.result,t));break}}catch(n){t.errors.push(n);for(let o of this.middlewarePlugins)await((r=o.onError)==null?void 0:r.call(o,n,t))}return t.result}catch(i){throw i}}convertExtensions(e){var o,s;let t={},{attributes:r,tag:i,value:n}=e;if(r&&Object.entries(r).forEach(([a,c])=>{t[a]=c}),(o=e==null?void 0:e.children)!=null&&o.length)(s=e.children)==null||s.forEach(a=>{t[a.tag]=this.convertExtensions(a)});else if(n!==void 0)return n;return t}};var ke=h(require("dayjs")),Ge=h(require("dayjs/plugin/utc.js"));var be={temperature:"atemp",wtemp:"wtemp",heartRate:"hr",cadence:"cad"};var Ie={temperature:"Temperature",Depth:"Depth"};ke.default.extend(Ge.default);var E=class{constructor(e={}){this.formatElevation=e=>{let t=parseFloat(e);return isNaN(t)?e:this.roundTo(t,2).toString()};this.compact=e.compact??!0}async encode(e){let t=this.buildGPXXML(e);return Buffer.from(t,"utf-8")}encodeToString(e){return this.buildGPXXML(e)}buildGPXXML(e){let t=this.buildXMLHeader(),r=this.buildGPXContent(e),n=`${t}${r}
2
+ </gpx>`;return this.compact?this.compressXML(n):n}compressXML(e){return e.replace(/>\s+</g,"><").replace(/^\s+|\s+$/gm,"").replace(/\s+/g," ").trim()}buildXMLHeader(){return['<?xml version="1.0" encoding="UTF-8"?>','<gpx creator="https://gpxonline.net" version="1.1"',' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"',' xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd'," http://www.garmin.com/xmlschemas/GpxExtensions/v3 http://www.garmin.com/xmlschemas/GpxExtensionsv3.xsd"," http://www.garmin.com/xmlschemas/TrackPointExtension/v1 http://www.garmin.com/xmlschemas/TrackPointExtensionv1.xsd"," http://www.garmin.com/xmlschemas/PowerExtension/v1 http://www.garmin.com/xmlschemas/PowerExtensionv1.xsd",' http://www.topografix.com/GPX/gpx_style/0/2 http://www.topografix.com/GPX/gpx_style/0/2/gpx_style.xsd"',' xmlns:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1"',' xmlns:gpxx="http://www.garmin.com/xmlschemas/GpxExtensions/v3"',' xmlns:gpxpx="http://www.garmin.com/xmlschemas/PowerExtension/v1"',' xmlns:gpx_style="http://www.topografix.com/GPX/gpx_style/0/2"',' xmlns="http://www.topografix.com/GPX/1/1">'].join(`
3
+ `)}buildGPXContent(e){let{metadata:t,wpt:r=[],rte:i=[],trk:n=[]}=e,o=[];return t&&o.push(this.buildMetadata(t)),r.forEach(s=>{o.push(this.buildWaypoint(s,"wpt"))}),i.forEach(s=>{o.push(this.buildRoute(s))}),n.forEach(s=>{o.push(this.buildTrack(s))}),o.join(`
4
+ `)}buildMetadata(e){let t=["<metadata>"];return this.addOptionalElement(t,"name",e.name),this.addOptionalElement(t,"desc",e.desc),e.author&&t.push(this.buildAuthor(e.author)),e.copyright&&t.push(this.buildCopyright(e.copyright)),e.link&&this.addLinks(t,e.link),e.time&&t.push(this.buildTimeElement(e.time)),this.addOptionalElement(t,"keywords",e.keywords),e.bounds&&t.push(this.buildBounds(e.bounds)),e.extensions&&t.push(this.buildExtensions(e.extensions)),t.push("</metadata>"),t.join(`
5
+ `)}buildAuthor(e){let t=["<author>"];return this.addOptionalElement(t,"name",e.name),e.email&&t.push(`<email id="${this.escapeXML(e.email.id||"")}" domain="${this.escapeXML(e.email.domain||"")}"/>`),e.link&&t.push(this.buildLink(e.link)),t.push("</author>"),t.join(`
6
+ `)}buildCopyright(e){let t=[`<copyright author="${this.escapeXML(e.author||"")}">`];return this.addOptionalElement(t,"year",e.year),this.addOptionalElement(t,"license",e.license),t.push("</copyright>"),t.join(`
7
+ `)}buildBounds(e){let t=this.escapeXMLAttribute((e.minlat||0).toString()),r=this.escapeXMLAttribute((e.minlon||0).toString()),i=this.escapeXMLAttribute((e.maxlat||0).toString()),n=this.escapeXMLAttribute((e.maxlon||0).toString());return`<bounds minlat="${t}" minlon="${r}" maxlat="${i}" maxlon="${n}"/>`}buildWaypoint(e,t){var i,n,o;if(!this.isValidCoordinate(e.lat,e.lon))return"";let r=[`<${t} lat="${this.escapeXMLAttribute(this.formatCoordinate(e.lat))}" lon="${this.escapeXMLAttribute(this.formatCoordinate(e.lon))}">`];if(this.addOptionalElement(r,"ele",(i=e.ele)==null?void 0:i.toString(),this.formatElevation),e.time&&r.push(this.buildTimeElement(e.time)),this.addOptionalElement(r,"speed",(n=e.speed)==null?void 0:n.toString()),this.addOptionalElement(r,"course",(o=e.course)==null?void 0:o.toString()),this.addStandardWaypointElements(r,e),e.extensions){let s=this.processPointExtensions(e,e.extensions);Object.keys(s).length>0&&r.push(this.buildExtensions(s))}return r.push(`</${t}>`),r.join(`
8
+ `)}addStandardWaypointElements(e,t){var r,i,n,o,s,a,c;this.addOptionalElement(e,"magvar",(r=t.magvar)==null?void 0:r.toString()),this.addOptionalElement(e,"geoidheight",(i=t.geoidheight)==null?void 0:i.toString()),this.addOptionalElement(e,"name",t.name),this.addOptionalElement(e,"cmt",t.cmt),this.addOptionalElement(e,"desc",t.desc),this.addOptionalElement(e,"src",t.src),t.link&&this.addLinks(e,t.link),this.addOptionalElement(e,"sym",t.sym),this.addOptionalElement(e,"type",t.type),this.addOptionalElement(e,"fix",t.fix),this.addOptionalElement(e,"sat",t.sat),this.addOptionalElement(e,"hdop",(n=t.hdop)==null?void 0:n.toString()),this.addOptionalElement(e,"vdop",(o=t.vdop)==null?void 0:o.toString()),this.addOptionalElement(e,"pdop",(s=t.pdop)==null?void 0:s.toString()),this.addOptionalElement(e,"ageofdgpsdata",(a=t.ageofdgpsdata)==null?void 0:a.toString()),this.addOptionalElement(e,"dgpsid",(c=t.dgpsid)==null?void 0:c.toString())}buildRoute(e){var r;let t=["<rte>"];return this.addRouteTrackCommonElements(t,e),e.rtept&&((r=e.rtept)==null||r.forEach(i=>{t.push(this.buildWaypoint(i,"rtept"))})),e.extensions&&t.push(this.buildExtensions(e.extensions)),t.push("</rte>"),t.join(`
9
+ `)}buildTrack(e){let t=["<trk>"];return this.addRouteTrackCommonElements(t,e),e.trkseg&&e.trkseg.forEach(r=>{t.push(this.buildTrackSegment(r))}),e.extensions&&t.push(this.buildExtensions(e.extensions)),t.push("</trk>"),t.join(`
10
+ `)}buildTrackSegment(e){let t=["<trkseg>"];return e.trkpt&&e.trkpt.forEach(r=>{t.push(this.buildWaypoint(r,"trkpt"))}),e.extensions&&t.push(this.buildExtensions(e.extensions)),t.push("</trkseg>"),t.join(`
11
+ `)}addRouteTrackCommonElements(e,t){var r;this.addOptionalElement(e,"name",t.name),this.addOptionalElement(e,"cmt",t.cmt),this.addOptionalElement(e,"desc",t.desc),this.addOptionalElement(e,"src",t.src),t.link&&this.addLinks(e,t.link),this.addOptionalElement(e,"number",(r=t.number)==null?void 0:r.toString()),this.addOptionalElement(e,"type",t.type)}processPointExtensions(e,t){let r=this.deepClone(t),i=this.buildTrackPointExtension(e,t);Object.keys(i).length>0&&(r["gpxtpx:TrackPointExtension"]=i);let n=this.buildPowerExtension(e,t);Object.keys(n).length>0&&(r["gpxpx:PowerExtension"]=n);let o=this.buildGpxExtensions(e,t);return Object.keys(o).length>0&&(r["gpxx:GpxExtensions"]=o),r}buildTrackPointExtension(e,t){let r=this.deepClone(t["gpxtpx:TrackPointExtension"]||{}),i=Object.keys(be);return Object.keys(e).filter(n=>i.includes(n)).forEach(n=>{let o=be[n];o&&e[n]!==void 0&&(r[`gpxtpx:${o}`]=e[n])}),r}buildPowerExtension(e,t){return this.deepClone(t["gpxpx:PowerExtension"]||{})}buildGpxExtensions(e,t){let r=this.deepClone(t["gpxx:GpxExtensions"]||{}),i=Object.keys(Ie);return Object.keys(e).filter(n=>i.includes(n)).forEach(n=>{let o=Ie[n];o&&e[n]!==void 0&&(r[`gpxx:${o}`]=e[n])}),r}buildExtensions(e){let t=this.buildExtensionContent(e);return t?`<extensions>${t}</extensions>`:""}buildExtensionContent(e){return Object.entries(e).filter(([t])=>!t.startsWith("xmlns")).map(([t,r])=>{if(r&&typeof r=="object"){let i=this.buildExtensionContent(r);return`<${t}>${i}</${t}>`}else if(r!=null)return`<${t}>${this.escapeXML(String(r))}</${t}>`;return""}).filter(t=>t).join("")}buildLink(e){let t=[`<link href="${this.escapeXMLAttribute(e.href||"")}">`];return this.addOptionalElement(t,"text",e.text),this.addOptionalElement(t,"type",e.type),t.push("</link>"),t.join("")}addLinks(e,t){(Array.isArray(t)?t:[t]).forEach(i=>{e.push(this.buildLink(i))})}buildTimeElement(e){return typeof e=="string"&&/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z?$/.test(e)?`<time>${e}</time>`:`<time>${(0,ke.default)(e).utc().format("YYYY-MM-DDTHH:mm:ss[Z]")}</time>`}addOptionalElement(e,t,r,i){if(r!=null&&r!==""){let n=i?i(r):this.escapeXML(r);e.push(`<${t}>${n}</${t}>`)}}isValidCoordinate(e,t){return e!=null&&t!==void 0&&t!==null&&!isNaN(e)&&!isNaN(t)}formatCoordinate(e){return this.roundTo(e,6).toString()}roundTo(e,t){let r=Math.pow(10,t);return Math.round(e*r)/r}escapeXML(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;")}escapeXMLAttribute(e){return typeof e!="string"?String(e||""):e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/'/g,"&apos;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/\r/g,"&#13;").replace(/\n/g,"&#10;").replace(/\t/g,"&#9;")}deepClone(e){if(e===null||typeof e!="object")return e;if(e instanceof Date)return new Date(e.getTime());if(Array.isArray(e))return e.map(r=>this.deepClone(r));let t={};for(let r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=this.deepClone(e[r]));return t}encoder(e){return this.encode(e)}};var Fe=class extends _{constructor(){super(...arguments);this.name="performance-middleware";this.description="Monitor parsing performance"}async onTokenize(t,r){return t}async onAstGenerate(t,r){let i=this.countNodes(t);return t}async onComplete(t,r){let i=r.metadata.get("performance");return t}countNodes(t){let r=1;if(t.children)for(let i of t.children)r+=this.countNodes(i);return r}},Ae=class extends _{constructor(){super(...arguments);this.name="validation-middleware";this.description="Validate GPX data integrity"}async onComplete(t,r){let i=this.validateGPX(t);return i.length>0&&r.metadata.set("validation-errors",i),t}validateGPX(t){let r=[];if(t.version||r.push("Missing GPX version information"),t.creator||r.push("Missing GPX creator information"),t.trk){for(let i of t.trk)if(i.trkseg){for(let n of i.trkseg)if(n.trkpt)for(let o of n.trkpt)(typeof o.lat!="number"||typeof o.lon!="number")&&r.push("Invalid track point coordinates")}}return r}};async function Be(p){let e=[new Fe,new Ae];for(let t of e)await p.registerMiddleware(t)}var He={GPXDecoder:P,GPXEncoder:E,registerDefaultMiddlewares:Be,PipelineStage:ee};var te=class{constructor(){this.stage="parse"}async process(e){let t=Date.now();if(!e.rawData)throw new Error("FIT data cannot be empty");try{let r=await this.parseWithFitSDK(e.rawData);return e.rawMessages=r,e.performance.parseTime=Date.now()-t,e}catch(r){throw new Error(`FIT parsing failed: ${r.message}`)}}async parseWithFitSDK(e){let{Decoder:t,Stream:r}=await import("@garmin/fitsdk"),i=r.fromBuffer(e);if(!t.isFIT(i))throw new Error("Not a valid FIT file");let n=new t(i),{messages:o,errors:s}=n.read();return s&&s.length>0,o}},re=class{constructor(e){this.getConverters=e;this.stage="extract"}async process(e){let t=Date.now();if(!e.rawMessages)throw new Error("Raw messages cannot be empty");let r={};for(let[i,n]of Object.entries(e.rawMessages)){if(!Array.isArray(n)||n.length===0){r[i]=n;continue}let o=this.getConverters(i);if(o.length===0)r[i]=n;else{let s=o[0];try{let a=s.convertMessages(n,e);r[i]=a}catch(a){e.errors.push(a),r[i]=n}}}return e.rawMessages=r,e.performance.extractTime=Date.now()-t,e}},ne=class{constructor(e){this.getStructurePlugins=e;this.stage="structure"}async process(e){let t=Date.now();if(!e.rawMessages)throw new Error("Message data cannot be empty");let r={},i=this.getStructurePlugins();for(let n of i)try{let o=n.structureData(e.rawMessages,e);r={...r,...o}}catch(o){e.errors.push(o)}return e.result=r,e.performance.structureTime=Date.now()-t,e}},ie=class{constructor(){this.stage="complete"}async process(e){e.performance.endTime=Date.now();let t=e.performance.endTime-e.performance.startTime;return e.metadata.set("performance",{totalTime:t,parseTime:e.performance.parseTime,extractTime:e.performance.extractTime,structureTime:e.performance.structureTime}),e.stats&&(e.stats.endTime=Date.now(),e.rawMessages&&(e.stats.processedTokens=this.countTotalMessages(e.rawMessages))),e}countTotalMessages(e){let t=0;return Object.values(e).forEach(r=>{Array.isArray(r)&&(t+=r.length)}),t}};var m=h(require("dayjs"));var v=class{constructor(){this.version="1.0.0";this.priority=100}async initialize(e){e.metadata.set(`plugin:${this.name}:initialized`,!0)}async destroy(e){e.metadata.delete(`plugin:${this.name}:initialized`)}async validate(e){return!0}};var X=class extends v{constructor(){super(...arguments);this.name="SessionStructurePlugin";this.priority=10}structureData(t,r){let{sessionMesgs:i,lapMesgs:n,recordMesgs:o}=t;return i!=null&&i.length?{sessionMesgs:i.map(a=>{let c=(0,m.default)(a.startTime).valueOf(),d=(0,m.default)(a.timestamp).valueOf(),f=((n==null?void 0:n.filter(g=>{let A=(0,m.default)(g.startTime).valueOf(),D=(0,m.default)(g.timestamp).valueOf();return A>=c&&D<=d}))||[]).map(g=>{let A=(0,m.default)(g.startTime).valueOf(),D=(0,m.default)(g.timestamp).valueOf(),$=(o==null?void 0:o.filter(Ne=>{let Le=(0,m.default)(Ne.timestamp).valueOf();return Le>=A&&Le<=D}))||[];return{...g,recordMesgs:$}});return{...a,lapMesgs:f}})}:{}}},R=class extends v{constructor(){super(...arguments);this.name="CourseStructurePlugin";this.priority=10}structureData(t,r){let{courseMesgs:i,lapMesgs:n,recordMesgs:o}=t;if(!(i!=null&&i.length))return{};let s=2e3;return{courseMesgs:i.map(c=>{let d=(n==null?void 0:n.map(l=>{let f=(0,m.default)(l.startTime).valueOf(),g=(0,m.default)(l.timestamp).valueOf(),A=(o==null?void 0:o.filter(D=>{let $=(0,m.default)(D.timestamp).valueOf();return $>=f-s&&$<=g+s}))||[];return{...l,recordMesgs:A}}))||[];return{...c,lapMesgs:d}})}}},M=class extends v{constructor(){super(...arguments);this.name="FileHeaderPlugin";this.priority=1}structureData(t,r){let{fileIdMesgs:i}=t;if(i!=null&&i.length&&i[0]){let n=i[0];r.fileHeader={type:n.type,manufacturer:n.manufacturer,product:n.product}}return{}}};var w=class{constructor(){this.converterPlugins=new Map;this.registeredPlugins=new Set;this.structurePlugins=[];this.middlewarePlugins=[];this.processors=[];this.initialized=!1;this.defaultPluginsRegistered=!1;this.initializePipeline()}initializePipeline(){this.processors=[new te,new re(e=>this.getConverters(e)),new ne(()=>this.structurePlugins),new ie]}async registerDefaultPlugins(){if(this.defaultPluginsRegistered)return;let e=[new M,new X,new R];for(let t of e)this.addStructurePlugin(t),this.registeredPlugins.add(t.name);this.defaultPluginsRegistered=!0}addConverterForMessageType(e,t){this.converterPlugins.has(e)||this.converterPlugins.set(e,[]);let r=this.converterPlugins.get(e);r.push(t),r.sort((i,n)=>(i.priority||100)-(n.priority||100))}addStructurePlugin(e){this.structurePlugins.push(e),this.structurePlugins.sort((t,r)=>(t.priority||100)-(r.priority||100))}async registerMessageConverter(e){if(this.registeredPlugins.has(e.name))throw new Error(`Message converter plugin ${e.name} already exists`);e.supportedMessageTypes.forEach(r=>{this.addConverterForMessageType(r,e)}),this.registeredPlugins.add(e.name);let t=e.priority!==void 0?` (priority: ${e.priority})`:"";e.supportedMessageTypes.forEach(r=>{let n=(this.converterPlugins.get(r)||[]).map(o=>`${o.name}(${o.priority||100})`)})}async registerStructurePlugin(e){if(this.registeredPlugins.has(e.name))throw new Error(`Structure plugin ${e.name} already exists`);this.addStructurePlugin(e),this.registeredPlugins.add(e.name);let t=e.priority!==void 0?` (priority: ${e.priority})`:""}async registerMiddleware(e){let t=this.middlewarePlugins.findIndex(i=>i.name===e.name);t!==-1?this.middlewarePlugins[t]=e:(this.middlewarePlugins.push(e),this.middlewarePlugins.sort((i,n)=>(i.priority||100)-(n.priority||100)));let r=[];e.onParse&&r.push("onParse"),e.onExtractMessages&&r.push("onExtractMessages"),e.onStructure&&r.push("onStructure"),e.onComplete&&r.push("onComplete"),e.onError&&r.push("onError"),r.length>0}getConverter(e){let t=this.converterPlugins.get(e);return t&&t.length>0?t[0]:void 0}getConverters(e){return this.converterPlugins.get(e)||[]}unregisterPlugin(e){if(!this.registeredPlugins.has(e))return!1;for(let[i,n]of this.converterPlugins){let o=n.findIndex(s=>s.name===e);o!==-1&&(n.splice(o,1),n.length===0&&this.converterPlugins.delete(i))}let t=this.structurePlugins.findIndex(i=>i.name===e);t!==-1&&this.structurePlugins.splice(t,1);let r=this.middlewarePlugins.findIndex(i=>i.name===e);return r!==-1&&this.middlewarePlugins.splice(r,1),this.registeredPlugins.delete(e),!0}async initialize(){var r;if(this.initialized)return;await this.registerDefaultPlugins();let e=this.createContext(),t=[...Array.from(this.converterPlugins.values()).flat(),...this.structurePlugins,...this.middlewarePlugins];for(let i of t)try{await((r=i.initialize)==null?void 0:r.call(i,e))}catch{}this.initialized=!0}async destroy(){var r;if(!this.initialized)return;let e=this.createContext(),t=[...Array.from(this.converterPlugins.values()).flat(),...this.structurePlugins,...this.middlewarePlugins];for(let i of t)try{await((r=i.destroy)==null?void 0:r.call(i,e))}catch{}this.initialized=!1}createContext(){return{metadata:new Map,errors:[],warnings:[],stats:{startTime:Date.now(),processedTokens:0,convertedElements:0},performance:{startTime:Date.now()}}}async executeMiddlewareHook(e,t,r){var n;let i=t;for(let o of this.middlewarePlugins){let s=o[e];if(s)try{i=await s.call(o,i,r)||i}catch(a){r.errors.push(a),await((n=o.onError)==null?void 0:n.call(o,a,r))}}return i}async parseByBuffer(e,t={}){var i;await this.initialize();let r=this.createContext();r.rawData=e,r.userData=t.userData,r.metadata.set("decoder",this);try{for(let n of this.processors)try{switch(r=await n.process(r),n.stage){case"parse":r.rawData&&(r.rawData=await this.executeMiddlewareHook("onParse",r.rawData,r));break;case"extract":r.rawMessages&&(r.rawMessages=await this.executeMiddlewareHook("onExtractMessages",r.rawMessages,r));break;case"structure":r.result&&(r.result=await this.executeMiddlewareHook("onStructure",r.result,r));break;case"complete":r.result&&(r.result=await this.executeMiddlewareHook("onComplete",r.result,r));break}}catch(o){r.errors.push(o);for(let s of this.middlewarePlugins)await((i=s.onError)==null?void 0:i.call(s,o,r))}return r.result||{}}catch(n){throw n}}};var ot={file:{course:6,device:1,settings:2,sport:3,activity:4,workout:5,schedules:7,weight:9,totals:10,goals:11,blood_pressure:14,monitoring_a:15,activity_summary:20,monitoring_daily:28,monitoring_b:32,segment_list:35,exd_configuration:40,invalid:0},sport:{generic:0,running:1,cycling:2,transition:3,fitness_equipment:4,swimming:5,basketball:6,soccer:7,tennis:8,american_football:9,training:10,walking:11,cross_country_skiing:12,alpine_skiing:13,snowboarding:14,rowing:15,mountaineering:16,hiking:17,multisport:18,paddling:19,invalid:254},event:{timer:0,workout:3,workout_step:4,power_down:5,power_up:6,off_course:7,session:8,lap:9,course_point:10,battery:11,virtual_partner_pace:12,hr_high_alert:13,hr_low_alert:14,speed_high_alert:15,speed_low_alert:16,cad_high_alert:17,cad_low_alert:18,power_high_alert:19,power_low_alert:20,recovery_hr:21,battery_low:22,time_duration_alert:23,distance_duration_alert:24,calorie_duration_alert:25,activity:26,fitness_equipment:27,length:28,user_marker:32,sport_point:33,calibration:36,front_gear_change:42,rear_gear_change:43,rider_position_change:44,elev_high_alert:45,elev_low_alert:46,comm_timeout:47,invalid:255},event_type:{start:0,stop:1,consecutive_depreciated:2,marker:3,stop_all:4,begin_depreciated:5,end_depreciated:6,end_all_depreciated:7,stop_disable:8,stop_disable_all:9,invalid:255},course_point:{generic:0,summit:1,valley:2,water:3,food:4,danger:5,left:6,right:7,straight:8,first_aid:9,fourth_category:10,third_category:11,second_category:12,first_category:13,hors_category:14,sprint:15,left_fork:16,right_fork:17,middle_fork:18,slight_left:19,sharp_left:20,slight_right:21,sharp_right:22,u_turn:23,segment_start:24,segment_end:25,invalid:255}},x=p=>{let e=ot[p];return{size:1,baseType:0,mapValue:t=>typeof t=="string"?e[t]??255:t,setValue:function(t,r){this.setUint8(t,r)}}},De={enum_file:x("file"),enum_activity:x("sport"),enum_sport:x("sport"),enum_sub_sport:x("sport"),enum_event:x("event"),enum_event_type:x("event_type"),enum_course_point:x("course_point"),uint8:{size:1,baseType:2,setValue:DataView.prototype.setUint8},sint8:{size:1,baseType:1,setValue:DataView.prototype.setInt8},uint16:{size:2,baseType:132,setValue:DataView.prototype.setUint16},sint16:{size:2,baseType:131,setValue:DataView.prototype.setInt16},uint32:{size:4,baseType:134,setValue:DataView.prototype.setUint32},sint32:{size:4,baseType:133,setValue:DataView.prototype.setInt32},string:{size:0,baseType:7,mapValue:p=>Array.from(Ve(p)),setValue:at},distance:{size:4,baseType:134,setValue:DataView.prototype.setUint32,mapValue:p=>Math.round(p*1e3)},speed:{size:2,baseType:132,setValue:DataView.prototype.setUint16,mapValue:p=>Math.round(p*100)},altitude:{size:2,baseType:132,setValue:DataView.prototype.setUint16,mapValue:p=>Math.round((p+500)*5)},seconds:{size:4,baseType:134,setValue:DataView.prototype.setUint32,mapValue:p=>Math.round(p*1e3)},date_time:{size:4,baseType:134,setValue:DataView.prototype.setUint32,mapValue:p=>{let e;return p instanceof Date?(e=Math.floor(p.getTime()/1e3),e-631065600):typeof p=="string"?(e=Math.floor(new Date(p).getTime()/1e3),e-631065600):p<631065600?Math.floor(p):(p>9999999999?e=Math.floor(p/1e3):e=Math.floor(p),e-631065600)}},semicircles:{size:4,baseType:133,setValue:DataView.prototype.setInt32,mapValue:p=>Math.round(p/180*2147483648)}};function ze(p){return Array.from(Ve(p)).length+1}function*Ve(p){for(let e of st(p))e<128?yield e:e<2048?(yield 192|e>>6,yield 128|e&63):e<65536?(yield 224|e>>12,yield 128|e>>6&63,yield 128|e&63):(yield 240|e>>18,yield 128|e>>12&63,yield 128|e>>6&63,yield 128|e&63);yield 0}function*st(p){for(let e=0;e<p.length;){let t=p.codePointAt(e);if(t===void 0)break;yield t,e+=t>65535?2:1}}function at(p,e){for(let t=0;t<e.length;t++)this.setUint8(p+t,e[t])}var pt={file_id:{mesgNum:0,fieldDefns:[{name:"type",number:0,type:"enum_file"},{name:"time_created",number:4,type:"date_time"}]},session:{mesgNum:18,fieldDefns:[{name:"timestamp",number:253,type:"date_time"},{name:"start_time",number:2,type:"date_time"},{name:"total_elapsed_time",number:7,type:"seconds"},{name:"total_timer_time",number:8,type:"seconds"},{name:"start_position_lat",number:3,type:"semicircles"},{name:"start_position_long",number:4,type:"semicircles"},{name:"total_distance",number:9,type:"distance"},{name:"total_ascent",number:21,type:"uint16"},{name:"total_descent",number:22,type:"uint16"},{name:"sport",number:5,type:"enum_sport"},{name:"sub_sport",number:6,type:"enum_sub_sport"},{name:"first_lap_index",number:11,type:"uint16"},{name:"num_laps",number:26,type:"uint16"}]},lap:{mesgNum:19,fieldDefns:[{name:"timestamp",number:253,type:"date_time"},{name:"start_time",number:2,type:"date_time"},{name:"start_position_lat",number:3,type:"semicircles"},{name:"start_position_long",number:4,type:"semicircles"},{name:"end_position_lat",number:5,type:"semicircles"},{name:"end_position_long",number:6,type:"semicircles"},{name:"total_elapsed_time",number:7,type:"seconds"},{name:"total_timer_time",number:8,type:"seconds"},{name:"total_distance",number:9,type:"distance"},{name:"total_ascent",number:21,type:"uint16"},{name:"total_descent",number:22,type:"uint16"}]},record:{mesgNum:20,fieldDefns:[{name:"timestamp",number:253,type:"date_time"},{name:"position_lat",number:0,type:"semicircles"},{name:"position_long",number:1,type:"semicircles"},{name:"altitude",number:2,type:"altitude"},{name:"distance",number:5,type:"distance"},{name:"heart_rate",number:3,type:"uint8"},{name:"cadence",number:4,type:"uint8"},{name:"speed",number:6,type:"speed"},{name:"power",number:7,type:"uint16"}]},event:{mesgNum:21,fieldDefns:[{name:"timestamp",number:253,type:"date_time"},{name:"event",number:0,type:"enum_event"},{name:"event_type",number:1,type:"enum_event_type"},{name:"event_group",number:4,type:"uint8"}]},course:{mesgNum:31,fieldDefns:[{name:"name",number:5,type:"string"},{name:"sport",number:4,type:"enum_sport"},{name:"sub_sport",number:7,type:"enum_sub_sport"}]},activity:{mesgNum:34,fieldDefns:[{name:"timestamp",number:253,type:"date_time"},{name:"total_timer_time",number:0,type:"seconds"},{name:"num_sessions",number:1,type:"uint16"},{name:"type",number:2,type:"enum_activity"},{name:"event",number:3,type:"enum_event"},{name:"event_type",number:4,type:"enum_event_type"},{name:"local_timestamp",number:5,type:"date_time"},{name:"event_group",number:6,type:"uint8"}]},course_point:{mesgNum:32,fieldDefns:[{name:"timestamp",number:1,type:"date_time"},{name:"position_lat",number:2,type:"semicircles"},{name:"position_long",number:3,type:"semicircles"},{name:"distance",number:4,type:"distance"},{name:"type",number:5,type:"enum_course_point"}]}},ct=(p,e)=>p.map(t=>({...t,value:e[t.name]})).filter(({value:t})=>t!==void 0),oe=class p{static check(e,t,r,i){if(t===void 0)throw new Error(`Message '${e}' not known`);if(r===void 0)throw new Error(`Message '${e}' has no field definitions`);let n=r.map(s=>s.name),o=Object.keys(i).filter(s=>!n.includes(s));if(o.length)throw new Error(`Message '${e}' has no field definitions named '${o}'`)}constructor(e,t,r){let i=pt[t];if(!i)throw new Error(`Unknown message type: ${t}`);let{mesgNum:n,fieldDefns:o}=i;p.check(t,n,o,r),this.localNum=e,this.mesgNum=n,this.fields=ct(o,r)}get mesgDefn(){let e=this.fields.map(({number:t,type:r,value:i})=>{let n=De[r];if(!n)throw new Error(`Unknown type: ${r}`);let{size:o,baseType:s}=n;return r==="string"?{number:t,size:ze(i),baseType:s}:{number:t,size:o,baseType:s}});return{localNum:this.localNum,mesgNum:this.mesgNum,fieldDefns:e}}isSameDefn(e){let t=(s,a)=>s.number===a.number&&s.size===a.size&&s.baseType===a.baseType,r=(s,a)=>s.length===a.length&&s.every((c,d)=>t(c,a[d])),{localNum:i,mesgNum:n,fieldDefns:o}=this.mesgDefn;return n===e.mesgNum&&i===e.localNum&&r(o,e.fieldDefns)}get defnRecord(){let{localNum:e,mesgNum:t,fieldDefns:r}=this.mesgDefn,i=6+3*r.length,n=new DataView(new ArrayBuffer(i));n.setUint8(0,64|e),n.setUint8(2,1),n.setUint16(3,t),n.setUint8(5,r.length);let o=6;for(let s of r)n.setUint8(o++,s.number),n.setUint8(o++,s.size),n.setUint8(o++,s.baseType);return n.buffer}get dataRecord(){let{fieldDefns:e}=this.mesgDefn,t=1+e.reduce((n,{size:o})=>n+o,0),r=new DataView(new ArrayBuffer(t));r.setUint8(0,this.localNum);let i=1;for(let{number:n,type:o,value:s}of this.fields){let a=De[o];if(!a)throw new Error(`Unknown type: ${o}`);let{size:c,setValue:d}=a,l;"mapValue"in a?l=a.mapValue(s):l=s,d&&d.call(r,i,l),i+=c}return r.buffer}};var dt=[0,52225,55297,5120,61441,15360,10240,58369,40961,27648,30720,46081,20480,39937,34817,17408],Ue=(p,e)=>(p>>>4^dt[p&15^e])&65535,lt=(p,e,t)=>Ue(Ue(p,e),t),ut=(p,e)=>lt(p,e&15,e>>>4);function _e(p,e=0){let t=e,r=p instanceof ArrayBuffer?new Uint8Array(p):p;for(let i=0;i<r.length;i++)t=ut(t,r[i]);return t}var je=h(require("dayjs")),We=14,mt=16,Tt=2078,ft=776358228,S=class{constructor(e={}){this.localNum={};this.mesgDefn=[];this.messages=[];this.options={compact:e.compact??!0,defaultSport:e.defaultSport??"cycling",defaultSubSport:e.defaultSubSport??"generic"}}async encode(e){return this.reset(),this.buildFITContent(e,"activity"),Buffer.from(await this.blob.arrayBuffer())}async encodeCourse(e){return this.reset(),this.buildFITContent(e,"course"),Buffer.from(await this.blob.arrayBuffer())}async encodeToBlob(e,t="activity"){return this.reset(),this.buildFITContent(e,t),this.blob}reset(){this.localNum={},this.mesgDefn=[],this.messages=[]}buildFITContent(e,t){this.buildFileId(e,t),t==="course"?this.buildCourseContent(e):this.buildActivityContent(e)}buildActivityContent(e){let t=e.sessionMesgs||[];if(t.length===0)throw new Error("Activity file must contain at least one Session");let r=0,i=[],n=[];for(let o of t){if(o.lapMesgs&&this.buildEventsFromLaps(o.lapMesgs,i),o.lapMesgs)for(let s of o.lapMesgs)s.recordMesgs&&this.buildRecords(s.recordMesgs);o.lapMesgs&&this.buildLaps(o.lapMesgs),this.buildSession(o),r++,this.buildActivityFromSession(o,n)}i.forEach(o=>this.buildEvent(o)),n.forEach(o=>this.buildActivity(o))}buildCourseContent(e){let t=e.sessionMesgs||[];if(t.length===0)throw new Error("Course file must contain track data");let r=t[0];if(this.buildCourse({name:"course",sport:this.options.defaultSport}),r.lapMesgs){let i=[];for(let s of r.lapMesgs)s.recordMesgs&&i.push(...s.recordMesgs);i.sort((s,a)=>s.timestamp&&a.timestamp?new Date(s.timestamp).getTime()-new Date(a.timestamp).getTime():(s.distance||0)-(a.distance||0));let n=i[0],o=i[i.length-1];n.timestamp&&this.buildEvent({timestamp:n.timestamp,event:"timer",eventType:"start",eventGroup:0}),i.forEach(s=>this.buildRecord(s)),o.timestamp&&this.buildEvent({timestamp:o.timestamp,event:"timer",eventType:"stop_all",eventGroup:0}),r.lapMesgs[0]&&this.buildLap(r.lapMesgs[0])}}buildFileId(e,t){var i;let r=((i=e.fileIdMesgs)==null?void 0:i[0])||{};this.writeMesg("file_id",{type:t,time_created:r.timeCreated?this.parseTimestamp(r.timeCreated):Date.now(),manufacturer:r.manufacturer,product:r.product,serial_number:r.serialNumber})}buildSession(e){var t;this.writeMesg("session",{timestamp:e.timestamp?this.parseTimestamp(e.timestamp):void 0,start_time:e.startTime?this.parseTimestamp(e.startTime):void 0,total_elapsed_time:e.totalElapsedTime,total_timer_time:e.totalTimerTime,start_position_lat:this.convertToSemicircles(e.startPositionLat),start_position_long:this.convertToSemicircles(e.startPositionLong),total_distance:e.totalDistance,total_ascent:e.totalAscent,total_descent:e.totalDescent,sport:e.sport||this.options.defaultSport,sub_sport:e.subSport||this.options.defaultSubSport,first_lap_index:e.firstLapIndex||0,num_laps:e.numLaps||((t=e.lapMesgs)==null?void 0:t.length)||1})}buildLaps(e){e.forEach(t=>this.buildLap(t))}buildLap(e){this.writeMesg("lap",{timestamp:e.timestamp?this.parseTimestamp(e.timestamp):void 0,start_time:e.startTime?this.parseTimestamp(e.startTime):void 0,start_position_lat:this.convertToSemicircles(e.startPositionLat),start_position_long:this.convertToSemicircles(e.startPositionLong),end_position_lat:this.convertToSemicircles(e.endPositionLat),end_position_long:this.convertToSemicircles(e.endPositionLong),total_elapsed_time:e.totalElapsedTime,total_timer_time:e.totalTimerTime,total_distance:e.totalDistance,total_ascent:e.totalAscent,total_descent:e.totalDescent})}buildRecords(e){e.forEach(t=>this.buildRecord(t))}buildRecord(e){this.writeMesg("record",{timestamp:e.timestamp?this.parseTimestamp(e.timestamp):void 0,position_lat:this.convertToSemicircles(e.positionLat),position_long:this.convertToSemicircles(e.positionLong),altitude:e.enhancedAltitude||e.altitude,distance:e.distance,heart_rate:e.heartRate,cadence:e.cadence,speed:e.enhancedSpeed||e.speed,power:e.power})}buildEvent(e){this.writeMesg("event",{timestamp:e.timestamp?this.parseTimestamp(e.timestamp):void 0,event:e.event,event_type:e.eventType,event_group:e.eventGroup})}buildActivity(e){this.writeMesg("activity",{timestamp:e.timestamp?this.parseTimestamp(e.timestamp):void 0,total_timer_time:e.totalTimerTime,num_sessions:e.numSessions,type:e.type,event:e.event,event_type:e.eventType,local_timestamp:e.localTimestamp?this.parseTimestamp(e.localTimestamp):void 0,event_group:e.eventGroup})}buildCourse(e){this.writeMesg("course",{name:e.name,sport:e.sport})}buildEventsFromLaps(e,t){e.forEach((r,i)=>{r.startTime&&t.push({timestamp:r.startTime,event:"timer",eventType:"start",eventGroup:i}),r.timestamp&&t.push({timestamp:r.timestamp,event:"timer",eventType:i===e.length-1?"stop_all":"stop",eventGroup:i})})}buildActivityFromSession(e,t){t.push({timestamp:e.timestamp,totalTimerTime:e.totalTimerTime,numSessions:1,type:e.sport||this.options.defaultSport,event:"activity",eventType:"stop",eventGroup:0})}parseTimestamp(e){return typeof e=="number"?e:(0,je.default)(e).valueOf()}convertToSemicircles(e){if(e!=null)return Math.round(e*2**31/180)}validateRequiredFields(e){if(!e.sessionMesgs||e.sessionMesgs.length===0)throw new Error("FIT file must contain at least one Session")}writeMesg(e,t){let r=Object.fromEntries(Object.entries(t).filter(([s,a])=>a!==void 0));if(Object.keys(r).length===0)return;let i=this.localNum[e];i===void 0&&(i=this.localNum[e]=Object.keys(this.localNum).length);let n=new oe(i,e,r),o=this.mesgDefn[i];(!o||!n.isSameDefn(o))&&(this.messages.push(n.defnRecord),this.mesgDefn[i]=n.mesgDefn),this.messages.push(n.dataRecord)}get blob(){let e=[this.header,...this.messages,this.trailer];return new Blob(e,{type:"application/octet-stream"})}get dataLen(){return this.messages.reduce((e,t)=>e+t.byteLength,0)}get dataCrc(){return this.messages.reduce((e,t)=>_e(t,e),0)}get header(){let e=new DataView(new ArrayBuffer(We));return e.setUint8(0,We),e.setUint8(1,mt),e.setUint16(2,Tt,!0),e.setUint32(4,this.dataLen,!0),e.setUint32(8,ft),e.setUint16(12,_e(e.buffer.slice(0,12)),!0),e.buffer}get trailer(){let e=new DataView(new ArrayBuffer(2));return e.setUint16(0,this.dataCrc,!0),e.buffer}async encoder(e){return this.encode(e)}};var T=class extends y{parseHeartRate(e){let t=this.parseFloat(e);return t>0&&t<300?t:void 0}parseTCXTime(e){if(!e)return;let t=new Date(e);return isNaN(t.getTime())?void 0:t}parseDistance(e){let t=this.parseFloat(e);return t>=0?t:void 0}parseSpeed(e){let t=this.parseFloat(e);return t>=0?t:void 0}parseAltitude(e){return this.parseFloat(e)}parseCoordinate(e){let t=this.parseFloat(e);return t!==0?t:void 0}};var se=class extends T{constructor(){super(...arguments);this.name="PositionConverter";this.supportedTags=["Position"]}convert(t,r){let i={};return this.processChildren(t,i,{LatitudeDegrees:(n,o)=>o.LatitudeDegrees=this.parseString(n.value),LongitudeDegrees:(n,o)=>o.LongitudeDegrees=this.parseString(n.value)}),i}},ae=class extends T{constructor(){super(...arguments);this.name="TrackpointConverter";this.supportedTags=["Trackpoint"]}convert(t,r){let i={};return this.processChildren(t,i,{Time:(n,o)=>o.Time=this.parseString(n.value),Position:(n,o)=>{var a;let s=r.metadata.get("decoder");o.Position=(a=s==null?void 0:s.getConverter("Position"))==null?void 0:a.convert(n,r)},AltitudeMeters:(n,o)=>o.AltitudeMeters=this.parseFloat(n.value),DistanceMeters:(n,o)=>o.DistanceMeters=this.parseFloat(n.value),HeartRateBpm:(n,o)=>{if(n.value)o.HeartRateBpm=this.parseFloat(n.value);else{let s=this.getChildByTag(n,"Value");s!=null&&s.value&&(o.HeartRateBpm=this.parseFloat(s.value))}},Cadence:(n,o)=>{let s={Low:0,High:0};this.processChildren(n,s,{Low:(a,c)=>c.Low=this.parseFloat(a.value),High:(a,c)=>c.High=this.parseFloat(a.value)}),o.Cadence=s},SensorState:(n,o)=>o.SensorState=n.value,Extensions:(n,o)=>o.Extensions=this.convertExtensions(n)}),i}convertExtensions(t){var i;let r={};return(i=t.children)==null||i.forEach(n=>{r[n.tag]=this.convertExtensionContent(n)}),r}convertExtensionContent(t){var r;if((r=t.children)!=null&&r.length){let i={};return t.children.forEach(n=>{i[n.tag]=this.convertExtensionContent(n)}),i}else return t.value}},pe=class extends T{constructor(){super(...arguments);this.name="TrackConverter";this.supportedTags=["Track"]}convert(t,r){let i={Trackpoint:[]};return this.processChildren(t,i,{Trackpoint:(n,o)=>{var c;let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("Trackpoint"))==null?void 0:c.convert(n,r);a&&o.Trackpoint&&o.Trackpoint.push(a)}}),i}},ce=class extends T{constructor(){super(...arguments);this.name="ActivityLapConverter";this.supportedTags=["Lap"]}convert(t,r){let i={};return this.extractAttributes(t,i,{StartTime:"Id"}),this.processChildren(t,i,{TotalTimeSeconds:(n,o)=>o.TotalTimeSeconds=this.parseFloat(n.value),DistanceMeters:(n,o)=>o.DistanceMeters=this.parseFloat(n.value),MaximumSpeed:(n,o)=>o.MaximumSpeed=this.parseFloat(n.value),Calories:(n,o)=>o.Calories=this.parseFloat(n.value),AverageHeartRateBpm:(n,o)=>o.AverageHeartRateBpm=this.parseFloat(n.value),MaximumHeartRateBpm:(n,o)=>o.MaximumHeartRateBpm=this.parseFloat(n.value),Intensity:(n,o)=>o.Intensity=n.value,TriggerMethod:(n,o)=>o.TriggerMethod=n.value,Track:(n,o)=>{var c;o.Track||(o.Track=[]);let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("Track"))==null?void 0:c.convert(n,r);a&&o.Track.push(a)},Notes:(n,o)=>o.Notes=this.parseString(n.value),Extensions:(n,o)=>o.Extensions=this.convertExtensions(n)}),i}convertExtensions(t){var i;let r={};return(i=t.children)==null||i.forEach(n=>{r[n.tag]=this.convertExtensionContent(n)}),r}convertExtensionContent(t){var r;if((r=t.children)!=null&&r.length){let i={};return t.children.forEach(n=>{i[n.tag]=this.convertExtensionContent(n)}),i}else return t.value}},de=class extends T{constructor(){super(...arguments);this.name="ActivityConverter";this.supportedTags=["Activity"]}convert(t,r){let i={Id:"",Lap:[]};return this.extractAttributes(t,i,{Sport:"Sport"}),this.processChildren(t,i,{Id:(n,o)=>o.Id=this.parseString(n.value),Lap:(n,o)=>{var c;let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("Lap"))==null?void 0:c.convert(n,r);a&&o.Lap.push(a)},Notes:(n,o)=>o.Notes=this.parseString(n.value),Training:(n,o)=>o.Training=this.convertTraining(n),Creator:(n,o)=>o.Creator=this.convertCreator(n),Extensions:(n,o)=>o.Extensions=this.convertExtensions(n)}),i}convertTraining(t){var i;let r={};return t.attributes&&Object.entries(t.attributes).forEach(([n,o])=>{r[n]=o}),(i=t.children)==null||i.forEach(n=>{r[n.tag]=this.convertExtensionContent(n)}),r}convertCreator(t){var i;let r={};return(i=t.children)==null||i.forEach(n=>{r[n.tag]=this.convertExtensionContent(n)}),r}convertExtensions(t){var i;let r={};return(i=t.children)==null||i.forEach(n=>{r[n.tag]=this.convertExtensionContent(n)}),r}convertExtensionContent(t){var r;if((r=t.children)!=null&&r.length){let i={};return t.children.forEach(n=>{i[n.tag]=this.convertExtensionContent(n)}),i}else return t.value}},le=class extends T{constructor(){super(...arguments);this.name="ActivityListConverter";this.supportedTags=["Activities"]}convert(t,r){let i={Activity:[],MultiSportSession:[]};return this.processChildren(t,i,{Activity:(n,o)=>{var c;let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("Activity"))==null?void 0:c.convert(n,r);a&&o.Activity&&o.Activity.push(a)},MultiSportSession:(n,o)=>{var c;let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("MultiSportSession"))==null?void 0:c.convert(n,r);a&&o.MultiSportSession&&o.MultiSportSession.push(a)}}),i}},ue=class extends T{constructor(){super(...arguments);this.name="MultiSportSessionConverter";this.supportedTags=["MultiSportSession"]}convert(t,r){let i={};return this.processChildren(t,i,{Id:(n,o)=>o.Id=this.parseString(n.value),FirstSport:(n,o)=>{var a;let s=r.metadata.get("decoder");o.FirstSport=(a=s==null?void 0:s.getConverter("FirstSport"))==null?void 0:a.convert(n,r)},NextSport:(n,o)=>{var c;o.NextSport||(o.NextSport=[]);let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("NextSport"))==null?void 0:c.convert(n,r);a&&o.NextSport.push(a)},Notes:(n,o)=>o.Notes=this.parseString(n.value)}),i}},me=class extends T{constructor(){super(...arguments);this.name="AbstractSourceConverter";this.supportedTags=["Author","Creator"]}convert(t,r){let i={};return this.processChildren(t,i,{Name:(n,o)=>o.Name=this.parseString(n.value)}),i}};var Xe=require("htmlparser2"),Te=class{static tokenizeXML(e){let t=[],r=new Xe.Parser({onopentag(i,n){t.push({type:"open",tag:i,attributes:n})},ontext(i){let n=i.replace(/\n/g,"").trim();n&&t.push({type:"text",tag:"text",value:n})},onclosetag(i){t.push({type:"close",tag:i})}},{xmlMode:!0});return r.write(e),r.end(),t}static compressXML(e){return e.replace(/>\s+</g,"><").replace(/\s+/g," ").trim()}static formatXML(e,t=2){let r=" ".repeat(t),i="",n=0,o=!1;for(let s=0;s<e.length;s++){let a=e[s],c=e[s+1];a==="<"?(c==="/"?(n--,o||(i+=`
12
+ `+r.repeat(n))):c!=="?"&&c!=="!"&&(o||(i+=`
13
+ `+r.repeat(n)),n++),o=!0):a===">"&&(o=!1,c==="<"&&e[s+2]==="/"&&n--),i+=a}return i.trim()}static validateXML(e){try{let t=new Xe.Parser({},{xmlMode:!0});return t.write(e),t.end(),{isValid:!0}}catch(t){return{isValid:!1,error:t.message}}}static extractXMLDeclaration(e){let t=e.match(/<\?xml\s+([^>]+)\?>/);if(!t)return{};let r=t[1],i={},n=r.match(/version=["']([^"']+)["']/);n&&(i.version=n[1]);let o=r.match(/encoding=["']([^"']+)["']/);o&&(i.encoding=o[1]);let s=r.match(/standalone=["']([^"']+)["']/);return s&&(i.standalone=s[1]),i}static escapeXML(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}static unescapeXML(e){return e.replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&quot;/g,'"').replace(/&#39;/g,"'").replace(/&amp;/g,"&")}};var fe=class{constructor(){this.stage="tokenize";this.name="tokenize-processor"}async process(e){if(!e.xmlContent)throw new Error("TCX data cannot be empty");let t=Te.tokenizeXML(e.xmlContent);if(t.length===0)throw new Error("Not a valid TCX file");return e.tokens=t,e.stats.processedTokens=t.length,e}},ge=class{constructor(){this.stage="ast-generate";this.name="ast-generate-processor"}async process(e){if(!e.tokens||e.tokens.length===0)throw new Error("Tokens are empty, cannot generate AST");let t=this.buildAST(e.tokens);if(!t)throw new Error("Failed to generate AST");return e.ast=t,e}buildAST(e){if(e.length===0)return;let t=[],r;for(let i of e)if(i.type==="open"){let n={tag:i.tag,attributes:i.attributes,children:[]};r&&(r.children=r.children||[],r.children.push(n)),t.push(n),r=n,t.length||r||(r=n)}else i.type==="close"?(t.pop(),r=t[t.length-1]):i.type==="text"&&r&&i.value&&typeof i.value=="string"&&i.value.trim()&&(r.value=i.value.trim());return r}},he=class{constructor(e){this.getConverter=e;this.stage="convert";this.name="convert-processor"}async process(e){if(!e.ast)throw new Error("AST is empty, cannot convert");let t=this.findTCXRoot(e.ast);if(!t)throw new Error("Not a valid TCX file: TrainingCenterDatabase element not found");let r=this.convertAST(t,e);return e.result=r,e.stats.convertedElements=this.countElements(e.ast),e}findTCXRoot(e){if(e.tag==="TrainingCenterDatabase")return e;if(e.children)for(let t of e.children){let r=this.findTCXRoot(t);if(r)return r}}convertAST(e,t){let r=this.getConverter(e.tag);return r?r.convert(e,t):this.genericConvert(e,t)}genericConvert(e,t){let r={};if(e.attributes&&Object.entries(e.attributes).forEach(([i,n])=>{r[i]=n}),e.value!==void 0)if(e.children&&e.children.length>0)r._value=e.value;else return e.value;return e.children&&e.children.forEach(i=>{let n=this.convertAST(i,t);r[i.tag]?(Array.isArray(r[i.tag])||(r[i.tag]=[r[i.tag]]),r[i.tag].push(n)):r[i.tag]=n}),r}countElements(e){let t=1;if(e.children)for(let r of e.children)t+=this.countElements(r);return t}},ye=class{constructor(){this.stage="complete";this.name="complete-processor"}async process(e){if(!e.result)throw new Error("No conversion result found");let t=Date.now(),r=t-e.performance.startTime;return e.performance.endTime=t,e.performance.processingTime=r,e.metadata.set("performance",{processingTime:r,processedTokens:e.stats.processedTokens,convertedElements:e.stats.convertedElements}),e}};var b=class{constructor(){this.converterPlugins=new Map;this.registeredPlugins=new Set;this.middlewarePlugins=[];this.processors=[];this.initialized=!1;this.defaultConvertersRegistered=!1;this.initializePipeline()}initializePipeline(){this.processors=[new fe,new ge,new he(e=>this.getConverter(e)),new ye]}async registerDefaultConverters(){var t;if(this.defaultConvertersRegistered)return;let e=[new se,new ae,new pe,new ce,new de,new le,new ue,new me];for(let r of e)(t=r.supportedTags)==null||t.forEach(i=>{this.addConverterForTag(i,r)}),this.registeredPlugins.add(r.name);this.defaultConvertersRegistered=!0}addConverterForTag(e,t){this.converterPlugins.has(e)||this.converterPlugins.set(e,[]);let r=this.converterPlugins.get(e);r.push(t),r.sort((i,n)=>(i.priority||100)-(n.priority||100))}async registerConverter(e){var r,n;if(this.registeredPlugins.has(e.name))throw new Error(`Converter plugin ${e.name} already exists`);(r=e.supportedTags)==null||r.forEach(o=>{this.addConverterForTag(o,e)}),this.registeredPlugins.add(e.name);let t=e.priority!==void 0?` (priority: ${e.priority})`:"";(n=e.supportedTags)==null||n.forEach(o=>{let a=(this.converterPlugins.get(o)||[]).map(c=>`${c.name}(${c.priority||100})`)})}async registerMiddleware(e){let t=this.middlewarePlugins.findIndex(i=>i.name===e.name);t!==-1?this.middlewarePlugins[t]=e:this.middlewarePlugins.push(e);let r=[];e.onTokenize&&r.push("onTokenize"),e.onAstGenerate&&r.push("onAstGenerate"),e.onConvert&&r.push("onConvert"),e.onComplete&&r.push("onComplete"),e.onError&&r.push("onError"),r.length>0}getConverter(e){let t=this.converterPlugins.get(e);return t&&t.length>0?t[0]:void 0}getAllConverters(e){return this.converterPlugins.get(e)||[]}unregisterConverter(e){let t;for(let[r,i]of this.converterPlugins){let n=i.findIndex(o=>o.name===e);n!==-1&&(t=i[n],i.splice(n,1),i.length===0&&this.converterPlugins.delete(r))}t&&this.registeredPlugins.delete(e)}unregisterMiddleware(e){let t=this.middlewarePlugins.findIndex(r=>r.name===e);t!==-1&&this.middlewarePlugins.splice(t,1)}async initialize(){var r;if(this.initialized)return;await this.registerDefaultConverters();let e=this.createContext(),t=[...Array.from(this.converterPlugins.values()).flat(),...this.middlewarePlugins];for(let i of t)try{await((r=i.initialize)==null?void 0:r.call(i,e))}catch{}this.initialized=!0}async destroy(){var r;if(!this.initialized)return;let e=this.createContext(),t=[...Array.from(this.converterPlugins.values()).flat(),...this.middlewarePlugins];for(let i of t)try{await((r=i.destroy)==null?void 0:r.call(i,e))}catch{}this.initialized=!1}createContext(){return{metadata:new Map,errors:[],warnings:[],stats:{startTime:Date.now(),processedTokens:0,convertedElements:0},performance:{startTime:Date.now()}}}async executeMiddlewareHook(e,t,r){var n;let i=t;for(let o of this.middlewarePlugins){let s=o[e];if(s)try{i=await s.call(o,i,r)||i}catch(a){r.errors.push(a),await((n=o.onError)==null?void 0:n.call(o,a,r))}}return i}async parseByBuffer(e){var r;await this.initialize();let t=this.createContext();t.rawData=e,t.xmlContent=e.toString("utf-8"),t.metadata.set("decoder",this);try{for(let i of this.processors)try{switch(t=await i.process(t),i.stage){case"tokenize":t.tokens&&(t.tokens=await this.executeMiddlewareHook("onTokenize",t.tokens,t));break;case"ast-generate":t.ast&&(t.ast=await this.executeMiddlewareHook("onAstGenerate",t.ast,t));break;case"convert":t.result&&(t.result=await this.executeMiddlewareHook("onConvert",t.result,t));break;case"complete":t.result&&(t.result=await this.executeMiddlewareHook("onComplete",t.result,t));break}}catch(n){t.errors.push(n);for(let o of this.middlewarePlugins)await((r=o.onError)==null?void 0:r.call(o,n,t))}return t.result}catch(i){throw i}}convertExtensions(e){var o,s;let t={},{attributes:r,tag:i,value:n}=e;if(r&&Object.entries(r).forEach(([a,c])=>{t[a]=c}),(o=e==null?void 0:e.children)!=null&&o.length)(s=e.children)==null||s.forEach(a=>{t[a.tag]=this.convertExtensions(a)});else if(n!==void 0)return n;return t}async parserByBuffer(e){return this.parseByBuffer(e)}async parseByString(e){let t=Buffer.from(e,"utf-8");return this.parseByBuffer(t)}};var Re=h(require("dayjs")),Ke=h(require("dayjs/plugin/utc.js"));Re.default.extend(Ke.default);var L=class{constructor(e={}){this.compact=e.compact??!0}async encode(e){let t=this.buildTCXXML(e);return Buffer.from(t,"utf-8")}encodeToString(e){return this.buildTCXXML(e)}buildTCXXML(e){let t=this.buildXMLHeader(e),r=this.buildTCXContent(e),n=`${t}${r}
14
+ </TrainingCenterDatabase>`;return this.compact?this.compressXML(n):n}compressXML(e){return e.replace(/>\s+</g,"><").replace(/^\s+|\s+$/gm,"").replace(/\s+/g," ").trim()}buildXMLHeader(e){let t=e.version||"1.0",r=e.creator||"trackswap",i=e.xmlns||"http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2",n=e["xmlns:xsi"]||"http://www.w3.org/2001/XMLSchema-instance",o=e["xsi:schemaLocation"]||"http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2 http://www8.garmin.com/xmlschemas/TrainingCenterDatabasev2.xsd";return['<?xml version="1.0" encoding="UTF-8"?>',`<TrainingCenterDatabase version="${this.escapeXMLAttribute(t)}"`,` creator="${this.escapeXMLAttribute(r)}"`,` xmlns="${this.escapeXMLAttribute(i)}"`,` xmlns:xsi="${this.escapeXMLAttribute(n)}"`,` xsi:schemaLocation="${this.escapeXMLAttribute(o)}">`].join(`
15
+ `)}buildTCXContent(e){let t=[];return e.Folders&&t.push(this.buildFolders(e.Folders)),e.Activities&&t.push(this.buildActivities(e.Activities)),e.Workouts&&t.push(this.buildWorkouts(e.Workouts)),e.Courses&&t.push(this.buildCourses(e.Courses)),e.Author&&t.push(this.buildAuthor(e.Author)),e.Extensions&&t.push(this.buildExtensions(e.Extensions)),t.join(`
16
+ `)}buildFolders(e){let t=["<Folders>"];return e.History&&t.push(this.buildHistory(e.History)),e.Workouts&&t.push(this.buildWorkouts(e.Workouts)),e.Courses,t.push("</Folders>"),t.join(`
17
+ `)}buildHistory(e){let t=["<History>"];return e.Running&&t.push(`<Running>${this.buildHistoryFolder(e.Running)}</Running>`),e.Biking&&t.push(`<Biking>${this.buildHistoryFolder(e.Biking)}</Biking>`),e.Other&&t.push(`<Other>${this.buildHistoryFolder(e.Other)}</Other>`),e.MultiSport&&t.push(`<MultiSport>${this.buildHistoryFolder(e.MultiSport)}</MultiSport>`),e.Extensions&&t.push(this.buildExtensions(e.Extensions)),t.push("</History>"),t.join(`
18
+ `)}buildHistoryFolder(e){return""}buildActivities(e){let t=["<Activities>"];return e.Activity&&e.Activity.forEach(r=>{t.push(this.buildActivity(r))}),e.MultiSportSession&&e.MultiSportSession.forEach(r=>{t.push(this.buildMultiSportSession(r))}),t.push("</Activities>"),t.join(`
19
+ `)}buildActivity(e){let r=[`<Activity Sport="${e.Sport||"Other"}">`];return r.push(`<Id>${this.formatTime(e.Id)}</Id>`),e.Lap&&e.Lap.length>0&&e.Lap.forEach(i=>{r.push(this.buildActivityLap(i))}),this.addOptionalElement(r,"Notes",e.Notes),e.Training,e.Creator,e.Extensions&&r.push(this.buildExtensions(e.Extensions)),r.push("</Activity>"),r.join(`
20
+ `)}buildActivityLap(e){let t=["<Lap>"];return this.addOptionalNumericElement(t,"TotalTimeSeconds",e.TotalTimeSeconds),this.addOptionalNumericElement(t,"DistanceMeters",e.DistanceMeters),this.addOptionalNumericElement(t,"MaximumSpeed",e.MaximumSpeed),this.addOptionalNumericElement(t,"Calories",e.Calories),e.AverageHeartRateBpm&&t.push(`<AverageHeartRateBpm xsi:type="HeartRateInBeatsPerMinute_t"><Value>${e.AverageHeartRateBpm}</Value></AverageHeartRateBpm>`),e.MaximumHeartRateBpm&&t.push(`<MaximumHeartRateBpm xsi:type="HeartRateInBeatsPerMinute_t"><Value>${e.MaximumHeartRateBpm}</Value></MaximumHeartRateBpm>`),this.addOptionalElement(t,"Intensity",e.Intensity),e.Cadence&&t.push(this.buildCadence(e.Cadence)),this.addOptionalElement(t,"TriggerMethod",e.TriggerMethod),e.Track&&e.Track.forEach(r=>{t.push(this.buildTrack(r))}),this.addOptionalElement(t,"Notes",e.Notes),e.Extensions&&t.push(this.buildExtensions(e.Extensions)),t.push("</Lap>"),t.join(`
21
+ `)}buildTrack(e){let t=["<Track>"];return e.Trackpoint&&e.Trackpoint.forEach(r=>{t.push(this.buildTrackpoint(r))}),t.push("</Track>"),t.join(`
22
+ `)}buildTrackpoint(e){let t=["<Trackpoint>"];return e.Time&&t.push(`<Time>${this.formatTime(e.Time)}</Time>`),e.Position&&t.push(this.buildPosition(e.Position)),this.addOptionalNumericElement(t,"AltitudeMeters",e.AltitudeMeters),this.addOptionalNumericElement(t,"DistanceMeters",e.DistanceMeters),e.HeartRateBpm&&t.push(`<HeartRateBpm xsi:type="HeartRateInBeatsPerMinute_t"><Value>${e.HeartRateBpm}</Value></HeartRateBpm>`),e.Cadence&&t.push(this.buildCadence(e.Cadence)),this.addOptionalElement(t,"SensorState",e.SensorState),e.Extensions&&t.push(this.buildExtensions(e.Extensions)),t.push("</Trackpoint>"),t.join(`
23
+ `)}buildPosition(e){let t=["<Position>"];return e.LatitudeDegrees&&t.push(`<LatitudeDegrees>${this.formatCoordinate(parseFloat(e.LatitudeDegrees))}</LatitudeDegrees>`),e.LongitudeDegrees&&t.push(`<LongitudeDegrees>${this.formatCoordinate(parseFloat(e.LongitudeDegrees))}</LongitudeDegrees>`),t.push("</Position>"),t.join("")}buildCadence(e){return`<Cadence><Low>${e.Low}</Low><High>${e.High}</High></Cadence>`}buildMultiSportSession(e){let t=["<MultiSportSession>"];return e.Id&&t.push(`<Id>${this.formatTime(e.Id)}</Id>`),e.FirstSport&&t.push(this.buildFirstSport(e.FirstSport)),e.NextSport&&e.NextSport.forEach(r=>{t.push(this.buildNextSport(r))}),this.addOptionalElement(t,"Notes",e.Notes),t.push("</MultiSportSession>"),t.join(`
24
+ `)}buildFirstSport(e){let t=["<FirstSport>"];return e.Activity&&t.push(this.buildActivity(e.Activity)),t.push("</FirstSport>"),t.join(`
25
+ `)}buildNextSport(e){let t=["<NextSport>"];return e.Transition&&t.push(`<Transition>${this.buildActivityLap(e.Transition)}</Transition>`),e.Activity&&t.push(this.buildActivity(e.Activity)),t.push("</NextSport>"),t.join(`
26
+ `)}buildWorkouts(e){return"<Workouts></Workouts>"}buildCourses(e){return"<Courses></Courses>"}buildAuthor(e){let t=["<Author>"];return this.addOptionalElement(t,"Name",e.Name),t.push("</Author>"),t.join("")}buildExtensions(e){let t=this.buildExtensionContent(e);return t?`<Extensions>${t}</Extensions>`:""}buildExtensionContent(e){return Object.entries(e).filter(([t])=>!t.startsWith("xmlns")).map(([t,r])=>{if(r&&typeof r=="object"){let i=this.buildExtensionContent(r);return`<${t}>${i}</${t}>`}else if(r!=null)return`<${t}>${this.escapeXML(String(r))}</${t}>`;return""}).filter(t=>t).join("")}formatTime(e){return typeof e=="string"&&/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/.test(e)?e:(0,Re.default)(e).utc().format("YYYY-MM-DDTHH:mm:ss[Z]")}addOptionalElement(e,t,r,i){if(r!=null&&r!==""){let n=i?i(r):this.escapeXML(r);e.push(`<${t}>${n}</${t}>`)}}addOptionalNumericElement(e,t,r){r!=null&&!isNaN(r)&&e.push(`<${t}>${r}</${t}>`)}isValidCoordinate(e,t){return e!=null&&t!==void 0&&t!==null&&!isNaN(e)&&!isNaN(t)}formatCoordinate(e){return this.roundTo(e,6).toString()}roundTo(e,t){let r=Math.pow(10,t);return Math.round(e*r)/r}escapeXML(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;")}escapeXMLAttribute(e){return typeof e!="string"?String(e||""):e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/'/g,"&apos;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/\r/g,"&#13;").replace(/\n/g,"&#10;").replace(/\t/g,"&#9;")}deepClone(e){if(e===null||typeof e!="object")return e;if(e instanceof Date)return new Date(e.getTime());if(Array.isArray(e))return e.map(r=>this.deepClone(r));let t={};for(let r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=this.deepClone(e[r]));return t}encoder(e){return this.encode(e)}};var I=class extends y{convertPoints(e){return e.map(t=>this.convertPoint(t)).filter(t=>t!==void 0)}convertTime(e){if(e){if(typeof e=="number")return e;if(e instanceof Date)return e.getTime();if(typeof e=="string"){let t=new Date(e);return isNaN(t.getTime())?void 0:t.getTime()}}}calculateDistance(e){if(e.length<2)return;let t=0;for(let r=1;r<e.length;r++){let i=e[r-1],n=e[r],o=6371e3,s=i.lat*Math.PI/180,a=n.lat*Math.PI/180,c=(n.lat-i.lat)*Math.PI/180,d=(n.lon-i.lon)*Math.PI/180,l=Math.sin(c/2)*Math.sin(c/2)+Math.cos(s)*Math.cos(a)*Math.sin(d/2)*Math.sin(d/2),f=2*Math.atan2(Math.sqrt(l),Math.sqrt(1-l));t+=o*f}return t}calculateDuration(e){var i,n;if(e.length<2)return;let t=(i=e[0])==null?void 0:i.time,r=(n=e[e.length-1])==null?void 0:n.time;if(!(!t||!r))return Math.round((r-t)/1e3)}},k=class{constructor(){this.version="1.0.0";this.priority=100}supports(e){return this.supportedTags.includes(e)}async initialize(e){e.metadata.set(`plugin:${this.name}:initialized`,!0)}async destroy(e){e.metadata.delete(`plugin:${this.name}:initialized`)}async validate(e){return!0}convertTimeToDate(e){return e?new Date(e):new Date}convertTimeToString(e){return this.convertTimeToDate(e).toISOString()}ensureValidCoordinates(e,t){return e>=-90&&e<=90&&t>=-180&&t<=180}round(e,t=6){let r=Math.pow(10,t);return Math.round(e*r)/r}};var Ye={"gpxtpx:cad":"cadence","gpxtpx:hr":"heartRate","gpxtpx:temp":"temperature","gpxtpx:wtemp":"wtemp","gpxtpx:atemp":"atemp","gpxx:Temperature":"temperature","gpxx:Depth":"depth"},Me=p=>p*(180/Math.pow(2,31));var F=h(require("dayjs"));function Ze(p,e=0){let t=Math.pow(10,e);return Math.round(p*t)/t}var ve=class extends I{constructor(){super(...arguments);this.name="gpx-to-sport-converter";this.supportedTags=["gpx"];this.convertGPXExtensions=t=>{let r={};return Object.entries(t).forEach(([i,n])=>{if(typeof n!="string"&&typeof n!="number")r={...r,...this.convertGPXExtensions(n)};else if(typeof n<"u"&&n!=="undefined"){let o=Ye[i]||i;r[o]=n}}),r}}convert(t,r){if(r.sourceFormat!=="gpx")return;let i=r.sourceData;return this.convertGPX(i)}convertGPX(t){let r={metadata:{originType:"GPX",creator:t.creator,fileType:"gpx"}};return t.wpt&&(r.points=this.convertWpts2Points(t.wpt)),t.trk&&(r.tracks=t.trk.map(i=>{var n;return{name:i.name,trackseg:((n=i.trkseg)==null?void 0:n.map(o=>({name:i.name,points:o.trkpt?this.convertWpts2Points(o.trkpt):[]})))||[]}})),t.rte&&(r.routes=t.rte.map(i=>({name:i.name,points:i.rtept?this.convertWpts2Points(i.rtept):[]}))),r}convertPoint(t){if(!t.lat||!t.lon)return;let{extensions:r}=t,i=r?this.convertGPXExtensions(r):{};return{lat:t.lat,lon:t.lon,ele:t.ele,time:this.convertTime(t.time),...i}}convertWpts2Points(t){let r=[];for(let i=0;i<t.length;i++){let n=t[i];if(n.lat&&n.lon){let o=this.convertPoint(n);o&&r.push(o)}}return r}},xe=class extends I{constructor(){super(...arguments);this.name="fit-to-sport-converter";this.supportedTags=["fit"]}convert(t,r){if(r.sourceFormat!=="fit")return;let i=r.sourceData;return this.convertFIT(i)}convertFIT(t){var i,n;let r={metadata:{originType:"FIT",fileType:"fit"}};if((i=t.sessionMesgs)!=null&&i.length){r.tracks=[];for(let o of t.sessionMesgs)r.tracks.push({name:o.event,startTime:o.startTime?(0,F.default)(o.startTime).valueOf():void 0,distance:o.totalDistance,duration:o.totalElapsedTime,sport:o.sport,trackseg:this.convertFITLap2Trackseg(o==null?void 0:o.lapMesgs),__fit__sessionMesgType:o})}else if((n=t.courseMesgs)!=null&&n.length){r.routes=[];for(let o of t.courseMesgs)r.routes.push({name:o.event,points:this.convertLap2Points(o==null?void 0:o.lapMesgs)})}return r}convertPoint(t){let{positionLong:r,positionLat:i,altitude:n,timestamp:o,...s}=t;if(!(!r||!i))return{lat:Ze(Me(Number(i)),6),lon:Ze(Me(Number(r)),6),ele:n,time:o?(0,F.default)(o).valueOf():void 0,...s}}convertFITLap2Trackseg(t){var i;let r=[];if(!(t!=null&&t.length))return[];for(let n of t){let o=((i=n==null?void 0:n.recordMesgs)==null?void 0:i.map(s=>this.convertPoint(s)).filter(s=>s!==void 0))||[];r.push({points:o,duration:n.totalElapsedTime,distance:n.totalDistance,startTime:n.startTime?(0,F.default)(n.startTime).valueOf():void 0,endTime:n.startTime&&n.totalElapsedTime?(0,F.default)(n.startTime).add(n.totalElapsedTime,"second").valueOf():void 0,avgSpeed:n.avgSpeed,maxSpeed:n.maxSpeed,avgCadenceBpm:n.avgCadence,maxCadenceBpm:n.maxCadence,avgPower:n.avgPower,maxPower:n.maxPower,totalAscent:n.totalAscent,totalDescent:n.totalDescent,calories:n.totalCalories,__fit__lapMesgType:n})}return r}convertLap2Points(t){var i;let r=[];if(!(t!=null&&t.length))return[];for(let n of t){let o=((i=n.recordMesgs)==null?void 0:i.map(s=>this.convertPoint(s)).filter(s=>s!==void 0))||[];o.length&&(r=[...r,...o])}return r}},Ce=class extends I{constructor(){super(...arguments);this.name="tcx-to-sport-converter";this.supportedTags=["tcx"]}convert(t,r){if(r.sourceFormat!=="tcx")return;let i=r.sourceData;return this.convertTCX(i)}convertTCX(t){var i,n,o,s;let r={metadata:{originType:"TCX",fileType:"tcx"}};if((n=(i=t.Activities)==null?void 0:i.Activity)!=null&&n.length){r.tracks=[];for(let a of t.Activities.Activity)r.tracks.push({name:a.Id,sport:a.Sport,trackseg:this.convertLap2Trackseg(a.Lap)})}if((s=(o=t.Courses)==null?void 0:o.Course)!=null&&s.length){r.routes=[];for(let a of t.Courses.Course){let c=a.Track||[];for(let d of c)r.routes.push({name:a.Name||"",points:this.convertTCXTrack(d)})}}return r}convertPoint(t){let{Position:r,Time:i,DistanceMeters:n,AltitudeMeters:o}=t;if(!(!(r!=null&&r.LatitudeDegrees)||!(r!=null&&r.LongitudeDegrees)))return{lat:Number(r.LatitudeDegrees),lon:Number(r.LongitudeDegrees),time:i?(0,F.default)(i).valueOf():void 0,distance:n,ele:o}}convertLap2Trackseg(t){var i,n,o,s;let r=[];for(let a of t)if(a.Track){for(let c of a.Track)if(c.Trackpoint){let d=c.Trackpoint.map(f=>this.convertPoint(f)).filter(f=>f!==void 0),l={duration:a.TotalTimeSeconds,distance:a.DistanceMeters,startTime:(i=d==null?void 0:d[0])==null?void 0:i.time,endTime:(n=d==null?void 0:d[d.length-1])==null?void 0:n.time,avgHeartRateBpm:a==null?void 0:a.AverageHeartRateBpm,maxHeartRateBpm:a==null?void 0:a.MaximumHeartRateBpm,maxSpeed:a.MaximumSpeed,calories:a.Calories,__tcx__Intensity:a==null?void 0:a.Intensity,__tcx__TriggerMethod:a==null?void 0:a.TriggerMethod,avgCadenceBpm:(o=a==null?void 0:a.Cadence)==null?void 0:o.Low,maxCadenceBpm:(s=a==null?void 0:a.Cadence)==null?void 0:s.High,points:d};r.push(l)}}return r}convertTCXTrack(t){return t.Trackpoint?t.Trackpoint.map(r=>this.convertPoint(r)).filter(r=>r!==void 0):[]}};function qe(p){return Math.round(p*(Math.pow(2,31)/180))}var Pe=class extends k{constructor(){super(...arguments);this.name="sport-to-gpx-encoder";this.supportedTags=["gpx"]}encode(t,r){var n,o,s,a;if(r.targetFormat!=="gpx")return;let i={version:"1.1",creator:((n=t.metadata)==null?void 0:n.creator)||"TrackSwap"};return(o=t.points)!=null&&o.length&&(i.wpt=this.convertPoints2Wpts(t.points)),(s=t.routes)!=null&&s.length&&(i.rte=t.routes.map(c=>this.convertRoute2GPXRoute(c))),(a=t.tracks)!=null&&a.length&&(i.trk=t.tracks.map(c=>this.convertTrack2GPXTrack(c))),i}convertPoints2Wpts(t){return t.map(r=>({lat:r.lat,lon:r.lon,ele:r.ele,time:r.time?this.convertTimeToDate(r.time):void 0,speed:r.speed,magvar:r.magvar,extensions:this.extractGPXExtensions(r)}))}convertRoute2GPXRoute(t){return{name:t.name,rtept:t.points?this.convertPoints2Wpts(t.points):[]}}convertTrack2GPXTrack(t){var r;return{name:t.name,trkseg:((r=t.trackseg)==null?void 0:r.map(i=>({trkpt:i.points?this.convertPoints2Wpts(i.points):[]})))||[]}}extractGPXExtensions(t){let r={};return t.heart&&(r["gpxtpx:hr"]=t.heart),t.cadence&&(r["gpxtpx:cad"]=t.cadence),t.temperature&&(r["gpxtpx:atemp"]=t.temperature),Object.keys(r).length>0?r:void 0}},Ee=class extends k{constructor(){super(...arguments);this.name="sport-to-fit-encoder";this.supportedTags=["fit"]}encode(t,r){var n,o;if(r.targetFormat!=="fit")return;let i={};return(n=t.tracks)!=null&&n.length&&(i.sessionMesgs=t.tracks.map(s=>this.convertTrack2FITSession(s))),(o=t.routes)!=null&&o.length&&(i.courseMesgs=t.routes.map(s=>this.convertRoute2FITCourse(s))),i}convertTrack2FITSession(t){var i;return{event:t.name||"session",sport:t.sport||"generic",startTime:t.startTime?this.convertTimeToString(t.startTime):this.convertTimeToString(void 0),totalDistance:t.distance,totalElapsedTime:t.duration,lapMesgs:((i=t.trackseg)==null?void 0:i.map(n=>this.convertSeg2FITLap(n)))||[]}}convertSeg2FITLap(t){var i;return{startTime:t.startTime?this.convertTimeToString(t.startTime):this.convertTimeToString(void 0),totalElapsedTime:t.duration,totalDistance:t.distance,avgSpeed:t.avgSpeed,maxSpeed:t.maxSpeed,avgCadence:t.avgCadenceBpm,maxCadence:t.maxCadenceBpm,avgPower:t.avgPower,maxPower:t.maxPower,totalAscent:t.totalAscent,totalDescent:t.totalDescent,totalCalories:t.calories,recordMesgs:((i=t.points)==null?void 0:i.map(n=>this.convertPoint2FITRecord(n)))||[]}}convertPoint2FITRecord(t){return{timestamp:t.time?this.convertTimeToString(t.time):this.convertTimeToString(void 0),positionLat:qe(t.lat),positionLong:qe(t.lon),altitude:t.ele,speed:t.speed,power:t.power,heartRate:t.heart,cadence:t.cadence,temperature:t.temperature,distance:t.distance,enhancedSpeed:t.enhancedSpeed,enhancedAltitude:t.enhancedAltitude,accumulatedPower:t.accumulatedPower}}convertRoute2FITCourse(t){return{event:t.name||"course",lapMesgs:t.points?[this.convertPoints2FITLap(t.points)]:[]}}convertPoints2FITLap(t){let r=t[0],i=t[t.length-1],n=r!=null&&r.time?this.convertTimeToString(r.time):this.convertTimeToString(void 0),o=r!=null&&r.time&&(i!=null&&i.time)?Math.round((i.time-r.time)/1e3):0,s=(i==null?void 0:i.distance)||0;return{startTime:n,totalElapsedTime:o,totalDistance:s,recordMesgs:t.map(a=>this.convertPoint2FITRecord(a))}}},we=class extends k{constructor(){super(...arguments);this.name="sport-to-tcx-encoder";this.supportedTags=["tcx"]}encode(t,r){var n,o,s;if(r.targetFormat!=="tcx")return;let i={Author:{Name:((n=t.metadata)==null?void 0:n.creator)||"TrackSwap"}};return(o=t.tracks)!=null&&o.length&&(i.Activities={Activity:t.tracks.map(a=>this.convertTrack2TCXActivity(a))}),(s=t.routes)!=null&&s.length&&(i.Courses={Course:t.routes.map(a=>this.convertRoute2TCXCourse(a))}),i}convertTrack2TCXActivity(t){var i;let r="Other";return(t.sport==="Running"||t.sport==="Biking")&&(r=t.sport),{Id:t.name||`Activity_${Date.now()}`,Sport:r,Lap:((i=t.trackseg)==null?void 0:i.map(n=>this.convertSeg2TCXLap(n)))||[]}}convertSeg2TCXLap(t){let r={TotalTimeSeconds:t.duration,DistanceMeters:t.distance,MaximumSpeed:t.maxSpeed,Calories:t.calories,AverageHeartRateBpm:t.avgHeartRateBpm,MaximumHeartRateBpm:t.maxHeartRateBpm,Intensity:t.__tcx__Intensity||"Active",TriggerMethod:t.__tcx__TriggerMethod||"Manual",Track:t.points?[this.convertPoints2TCXTrack(t.points)]:[]};return(t.avgCadenceBpm!==void 0||t.maxCadenceBpm!==void 0)&&(r.Cadence={Low:t.avgCadenceBpm||0,High:t.maxCadenceBpm||0}),r}convertPoints2TCXTrack(t){return{Trackpoint:t.map(r=>this.convertPoint2TCXTrackpoint(r))}}convertPoint2TCXTrackpoint(t){let r={Time:t.time?this.convertTimeToString(t.time):this.convertTimeToString(void 0),Position:{LatitudeDegrees:t.lat.toString(),LongitudeDegrees:t.lon.toString()},AltitudeMeters:t.ele,DistanceMeters:t.distance};return t.heart&&(r.HeartRateBpm=t.heart),r}convertRoute2TCXCourse(t){return{Name:t.name||`Course_${Date.now()}`,Track:t.points?[this.convertPoints2TCXTrack(t.points)]:[]}}};var Se=class{constructor(){this.converters=new Map;this.encoders=new Map;this.registerDefaultConverters(),this.registerDefaultEncoders()}registerDefaultConverters(){this.registerConverter(new ve),this.registerConverter(new xe),this.registerConverter(new Ce)}registerDefaultEncoders(){this.registerEncoder(new Pe),this.registerEncoder(new Ee),this.registerEncoder(new we)}registerConverter(e){this.converters.set(e.name,e)}registerEncoder(e){this.encoders.set(e.name,e)}async convertToSport(e,t){let r={metadata:new Map,errors:[],warnings:[],stats:{startTime:Date.now(),processedTokens:0,convertedElements:0},sourceFormat:t,sourceData:e,performance:{startTime:Date.now()}};try{let i=this.findConverter(t);if(!i)throw new Error(`No converter found for format "${t}"`);let n=Date.now(),o=i.convert({},r);if(r.performance.convertTime=Date.now()-n,!o)throw new Error(`Converter "${i.name}" returned empty result`);return r.result=o,r.performance.endTime=Date.now(),r.stats.endTime=Date.now(),o}catch(i){throw r.errors.push(i),i}}async encodeSport(e,t){let r={metadata:new Map,errors:[],warnings:[],stats:{startTime:Date.now(),processedTokens:0,convertedElements:0},targetFormat:t,performance:{startTime:Date.now()}};try{let i=this.findEncoder(t);if(!i)throw new Error(`No encoder found for format "${t}"`);let n=Date.now(),o=i.encode(e,r);if(r.performance.encodeTime=Date.now()-n,!o)throw new Error(`Encoder "${i.name}" returned empty result`);return r.result=o,r.performance.endTime=Date.now(),r.stats.endTime=Date.now(),o}catch(i){throw r.errors.push(i),i}}findConverter(e){return Array.from(this.converters.values()).find(t=>{var r;return(r=t.supportedTags)==null?void 0:r.includes(e)})}findEncoder(e){return Array.from(this.encoders.values()).find(t=>{var r;return(r=t.supportedTags)==null?void 0:r.includes(e)})}async destroy(){this.converters.clear(),this.encoders.clear()}};var O=class{constructor(){this.gpxDecoder=new P,this.gpxEncoder=new E,this.fitDecoder=new w,this.fitEncoder=new S,this.tcxDecoder=new b,this.tcxEncoder=new L,this.sportProcessor=new Se}async parseGPX(e){try{return await this.gpxDecoder.parserByBuffer(e)}catch(t){throw new Error(`GPX parsing failed: ${t.message}`)}}async parseGPXString(e){let t=Buffer.from(e,"utf-8");return this.parseGPX(t)}async encodeGPX(e){try{return await this.gpxEncoder.encode(e)}catch(t){throw new Error(`GPX encoding failed: ${t.message}`)}}encodeGPXString(e){try{return this.gpxEncoder.encodeToString(e)}catch(t){throw new Error(`GPX encoding failed: ${t.message}`)}}async parseFIT(e){try{return await this.fitDecoder.parseByBuffer(e)}catch(t){throw new Error(`FIT parsing failed: ${t.message}`)}}async encodeFIT(e){try{return await this.fitEncoder.encode(e)}catch(t){throw new Error(`FIT encoding failed: ${t.message}`)}}async encodeFITCourse(e){try{return await this.fitEncoder.encodeCourse(e)}catch(t){throw new Error(`FIT Course encoding failed: ${t.message}`)}}async parseTCX(e){try{let t=await this.tcxDecoder.parseByBuffer(e);if(!t)throw new Error("TCX parsing result is empty");return t}catch(t){throw new Error(`TCX parsing failed: ${t.message}`)}}async parseTCXString(e){let t=Buffer.from(e,"utf-8");return this.parseTCX(t)}async encodeTCX(e){try{return await this.tcxEncoder.encode(e)}catch(t){throw new Error(`TCX encoding failed: ${t.message}`)}}async encodeTCXString(e){try{return await this.tcxEncoder.encodeToString(e)}catch(t){throw new Error(`TCX encoding failed: ${t.message}`)}}async convertGPXToSport(e){return await this.sportProcessor.convertToSport(e,"gpx")}async convertFITToSport(e){return await this.sportProcessor.convertToSport(e,"fit")}async convertTCXToSport(e){return await this.sportProcessor.convertToSport(e,"tcx")}async convertSportToGPX(e){return await this.sportProcessor.encodeSport(e,"gpx")}async convertSportToFIT(e){return await this.sportProcessor.encodeSport(e,"fit")}async convertSportToTCX(e){return await this.sportProcessor.encodeSport(e,"tcx")}async convertFile(e,t,r){try{let i=r||this.detectFormat(e);if(i==="unknown")throw new Error("Unable to recognize source file format, please specify sourceType parameter");if(i===t)return e;let n;switch(i){case"gpx":let s=await this.parseGPX(e);if(!s)throw new Error("GPX file parsing failed");n=s;break;case"fit":n=await this.parseFIT(e);break;case"tcx":n=await this.parseTCX(e);break;default:throw new Error(`Unsupported source file format: ${i}`)}let o;switch(i){case"gpx":o=await this.convertGPXToSport(n);break;case"fit":o=await this.convertFITToSport(n);break;case"tcx":o=await this.convertTCXToSport(n);break;default:throw new Error(`Unsupported source file format conversion: ${i}`)}switch(t){case"gpx":let s=await this.convertSportToGPX(o);return await this.encodeGPX(s);case"fit":let a=await this.convertSportToFIT(o);return await this.encodeFIT(a);case"tcx":let c=await this.convertSportToTCX(o);return await this.encodeTCX(c);default:throw new Error(`Unsupported target file format: ${t}`)}}catch(i){let n=r||"auto-detect";throw new Error(`${n} to ${t.toUpperCase()} failed: ${i.message}`)}}detectFormat(e){let t=e.toString("utf-8",0,Math.min(1024,e.length));if(e.length>=12&&e.toString("ascii",8,12)===".FIT")return"fit";if(t.includes("<?xml")){if(t.includes("<gpx")||t.includes("http://www.topografix.com/GPX/"))return"gpx";if(t.includes("<TrainingCenterDatabase")||t.includes("http://www.garmin.com/xmlschemas/TrainingCenterDatabase/"))return"tcx"}return"unknown"}async parseFile(e,t){let r=t||this.detectFormat(e);if(r==="unknown")throw new Error("Unable to recognize file format, please specify sourceType parameter");switch(r){case"gpx":let i=await this.parseGPX(e);if(!i)throw new Error("GPX parsing failed");return i;case"fit":return await this.parseFIT(e);case"tcx":return await this.parseTCX(e);default:throw new Error(`Unsupported file format: ${r}`)}}async parseToSport(e,t){let r=t||this.detectFormat(e);if(r==="unknown")throw new Error("Unable to recognize file format, please specify sourceType parameter");switch(r){case"gpx":let i=await this.parseGPX(e);if(!i)throw new Error("GPX parsing failed");return this.convertGPXToSport(i);case"fit":let n=await this.parseFIT(e);return this.convertFITToSport(n);case"tcx":let o=await this.parseTCX(e);return this.convertTCXToSport(o);default:throw new Error(`Unsupported file format: ${r}`)}}getSportProcessor(){return this.sportProcessor}getGPXDecoder(){return this.gpxDecoder}getGPXEncoder(){return this.gpxEncoder}getFITDecoder(){return this.fitDecoder}getFITEncoder(){return this.fitEncoder}getTCXDecoder(){return this.tcxDecoder}getTCXEncoder(){return this.tcxEncoder}async destroy(){await this.gpxDecoder.destroy(),await this.fitDecoder.destroy(),await this.tcxDecoder.destroy(),await this.sportProcessor.destroy()}};var gt=O;0&&(module.exports={GPXManager,TrackSwap});