trackswap 0.0.3 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  一个强大的多格式轨迹文件处理库,支持 GPX、FIT、TCX 文件的解析、编码和格式转换。
4
4
 
5
+ ---
6
+
7
+ **🌐 Language / 语言**: [English](README_EN.md) | [中文](README.md)
8
+
9
+ ---
10
+
5
11
  ## 🚀 特性
6
12
 
7
13
  - 🔄 **多格式支持**: GPX 1.1、FIT、TCX 格式
@@ -1,21 +1,16 @@
1
- import { IPlugin as ICorePlugin, IConverterPlugin as ICoreConverterPlugin, IMiddlewarePlugin as ICoreMiddlewarePlugin, BaseConverter as CoreBaseConverter, BaseMiddleware as CoreBaseMiddleware } from "../core/base.js";
1
+ import { IPlugin, IConverterPlugin, IMiddlewarePlugin, BaseConverter, BaseMiddleware } from "../core/base.js";
2
2
  import { DecoderContext, GPX11Type } from "./types.js";
3
- export interface IGPXPlugin extends ICorePlugin<DecoderContext> {
3
+ export interface IGPXPlugin extends IPlugin<DecoderContext> {
4
4
  }
5
- export interface IGPXConverterPlugin extends ICoreConverterPlugin<DecoderContext> {
5
+ export interface IGPXConverterPlugin extends IConverterPlugin<DecoderContext> {
6
6
  }
7
- export interface IGPXMiddlewarePlugin extends ICoreMiddlewarePlugin<DecoderContext, GPX11Type> {
7
+ export interface IGPXMiddlewarePlugin extends IMiddlewarePlugin<DecoderContext, GPX11Type> {
8
8
  }
9
- export declare abstract class BaseGPXConverter extends CoreBaseConverter<DecoderContext> implements IGPXConverterPlugin {
9
+ export declare abstract class BaseGPXConverter extends BaseConverter<DecoderContext> implements IGPXConverterPlugin {
10
10
  protected parseCoordinate(value: string | number | undefined): number | undefined;
11
11
  protected parseGPXTime(value: string | undefined): Date | undefined;
12
12
  protected extractNumericAttributes<U extends Record<string, any>>(ast: any, target: U, mapping: Record<string, keyof U>): void;
13
13
  }
14
- export declare abstract class BaseGPXMiddleware extends CoreBaseMiddleware<DecoderContext, GPX11Type> implements IGPXMiddlewarePlugin {
14
+ export declare abstract class BaseGPXMiddleware extends BaseMiddleware<DecoderContext, GPX11Type> implements IGPXMiddlewarePlugin {
15
15
  onError(error: Error, context: DecoderContext): Promise<void>;
16
16
  }
17
- export type IPlugin = IGPXPlugin;
18
- export type IConverterPlugin = IGPXConverterPlugin;
19
- export type IMiddlewarePlugin = IGPXMiddlewarePlugin;
20
- export declare const BaseConverter: typeof BaseGPXConverter;
21
- export declare const BaseMiddleware: typeof BaseGPXMiddleware;
@@ -1,13 +1,12 @@
1
- import { TCXDecoder } from "./decoder.js";
2
- import { TCXEncoder } from "./encoder.js";
3
1
  export { TCXDecoder } from "./decoder.js";
4
2
  export { TCXEncoder } from "./encoder.js";
5
- export { TCXFileType, TCXContext } from "./types.js";
6
- export { AstGenerateProcessor, CompleteProcessor, ConvertProcessor, IPipelineProcessor, TokenizeProcessor, PipelineStage, } from "./processor.js";
3
+ export * from "./types.js";
7
4
  export * from "./base.js";
8
5
  export * from "./converters.js";
6
+ export * from "./middleware.js";
7
+ export * from "./processor.js";
8
+ import { TCXDecoder } from "./decoder.js";
9
9
  declare const _default: {
10
10
  TCXDecoder: typeof TCXDecoder;
11
- TCXEncoder: typeof TCXEncoder;
12
11
  };
13
12
  export default _default;
@@ -1,7 +1,7 @@
1
1
  import { Token, TokenAST } from "../types.js";
2
2
  import { BaseTCXMiddleware } from "./base.js";
3
3
  import { TCXContext } from "./types.js";
4
- export declare class PerformanceMiddleware extends BaseTCXMiddleware {
4
+ export declare class TCXPerformanceMiddleware extends BaseTCXMiddleware {
5
5
  name: string;
6
6
  description: string;
7
7
  onTokenize(tokens: Token[], context: TCXContext): Promise<Token[]>;
@@ -9,10 +9,17 @@ export declare class PerformanceMiddleware extends BaseTCXMiddleware {
9
9
  onComplete(result: any, context: TCXContext): Promise<any>;
10
10
  private countNodes;
11
11
  }
12
- export declare class ValidationMiddleware extends BaseTCXMiddleware {
12
+ export declare class TCXValidationMiddleware extends BaseTCXMiddleware {
13
13
  name: string;
14
14
  description: string;
15
15
  onComplete(result: any, context: TCXContext): Promise<any>;
16
- private validateGPX;
16
+ private validateTCX;
17
17
  }
18
- export declare function registerDefaultMiddlewares(decoder: any): Promise<void>;
18
+ export declare class TCXEnhancementMiddleware extends BaseTCXMiddleware {
19
+ name: string;
20
+ description: string;
21
+ onComplete(result: any, context: TCXContext): Promise<any>;
22
+ private calculateTotalDistance;
23
+ private calculateTotalDuration;
24
+ }
25
+ export declare function registerDefaultTCXMiddlewares(decoder: any): Promise<void>;
@@ -1,30 +1,40 @@
1
1
  import { TCXContext } from "./types.js";
2
+ import { ITCXConverterPlugin } from "./base.js";
2
3
  export declare enum PipelineStage {
3
4
  TOKENIZE = "tokenize",
4
- AST_GENERATE = "ast_generate",
5
+ AST_GENERATE = "ast-generate",
5
6
  CONVERT = "convert",
6
7
  COMPLETE = "complete"
7
8
  }
8
9
  export interface IPipelineProcessor {
9
10
  stage: PipelineStage;
11
+ name: string;
10
12
  process(context: TCXContext): Promise<TCXContext>;
11
13
  }
12
14
  export declare class TokenizeProcessor implements IPipelineProcessor {
13
15
  stage: PipelineStage;
16
+ name: string;
14
17
  process(context: TCXContext): Promise<TCXContext>;
15
18
  }
16
19
  export declare class AstGenerateProcessor implements IPipelineProcessor {
17
20
  stage: PipelineStage;
21
+ name: string;
18
22
  process(context: TCXContext): Promise<TCXContext>;
23
+ private buildAST;
19
24
  }
20
25
  export declare class ConvertProcessor implements IPipelineProcessor {
21
26
  private getConverter;
22
27
  stage: PipelineStage;
23
- constructor(getConverter: (tag: string) => any);
28
+ name: string;
29
+ constructor(getConverter: (tag: string) => ITCXConverterPlugin | undefined);
24
30
  process(context: TCXContext): Promise<TCXContext>;
25
- private assignResult;
31
+ private findTCXRoot;
32
+ private convertAST;
33
+ private genericConvert;
34
+ private countElements;
26
35
  }
27
36
  export declare class CompleteProcessor implements IPipelineProcessor {
28
37
  stage: PipelineStage;
38
+ name: string;
29
39
  process(context: TCXContext): Promise<TCXContext>;
30
40
  }
@@ -186,5 +186,6 @@ export interface TCXContext extends IProcessingContext {
186
186
  astTime?: number;
187
187
  convertTime?: number;
188
188
  endTime?: number;
189
+ processingTime?: number;
189
190
  };
190
191
  }
package/dist/index.cjs ADDED
@@ -0,0 +1,26 @@
1
+ "use strict";var Je=Object.create;var G=Object.defineProperty;var Qe=Object.getOwnPropertyDescriptor;var et=Object.getOwnPropertyNames;var tt=Object.getPrototypeOf,rt=Object.prototype.hasOwnProperty;var nt=(p,e)=>{for(var t in e)G(p,t,{get:e[t],enumerable:!0})},Oe=(p,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of et(e))!rt.call(p,i)&&i!==t&&G(p,i,{get:()=>e[i],enumerable:!(r=Qe(e,i))||r.enumerable});return p};var h=(p,e,t)=>(t=p!=null?Je(tt(p)):{},Oe(e||!p||!p.__esModule?G(t,"default",{value:p,enumerable:!0}):t,p)),it=p=>Oe(G({},"__esModule",{value:!0}),p);var ht={};nt(ht,{GPXManager:()=>He,TrackSwap:()=>O,default:()=>gt});module.exports=it(ht);var y=class{constructor(){this.version="1.0.0";this.priority=100}supports(e){return this.supportedTags.includes(e)}async initialize(e){e.metadata.set(`plugin:${this.name}:initialized`,!0)}async destroy(e){e.metadata.delete(`plugin:${this.name}:initialized`)}async validate(e){return!0}parseFloat(e){return typeof e=="number"?e:typeof e=="string"&&parseFloat(e)||0}parseInt(e){return typeof e=="number"?Math.floor(e):typeof e=="string"&&parseInt(e,10)||0}parseString(e){return String(e||"")}parseBoolean(e){return typeof e=="boolean"?e:typeof e=="string"?e.toLowerCase()==="true":!1}parseDate(e){if(!e)return;let t=new Date(e);return isNaN(t.getTime())?void 0:t}hasRequiredAttributes(e,t){return t.every(r=>{var i;return(i=e.attributes)==null?void 0:i[r]})}extractAttributes(e,t,r){e.attributes&&Object.entries(e.attributes).forEach(([i,n])=>{let o=r[i];o&&o in t&&(t[o]=String(n||""))})}processChildren(e,t,r){var i;(i=e.children)==null||i.forEach(n=>{let o=r[n.tag];o&&o(n,t)})}getChildValue(e,t){var i;let r=(i=e.children)==null?void 0:i.find(n=>n.tag===t);return r!=null&&r.value?String(r.value):void 0}getChildByTag(e,t){var r;return(r=e.children)==null?void 0:r.find(i=>i.tag===t)}getChildrenByTag(e,t){var r;return((r=e.children)==null?void 0:r.filter(i=>i.tag===t))||[]}convertExtensions(e){var r;let t={};return(r=e.children)==null||r.forEach(i=>{t[i.tag]=this.convertExtensionContent(i)}),t}convertExtensionContent(e){var t;if((t=e.children)!=null&&t.length){let r={};return e.children.forEach(i=>{r[i.tag]=this.convertExtensionContent(i)}),r}else return e.value}},C=class{constructor(){this.version="1.0.0";this.description=""}async initialize(e){}async destroy(e){}async validate(e){return!0}async onTokenize(e,t){return e}async onAstGenerate(e,t){return e}async onConvert(e,t){return e}async onComplete(e,t){return e}async onError(e,t){}};var u=class extends y{parseCoordinate(e){let t=this.parseFloat(e);return t===0?void 0:t}parseGPXTime(e){if(!e)return;let t=new Date(e);return isNaN(t.getTime())?void 0:t}extractNumericAttributes(e,t,r){e.attributes&&Object.entries(e.attributes).forEach(([i,n])=>{let o=r[i];o&&o in t&&typeof n<"u"&&(t[o]=this.parseFloat(n))})}},_=class extends C{async onError(e,t){t.warnings.push(`Middleware ${this.name} error: ${e.message}`)}};var B=class extends u{constructor(){super(...arguments);this.name="wpt-converter";this.supportedTags=["wpt","trkpt","rtept"];this.version="1.0.0"}convert(t,r){if(!this.hasRequiredAttributes(t,["lat","lon"]))return;let i={lat:this.parseFloat(t.attributes.lat),lon:this.parseFloat(t.attributes.lon)};return this.extractAttributes(t,i,{lat:"lat",lon:"lon"}),this.processChildren(t,i,{ele:(n,o)=>o.ele=this.parseFloat(n.value),time:(n,o)=>o.time=new Date(this.parseString(n.value)),speed:(n,o)=>o.speed=this.parseFloat(n.value),course:(n,o)=>o.course=this.parseFloat(n.value),name:(n,o)=>o.name=this.parseString(n.value),cmt:(n,o)=>o.cmt=this.parseString(n.value),desc:(n,o)=>o.desc=this.parseString(n.value),src:(n,o)=>o.src=this.parseString(n.value),sym:(n,o)=>o.sym=this.parseString(n.value),type:(n,o)=>o.type=this.parseString(n.value),fix:(n,o)=>o.fix=this.parseString(n.value),sat:(n,o)=>o.sat=this.parseString(n.value),hdop:(n,o)=>o.hdop=this.parseFloat(n.value),vdop:(n,o)=>o.vdop=this.parseFloat(n.value),pdop:(n,o)=>o.pdop=this.parseFloat(n.value),ageofdgpsdata:(n,o)=>o.ageofdgpsdata=this.parseFloat(n.value),geoidheight:(n,o)=>o.geoidheight=this.parseFloat(n.value),magvar:(n,o)=>o.magvar=this.parseFloat(n.value),dgpsid:(n,o)=>o.dgpsid=this.parseFloat(n.value),extensions:(n,o)=>{let s=r.metadata.get("decoder");s&&(o.extensions=s.convertExtensions(n))},link:(n,o)=>{var c;o.link||(o.link=[]);let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("link"))==null?void 0:c.convert(n,r);a&&o.link&&o.link.push(a)}}),i}},H=class extends u{constructor(){super(...arguments);this.name="rte-converter";this.supportedTags=["rte"]}convert(t,r){let i={rtept:[]};return this.processChildren(t,i,{name:(n,o)=>o.name=this.parseString(n.value),cmt:(n,o)=>o.cmt=this.parseString(n.value),desc:(n,o)=>o.desc=this.parseString(n.value),src:(n,o)=>o.src=this.parseString(n.value),number:(n,o)=>o.number=this.parseFloat(n.value),type:(n,o)=>o.type=this.parseString(n.value),rtept:(n,o)=>{var c;let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("wpt"))==null?void 0:c.convert(n,r);a&&o.rtept&&o.rtept.push(a)},extensions:(n,o)=>{let s=r.metadata.get("decoder");s&&(o.extensions=s.convertExtensions(n))},link:(n,o)=>{var a;o.link||(o.link=[]);let s=r.metadata.get("decoder");(a=n.children)==null||a.forEach(c=>{var l;let d=(l=s==null?void 0:s.getConverter("link"))==null?void 0:l.convert(c,r);d&&o.link&&o.link.push(d)})}}),i}},z=class extends u{constructor(){super(...arguments);this.name="trk-converter";this.supportedTags=["trk"]}convert(t,r){let i={trkseg:[]};return this.processChildren(t,i,{name:(n,o)=>o.name=this.parseString(n.value),cmt:(n,o)=>o.cmt=this.parseString(n.value),desc:(n,o)=>o.desc=this.parseString(n.value),src:(n,o)=>o.src=this.parseString(n.value),number:(n,o)=>o.number=this.parseFloat(n.value),type:(n,o)=>o.type=this.parseString(n.value),trkseg:(n,o)=>{var c;let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("trkseg"))==null?void 0:c.convert(n,r);a&&o.trkseg&&o.trkseg.push(a)},extensions:(n,o)=>{let s=r.metadata.get("decoder");s&&(o.extensions=s.convertExtensions(n))},link:(n,o)=>{var a;o.link||(o.link=[]);let s=r.metadata.get("decoder");(a=n.children)==null||a.forEach(c=>{var l;let d=(l=s==null?void 0:s.getConverter("link"))==null?void 0:l.convert(c,r);d&&o.link&&o.link.push(d)})}}),i}},V=class extends u{constructor(){super(...arguments);this.name="trkseg-converter";this.supportedTags=["trkseg"]}convert(t,r){let i={trkpt:[]};return this.processChildren(t,i,{trkpt:(n,o)=>{var c;let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("wpt"))==null?void 0:c.convert(n,r);a&&o.trkpt&&o.trkpt.push(a)},extensions:(n,o)=>{let s=r.metadata.get("decoder");s&&(o.extensions=s.convertExtensions(n))}}),i}},U=class extends u{constructor(){super(...arguments);this.name="link-converter";this.supportedTags=["link"]}convert(t,r){var n;let i={};return(n=t.attributes)!=null&&n.href&&(i.href=t.attributes.href),this.processChildren(t,i,{text:(o,s)=>s.text=this.parseString(o.value),type:(o,s)=>s.type=this.parseString(o.value)}),i}},W=class extends u{constructor(){super(...arguments);this.name="metadata-converter";this.supportedTags=["metadata"]}convert(t,r){let i={};return this.processChildren(t,i,{name:(n,o)=>o.name=this.parseString(n.value),desc:(n,o)=>o.desc=this.parseString(n.value),keywords:(n,o)=>o.keywords=this.parseString(n.value),time:(n,o)=>o.time=new Date(this.parseString(n.value)),author:(n,o)=>{var a;let s=r.metadata.get("decoder");o.author=(a=s==null?void 0:s.getConverter("author"))==null?void 0:a.convert(n,r)},copyright:(n,o)=>{var a;let s=r.metadata.get("decoder");o.copyright=(a=s==null?void 0:s.getConverter("copyright"))==null?void 0:a.convert(n,r)},bounds:(n,o)=>{var a;let s=r.metadata.get("decoder");o.bounds=(a=s==null?void 0:s.getConverter("bounds"))==null?void 0:a.convert(n,r)},extensions:(n,o)=>{let s=r.metadata.get("decoder");s&&(o.extensions=s.convertExtensions(n))},link:(n,o)=>{var c;o.link||(o.link=[]);let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("link"))==null?void 0:c.convert(n,r);a&&o.link&&o.link.push(a)}}),i}},j=class extends u{constructor(){super(...arguments);this.name="person-converter";this.supportedTags=["author"]}convert(t,r){var n;let i={};return t.value&&!((n=t.children)!=null&&n.length)?(i.name=this.parseString(t.value),i):(this.processChildren(t,i,{name:(o,s)=>s.name=this.parseString(o.value),email:(o,s)=>{var c;let a=r.metadata.get("decoder");s.email=(c=a==null?void 0:a.getConverter("email"))==null?void 0:c.convert(o,r)},link:(o,s)=>{var c;let a=r.metadata.get("decoder");s.link=(c=a==null?void 0:a.getConverter("link"))==null?void 0:c.convert(o,r)}}),i)}},K=class extends u{constructor(){super(...arguments);this.name="email-converter";this.supportedTags=["email"]}convert(t,r){let i={};return this.processChildren(t,i,{id:(n,o)=>o.id=this.parseString(n.value),domain:(n,o)=>o.domain=this.parseString(n.value)}),i}},Y=class extends u{constructor(){super(...arguments);this.name="copyright-converter";this.supportedTags=["copyright"]}convert(t,r){var n;let i={};return(n=t.attributes)!=null&&n.author&&(i.author=t.attributes.author),this.processChildren(t,i,{year:(o,s)=>s.year=this.parseString(o.value),license:(o,s)=>s.license=this.parseString(o.value)}),i}},Z=class extends u{constructor(){super(...arguments);this.name="bounds-converter";this.supportedTags=["bounds"]}convert(t,r){let i={};return this.extractAttributes(t,i,{minlat:"minlat",minlon:"minlon",maxlat:"maxlat",maxlon:"maxlon"}),i}};var $e=require("htmlparser2"),ee=(i=>(i.TOKENIZE="tokenize",i.AST_GENERATE="ast_generate",i.CONVERT="convert",i.COMPLETE="complete",i))(ee||{}),q=class{constructor(){this.stage="tokenize"}async process(e){let t=Date.now();if(!e.xmlContent)throw new Error("XML content cannot be empty");let r=[],i=new $e.Parser({onopentag(n,o){r.push({type:"open",tag:n,attributes:o})},ontext(n){let o=n.replace(/\n/g,"").trim();o&&r.push({type:"text",tag:"text",value:o})},onclosetag(n){r.push({type:"close",tag:n})}},{xmlMode:!0});return i.write(e.xmlContent),i.end(),e.tokens=r,e.performance.tokenizeTime=Date.now()-t,e}},N=class{constructor(){this.stage="ast_generate"}async process(e){var o;let t=Date.now();if(!e.tokens)throw new Error("Tokens cannot be empty");let r=[],i,n=null;for(let s of e.tokens)if(s.type==="open"){let a={tag:s.tag,attributes:s.attributes||{},children:[]};i?n&&((o=n.children)==null||o.push(a)):i=a,r.push(a),n=a}else s.type==="text"&&n?n.value=s.value:s.type==="close"&&(r.pop(),n=r[r.length-1]||null);return e.ast=i,e.performance.astTime=Date.now()-t,e}},J=class{constructor(e){this.getConverter=e;this.stage="convert"}async process(e){var i;let t=Date.now();if(!e.ast)throw new Error("AST cannot be empty");let r={};return e.ast.attributes&&Object.entries(e.ast.attributes).forEach(([n,o])=>{n.startsWith("xmlns:")?r[n]=o.replace(/&#39;/g,"'"):n==="xsi:schemaLocation"?r[n]=o.replace(/&#39;/g,"'"):r[n]=o}),(i=e.ast.children)==null||i.forEach(n=>{let o=this.getConverter(n.tag);try{let s=o.convert(n,e);s&&this.assignResult(r,n.tag,s)}catch(s){e.errors.push(s)}}),e.result=r,e.performance.convertTime=Date.now()-t,e}assignResult(e,t,r){switch(t){case"metadata":e.metadata=r;break;case"wpt":e.wpt||(e.wpt=[]),e.wpt.push(r);break;case"rte":e.rte||(e.rte=[]),e.rte.push(r);break;case"trk":e.trk||(e.trk=[]),e.trk.push(r);break;case"extensions":e.extensions=r;break}}},Q=class{constructor(){this.stage="complete"}async process(e){e.performance.endTime=Date.now();let t=e.performance.endTime-e.performance.startTime;return e.metadata.set("performance",{totalTime:t,tokenizeTime:e.performance.tokenizeTime,astTime:e.performance.astTime,convertTime:e.performance.convertTime}),e}};var P=class{constructor(){this.converterPlugins=new Map;this.registeredPlugins=new Set;this.middlewarePlugins=[];this.processors=[];this.initialized=!1;this.defaultConvertersRegistered=!1;this.initializePipeline()}initializePipeline(){this.processors=[new q,new N,new J(e=>this.getConverter(e)),new Q]}async registerDefaultConverters(){var t;if(this.defaultConvertersRegistered)return;let e=[new B,new H,new z,new V,new U,new W,new j,new K,new Y,new Z];for(let r of e)(t=r.supportedTags)==null||t.forEach(i=>{this.addConverterForTag(i,r)}),this.registeredPlugins.add(r.name);this.defaultConvertersRegistered=!0}addConverterForTag(e,t){this.converterPlugins.has(e)||this.converterPlugins.set(e,[]);let r=this.converterPlugins.get(e);r.push(t),r.sort((i,n)=>(i.priority||100)-(n.priority||100))}async registerConverter(e){var r,n;if(this.registeredPlugins.has(e.name))throw new Error(`Converter plugin ${e.name} already exists`);(r=e.supportedTags)==null||r.forEach(o=>{this.addConverterForTag(o,e)}),this.registeredPlugins.add(e.name);let t=e.priority!==void 0?` (priority: ${e.priority})`:"";(n=e.supportedTags)==null||n.forEach(o=>{let a=(this.converterPlugins.get(o)||[]).map(c=>`${c.name}(${c.priority||100})`)})}async registerMiddleware(e){let t=this.middlewarePlugins.findIndex(i=>i.name===e.name);t!==-1?this.middlewarePlugins[t]=e:this.middlewarePlugins.push(e);let r=[];e.onTokenize&&r.push("onTokenize"),e.onAstGenerate&&r.push("onAstGenerate"),e.onConvert&&r.push("onConvert"),e.onComplete&&r.push("onComplete"),e.onError&&r.push("onError"),r.length>0}getConverter(e){let t=this.converterPlugins.get(e);return t&&t.length>0?t[0]:void 0}getAllConverters(e){return this.converterPlugins.get(e)||[]}unregisterConverter(e){let t;for(let[r,i]of this.converterPlugins){let n=i.findIndex(o=>o.name===e);n!==-1&&(t=i[n],i.splice(n,1),i.length===0&&this.converterPlugins.delete(r))}t&&this.registeredPlugins.delete(e)}unregisterMiddleware(e){let t=this.middlewarePlugins.findIndex(r=>r.name===e);t!==-1&&this.middlewarePlugins.splice(t,1)}listConverters(){return Array.from(this.converterPlugins.keys())}listConverterPlugins(){return Array.from(this.registeredPlugins)}listMiddlewares(){return this.middlewarePlugins.map(e=>e.name)}listProcessors(){return this.processors.map(e=>e.constructor.name)}getConverterDetails(e){let t={};if(e){let r=this.converterPlugins.get(e);r&&(t[e]=r.map(i=>({name:i.name,priority:i.priority||100})))}else for(let[r,i]of this.converterPlugins)t[r]=i.map(n=>({name:n.name,priority:n.priority||100}));return t}getMiddlewareDetails(){return this.middlewarePlugins.map(e=>{let t=[];return e.onTokenize&&t.push("onTokenize"),e.onAstGenerate&&t.push("onAstGenerate"),e.onConvert&&t.push("onConvert"),e.onComplete&&t.push("onComplete"),e.onError&&t.push("onError"),{name:e.name,hooks:t}})}async initialize(){var r;if(this.initialized)return;await this.registerDefaultConverters();let e=this.createContext(),t=[...Array.from(this.converterPlugins.values()).flat(),...this.middlewarePlugins];for(let i of t)try{await((r=i.initialize)==null?void 0:r.call(i,e))}catch{}this.initialized=!0}async destroy(){var r;if(!this.initialized)return;let e=this.createContext(),t=[...Array.from(this.converterPlugins.values()).flat(),...this.middlewarePlugins];for(let i of t)try{await((r=i.destroy)==null?void 0:r.call(i,e))}catch{}this.initialized=!1}createContext(){return{metadata:new Map,errors:[],warnings:[],stats:{startTime:Date.now(),processedTokens:0,convertedElements:0},performance:{startTime:Date.now()}}}async executeMiddlewareHook(e,t,r){var n;let i=t;for(let o of this.middlewarePlugins){let s=o[e];if(s)try{i=await s.call(o,i,r)||i}catch(a){r.errors.push(a),await((n=o.onError)==null?void 0:n.call(o,a,r))}}return i}async parserByBuffer(e){var r;await this.initialize();let t=this.createContext();t.rawData=e,t.xmlContent=e.toString("utf-8"),t.metadata.set("decoder",this);try{for(let i of this.processors)try{switch(t=await i.process(t),i.stage){case"tokenize":t.tokens&&(t.tokens=await this.executeMiddlewareHook("onTokenize",t.tokens,t));break;case"ast_generate":t.ast&&(t.ast=await this.executeMiddlewareHook("onAstGenerate",t.ast,t));break;case"convert":t.result&&(t.result=await this.executeMiddlewareHook("onConvert",t.result,t));break;case"complete":t.result&&(t.result=await this.executeMiddlewareHook("onComplete",t.result,t));break}}catch(n){t.errors.push(n);for(let o of this.middlewarePlugins)await((r=o.onError)==null?void 0:r.call(o,n,t))}return t.result}catch(i){throw i}}convertExtensions(e){var o,s;let t={},{attributes:r,tag:i,value:n}=e;if(r&&Object.entries(r).forEach(([a,c])=>{t[a]=c}),(o=e==null?void 0:e.children)!=null&&o.length)(s=e.children)==null||s.forEach(a=>{t[a.tag]=this.convertExtensions(a)});else if(n!==void 0)return n;return t}};var ke=h(require("dayjs")),Ge=h(require("dayjs/plugin/utc.js"));var be={temperature:"atemp",wtemp:"wtemp",heartRate:"hr",cadence:"cad"};var Ie={temperature:"Temperature",Depth:"Depth"};ke.default.extend(Ge.default);var E=class{constructor(e={}){this.formatElevation=e=>{let t=parseFloat(e);return isNaN(t)?e:this.roundTo(t,2).toString()};this.compact=e.compact??!0}async encode(e){let t=this.buildGPXXML(e);return Buffer.from(t,"utf-8")}encodeToString(e){return this.buildGPXXML(e)}buildGPXXML(e){let t=this.buildXMLHeader(),r=this.buildGPXContent(e),n=`${t}${r}
2
+ </gpx>`;return this.compact?this.compressXML(n):n}compressXML(e){return e.replace(/>\s+</g,"><").replace(/^\s+|\s+$/gm,"").replace(/\s+/g," ").trim()}buildXMLHeader(){return['<?xml version="1.0" encoding="UTF-8"?>','<gpx creator="https://gpxonline.net" version="1.1"',' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"',' xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd'," http://www.garmin.com/xmlschemas/GpxExtensions/v3 http://www.garmin.com/xmlschemas/GpxExtensionsv3.xsd"," http://www.garmin.com/xmlschemas/TrackPointExtension/v1 http://www.garmin.com/xmlschemas/TrackPointExtensionv1.xsd"," http://www.garmin.com/xmlschemas/PowerExtension/v1 http://www.garmin.com/xmlschemas/PowerExtensionv1.xsd",' http://www.topografix.com/GPX/gpx_style/0/2 http://www.topografix.com/GPX/gpx_style/0/2/gpx_style.xsd"',' xmlns:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1"',' xmlns:gpxx="http://www.garmin.com/xmlschemas/GpxExtensions/v3"',' xmlns:gpxpx="http://www.garmin.com/xmlschemas/PowerExtension/v1"',' xmlns:gpx_style="http://www.topografix.com/GPX/gpx_style/0/2"',' xmlns="http://www.topografix.com/GPX/1/1">'].join(`
3
+ `)}buildGPXContent(e){let{metadata:t,wpt:r=[],rte:i=[],trk:n=[]}=e,o=[];return t&&o.push(this.buildMetadata(t)),r.forEach(s=>{o.push(this.buildWaypoint(s,"wpt"))}),i.forEach(s=>{o.push(this.buildRoute(s))}),n.forEach(s=>{o.push(this.buildTrack(s))}),o.join(`
4
+ `)}buildMetadata(e){let t=["<metadata>"];return this.addOptionalElement(t,"name",e.name),this.addOptionalElement(t,"desc",e.desc),e.author&&t.push(this.buildAuthor(e.author)),e.copyright&&t.push(this.buildCopyright(e.copyright)),e.link&&this.addLinks(t,e.link),e.time&&t.push(this.buildTimeElement(e.time)),this.addOptionalElement(t,"keywords",e.keywords),e.bounds&&t.push(this.buildBounds(e.bounds)),e.extensions&&t.push(this.buildExtensions(e.extensions)),t.push("</metadata>"),t.join(`
5
+ `)}buildAuthor(e){let t=["<author>"];return this.addOptionalElement(t,"name",e.name),e.email&&t.push(`<email id="${this.escapeXML(e.email.id||"")}" domain="${this.escapeXML(e.email.domain||"")}"/>`),e.link&&t.push(this.buildLink(e.link)),t.push("</author>"),t.join(`
6
+ `)}buildCopyright(e){let t=[`<copyright author="${this.escapeXML(e.author||"")}">`];return this.addOptionalElement(t,"year",e.year),this.addOptionalElement(t,"license",e.license),t.push("</copyright>"),t.join(`
7
+ `)}buildBounds(e){let t=this.escapeXMLAttribute((e.minlat||0).toString()),r=this.escapeXMLAttribute((e.minlon||0).toString()),i=this.escapeXMLAttribute((e.maxlat||0).toString()),n=this.escapeXMLAttribute((e.maxlon||0).toString());return`<bounds minlat="${t}" minlon="${r}" maxlat="${i}" maxlon="${n}"/>`}buildWaypoint(e,t){var i,n,o;if(!this.isValidCoordinate(e.lat,e.lon))return"";let r=[`<${t} lat="${this.escapeXMLAttribute(this.formatCoordinate(e.lat))}" lon="${this.escapeXMLAttribute(this.formatCoordinate(e.lon))}">`];if(this.addOptionalElement(r,"ele",(i=e.ele)==null?void 0:i.toString(),this.formatElevation),e.time&&r.push(this.buildTimeElement(e.time)),this.addOptionalElement(r,"speed",(n=e.speed)==null?void 0:n.toString()),this.addOptionalElement(r,"course",(o=e.course)==null?void 0:o.toString()),this.addStandardWaypointElements(r,e),e.extensions){let s=this.processPointExtensions(e,e.extensions);Object.keys(s).length>0&&r.push(this.buildExtensions(s))}return r.push(`</${t}>`),r.join(`
8
+ `)}addStandardWaypointElements(e,t){var r,i,n,o,s,a,c;this.addOptionalElement(e,"magvar",(r=t.magvar)==null?void 0:r.toString()),this.addOptionalElement(e,"geoidheight",(i=t.geoidheight)==null?void 0:i.toString()),this.addOptionalElement(e,"name",t.name),this.addOptionalElement(e,"cmt",t.cmt),this.addOptionalElement(e,"desc",t.desc),this.addOptionalElement(e,"src",t.src),t.link&&this.addLinks(e,t.link),this.addOptionalElement(e,"sym",t.sym),this.addOptionalElement(e,"type",t.type),this.addOptionalElement(e,"fix",t.fix),this.addOptionalElement(e,"sat",t.sat),this.addOptionalElement(e,"hdop",(n=t.hdop)==null?void 0:n.toString()),this.addOptionalElement(e,"vdop",(o=t.vdop)==null?void 0:o.toString()),this.addOptionalElement(e,"pdop",(s=t.pdop)==null?void 0:s.toString()),this.addOptionalElement(e,"ageofdgpsdata",(a=t.ageofdgpsdata)==null?void 0:a.toString()),this.addOptionalElement(e,"dgpsid",(c=t.dgpsid)==null?void 0:c.toString())}buildRoute(e){var r;let t=["<rte>"];return this.addRouteTrackCommonElements(t,e),e.rtept&&((r=e.rtept)==null||r.forEach(i=>{t.push(this.buildWaypoint(i,"rtept"))})),e.extensions&&t.push(this.buildExtensions(e.extensions)),t.push("</rte>"),t.join(`
9
+ `)}buildTrack(e){let t=["<trk>"];return this.addRouteTrackCommonElements(t,e),e.trkseg&&e.trkseg.forEach(r=>{t.push(this.buildTrackSegment(r))}),e.extensions&&t.push(this.buildExtensions(e.extensions)),t.push("</trk>"),t.join(`
10
+ `)}buildTrackSegment(e){let t=["<trkseg>"];return e.trkpt&&e.trkpt.forEach(r=>{t.push(this.buildWaypoint(r,"trkpt"))}),e.extensions&&t.push(this.buildExtensions(e.extensions)),t.push("</trkseg>"),t.join(`
11
+ `)}addRouteTrackCommonElements(e,t){var r;this.addOptionalElement(e,"name",t.name),this.addOptionalElement(e,"cmt",t.cmt),this.addOptionalElement(e,"desc",t.desc),this.addOptionalElement(e,"src",t.src),t.link&&this.addLinks(e,t.link),this.addOptionalElement(e,"number",(r=t.number)==null?void 0:r.toString()),this.addOptionalElement(e,"type",t.type)}processPointExtensions(e,t){let r=this.deepClone(t),i=this.buildTrackPointExtension(e,t);Object.keys(i).length>0&&(r["gpxtpx:TrackPointExtension"]=i);let n=this.buildPowerExtension(e,t);Object.keys(n).length>0&&(r["gpxpx:PowerExtension"]=n);let o=this.buildGpxExtensions(e,t);return Object.keys(o).length>0&&(r["gpxx:GpxExtensions"]=o),r}buildTrackPointExtension(e,t){let r=this.deepClone(t["gpxtpx:TrackPointExtension"]||{}),i=Object.keys(be);return Object.keys(e).filter(n=>i.includes(n)).forEach(n=>{let o=be[n];o&&e[n]!==void 0&&(r[`gpxtpx:${o}`]=e[n])}),r}buildPowerExtension(e,t){return this.deepClone(t["gpxpx:PowerExtension"]||{})}buildGpxExtensions(e,t){let r=this.deepClone(t["gpxx:GpxExtensions"]||{}),i=Object.keys(Ie);return Object.keys(e).filter(n=>i.includes(n)).forEach(n=>{let o=Ie[n];o&&e[n]!==void 0&&(r[`gpxx:${o}`]=e[n])}),r}buildExtensions(e){let t=this.buildExtensionContent(e);return t?`<extensions>${t}</extensions>`:""}buildExtensionContent(e){return Object.entries(e).filter(([t])=>!t.startsWith("xmlns")).map(([t,r])=>{if(r&&typeof r=="object"){let i=this.buildExtensionContent(r);return`<${t}>${i}</${t}>`}else if(r!=null)return`<${t}>${this.escapeXML(String(r))}</${t}>`;return""}).filter(t=>t).join("")}buildLink(e){let t=[`<link href="${this.escapeXMLAttribute(e.href||"")}">`];return this.addOptionalElement(t,"text",e.text),this.addOptionalElement(t,"type",e.type),t.push("</link>"),t.join("")}addLinks(e,t){(Array.isArray(t)?t:[t]).forEach(i=>{e.push(this.buildLink(i))})}buildTimeElement(e){return typeof e=="string"&&/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z?$/.test(e)?`<time>${e}</time>`:`<time>${(0,ke.default)(e).utc().format("YYYY-MM-DDTHH:mm:ss[Z]")}</time>`}addOptionalElement(e,t,r,i){if(r!=null&&r!==""){let n=i?i(r):this.escapeXML(r);e.push(`<${t}>${n}</${t}>`)}}isValidCoordinate(e,t){return e!=null&&t!==void 0&&t!==null&&!isNaN(e)&&!isNaN(t)}formatCoordinate(e){return this.roundTo(e,6).toString()}roundTo(e,t){let r=Math.pow(10,t);return Math.round(e*r)/r}escapeXML(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;")}escapeXMLAttribute(e){return typeof e!="string"?String(e||""):e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/'/g,"&apos;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/\r/g,"&#13;").replace(/\n/g,"&#10;").replace(/\t/g,"&#9;")}deepClone(e){if(e===null||typeof e!="object")return e;if(e instanceof Date)return new Date(e.getTime());if(Array.isArray(e))return e.map(r=>this.deepClone(r));let t={};for(let r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=this.deepClone(e[r]));return t}encoder(e){return this.encode(e)}};var Fe=class extends _{constructor(){super(...arguments);this.name="performance-middleware";this.description="Monitor parsing performance"}async onTokenize(t,r){return t}async onAstGenerate(t,r){let i=this.countNodes(t);return t}async onComplete(t,r){let i=r.metadata.get("performance");return t}countNodes(t){let r=1;if(t.children)for(let i of t.children)r+=this.countNodes(i);return r}},Ae=class extends _{constructor(){super(...arguments);this.name="validation-middleware";this.description="Validate GPX data integrity"}async onComplete(t,r){let i=this.validateGPX(t);return i.length>0&&r.metadata.set("validation-errors",i),t}validateGPX(t){let r=[];if(t.version||r.push("Missing GPX version information"),t.creator||r.push("Missing GPX creator information"),t.trk){for(let i of t.trk)if(i.trkseg){for(let n of i.trkseg)if(n.trkpt)for(let o of n.trkpt)(typeof o.lat!="number"||typeof o.lon!="number")&&r.push("Invalid track point coordinates")}}return r}};async function Be(p){let e=[new Fe,new Ae];for(let t of e)await p.registerMiddleware(t)}var He={GPXDecoder:P,GPXEncoder:E,registerDefaultMiddlewares:Be,PipelineStage:ee};var te=class{constructor(){this.stage="parse"}async process(e){let t=Date.now();if(!e.rawData)throw new Error("FIT data cannot be empty");try{let r=await this.parseWithFitSDK(e.rawData);return e.rawMessages=r,e.performance.parseTime=Date.now()-t,e}catch(r){throw new Error(`FIT parsing failed: ${r.message}`)}}async parseWithFitSDK(e){let{Decoder:t,Stream:r}=await import("@garmin/fitsdk"),i=r.fromBuffer(e);if(!t.isFIT(i))throw new Error("Not a valid FIT file");let n=new t(i),{messages:o,errors:s}=n.read();return s&&s.length>0,o}},re=class{constructor(e){this.getConverters=e;this.stage="extract"}async process(e){let t=Date.now();if(!e.rawMessages)throw new Error("Raw messages cannot be empty");let r={};for(let[i,n]of Object.entries(e.rawMessages)){if(!Array.isArray(n)||n.length===0){r[i]=n;continue}let o=this.getConverters(i);if(o.length===0)r[i]=n;else{let s=o[0];try{let a=s.convertMessages(n,e);r[i]=a}catch(a){e.errors.push(a),r[i]=n}}}return e.rawMessages=r,e.performance.extractTime=Date.now()-t,e}},ne=class{constructor(e){this.getStructurePlugins=e;this.stage="structure"}async process(e){let t=Date.now();if(!e.rawMessages)throw new Error("Message data cannot be empty");let r={},i=this.getStructurePlugins();for(let n of i)try{let o=n.structureData(e.rawMessages,e);r={...r,...o}}catch(o){e.errors.push(o)}return e.result=r,e.performance.structureTime=Date.now()-t,e}},ie=class{constructor(){this.stage="complete"}async process(e){e.performance.endTime=Date.now();let t=e.performance.endTime-e.performance.startTime;return e.metadata.set("performance",{totalTime:t,parseTime:e.performance.parseTime,extractTime:e.performance.extractTime,structureTime:e.performance.structureTime}),e.stats&&(e.stats.endTime=Date.now(),e.rawMessages&&(e.stats.processedTokens=this.countTotalMessages(e.rawMessages))),e}countTotalMessages(e){let t=0;return Object.values(e).forEach(r=>{Array.isArray(r)&&(t+=r.length)}),t}};var m=h(require("dayjs"));var v=class{constructor(){this.version="1.0.0";this.priority=100}async initialize(e){e.metadata.set(`plugin:${this.name}:initialized`,!0)}async destroy(e){e.metadata.delete(`plugin:${this.name}:initialized`)}async validate(e){return!0}};var X=class extends v{constructor(){super(...arguments);this.name="SessionStructurePlugin";this.priority=10}structureData(t,r){let{sessionMesgs:i,lapMesgs:n,recordMesgs:o}=t;return i!=null&&i.length?{sessionMesgs:i.map(a=>{let c=(0,m.default)(a.startTime).valueOf(),d=(0,m.default)(a.timestamp).valueOf(),f=((n==null?void 0:n.filter(g=>{let A=(0,m.default)(g.startTime).valueOf(),D=(0,m.default)(g.timestamp).valueOf();return A>=c&&D<=d}))||[]).map(g=>{let A=(0,m.default)(g.startTime).valueOf(),D=(0,m.default)(g.timestamp).valueOf(),$=(o==null?void 0:o.filter(Ne=>{let Le=(0,m.default)(Ne.timestamp).valueOf();return Le>=A&&Le<=D}))||[];return{...g,recordMesgs:$}});return{...a,lapMesgs:f}})}:{}}},R=class extends v{constructor(){super(...arguments);this.name="CourseStructurePlugin";this.priority=10}structureData(t,r){let{courseMesgs:i,lapMesgs:n,recordMesgs:o}=t;if(!(i!=null&&i.length))return{};let s=2e3;return{courseMesgs:i.map(c=>{let d=(n==null?void 0:n.map(l=>{let f=(0,m.default)(l.startTime).valueOf(),g=(0,m.default)(l.timestamp).valueOf(),A=(o==null?void 0:o.filter(D=>{let $=(0,m.default)(D.timestamp).valueOf();return $>=f-s&&$<=g+s}))||[];return{...l,recordMesgs:A}}))||[];return{...c,lapMesgs:d}})}}},M=class extends v{constructor(){super(...arguments);this.name="FileHeaderPlugin";this.priority=1}structureData(t,r){let{fileIdMesgs:i}=t;if(i!=null&&i.length&&i[0]){let n=i[0];r.fileHeader={type:n.type,manufacturer:n.manufacturer,product:n.product}}return{}}};var w=class{constructor(){this.converterPlugins=new Map;this.registeredPlugins=new Set;this.structurePlugins=[];this.middlewarePlugins=[];this.processors=[];this.initialized=!1;this.defaultPluginsRegistered=!1;this.initializePipeline()}initializePipeline(){this.processors=[new te,new re(e=>this.getConverters(e)),new ne(()=>this.structurePlugins),new ie]}async registerDefaultPlugins(){if(this.defaultPluginsRegistered)return;let e=[new M,new X,new R];for(let t of e)this.addStructurePlugin(t),this.registeredPlugins.add(t.name);this.defaultPluginsRegistered=!0}addConverterForMessageType(e,t){this.converterPlugins.has(e)||this.converterPlugins.set(e,[]);let r=this.converterPlugins.get(e);r.push(t),r.sort((i,n)=>(i.priority||100)-(n.priority||100))}addStructurePlugin(e){this.structurePlugins.push(e),this.structurePlugins.sort((t,r)=>(t.priority||100)-(r.priority||100))}async registerMessageConverter(e){if(this.registeredPlugins.has(e.name))throw new Error(`Message converter plugin ${e.name} already exists`);e.supportedMessageTypes.forEach(r=>{this.addConverterForMessageType(r,e)}),this.registeredPlugins.add(e.name);let t=e.priority!==void 0?` (priority: ${e.priority})`:"";e.supportedMessageTypes.forEach(r=>{let n=(this.converterPlugins.get(r)||[]).map(o=>`${o.name}(${o.priority||100})`)})}async registerStructurePlugin(e){if(this.registeredPlugins.has(e.name))throw new Error(`Structure plugin ${e.name} already exists`);this.addStructurePlugin(e),this.registeredPlugins.add(e.name);let t=e.priority!==void 0?` (priority: ${e.priority})`:""}async registerMiddleware(e){let t=this.middlewarePlugins.findIndex(i=>i.name===e.name);t!==-1?this.middlewarePlugins[t]=e:(this.middlewarePlugins.push(e),this.middlewarePlugins.sort((i,n)=>(i.priority||100)-(n.priority||100)));let r=[];e.onParse&&r.push("onParse"),e.onExtractMessages&&r.push("onExtractMessages"),e.onStructure&&r.push("onStructure"),e.onComplete&&r.push("onComplete"),e.onError&&r.push("onError"),r.length>0}getConverter(e){let t=this.converterPlugins.get(e);return t&&t.length>0?t[0]:void 0}getConverters(e){return this.converterPlugins.get(e)||[]}unregisterPlugin(e){if(!this.registeredPlugins.has(e))return!1;for(let[i,n]of this.converterPlugins){let o=n.findIndex(s=>s.name===e);o!==-1&&(n.splice(o,1),n.length===0&&this.converterPlugins.delete(i))}let t=this.structurePlugins.findIndex(i=>i.name===e);t!==-1&&this.structurePlugins.splice(t,1);let r=this.middlewarePlugins.findIndex(i=>i.name===e);return r!==-1&&this.middlewarePlugins.splice(r,1),this.registeredPlugins.delete(e),!0}async initialize(){var r;if(this.initialized)return;await this.registerDefaultPlugins();let e=this.createContext(),t=[...Array.from(this.converterPlugins.values()).flat(),...this.structurePlugins,...this.middlewarePlugins];for(let i of t)try{await((r=i.initialize)==null?void 0:r.call(i,e))}catch{}this.initialized=!0}async destroy(){var r;if(!this.initialized)return;let e=this.createContext(),t=[...Array.from(this.converterPlugins.values()).flat(),...this.structurePlugins,...this.middlewarePlugins];for(let i of t)try{await((r=i.destroy)==null?void 0:r.call(i,e))}catch{}this.initialized=!1}createContext(){return{metadata:new Map,errors:[],warnings:[],stats:{startTime:Date.now(),processedTokens:0,convertedElements:0},performance:{startTime:Date.now()}}}async executeMiddlewareHook(e,t,r){var n;let i=t;for(let o of this.middlewarePlugins){let s=o[e];if(s)try{i=await s.call(o,i,r)||i}catch(a){r.errors.push(a),await((n=o.onError)==null?void 0:n.call(o,a,r))}}return i}async parseByBuffer(e,t={}){var i;await this.initialize();let r=this.createContext();r.rawData=e,r.userData=t.userData,r.metadata.set("decoder",this);try{for(let n of this.processors)try{switch(r=await n.process(r),n.stage){case"parse":r.rawData&&(r.rawData=await this.executeMiddlewareHook("onParse",r.rawData,r));break;case"extract":r.rawMessages&&(r.rawMessages=await this.executeMiddlewareHook("onExtractMessages",r.rawMessages,r));break;case"structure":r.result&&(r.result=await this.executeMiddlewareHook("onStructure",r.result,r));break;case"complete":r.result&&(r.result=await this.executeMiddlewareHook("onComplete",r.result,r));break}}catch(o){r.errors.push(o);for(let s of this.middlewarePlugins)await((i=s.onError)==null?void 0:i.call(s,o,r))}return r.result||{}}catch(n){throw n}}};var ot={file:{course:6,device:1,settings:2,sport:3,activity:4,workout:5,schedules:7,weight:9,totals:10,goals:11,blood_pressure:14,monitoring_a:15,activity_summary:20,monitoring_daily:28,monitoring_b:32,segment_list:35,exd_configuration:40,invalid:0},sport:{generic:0,running:1,cycling:2,transition:3,fitness_equipment:4,swimming:5,basketball:6,soccer:7,tennis:8,american_football:9,training:10,walking:11,cross_country_skiing:12,alpine_skiing:13,snowboarding:14,rowing:15,mountaineering:16,hiking:17,multisport:18,paddling:19,invalid:254},event:{timer:0,workout:3,workout_step:4,power_down:5,power_up:6,off_course:7,session:8,lap:9,course_point:10,battery:11,virtual_partner_pace:12,hr_high_alert:13,hr_low_alert:14,speed_high_alert:15,speed_low_alert:16,cad_high_alert:17,cad_low_alert:18,power_high_alert:19,power_low_alert:20,recovery_hr:21,battery_low:22,time_duration_alert:23,distance_duration_alert:24,calorie_duration_alert:25,activity:26,fitness_equipment:27,length:28,user_marker:32,sport_point:33,calibration:36,front_gear_change:42,rear_gear_change:43,rider_position_change:44,elev_high_alert:45,elev_low_alert:46,comm_timeout:47,invalid:255},event_type:{start:0,stop:1,consecutive_depreciated:2,marker:3,stop_all:4,begin_depreciated:5,end_depreciated:6,end_all_depreciated:7,stop_disable:8,stop_disable_all:9,invalid:255},course_point:{generic:0,summit:1,valley:2,water:3,food:4,danger:5,left:6,right:7,straight:8,first_aid:9,fourth_category:10,third_category:11,second_category:12,first_category:13,hors_category:14,sprint:15,left_fork:16,right_fork:17,middle_fork:18,slight_left:19,sharp_left:20,slight_right:21,sharp_right:22,u_turn:23,segment_start:24,segment_end:25,invalid:255}},x=p=>{let e=ot[p];return{size:1,baseType:0,mapValue:t=>typeof t=="string"?e[t]??255:t,setValue:function(t,r){this.setUint8(t,r)}}},De={enum_file:x("file"),enum_activity:x("sport"),enum_sport:x("sport"),enum_sub_sport:x("sport"),enum_event:x("event"),enum_event_type:x("event_type"),enum_course_point:x("course_point"),uint8:{size:1,baseType:2,setValue:DataView.prototype.setUint8},sint8:{size:1,baseType:1,setValue:DataView.prototype.setInt8},uint16:{size:2,baseType:132,setValue:DataView.prototype.setUint16},sint16:{size:2,baseType:131,setValue:DataView.prototype.setInt16},uint32:{size:4,baseType:134,setValue:DataView.prototype.setUint32},sint32:{size:4,baseType:133,setValue:DataView.prototype.setInt32},string:{size:0,baseType:7,mapValue:p=>Array.from(Ve(p)),setValue:at},distance:{size:4,baseType:134,setValue:DataView.prototype.setUint32,mapValue:p=>Math.round(p*1e3)},speed:{size:2,baseType:132,setValue:DataView.prototype.setUint16,mapValue:p=>Math.round(p*100)},altitude:{size:2,baseType:132,setValue:DataView.prototype.setUint16,mapValue:p=>Math.round((p+500)*5)},seconds:{size:4,baseType:134,setValue:DataView.prototype.setUint32,mapValue:p=>Math.round(p*1e3)},date_time:{size:4,baseType:134,setValue:DataView.prototype.setUint32,mapValue:p=>{let e;return p instanceof Date?(e=Math.floor(p.getTime()/1e3),e-631065600):typeof p=="string"?(e=Math.floor(new Date(p).getTime()/1e3),e-631065600):p<631065600?Math.floor(p):(p>9999999999?e=Math.floor(p/1e3):e=Math.floor(p),e-631065600)}},semicircles:{size:4,baseType:133,setValue:DataView.prototype.setInt32,mapValue:p=>Math.round(p/180*2147483648)}};function ze(p){return Array.from(Ve(p)).length+1}function*Ve(p){for(let e of st(p))e<128?yield e:e<2048?(yield 192|e>>6,yield 128|e&63):e<65536?(yield 224|e>>12,yield 128|e>>6&63,yield 128|e&63):(yield 240|e>>18,yield 128|e>>12&63,yield 128|e>>6&63,yield 128|e&63);yield 0}function*st(p){for(let e=0;e<p.length;){let t=p.codePointAt(e);if(t===void 0)break;yield t,e+=t>65535?2:1}}function at(p,e){for(let t=0;t<e.length;t++)this.setUint8(p+t,e[t])}var pt={file_id:{mesgNum:0,fieldDefns:[{name:"type",number:0,type:"enum_file"},{name:"time_created",number:4,type:"date_time"}]},session:{mesgNum:18,fieldDefns:[{name:"timestamp",number:253,type:"date_time"},{name:"start_time",number:2,type:"date_time"},{name:"total_elapsed_time",number:7,type:"seconds"},{name:"total_timer_time",number:8,type:"seconds"},{name:"start_position_lat",number:3,type:"semicircles"},{name:"start_position_long",number:4,type:"semicircles"},{name:"total_distance",number:9,type:"distance"},{name:"total_ascent",number:21,type:"uint16"},{name:"total_descent",number:22,type:"uint16"},{name:"sport",number:5,type:"enum_sport"},{name:"sub_sport",number:6,type:"enum_sub_sport"},{name:"first_lap_index",number:11,type:"uint16"},{name:"num_laps",number:26,type:"uint16"}]},lap:{mesgNum:19,fieldDefns:[{name:"timestamp",number:253,type:"date_time"},{name:"start_time",number:2,type:"date_time"},{name:"start_position_lat",number:3,type:"semicircles"},{name:"start_position_long",number:4,type:"semicircles"},{name:"end_position_lat",number:5,type:"semicircles"},{name:"end_position_long",number:6,type:"semicircles"},{name:"total_elapsed_time",number:7,type:"seconds"},{name:"total_timer_time",number:8,type:"seconds"},{name:"total_distance",number:9,type:"distance"},{name:"total_ascent",number:21,type:"uint16"},{name:"total_descent",number:22,type:"uint16"}]},record:{mesgNum:20,fieldDefns:[{name:"timestamp",number:253,type:"date_time"},{name:"position_lat",number:0,type:"semicircles"},{name:"position_long",number:1,type:"semicircles"},{name:"altitude",number:2,type:"altitude"},{name:"distance",number:5,type:"distance"},{name:"heart_rate",number:3,type:"uint8"},{name:"cadence",number:4,type:"uint8"},{name:"speed",number:6,type:"speed"},{name:"power",number:7,type:"uint16"}]},event:{mesgNum:21,fieldDefns:[{name:"timestamp",number:253,type:"date_time"},{name:"event",number:0,type:"enum_event"},{name:"event_type",number:1,type:"enum_event_type"},{name:"event_group",number:4,type:"uint8"}]},course:{mesgNum:31,fieldDefns:[{name:"name",number:5,type:"string"},{name:"sport",number:4,type:"enum_sport"},{name:"sub_sport",number:7,type:"enum_sub_sport"}]},activity:{mesgNum:34,fieldDefns:[{name:"timestamp",number:253,type:"date_time"},{name:"total_timer_time",number:0,type:"seconds"},{name:"num_sessions",number:1,type:"uint16"},{name:"type",number:2,type:"enum_activity"},{name:"event",number:3,type:"enum_event"},{name:"event_type",number:4,type:"enum_event_type"},{name:"local_timestamp",number:5,type:"date_time"},{name:"event_group",number:6,type:"uint8"}]},course_point:{mesgNum:32,fieldDefns:[{name:"timestamp",number:1,type:"date_time"},{name:"position_lat",number:2,type:"semicircles"},{name:"position_long",number:3,type:"semicircles"},{name:"distance",number:4,type:"distance"},{name:"type",number:5,type:"enum_course_point"}]}},ct=(p,e)=>p.map(t=>({...t,value:e[t.name]})).filter(({value:t})=>t!==void 0),oe=class p{static check(e,t,r,i){if(t===void 0)throw new Error(`Message '${e}' not known`);if(r===void 0)throw new Error(`Message '${e}' has no field definitions`);let n=r.map(s=>s.name),o=Object.keys(i).filter(s=>!n.includes(s));if(o.length)throw new Error(`Message '${e}' has no field definitions named '${o}'`)}constructor(e,t,r){let i=pt[t];if(!i)throw new Error(`Unknown message type: ${t}`);let{mesgNum:n,fieldDefns:o}=i;p.check(t,n,o,r),this.localNum=e,this.mesgNum=n,this.fields=ct(o,r)}get mesgDefn(){let e=this.fields.map(({number:t,type:r,value:i})=>{let n=De[r];if(!n)throw new Error(`Unknown type: ${r}`);let{size:o,baseType:s}=n;return r==="string"?{number:t,size:ze(i),baseType:s}:{number:t,size:o,baseType:s}});return{localNum:this.localNum,mesgNum:this.mesgNum,fieldDefns:e}}isSameDefn(e){let t=(s,a)=>s.number===a.number&&s.size===a.size&&s.baseType===a.baseType,r=(s,a)=>s.length===a.length&&s.every((c,d)=>t(c,a[d])),{localNum:i,mesgNum:n,fieldDefns:o}=this.mesgDefn;return n===e.mesgNum&&i===e.localNum&&r(o,e.fieldDefns)}get defnRecord(){let{localNum:e,mesgNum:t,fieldDefns:r}=this.mesgDefn,i=6+3*r.length,n=new DataView(new ArrayBuffer(i));n.setUint8(0,64|e),n.setUint8(2,1),n.setUint16(3,t),n.setUint8(5,r.length);let o=6;for(let s of r)n.setUint8(o++,s.number),n.setUint8(o++,s.size),n.setUint8(o++,s.baseType);return n.buffer}get dataRecord(){let{fieldDefns:e}=this.mesgDefn,t=1+e.reduce((n,{size:o})=>n+o,0),r=new DataView(new ArrayBuffer(t));r.setUint8(0,this.localNum);let i=1;for(let{number:n,type:o,value:s}of this.fields){let a=De[o];if(!a)throw new Error(`Unknown type: ${o}`);let{size:c,setValue:d}=a,l;"mapValue"in a?l=a.mapValue(s):l=s,d&&d.call(r,i,l),i+=c}return r.buffer}};var dt=[0,52225,55297,5120,61441,15360,10240,58369,40961,27648,30720,46081,20480,39937,34817,17408],Ue=(p,e)=>(p>>>4^dt[p&15^e])&65535,lt=(p,e,t)=>Ue(Ue(p,e),t),ut=(p,e)=>lt(p,e&15,e>>>4);function _e(p,e=0){let t=e,r=p instanceof ArrayBuffer?new Uint8Array(p):p;for(let i=0;i<r.length;i++)t=ut(t,r[i]);return t}var je=h(require("dayjs")),We=14,mt=16,Tt=2078,ft=776358228,S=class{constructor(e={}){this.localNum={};this.mesgDefn=[];this.messages=[];this.options={compact:e.compact??!0,defaultSport:e.defaultSport??"cycling",defaultSubSport:e.defaultSubSport??"generic"}}async encode(e){return this.reset(),this.buildFITContent(e,"activity"),Buffer.from(await this.blob.arrayBuffer())}async encodeCourse(e){return this.reset(),this.buildFITContent(e,"course"),Buffer.from(await this.blob.arrayBuffer())}async encodeToBlob(e,t="activity"){return this.reset(),this.buildFITContent(e,t),this.blob}reset(){this.localNum={},this.mesgDefn=[],this.messages=[]}buildFITContent(e,t){this.buildFileId(e,t),t==="course"?this.buildCourseContent(e):this.buildActivityContent(e)}buildActivityContent(e){let t=e.sessionMesgs||[];if(t.length===0)throw new Error("Activity file must contain at least one Session");let r=0,i=[],n=[];for(let o of t){if(o.lapMesgs&&this.buildEventsFromLaps(o.lapMesgs,i),o.lapMesgs)for(let s of o.lapMesgs)s.recordMesgs&&this.buildRecords(s.recordMesgs);o.lapMesgs&&this.buildLaps(o.lapMesgs),this.buildSession(o),r++,this.buildActivityFromSession(o,n)}i.forEach(o=>this.buildEvent(o)),n.forEach(o=>this.buildActivity(o))}buildCourseContent(e){let t=e.sessionMesgs||[];if(t.length===0)throw new Error("Course file must contain track data");let r=t[0];if(this.buildCourse({name:"course",sport:this.options.defaultSport}),r.lapMesgs){let i=[];for(let s of r.lapMesgs)s.recordMesgs&&i.push(...s.recordMesgs);i.sort((s,a)=>s.timestamp&&a.timestamp?new Date(s.timestamp).getTime()-new Date(a.timestamp).getTime():(s.distance||0)-(a.distance||0));let n=i[0],o=i[i.length-1];n.timestamp&&this.buildEvent({timestamp:n.timestamp,event:"timer",eventType:"start",eventGroup:0}),i.forEach(s=>this.buildRecord(s)),o.timestamp&&this.buildEvent({timestamp:o.timestamp,event:"timer",eventType:"stop_all",eventGroup:0}),r.lapMesgs[0]&&this.buildLap(r.lapMesgs[0])}}buildFileId(e,t){var i;let r=((i=e.fileIdMesgs)==null?void 0:i[0])||{};this.writeMesg("file_id",{type:t,time_created:r.timeCreated?this.parseTimestamp(r.timeCreated):Date.now(),manufacturer:r.manufacturer,product:r.product,serial_number:r.serialNumber})}buildSession(e){var t;this.writeMesg("session",{timestamp:e.timestamp?this.parseTimestamp(e.timestamp):void 0,start_time:e.startTime?this.parseTimestamp(e.startTime):void 0,total_elapsed_time:e.totalElapsedTime,total_timer_time:e.totalTimerTime,start_position_lat:this.convertToSemicircles(e.startPositionLat),start_position_long:this.convertToSemicircles(e.startPositionLong),total_distance:e.totalDistance,total_ascent:e.totalAscent,total_descent:e.totalDescent,sport:e.sport||this.options.defaultSport,sub_sport:e.subSport||this.options.defaultSubSport,first_lap_index:e.firstLapIndex||0,num_laps:e.numLaps||((t=e.lapMesgs)==null?void 0:t.length)||1})}buildLaps(e){e.forEach(t=>this.buildLap(t))}buildLap(e){this.writeMesg("lap",{timestamp:e.timestamp?this.parseTimestamp(e.timestamp):void 0,start_time:e.startTime?this.parseTimestamp(e.startTime):void 0,start_position_lat:this.convertToSemicircles(e.startPositionLat),start_position_long:this.convertToSemicircles(e.startPositionLong),end_position_lat:this.convertToSemicircles(e.endPositionLat),end_position_long:this.convertToSemicircles(e.endPositionLong),total_elapsed_time:e.totalElapsedTime,total_timer_time:e.totalTimerTime,total_distance:e.totalDistance,total_ascent:e.totalAscent,total_descent:e.totalDescent})}buildRecords(e){e.forEach(t=>this.buildRecord(t))}buildRecord(e){this.writeMesg("record",{timestamp:e.timestamp?this.parseTimestamp(e.timestamp):void 0,position_lat:this.convertToSemicircles(e.positionLat),position_long:this.convertToSemicircles(e.positionLong),altitude:e.enhancedAltitude||e.altitude,distance:e.distance,heart_rate:e.heartRate,cadence:e.cadence,speed:e.enhancedSpeed||e.speed,power:e.power})}buildEvent(e){this.writeMesg("event",{timestamp:e.timestamp?this.parseTimestamp(e.timestamp):void 0,event:e.event,event_type:e.eventType,event_group:e.eventGroup})}buildActivity(e){this.writeMesg("activity",{timestamp:e.timestamp?this.parseTimestamp(e.timestamp):void 0,total_timer_time:e.totalTimerTime,num_sessions:e.numSessions,type:e.type,event:e.event,event_type:e.eventType,local_timestamp:e.localTimestamp?this.parseTimestamp(e.localTimestamp):void 0,event_group:e.eventGroup})}buildCourse(e){this.writeMesg("course",{name:e.name,sport:e.sport})}buildEventsFromLaps(e,t){e.forEach((r,i)=>{r.startTime&&t.push({timestamp:r.startTime,event:"timer",eventType:"start",eventGroup:i}),r.timestamp&&t.push({timestamp:r.timestamp,event:"timer",eventType:i===e.length-1?"stop_all":"stop",eventGroup:i})})}buildActivityFromSession(e,t){t.push({timestamp:e.timestamp,totalTimerTime:e.totalTimerTime,numSessions:1,type:e.sport||this.options.defaultSport,event:"activity",eventType:"stop",eventGroup:0})}parseTimestamp(e){return typeof e=="number"?e:(0,je.default)(e).valueOf()}convertToSemicircles(e){if(e!=null)return Math.round(e*2**31/180)}validateRequiredFields(e){if(!e.sessionMesgs||e.sessionMesgs.length===0)throw new Error("FIT file must contain at least one Session")}writeMesg(e,t){let r=Object.fromEntries(Object.entries(t).filter(([s,a])=>a!==void 0));if(Object.keys(r).length===0)return;let i=this.localNum[e];i===void 0&&(i=this.localNum[e]=Object.keys(this.localNum).length);let n=new oe(i,e,r),o=this.mesgDefn[i];(!o||!n.isSameDefn(o))&&(this.messages.push(n.defnRecord),this.mesgDefn[i]=n.mesgDefn),this.messages.push(n.dataRecord)}get blob(){let e=[this.header,...this.messages,this.trailer];return new Blob(e,{type:"application/octet-stream"})}get dataLen(){return this.messages.reduce((e,t)=>e+t.byteLength,0)}get dataCrc(){return this.messages.reduce((e,t)=>_e(t,e),0)}get header(){let e=new DataView(new ArrayBuffer(We));return e.setUint8(0,We),e.setUint8(1,mt),e.setUint16(2,Tt,!0),e.setUint32(4,this.dataLen,!0),e.setUint32(8,ft),e.setUint16(12,_e(e.buffer.slice(0,12)),!0),e.buffer}get trailer(){let e=new DataView(new ArrayBuffer(2));return e.setUint16(0,this.dataCrc,!0),e.buffer}async encoder(e){return this.encode(e)}};var T=class extends y{parseHeartRate(e){let t=this.parseFloat(e);return t>0&&t<300?t:void 0}parseTCXTime(e){if(!e)return;let t=new Date(e);return isNaN(t.getTime())?void 0:t}parseDistance(e){let t=this.parseFloat(e);return t>=0?t:void 0}parseSpeed(e){let t=this.parseFloat(e);return t>=0?t:void 0}parseAltitude(e){return this.parseFloat(e)}parseCoordinate(e){let t=this.parseFloat(e);return t!==0?t:void 0}};var se=class extends T{constructor(){super(...arguments);this.name="PositionConverter";this.supportedTags=["Position"]}convert(t,r){let i={};return this.processChildren(t,i,{LatitudeDegrees:(n,o)=>o.LatitudeDegrees=this.parseString(n.value),LongitudeDegrees:(n,o)=>o.LongitudeDegrees=this.parseString(n.value)}),i}},ae=class extends T{constructor(){super(...arguments);this.name="TrackpointConverter";this.supportedTags=["Trackpoint"]}convert(t,r){let i={};return this.processChildren(t,i,{Time:(n,o)=>o.Time=this.parseString(n.value),Position:(n,o)=>{var a;let s=r.metadata.get("decoder");o.Position=(a=s==null?void 0:s.getConverter("Position"))==null?void 0:a.convert(n,r)},AltitudeMeters:(n,o)=>o.AltitudeMeters=this.parseFloat(n.value),DistanceMeters:(n,o)=>o.DistanceMeters=this.parseFloat(n.value),HeartRateBpm:(n,o)=>{if(n.value)o.HeartRateBpm=this.parseFloat(n.value);else{let s=this.getChildByTag(n,"Value");s!=null&&s.value&&(o.HeartRateBpm=this.parseFloat(s.value))}},Cadence:(n,o)=>{let s={Low:0,High:0};this.processChildren(n,s,{Low:(a,c)=>c.Low=this.parseFloat(a.value),High:(a,c)=>c.High=this.parseFloat(a.value)}),o.Cadence=s},SensorState:(n,o)=>o.SensorState=n.value,Extensions:(n,o)=>o.Extensions=this.convertExtensions(n)}),i}convertExtensions(t){var i;let r={};return(i=t.children)==null||i.forEach(n=>{r[n.tag]=this.convertExtensionContent(n)}),r}convertExtensionContent(t){var r;if((r=t.children)!=null&&r.length){let i={};return t.children.forEach(n=>{i[n.tag]=this.convertExtensionContent(n)}),i}else return t.value}},pe=class extends T{constructor(){super(...arguments);this.name="TrackConverter";this.supportedTags=["Track"]}convert(t,r){let i={Trackpoint:[]};return this.processChildren(t,i,{Trackpoint:(n,o)=>{var c;let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("Trackpoint"))==null?void 0:c.convert(n,r);a&&o.Trackpoint&&o.Trackpoint.push(a)}}),i}},ce=class extends T{constructor(){super(...arguments);this.name="ActivityLapConverter";this.supportedTags=["Lap"]}convert(t,r){let i={};return this.extractAttributes(t,i,{StartTime:"Id"}),this.processChildren(t,i,{TotalTimeSeconds:(n,o)=>o.TotalTimeSeconds=this.parseFloat(n.value),DistanceMeters:(n,o)=>o.DistanceMeters=this.parseFloat(n.value),MaximumSpeed:(n,o)=>o.MaximumSpeed=this.parseFloat(n.value),Calories:(n,o)=>o.Calories=this.parseFloat(n.value),AverageHeartRateBpm:(n,o)=>o.AverageHeartRateBpm=this.parseFloat(n.value),MaximumHeartRateBpm:(n,o)=>o.MaximumHeartRateBpm=this.parseFloat(n.value),Intensity:(n,o)=>o.Intensity=n.value,TriggerMethod:(n,o)=>o.TriggerMethod=n.value,Track:(n,o)=>{var c;o.Track||(o.Track=[]);let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("Track"))==null?void 0:c.convert(n,r);a&&o.Track.push(a)},Notes:(n,o)=>o.Notes=this.parseString(n.value),Extensions:(n,o)=>o.Extensions=this.convertExtensions(n)}),i}convertExtensions(t){var i;let r={};return(i=t.children)==null||i.forEach(n=>{r[n.tag]=this.convertExtensionContent(n)}),r}convertExtensionContent(t){var r;if((r=t.children)!=null&&r.length){let i={};return t.children.forEach(n=>{i[n.tag]=this.convertExtensionContent(n)}),i}else return t.value}},de=class extends T{constructor(){super(...arguments);this.name="ActivityConverter";this.supportedTags=["Activity"]}convert(t,r){let i={Id:"",Lap:[]};return this.extractAttributes(t,i,{Sport:"Sport"}),this.processChildren(t,i,{Id:(n,o)=>o.Id=this.parseString(n.value),Lap:(n,o)=>{var c;let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("Lap"))==null?void 0:c.convert(n,r);a&&o.Lap.push(a)},Notes:(n,o)=>o.Notes=this.parseString(n.value),Training:(n,o)=>o.Training=this.convertTraining(n),Creator:(n,o)=>o.Creator=this.convertCreator(n),Extensions:(n,o)=>o.Extensions=this.convertExtensions(n)}),i}convertTraining(t){var i;let r={};return t.attributes&&Object.entries(t.attributes).forEach(([n,o])=>{r[n]=o}),(i=t.children)==null||i.forEach(n=>{r[n.tag]=this.convertExtensionContent(n)}),r}convertCreator(t){var i;let r={};return(i=t.children)==null||i.forEach(n=>{r[n.tag]=this.convertExtensionContent(n)}),r}convertExtensions(t){var i;let r={};return(i=t.children)==null||i.forEach(n=>{r[n.tag]=this.convertExtensionContent(n)}),r}convertExtensionContent(t){var r;if((r=t.children)!=null&&r.length){let i={};return t.children.forEach(n=>{i[n.tag]=this.convertExtensionContent(n)}),i}else return t.value}},le=class extends T{constructor(){super(...arguments);this.name="ActivityListConverter";this.supportedTags=["Activities"]}convert(t,r){let i={Activity:[],MultiSportSession:[]};return this.processChildren(t,i,{Activity:(n,o)=>{var c;let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("Activity"))==null?void 0:c.convert(n,r);a&&o.Activity&&o.Activity.push(a)},MultiSportSession:(n,o)=>{var c;let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("MultiSportSession"))==null?void 0:c.convert(n,r);a&&o.MultiSportSession&&o.MultiSportSession.push(a)}}),i}},ue=class extends T{constructor(){super(...arguments);this.name="MultiSportSessionConverter";this.supportedTags=["MultiSportSession"]}convert(t,r){let i={};return this.processChildren(t,i,{Id:(n,o)=>o.Id=this.parseString(n.value),FirstSport:(n,o)=>{var a;let s=r.metadata.get("decoder");o.FirstSport=(a=s==null?void 0:s.getConverter("FirstSport"))==null?void 0:a.convert(n,r)},NextSport:(n,o)=>{var c;o.NextSport||(o.NextSport=[]);let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("NextSport"))==null?void 0:c.convert(n,r);a&&o.NextSport.push(a)},Notes:(n,o)=>o.Notes=this.parseString(n.value)}),i}},me=class extends T{constructor(){super(...arguments);this.name="AbstractSourceConverter";this.supportedTags=["Author","Creator"]}convert(t,r){let i={};return this.processChildren(t,i,{Name:(n,o)=>o.Name=this.parseString(n.value)}),i}};var Xe=require("htmlparser2"),Te=class{static tokenizeXML(e){let t=[],r=new Xe.Parser({onopentag(i,n){t.push({type:"open",tag:i,attributes:n})},ontext(i){let n=i.replace(/\n/g,"").trim();n&&t.push({type:"text",tag:"text",value:n})},onclosetag(i){t.push({type:"close",tag:i})}},{xmlMode:!0});return r.write(e),r.end(),t}static compressXML(e){return e.replace(/>\s+</g,"><").replace(/\s+/g," ").trim()}static formatXML(e,t=2){let r=" ".repeat(t),i="",n=0,o=!1;for(let s=0;s<e.length;s++){let a=e[s],c=e[s+1];a==="<"?(c==="/"?(n--,o||(i+=`
12
+ `+r.repeat(n))):c!=="?"&&c!=="!"&&(o||(i+=`
13
+ `+r.repeat(n)),n++),o=!0):a===">"&&(o=!1,c==="<"&&e[s+2]==="/"&&n--),i+=a}return i.trim()}static validateXML(e){try{let t=new Xe.Parser({},{xmlMode:!0});return t.write(e),t.end(),{isValid:!0}}catch(t){return{isValid:!1,error:t.message}}}static extractXMLDeclaration(e){let t=e.match(/<\?xml\s+([^>]+)\?>/);if(!t)return{};let r=t[1],i={},n=r.match(/version=["']([^"']+)["']/);n&&(i.version=n[1]);let o=r.match(/encoding=["']([^"']+)["']/);o&&(i.encoding=o[1]);let s=r.match(/standalone=["']([^"']+)["']/);return s&&(i.standalone=s[1]),i}static escapeXML(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}static unescapeXML(e){return e.replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&quot;/g,'"').replace(/&#39;/g,"'").replace(/&amp;/g,"&")}};var fe=class{constructor(){this.stage="tokenize";this.name="tokenize-processor"}async process(e){if(!e.xmlContent)throw new Error("TCX data cannot be empty");let t=Te.tokenizeXML(e.xmlContent);if(t.length===0)throw new Error("Not a valid TCX file");return e.tokens=t,e.stats.processedTokens=t.length,e}},ge=class{constructor(){this.stage="ast-generate";this.name="ast-generate-processor"}async process(e){if(!e.tokens||e.tokens.length===0)throw new Error("Tokens are empty, cannot generate AST");let t=this.buildAST(e.tokens);if(!t)throw new Error("Failed to generate AST");return e.ast=t,e}buildAST(e){if(e.length===0)return;let t=[],r;for(let i of e)if(i.type==="open"){let n={tag:i.tag,attributes:i.attributes,children:[]};r&&(r.children=r.children||[],r.children.push(n)),t.push(n),r=n,t.length||r||(r=n)}else i.type==="close"?(t.pop(),r=t[t.length-1]):i.type==="text"&&r&&i.value&&typeof i.value=="string"&&i.value.trim()&&(r.value=i.value.trim());return r}},he=class{constructor(e){this.getConverter=e;this.stage="convert";this.name="convert-processor"}async process(e){if(!e.ast)throw new Error("AST is empty, cannot convert");let t=this.findTCXRoot(e.ast);if(!t)throw new Error("Not a valid TCX file: TrainingCenterDatabase element not found");let r=this.convertAST(t,e);return e.result=r,e.stats.convertedElements=this.countElements(e.ast),e}findTCXRoot(e){if(e.tag==="TrainingCenterDatabase")return e;if(e.children)for(let t of e.children){let r=this.findTCXRoot(t);if(r)return r}}convertAST(e,t){let r=this.getConverter(e.tag);return r?r.convert(e,t):this.genericConvert(e,t)}genericConvert(e,t){let r={};if(e.attributes&&Object.entries(e.attributes).forEach(([i,n])=>{r[i]=n}),e.value!==void 0)if(e.children&&e.children.length>0)r._value=e.value;else return e.value;return e.children&&e.children.forEach(i=>{let n=this.convertAST(i,t);r[i.tag]?(Array.isArray(r[i.tag])||(r[i.tag]=[r[i.tag]]),r[i.tag].push(n)):r[i.tag]=n}),r}countElements(e){let t=1;if(e.children)for(let r of e.children)t+=this.countElements(r);return t}},ye=class{constructor(){this.stage="complete";this.name="complete-processor"}async process(e){if(!e.result)throw new Error("No conversion result found");let t=Date.now(),r=t-e.performance.startTime;return e.performance.endTime=t,e.performance.processingTime=r,e.metadata.set("performance",{processingTime:r,processedTokens:e.stats.processedTokens,convertedElements:e.stats.convertedElements}),e}};var b=class{constructor(){this.converterPlugins=new Map;this.registeredPlugins=new Set;this.middlewarePlugins=[];this.processors=[];this.initialized=!1;this.defaultConvertersRegistered=!1;this.initializePipeline()}initializePipeline(){this.processors=[new fe,new ge,new he(e=>this.getConverter(e)),new ye]}async registerDefaultConverters(){var t;if(this.defaultConvertersRegistered)return;let e=[new se,new ae,new pe,new ce,new de,new le,new ue,new me];for(let r of e)(t=r.supportedTags)==null||t.forEach(i=>{this.addConverterForTag(i,r)}),this.registeredPlugins.add(r.name);this.defaultConvertersRegistered=!0}addConverterForTag(e,t){this.converterPlugins.has(e)||this.converterPlugins.set(e,[]);let r=this.converterPlugins.get(e);r.push(t),r.sort((i,n)=>(i.priority||100)-(n.priority||100))}async registerConverter(e){var r,n;if(this.registeredPlugins.has(e.name))throw new Error(`Converter plugin ${e.name} already exists`);(r=e.supportedTags)==null||r.forEach(o=>{this.addConverterForTag(o,e)}),this.registeredPlugins.add(e.name);let t=e.priority!==void 0?` (priority: ${e.priority})`:"";(n=e.supportedTags)==null||n.forEach(o=>{let a=(this.converterPlugins.get(o)||[]).map(c=>`${c.name}(${c.priority||100})`)})}async registerMiddleware(e){let t=this.middlewarePlugins.findIndex(i=>i.name===e.name);t!==-1?this.middlewarePlugins[t]=e:this.middlewarePlugins.push(e);let r=[];e.onTokenize&&r.push("onTokenize"),e.onAstGenerate&&r.push("onAstGenerate"),e.onConvert&&r.push("onConvert"),e.onComplete&&r.push("onComplete"),e.onError&&r.push("onError"),r.length>0}getConverter(e){let t=this.converterPlugins.get(e);return t&&t.length>0?t[0]:void 0}getAllConverters(e){return this.converterPlugins.get(e)||[]}unregisterConverter(e){let t;for(let[r,i]of this.converterPlugins){let n=i.findIndex(o=>o.name===e);n!==-1&&(t=i[n],i.splice(n,1),i.length===0&&this.converterPlugins.delete(r))}t&&this.registeredPlugins.delete(e)}unregisterMiddleware(e){let t=this.middlewarePlugins.findIndex(r=>r.name===e);t!==-1&&this.middlewarePlugins.splice(t,1)}async initialize(){var r;if(this.initialized)return;await this.registerDefaultConverters();let e=this.createContext(),t=[...Array.from(this.converterPlugins.values()).flat(),...this.middlewarePlugins];for(let i of t)try{await((r=i.initialize)==null?void 0:r.call(i,e))}catch{}this.initialized=!0}async destroy(){var r;if(!this.initialized)return;let e=this.createContext(),t=[...Array.from(this.converterPlugins.values()).flat(),...this.middlewarePlugins];for(let i of t)try{await((r=i.destroy)==null?void 0:r.call(i,e))}catch{}this.initialized=!1}createContext(){return{metadata:new Map,errors:[],warnings:[],stats:{startTime:Date.now(),processedTokens:0,convertedElements:0},performance:{startTime:Date.now()}}}async executeMiddlewareHook(e,t,r){var n;let i=t;for(let o of this.middlewarePlugins){let s=o[e];if(s)try{i=await s.call(o,i,r)||i}catch(a){r.errors.push(a),await((n=o.onError)==null?void 0:n.call(o,a,r))}}return i}async parseByBuffer(e){var r;await this.initialize();let t=this.createContext();t.rawData=e,t.xmlContent=e.toString("utf-8"),t.metadata.set("decoder",this);try{for(let i of this.processors)try{switch(t=await i.process(t),i.stage){case"tokenize":t.tokens&&(t.tokens=await this.executeMiddlewareHook("onTokenize",t.tokens,t));break;case"ast-generate":t.ast&&(t.ast=await this.executeMiddlewareHook("onAstGenerate",t.ast,t));break;case"convert":t.result&&(t.result=await this.executeMiddlewareHook("onConvert",t.result,t));break;case"complete":t.result&&(t.result=await this.executeMiddlewareHook("onComplete",t.result,t));break}}catch(n){t.errors.push(n);for(let o of this.middlewarePlugins)await((r=o.onError)==null?void 0:r.call(o,n,t))}return t.result}catch(i){throw i}}convertExtensions(e){var o,s;let t={},{attributes:r,tag:i,value:n}=e;if(r&&Object.entries(r).forEach(([a,c])=>{t[a]=c}),(o=e==null?void 0:e.children)!=null&&o.length)(s=e.children)==null||s.forEach(a=>{t[a.tag]=this.convertExtensions(a)});else if(n!==void 0)return n;return t}async parserByBuffer(e){return this.parseByBuffer(e)}async parseByString(e){let t=Buffer.from(e,"utf-8");return this.parseByBuffer(t)}};var Re=h(require("dayjs")),Ke=h(require("dayjs/plugin/utc.js"));Re.default.extend(Ke.default);var L=class{constructor(e={}){this.compact=e.compact??!0}async encode(e){let t=this.buildTCXXML(e);return Buffer.from(t,"utf-8")}encodeToString(e){return this.buildTCXXML(e)}buildTCXXML(e){let t=this.buildXMLHeader(e),r=this.buildTCXContent(e),n=`${t}${r}
14
+ </TrainingCenterDatabase>`;return this.compact?this.compressXML(n):n}compressXML(e){return e.replace(/>\s+</g,"><").replace(/^\s+|\s+$/gm,"").replace(/\s+/g," ").trim()}buildXMLHeader(e){let t=e.version||"1.0",r=e.creator||"trackswap",i=e.xmlns||"http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2",n=e["xmlns:xsi"]||"http://www.w3.org/2001/XMLSchema-instance",o=e["xsi:schemaLocation"]||"http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2 http://www8.garmin.com/xmlschemas/TrainingCenterDatabasev2.xsd";return['<?xml version="1.0" encoding="UTF-8"?>',`<TrainingCenterDatabase version="${this.escapeXMLAttribute(t)}"`,` creator="${this.escapeXMLAttribute(r)}"`,` xmlns="${this.escapeXMLAttribute(i)}"`,` xmlns:xsi="${this.escapeXMLAttribute(n)}"`,` xsi:schemaLocation="${this.escapeXMLAttribute(o)}">`].join(`
15
+ `)}buildTCXContent(e){let t=[];return e.Folders&&t.push(this.buildFolders(e.Folders)),e.Activities&&t.push(this.buildActivities(e.Activities)),e.Workouts&&t.push(this.buildWorkouts(e.Workouts)),e.Courses&&t.push(this.buildCourses(e.Courses)),e.Author&&t.push(this.buildAuthor(e.Author)),e.Extensions&&t.push(this.buildExtensions(e.Extensions)),t.join(`
16
+ `)}buildFolders(e){let t=["<Folders>"];return e.History&&t.push(this.buildHistory(e.History)),e.Workouts&&t.push(this.buildWorkouts(e.Workouts)),e.Courses,t.push("</Folders>"),t.join(`
17
+ `)}buildHistory(e){let t=["<History>"];return e.Running&&t.push(`<Running>${this.buildHistoryFolder(e.Running)}</Running>`),e.Biking&&t.push(`<Biking>${this.buildHistoryFolder(e.Biking)}</Biking>`),e.Other&&t.push(`<Other>${this.buildHistoryFolder(e.Other)}</Other>`),e.MultiSport&&t.push(`<MultiSport>${this.buildHistoryFolder(e.MultiSport)}</MultiSport>`),e.Extensions&&t.push(this.buildExtensions(e.Extensions)),t.push("</History>"),t.join(`
18
+ `)}buildHistoryFolder(e){return""}buildActivities(e){let t=["<Activities>"];return e.Activity&&e.Activity.forEach(r=>{t.push(this.buildActivity(r))}),e.MultiSportSession&&e.MultiSportSession.forEach(r=>{t.push(this.buildMultiSportSession(r))}),t.push("</Activities>"),t.join(`
19
+ `)}buildActivity(e){let r=[`<Activity Sport="${e.Sport||"Other"}">`];return r.push(`<Id>${this.formatTime(e.Id)}</Id>`),e.Lap&&e.Lap.length>0&&e.Lap.forEach(i=>{r.push(this.buildActivityLap(i))}),this.addOptionalElement(r,"Notes",e.Notes),e.Training,e.Creator,e.Extensions&&r.push(this.buildExtensions(e.Extensions)),r.push("</Activity>"),r.join(`
20
+ `)}buildActivityLap(e){let t=["<Lap>"];return this.addOptionalNumericElement(t,"TotalTimeSeconds",e.TotalTimeSeconds),this.addOptionalNumericElement(t,"DistanceMeters",e.DistanceMeters),this.addOptionalNumericElement(t,"MaximumSpeed",e.MaximumSpeed),this.addOptionalNumericElement(t,"Calories",e.Calories),e.AverageHeartRateBpm&&t.push(`<AverageHeartRateBpm xsi:type="HeartRateInBeatsPerMinute_t"><Value>${e.AverageHeartRateBpm}</Value></AverageHeartRateBpm>`),e.MaximumHeartRateBpm&&t.push(`<MaximumHeartRateBpm xsi:type="HeartRateInBeatsPerMinute_t"><Value>${e.MaximumHeartRateBpm}</Value></MaximumHeartRateBpm>`),this.addOptionalElement(t,"Intensity",e.Intensity),e.Cadence&&t.push(this.buildCadence(e.Cadence)),this.addOptionalElement(t,"TriggerMethod",e.TriggerMethod),e.Track&&e.Track.forEach(r=>{t.push(this.buildTrack(r))}),this.addOptionalElement(t,"Notes",e.Notes),e.Extensions&&t.push(this.buildExtensions(e.Extensions)),t.push("</Lap>"),t.join(`
21
+ `)}buildTrack(e){let t=["<Track>"];return e.Trackpoint&&e.Trackpoint.forEach(r=>{t.push(this.buildTrackpoint(r))}),t.push("</Track>"),t.join(`
22
+ `)}buildTrackpoint(e){let t=["<Trackpoint>"];return e.Time&&t.push(`<Time>${this.formatTime(e.Time)}</Time>`),e.Position&&t.push(this.buildPosition(e.Position)),this.addOptionalNumericElement(t,"AltitudeMeters",e.AltitudeMeters),this.addOptionalNumericElement(t,"DistanceMeters",e.DistanceMeters),e.HeartRateBpm&&t.push(`<HeartRateBpm xsi:type="HeartRateInBeatsPerMinute_t"><Value>${e.HeartRateBpm}</Value></HeartRateBpm>`),e.Cadence&&t.push(this.buildCadence(e.Cadence)),this.addOptionalElement(t,"SensorState",e.SensorState),e.Extensions&&t.push(this.buildExtensions(e.Extensions)),t.push("</Trackpoint>"),t.join(`
23
+ `)}buildPosition(e){let t=["<Position>"];return e.LatitudeDegrees&&t.push(`<LatitudeDegrees>${this.formatCoordinate(parseFloat(e.LatitudeDegrees))}</LatitudeDegrees>`),e.LongitudeDegrees&&t.push(`<LongitudeDegrees>${this.formatCoordinate(parseFloat(e.LongitudeDegrees))}</LongitudeDegrees>`),t.push("</Position>"),t.join("")}buildCadence(e){return`<Cadence><Low>${e.Low}</Low><High>${e.High}</High></Cadence>`}buildMultiSportSession(e){let t=["<MultiSportSession>"];return e.Id&&t.push(`<Id>${this.formatTime(e.Id)}</Id>`),e.FirstSport&&t.push(this.buildFirstSport(e.FirstSport)),e.NextSport&&e.NextSport.forEach(r=>{t.push(this.buildNextSport(r))}),this.addOptionalElement(t,"Notes",e.Notes),t.push("</MultiSportSession>"),t.join(`
24
+ `)}buildFirstSport(e){let t=["<FirstSport>"];return e.Activity&&t.push(this.buildActivity(e.Activity)),t.push("</FirstSport>"),t.join(`
25
+ `)}buildNextSport(e){let t=["<NextSport>"];return e.Transition&&t.push(`<Transition>${this.buildActivityLap(e.Transition)}</Transition>`),e.Activity&&t.push(this.buildActivity(e.Activity)),t.push("</NextSport>"),t.join(`
26
+ `)}buildWorkouts(e){return"<Workouts></Workouts>"}buildCourses(e){return"<Courses></Courses>"}buildAuthor(e){let t=["<Author>"];return this.addOptionalElement(t,"Name",e.Name),t.push("</Author>"),t.join("")}buildExtensions(e){let t=this.buildExtensionContent(e);return t?`<Extensions>${t}</Extensions>`:""}buildExtensionContent(e){return Object.entries(e).filter(([t])=>!t.startsWith("xmlns")).map(([t,r])=>{if(r&&typeof r=="object"){let i=this.buildExtensionContent(r);return`<${t}>${i}</${t}>`}else if(r!=null)return`<${t}>${this.escapeXML(String(r))}</${t}>`;return""}).filter(t=>t).join("")}formatTime(e){return typeof e=="string"&&/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/.test(e)?e:(0,Re.default)(e).utc().format("YYYY-MM-DDTHH:mm:ss[Z]")}addOptionalElement(e,t,r,i){if(r!=null&&r!==""){let n=i?i(r):this.escapeXML(r);e.push(`<${t}>${n}</${t}>`)}}addOptionalNumericElement(e,t,r){r!=null&&!isNaN(r)&&e.push(`<${t}>${r}</${t}>`)}isValidCoordinate(e,t){return e!=null&&t!==void 0&&t!==null&&!isNaN(e)&&!isNaN(t)}formatCoordinate(e){return this.roundTo(e,6).toString()}roundTo(e,t){let r=Math.pow(10,t);return Math.round(e*r)/r}escapeXML(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;")}escapeXMLAttribute(e){return typeof e!="string"?String(e||""):e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/'/g,"&apos;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/\r/g,"&#13;").replace(/\n/g,"&#10;").replace(/\t/g,"&#9;")}deepClone(e){if(e===null||typeof e!="object")return e;if(e instanceof Date)return new Date(e.getTime());if(Array.isArray(e))return e.map(r=>this.deepClone(r));let t={};for(let r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=this.deepClone(e[r]));return t}encoder(e){return this.encode(e)}};var I=class extends y{convertPoints(e){return e.map(t=>this.convertPoint(t)).filter(t=>t!==void 0)}convertTime(e){if(e){if(typeof e=="number")return e;if(e instanceof Date)return e.getTime();if(typeof e=="string"){let t=new Date(e);return isNaN(t.getTime())?void 0:t.getTime()}}}calculateDistance(e){if(e.length<2)return;let t=0;for(let r=1;r<e.length;r++){let i=e[r-1],n=e[r],o=6371e3,s=i.lat*Math.PI/180,a=n.lat*Math.PI/180,c=(n.lat-i.lat)*Math.PI/180,d=(n.lon-i.lon)*Math.PI/180,l=Math.sin(c/2)*Math.sin(c/2)+Math.cos(s)*Math.cos(a)*Math.sin(d/2)*Math.sin(d/2),f=2*Math.atan2(Math.sqrt(l),Math.sqrt(1-l));t+=o*f}return t}calculateDuration(e){var i,n;if(e.length<2)return;let t=(i=e[0])==null?void 0:i.time,r=(n=e[e.length-1])==null?void 0:n.time;if(!(!t||!r))return Math.round((r-t)/1e3)}},k=class{constructor(){this.version="1.0.0";this.priority=100}supports(e){return this.supportedTags.includes(e)}async initialize(e){e.metadata.set(`plugin:${this.name}:initialized`,!0)}async destroy(e){e.metadata.delete(`plugin:${this.name}:initialized`)}async validate(e){return!0}convertTimeToDate(e){return e?new Date(e):new Date}convertTimeToString(e){return this.convertTimeToDate(e).toISOString()}ensureValidCoordinates(e,t){return e>=-90&&e<=90&&t>=-180&&t<=180}round(e,t=6){let r=Math.pow(10,t);return Math.round(e*r)/r}};var Ye={"gpxtpx:cad":"cadence","gpxtpx:hr":"heartRate","gpxtpx:temp":"temperature","gpxtpx:wtemp":"wtemp","gpxtpx:atemp":"atemp","gpxx:Temperature":"temperature","gpxx:Depth":"depth"},Me=p=>p*(180/Math.pow(2,31));var F=h(require("dayjs"));function Ze(p,e=0){let t=Math.pow(10,e);return Math.round(p*t)/t}var ve=class extends I{constructor(){super(...arguments);this.name="gpx-to-sport-converter";this.supportedTags=["gpx"];this.convertGPXExtensions=t=>{let r={};return Object.entries(t).forEach(([i,n])=>{if(typeof n!="string"&&typeof n!="number")r={...r,...this.convertGPXExtensions(n)};else if(typeof n<"u"&&n!=="undefined"){let o=Ye[i]||i;r[o]=n}}),r}}convert(t,r){if(r.sourceFormat!=="gpx")return;let i=r.sourceData;return this.convertGPX(i)}convertGPX(t){let r={metadata:{originType:"GPX",creator:t.creator,fileType:"gpx"}};return t.wpt&&(r.points=this.convertWpts2Points(t.wpt)),t.trk&&(r.tracks=t.trk.map(i=>{var n;return{name:i.name,trackseg:((n=i.trkseg)==null?void 0:n.map(o=>({name:i.name,points:o.trkpt?this.convertWpts2Points(o.trkpt):[]})))||[]}})),t.rte&&(r.routes=t.rte.map(i=>({name:i.name,points:i.rtept?this.convertWpts2Points(i.rtept):[]}))),r}convertPoint(t){if(t.lat==null||t.lon==null||typeof t.lat!="number"||typeof t.lon!="number")return;let{extensions:r}=t,i=r?this.convertGPXExtensions(r):{};return{lat:t.lat,lon:t.lon,ele:t.ele,time:this.convertTime(t.time),...i}}convertWpts2Points(t){let r=[];for(let i=0;i<t.length;i++){let n=t[i];if(n.lat!=null&&n.lon!=null&&typeof n.lat=="number"&&typeof n.lon=="number"){let o=this.convertPoint(n);o&&r.push(o)}}return r}},xe=class extends I{constructor(){super(...arguments);this.name="fit-to-sport-converter";this.supportedTags=["fit"]}convert(t,r){if(r.sourceFormat!=="fit")return;let i=r.sourceData;return this.convertFIT(i)}convertFIT(t){var i,n;let r={metadata:{originType:"FIT",fileType:"fit"}};if((i=t.sessionMesgs)!=null&&i.length){r.tracks=[];for(let o of t.sessionMesgs)r.tracks.push({name:o.event,startTime:o.startTime?(0,F.default)(o.startTime).valueOf():void 0,distance:o.totalDistance,duration:o.totalElapsedTime,sport:o.sport,trackseg:this.convertFITLap2Trackseg(o==null?void 0:o.lapMesgs),__fit__sessionMesgType:o})}else if((n=t.courseMesgs)!=null&&n.length){r.routes=[];for(let o of t.courseMesgs)r.routes.push({name:o.event,points:this.convertLap2Points(o==null?void 0:o.lapMesgs)})}return r}convertPoint(t){let{positionLong:r,positionLat:i,altitude:n,timestamp:o,...s}=t;if(!(r==null||i==null||typeof r!="number"||typeof i!="number"))return{lat:Ze(Me(Number(i)),6),lon:Ze(Me(Number(r)),6),ele:n,time:o?(0,F.default)(o).valueOf():void 0,...s}}convertFITLap2Trackseg(t){var i;let r=[];if(!(t!=null&&t.length))return[];for(let o of t){let s=((i=o==null?void 0:o.recordMesgs)==null?void 0:i.map(a=>this.convertPoint(a)).filter(a=>a!==void 0))||[];r.push({points:s,duration:o.totalElapsedTime,distance:o.totalDistance,startTime:o.startTime?(0,F.default)(o.startTime).valueOf():void 0,endTime:o.startTime&&o.totalElapsedTime?(0,F.default)(o.startTime).add(o.totalElapsedTime,"second").valueOf():void 0,avgSpeed:o.avgSpeed,maxSpeed:o.maxSpeed,avgCadenceBpm:o.avgCadence,maxCadenceBpm:o.maxCadence,avgPower:o.avgPower,maxPower:o.maxPower,totalAscent:o.totalAscent,totalDescent:o.totalDescent,calories:o.totalCalories,__fit__lapMesgType:o})}return r}convertLap2Points(t){var i;let r=[];if(!(t!=null&&t.length))return[];for(let n of t){let o=((i=n.recordMesgs)==null?void 0:i.map(s=>this.convertPoint(s)).filter(s=>s!==void 0))||[];o.length&&(r=[...r,...o])}return r}},Ce=class extends I{constructor(){super(...arguments);this.name="tcx-to-sport-converter";this.supportedTags=["tcx"]}convert(t,r){if(r.sourceFormat!=="tcx")return;let i=r.sourceData;return this.convertTCX(i)}convertTCX(t){var i,n,o,s;let r={metadata:{originType:"TCX",fileType:"tcx"}};if((n=(i=t.Activities)==null?void 0:i.Activity)!=null&&n.length){r.tracks=[];for(let a of t.Activities.Activity)r.tracks.push({name:a.Id,sport:a.Sport,trackseg:this.convertLap2Trackseg(a.Lap)})}if((s=(o=t.Courses)==null?void 0:o.Course)!=null&&s.length){r.routes=[];for(let a of t.Courses.Course){let c=a.Track||[];for(let d of c)r.routes.push({name:a.Name||"",points:this.convertTCXTrack(d)})}}return r}convertPoint(t){let{Position:r,Time:i,DistanceMeters:n,AltitudeMeters:o}=t;if(!(!(r!=null&&r.LatitudeDegrees)||!(r!=null&&r.LongitudeDegrees)||r.LatitudeDegrees===""||r.LongitudeDegrees===""))return{lat:Number(r.LatitudeDegrees),lon:Number(r.LongitudeDegrees),time:i?(0,F.default)(i).valueOf():void 0,distance:n,ele:o}}convertLap2Trackseg(t){var i,n,o,s;let r=[];for(let a of t)if(a.Track){for(let c of a.Track)if(c.Trackpoint){let d=c.Trackpoint.map(f=>this.convertPoint(f)).filter(f=>f!==void 0),l={duration:a.TotalTimeSeconds,distance:a.DistanceMeters,startTime:(i=d==null?void 0:d[0])==null?void 0:i.time,endTime:(n=d==null?void 0:d[d.length-1])==null?void 0:n.time,avgHeartRateBpm:a==null?void 0:a.AverageHeartRateBpm,maxHeartRateBpm:a==null?void 0:a.MaximumHeartRateBpm,maxSpeed:a.MaximumSpeed,calories:a.Calories,__tcx__Intensity:a==null?void 0:a.Intensity,__tcx__TriggerMethod:a==null?void 0:a.TriggerMethod,avgCadenceBpm:(o=a==null?void 0:a.Cadence)==null?void 0:o.Low,maxCadenceBpm:(s=a==null?void 0:a.Cadence)==null?void 0:s.High,points:d};r.push(l)}}return r}convertTCXTrack(t){return t.Trackpoint?t.Trackpoint.map(r=>this.convertPoint(r)).filter(r=>r!==void 0):[]}};function qe(p){return Math.round(p*(Math.pow(2,31)/180))}var Pe=class extends k{constructor(){super(...arguments);this.name="sport-to-gpx-encoder";this.supportedTags=["gpx"]}encode(t,r){var n,o,s,a;if(r.targetFormat!=="gpx")return;let i={version:"1.1",creator:((n=t.metadata)==null?void 0:n.creator)||"TrackSwap"};return(o=t.points)!=null&&o.length&&(i.wpt=this.convertPoints2Wpts(t.points)),(s=t.routes)!=null&&s.length&&(i.rte=t.routes.map(c=>this.convertRoute2GPXRoute(c))),(a=t.tracks)!=null&&a.length&&(i.trk=t.tracks.map(c=>this.convertTrack2GPXTrack(c))),i}convertPoints2Wpts(t){return t.map(r=>({lat:r.lat,lon:r.lon,ele:r.ele,time:r.time?this.convertTimeToDate(r.time):void 0,speed:r.speed,magvar:r.magvar,extensions:this.extractGPXExtensions(r)}))}convertRoute2GPXRoute(t){return{name:t.name,rtept:t.points?this.convertPoints2Wpts(t.points):[]}}convertTrack2GPXTrack(t){var r;return{name:t.name,trkseg:((r=t.trackseg)==null?void 0:r.map(i=>({trkpt:i.points?this.convertPoints2Wpts(i.points):[]})))||[]}}extractGPXExtensions(t){let r={};return t.heart&&(r["gpxtpx:hr"]=t.heart),t.cadence&&(r["gpxtpx:cad"]=t.cadence),t.temperature&&(r["gpxtpx:atemp"]=t.temperature),Object.keys(r).length>0?r:void 0}},Ee=class extends k{constructor(){super(...arguments);this.name="sport-to-fit-encoder";this.supportedTags=["fit"]}encode(t,r){var n,o;if(r.targetFormat!=="fit")return;let i={};return(n=t.tracks)!=null&&n.length&&(i.sessionMesgs=t.tracks.map(s=>this.convertTrack2FITSession(s))),(o=t.routes)!=null&&o.length&&(i.courseMesgs=t.routes.map(s=>this.convertRoute2FITCourse(s))),i}convertTrack2FITSession(t){var i;return{event:t.name||"session",sport:t.sport||"generic",startTime:t.startTime?this.convertTimeToString(t.startTime):this.convertTimeToString(void 0),totalDistance:t.distance,totalElapsedTime:t.duration,lapMesgs:((i=t.trackseg)==null?void 0:i.map(n=>this.convertSeg2FITLap(n)))||[]}}convertSeg2FITLap(t){var i;return{startTime:t.startTime?this.convertTimeToString(t.startTime):this.convertTimeToString(void 0),totalElapsedTime:t.duration,totalDistance:t.distance,avgSpeed:t.avgSpeed,maxSpeed:t.maxSpeed,avgCadence:t.avgCadenceBpm,maxCadence:t.maxCadenceBpm,avgPower:t.avgPower,maxPower:t.maxPower,totalAscent:t.totalAscent,totalDescent:t.totalDescent,totalCalories:t.calories,recordMesgs:((i=t.points)==null?void 0:i.map(n=>this.convertPoint2FITRecord(n)))||[]}}convertPoint2FITRecord(t){return{timestamp:t.time?this.convertTimeToString(t.time):this.convertTimeToString(void 0),positionLat:qe(t.lat),positionLong:qe(t.lon),altitude:t.ele,speed:t.speed,power:t.power,heartRate:t.heart,cadence:t.cadence,temperature:t.temperature,distance:t.distance,enhancedSpeed:t.enhancedSpeed,enhancedAltitude:t.enhancedAltitude,accumulatedPower:t.accumulatedPower}}convertRoute2FITCourse(t){return{event:t.name||"course",lapMesgs:t.points?[this.convertPoints2FITLap(t.points)]:[]}}convertPoints2FITLap(t){let r=t[0],i=t[t.length-1],n=r!=null&&r.time?this.convertTimeToString(r.time):this.convertTimeToString(void 0),o=r!=null&&r.time&&(i!=null&&i.time)?Math.round((i.time-r.time)/1e3):0,s=(i==null?void 0:i.distance)||0;return{startTime:n,totalElapsedTime:o,totalDistance:s,recordMesgs:t.map(a=>this.convertPoint2FITRecord(a))}}},we=class extends k{constructor(){super(...arguments);this.name="sport-to-tcx-encoder";this.supportedTags=["tcx"]}encode(t,r){var n,o,s;if(r.targetFormat!=="tcx")return;let i={Author:{Name:((n=t.metadata)==null?void 0:n.creator)||"TrackSwap"}};return(o=t.tracks)!=null&&o.length&&(i.Activities={Activity:t.tracks.map(a=>this.convertTrack2TCXActivity(a))}),(s=t.routes)!=null&&s.length&&(i.Courses={Course:t.routes.map(a=>this.convertRoute2TCXCourse(a))}),i}convertTrack2TCXActivity(t){var i;let r="Other";return(t.sport==="Running"||t.sport==="Biking")&&(r=t.sport),{Id:t.name||`Activity_${Date.now()}`,Sport:r,Lap:((i=t.trackseg)==null?void 0:i.map(n=>this.convertSeg2TCXLap(n)))||[]}}convertSeg2TCXLap(t){let r={TotalTimeSeconds:t.duration,DistanceMeters:t.distance,MaximumSpeed:t.maxSpeed,Calories:t.calories,AverageHeartRateBpm:t.avgHeartRateBpm,MaximumHeartRateBpm:t.maxHeartRateBpm,Intensity:t.__tcx__Intensity||"Active",TriggerMethod:t.__tcx__TriggerMethod||"Manual",Track:t.points?[this.convertPoints2TCXTrack(t.points)]:[]};return(t.avgCadenceBpm!==void 0||t.maxCadenceBpm!==void 0)&&(r.Cadence={Low:t.avgCadenceBpm||0,High:t.maxCadenceBpm||0}),r}convertPoints2TCXTrack(t){return{Trackpoint:t.map(r=>this.convertPoint2TCXTrackpoint(r))}}convertPoint2TCXTrackpoint(t){let r={Time:t.time?this.convertTimeToString(t.time):this.convertTimeToString(void 0),Position:{LatitudeDegrees:t.lat.toString(),LongitudeDegrees:t.lon.toString()},AltitudeMeters:t.ele,DistanceMeters:t.distance};return t.heart&&(r.HeartRateBpm=t.heart),r}convertRoute2TCXCourse(t){return{Name:t.name||`Course_${Date.now()}`,Track:t.points?[this.convertPoints2TCXTrack(t.points)]:[]}}};var Se=class{constructor(){this.converters=new Map;this.encoders=new Map;this.registerDefaultConverters(),this.registerDefaultEncoders()}registerDefaultConverters(){this.registerConverter(new ve),this.registerConverter(new xe),this.registerConverter(new Ce)}registerDefaultEncoders(){this.registerEncoder(new Pe),this.registerEncoder(new Ee),this.registerEncoder(new we)}registerConverter(e){this.converters.set(e.name,e)}registerEncoder(e){this.encoders.set(e.name,e)}async convertToSport(e,t){let r={metadata:new Map,errors:[],warnings:[],stats:{startTime:Date.now(),processedTokens:0,convertedElements:0},sourceFormat:t,sourceData:e,performance:{startTime:Date.now()}};try{let i=this.findConverter(t);if(!i)throw new Error(`No converter found for format "${t}"`);let n=Date.now(),o=i.convert({},r);if(r.performance.convertTime=Date.now()-n,!o)throw new Error(`Converter "${i.name}" returned empty result`);return r.result=o,r.performance.endTime=Date.now(),r.stats.endTime=Date.now(),o}catch(i){throw r.errors.push(i),i}}async encodeSport(e,t){let r={metadata:new Map,errors:[],warnings:[],stats:{startTime:Date.now(),processedTokens:0,convertedElements:0},targetFormat:t,performance:{startTime:Date.now()}};try{let i=this.findEncoder(t);if(!i)throw new Error(`No encoder found for format "${t}"`);let n=Date.now(),o=i.encode(e,r);if(r.performance.encodeTime=Date.now()-n,!o)throw new Error(`Encoder "${i.name}" returned empty result`);return r.result=o,r.performance.endTime=Date.now(),r.stats.endTime=Date.now(),o}catch(i){throw r.errors.push(i),i}}findConverter(e){return Array.from(this.converters.values()).find(t=>{var r;return(r=t.supportedTags)==null?void 0:r.includes(e)})}findEncoder(e){return Array.from(this.encoders.values()).find(t=>{var r;return(r=t.supportedTags)==null?void 0:r.includes(e)})}async destroy(){this.converters.clear(),this.encoders.clear()}};var O=class{constructor(){this.gpxDecoder=new P,this.gpxEncoder=new E,this.fitDecoder=new w,this.fitEncoder=new S,this.tcxDecoder=new b,this.tcxEncoder=new L,this.sportProcessor=new Se}async parseGPX(e){try{return await this.gpxDecoder.parserByBuffer(e)}catch(t){throw new Error(`GPX parsing failed: ${t.message}`)}}async parseGPXString(e){let t=Buffer.from(e,"utf-8");return this.parseGPX(t)}async encodeGPX(e){try{return await this.gpxEncoder.encode(e)}catch(t){throw new Error(`GPX encoding failed: ${t.message}`)}}encodeGPXString(e){try{return this.gpxEncoder.encodeToString(e)}catch(t){throw new Error(`GPX encoding failed: ${t.message}`)}}async parseFIT(e){try{return await this.fitDecoder.parseByBuffer(e)}catch(t){throw new Error(`FIT parsing failed: ${t.message}`)}}async encodeFIT(e){try{return await this.fitEncoder.encode(e)}catch(t){throw new Error(`FIT encoding failed: ${t.message}`)}}async encodeFITCourse(e){try{return await this.fitEncoder.encodeCourse(e)}catch(t){throw new Error(`FIT Course encoding failed: ${t.message}`)}}async parseTCX(e){try{let t=await this.tcxDecoder.parseByBuffer(e);if(!t)throw new Error("TCX parsing result is empty");return t}catch(t){throw new Error(`TCX parsing failed: ${t.message}`)}}async parseTCXString(e){let t=Buffer.from(e,"utf-8");return this.parseTCX(t)}async encodeTCX(e){try{return await this.tcxEncoder.encode(e)}catch(t){throw new Error(`TCX encoding failed: ${t.message}`)}}async encodeTCXString(e){try{return await this.tcxEncoder.encodeToString(e)}catch(t){throw new Error(`TCX encoding failed: ${t.message}`)}}async convertGPXToSport(e){return await this.sportProcessor.convertToSport(e,"gpx")}async convertFITToSport(e){return await this.sportProcessor.convertToSport(e,"fit")}async convertTCXToSport(e){return await this.sportProcessor.convertToSport(e,"tcx")}async convertSportToGPX(e){return await this.sportProcessor.encodeSport(e,"gpx")}async convertSportToFIT(e){return await this.sportProcessor.encodeSport(e,"fit")}async convertSportToTCX(e){return await this.sportProcessor.encodeSport(e,"tcx")}async convertFile(e,t,r){try{let i=r||this.detectFormat(e);if(i==="unknown")throw new Error("Unable to recognize source file format, please specify sourceType parameter");if(i===t)return e;let n;switch(i){case"gpx":let s=await this.parseGPX(e);if(!s)throw new Error("GPX file parsing failed");n=s;break;case"fit":n=await this.parseFIT(e);break;case"tcx":n=await this.parseTCX(e);break;default:throw new Error(`Unsupported source file format: ${i}`)}let o;switch(i){case"gpx":o=await this.convertGPXToSport(n);break;case"fit":o=await this.convertFITToSport(n);break;case"tcx":o=await this.convertTCXToSport(n);break;default:throw new Error(`Unsupported source file format conversion: ${i}`)}switch(t){case"gpx":let s=await this.convertSportToGPX(o);return await this.encodeGPX(s);case"fit":let a=await this.convertSportToFIT(o);return await this.encodeFIT(a);case"tcx":let c=await this.convertSportToTCX(o);return await this.encodeTCX(c);default:throw new Error(`Unsupported target file format: ${t}`)}}catch(i){let n=r||"auto-detect";throw new Error(`${n} to ${t.toUpperCase()} failed: ${i.message}`)}}detectFormat(e){let t=e.toString("utf-8",0,Math.min(1024,e.length));if(e.length>=12&&e.toString("ascii",8,12)===".FIT")return"fit";if(t.includes("<?xml")){if(t.includes("<gpx")||t.includes("http://www.topografix.com/GPX/"))return"gpx";if(t.includes("<TrainingCenterDatabase")||t.includes("http://www.garmin.com/xmlschemas/TrainingCenterDatabase/"))return"tcx"}return"unknown"}async parseFile(e,t){let r=t||this.detectFormat(e);if(r==="unknown")throw new Error("Unable to recognize file format, please specify sourceType parameter");switch(r){case"gpx":let i=await this.parseGPX(e);if(!i)throw new Error("GPX parsing failed");return i;case"fit":return await this.parseFIT(e);case"tcx":return await this.parseTCX(e);default:throw new Error(`Unsupported file format: ${r}`)}}async parseToSport(e,t){let r=t||this.detectFormat(e);if(r==="unknown")throw new Error("Unable to recognize file format, please specify sourceType parameter");switch(r){case"gpx":let i=await this.parseGPX(e);if(!i)throw new Error("GPX parsing failed");return this.convertGPXToSport(i);case"fit":let n=await this.parseFIT(e);return this.convertFITToSport(n);case"tcx":let o=await this.parseTCX(e);return this.convertTCXToSport(o);default:throw new Error(`Unsupported file format: ${r}`)}}getSportProcessor(){return this.sportProcessor}getGPXDecoder(){return this.gpxDecoder}getGPXEncoder(){return this.gpxEncoder}getFITDecoder(){return this.fitDecoder}getFITEncoder(){return this.fitEncoder}getTCXDecoder(){return this.tcxDecoder}getTCXEncoder(){return this.tcxEncoder}async destroy(){await this.gpxDecoder.destroy(),await this.fitDecoder.destroy(),await this.tcxDecoder.destroy(),await this.sportProcessor.destroy()}};var gt=O;0&&(module.exports={GPXManager,TrackSwap});
package/dist/index.js CHANGED
@@ -1,24 +1,26 @@
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}
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 i;return(i=e.attributes)==null?void 0:i[r]})}extractAttributes(e,t,r){e.attributes&&Object.entries(e.attributes).forEach(([i,n])=>{let o=r[i];o&&o in t&&(t[o]=String(n||""))})}processChildren(e,t,r){var i;(i=e.children)==null||i.forEach(n=>{let o=r[n.tag];o&&o(n,t)})}getChildValue(e,t){var i;let r=(i=e.children)==null?void 0:i.find(n=>n.tag===t);return r!=null&&r.value?String(r.value):void 0}getChildByTag(e,t){var r;return(r=e.children)==null?void 0:r.find(i=>i.tag===t)}getChildrenByTag(e,t){var r;return((r=e.children)==null?void 0:r.filter(i=>i.tag===t))||[]}convertExtensions(e){var r;let t={};return(r=e.children)==null||r.forEach(i=>{t[i.tag]=this.convertExtensionContent(i)}),t}convertExtensionContent(e){var t;if((t=e.children)!=null&&t.length){let r={};return e.children.forEach(i=>{r[i.tag]=this.convertExtensionContent(i)}),r}else return e.value}},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(([i,n])=>{let o=r[i];o&&o in t&&typeof n<"u"&&(t[o]=this.parseFloat(n))})}},A=class extends x{async onError(e,t){t.warnings.push(`Middleware ${this.name} error: ${e.message}`)}};var O=class extends u{constructor(){super(...arguments);this.name="wpt-converter";this.supportedTags=["wpt","trkpt","rtept"];this.version="1.0.0"}convert(t,r){if(!this.hasRequiredAttributes(t,["lat","lon"]))return;let i={lat:this.parseFloat(t.attributes.lat),lon:this.parseFloat(t.attributes.lon)};return this.extractAttributes(t,i,{lat:"lat",lon:"lon"}),this.processChildren(t,i,{ele:(n,o)=>o.ele=this.parseFloat(n.value),time:(n,o)=>o.time=new Date(this.parseString(n.value)),speed:(n,o)=>o.speed=this.parseFloat(n.value),course:(n,o)=>o.course=this.parseFloat(n.value),name:(n,o)=>o.name=this.parseString(n.value),cmt:(n,o)=>o.cmt=this.parseString(n.value),desc:(n,o)=>o.desc=this.parseString(n.value),src:(n,o)=>o.src=this.parseString(n.value),sym:(n,o)=>o.sym=this.parseString(n.value),type:(n,o)=>o.type=this.parseString(n.value),fix:(n,o)=>o.fix=this.parseString(n.value),sat:(n,o)=>o.sat=this.parseString(n.value),hdop:(n,o)=>o.hdop=this.parseFloat(n.value),vdop:(n,o)=>o.vdop=this.parseFloat(n.value),pdop:(n,o)=>o.pdop=this.parseFloat(n.value),ageofdgpsdata:(n,o)=>o.ageofdgpsdata=this.parseFloat(n.value),geoidheight:(n,o)=>o.geoidheight=this.parseFloat(n.value),magvar:(n,o)=>o.magvar=this.parseFloat(n.value),dgpsid:(n,o)=>o.dgpsid=this.parseFloat(n.value),extensions:(n,o)=>{let s=r.metadata.get("decoder");s&&(o.extensions=s.convertExtensions(n))},link:(n,o)=>{var c;o.link||(o.link=[]);let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("link"))==null?void 0:c.convert(n,r);a&&o.link&&o.link.push(a)}}),i}},$=class extends u{constructor(){super(...arguments);this.name="rte-converter";this.supportedTags=["rte"]}convert(t,r){let i={rtept:[]};return this.processChildren(t,i,{name:(n,o)=>o.name=this.parseString(n.value),cmt:(n,o)=>o.cmt=this.parseString(n.value),desc:(n,o)=>o.desc=this.parseString(n.value),src:(n,o)=>o.src=this.parseString(n.value),number:(n,o)=>o.number=this.parseFloat(n.value),type:(n,o)=>o.type=this.parseString(n.value),rtept:(n,o)=>{var c;let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("wpt"))==null?void 0:c.convert(n,r);a&&o.rtept&&o.rtept.push(a)},extensions:(n,o)=>{let s=r.metadata.get("decoder");s&&(o.extensions=s.convertExtensions(n))},link:(n,o)=>{var a;o.link||(o.link=[]);let s=r.metadata.get("decoder");(a=n.children)==null||a.forEach(c=>{var l;let d=(l=s==null?void 0:s.getConverter("link"))==null?void 0:l.convert(c,r);d&&o.link&&o.link.push(d)})}}),i}},G=class extends u{constructor(){super(...arguments);this.name="trk-converter";this.supportedTags=["trk"]}convert(t,r){let i={trkseg:[]};return this.processChildren(t,i,{name:(n,o)=>o.name=this.parseString(n.value),cmt:(n,o)=>o.cmt=this.parseString(n.value),desc:(n,o)=>o.desc=this.parseString(n.value),src:(n,o)=>o.src=this.parseString(n.value),number:(n,o)=>o.number=this.parseFloat(n.value),type:(n,o)=>o.type=this.parseString(n.value),trkseg:(n,o)=>{var c;let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("trkseg"))==null?void 0:c.convert(n,r);a&&o.trkseg&&o.trkseg.push(a)},extensions:(n,o)=>{let s=r.metadata.get("decoder");s&&(o.extensions=s.convertExtensions(n))},link:(n,o)=>{var a;o.link||(o.link=[]);let s=r.metadata.get("decoder");(a=n.children)==null||a.forEach(c=>{var l;let d=(l=s==null?void 0:s.getConverter("link"))==null?void 0:l.convert(c,r);d&&o.link&&o.link.push(d)})}}),i}},B=class extends u{constructor(){super(...arguments);this.name="trkseg-converter";this.supportedTags=["trkseg"]}convert(t,r){let i={trkpt:[]};return this.processChildren(t,i,{trkpt:(n,o)=>{var c;let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("wpt"))==null?void 0:c.convert(n,r);a&&o.trkpt&&o.trkpt.push(a)},extensions:(n,o)=>{let s=r.metadata.get("decoder");s&&(o.extensions=s.convertExtensions(n))}}),i}},H=class extends u{constructor(){super(...arguments);this.name="link-converter";this.supportedTags=["link"]}convert(t,r){var n;let i={};return(n=t.attributes)!=null&&n.href&&(i.href=t.attributes.href),this.processChildren(t,i,{text:(o,s)=>s.text=this.parseString(o.value),type:(o,s)=>s.type=this.parseString(o.value)}),i}},z=class extends u{constructor(){super(...arguments);this.name="metadata-converter";this.supportedTags=["metadata"]}convert(t,r){let i={};return this.processChildren(t,i,{name:(n,o)=>o.name=this.parseString(n.value),desc:(n,o)=>o.desc=this.parseString(n.value),keywords:(n,o)=>o.keywords=this.parseString(n.value),time:(n,o)=>o.time=new Date(this.parseString(n.value)),author:(n,o)=>{var a;let s=r.metadata.get("decoder");o.author=(a=s==null?void 0:s.getConverter("author"))==null?void 0:a.convert(n,r)},copyright:(n,o)=>{var a;let s=r.metadata.get("decoder");o.copyright=(a=s==null?void 0:s.getConverter("copyright"))==null?void 0:a.convert(n,r)},bounds:(n,o)=>{var a;let s=r.metadata.get("decoder");o.bounds=(a=s==null?void 0:s.getConverter("bounds"))==null?void 0:a.convert(n,r)},extensions:(n,o)=>{let s=r.metadata.get("decoder");s&&(o.extensions=s.convertExtensions(n))},link:(n,o)=>{var c;o.link||(o.link=[]);let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("link"))==null?void 0:c.convert(n,r);a&&o.link&&o.link.push(a)}}),i}},V=class extends u{constructor(){super(...arguments);this.name="person-converter";this.supportedTags=["author"]}convert(t,r){var n;let i={};return t.value&&!((n=t.children)!=null&&n.length)?(i.name=this.parseString(t.value),i):(this.processChildren(t,i,{name:(o,s)=>s.name=this.parseString(o.value),email:(o,s)=>{var c;let a=r.metadata.get("decoder");s.email=(c=a==null?void 0:a.getConverter("email"))==null?void 0:c.convert(o,r)},link:(o,s)=>{var c;let a=r.metadata.get("decoder");s.link=(c=a==null?void 0:a.getConverter("link"))==null?void 0:c.convert(o,r)}}),i)}},U=class extends u{constructor(){super(...arguments);this.name="email-converter";this.supportedTags=["email"]}convert(t,r){let i={};return this.processChildren(t,i,{id:(n,o)=>o.id=this.parseString(n.value),domain:(n,o)=>o.domain=this.parseString(n.value)}),i}},W=class extends u{constructor(){super(...arguments);this.name="copyright-converter";this.supportedTags=["copyright"]}convert(t,r){var n;let i={};return(n=t.attributes)!=null&&n.author&&(i.author=t.attributes.author),this.processChildren(t,i,{year:(o,s)=>s.year=this.parseString(o.value),license:(o,s)=>s.license=this.parseString(o.value)}),i}},j=class extends u{constructor(){super(...arguments);this.name="bounds-converter";this.supportedTags=["bounds"]}convert(t,r){let i={};return this.extractAttributes(t,i,{minlat:"minlat",minlon:"minlon",maxlat:"maxlat",maxlon:"maxlon"}),i}};import{Parser as Ue}from"htmlparser2";var N=(i=>(i.TOKENIZE="tokenize",i.AST_GENERATE="ast_generate",i.CONVERT="convert",i.COMPLETE="complete",i))(N||{}),K=class{constructor(){this.stage="tokenize"}async process(e){let t=Date.now();if(!e.xmlContent)throw new Error("XML content cannot be empty");let r=[],i=new Ue({onopentag(n,o){r.push({type:"open",tag:n,attributes:o})},ontext(n){let o=n.replace(/\n/g,"").trim();o&&r.push({type:"text",tag:"text",value:o})},onclosetag(n){r.push({type:"close",tag:n})}},{xmlMode:!0});return i.write(e.xmlContent),i.end(),e.tokens=r,e.performance.tokenizeTime=Date.now()-t,e}},Y=class{constructor(){this.stage="ast_generate"}async process(e){var o;let t=Date.now();if(!e.tokens)throw new Error("Tokens cannot be empty");let r=[],i,n=null;for(let s of e.tokens)if(s.type==="open"){let a={tag:s.tag,attributes:s.attributes||{},children:[]};i?n&&((o=n.children)==null||o.push(a)):i=a,r.push(a),n=a}else s.type==="text"&&n?n.value=s.value:s.type==="close"&&(r.pop(),n=r[r.length-1]||null);return e.ast=i,e.performance.astTime=Date.now()-t,e}},Z=class{constructor(e){this.getConverter=e;this.stage="convert"}async process(e){var i;let t=Date.now();if(!e.ast)throw new Error("AST cannot be empty");let r={};return e.ast.attributes&&Object.entries(e.ast.attributes).forEach(([n,o])=>{n.startsWith("xmlns:")?r[n]=o.replace(/&#39;/g,"'"):n==="xsi:schemaLocation"?r[n]=o.replace(/&#39;/g,"'"):r[n]=o}),(i=e.ast.children)==null||i.forEach(n=>{let o=this.getConverter(n.tag);try{let s=o.convert(n,e);s&&this.assignResult(r,n.tag,s)}catch(s){e.errors.push(s)}}),e.result=r,e.performance.convertTime=Date.now()-t,e}assignResult(e,t,r){switch(t){case"metadata":e.metadata=r;break;case"wpt":e.wpt||(e.wpt=[]),e.wpt.push(r);break;case"rte":e.rte||(e.rte=[]),e.rte.push(r);break;case"trk":e.trk||(e.trk=[]),e.trk.push(r);break;case"extensions":e.extensions=r;break}}},q=class{constructor(){this.stage="complete"}async process(e){e.performance.endTime=Date.now();let t=e.performance.endTime-e.performance.startTime;return e.metadata.set("performance",{totalTime:t,tokenizeTime:e.performance.tokenizeTime,astTime:e.performance.astTime,convertTime:e.performance.convertTime}),e}};var 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 K,new Y,new Z(e=>this.getConverter(e)),new q]}async registerDefaultConverters(){var t;if(this.defaultConvertersRegistered)return;let e=[new O,new $,new G,new B,new H,new z,new V,new U,new W,new j];for(let r of e)(t=r.supportedTags)==null||t.forEach(i=>{this.addConverterForTag(i,r)}),this.registeredPlugins.add(r.name);this.defaultConvertersRegistered=!0}addConverterForTag(e,t){this.converterPlugins.has(e)||this.converterPlugins.set(e,[]);let r=this.converterPlugins.get(e);r.push(t),r.sort((i,n)=>(i.priority||100)-(n.priority||100))}async registerConverter(e){var r,n;if(this.registeredPlugins.has(e.name))throw new Error(`Converter plugin ${e.name} already exists`);(r=e.supportedTags)==null||r.forEach(o=>{this.addConverterForTag(o,e)}),this.registeredPlugins.add(e.name);let t=e.priority!==void 0?` (priority: ${e.priority})`:"";(n=e.supportedTags)==null||n.forEach(o=>{let a=(this.converterPlugins.get(o)||[]).map(c=>`${c.name}(${c.priority||100})`)})}async registerMiddleware(e){let t=this.middlewarePlugins.findIndex(i=>i.name===e.name);t!==-1?this.middlewarePlugins[t]=e:this.middlewarePlugins.push(e);let r=[];e.onTokenize&&r.push("onTokenize"),e.onAstGenerate&&r.push("onAstGenerate"),e.onConvert&&r.push("onConvert"),e.onComplete&&r.push("onComplete"),e.onError&&r.push("onError"),r.length>0}getConverter(e){let t=this.converterPlugins.get(e);return t&&t.length>0?t[0]:void 0}getAllConverters(e){return this.converterPlugins.get(e)||[]}unregisterConverter(e){let t;for(let[r,i]of this.converterPlugins){let n=i.findIndex(o=>o.name===e);n!==-1&&(t=i[n],i.splice(n,1),i.length===0&&this.converterPlugins.delete(r))}t&&this.registeredPlugins.delete(e)}unregisterMiddleware(e){let t=this.middlewarePlugins.findIndex(r=>r.name===e);t!==-1&&this.middlewarePlugins.splice(t,1)}listConverters(){return Array.from(this.converterPlugins.keys())}listConverterPlugins(){return Array.from(this.registeredPlugins)}listMiddlewares(){return this.middlewarePlugins.map(e=>e.name)}listProcessors(){return this.processors.map(e=>e.constructor.name)}getConverterDetails(e){let t={};if(e){let r=this.converterPlugins.get(e);r&&(t[e]=r.map(i=>({name:i.name,priority:i.priority||100})))}else for(let[r,i]of this.converterPlugins)t[r]=i.map(n=>({name:n.name,priority:n.priority||100}));return t}getMiddlewareDetails(){return this.middlewarePlugins.map(e=>{let t=[];return e.onTokenize&&t.push("onTokenize"),e.onAstGenerate&&t.push("onAstGenerate"),e.onConvert&&t.push("onConvert"),e.onComplete&&t.push("onComplete"),e.onError&&t.push("onError"),{name:e.name,hooks:t}})}async initialize(){var r;if(this.initialized)return;await this.registerDefaultConverters();let e=this.createContext(),t=[...Array.from(this.converterPlugins.values()).flat(),...this.middlewarePlugins];for(let i of t)try{await((r=i.initialize)==null?void 0:r.call(i,e))}catch{}this.initialized=!0}async destroy(){var r;if(!this.initialized)return;let e=this.createContext(),t=[...Array.from(this.converterPlugins.values()).flat(),...this.middlewarePlugins];for(let i of t)try{await((r=i.destroy)==null?void 0:r.call(i,e))}catch{}this.initialized=!1}createContext(){return{metadata:new Map,errors:[],warnings:[],stats:{startTime:Date.now(),processedTokens:0,convertedElements:0},performance:{startTime:Date.now()}}}async executeMiddlewareHook(e,t,r){var n;let i=t;for(let o of this.middlewarePlugins){let s=o[e];if(s)try{i=await s.call(o,i,r)||i}catch(a){r.errors.push(a),await((n=o.onError)==null?void 0:n.call(o,a,r))}}return i}async parserByBuffer(e){var r;await this.initialize();let t=this.createContext();t.rawData=e,t.xmlContent=e.toString("utf-8"),t.metadata.set("decoder",this);try{for(let i of this.processors)try{switch(t=await i.process(t),i.stage){case"tokenize":t.tokens&&(t.tokens=await this.executeMiddlewareHook("onTokenize",t.tokens,t));break;case"ast_generate":t.ast&&(t.ast=await this.executeMiddlewareHook("onAstGenerate",t.ast,t));break;case"convert":t.result&&(t.result=await this.executeMiddlewareHook("onConvert",t.result,t));break;case"complete":t.result&&(t.result=await this.executeMiddlewareHook("onComplete",t.result,t));break}}catch(n){t.errors.push(n);for(let o of this.middlewarePlugins)await((r=o.onError)==null?void 0:r.call(o,n,t))}return t.result}catch(i){throw i}}convertExtensions(e){var o,s;let t={},{attributes:r,tag:i,value:n}=e;if(r&&Object.entries(r).forEach(([a,c])=>{t[a]=c}),(o=e==null?void 0:e.children)!=null&&o.length)(s=e.children)==null||s.forEach(a=>{t[a.tag]=this.convertExtensions(a)});else if(n!==void 0)return n;return t}};import _e from"dayjs";import We from"dayjs/plugin/utc.js";var we={temperature:"atemp",wtemp:"wtemp",heartRate:"hr",cadence:"cad"};var Se={temperature:"Temperature",Depth:"Depth"};_e.extend(We);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
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(`
3
+ `)}buildGPXContent(e){let{metadata:t,wpt:r=[],rte:i=[],trk:n=[]}=e,o=[];return t&&o.push(this.buildMetadata(t)),r.forEach(s=>{o.push(this.buildWaypoint(s,"wpt"))}),i.forEach(s=>{o.push(this.buildRoute(s))}),n.forEach(s=>{o.push(this.buildTrack(s))}),o.join(`
4
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
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
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(`
7
+ `)}buildBounds(e){let t=this.escapeXMLAttribute((e.minlat||0).toString()),r=this.escapeXMLAttribute((e.minlon||0).toString()),i=this.escapeXMLAttribute((e.maxlat||0).toString()),n=this.escapeXMLAttribute((e.maxlon||0).toString());return`<bounds minlat="${t}" minlon="${r}" maxlat="${i}" maxlon="${n}"/>`}buildWaypoint(e,t){var i,n,o;if(!this.isValidCoordinate(e.lat,e.lon))return"";let r=[`<${t} lat="${this.escapeXMLAttribute(this.formatCoordinate(e.lat))}" lon="${this.escapeXMLAttribute(this.formatCoordinate(e.lon))}">`];if(this.addOptionalElement(r,"ele",(i=e.ele)==null?void 0:i.toString(),this.formatElevation),e.time&&r.push(this.buildTimeElement(e.time)),this.addOptionalElement(r,"speed",(n=e.speed)==null?void 0:n.toString()),this.addOptionalElement(r,"course",(o=e.course)==null?void 0:o.toString()),this.addStandardWaypointElements(r,e),e.extensions){let s=this.processPointExtensions(e,e.extensions);Object.keys(s).length>0&&r.push(this.buildExtensions(s))}return r.push(`</${t}>`),r.join(`
8
+ `)}addStandardWaypointElements(e,t){var r,i,n,o,s,a,c;this.addOptionalElement(e,"magvar",(r=t.magvar)==null?void 0:r.toString()),this.addOptionalElement(e,"geoidheight",(i=t.geoidheight)==null?void 0:i.toString()),this.addOptionalElement(e,"name",t.name),this.addOptionalElement(e,"cmt",t.cmt),this.addOptionalElement(e,"desc",t.desc),this.addOptionalElement(e,"src",t.src),t.link&&this.addLinks(e,t.link),this.addOptionalElement(e,"sym",t.sym),this.addOptionalElement(e,"type",t.type),this.addOptionalElement(e,"fix",t.fix),this.addOptionalElement(e,"sat",t.sat),this.addOptionalElement(e,"hdop",(n=t.hdop)==null?void 0:n.toString()),this.addOptionalElement(e,"vdop",(o=t.vdop)==null?void 0:o.toString()),this.addOptionalElement(e,"pdop",(s=t.pdop)==null?void 0:s.toString()),this.addOptionalElement(e,"ageofdgpsdata",(a=t.ageofdgpsdata)==null?void 0:a.toString()),this.addOptionalElement(e,"dgpsid",(c=t.dgpsid)==null?void 0:c.toString())}buildRoute(e){var r;let t=["<rte>"];return this.addRouteTrackCommonElements(t,e),e.rtept&&((r=e.rtept)==null||r.forEach(i=>{t.push(this.buildWaypoint(i,"rtept"))})),e.extensions&&t.push(this.buildExtensions(e.extensions)),t.push("</rte>"),t.join(`
9
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
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(`
11
+ `)}addRouteTrackCommonElements(e,t){var r;this.addOptionalElement(e,"name",t.name),this.addOptionalElement(e,"cmt",t.cmt),this.addOptionalElement(e,"desc",t.desc),this.addOptionalElement(e,"src",t.src),t.link&&this.addLinks(e,t.link),this.addOptionalElement(e,"number",(r=t.number)==null?void 0:r.toString()),this.addOptionalElement(e,"type",t.type)}processPointExtensions(e,t){let r=this.deepClone(t),i=this.buildTrackPointExtension(e,t);Object.keys(i).length>0&&(r["gpxtpx:TrackPointExtension"]=i);let n=this.buildPowerExtension(e,t);Object.keys(n).length>0&&(r["gpxpx:PowerExtension"]=n);let o=this.buildGpxExtensions(e,t);return Object.keys(o).length>0&&(r["gpxx:GpxExtensions"]=o),r}buildTrackPointExtension(e,t){let r=this.deepClone(t["gpxtpx:TrackPointExtension"]||{}),i=Object.keys(we);return Object.keys(e).filter(n=>i.includes(n)).forEach(n=>{let o=we[n];o&&e[n]!==void 0&&(r[`gpxtpx:${o}`]=e[n])}),r}buildPowerExtension(e,t){return this.deepClone(t["gpxpx:PowerExtension"]||{})}buildGpxExtensions(e,t){let r=this.deepClone(t["gpxx:GpxExtensions"]||{}),i=Object.keys(Se);return Object.keys(e).filter(n=>i.includes(n)).forEach(n=>{let o=Se[n];o&&e[n]!==void 0&&(r[`gpxx:${o}`]=e[n])}),r}buildExtensions(e){let t=this.buildExtensionContent(e);return t?`<extensions>${t}</extensions>`:""}buildExtensionContent(e){return Object.entries(e).filter(([t])=>!t.startsWith("xmlns")).map(([t,r])=>{if(r&&typeof r=="object"){let i=this.buildExtensionContent(r);return`<${t}>${i}</${t}>`}else if(r!=null)return`<${t}>${this.escapeXML(String(r))}</${t}>`;return""}).filter(t=>t).join("")}buildLink(e){let t=[`<link href="${this.escapeXMLAttribute(e.href||"")}">`];return this.addOptionalElement(t,"text",e.text),this.addOptionalElement(t,"type",e.type),t.push("</link>"),t.join("")}addLinks(e,t){(Array.isArray(t)?t:[t]).forEach(i=>{e.push(this.buildLink(i))})}buildTimeElement(e){return typeof e=="string"&&/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z?$/.test(e)?`<time>${e}</time>`:`<time>${_e(e).utc().format("YYYY-MM-DDTHH:mm:ss[Z]")}</time>`}addOptionalElement(e,t,r,i){if(r!=null&&r!==""){let n=i?i(r):this.escapeXML(r);e.push(`<${t}>${n}</${t}>`)}}isValidCoordinate(e,t){return e!=null&&t!==void 0&&t!==null&&!isNaN(e)&&!isNaN(t)}formatCoordinate(e){return this.roundTo(e,6).toString()}roundTo(e,t){let r=Math.pow(10,t);return Math.round(e*r)/r}escapeXML(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;")}escapeXMLAttribute(e){return typeof e!="string"?String(e||""):e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/'/g,"&apos;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/\r/g,"&#13;").replace(/\n/g,"&#10;").replace(/\t/g,"&#9;")}deepClone(e){if(e===null||typeof e!="object")return e;if(e instanceof Date)return new Date(e.getTime());if(Array.isArray(e))return e.map(r=>this.deepClone(r));let t={};for(let r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=this.deepClone(e[r]));return t}encoder(e){return this.encode(e)}};var be=class extends A{constructor(){super(...arguments);this.name="performance-middleware";this.description="Monitor parsing performance"}async onTokenize(t,r){return t}async onAstGenerate(t,r){let i=this.countNodes(t);return t}async onComplete(t,r){let i=r.metadata.get("performance");return t}countNodes(t){let r=1;if(t.children)for(let i of t.children)r+=this.countNodes(i);return r}},Ie=class extends A{constructor(){super(...arguments);this.name="validation-middleware";this.description="Validate GPX data integrity"}async onComplete(t,r){let i=this.validateGPX(t);return i.length>0&&r.metadata.set("validation-errors",i),t}validateGPX(t){let r=[];if(t.version||r.push("Missing GPX version information"),t.creator||r.push("Missing GPX creator information"),t.trk){for(let i of t.trk)if(i.trkseg){for(let n of i.trkseg)if(n.trkpt)for(let o of n.trkpt)(typeof o.lat!="number"||typeof o.lon!="number")&&r.push("Invalid track point coordinates")}}return r}};async function Xe(p){let e=[new be,new Ie];for(let t of e)await p.registerMiddleware(t)}var je={GPXDecoder:C,GPXEncoder:P,registerDefaultMiddlewares:Xe,PipelineStage:N};var J=class{constructor(){this.stage="parse"}async process(e){let t=Date.now();if(!e.rawData)throw new Error("FIT data cannot be empty");try{let r=await this.parseWithFitSDK(e.rawData);return e.rawMessages=r,e.performance.parseTime=Date.now()-t,e}catch(r){throw new Error(`FIT parsing failed: ${r.message}`)}}async parseWithFitSDK(e){let{Decoder:t,Stream:r}=await import("@garmin/fitsdk"),i=r.fromBuffer(e);if(!t.isFIT(i))throw new Error("Not a valid FIT file");let n=new t(i),{messages:o,errors:s}=n.read();return s&&s.length>0,o}},Q=class{constructor(e){this.getConverters=e;this.stage="extract"}async process(e){let t=Date.now();if(!e.rawMessages)throw new Error("Raw messages cannot be empty");let r={};for(let[i,n]of Object.entries(e.rawMessages)){if(!Array.isArray(n)||n.length===0){r[i]=n;continue}let o=this.getConverters(i);if(o.length===0)r[i]=n;else{let s=o[0];try{let a=s.convertMessages(n,e);r[i]=a}catch(a){e.errors.push(a),r[i]=n}}}return e.rawMessages=r,e.performance.extractTime=Date.now()-t,e}},ee=class{constructor(e){this.getStructurePlugins=e;this.stage="structure"}async process(e){let t=Date.now();if(!e.rawMessages)throw new Error("Message data cannot be empty");let r={},i=this.getStructurePlugins();for(let n of i)try{let o=n.structureData(e.rawMessages,e);r={...r,...o}}catch(o){e.errors.push(o)}return e.result=r,e.performance.structureTime=Date.now()-t,e}},te=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:i,lapMesgs:n,recordMesgs:o}=t;return i!=null&&i.length?{sessionMesgs:i.map(a=>{let c=T(a.startTime).valueOf(),d=T(a.timestamp).valueOf(),f=((n==null?void 0:n.filter(g=>{let k=T(g.startTime).valueOf(),F=T(g.timestamp).valueOf();return k>=c&&F<=d}))||[]).map(g=>{let k=T(g.startTime).valueOf(),F=T(g.timestamp).valueOf(),L=(o==null?void 0:o.filter(Ve=>{let De=T(Ve.timestamp).valueOf();return De>=k&&De<=F}))||[];return{...g,recordMesgs:L}});return{...a,lapMesgs:f}})}:{}}},_=class extends y{constructor(){super(...arguments);this.name="CourseStructurePlugin";this.priority=10}structureData(t,r){let{courseMesgs:i,lapMesgs:n,recordMesgs:o}=t;if(!(i!=null&&i.length))return{};let s=2e3;return{courseMesgs:i.map(c=>{let d=(n==null?void 0:n.map(l=>{let f=T(l.startTime).valueOf(),g=T(l.timestamp).valueOf(),k=(o==null?void 0:o.filter(F=>{let L=T(F.timestamp).valueOf();return L>=f-s&&L<=g+s}))||[];return{...l,recordMesgs:k}}))||[];return{...c,lapMesgs:d}})}}},X=class extends y{constructor(){super(...arguments);this.name="FileHeaderPlugin";this.priority=1}structureData(t,r){let{fileIdMesgs:i}=t;if(i!=null&&i.length&&i[0]){let n=i[0];r.fileHeader={type:n.type,manufacturer:n.manufacturer,product:n.product}}return{}}};var 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 J,new Q(e=>this.getConverters(e)),new ee(()=>this.structurePlugins),new te]}async registerDefaultPlugins(){if(this.defaultPluginsRegistered)return;let e=[new X,new D,new _];for(let t of e)this.addStructurePlugin(t),this.registeredPlugins.add(t.name);this.defaultPluginsRegistered=!0}addConverterForMessageType(e,t){this.converterPlugins.has(e)||this.converterPlugins.set(e,[]);let r=this.converterPlugins.get(e);r.push(t),r.sort((i,n)=>(i.priority||100)-(n.priority||100))}addStructurePlugin(e){this.structurePlugins.push(e),this.structurePlugins.sort((t,r)=>(t.priority||100)-(r.priority||100))}async registerMessageConverter(e){if(this.registeredPlugins.has(e.name))throw new Error(`Message converter plugin ${e.name} already exists`);e.supportedMessageTypes.forEach(r=>{this.addConverterForMessageType(r,e)}),this.registeredPlugins.add(e.name);let t=e.priority!==void 0?` (priority: ${e.priority})`:"";e.supportedMessageTypes.forEach(r=>{let n=(this.converterPlugins.get(r)||[]).map(o=>`${o.name}(${o.priority||100})`)})}async registerStructurePlugin(e){if(this.registeredPlugins.has(e.name))throw new Error(`Structure plugin ${e.name} already exists`);this.addStructurePlugin(e),this.registeredPlugins.add(e.name);let t=e.priority!==void 0?` (priority: ${e.priority})`:""}async registerMiddleware(e){let t=this.middlewarePlugins.findIndex(i=>i.name===e.name);t!==-1?this.middlewarePlugins[t]=e:(this.middlewarePlugins.push(e),this.middlewarePlugins.sort((i,n)=>(i.priority||100)-(n.priority||100)));let r=[];e.onParse&&r.push("onParse"),e.onExtractMessages&&r.push("onExtractMessages"),e.onStructure&&r.push("onStructure"),e.onComplete&&r.push("onComplete"),e.onError&&r.push("onError"),r.length>0}getConverter(e){let t=this.converterPlugins.get(e);return t&&t.length>0?t[0]:void 0}getConverters(e){return this.converterPlugins.get(e)||[]}unregisterPlugin(e){if(!this.registeredPlugins.has(e))return!1;for(let[i,n]of this.converterPlugins){let o=n.findIndex(s=>s.name===e);o!==-1&&(n.splice(o,1),n.length===0&&this.converterPlugins.delete(i))}let t=this.structurePlugins.findIndex(i=>i.name===e);t!==-1&&this.structurePlugins.splice(t,1);let r=this.middlewarePlugins.findIndex(i=>i.name===e);return r!==-1&&this.middlewarePlugins.splice(r,1),this.registeredPlugins.delete(e),!0}async initialize(){var r;if(this.initialized)return;await this.registerDefaultPlugins();let e=this.createContext(),t=[...Array.from(this.converterPlugins.values()).flat(),...this.structurePlugins,...this.middlewarePlugins];for(let i of t)try{await((r=i.initialize)==null?void 0:r.call(i,e))}catch{}this.initialized=!0}async destroy(){var r;if(!this.initialized)return;let e=this.createContext(),t=[...Array.from(this.converterPlugins.values()).flat(),...this.structurePlugins,...this.middlewarePlugins];for(let i of t)try{await((r=i.destroy)==null?void 0:r.call(i,e))}catch{}this.initialized=!1}createContext(){return{metadata:new Map,errors:[],warnings:[],stats:{startTime:Date.now(),processedTokens:0,convertedElements:0},performance:{startTime:Date.now()}}}async executeMiddlewareHook(e,t,r){var n;let i=t;for(let o of this.middlewarePlugins){let s=o[e];if(s)try{i=await s.call(o,i,r)||i}catch(a){r.errors.push(a),await((n=o.onError)==null?void 0:n.call(o,a,r))}}return i}async parseByBuffer(e,t={}){var i;await this.initialize();let r=this.createContext();r.rawData=e,r.userData=t.userData,r.metadata.set("decoder",this);try{for(let n of this.processors)try{switch(r=await n.process(r),n.stage){case"parse":r.rawData&&(r.rawData=await this.executeMiddlewareHook("onParse",r.rawData,r));break;case"extract":r.rawMessages&&(r.rawMessages=await this.executeMiddlewareHook("onExtractMessages",r.rawMessages,r));break;case"structure":r.result&&(r.result=await this.executeMiddlewareHook("onStructure",r.result,r));break;case"complete":r.result&&(r.result=await this.executeMiddlewareHook("onComplete",r.result,r));break}}catch(o){r.errors.push(o);for(let s of this.middlewarePlugins)await((i=s.onError)==null?void 0:i.call(s,o,r))}return r.result||{}}catch(n){throw n}}};var Ke={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=Ke[p];return{size:1,baseType:0,mapValue:t=>typeof t=="string"?e[t]??255:t,setValue:function(t,r){this.setUint8(t,r)}}},ke={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(Me(p)),setValue:Ze},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 Re(p){return Array.from(Me(p)).length+1}function*Me(p){for(let e of Ye(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*Ye(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 Ze(p,e){for(let t=0;t<e.length;t++)this.setUint8(p+t,e[t])}var qe={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"}]}},Ne=(p,e)=>p.map(t=>({...t,value:e[t.name]})).filter(({value:t})=>t!==void 0),re=class p{static check(e,t,r,i){if(t===void 0)throw new Error(`Message '${e}' not known`);if(r===void 0)throw new Error(`Message '${e}' has no field definitions`);let n=r.map(s=>s.name),o=Object.keys(i).filter(s=>!n.includes(s));if(o.length)throw new Error(`Message '${e}' has no field definitions named '${o}'`)}constructor(e,t,r){let i=qe[t];if(!i)throw new Error(`Unknown message type: ${t}`);let{mesgNum:n,fieldDefns:o}=i;p.check(t,n,o,r),this.localNum=e,this.mesgNum=n,this.fields=Ne(o,r)}get mesgDefn(){let e=this.fields.map(({number:t,type:r,value:i})=>{let n=ke[r];if(!n)throw new Error(`Unknown type: ${r}`);let{size:o,baseType:s}=n;return r==="string"?{number:t,size:Re(i),baseType:s}:{number:t,size:o,baseType:s}});return{localNum:this.localNum,mesgNum:this.mesgNum,fieldDefns:e}}isSameDefn(e){let t=(s,a)=>s.number===a.number&&s.size===a.size&&s.baseType===a.baseType,r=(s,a)=>s.length===a.length&&s.every((c,d)=>t(c,a[d])),{localNum:i,mesgNum:n,fieldDefns:o}=this.mesgDefn;return n===e.mesgNum&&i===e.localNum&&r(o,e.fieldDefns)}get defnRecord(){let{localNum:e,mesgNum:t,fieldDefns:r}=this.mesgDefn,i=6+3*r.length,n=new DataView(new ArrayBuffer(i));n.setUint8(0,64|e),n.setUint8(2,1),n.setUint16(3,t),n.setUint8(5,r.length);let o=6;for(let s of r)n.setUint8(o++,s.number),n.setUint8(o++,s.size),n.setUint8(o++,s.baseType);return n.buffer}get dataRecord(){let{fieldDefns:e}=this.mesgDefn,t=1+e.reduce((n,{size:o})=>n+o,0),r=new DataView(new ArrayBuffer(t));r.setUint8(0,this.localNum);let i=1;for(let{number:n,type:o,value:s}of this.fields){let a=ke[o];if(!a)throw new Error(`Unknown type: ${o}`);let{size:c,setValue:d}=a,l;"mapValue"in a?l=a.mapValue(s):l=s,d&&d.call(r,i,l),i+=c}return r.buffer}};var Je=[0,52225,55297,5120,61441,15360,10240,58369,40961,27648,30720,46081,20480,39937,34817,17408],Le=(p,e)=>(p>>>4^Je[p&15^e])&65535,Qe=(p,e,t)=>Le(Le(p,e),t),et=(p,e)=>Qe(p,e&15,e>>>4);function Fe(p,e=0){let t=e,r=p instanceof ArrayBuffer?new Uint8Array(p):p;for(let i=0;i<r.length;i++)t=et(t,r[i]);return t}import tt from"dayjs";var Oe=14,rt=16,nt=2078,it=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 file must contain at least one Session");let r=0,i=[],n=[];for(let o of t){if(o.lapMesgs&&this.buildEventsFromLaps(o.lapMesgs,i),o.lapMesgs)for(let s of o.lapMesgs)s.recordMesgs&&this.buildRecords(s.recordMesgs);o.lapMesgs&&this.buildLaps(o.lapMesgs),this.buildSession(o),r++,this.buildActivityFromSession(o,n)}i.forEach(o=>this.buildEvent(o)),n.forEach(o=>this.buildActivity(o))}buildCourseContent(e){let t=e.sessionMesgs||[];if(t.length===0)throw new Error("Course file must contain track data");let r=t[0];if(this.buildCourse({name:"course",sport:this.options.defaultSport}),r.lapMesgs){let i=[];for(let s of r.lapMesgs)s.recordMesgs&&i.push(...s.recordMesgs);i.sort((s,a)=>s.timestamp&&a.timestamp?new Date(s.timestamp).getTime()-new Date(a.timestamp).getTime():(s.distance||0)-(a.distance||0));let n=i[0],o=i[i.length-1];n.timestamp&&this.buildEvent({timestamp:n.timestamp,event:"timer",eventType:"start",eventGroup:0}),i.forEach(s=>this.buildRecord(s)),o.timestamp&&this.buildEvent({timestamp:o.timestamp,event:"timer",eventType:"stop_all",eventGroup:0}),r.lapMesgs[0]&&this.buildLap(r.lapMesgs[0])}}buildFileId(e,t){var i;let r=((i=e.fileIdMesgs)==null?void 0:i[0])||{};this.writeMesg("file_id",{type:t,time_created:r.timeCreated?this.parseTimestamp(r.timeCreated):Date.now(),manufacturer:r.manufacturer,product:r.product,serial_number:r.serialNumber})}buildSession(e){var t;this.writeMesg("session",{timestamp:e.timestamp?this.parseTimestamp(e.timestamp):void 0,start_time:e.startTime?this.parseTimestamp(e.startTime):void 0,total_elapsed_time:e.totalElapsedTime,total_timer_time:e.totalTimerTime,start_position_lat:this.convertToSemicircles(e.startPositionLat),start_position_long:this.convertToSemicircles(e.startPositionLong),total_distance:e.totalDistance,total_ascent:e.totalAscent,total_descent:e.totalDescent,sport:e.sport||this.options.defaultSport,sub_sport:e.subSport||this.options.defaultSubSport,first_lap_index:e.firstLapIndex||0,num_laps:e.numLaps||((t=e.lapMesgs)==null?void 0:t.length)||1})}buildLaps(e){e.forEach(t=>this.buildLap(t))}buildLap(e){this.writeMesg("lap",{timestamp:e.timestamp?this.parseTimestamp(e.timestamp):void 0,start_time:e.startTime?this.parseTimestamp(e.startTime):void 0,start_position_lat:this.convertToSemicircles(e.startPositionLat),start_position_long:this.convertToSemicircles(e.startPositionLong),end_position_lat:this.convertToSemicircles(e.endPositionLat),end_position_long:this.convertToSemicircles(e.endPositionLong),total_elapsed_time:e.totalElapsedTime,total_timer_time:e.totalTimerTime,total_distance:e.totalDistance,total_ascent:e.totalAscent,total_descent:e.totalDescent})}buildRecords(e){e.forEach(t=>this.buildRecord(t))}buildRecord(e){this.writeMesg("record",{timestamp:e.timestamp?this.parseTimestamp(e.timestamp):void 0,position_lat:this.convertToSemicircles(e.positionLat),position_long:this.convertToSemicircles(e.positionLong),altitude:e.enhancedAltitude||e.altitude,distance:e.distance,heart_rate:e.heartRate,cadence:e.cadence,speed:e.enhancedSpeed||e.speed,power:e.power})}buildEvent(e){this.writeMesg("event",{timestamp:e.timestamp?this.parseTimestamp(e.timestamp):void 0,event:e.event,event_type:e.eventType,event_group:e.eventGroup})}buildActivity(e){this.writeMesg("activity",{timestamp:e.timestamp?this.parseTimestamp(e.timestamp):void 0,total_timer_time:e.totalTimerTime,num_sessions:e.numSessions,type:e.type,event:e.event,event_type:e.eventType,local_timestamp:e.localTimestamp?this.parseTimestamp(e.localTimestamp):void 0,event_group:e.eventGroup})}buildCourse(e){this.writeMesg("course",{name:e.name,sport:e.sport})}buildEventsFromLaps(e,t){e.forEach((r,i)=>{r.startTime&&t.push({timestamp:r.startTime,event:"timer",eventType:"start",eventGroup:i}),r.timestamp&&t.push({timestamp:r.timestamp,event:"timer",eventType:i===e.length-1?"stop_all":"stop",eventGroup:i})})}buildActivityFromSession(e,t){t.push({timestamp:e.timestamp,totalTimerTime:e.totalTimerTime,numSessions:1,type:e.sport||this.options.defaultSport,event:"activity",eventType:"stop",eventGroup:0})}parseTimestamp(e){return typeof e=="number"?e:tt(e).valueOf()}convertToSemicircles(e){if(e!=null)return Math.round(e*2**31/180)}validateRequiredFields(e){if(!e.sessionMesgs||e.sessionMesgs.length===0)throw new Error("FIT file must contain at least one Session")}writeMesg(e,t){let r=Object.fromEntries(Object.entries(t).filter(([s,a])=>a!==void 0));if(Object.keys(r).length===0)return;let i=this.localNum[e];i===void 0&&(i=this.localNum[e]=Object.keys(this.localNum).length);let n=new re(i,e,r),o=this.mesgDefn[i];(!o||!n.isSameDefn(o))&&(this.messages.push(n.defnRecord),this.mesgDefn[i]=n.mesgDefn),this.messages.push(n.dataRecord)}get blob(){let e=[this.header,...this.messages,this.trailer];return new Blob(e,{type:"application/octet-stream"})}get dataLen(){return this.messages.reduce((e,t)=>e+t.byteLength,0)}get dataCrc(){return this.messages.reduce((e,t)=>Fe(t,e),0)}get header(){let e=new DataView(new ArrayBuffer(Oe));return e.setUint8(0,Oe),e.setUint8(1,rt),e.setUint16(2,nt,!0),e.setUint32(4,this.dataLen,!0),e.setUint32(8,it),e.setUint16(12,Fe(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 ne=class extends m{constructor(){super(...arguments);this.name="PositionConverter";this.supportedTags=["Position"]}convert(t,r){let i={};return this.processChildren(t,i,{LatitudeDegrees:(n,o)=>o.LatitudeDegrees=this.parseString(n.value),LongitudeDegrees:(n,o)=>o.LongitudeDegrees=this.parseString(n.value)}),i}},ie=class extends m{constructor(){super(...arguments);this.name="TrackpointConverter";this.supportedTags=["Trackpoint"]}convert(t,r){let i={};return this.processChildren(t,i,{Time:(n,o)=>o.Time=this.parseString(n.value),Position:(n,o)=>{var a;let s=r.metadata.get("decoder");o.Position=(a=s==null?void 0:s.getConverter("Position"))==null?void 0:a.convert(n,r)},AltitudeMeters:(n,o)=>o.AltitudeMeters=this.parseFloat(n.value),DistanceMeters:(n,o)=>o.DistanceMeters=this.parseFloat(n.value),HeartRateBpm:(n,o)=>{if(n.value)o.HeartRateBpm=this.parseFloat(n.value);else{let s=this.getChildByTag(n,"Value");s!=null&&s.value&&(o.HeartRateBpm=this.parseFloat(s.value))}},Cadence:(n,o)=>{let s={Low:0,High:0};this.processChildren(n,s,{Low:(a,c)=>c.Low=this.parseFloat(a.value),High:(a,c)=>c.High=this.parseFloat(a.value)}),o.Cadence=s},SensorState:(n,o)=>o.SensorState=n.value,Extensions:(n,o)=>o.Extensions=this.convertExtensions(n)}),i}convertExtensions(t){var i;let r={};return(i=t.children)==null||i.forEach(n=>{r[n.tag]=this.convertExtensionContent(n)}),r}convertExtensionContent(t){var r;if((r=t.children)!=null&&r.length){let i={};return t.children.forEach(n=>{i[n.tag]=this.convertExtensionContent(n)}),i}else return t.value}},oe=class extends m{constructor(){super(...arguments);this.name="TrackConverter";this.supportedTags=["Track"]}convert(t,r){let i={Trackpoint:[]};return this.processChildren(t,i,{Trackpoint:(n,o)=>{var c;let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("Trackpoint"))==null?void 0:c.convert(n,r);a&&o.Trackpoint&&o.Trackpoint.push(a)}}),i}},se=class extends m{constructor(){super(...arguments);this.name="ActivityLapConverter";this.supportedTags=["Lap"]}convert(t,r){let i={};return this.extractAttributes(t,i,{StartTime:"Id"}),this.processChildren(t,i,{TotalTimeSeconds:(n,o)=>o.TotalTimeSeconds=this.parseFloat(n.value),DistanceMeters:(n,o)=>o.DistanceMeters=this.parseFloat(n.value),MaximumSpeed:(n,o)=>o.MaximumSpeed=this.parseFloat(n.value),Calories:(n,o)=>o.Calories=this.parseFloat(n.value),AverageHeartRateBpm:(n,o)=>o.AverageHeartRateBpm=this.parseFloat(n.value),MaximumHeartRateBpm:(n,o)=>o.MaximumHeartRateBpm=this.parseFloat(n.value),Intensity:(n,o)=>o.Intensity=n.value,TriggerMethod:(n,o)=>o.TriggerMethod=n.value,Track:(n,o)=>{var c;o.Track||(o.Track=[]);let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("Track"))==null?void 0:c.convert(n,r);a&&o.Track.push(a)},Notes:(n,o)=>o.Notes=this.parseString(n.value),Extensions:(n,o)=>o.Extensions=this.convertExtensions(n)}),i}convertExtensions(t){var i;let r={};return(i=t.children)==null||i.forEach(n=>{r[n.tag]=this.convertExtensionContent(n)}),r}convertExtensionContent(t){var r;if((r=t.children)!=null&&r.length){let i={};return t.children.forEach(n=>{i[n.tag]=this.convertExtensionContent(n)}),i}else return t.value}},ae=class extends m{constructor(){super(...arguments);this.name="ActivityConverter";this.supportedTags=["Activity"]}convert(t,r){let i={Id:"",Lap:[]};return this.extractAttributes(t,i,{Sport:"Sport"}),this.processChildren(t,i,{Id:(n,o)=>o.Id=this.parseString(n.value),Lap:(n,o)=>{var c;let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("Lap"))==null?void 0:c.convert(n,r);a&&o.Lap.push(a)},Notes:(n,o)=>o.Notes=this.parseString(n.value),Training:(n,o)=>o.Training=this.convertTraining(n),Creator:(n,o)=>o.Creator=this.convertCreator(n),Extensions:(n,o)=>o.Extensions=this.convertExtensions(n)}),i}convertTraining(t){var i;let r={};return t.attributes&&Object.entries(t.attributes).forEach(([n,o])=>{r[n]=o}),(i=t.children)==null||i.forEach(n=>{r[n.tag]=this.convertExtensionContent(n)}),r}convertCreator(t){var i;let r={};return(i=t.children)==null||i.forEach(n=>{r[n.tag]=this.convertExtensionContent(n)}),r}convertExtensions(t){var i;let r={};return(i=t.children)==null||i.forEach(n=>{r[n.tag]=this.convertExtensionContent(n)}),r}convertExtensionContent(t){var r;if((r=t.children)!=null&&r.length){let i={};return t.children.forEach(n=>{i[n.tag]=this.convertExtensionContent(n)}),i}else return t.value}},pe=class extends m{constructor(){super(...arguments);this.name="ActivityListConverter";this.supportedTags=["Activities"]}convert(t,r){let i={Activity:[],MultiSportSession:[]};return this.processChildren(t,i,{Activity:(n,o)=>{var c;let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("Activity"))==null?void 0:c.convert(n,r);a&&o.Activity&&o.Activity.push(a)},MultiSportSession:(n,o)=>{var c;let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("MultiSportSession"))==null?void 0:c.convert(n,r);a&&o.MultiSportSession&&o.MultiSportSession.push(a)}}),i}},ce=class extends m{constructor(){super(...arguments);this.name="MultiSportSessionConverter";this.supportedTags=["MultiSportSession"]}convert(t,r){let i={};return this.processChildren(t,i,{Id:(n,o)=>o.Id=this.parseString(n.value),FirstSport:(n,o)=>{var a;let s=r.metadata.get("decoder");o.FirstSport=(a=s==null?void 0:s.getConverter("FirstSport"))==null?void 0:a.convert(n,r)},NextSport:(n,o)=>{var c;o.NextSport||(o.NextSport=[]);let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("NextSport"))==null?void 0:c.convert(n,r);a&&o.NextSport.push(a)},Notes:(n,o)=>o.Notes=this.parseString(n.value)}),i}},de=class extends m{constructor(){super(...arguments);this.name="AbstractSourceConverter";this.supportedTags=["Author","Creator"]}convert(t,r){let i={};return this.processChildren(t,i,{Name:(n,o)=>o.Name=this.parseString(n.value)}),i}};import{Parser as $e}from"htmlparser2";var le=class{static tokenizeXML(e){let t=[],r=new $e({onopentag(i,n){t.push({type:"open",tag:i,attributes:n})},ontext(i){let n=i.replace(/\n/g,"").trim();n&&t.push({type:"text",tag:"text",value:n})},onclosetag(i){t.push({type:"close",tag:i})}},{xmlMode:!0});return r.write(e),r.end(),t}static compressXML(e){return e.replace(/>\s+</g,"><").replace(/\s+/g," ").trim()}static formatXML(e,t=2){let r=" ".repeat(t),i="",n=0,o=!1;for(let s=0;s<e.length;s++){let a=e[s],c=e[s+1];a==="<"?(c==="/"?(n--,o||(i+=`
12
+ `+r.repeat(n))):c!=="?"&&c!=="!"&&(o||(i+=`
13
+ `+r.repeat(n)),n++),o=!0):a===">"&&(o=!1,c==="<"&&e[s+2]==="/"&&n--),i+=a}return i.trim()}static validateXML(e){try{let t=new $e({},{xmlMode:!0});return t.write(e),t.end(),{isValid:!0}}catch(t){return{isValid:!1,error:t.message}}}static extractXMLDeclaration(e){let t=e.match(/<\?xml\s+([^>]+)\?>/);if(!t)return{};let r=t[1],i={},n=r.match(/version=["']([^"']+)["']/);n&&(i.version=n[1]);let o=r.match(/encoding=["']([^"']+)["']/);o&&(i.encoding=o[1]);let s=r.match(/standalone=["']([^"']+)["']/);return s&&(i.standalone=s[1]),i}static escapeXML(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}static unescapeXML(e){return e.replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&quot;/g,'"').replace(/&#39;/g,"'").replace(/&amp;/g,"&")}};var ue=class{constructor(){this.stage="tokenize";this.name="tokenize-processor"}async process(e){if(!e.xmlContent)throw new Error("TCX data cannot be empty");let t=le.tokenizeXML(e.xmlContent);if(t.length===0)throw new Error("Not a valid TCX file");return e.tokens=t,e.stats.processedTokens=t.length,e}},me=class{constructor(){this.stage="ast-generate";this.name="ast-generate-processor"}async process(e){if(!e.tokens||e.tokens.length===0)throw new Error("Tokens are empty, cannot generate AST");let t=this.buildAST(e.tokens);if(!t)throw new Error("Failed to generate AST");return e.ast=t,e}buildAST(e){if(e.length===0)return;let t=[],r;for(let i of e)if(i.type==="open"){let n={tag:i.tag,attributes:i.attributes,children:[]};r&&(r.children=r.children||[],r.children.push(n)),t.push(n),r=n,t.length||r||(r=n)}else i.type==="close"?(t.pop(),r=t[t.length-1]):i.type==="text"&&r&&i.value&&typeof i.value=="string"&&i.value.trim()&&(r.value=i.value.trim());return r}},Te=class{constructor(e){this.getConverter=e;this.stage="convert";this.name="convert-processor"}async process(e){if(!e.ast)throw new Error("AST is empty, cannot convert");let t=this.findTCXRoot(e.ast);if(!t)throw new Error("Not a valid TCX file: TrainingCenterDatabase element not found");let r=this.convertAST(t,e);return e.result=r,e.stats.convertedElements=this.countElements(e.ast),e}findTCXRoot(e){if(e.tag==="TrainingCenterDatabase")return e;if(e.children)for(let t of e.children){let r=this.findTCXRoot(t);if(r)return r}}convertAST(e,t){let r=this.getConverter(e.tag);return r?r.convert(e,t):this.genericConvert(e,t)}genericConvert(e,t){let r={};if(e.attributes&&Object.entries(e.attributes).forEach(([i,n])=>{r[i]=n}),e.value!==void 0)if(e.children&&e.children.length>0)r._value=e.value;else return e.value;return e.children&&e.children.forEach(i=>{let n=this.convertAST(i,t);r[i.tag]?(Array.isArray(r[i.tag])||(r[i.tag]=[r[i.tag]]),r[i.tag].push(n)):r[i.tag]=n}),r}countElements(e){let t=1;if(e.children)for(let r of e.children)t+=this.countElements(r);return t}},fe=class{constructor(){this.stage="complete";this.name="complete-processor"}async process(e){if(!e.result)throw new Error("No conversion result found");let t=Date.now(),r=t-e.performance.startTime;return e.performance.endTime=t,e.performance.processingTime=r,e.metadata.set("performance",{processingTime:r,processedTokens:e.stats.processedTokens,convertedElements:e.stats.convertedElements}),e}};var 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 ue,new me,new Te(e=>this.getConverter(e)),new fe]}async registerDefaultConverters(){var t;if(this.defaultConvertersRegistered)return;let e=[new ne,new ie,new oe,new se,new ae,new pe,new ce,new de];for(let r of e)(t=r.supportedTags)==null||t.forEach(i=>{this.addConverterForTag(i,r)}),this.registeredPlugins.add(r.name);this.defaultConvertersRegistered=!0}addConverterForTag(e,t){this.converterPlugins.has(e)||this.converterPlugins.set(e,[]);let r=this.converterPlugins.get(e);r.push(t),r.sort((i,n)=>(i.priority||100)-(n.priority||100))}async registerConverter(e){var r,n;if(this.registeredPlugins.has(e.name))throw new Error(`Converter plugin ${e.name} already exists`);(r=e.supportedTags)==null||r.forEach(o=>{this.addConverterForTag(o,e)}),this.registeredPlugins.add(e.name);let t=e.priority!==void 0?` (priority: ${e.priority})`:"";(n=e.supportedTags)==null||n.forEach(o=>{let a=(this.converterPlugins.get(o)||[]).map(c=>`${c.name}(${c.priority||100})`)})}async registerMiddleware(e){let t=this.middlewarePlugins.findIndex(i=>i.name===e.name);t!==-1?this.middlewarePlugins[t]=e:this.middlewarePlugins.push(e);let r=[];e.onTokenize&&r.push("onTokenize"),e.onAstGenerate&&r.push("onAstGenerate"),e.onConvert&&r.push("onConvert"),e.onComplete&&r.push("onComplete"),e.onError&&r.push("onError"),r.length>0}getConverter(e){let t=this.converterPlugins.get(e);return t&&t.length>0?t[0]:void 0}getAllConverters(e){return this.converterPlugins.get(e)||[]}unregisterConverter(e){let t;for(let[r,i]of this.converterPlugins){let n=i.findIndex(o=>o.name===e);n!==-1&&(t=i[n],i.splice(n,1),i.length===0&&this.converterPlugins.delete(r))}t&&this.registeredPlugins.delete(e)}unregisterMiddleware(e){let t=this.middlewarePlugins.findIndex(r=>r.name===e);t!==-1&&this.middlewarePlugins.splice(t,1)}async initialize(){var r;if(this.initialized)return;await this.registerDefaultConverters();let e=this.createContext(),t=[...Array.from(this.converterPlugins.values()).flat(),...this.middlewarePlugins];for(let i of t)try{await((r=i.initialize)==null?void 0:r.call(i,e))}catch{}this.initialized=!0}async destroy(){var r;if(!this.initialized)return;let e=this.createContext(),t=[...Array.from(this.converterPlugins.values()).flat(),...this.middlewarePlugins];for(let i of t)try{await((r=i.destroy)==null?void 0:r.call(i,e))}catch{}this.initialized=!1}createContext(){return{metadata:new Map,errors:[],warnings:[],stats:{startTime:Date.now(),processedTokens:0,convertedElements:0},performance:{startTime:Date.now()}}}async executeMiddlewareHook(e,t,r){var n;let i=t;for(let o of this.middlewarePlugins){let s=o[e];if(s)try{i=await s.call(o,i,r)||i}catch(a){r.errors.push(a),await((n=o.onError)==null?void 0:n.call(o,a,r))}}return i}async parseByBuffer(e){var r;await this.initialize();let t=this.createContext();t.rawData=e,t.xmlContent=e.toString("utf-8"),t.metadata.set("decoder",this);try{for(let i of this.processors)try{switch(t=await i.process(t),i.stage){case"tokenize":t.tokens&&(t.tokens=await this.executeMiddlewareHook("onTokenize",t.tokens,t));break;case"ast-generate":t.ast&&(t.ast=await this.executeMiddlewareHook("onAstGenerate",t.ast,t));break;case"convert":t.result&&(t.result=await this.executeMiddlewareHook("onConvert",t.result,t));break;case"complete":t.result&&(t.result=await this.executeMiddlewareHook("onComplete",t.result,t));break}}catch(n){t.errors.push(n);for(let o of this.middlewarePlugins)await((r=o.onError)==null?void 0:r.call(o,n,t))}return t.result}catch(i){throw i}}convertExtensions(e){var o,s;let t={},{attributes:r,tag:i,value:n}=e;if(r&&Object.entries(r).forEach(([a,c])=>{t[a]=c}),(o=e==null?void 0:e.children)!=null&&o.length)(s=e.children)==null||s.forEach(a=>{t[a.tag]=this.convertExtensions(a)});else if(n!==void 0)return n;return t}async parserByBuffer(e){return this.parseByBuffer(e)}async parseByString(e){let t=Buffer.from(e,"utf-8");return this.parseByBuffer(t)}};import Ge from"dayjs";import ot from"dayjs/plugin/utc.js";Ge.extend(ot);var R=class{constructor(e={}){this.compact=e.compact??!0}async encode(e){let t=this.buildTCXXML(e);return Buffer.from(t,"utf-8")}encodeToString(e){return this.buildTCXXML(e)}buildTCXXML(e){let t=this.buildXMLHeader(e),r=this.buildTCXContent(e),n=`${t}${r}
14
+ </TrainingCenterDatabase>`;return this.compact?this.compressXML(n):n}compressXML(e){return e.replace(/>\s+</g,"><").replace(/^\s+|\s+$/gm,"").replace(/\s+/g," ").trim()}buildXMLHeader(e){let t=e.version||"1.0",r=e.creator||"trackswap",i=e.xmlns||"http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2",n=e["xmlns:xsi"]||"http://www.w3.org/2001/XMLSchema-instance",o=e["xsi:schemaLocation"]||"http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2 http://www8.garmin.com/xmlschemas/TrainingCenterDatabasev2.xsd";return['<?xml version="1.0" encoding="UTF-8"?>',`<TrainingCenterDatabase version="${this.escapeXMLAttribute(t)}"`,` creator="${this.escapeXMLAttribute(r)}"`,` xmlns="${this.escapeXMLAttribute(i)}"`,` xmlns:xsi="${this.escapeXMLAttribute(n)}"`,` xsi:schemaLocation="${this.escapeXMLAttribute(o)}">`].join(`
13
15
  `)}buildTCXContent(e){let t=[];return e.Folders&&t.push(this.buildFolders(e.Folders)),e.Activities&&t.push(this.buildActivities(e.Activities)),e.Workouts&&t.push(this.buildWorkouts(e.Workouts)),e.Courses&&t.push(this.buildCourses(e.Courses)),e.Author&&t.push(this.buildAuthor(e.Author)),e.Extensions&&t.push(this.buildExtensions(e.Extensions)),t.join(`
14
16
  `)}buildFolders(e){let t=["<Folders>"];return e.History&&t.push(this.buildHistory(e.History)),e.Workouts&&t.push(this.buildWorkouts(e.Workouts)),e.Courses,t.push("</Folders>"),t.join(`
15
17
  `)}buildHistory(e){let t=["<History>"];return e.Running&&t.push(`<Running>${this.buildHistoryFolder(e.Running)}</Running>`),e.Biking&&t.push(`<Biking>${this.buildHistoryFolder(e.Biking)}</Biking>`),e.Other&&t.push(`<Other>${this.buildHistoryFolder(e.Other)}</Other>`),e.MultiSport&&t.push(`<MultiSport>${this.buildHistoryFolder(e.MultiSport)}</MultiSport>`),e.Extensions&&t.push(this.buildExtensions(e.Extensions)),t.push("</History>"),t.join(`
16
18
  `)}buildHistoryFolder(e){return""}buildActivities(e){let t=["<Activities>"];return e.Activity&&e.Activity.forEach(r=>{t.push(this.buildActivity(r))}),e.MultiSportSession&&e.MultiSportSession.forEach(r=>{t.push(this.buildMultiSportSession(r))}),t.push("</Activities>"),t.join(`
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(`
19
+ `)}buildActivity(e){let r=[`<Activity Sport="${e.Sport||"Other"}">`];return r.push(`<Id>${this.formatTime(e.Id)}</Id>`),e.Lap&&e.Lap.length>0&&e.Lap.forEach(i=>{r.push(this.buildActivityLap(i))}),this.addOptionalElement(r,"Notes",e.Notes),e.Training,e.Creator,e.Extensions&&r.push(this.buildExtensions(e.Extensions)),r.push("</Activity>"),r.join(`
18
20
  `)}buildActivityLap(e){let t=["<Lap>"];return this.addOptionalNumericElement(t,"TotalTimeSeconds",e.TotalTimeSeconds),this.addOptionalNumericElement(t,"DistanceMeters",e.DistanceMeters),this.addOptionalNumericElement(t,"MaximumSpeed",e.MaximumSpeed),this.addOptionalNumericElement(t,"Calories",e.Calories),e.AverageHeartRateBpm&&t.push(`<AverageHeartRateBpm xsi:type="HeartRateInBeatsPerMinute_t"><Value>${e.AverageHeartRateBpm}</Value></AverageHeartRateBpm>`),e.MaximumHeartRateBpm&&t.push(`<MaximumHeartRateBpm xsi:type="HeartRateInBeatsPerMinute_t"><Value>${e.MaximumHeartRateBpm}</Value></MaximumHeartRateBpm>`),this.addOptionalElement(t,"Intensity",e.Intensity),e.Cadence&&t.push(this.buildCadence(e.Cadence)),this.addOptionalElement(t,"TriggerMethod",e.TriggerMethod),e.Track&&e.Track.forEach(r=>{t.push(this.buildTrack(r))}),this.addOptionalElement(t,"Notes",e.Notes),e.Extensions&&t.push(this.buildExtensions(e.Extensions)),t.push("</Lap>"),t.join(`
19
21
  `)}buildTrack(e){let t=["<Track>"];return e.Trackpoint&&e.Trackpoint.forEach(r=>{t.push(this.buildTrackpoint(r))}),t.push("</Track>"),t.join(`
20
22
  `)}buildTrackpoint(e){let t=["<Trackpoint>"];return e.Time&&t.push(`<Time>${this.formatTime(e.Time)}</Time>`),e.Position&&t.push(this.buildPosition(e.Position)),this.addOptionalNumericElement(t,"AltitudeMeters",e.AltitudeMeters),this.addOptionalNumericElement(t,"DistanceMeters",e.DistanceMeters),e.HeartRateBpm&&t.push(`<HeartRateBpm xsi:type="HeartRateInBeatsPerMinute_t"><Value>${e.HeartRateBpm}</Value></HeartRateBpm>`),e.Cadence&&t.push(this.buildCadence(e.Cadence)),this.addOptionalElement(t,"SensorState",e.SensorState),e.Extensions&&t.push(this.buildExtensions(e.Extensions)),t.push("</Trackpoint>"),t.join(`
21
23
  `)}buildPosition(e){let t=["<Position>"];return e.LatitudeDegrees&&t.push(`<LatitudeDegrees>${this.formatCoordinate(parseFloat(e.LatitudeDegrees))}</LatitudeDegrees>`),e.LongitudeDegrees&&t.push(`<LongitudeDegrees>${this.formatCoordinate(parseFloat(e.LongitudeDegrees))}</LongitudeDegrees>`),t.push("</Position>"),t.join("")}buildCadence(e){return`<Cadence><Low>${e.Low}</Low><High>${e.High}</High></Cadence>`}buildMultiSportSession(e){let t=["<MultiSportSession>"];return e.Id&&t.push(`<Id>${this.formatTime(e.Id)}</Id>`),e.FirstSport&&t.push(this.buildFirstSport(e.FirstSport)),e.NextSport&&e.NextSport.forEach(r=>{t.push(this.buildNextSport(r))}),this.addOptionalElement(t,"Notes",e.Notes),t.push("</MultiSportSession>"),t.join(`
22
24
  `)}buildFirstSport(e){let t=["<FirstSport>"];return e.Activity&&t.push(this.buildActivity(e.Activity)),t.push("</FirstSport>"),t.join(`
23
25
  `)}buildNextSport(e){let t=["<NextSport>"];return e.Transition&&t.push(`<Transition>${this.buildActivityLap(e.Transition)}</Transition>`),e.Activity&&t.push(this.buildActivity(e.Activity)),t.push("</NextSport>"),t.join(`
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};
26
+ `)}buildWorkouts(e){return"<Workouts></Workouts>"}buildCourses(e){return"<Courses></Courses>"}buildAuthor(e){let t=["<Author>"];return this.addOptionalElement(t,"Name",e.Name),t.push("</Author>"),t.join("")}buildExtensions(e){let t=this.buildExtensionContent(e);return t?`<Extensions>${t}</Extensions>`:""}buildExtensionContent(e){return Object.entries(e).filter(([t])=>!t.startsWith("xmlns")).map(([t,r])=>{if(r&&typeof r=="object"){let i=this.buildExtensionContent(r);return`<${t}>${i}</${t}>`}else if(r!=null)return`<${t}>${this.escapeXML(String(r))}</${t}>`;return""}).filter(t=>t).join("")}formatTime(e){return typeof e=="string"&&/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/.test(e)?e:Ge(e).utc().format("YYYY-MM-DDTHH:mm:ss[Z]")}addOptionalElement(e,t,r,i){if(r!=null&&r!==""){let n=i?i(r):this.escapeXML(r);e.push(`<${t}>${n}</${t}>`)}}addOptionalNumericElement(e,t,r){r!=null&&!isNaN(r)&&e.push(`<${t}>${r}</${t}>`)}isValidCoordinate(e,t){return e!=null&&t!==void 0&&t!==null&&!isNaN(e)&&!isNaN(t)}formatCoordinate(e){return this.roundTo(e,6).toString()}roundTo(e,t){let r=Math.pow(10,t);return Math.round(e*r)/r}escapeXML(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;")}escapeXMLAttribute(e){return typeof e!="string"?String(e||""):e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/'/g,"&apos;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/\r/g,"&#13;").replace(/\n/g,"&#10;").replace(/\t/g,"&#9;")}deepClone(e){if(e===null||typeof e!="object")return e;if(e instanceof Date)return new Date(e.getTime());if(Array.isArray(e))return e.map(r=>this.deepClone(r));let t={};for(let r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=this.deepClone(e[r]));return t}encoder(e){return this.encode(e)}};var b=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 i=e[r-1],n=e[r],o=6371e3,s=i.lat*Math.PI/180,a=n.lat*Math.PI/180,c=(n.lat-i.lat)*Math.PI/180,d=(n.lon-i.lon)*Math.PI/180,l=Math.sin(c/2)*Math.sin(c/2)+Math.cos(s)*Math.cos(a)*Math.sin(d/2)*Math.sin(d/2),f=2*Math.atan2(Math.sqrt(l),Math.sqrt(1-l));t+=o*f}return t}calculateDuration(e){var i,n;if(e.length<2)return;let t=(i=e[0])==null?void 0:i.time,r=(n=e[e.length-1])==null?void 0:n.time;if(!(!t||!r))return Math.round((r-t)/1e3)}},I=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 Be={"gpxtpx:cad":"cadence","gpxtpx:hr":"heartRate","gpxtpx:temp":"temperature","gpxtpx:wtemp":"wtemp","gpxtpx:atemp":"atemp","gpxx:Temperature":"temperature","gpxx:Depth":"depth"},Ae=p=>p*(180/Math.pow(2,31));import M from"dayjs";function He(p,e=0){let t=Math.pow(10,e);return Math.round(p*t)/t}var ge=class extends b{constructor(){super(...arguments);this.name="gpx-to-sport-converter";this.supportedTags=["gpx"];this.convertGPXExtensions=t=>{let r={};return Object.entries(t).forEach(([i,n])=>{if(typeof n!="string"&&typeof n!="number")r={...r,...this.convertGPXExtensions(n)};else if(typeof n<"u"&&n!=="undefined"){let o=Be[i]||i;r[o]=n}}),r}}convert(t,r){if(r.sourceFormat!=="gpx")return;let i=r.sourceData;return this.convertGPX(i)}convertGPX(t){let r={metadata:{originType:"GPX",creator:t.creator,fileType:"gpx"}};return t.wpt&&(r.points=this.convertWpts2Points(t.wpt)),t.trk&&(r.tracks=t.trk.map(i=>{var n;return{name:i.name,trackseg:((n=i.trkseg)==null?void 0:n.map(o=>({name:i.name,points:o.trkpt?this.convertWpts2Points(o.trkpt):[]})))||[]}})),t.rte&&(r.routes=t.rte.map(i=>({name:i.name,points:i.rtept?this.convertWpts2Points(i.rtept):[]}))),r}convertPoint(t){if(t.lat==null||t.lon==null||typeof t.lat!="number"||typeof t.lon!="number")return;let{extensions:r}=t,i=r?this.convertGPXExtensions(r):{};return{lat:t.lat,lon:t.lon,ele:t.ele,time:this.convertTime(t.time),...i}}convertWpts2Points(t){let r=[];for(let i=0;i<t.length;i++){let n=t[i];if(n.lat!=null&&n.lon!=null&&typeof n.lat=="number"&&typeof n.lon=="number"){let o=this.convertPoint(n);o&&r.push(o)}}return r}},he=class extends b{constructor(){super(...arguments);this.name="fit-to-sport-converter";this.supportedTags=["fit"]}convert(t,r){if(r.sourceFormat!=="fit")return;let i=r.sourceData;return this.convertFIT(i)}convertFIT(t){var i,n;let r={metadata:{originType:"FIT",fileType:"fit"}};if((i=t.sessionMesgs)!=null&&i.length){r.tracks=[];for(let o of t.sessionMesgs)r.tracks.push({name:o.event,startTime:o.startTime?M(o.startTime).valueOf():void 0,distance:o.totalDistance,duration:o.totalElapsedTime,sport:o.sport,trackseg:this.convertFITLap2Trackseg(o==null?void 0:o.lapMesgs),__fit__sessionMesgType:o})}else if((n=t.courseMesgs)!=null&&n.length){r.routes=[];for(let o of t.courseMesgs)r.routes.push({name:o.event,points:this.convertLap2Points(o==null?void 0:o.lapMesgs)})}return r}convertPoint(t){let{positionLong:r,positionLat:i,altitude:n,timestamp:o,...s}=t;if(!(r==null||i==null||typeof r!="number"||typeof i!="number"))return{lat:He(Ae(Number(i)),6),lon:He(Ae(Number(r)),6),ele:n,time:o?M(o).valueOf():void 0,...s}}convertFITLap2Trackseg(t){var i;let r=[];if(!(t!=null&&t.length))return[];for(let o of t){let s=((i=o==null?void 0:o.recordMesgs)==null?void 0:i.map(a=>this.convertPoint(a)).filter(a=>a!==void 0))||[];r.push({points:s,duration:o.totalElapsedTime,distance:o.totalDistance,startTime:o.startTime?M(o.startTime).valueOf():void 0,endTime:o.startTime&&o.totalElapsedTime?M(o.startTime).add(o.totalElapsedTime,"second").valueOf():void 0,avgSpeed:o.avgSpeed,maxSpeed:o.maxSpeed,avgCadenceBpm:o.avgCadence,maxCadenceBpm:o.maxCadence,avgPower:o.avgPower,maxPower:o.maxPower,totalAscent:o.totalAscent,totalDescent:o.totalDescent,calories:o.totalCalories,__fit__lapMesgType:o})}return r}convertLap2Points(t){var i;let r=[];if(!(t!=null&&t.length))return[];for(let n of t){let o=((i=n.recordMesgs)==null?void 0:i.map(s=>this.convertPoint(s)).filter(s=>s!==void 0))||[];o.length&&(r=[...r,...o])}return r}},ye=class extends b{constructor(){super(...arguments);this.name="tcx-to-sport-converter";this.supportedTags=["tcx"]}convert(t,r){if(r.sourceFormat!=="tcx")return;let i=r.sourceData;return this.convertTCX(i)}convertTCX(t){var i,n,o,s;let r={metadata:{originType:"TCX",fileType:"tcx"}};if((n=(i=t.Activities)==null?void 0:i.Activity)!=null&&n.length){r.tracks=[];for(let a of t.Activities.Activity)r.tracks.push({name:a.Id,sport:a.Sport,trackseg:this.convertLap2Trackseg(a.Lap)})}if((s=(o=t.Courses)==null?void 0:o.Course)!=null&&s.length){r.routes=[];for(let a of t.Courses.Course){let c=a.Track||[];for(let d of c)r.routes.push({name:a.Name||"",points:this.convertTCXTrack(d)})}}return r}convertPoint(t){let{Position:r,Time:i,DistanceMeters:n,AltitudeMeters:o}=t;if(!(!(r!=null&&r.LatitudeDegrees)||!(r!=null&&r.LongitudeDegrees)||r.LatitudeDegrees===""||r.LongitudeDegrees===""))return{lat:Number(r.LatitudeDegrees),lon:Number(r.LongitudeDegrees),time:i?M(i).valueOf():void 0,distance:n,ele:o}}convertLap2Trackseg(t){var i,n,o,s;let r=[];for(let a of t)if(a.Track){for(let c of a.Track)if(c.Trackpoint){let d=c.Trackpoint.map(f=>this.convertPoint(f)).filter(f=>f!==void 0),l={duration:a.TotalTimeSeconds,distance:a.DistanceMeters,startTime:(i=d==null?void 0:d[0])==null?void 0:i.time,endTime:(n=d==null?void 0:d[d.length-1])==null?void 0:n.time,avgHeartRateBpm:a==null?void 0:a.AverageHeartRateBpm,maxHeartRateBpm:a==null?void 0:a.MaximumHeartRateBpm,maxSpeed:a.MaximumSpeed,calories:a.Calories,__tcx__Intensity:a==null?void 0:a.Intensity,__tcx__TriggerMethod:a==null?void 0:a.TriggerMethod,avgCadenceBpm:(o=a==null?void 0:a.Cadence)==null?void 0:o.Low,maxCadenceBpm:(s=a==null?void 0:a.Cadence)==null?void 0:s.High,points:d};r.push(l)}}return r}convertTCXTrack(t){return t.Trackpoint?t.Trackpoint.map(r=>this.convertPoint(r)).filter(r=>r!==void 0):[]}};function ze(p){return Math.round(p*(Math.pow(2,31)/180))}var ve=class extends I{constructor(){super(...arguments);this.name="sport-to-gpx-encoder";this.supportedTags=["gpx"]}encode(t,r){var n,o,s,a;if(r.targetFormat!=="gpx")return;let i={version:"1.1",creator:((n=t.metadata)==null?void 0:n.creator)||"TrackSwap"};return(o=t.points)!=null&&o.length&&(i.wpt=this.convertPoints2Wpts(t.points)),(s=t.routes)!=null&&s.length&&(i.rte=t.routes.map(c=>this.convertRoute2GPXRoute(c))),(a=t.tracks)!=null&&a.length&&(i.trk=t.tracks.map(c=>this.convertTrack2GPXTrack(c))),i}convertPoints2Wpts(t){return t.map(r=>({lat:r.lat,lon:r.lon,ele:r.ele,time:r.time?this.convertTimeToDate(r.time):void 0,speed:r.speed,magvar:r.magvar,extensions:this.extractGPXExtensions(r)}))}convertRoute2GPXRoute(t){return{name:t.name,rtept:t.points?this.convertPoints2Wpts(t.points):[]}}convertTrack2GPXTrack(t){var r;return{name:t.name,trkseg:((r=t.trackseg)==null?void 0:r.map(i=>({trkpt:i.points?this.convertPoints2Wpts(i.points):[]})))||[]}}extractGPXExtensions(t){let r={};return t.heart&&(r["gpxtpx:hr"]=t.heart),t.cadence&&(r["gpxtpx:cad"]=t.cadence),t.temperature&&(r["gpxtpx:atemp"]=t.temperature),Object.keys(r).length>0?r:void 0}},xe=class extends I{constructor(){super(...arguments);this.name="sport-to-fit-encoder";this.supportedTags=["fit"]}encode(t,r){var n,o;if(r.targetFormat!=="fit")return;let i={};return(n=t.tracks)!=null&&n.length&&(i.sessionMesgs=t.tracks.map(s=>this.convertTrack2FITSession(s))),(o=t.routes)!=null&&o.length&&(i.courseMesgs=t.routes.map(s=>this.convertRoute2FITCourse(s))),i}convertTrack2FITSession(t){var i;return{event:t.name||"session",sport:t.sport||"generic",startTime:t.startTime?this.convertTimeToString(t.startTime):this.convertTimeToString(void 0),totalDistance:t.distance,totalElapsedTime:t.duration,lapMesgs:((i=t.trackseg)==null?void 0:i.map(n=>this.convertSeg2FITLap(n)))||[]}}convertSeg2FITLap(t){var i;return{startTime:t.startTime?this.convertTimeToString(t.startTime):this.convertTimeToString(void 0),totalElapsedTime:t.duration,totalDistance:t.distance,avgSpeed:t.avgSpeed,maxSpeed:t.maxSpeed,avgCadence:t.avgCadenceBpm,maxCadence:t.maxCadenceBpm,avgPower:t.avgPower,maxPower:t.maxPower,totalAscent:t.totalAscent,totalDescent:t.totalDescent,totalCalories:t.calories,recordMesgs:((i=t.points)==null?void 0:i.map(n=>this.convertPoint2FITRecord(n)))||[]}}convertPoint2FITRecord(t){return{timestamp:t.time?this.convertTimeToString(t.time):this.convertTimeToString(void 0),positionLat:ze(t.lat),positionLong:ze(t.lon),altitude:t.ele,speed:t.speed,power:t.power,heartRate:t.heart,cadence:t.cadence,temperature:t.temperature,distance:t.distance,enhancedSpeed:t.enhancedSpeed,enhancedAltitude:t.enhancedAltitude,accumulatedPower:t.accumulatedPower}}convertRoute2FITCourse(t){return{event:t.name||"course",lapMesgs:t.points?[this.convertPoints2FITLap(t.points)]:[]}}convertPoints2FITLap(t){let r=t[0],i=t[t.length-1],n=r!=null&&r.time?this.convertTimeToString(r.time):this.convertTimeToString(void 0),o=r!=null&&r.time&&(i!=null&&i.time)?Math.round((i.time-r.time)/1e3):0,s=(i==null?void 0:i.distance)||0;return{startTime:n,totalElapsedTime:o,totalDistance:s,recordMesgs:t.map(a=>this.convertPoint2FITRecord(a))}}},Ce=class extends I{constructor(){super(...arguments);this.name="sport-to-tcx-encoder";this.supportedTags=["tcx"]}encode(t,r){var n,o,s;if(r.targetFormat!=="tcx")return;let i={Author:{Name:((n=t.metadata)==null?void 0:n.creator)||"TrackSwap"}};return(o=t.tracks)!=null&&o.length&&(i.Activities={Activity:t.tracks.map(a=>this.convertTrack2TCXActivity(a))}),(s=t.routes)!=null&&s.length&&(i.Courses={Course:t.routes.map(a=>this.convertRoute2TCXCourse(a))}),i}convertTrack2TCXActivity(t){var i;let r="Other";return(t.sport==="Running"||t.sport==="Biking")&&(r=t.sport),{Id:t.name||`Activity_${Date.now()}`,Sport:r,Lap:((i=t.trackseg)==null?void 0:i.map(n=>this.convertSeg2TCXLap(n)))||[]}}convertSeg2TCXLap(t){let r={TotalTimeSeconds:t.duration,DistanceMeters:t.distance,MaximumSpeed:t.maxSpeed,Calories:t.calories,AverageHeartRateBpm:t.avgHeartRateBpm,MaximumHeartRateBpm:t.maxHeartRateBpm,Intensity:t.__tcx__Intensity||"Active",TriggerMethod:t.__tcx__TriggerMethod||"Manual",Track:t.points?[this.convertPoints2TCXTrack(t.points)]:[]};return(t.avgCadenceBpm!==void 0||t.maxCadenceBpm!==void 0)&&(r.Cadence={Low:t.avgCadenceBpm||0,High:t.maxCadenceBpm||0}),r}convertPoints2TCXTrack(t){return{Trackpoint:t.map(r=>this.convertPoint2TCXTrackpoint(r))}}convertPoint2TCXTrackpoint(t){let r={Time:t.time?this.convertTimeToString(t.time):this.convertTimeToString(void 0),Position:{LatitudeDegrees:t.lat.toString(),LongitudeDegrees:t.lon.toString()},AltitudeMeters:t.ele,DistanceMeters:t.distance};return t.heart&&(r.HeartRateBpm=t.heart),r}convertRoute2TCXCourse(t){return{Name:t.name||`Course_${Date.now()}`,Track:t.points?[this.convertPoints2TCXTrack(t.points)]:[]}}};var Pe=class{constructor(){this.converters=new Map;this.encoders=new Map;this.registerDefaultConverters(),this.registerDefaultEncoders()}registerDefaultConverters(){this.registerConverter(new ge),this.registerConverter(new he),this.registerConverter(new ye)}registerDefaultEncoders(){this.registerEncoder(new ve),this.registerEncoder(new xe),this.registerEncoder(new Ce)}registerConverter(e){this.converters.set(e.name,e)}registerEncoder(e){this.encoders.set(e.name,e)}async convertToSport(e,t){let r={metadata:new Map,errors:[],warnings:[],stats:{startTime:Date.now(),processedTokens:0,convertedElements:0},sourceFormat:t,sourceData:e,performance:{startTime:Date.now()}};try{let i=this.findConverter(t);if(!i)throw new Error(`No converter found for format "${t}"`);let n=Date.now(),o=i.convert({},r);if(r.performance.convertTime=Date.now()-n,!o)throw new Error(`Converter "${i.name}" returned empty result`);return r.result=o,r.performance.endTime=Date.now(),r.stats.endTime=Date.now(),o}catch(i){throw r.errors.push(i),i}}async encodeSport(e,t){let r={metadata:new Map,errors:[],warnings:[],stats:{startTime:Date.now(),processedTokens:0,convertedElements:0},targetFormat:t,performance:{startTime:Date.now()}};try{let i=this.findEncoder(t);if(!i)throw new Error(`No encoder found for format "${t}"`);let n=Date.now(),o=i.encode(e,r);if(r.performance.encodeTime=Date.now()-n,!o)throw new Error(`Encoder "${i.name}" returned empty result`);return r.result=o,r.performance.endTime=Date.now(),r.stats.endTime=Date.now(),o}catch(i){throw r.errors.push(i),i}}findConverter(e){return Array.from(this.converters.values()).find(t=>{var r;return(r=t.supportedTags)==null?void 0:r.includes(e)})}findEncoder(e){return Array.from(this.encoders.values()).find(t=>{var r;return(r=t.supportedTags)==null?void 0:r.includes(e)})}async destroy(){this.converters.clear(),this.encoders.clear()}};var Ee=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 R,this.sportProcessor=new Pe}async parseGPX(e){try{return await this.gpxDecoder.parserByBuffer(e)}catch(t){throw new Error(`GPX parsing failed: ${t.message}`)}}async parseGPXString(e){let t=Buffer.from(e,"utf-8");return this.parseGPX(t)}async encodeGPX(e){try{return await this.gpxEncoder.encode(e)}catch(t){throw new Error(`GPX encoding failed: ${t.message}`)}}encodeGPXString(e){try{return this.gpxEncoder.encodeToString(e)}catch(t){throw new Error(`GPX encoding failed: ${t.message}`)}}async parseFIT(e){try{return await this.fitDecoder.parseByBuffer(e)}catch(t){throw new Error(`FIT parsing failed: ${t.message}`)}}async encodeFIT(e){try{return await this.fitEncoder.encode(e)}catch(t){throw new Error(`FIT encoding failed: ${t.message}`)}}async encodeFITCourse(e){try{return await this.fitEncoder.encodeCourse(e)}catch(t){throw new Error(`FIT Course encoding failed: ${t.message}`)}}async parseTCX(e){try{let t=await this.tcxDecoder.parseByBuffer(e);if(!t)throw new Error("TCX parsing result is empty");return t}catch(t){throw new Error(`TCX parsing failed: ${t.message}`)}}async parseTCXString(e){let t=Buffer.from(e,"utf-8");return this.parseTCX(t)}async encodeTCX(e){try{return await this.tcxEncoder.encode(e)}catch(t){throw new Error(`TCX encoding failed: ${t.message}`)}}async encodeTCXString(e){try{return await this.tcxEncoder.encodeToString(e)}catch(t){throw new Error(`TCX encoding failed: ${t.message}`)}}async convertGPXToSport(e){return await this.sportProcessor.convertToSport(e,"gpx")}async convertFITToSport(e){return await this.sportProcessor.convertToSport(e,"fit")}async convertTCXToSport(e){return await this.sportProcessor.convertToSport(e,"tcx")}async convertSportToGPX(e){return await this.sportProcessor.encodeSport(e,"gpx")}async convertSportToFIT(e){return await this.sportProcessor.encodeSport(e,"fit")}async convertSportToTCX(e){return await this.sportProcessor.encodeSport(e,"tcx")}async convertFile(e,t,r){try{let i=r||this.detectFormat(e);if(i==="unknown")throw new Error("Unable to recognize source file format, please specify sourceType parameter");if(i===t)return e;let n;switch(i){case"gpx":let s=await this.parseGPX(e);if(!s)throw new Error("GPX file parsing failed");n=s;break;case"fit":n=await this.parseFIT(e);break;case"tcx":n=await this.parseTCX(e);break;default:throw new Error(`Unsupported source file format: ${i}`)}let o;switch(i){case"gpx":o=await this.convertGPXToSport(n);break;case"fit":o=await this.convertFITToSport(n);break;case"tcx":o=await this.convertTCXToSport(n);break;default:throw new Error(`Unsupported source file format conversion: ${i}`)}switch(t){case"gpx":let s=await this.convertSportToGPX(o);return await this.encodeGPX(s);case"fit":let a=await this.convertSportToFIT(o);return await this.encodeFIT(a);case"tcx":let c=await this.convertSportToTCX(o);return await this.encodeTCX(c);default:throw new Error(`Unsupported target file format: ${t}`)}}catch(i){let n=r||"auto-detect";throw new Error(`${n} to ${t.toUpperCase()} failed: ${i.message}`)}}detectFormat(e){let t=e.toString("utf-8",0,Math.min(1024,e.length));if(e.length>=12&&e.toString("ascii",8,12)===".FIT")return"fit";if(t.includes("<?xml")){if(t.includes("<gpx")||t.includes("http://www.topografix.com/GPX/"))return"gpx";if(t.includes("<TrainingCenterDatabase")||t.includes("http://www.garmin.com/xmlschemas/TrainingCenterDatabase/"))return"tcx"}return"unknown"}async parseFile(e,t){let r=t||this.detectFormat(e);if(r==="unknown")throw new Error("Unable to recognize file format, please specify sourceType parameter");switch(r){case"gpx":let i=await this.parseGPX(e);if(!i)throw new Error("GPX parsing failed");return i;case"fit":return await this.parseFIT(e);case"tcx":return await this.parseTCX(e);default:throw new Error(`Unsupported file format: ${r}`)}}async parseToSport(e,t){let r=t||this.detectFormat(e);if(r==="unknown")throw new Error("Unable to recognize file format, please specify sourceType parameter");switch(r){case"gpx":let i=await this.parseGPX(e);if(!i)throw new Error("GPX parsing failed");return this.convertGPXToSport(i);case"fit":let n=await this.parseFIT(e);return this.convertFITToSport(n);case"tcx":let o=await this.parseTCX(e);return this.convertTCXToSport(o);default:throw new Error(`Unsupported file format: ${r}`)}}getSportProcessor(){return this.sportProcessor}getGPXDecoder(){return this.gpxDecoder}getGPXEncoder(){return this.gpxEncoder}getFITDecoder(){return this.fitDecoder}getFITEncoder(){return this.fitEncoder}getTCXDecoder(){return this.tcxDecoder}getTCXEncoder(){return this.tcxEncoder}async destroy(){await this.gpxDecoder.destroy(),await this.fitDecoder.destroy(),await this.tcxDecoder.destroy(),await this.sportProcessor.destroy()}};var gn=Ee;export{je as GPXManager,Ee as TrackSwap,gn as default};
@@ -1,31 +1,31 @@
1
1
  import { IPlugin, IConverterPlugin, IMiddlewarePlugin, BaseConverter, BaseMiddleware, IProcessingContext } from "../core/base.js";
2
- import { SportFileType, SportPointType, SportRouteSegType, SportTrackType } from "../types.js";
2
+ import { SportFileType, SportPointType, SportRouteSegType, SportTrackType, TokenAST } from "../types.js";
3
3
  export interface SportContext extends IProcessingContext {
4
- sourceFormat: "gpx" | "fit" | "tcx";
4
+ sourceFormat: string;
5
5
  sourceData: any;
6
6
  result?: SportFileType;
7
7
  performance: {
8
8
  startTime: number;
9
9
  convertTime?: number;
10
- validateTime?: number;
11
10
  endTime?: number;
12
11
  };
13
12
  }
14
13
  export interface SportEncodingContext extends IProcessingContext {
15
- targetFormat: "gpx" | "fit" | "tcx";
14
+ targetFormat: string;
16
15
  result?: any;
17
16
  performance: {
18
17
  startTime: number;
19
18
  encodeTime?: number;
20
- validateTime?: number;
21
19
  endTime?: number;
22
20
  };
23
21
  }
24
- export interface ISportPlugin extends IPlugin<SportContext> {
22
+ export interface ISportPlugin extends IPlugin {
25
23
  }
26
- export interface ISportConverterPlugin extends IConverterPlugin<SportContext> {
24
+ export interface ISportConverterPlugin extends IConverterPlugin {
25
+ convert(ast: TokenAST, context: SportContext): SportFileType | undefined;
27
26
  }
28
- export interface ISportMiddlewarePlugin extends IMiddlewarePlugin<SportContext, SportFileType> {
27
+ export interface ISportMiddlewarePlugin extends IMiddlewarePlugin {
28
+ process(context: SportContext): Promise<void>;
29
29
  }
30
30
  export interface ISportEncoderPlugin extends IPlugin<SportEncodingContext> {
31
31
  encode(sportData: SportFileType, context: SportEncodingContext): any | undefined;
@@ -55,6 +55,7 @@ export declare abstract class BaseSportEncoder implements ISportEncoderPlugin {
55
55
  protected round(value: number, precision?: number): number;
56
56
  }
57
57
  export declare abstract class BaseSportMiddleware extends BaseMiddleware<SportContext, SportFileType> implements ISportMiddlewarePlugin {
58
+ abstract process(context: SportContext): Promise<void>;
58
59
  onError(error: Error, context: SportContext): Promise<void>;
59
60
  protected validateSportFile(sportFile: SportFileType): boolean;
60
61
  protected validateTrack(track: SportTrackType): boolean;
package/package.json CHANGED
@@ -1,17 +1,20 @@
1
1
  {
2
2
  "name": "trackswap",
3
- "version": "0.0.3",
3
+ "version": "0.0.5",
4
4
  "description": "A powerful and flexible GPX parser and encoder library for Node.js and TypeScript. TrackSwap provides comprehensive support for GPX 1.1 format with advanced features like plugin system, middleware support, and optimized performance.",
5
- "main": "dist/index.js",
5
+ "main": "dist/index.cjs",
6
+ "module": "dist/index.js",
6
7
  "types": "dist/index.d.ts",
7
8
  "exports": {
8
9
  ".": {
9
10
  "import": "./dist/index.js",
11
+ "require": "./dist/index.cjs",
10
12
  "types": "./dist/index.d.ts"
11
13
  }
12
14
  },
13
15
  "files": [
14
16
  "dist/index.js",
17
+ "dist/index.cjs",
15
18
  "dist/index.d.ts",
16
19
  "dist/TrackSwap.d.ts",
17
20
  "dist/types.d.ts",
@@ -22,9 +25,10 @@
22
25
  "scripts": {
23
26
  "dev": "ts-node src/index.ts",
24
27
  "clean": "rm -rf dist",
25
- "build": "npm run clean && npm run build:types && npm run build:prod && npm run build:optimize",
28
+ "build": "npm run clean && npm run build:types && npm run build:esm && npm run build:cjs && npm run build:optimize",
26
29
  "build:types": "tsc --emitDeclarationOnly",
27
- "build:prod": "NODE_ENV=production node build.config.js",
30
+ "build:esm": "NODE_ENV=production node build.config.js",
31
+ "build:cjs": "NODE_ENV=production FORMAT=cjs node build.config.js",
28
32
  "build:dev": "npm run clean && npm run build:types && NODE_ENV=development node build.config.js",
29
33
  "build:optimize": "node scripts/optimize-dist.js",
30
34
  "build:js": "esbuild src/index.ts --bundle --platform=node --target=node14 --format=esm --outfile=dist/index.js --minify --sourcemap",
@@ -53,7 +57,6 @@
53
57
  ],
54
58
  "author": "berber1016",
55
59
  "license": "MIT",
56
- "type": "module",
57
60
  "repository": {
58
61
  "type": "git",
59
62
  "url": "https://github.com/berber1016/trackswap.git"