trackswap 0.0.2 → 0.0.3

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 (82) hide show
  1. package/README.md +322 -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 +0 -39
  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 -1
  24. package/dist/TCX/middleware.d.ts +0 -9
  25. package/dist/TCX/processor.d.ts +0 -18
  26. package/dist/TCX/types.d.ts +0 -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.js +24 -5
  31. package/dist/sport/base.d.ts +63 -0
  32. package/dist/sport/converters.d.ts +33 -0
  33. package/dist/sport/encoders.d.ts +34 -0
  34. package/dist/sport/index.d.ts +17 -0
  35. package/dist/sport/processor.d.ts +19 -0
  36. package/dist/types.d.ts +91 -13
  37. package/package.json +18 -3
  38. package/dist/FIT/base.js +0 -101
  39. package/dist/FIT/crc.js +0 -16
  40. package/dist/FIT/decoder.js +0 -323
  41. package/dist/FIT/encoder.js +0 -445
  42. package/dist/FIT/index.js +0 -13
  43. package/dist/FIT/mesg.js +0 -208
  44. package/dist/FIT/middleware.js +0 -206
  45. package/dist/FIT/plugins.js +0 -104
  46. package/dist/FIT/processor.js +0 -170
  47. package/dist/FIT/types/course_point.js +0 -58
  48. package/dist/FIT/types/event.js +0 -50
  49. package/dist/FIT/types/event_type.js +0 -19
  50. package/dist/FIT/types/file.js +0 -24
  51. package/dist/FIT/types/index.js +0 -297
  52. package/dist/FIT/types/mesg_num.js +0 -106
  53. package/dist/FIT/types/sport.js +0 -48
  54. package/dist/FIT/types.js +0 -1
  55. package/dist/FIT/util.js +0 -7
  56. package/dist/GPX/base.js +0 -56
  57. package/dist/GPX/converters.js +0 -352
  58. package/dist/GPX/decoder.js +0 -409
  59. package/dist/GPX/encoder.js +0 -513
  60. package/dist/GPX/extensions/index.js +0 -14
  61. package/dist/GPX/index.js +0 -11
  62. package/dist/GPX/middleware.js +0 -93
  63. package/dist/GPX/processor.js +0 -188
  64. package/dist/GPX/types.js +0 -1
  65. package/dist/GPX/util.js +0 -18
  66. package/dist/TCX/base.js +0 -62
  67. package/dist/TCX/converters.js +0 -333
  68. package/dist/TCX/decoder.js +0 -350
  69. package/dist/TCX/encoder.js +0 -513
  70. package/dist/TCX/index.js +0 -9
  71. package/dist/TCX/middleware.js +0 -93
  72. package/dist/TCX/processor.js +0 -197
  73. package/dist/TCX/types.js +0 -1
  74. package/dist/TrackSwap.js +0 -84
  75. package/dist/core/base.js +0 -138
  76. package/dist/core/decoder.d.ts +0 -66
  77. package/dist/core/decoder.js +0 -90
  78. package/dist/core/index.js +0 -4
  79. package/dist/core/processor.d.ts +0 -69
  80. package/dist/core/processor.js +0 -265
  81. package/dist/core/xml-utils.js +0 -140
  82. 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.js CHANGED
@@ -1,5 +1,24 @@
1
- import { TrackSwap } from "./TrackSwap.js";
2
- import GPXManager from "./GPX/index.js";
3
- export { TrackSwap, };
4
- export { GPXManager };
5
- export default TrackSwap;
1
+ var h=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 o;return(o=e.attributes)==null?void 0:o[r]})}extractAttributes(e,t,r){e.attributes&&Object.entries(e.attributes).forEach(([o,n])=>{let i=r[o];i&&i in t&&(t[i]=String(n||""))})}processChildren(e,t,r){var o;(o=e.children)==null||o.forEach(n=>{let i=r[n.tag];i&&i(n,t)})}getChildValue(e,t){var o;let r=(o=e.children)==null?void 0:o.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(o=>o.tag===t)}getChildrenByTag(e,t){var r;return((r=e.children)==null?void 0:r.filter(o=>o.tag===t))||[]}convertExtensions(e){var r;let t={};return(r=e.children)==null||r.forEach(o=>{t[o.tag]=this.convertExtensionContent(o)}),t}convertExtensionContent(e){var t;if((t=e.children)!=null&&t.length){let r={};return e.children.forEach(o=>{r[o.tag]=this.convertExtensionContent(o)}),r}else return e.value}},x=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 h{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(([o,n])=>{let i=r[o];i&&i in t&&typeof n<"u"&&(t[i]=this.parseFloat(n))})}},_=class extends x{async onError(e,t){t.warnings.push(`\u4E2D\u95F4\u4EF6 ${this.name} \u9519\u8BEF: ${e.message}`)}};var H=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 o={lat:this.parseFloat(t.attributes.lat),lon:this.parseFloat(t.attributes.lon)};return this.extractAttributes(t,o,{lat:"lat",lon:"lon"}),this.processChildren(t,o,{ele:(n,i)=>i.ele=this.parseFloat(n.value),time:(n,i)=>i.time=new Date(this.parseString(n.value)),speed:(n,i)=>i.speed=this.parseFloat(n.value),course:(n,i)=>i.course=this.parseFloat(n.value),name:(n,i)=>i.name=this.parseString(n.value),cmt:(n,i)=>i.cmt=this.parseString(n.value),desc:(n,i)=>i.desc=this.parseString(n.value),src:(n,i)=>i.src=this.parseString(n.value),sym:(n,i)=>i.sym=this.parseString(n.value),type:(n,i)=>i.type=this.parseString(n.value),fix:(n,i)=>i.fix=this.parseString(n.value),sat:(n,i)=>i.sat=this.parseString(n.value),hdop:(n,i)=>i.hdop=this.parseFloat(n.value),vdop:(n,i)=>i.vdop=this.parseFloat(n.value),pdop:(n,i)=>i.pdop=this.parseFloat(n.value),ageofdgpsdata:(n,i)=>i.ageofdgpsdata=this.parseFloat(n.value),geoidheight:(n,i)=>i.geoidheight=this.parseFloat(n.value),magvar:(n,i)=>i.magvar=this.parseFloat(n.value),dgpsid:(n,i)=>i.dgpsid=this.parseFloat(n.value),extensions:(n,i)=>{let s=r.metadata.get("decoder");s&&(i.extensions=s.convertExtensions(n))},link:(n,i)=>{var c;i.link||(i.link=[]);let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("link"))==null?void 0:c.convert(n,r);a&&i.link&&i.link.push(a)}}),o}},V=class extends u{constructor(){super(...arguments);this.name="rte-converter";this.supportedTags=["rte"]}convert(t,r){let o={rtept:[]};return this.processChildren(t,o,{name:(n,i)=>i.name=this.parseString(n.value),cmt:(n,i)=>i.cmt=this.parseString(n.value),desc:(n,i)=>i.desc=this.parseString(n.value),src:(n,i)=>i.src=this.parseString(n.value),number:(n,i)=>i.number=this.parseFloat(n.value),type:(n,i)=>i.type=this.parseString(n.value),rtept:(n,i)=>{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&&i.rtept&&i.rtept.push(a)},extensions:(n,i)=>{let s=r.metadata.get("decoder");s&&(i.extensions=s.convertExtensions(n))},link:(n,i)=>{var a;i.link||(i.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&&i.link&&i.link.push(d)})}}),o}},z=class extends u{constructor(){super(...arguments);this.name="trk-converter";this.supportedTags=["trk"]}convert(t,r){let o={trkseg:[]};return this.processChildren(t,o,{name:(n,i)=>i.name=this.parseString(n.value),cmt:(n,i)=>i.cmt=this.parseString(n.value),desc:(n,i)=>i.desc=this.parseString(n.value),src:(n,i)=>i.src=this.parseString(n.value),number:(n,i)=>i.number=this.parseFloat(n.value),type:(n,i)=>i.type=this.parseString(n.value),trkseg:(n,i)=>{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&&i.trkseg&&i.trkseg.push(a)},extensions:(n,i)=>{let s=r.metadata.get("decoder");s&&(i.extensions=s.convertExtensions(n))},link:(n,i)=>{var a;i.link||(i.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&&i.link&&i.link.push(d)})}}),o}},U=class extends u{constructor(){super(...arguments);this.name="trkseg-converter";this.supportedTags=["trkseg"]}convert(t,r){let o={trkpt:[]};return this.processChildren(t,o,{trkpt:(n,i)=>{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&&i.trkpt&&i.trkpt.push(a)},extensions:(n,i)=>{let s=r.metadata.get("decoder");s&&(i.extensions=s.convertExtensions(n))}}),o}},W=class extends u{constructor(){super(...arguments);this.name="link-converter";this.supportedTags=["link"]}convert(t,r){var n;let o={};return(n=t.attributes)!=null&&n.href&&(o.href=t.attributes.href),this.processChildren(t,o,{text:(i,s)=>s.text=this.parseString(i.value),type:(i,s)=>s.type=this.parseString(i.value)}),o}},j=class extends u{constructor(){super(...arguments);this.name="metadata-converter";this.supportedTags=["metadata"]}convert(t,r){let o={};return this.processChildren(t,o,{name:(n,i)=>i.name=this.parseString(n.value),desc:(n,i)=>i.desc=this.parseString(n.value),keywords:(n,i)=>i.keywords=this.parseString(n.value),time:(n,i)=>i.time=new Date(this.parseString(n.value)),author:(n,i)=>{var a;let s=r.metadata.get("decoder");i.author=(a=s==null?void 0:s.getConverter("author"))==null?void 0:a.convert(n,r)},copyright:(n,i)=>{var a;let s=r.metadata.get("decoder");i.copyright=(a=s==null?void 0:s.getConverter("copyright"))==null?void 0:a.convert(n,r)},bounds:(n,i)=>{var a;let s=r.metadata.get("decoder");i.bounds=(a=s==null?void 0:s.getConverter("bounds"))==null?void 0:a.convert(n,r)},extensions:(n,i)=>{let s=r.metadata.get("decoder");s&&(i.extensions=s.convertExtensions(n))},link:(n,i)=>{var c;i.link||(i.link=[]);let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("link"))==null?void 0:c.convert(n,r);a&&i.link&&i.link.push(a)}}),o}},Y=class extends u{constructor(){super(...arguments);this.name="person-converter";this.supportedTags=["author"]}convert(t,r){var n;let o={};return t.value&&!((n=t.children)!=null&&n.length)?(o.name=this.parseString(t.value),o):(this.processChildren(t,o,{name:(i,s)=>s.name=this.parseString(i.value),email:(i,s)=>{var c;let a=r.metadata.get("decoder");s.email=(c=a==null?void 0:a.getConverter("email"))==null?void 0:c.convert(i,r)},link:(i,s)=>{var c;let a=r.metadata.get("decoder");s.link=(c=a==null?void 0:a.getConverter("link"))==null?void 0:c.convert(i,r)}}),o)}},K=class extends u{constructor(){super(...arguments);this.name="email-converter";this.supportedTags=["email"]}convert(t,r){let o={};return this.processChildren(t,o,{id:(n,i)=>i.id=this.parseString(n.value),domain:(n,i)=>i.domain=this.parseString(n.value)}),o}},Z=class extends u{constructor(){super(...arguments);this.name="copyright-converter";this.supportedTags=["copyright"]}convert(t,r){var n;let o={};return(n=t.attributes)!=null&&n.author&&(o.author=t.attributes.author),this.processChildren(t,o,{year:(i,s)=>s.year=this.parseString(i.value),license:(i,s)=>s.license=this.parseString(i.value)}),o}},q=class extends u{constructor(){super(...arguments);this.name="bounds-converter";this.supportedTags=["bounds"]}convert(t,r){let o={};return this.extractAttributes(t,o,{minlat:"minlat",minlon:"minlon",maxlat:"maxlat",maxlon:"maxlon"}),o}};import{Parser as Ve}from"htmlparser2";var te=(o=>(o.TOKENIZE="tokenize",o.AST_GENERATE="ast_generate",o.CONVERT="convert",o.COMPLETE="complete",o))(te||{}),J=class{constructor(){this.stage="tokenize"}async process(e){let t=Date.now();if(!e.xmlContent)throw new Error("XML\u5185\u5BB9\u4E0D\u80FD\u4E3A\u7A7A");let r=[],o=new Ve({onopentag(n,i){r.push({type:"open",tag:n,attributes:i})},ontext(n){let i=n.replace(/\n/g,"").trim();i&&r.push({type:"text",tag:"text",value:i})},onclosetag(n){r.push({type:"close",tag:n})}},{xmlMode:!0});return o.write(e.xmlContent),o.end(),e.tokens=r,e.performance.tokenizeTime=Date.now()-t,e}},Q=class{constructor(){this.stage="ast_generate"}async process(e){var i;let t=Date.now();if(!e.tokens)throw new Error("Tokens\u4E0D\u80FD\u4E3A\u7A7A");let r=[],o,n=null;for(let s of e.tokens)if(s.type==="open"){let a={tag:s.tag,attributes:s.attributes||{},children:[]};o?n&&((i=n.children)==null||i.push(a)):o=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=o,e.performance.astTime=Date.now()-t,e}},N=class{constructor(e){this.getConverter=e;this.stage="convert"}async process(e){var o;let t=Date.now();if(!e.ast)throw new Error("AST\u4E0D\u80FD\u4E3A\u7A7A");let r={};return e.ast.attributes&&Object.entries(e.ast.attributes).forEach(([n,i])=>{n.startsWith("xmlns:")?r[n]=i.replace(/&#39;/g,"'"):n==="xsi:schemaLocation"?r[n]=i.replace(/&#39;/g,"'"):r[n]=i}),(o=e.ast.children)==null||o.forEach(n=>{let i=this.getConverter(n.tag);try{let s=i.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}}},ee=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 C=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 J,new Q,new N(e=>this.getConverter(e)),new ee]}async registerDefaultConverters(){var t;if(this.defaultConvertersRegistered)return;let e=[new H,new V,new z,new U,new W,new j,new Y,new K,new Z,new q];for(let r of e)(t=r.supportedTags)==null||t.forEach(o=>{this.addConverterForTag(o,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((o,n)=>(o.priority||100)-(n.priority||100))}async registerConverter(e){var r,n;if(this.registeredPlugins.has(e.name))throw new Error(`\u8F6C\u6362\u5668\u63D2\u4EF6 ${e.name} \u5DF2\u5B58\u5728`);(r=e.supportedTags)==null||r.forEach(i=>{this.addConverterForTag(i,e)}),this.registeredPlugins.add(e.name);let t=e.priority!==void 0?` (\u4F18\u5148\u7EA7: ${e.priority})`:"";(n=e.supportedTags)==null||n.forEach(i=>{let a=(this.converterPlugins.get(i)||[]).map(c=>`${c.name}(${c.priority||100})`)})}async registerMiddleware(e){let t=this.middlewarePlugins.findIndex(o=>o.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,o]of this.converterPlugins){let n=o.findIndex(i=>i.name===e);n!==-1&&(t=o[n],o.splice(n,1),o.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(o=>({name:o.name,priority:o.priority||100})))}else for(let[r,o]of this.converterPlugins)t[r]=o.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 o of t)try{await((r=o.initialize)==null?void 0:r.call(o,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 o of t)try{await((r=o.destroy)==null?void 0:r.call(o,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 o=t;for(let i of this.middlewarePlugins){let s=i[e];if(s)try{o=await s.call(i,o,r)||o}catch(a){r.errors.push(a),await((n=i.onError)==null?void 0:n.call(i,a,r))}}return o}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 o of this.processors)try{switch(t=await o.process(t),o.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 i of this.middlewarePlugins)await((r=i.onError)==null?void 0:r.call(i,n,t))}return t.result}catch(o){throw o}}convertExtensions(e){var i,s;let t={},{attributes:r,tag:o,value:n}=e;if(r&&Object.entries(r).forEach(([a,c])=>{t[a]=c}),(i=e==null?void 0:e.children)!=null&&i.length)(s=e.children)==null||s.forEach(a=>{t[a.tag]=this.convertExtensions(a)});else if(n!==void 0)return n;return t}};import _e from"dayjs";import ze from"dayjs/plugin/utc.js";var Ee={temperature:"atemp",wtemp:"wtemp",heartRate:"hr",cadence:"cad"};var we={temperature:"Temperature",Depth:"Depth"};_e.extend(ze);var P=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:o=[],trk:n=[]}=e,i=[];return t&&i.push(this.buildMetadata(t)),r.forEach(s=>{i.push(this.buildWaypoint(s,"wpt"))}),o.forEach(s=>{i.push(this.buildRoute(s))}),n.forEach(s=>{i.push(this.buildTrack(s))}),i.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()),o=this.escapeXMLAttribute((e.maxlat||0).toString()),n=this.escapeXMLAttribute((e.maxlon||0).toString());return`<bounds minlat="${t}" minlon="${r}" maxlat="${o}" maxlon="${n}"/>`}buildWaypoint(e,t){var o,n,i;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",(o=e.ele)==null?void 0:o.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",(i=e.course)==null?void 0:i.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,o,n,i,s,a,c;this.addOptionalElement(e,"magvar",(r=t.magvar)==null?void 0:r.toString()),this.addOptionalElement(e,"geoidheight",(o=t.geoidheight)==null?void 0:o.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",(i=t.vdop)==null?void 0:i.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(o=>{t.push(this.buildWaypoint(o,"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),o=this.buildTrackPointExtension(e,t);Object.keys(o).length>0&&(r["gpxtpx:TrackPointExtension"]=o);let n=this.buildPowerExtension(e,t);Object.keys(n).length>0&&(r["gpxpx:PowerExtension"]=n);let i=this.buildGpxExtensions(e,t);return Object.keys(i).length>0&&(r["gpxx:GpxExtensions"]=i),r}buildTrackPointExtension(e,t){let r=this.deepClone(t["gpxtpx:TrackPointExtension"]||{}),o=Object.keys(Ee);return Object.keys(e).filter(n=>o.includes(n)).forEach(n=>{let i=Ee[n];i&&e[n]!==void 0&&(r[`gpxtpx:${i}`]=e[n])}),r}buildPowerExtension(e,t){return this.deepClone(t["gpxpx:PowerExtension"]||{})}buildGpxExtensions(e,t){let r=this.deepClone(t["gpxx:GpxExtensions"]||{}),o=Object.keys(we);return Object.keys(e).filter(n=>o.includes(n)).forEach(n=>{let i=we[n];i&&e[n]!==void 0&&(r[`gpxx:${i}`]=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 o=this.buildExtensionContent(r);return`<${t}>${o}</${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(o=>{e.push(this.buildLink(o))})}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>${_e(e).utc().format("YYYY-MM-DDTHH:mm:ss[Z]")}</time>`}addOptionalElement(e,t,r,o){if(r!=null&&r!==""){let n=o?o(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 Se=class extends _{constructor(){super(...arguments);this.name="performance-middleware";this.description="\u76D1\u63A7\u89E3\u6790\u6027\u80FD"}async onTokenize(t,r){return t}async onAstGenerate(t,r){let o=this.countNodes(t);return t}async onComplete(t,r){let o=r.metadata.get("performance");return t}countNodes(t){let r=1;if(t.children)for(let o of t.children)r+=this.countNodes(o);return r}},be=class extends _{constructor(){super(...arguments);this.name="validation-middleware";this.description="\u9A8C\u8BC1GPX\u6570\u636E\u7684\u5B8C\u6574\u6027"}async onComplete(t,r){let o=this.validateGPX(t);return o.length>0&&r.metadata.set("validation-errors",o),t}validateGPX(t){let r=[];if(t.version||r.push("\u7F3A\u5C11GPX\u7248\u672C\u4FE1\u606F"),t.creator||r.push("\u7F3A\u5C11GPX\u521B\u5EFA\u8005\u4FE1\u606F"),t.trk){for(let o of t.trk)if(o.trkseg){for(let n of o.trkseg)if(n.trkpt)for(let i of n.trkpt)(typeof i.lat!="number"||typeof i.lon!="number")&&r.push("\u8F68\u8FF9\u70B9\u5750\u6807\u65E0\u6548")}}return r}};async function De(p){let e=[new Se,new be];for(let t of e)await p.registerMiddleware(t)}var Ue={GPXDecoder:C,GPXEncoder:P,registerDefaultMiddlewares:De,PipelineStage:te};var re=class{constructor(){this.stage="parse"}async process(e){let t=Date.now();if(!e.rawData)throw new Error("FIT \u6570\u636E\u4E0D\u80FD\u4E3A\u7A7A");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 \u89E3\u6790\u5931\u8D25: ${r.message}`)}}async parseWithFitSDK(e){let{Decoder:t,Stream:r}=await import("@garmin/fitsdk"),o=r.fromBuffer(e);if(!t.isFIT(o))throw new Error("\u4E0D\u662F\u6709\u6548\u7684 FIT \u6587\u4EF6");let n=new t(o),{messages:i,errors:s}=n.read();return s&&s.length>0,i}},ne=class{constructor(e){this.getConverters=e;this.stage="extract"}async process(e){let t=Date.now();if(!e.rawMessages)throw new Error("\u539F\u59CB\u6D88\u606F\u4E0D\u80FD\u4E3A\u7A7A");let r={};for(let[o,n]of Object.entries(e.rawMessages)){if(!Array.isArray(n)||n.length===0){r[o]=n;continue}let i=this.getConverters(o);if(i.length===0)r[o]=n;else{let s=i[0];try{let a=s.convertMessages(n,e);r[o]=a}catch(a){e.errors.push(a),r[o]=n}}}return e.rawMessages=r,e.performance.extractTime=Date.now()-t,e}},ie=class{constructor(e){this.getStructurePlugins=e;this.stage="structure"}async process(e){let t=Date.now();if(!e.rawMessages)throw new Error("\u6D88\u606F\u6570\u636E\u4E0D\u80FD\u4E3A\u7A7A");let r={},o=this.getStructurePlugins();for(let n of o)try{let i=n.structureData(e.rawMessages,e);r={...r,...i}}catch(i){e.errors.push(i)}return e.result=r,e.performance.structureTime=Date.now()-t,e}},oe=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}};import T from"dayjs";var y=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 D=class extends y{constructor(){super(...arguments);this.name="SessionStructurePlugin";this.priority=10}structureData(t,r){let{sessionMesgs:o,lapMesgs:n,recordMesgs:i}=t;return o!=null&&o.length?{sessionMesgs:o.map(a=>{let c=T(a.startTime).valueOf(),d=T(a.timestamp).valueOf(),f=((n==null?void 0:n.filter(g=>{let F=T(g.startTime).valueOf(),A=T(g.timestamp).valueOf();return F>=c&&A<=d}))||[]).map(g=>{let F=T(g.startTime).valueOf(),A=T(g.timestamp).valueOf(),B=(i==null?void 0:i.filter(He=>{let Ae=T(He.timestamp).valueOf();return Ae>=F&&Ae<=A}))||[];return{...g,recordMesgs:B}});return{...a,lapMesgs:f}})}:{}}},X=class extends y{constructor(){super(...arguments);this.name="CourseStructurePlugin";this.priority=10}structureData(t,r){let{courseMesgs:o,lapMesgs:n,recordMesgs:i}=t;if(!(o!=null&&o.length))return{};let s=2e3;return{courseMesgs:o.map(c=>{let d=(n==null?void 0:n.map(l=>{let f=T(l.startTime).valueOf(),g=T(l.timestamp).valueOf(),F=(i==null?void 0:i.filter(A=>{let B=T(A.timestamp).valueOf();return B>=f-s&&B<=g+s}))||[];return{...l,recordMesgs:F}}))||[];return{...c,lapMesgs:d}})}}},R=class extends y{constructor(){super(...arguments);this.name="FileHeaderPlugin";this.priority=1}structureData(t,r){let{fileIdMesgs:o}=t;if(o!=null&&o.length&&o[0]){let n=o[0];r.fileHeader={type:n.type,manufacturer:n.manufacturer,product:n.product}}return{}}};var E=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 re,new ne(e=>this.getConverters(e)),new ie(()=>this.structurePlugins),new oe]}async registerDefaultPlugins(){if(this.defaultPluginsRegistered)return;let e=[new R,new D,new X];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((o,n)=>(o.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(`\u6D88\u606F\u8F6C\u6362\u5668\u63D2\u4EF6 ${e.name} \u5DF2\u5B58\u5728`);e.supportedMessageTypes.forEach(r=>{this.addConverterForMessageType(r,e)}),this.registeredPlugins.add(e.name);let t=e.priority!==void 0?` (\u4F18\u5148\u7EA7: ${e.priority})`:"";e.supportedMessageTypes.forEach(r=>{let n=(this.converterPlugins.get(r)||[]).map(i=>`${i.name}(${i.priority||100})`)})}async registerStructurePlugin(e){if(this.registeredPlugins.has(e.name))throw new Error(`\u7ED3\u6784\u5316\u63D2\u4EF6 ${e.name} \u5DF2\u5B58\u5728`);this.addStructurePlugin(e),this.registeredPlugins.add(e.name);let t=e.priority!==void 0?` (\u4F18\u5148\u7EA7: ${e.priority})`:""}async registerMiddleware(e){let t=this.middlewarePlugins.findIndex(o=>o.name===e.name);t!==-1?this.middlewarePlugins[t]=e:(this.middlewarePlugins.push(e),this.middlewarePlugins.sort((o,n)=>(o.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[o,n]of this.converterPlugins){let i=n.findIndex(s=>s.name===e);i!==-1&&(n.splice(i,1),n.length===0&&this.converterPlugins.delete(o))}let t=this.structurePlugins.findIndex(o=>o.name===e);t!==-1&&this.structurePlugins.splice(t,1);let r=this.middlewarePlugins.findIndex(o=>o.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 o of t)try{await((r=o.initialize)==null?void 0:r.call(o,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 o of t)try{await((r=o.destroy)==null?void 0:r.call(o,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 o=t;for(let i of this.middlewarePlugins){let s=i[e];if(s)try{o=await s.call(i,o,r)||o}catch(a){r.errors.push(a),await((n=i.onError)==null?void 0:n.call(i,a,r))}}return o}async parseByBuffer(e,t={}){var o;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(i){r.errors.push(i);for(let s of this.middlewarePlugins)await((o=s.onError)==null?void 0:o.call(s,i,r))}return r.result||{}}catch(n){throw n}}};var We={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}},v=p=>{let e=We[p];return{size:1,baseType:0,mapValue:t=>typeof t=="string"?e[t]??255:t,setValue:function(t,r){this.setUint8(t,r)}}},Ie={enum_file:v("file"),enum_activity:v("sport"),enum_sport:v("sport"),enum_sub_sport:v("sport"),enum_event:v("event"),enum_event_type:v("event_type"),enum_course_point:v("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(Re(p)),setValue:Ye},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 Xe(p){return Array.from(Re(p)).length+1}function*Re(p){for(let e of je(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*je(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 Ye(p,e){for(let t=0;t<e.length;t++)this.setUint8(p+t,e[t])}var Ke={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"}]}},Ze=(p,e)=>p.map(t=>({...t,value:e[t.name]})).filter(({value:t})=>t!==void 0),se=class p{static check(e,t,r,o){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),i=Object.keys(o).filter(s=>!n.includes(s));if(i.length)throw new Error(`Message '${e}' has no field definitions named '${i}'`)}constructor(e,t,r){let o=Ke[t];if(!o)throw new Error(`Unknown message type: ${t}`);let{mesgNum:n,fieldDefns:i}=o;p.check(t,n,i,r),this.localNum=e,this.mesgNum=n,this.fields=Ze(i,r)}get mesgDefn(){let e=this.fields.map(({number:t,type:r,value:o})=>{let n=Ie[r];if(!n)throw new Error(`Unknown type: ${r}`);let{size:i,baseType:s}=n;return r==="string"?{number:t,size:Xe(o),baseType:s}:{number:t,size:i,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:o,mesgNum:n,fieldDefns:i}=this.mesgDefn;return n===e.mesgNum&&o===e.localNum&&r(i,e.fieldDefns)}get defnRecord(){let{localNum:e,mesgNum:t,fieldDefns:r}=this.mesgDefn,o=6+3*r.length,n=new DataView(new ArrayBuffer(o));n.setUint8(0,64|e),n.setUint8(2,1),n.setUint16(3,t),n.setUint8(5,r.length);let i=6;for(let s of r)n.setUint8(i++,s.number),n.setUint8(i++,s.size),n.setUint8(i++,s.baseType);return n.buffer}get dataRecord(){let{fieldDefns:e}=this.mesgDefn,t=1+e.reduce((n,{size:i})=>n+i,0),r=new DataView(new ArrayBuffer(t));r.setUint8(0,this.localNum);let o=1;for(let{number:n,type:i,value:s}of this.fields){let a=Ie[i];if(!a)throw new Error(`Unknown type: ${i}`);let{size:c,setValue:d}=a,l;"mapValue"in a?l=a.mapValue(s):l=s,d&&d.call(r,o,l),o+=c}return r.buffer}};var qe=[0,52225,55297,5120,61441,15360,10240,58369,40961,27648,30720,46081,20480,39937,34817,17408],Me=(p,e)=>(p>>>4^qe[p&15^e])&65535,Je=(p,e,t)=>Me(Me(p,e),t),Qe=(p,e)=>Je(p,e&15,e>>>4);function ke(p,e=0){let t=e,r=p instanceof ArrayBuffer?new Uint8Array(p):p;for(let o=0;o<r.length;o++)t=Qe(t,r[o]);return t}import Ne from"dayjs";var Le=14,et=16,tt=2078,rt=776358228,w=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\u6587\u4EF6\u5FC5\u987B\u5305\u542B\u81F3\u5C11\u4E00\u4E2ASession");let r=0,o=[],n=[];for(let i of t){if(i.lapMesgs&&this.buildEventsFromLaps(i.lapMesgs,o),i.lapMesgs)for(let s of i.lapMesgs)s.recordMesgs&&this.buildRecords(s.recordMesgs);i.lapMesgs&&this.buildLaps(i.lapMesgs),this.buildSession(i),r++,this.buildActivityFromSession(i,n)}o.forEach(i=>this.buildEvent(i)),n.forEach(i=>this.buildActivity(i))}buildCourseContent(e){let t=e.sessionMesgs||[];if(t.length===0)throw new Error("Course\u6587\u4EF6\u5FC5\u987B\u5305\u542B\u8F68\u8FF9\u6570\u636E");let r=t[0];if(this.buildCourse({name:"course",sport:this.options.defaultSport}),r.lapMesgs){let o=[];for(let s of r.lapMesgs)s.recordMesgs&&o.push(...s.recordMesgs);o.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=o[0],i=o[o.length-1];n.timestamp&&this.buildEvent({timestamp:n.timestamp,event:"timer",eventType:"start",eventGroup:0}),o.forEach(s=>this.buildRecord(s)),i.timestamp&&this.buildEvent({timestamp:i.timestamp,event:"timer",eventType:"stop_all",eventGroup:0}),r.lapMesgs[0]&&this.buildLap(r.lapMesgs[0])}}buildFileId(e,t){var o;let r=((o=e.fileIdMesgs)==null?void 0:o[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,o)=>{r.startTime&&t.push({timestamp:r.startTime,event:"timer",eventType:"start",eventGroup:o}),r.timestamp&&t.push({timestamp:r.timestamp,event:"timer",eventType:o===e.length-1?"stop_all":"stop",eventGroup:o})})}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:Ne(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\u6587\u4EF6\u5FC5\u987B\u5305\u542B\u81F3\u5C11\u4E00\u4E2ASession")}writeMesg(e,t){let r=Object.fromEntries(Object.entries(t).filter(([s,a])=>a!==void 0));if(Object.keys(r).length===0)return;let o=this.localNum[e];o===void 0&&(o=this.localNum[e]=Object.keys(this.localNum).length);let n=new se(o,e,r),i=this.mesgDefn[o];(!i||!n.isSameDefn(i))&&(this.messages.push(n.defnRecord),this.mesgDefn[o]=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)=>ke(t,e),0)}get header(){let e=new DataView(new ArrayBuffer(Le));return e.setUint8(0,Le),e.setUint8(1,et),e.setUint16(2,tt,!0),e.setUint32(4,this.dataLen,!0),e.setUint32(8,rt),e.setUint16(12,ke(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 m=class extends h{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 ae=class extends m{constructor(){super(...arguments);this.name="PositionConverter";this.supportedTags=["Position"]}convert(t,r){let o={};return this.processChildren(t,o,{LatitudeDegrees:(n,i)=>i.LatitudeDegrees=this.parseString(n.value),LongitudeDegrees:(n,i)=>i.LongitudeDegrees=this.parseString(n.value)}),o}},pe=class extends m{constructor(){super(...arguments);this.name="TrackpointConverter";this.supportedTags=["Trackpoint"]}convert(t,r){let o={};return this.processChildren(t,o,{Time:(n,i)=>i.Time=this.parseString(n.value),Position:(n,i)=>{var a;let s=r.metadata.get("decoder");i.Position=(a=s==null?void 0:s.getConverter("Position"))==null?void 0:a.convert(n,r)},AltitudeMeters:(n,i)=>i.AltitudeMeters=this.parseFloat(n.value),DistanceMeters:(n,i)=>i.DistanceMeters=this.parseFloat(n.value),HeartRateBpm:(n,i)=>{if(n.value)i.HeartRateBpm=this.parseFloat(n.value);else{let s=this.getChildByTag(n,"Value");s!=null&&s.value&&(i.HeartRateBpm=this.parseFloat(s.value))}},Cadence:(n,i)=>{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)}),i.Cadence=s},SensorState:(n,i)=>i.SensorState=n.value,Extensions:(n,i)=>i.Extensions=this.convertExtensions(n)}),o}convertExtensions(t){var o;let r={};return(o=t.children)==null||o.forEach(n=>{r[n.tag]=this.convertExtensionContent(n)}),r}convertExtensionContent(t){var r;if((r=t.children)!=null&&r.length){let o={};return t.children.forEach(n=>{o[n.tag]=this.convertExtensionContent(n)}),o}else return t.value}},ce=class extends m{constructor(){super(...arguments);this.name="TrackConverter";this.supportedTags=["Track"]}convert(t,r){let o={Trackpoint:[]};return this.processChildren(t,o,{Trackpoint:(n,i)=>{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&&i.Trackpoint&&i.Trackpoint.push(a)}}),o}},de=class extends m{constructor(){super(...arguments);this.name="ActivityLapConverter";this.supportedTags=["Lap"]}convert(t,r){let o={};return this.extractAttributes(t,o,{StartTime:"Id"}),this.processChildren(t,o,{TotalTimeSeconds:(n,i)=>i.TotalTimeSeconds=this.parseFloat(n.value),DistanceMeters:(n,i)=>i.DistanceMeters=this.parseFloat(n.value),MaximumSpeed:(n,i)=>i.MaximumSpeed=this.parseFloat(n.value),Calories:(n,i)=>i.Calories=this.parseFloat(n.value),AverageHeartRateBpm:(n,i)=>i.AverageHeartRateBpm=this.parseFloat(n.value),MaximumHeartRateBpm:(n,i)=>i.MaximumHeartRateBpm=this.parseFloat(n.value),Intensity:(n,i)=>i.Intensity=n.value,TriggerMethod:(n,i)=>i.TriggerMethod=n.value,Track:(n,i)=>{var c;i.Track||(i.Track=[]);let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("Track"))==null?void 0:c.convert(n,r);a&&i.Track.push(a)},Notes:(n,i)=>i.Notes=this.parseString(n.value),Extensions:(n,i)=>i.Extensions=this.convertExtensions(n)}),o}convertExtensions(t){var o;let r={};return(o=t.children)==null||o.forEach(n=>{r[n.tag]=this.convertExtensionContent(n)}),r}convertExtensionContent(t){var r;if((r=t.children)!=null&&r.length){let o={};return t.children.forEach(n=>{o[n.tag]=this.convertExtensionContent(n)}),o}else return t.value}},le=class extends m{constructor(){super(...arguments);this.name="ActivityConverter";this.supportedTags=["Activity"]}convert(t,r){let o={Id:"",Lap:[]};return this.extractAttributes(t,o,{Sport:"Sport"}),this.processChildren(t,o,{Id:(n,i)=>i.Id=this.parseString(n.value),Lap:(n,i)=>{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&&i.Lap.push(a)},Notes:(n,i)=>i.Notes=this.parseString(n.value),Training:(n,i)=>i.Training=this.convertTraining(n),Creator:(n,i)=>i.Creator=this.convertCreator(n),Extensions:(n,i)=>i.Extensions=this.convertExtensions(n)}),o}convertTraining(t){var o;let r={};return t.attributes&&Object.entries(t.attributes).forEach(([n,i])=>{r[n]=i}),(o=t.children)==null||o.forEach(n=>{r[n.tag]=this.convertExtensionContent(n)}),r}convertCreator(t){var o;let r={};return(o=t.children)==null||o.forEach(n=>{r[n.tag]=this.convertExtensionContent(n)}),r}convertExtensions(t){var o;let r={};return(o=t.children)==null||o.forEach(n=>{r[n.tag]=this.convertExtensionContent(n)}),r}convertExtensionContent(t){var r;if((r=t.children)!=null&&r.length){let o={};return t.children.forEach(n=>{o[n.tag]=this.convertExtensionContent(n)}),o}else return t.value}},ue=class extends m{constructor(){super(...arguments);this.name="ActivityListConverter";this.supportedTags=["Activities"]}convert(t,r){let o={Activity:[],MultiSportSession:[]};return this.processChildren(t,o,{Activity:(n,i)=>{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&&i.Activity&&i.Activity.push(a)},MultiSportSession:(n,i)=>{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&&i.MultiSportSession&&i.MultiSportSession.push(a)}}),o}},me=class extends m{constructor(){super(...arguments);this.name="MultiSportSessionConverter";this.supportedTags=["MultiSportSession"]}convert(t,r){let o={};return this.processChildren(t,o,{Id:(n,i)=>i.Id=this.parseString(n.value),FirstSport:(n,i)=>{var a;let s=r.metadata.get("decoder");i.FirstSport=(a=s==null?void 0:s.getConverter("FirstSport"))==null?void 0:a.convert(n,r)},NextSport:(n,i)=>{var c;i.NextSport||(i.NextSport=[]);let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("NextSport"))==null?void 0:c.convert(n,r);a&&i.NextSport.push(a)},Notes:(n,i)=>i.Notes=this.parseString(n.value)}),o}},Te=class extends m{constructor(){super(...arguments);this.name="AbstractSourceConverter";this.supportedTags=["Author","Creator"]}convert(t,r){let o={};return this.processChildren(t,o,{Name:(n,i)=>i.Name=this.parseString(n.value)}),o}};import{Parser as nt}from"htmlparser2";var M=class{constructor(){this.stage="tokenize"}async process(e){let t=Date.now();if(!e.xmlContent)throw new Error("XML\u5185\u5BB9\u4E0D\u80FD\u4E3A\u7A7A");let r=[],o=new nt({onopentag(n,i){r.push({type:"open",tag:n,attributes:i})},ontext(n){let i=n.replace(/\n/g,"").trim();i&&r.push({type:"text",tag:"text",value:i})},onclosetag(n){r.push({type:"close",tag:n})}},{xmlMode:!0});return o.write(e.xmlContent),o.end(),e.tokens=r,e.performance.tokenizeTime=Date.now()-t,e}},L=class{constructor(){this.stage="ast_generate"}async process(e){var i;let t=Date.now();if(!e.tokens)throw new Error("Tokens\u4E0D\u80FD\u4E3A\u7A7A");let r=[],o,n=null;for(let s of e.tokens)if(s.type==="open"){let a={tag:s.tag,attributes:s.attributes||{},children:[]};o?n&&((i=n.children)==null||i.push(a)):o=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=o,e.performance.astTime=Date.now()-t,e}},O=class{constructor(e){this.getConverter=e;this.stage="convert"}async process(e){var o;let t=Date.now();if(!e.ast)throw new Error("AST\u4E0D\u80FD\u4E3A\u7A7A");let r={};return e.ast.attributes&&Object.entries(e.ast.attributes).forEach(([n,i])=>{n.startsWith("xmlns:")?r[n]=i.replace(/&#39;/g,"'"):n==="xsi:schemaLocation"?r[n]=i.replace(/&#39;/g,"'"):r[n]=i}),(o=e.ast.children)==null||o.forEach(n=>{let i=this.getConverter(n.tag);if(i)try{let s=i.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"Folders":e.Folders=r;break;case"Activities":e.Activities=r;break;case"Workouts":e.Workouts=r;break;case"Courses":e.Courses=r;break;case"Author":e.Author=r;break;case"Extensions":e.Extensions=r;break;default:e[t]=r;break}}},$=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.stats&&(e.stats.endTime=Date.now(),e.tokens&&(e.stats.processedTokens=e.tokens.length)),e}};var S=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 M,new L,new O(e=>this.getConverter(e)),new $]}async registerDefaultConverters(){var t;if(this.defaultConvertersRegistered)return;let e=[new ae,new pe,new ce,new de,new le,new ue,new me,new Te];for(let r of e)(t=r.supportedTags)==null||t.forEach(o=>{this.addConverterForTag(o,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((o,n)=>(o.priority||100)-(n.priority||100))}async registerConverter(e){var r,n;if(this.registeredPlugins.has(e.name))throw new Error(`\u8F6C\u6362\u5668\u63D2\u4EF6 ${e.name} \u5DF2\u5B58\u5728`);(r=e.supportedTags)==null||r.forEach(i=>{this.addConverterForTag(i,e)}),this.registeredPlugins.add(e.name);let t=e.priority!==void 0?` (\u4F18\u5148\u7EA7: ${e.priority})`:"";(n=e.supportedTags)==null||n.forEach(i=>{let a=(this.converterPlugins.get(i)||[]).map(c=>`${c.name}(${c.priority||100})`)})}async registerMiddleware(e){let t=this.middlewarePlugins.findIndex(o=>o.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,o]of this.converterPlugins){let n=o.findIndex(i=>i.name===e);n!==-1&&(t=o[n],o.splice(n,1),o.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 o of t)try{await((r=o.initialize)==null?void 0:r.call(o,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 o of t)try{await((r=o.destroy)==null?void 0:r.call(o,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 o=t;for(let i of this.middlewarePlugins){let s=i[e];if(s)try{o=await s.call(i,o,r)||o}catch(a){r.errors.push(a),await((n=i.onError)==null?void 0:n.call(i,a,r))}}return o}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 o of this.processors)try{switch(t=await o.process(t),o.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 i of this.middlewarePlugins)await((r=i.onError)==null?void 0:r.call(i,n,t))}return t.result}catch(o){throw o}}convertExtensions(e){var i,s;let t={},{attributes:r,tag:o,value:n}=e;if(r&&Object.entries(r).forEach(([a,c])=>{t[a]=c}),(i=e==null?void 0:e.children)!=null&&i.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)}};import Oe from"dayjs";import ot from"dayjs/plugin/utc.js";Oe.extend(ot);var b=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}
12
+ </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",o=e.xmlns||"http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2",n=e["xmlns:xsi"]||"http://www.w3.org/2001/XMLSchema-instance",i=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(o)}"`,` xmlns:xsi="${this.escapeXMLAttribute(n)}"`,` xsi:schemaLocation="${this.escapeXMLAttribute(i)}">`].join(`
13
+ `)}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(`
14
+ `)}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(`
15
+ `)}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(`
16
+ `)}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(`
17
+ `)}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(o=>{r.push(this.buildActivityLap(o))}),this.addOptionalElement(r,"Notes",e.Notes),e.Training,e.Creator,e.Extensions&&r.push(this.buildExtensions(e.Extensions)),r.push("</Activity>"),r.join(`
18
+ `)}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(`
19
+ `)}buildTrack(e){let t=["<Track>"];return e.Trackpoint&&e.Trackpoint.forEach(r=>{t.push(this.buildTrackpoint(r))}),t.push("</Track>"),t.join(`
20
+ `)}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(`
21
+ `)}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(`
22
+ `)}buildFirstSport(e){let t=["<FirstSport>"];return e.Activity&&t.push(this.buildActivity(e.Activity)),t.push("</FirstSport>"),t.join(`
23
+ `)}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(`
24
+ `)}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 o=this.buildExtensionContent(r);return`<${t}>${o}</${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:Oe(e).utc().format("YYYY-MM-DDTHH:mm:ss[Z]")}addOptionalElement(e,t,r,o){if(r!=null&&r!==""){let n=o?o(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 h{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 o=e[r-1],n=e[r],i=6371e3,s=o.lat*Math.PI/180,a=n.lat*Math.PI/180,c=(n.lat-o.lat)*Math.PI/180,d=(n.lon-o.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+=i*f}return t}calculateDuration(e){var o,n;if(e.length<2)return;let t=(o=e[0])==null?void 0:o.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 $e={"gpxtpx:cad":"cadence","gpxtpx:hr":"heartRate","gpxtpx:temp":"temperature","gpxtpx:wtemp":"wtemp","gpxtpx:atemp":"atemp","gpxx:Temperature":"temperature","gpxx:Depth":"depth"},Fe=p=>p*(180/Math.pow(2,31));import G from"dayjs";function Ge(p,e=0){let t=Math.pow(10,e);return Math.round(p*t)/t}var fe=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(([o,n])=>{if(typeof n!="string"&&typeof n!="number")r={...r,...this.convertGPXExtensions(n)};else if(typeof n<"u"&&n!=="undefined"){let i=$e[o]||o;r[i]=n}}),r}}convert(t,r){if(r.sourceFormat!=="gpx")return;let o=r.sourceData;return this.convertGPX(o)}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(o=>{var n;return{name:o.name,trackseg:((n=o.trkseg)==null?void 0:n.map(i=>({name:o.name,points:i.trkpt?this.convertWpts2Points(i.trkpt):[]})))||[]}})),t.rte&&(r.routes=t.rte.map(o=>({name:o.name,points:o.rtept?this.convertWpts2Points(o.rtept):[]}))),r}convertPoint(t){if(!t.lat||!t.lon)return;let{extensions:r}=t,o=r?this.convertGPXExtensions(r):{};return{lat:t.lat,lon:t.lon,ele:t.ele,time:this.convertTime(t.time),...o}}convertWpts2Points(t){let r=[];for(let o=0;o<t.length;o++){let n=t[o];if(n.lat&&n.lon){let i=this.convertPoint(n);i&&r.push(i)}}return r}},ge=class extends I{constructor(){super(...arguments);this.name="fit-to-sport-converter";this.supportedTags=["fit"]}convert(t,r){if(r.sourceFormat!=="fit")return;let o=r.sourceData;return this.convertFIT(o)}convertFIT(t){var o,n;let r={metadata:{originType:"FIT",fileType:"fit"}};if((o=t.sessionMesgs)!=null&&o.length){r.tracks=[];for(let i of t.sessionMesgs)r.tracks.push({name:i.event,startTime:i.startTime?G(i.startTime).valueOf():void 0,distance:i.totalDistance,duration:i.totalElapsedTime,sport:i.sport,trackseg:this.convertFITLap2Trackseg(i==null?void 0:i.lapMesgs),__fit__sessionMesgType:i})}else if((n=t.courseMesgs)!=null&&n.length){r.routes=[];for(let i of t.courseMesgs)r.routes.push({name:i.event,points:this.convertLap2Points(i==null?void 0:i.lapMesgs)})}return r}convertPoint(t){let{positionLong:r,positionLat:o,altitude:n,timestamp:i,...s}=t;if(!(!r||!o))return{lat:Ge(Fe(Number(o)),6),lon:Ge(Fe(Number(r)),6),ele:n,time:i?G(i).valueOf():void 0,...s}}convertFITLap2Trackseg(t){var o;let r=[];if(!(t!=null&&t.length))return[];for(let n of t){let i=((o=n==null?void 0:n.recordMesgs)==null?void 0:o.map(s=>this.convertPoint(s)).filter(s=>s!==void 0))||[];r.push({points:i,duration:n.totalElapsedTime,distance:n.totalDistance,startTime:n.startTime?G(n.startTime).valueOf():void 0,endTime:n.startTime&&n.totalElapsedTime?G(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 o;let r=[];if(!(t!=null&&t.length))return[];for(let n of t){let i=((o=n.recordMesgs)==null?void 0:o.map(s=>this.convertPoint(s)).filter(s=>s!==void 0))||[];i.length&&(r=[...r,...i])}return r}},he=class extends I{constructor(){super(...arguments);this.name="tcx-to-sport-converter";this.supportedTags=["tcx"]}convert(t,r){if(r.sourceFormat!=="tcx")return;let o=r.sourceData;return this.convertTCX(o)}convertTCX(t){var o,n,i,s;let r={metadata:{originType:"TCX",fileType:"tcx"}};if((n=(o=t.Activities)==null?void 0:o.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=(i=t.Courses)==null?void 0:i.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:o,DistanceMeters:n,AltitudeMeters:i}=t;if(!(!(r!=null&&r.LatitudeDegrees)||!(r!=null&&r.LongitudeDegrees)))return{lat:Number(r.LatitudeDegrees),lon:Number(r.LongitudeDegrees),time:o?G(o).valueOf():void 0,distance:n,ele:i}}convertLap2Trackseg(t){var o,n,i,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:(o=d==null?void 0:d[0])==null?void 0:o.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:(i=a==null?void 0:a.Cadence)==null?void 0:i.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 Be(p){return Math.round(p*(Math.pow(2,31)/180))}var ye=class extends k{constructor(){super(...arguments);this.name="sport-to-gpx-encoder";this.supportedTags=["gpx"]}encode(t,r){var n,i,s,a;if(r.targetFormat!=="gpx")return;let o={version:"1.1",creator:((n=t.metadata)==null?void 0:n.creator)||"TrackSwap"};return(i=t.points)!=null&&i.length&&(o.wpt=this.convertPoints2Wpts(t.points)),(s=t.routes)!=null&&s.length&&(o.rte=t.routes.map(c=>this.convertRoute2GPXRoute(c))),(a=t.tracks)!=null&&a.length&&(o.trk=t.tracks.map(c=>this.convertTrack2GPXTrack(c))),o}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(o=>({trkpt:o.points?this.convertPoints2Wpts(o.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}},ve=class extends k{constructor(){super(...arguments);this.name="sport-to-fit-encoder";this.supportedTags=["fit"]}encode(t,r){var n,i;if(r.targetFormat!=="fit")return;let o={};return(n=t.tracks)!=null&&n.length&&(o.sessionMesgs=t.tracks.map(s=>this.convertTrack2FITSession(s))),(i=t.routes)!=null&&i.length&&(o.courseMesgs=t.routes.map(s=>this.convertRoute2FITCourse(s))),o}convertTrack2FITSession(t){var o;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:((o=t.trackseg)==null?void 0:o.map(n=>this.convertSeg2FITLap(n)))||[]}}convertSeg2FITLap(t){var o;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:((o=t.points)==null?void 0:o.map(n=>this.convertPoint2FITRecord(n)))||[]}}convertPoint2FITRecord(t){return{timestamp:t.time?this.convertTimeToString(t.time):this.convertTimeToString(void 0),positionLat:Be(t.lat),positionLong:Be(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],o=t[t.length-1],n=r!=null&&r.time?this.convertTimeToString(r.time):this.convertTimeToString(void 0),i=r!=null&&r.time&&(o!=null&&o.time)?Math.round((o.time-r.time)/1e3):0,s=(o==null?void 0:o.distance)||0;return{startTime:n,totalElapsedTime:i,totalDistance:s,recordMesgs:t.map(a=>this.convertPoint2FITRecord(a))}}},xe=class extends k{constructor(){super(...arguments);this.name="sport-to-tcx-encoder";this.supportedTags=["tcx"]}encode(t,r){var n,i,s;if(r.targetFormat!=="tcx")return;let o={Author:{Name:((n=t.metadata)==null?void 0:n.creator)||"TrackSwap"}};return(i=t.tracks)!=null&&i.length&&(o.Activities={Activity:t.tracks.map(a=>this.convertTrack2TCXActivity(a))}),(s=t.routes)!=null&&s.length&&(o.Courses={Course:t.routes.map(a=>this.convertRoute2TCXCourse(a))}),o}convertTrack2TCXActivity(t){var o;let r="Other";return(t.sport==="Running"||t.sport==="Biking")&&(r=t.sport),{Id:t.name||`Activity_${Date.now()}`,Sport:r,Lap:((o=t.trackseg)==null?void 0:o.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 Ce=class{constructor(){this.converters=new Map;this.encoders=new Map;this.registerDefaultConverters(),this.registerDefaultEncoders()}registerDefaultConverters(){this.registerConverter(new fe),this.registerConverter(new ge),this.registerConverter(new he)}registerDefaultEncoders(){this.registerEncoder(new ye),this.registerEncoder(new ve),this.registerEncoder(new xe)}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 o=this.findConverter(t);if(!o)throw new Error(`\u6CA1\u6709\u627E\u5230\u9002\u5408\u683C\u5F0F "${t}" \u7684\u8F6C\u6362\u5668`);let n=Date.now(),i=o.convert({},r);if(r.performance.convertTime=Date.now()-n,!i)throw new Error(`\u8F6C\u6362\u5668 "${o.name}" \u8FD4\u56DE\u4E86\u7A7A\u7ED3\u679C`);return r.result=i,r.performance.endTime=Date.now(),r.stats.endTime=Date.now(),i}catch(o){throw r.errors.push(o),o}}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 o=this.findEncoder(t);if(!o)throw new Error(`\u6CA1\u6709\u627E\u5230\u9002\u5408\u683C\u5F0F "${t}" \u7684\u7F16\u7801\u5668`);let n=Date.now(),i=o.encode(e,r);if(r.performance.encodeTime=Date.now()-n,!i)throw new Error(`\u7F16\u7801\u5668 "${o.name}" \u8FD4\u56DE\u4E86\u7A7A\u7ED3\u679C`);return r.result=i,r.performance.endTime=Date.now(),r.stats.endTime=Date.now(),i}catch(o){throw r.errors.push(o),o}}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 Pe=class{constructor(){this.gpxDecoder=new C,this.gpxEncoder=new P,this.fitDecoder=new E,this.fitEncoder=new w,this.tcxDecoder=new S,this.tcxEncoder=new b,this.sportProcessor=new Ce}async parseGPX(e){try{return await this.gpxDecoder.parserByBuffer(e)}catch(t){throw new Error(`GPX\u89E3\u6790\u5931\u8D25: ${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\u7F16\u7801\u5931\u8D25: ${t.message}`)}}encodeGPXString(e){try{return this.gpxEncoder.encodeToString(e)}catch(t){throw new Error(`GPX\u7F16\u7801\u5931\u8D25: ${t.message}`)}}async parseFIT(e){try{return await this.fitDecoder.parseByBuffer(e)}catch(t){throw new Error(`FIT\u89E3\u6790\u5931\u8D25: ${t.message}`)}}async encodeFIT(e){try{return await this.fitEncoder.encode(e)}catch(t){throw new Error(`FIT\u7F16\u7801\u5931\u8D25: ${t.message}`)}}async encodeFITCourse(e){try{return await this.fitEncoder.encodeCourse(e)}catch(t){throw new Error(`FIT Course\u7F16\u7801\u5931\u8D25: ${t.message}`)}}async parseTCX(e){try{let t=await this.tcxDecoder.parseByBuffer(e);if(!t)throw new Error("TCX\u89E3\u6790\u7ED3\u679C\u4E3A\u7A7A");return t}catch(t){throw new Error(`TCX\u89E3\u6790\u5931\u8D25: ${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\u7F16\u7801\u5931\u8D25: ${t.message}`)}}async encodeTCXString(e){try{return await this.tcxEncoder.encodeToString(e)}catch(t){throw new Error(`TCX\u7F16\u7801\u5931\u8D25: ${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 o=r||this.detectFormat(e);if(o==="unknown")throw new Error("\u65E0\u6CD5\u8BC6\u522B\u6E90\u6587\u4EF6\u683C\u5F0F\uFF0C\u8BF7\u6307\u5B9AsourceType\u53C2\u6570");if(o===t)return e;let n;switch(o){case"gpx":let s=await this.parseGPX(e);if(!s)throw new Error("GPX\u6587\u4EF6\u89E3\u6790\u5931\u8D25");n=s;break;case"fit":n=await this.parseFIT(e);break;case"tcx":n=await this.parseTCX(e);break;default:throw new Error(`\u4E0D\u652F\u6301\u7684\u6E90\u6587\u4EF6\u683C\u5F0F: ${o}`)}let i;switch(o){case"gpx":i=await this.convertGPXToSport(n);break;case"fit":i=await this.convertFITToSport(n);break;case"tcx":i=await this.convertTCXToSport(n);break;default:throw new Error(`\u4E0D\u652F\u6301\u7684\u6E90\u6587\u4EF6\u683C\u5F0F\u8F6C\u6362: ${o}`)}switch(t){case"gpx":let s=await this.convertSportToGPX(i);return await this.encodeGPX(s);case"fit":let a=await this.convertSportToFIT(i);return await this.encodeFIT(a);case"tcx":let c=await this.convertSportToTCX(i);return await this.encodeTCX(c);default:throw new Error(`\u4E0D\u652F\u6301\u7684\u76EE\u6807\u6587\u4EF6\u683C\u5F0F: ${t}`)}}catch(o){let n=r||"\u81EA\u52A8\u68C0\u6D4B";throw new Error(`${n}\u8F6C\u6362\u4E3A${t.toUpperCase()}\u5931\u8D25: ${o.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("\u65E0\u6CD5\u8BC6\u522B\u6587\u4EF6\u683C\u5F0F\uFF0C\u8BF7\u6307\u5B9AsourceType\u53C2\u6570");switch(r){case"gpx":let o=await this.parseGPX(e);if(!o)throw new Error("GPX\u89E3\u6790\u5931\u8D25");return o;case"fit":return await this.parseFIT(e);case"tcx":return await this.parseTCX(e);default:throw new Error(`\u4E0D\u652F\u6301\u7684\u6587\u4EF6\u683C\u5F0F: ${r}`)}}async parseToSport(e,t){let r=t||this.detectFormat(e);if(r==="unknown")throw new Error("\u65E0\u6CD5\u8BC6\u522B\u6587\u4EF6\u683C\u5F0F\uFF0C\u8BF7\u6307\u5B9AsourceType\u53C2\u6570");switch(r){case"gpx":let o=await this.parseGPX(e);if(!o)throw new Error("GPX\u89E3\u6790\u5931\u8D25");return this.convertGPXToSport(o);case"fit":let n=await this.parseFIT(e);return this.convertFITToSport(n);case"tcx":let i=await this.parseTCX(e);return this.convertTCXToSport(i);default:throw new Error(`\u4E0D\u652F\u6301\u7684\u6587\u4EF6\u683C\u5F0F: ${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 dn=Pe;export{Ue as GPXManager,Pe as TrackSwap,dn as default};
@@ -0,0 +1,63 @@
1
+ import { IPlugin, IConverterPlugin, IMiddlewarePlugin, BaseConverter, BaseMiddleware, IProcessingContext } from "../core/base.js";
2
+ import { SportFileType, SportPointType, SportRouteSegType, SportTrackType } from "../types.js";
3
+ export interface SportContext extends IProcessingContext {
4
+ sourceFormat: "gpx" | "fit" | "tcx";
5
+ sourceData: any;
6
+ result?: SportFileType;
7
+ performance: {
8
+ startTime: number;
9
+ convertTime?: number;
10
+ validateTime?: number;
11
+ endTime?: number;
12
+ };
13
+ }
14
+ export interface SportEncodingContext extends IProcessingContext {
15
+ targetFormat: "gpx" | "fit" | "tcx";
16
+ result?: any;
17
+ performance: {
18
+ startTime: number;
19
+ encodeTime?: number;
20
+ validateTime?: number;
21
+ endTime?: number;
22
+ };
23
+ }
24
+ export interface ISportPlugin extends IPlugin<SportContext> {
25
+ }
26
+ export interface ISportConverterPlugin extends IConverterPlugin<SportContext> {
27
+ }
28
+ export interface ISportMiddlewarePlugin extends IMiddlewarePlugin<SportContext, SportFileType> {
29
+ }
30
+ export interface ISportEncoderPlugin extends IPlugin<SportEncodingContext> {
31
+ encode(sportData: SportFileType, context: SportEncodingContext): any | undefined;
32
+ supports(format: string): boolean;
33
+ priority?: number;
34
+ }
35
+ export declare abstract class BaseSportConverter extends BaseConverter<SportContext> implements ISportConverterPlugin {
36
+ protected convertPoints(points: any[]): SportPointType[];
37
+ protected abstract convertPoint(point: any): SportPointType | undefined;
38
+ protected convertTime(time: Date | string | number | undefined): number | undefined;
39
+ protected calculateDistance(points: SportPointType[]): number | undefined;
40
+ protected calculateDuration(points: SportPointType[]): number | undefined;
41
+ }
42
+ export declare abstract class BaseSportEncoder implements ISportEncoderPlugin {
43
+ abstract name: string;
44
+ abstract supportedTags: string[];
45
+ version: string;
46
+ priority: number;
47
+ abstract encode(sportData: SportFileType, context: SportEncodingContext): any | undefined;
48
+ supports(format: string): boolean;
49
+ initialize(context: SportEncodingContext): Promise<void>;
50
+ destroy(context: SportEncodingContext): Promise<void>;
51
+ validate(context: SportEncodingContext): Promise<boolean>;
52
+ protected convertTimeToDate(time: number | undefined): Date;
53
+ protected convertTimeToString(time: number | undefined): string;
54
+ protected ensureValidCoordinates(lat: number, lon: number): boolean;
55
+ protected round(value: number, precision?: number): number;
56
+ }
57
+ export declare abstract class BaseSportMiddleware extends BaseMiddleware<SportContext, SportFileType> implements ISportMiddlewarePlugin {
58
+ onError(error: Error, context: SportContext): Promise<void>;
59
+ protected validateSportFile(sportFile: SportFileType): boolean;
60
+ protected validateTrack(track: SportTrackType): boolean;
61
+ protected validateRoute(route: SportRouteSegType): boolean;
62
+ protected validatePoint(point: SportPointType): boolean;
63
+ }
@@ -0,0 +1,33 @@
1
+ import { BaseSportConverter, SportContext } from "./base.js";
2
+ import { TokenAST } from "../types.js";
3
+ import { SportFileType, SportPointType } from "../types.js";
4
+ import { WptType } from "../GPX/types.js";
5
+ import { RecordMesgType } from "../FIT/types.js";
6
+ import { TrackpointType } from "../TCX/types.js";
7
+ export declare class GPXToSportConverter extends BaseSportConverter {
8
+ name: string;
9
+ supportedTags: string[];
10
+ convert(ast: TokenAST, context: SportContext): SportFileType | undefined;
11
+ private convertGPX;
12
+ protected convertPoint(point: WptType): SportPointType | undefined;
13
+ private convertWpts2Points;
14
+ private convertGPXExtensions;
15
+ }
16
+ export declare class FITToSportConverter extends BaseSportConverter {
17
+ name: string;
18
+ supportedTags: string[];
19
+ convert(ast: TokenAST, context: SportContext): SportFileType | undefined;
20
+ private convertFIT;
21
+ protected convertPoint(point: RecordMesgType): SportPointType | undefined;
22
+ private convertFITLap2Trackseg;
23
+ private convertLap2Points;
24
+ }
25
+ export declare class TCXToSportConverter extends BaseSportConverter {
26
+ name: string;
27
+ supportedTags: string[];
28
+ convert(ast: TokenAST, context: SportContext): SportFileType | undefined;
29
+ private convertTCX;
30
+ protected convertPoint(point: TrackpointType): SportPointType | undefined;
31
+ private convertLap2Trackseg;
32
+ private convertTCXTrack;
33
+ }
@@ -0,0 +1,34 @@
1
+ import { BaseSportEncoder, SportEncodingContext } from "./base.js";
2
+ import { SportFileType } from "../types.js";
3
+ import { GPX11Type } from "../GPX/types.js";
4
+ import { FITFileType } from "../FIT/types.js";
5
+ import { TCXFileType } from "../TCX/types.js";
6
+ export declare class SportToGPXEncoder extends BaseSportEncoder {
7
+ name: string;
8
+ supportedTags: string[];
9
+ encode(sportData: SportFileType, context: SportEncodingContext): GPX11Type | undefined;
10
+ private convertPoints2Wpts;
11
+ private convertRoute2GPXRoute;
12
+ private convertTrack2GPXTrack;
13
+ private extractGPXExtensions;
14
+ }
15
+ export declare class SportToFITEncoder extends BaseSportEncoder {
16
+ name: string;
17
+ supportedTags: string[];
18
+ encode(sportData: SportFileType, context: SportEncodingContext): FITFileType | undefined;
19
+ private convertTrack2FITSession;
20
+ private convertSeg2FITLap;
21
+ private convertPoint2FITRecord;
22
+ private convertRoute2FITCourse;
23
+ private convertPoints2FITLap;
24
+ }
25
+ export declare class SportToTCXEncoder extends BaseSportEncoder {
26
+ name: string;
27
+ supportedTags: string[];
28
+ encode(sportData: SportFileType, context: SportEncodingContext): TCXFileType | undefined;
29
+ private convertTrack2TCXActivity;
30
+ private convertSeg2TCXLap;
31
+ private convertPoints2TCXTrack;
32
+ private convertPoint2TCXTrackpoint;
33
+ private convertRoute2TCXCourse;
34
+ }
@@ -0,0 +1,17 @@
1
+ export * from "./base.js";
2
+ export * from "./converters.js";
3
+ export * from "./encoders.js";
4
+ export * from "./processor.js";
5
+ import { GPXToSportConverter, FITToSportConverter, TCXToSportConverter } from "./converters.js";
6
+ import { SportToGPXEncoder, SportToFITEncoder, SportToTCXEncoder } from "./encoders.js";
7
+ import { SportProcessor } from "./processor.js";
8
+ declare const _default: {
9
+ GPXToSportConverter: typeof GPXToSportConverter;
10
+ FITToSportConverter: typeof FITToSportConverter;
11
+ TCXToSportConverter: typeof TCXToSportConverter;
12
+ SportToGPXEncoder: typeof SportToGPXEncoder;
13
+ SportToFITEncoder: typeof SportToFITEncoder;
14
+ SportToTCXEncoder: typeof SportToTCXEncoder;
15
+ SportProcessor: typeof SportProcessor;
16
+ };
17
+ export default _default;