trackswap 0.0.5 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/TCX/index.d.ts +0 -5
- package/dist/TCX/processor.d.ts +6 -6
- package/dist/index.cjs +11 -11
- package/dist/index.d.ts +5 -4
- package/dist/index.js +11 -11
- package/package.json +1 -1
package/dist/TCX/index.d.ts
CHANGED
|
@@ -5,8 +5,3 @@ export * from "./base.js";
|
|
|
5
5
|
export * from "./converters.js";
|
|
6
6
|
export * from "./middleware.js";
|
|
7
7
|
export * from "./processor.js";
|
|
8
|
-
import { TCXDecoder } from "./decoder.js";
|
|
9
|
-
declare const _default: {
|
|
10
|
-
TCXDecoder: typeof TCXDecoder;
|
|
11
|
-
};
|
|
12
|
-
export default _default;
|
package/dist/TCX/processor.d.ts
CHANGED
|
@@ -1,30 +1,30 @@
|
|
|
1
1
|
import { TCXContext } from "./types.js";
|
|
2
2
|
import { ITCXConverterPlugin } from "./base.js";
|
|
3
|
-
export declare enum
|
|
3
|
+
export declare enum TCXPipelineStage {
|
|
4
4
|
TOKENIZE = "tokenize",
|
|
5
5
|
AST_GENERATE = "ast-generate",
|
|
6
6
|
CONVERT = "convert",
|
|
7
7
|
COMPLETE = "complete"
|
|
8
8
|
}
|
|
9
9
|
export interface IPipelineProcessor {
|
|
10
|
-
stage:
|
|
10
|
+
stage: TCXPipelineStage;
|
|
11
11
|
name: string;
|
|
12
12
|
process(context: TCXContext): Promise<TCXContext>;
|
|
13
13
|
}
|
|
14
14
|
export declare class TokenizeProcessor implements IPipelineProcessor {
|
|
15
|
-
stage:
|
|
15
|
+
stage: TCXPipelineStage;
|
|
16
16
|
name: string;
|
|
17
17
|
process(context: TCXContext): Promise<TCXContext>;
|
|
18
18
|
}
|
|
19
19
|
export declare class AstGenerateProcessor implements IPipelineProcessor {
|
|
20
|
-
stage:
|
|
20
|
+
stage: TCXPipelineStage;
|
|
21
21
|
name: string;
|
|
22
22
|
process(context: TCXContext): Promise<TCXContext>;
|
|
23
23
|
private buildAST;
|
|
24
24
|
}
|
|
25
25
|
export declare class ConvertProcessor implements IPipelineProcessor {
|
|
26
26
|
private getConverter;
|
|
27
|
-
stage:
|
|
27
|
+
stage: TCXPipelineStage;
|
|
28
28
|
name: string;
|
|
29
29
|
constructor(getConverter: (tag: string) => ITCXConverterPlugin | undefined);
|
|
30
30
|
process(context: TCXContext): Promise<TCXContext>;
|
|
@@ -34,7 +34,7 @@ export declare class ConvertProcessor implements IPipelineProcessor {
|
|
|
34
34
|
private countElements;
|
|
35
35
|
}
|
|
36
36
|
export declare class CompleteProcessor implements IPipelineProcessor {
|
|
37
|
-
stage:
|
|
37
|
+
stage: TCXPipelineStage;
|
|
38
38
|
name: string;
|
|
39
39
|
process(context: TCXContext): Promise<TCXContext>;
|
|
40
40
|
}
|
package/dist/index.cjs
CHANGED
|
@@ -1,26 +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(/'/g,"'"):n==="xsi:schemaLocation"?r[n]=o.replace(/'/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(
|
|
3
|
-
`)}buildGPXContent(e){let{metadata:t,wpt:r=[],rte:
|
|
1
|
+
"use strict";var it=Object.create;var J=Object.defineProperty;var ot=Object.getOwnPropertyDescriptor;var st=Object.getOwnPropertyNames;var at=Object.getPrototypeOf,pt=Object.prototype.hasOwnProperty;var ct=(p,e)=>{for(var t in e)J(p,t,{get:e[t],enumerable:!0})},Ue=(p,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of st(e))!pt.call(p,n)&&n!==t&&J(p,n,{get:()=>e[n],enumerable:!(r=ot(e,n))||r.enumerable});return p};var h=(p,e,t)=>(t=p!=null?it(at(p)):{},Ue(e||!p||!p.__esModule?J(t,"default",{value:p,enumerable:!0}):t,p)),dt=p=>Ue(J({},"__esModule",{value:!0}),p);var Et={};ct(Et,{AbstractSourceConverter:()=>j,ActivityConverter:()=>V,ActivityLapConverter:()=>z,ActivityListConverter:()=>U,AstGenerateProcessor:()=>Y,BaseFITMessageConverter:()=>ne,BaseFITMiddleware:()=>ie,BaseFITStructurePlugin:()=>y,BaseTCXConverter:()=>m,BaseTCXMiddleware:()=>S,CompleteProcessor:()=>q,ConvertProcessor:()=>Z,CourseStructurePlugin:()=>I,FITDecoder:()=>C,FITEncoder:()=>w,FileHeaderPlugin:()=>k,GPXDecoder:()=>F,GPXEncoder:()=>A,MultiSportSessionConverter:()=>W,PipelineStage:()=>xe,PositionConverter:()=>G,SessionStructurePlugin:()=>b,TCXDecoder:()=>D,TCXEncoder:()=>_,TCXEnhancementMiddleware:()=>Ee,TCXPerformanceMiddleware:()=>Pe,TCXPipelineStage:()=>Be,TCXValidationMiddleware:()=>we,TokenizeProcessor:()=>K,TrackConverter:()=>H,TrackSwap:()=>L,TrackpointConverter:()=>B,default:()=>wt,registerDefaultMiddlewares:()=>Je,registerDefaultTCXMiddlewares:()=>Pt});module.exports=dt(Et);var Q=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"),n=r.fromBuffer(e);if(!t.isFIT(n))throw new Error("Not a valid FIT file");let i=new t(n),{messages:o,errors:s}=i.read();return s&&s.length>0,o}},ee=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[n,i]of Object.entries(e.rawMessages)){if(!Array.isArray(i)||i.length===0){r[n]=i;continue}let o=this.getConverters(n);if(o.length===0)r[n]=i;else{let s=o[0];try{let a=s.convertMessages(i,e);r[n]=a}catch(a){e.errors.push(a),r[n]=i}}}return e.rawMessages=r,e.performance.extractTime=Date.now()-t,e}},te=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={},n=this.getStructurePlugins();for(let i of n)try{let o=i.structureData(e.rawMessages,e);r={...r,...o}}catch(o){e.errors.push(o)}return e.result=r,e.performance.structureTime=Date.now()-t,e}},re=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 T=h(require("dayjs"));var ne=class{constructor(){this.version="1.0.0";this.priority=100}supports(e){return this.supportedMessageTypes.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}parseTimestamp(e){if(!e)return;let t=new Date(e);return isNaN(t.getTime())?void 0:t}calculateDuration(e,t){if(!e||!t)return 0;let r=new Date(e).getTime(),n=new Date(t).getTime();return Math.max(0,(n-r)/1e3)}filterMessagesByTimeRange(e,t,r,n=2e3){let i=new Date(t).getTime(),o=new Date(r).getTime();return e.filter(s=>{if(!s.timestamp)return!1;let a=new Date(s.timestamp).getTime();return a>=i-n&&a<=o+n})}groupMessagesByLap(e,t){return t.map(r=>{let n=this.filterMessagesByTimeRange(e,r.startTime,r.timestamp);return{lap:r,records:n}})}},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}},ie=class{constructor(){this.version="1.0.0";this.description="";this.priority=100}async initialize(e){}async destroy(e){}async validate(e){return!0}async onParse(e,t){return e}async onExtractMessages(e,t){return e}async onStructure(e,t){return e}async onComplete(e,t){return e}async onError(e,t){}};var b=class extends y{constructor(){super(...arguments);this.name="SessionStructurePlugin";this.priority=10}structureData(t,r){let{sessionMesgs:n,lapMesgs:i,recordMesgs:o}=t;return n!=null&&n.length?{sessionMesgs:n.map(a=>{let c=(0,T.default)(a.startTime).valueOf(),d=(0,T.default)(a.timestamp).valueOf(),f=((i==null?void 0:i.filter(g=>{let x=(0,T.default)(g.startTime).valueOf(),O=(0,T.default)(g.timestamp).valueOf();return x>=c&&O<=d}))||[]).map(g=>{let x=(0,T.default)(g.startTime).valueOf(),O=(0,T.default)(g.timestamp).valueOf(),N=(o==null?void 0:o.filter(nt=>{let Ve=(0,T.default)(nt.timestamp).valueOf();return Ve>=x&&Ve<=O}))||[];return{...g,recordMesgs:N}});return{...a,lapMesgs:f}})}:{}}},I=class extends y{constructor(){super(...arguments);this.name="CourseStructurePlugin";this.priority=10}structureData(t,r){let{courseMesgs:n,lapMesgs:i,recordMesgs:o}=t;if(!(n!=null&&n.length))return{};let s=2e3;return{courseMesgs:n.map(c=>{let d=(i==null?void 0:i.map(l=>{let f=(0,T.default)(l.startTime).valueOf(),g=(0,T.default)(l.timestamp).valueOf(),x=(o==null?void 0:o.filter(O=>{let N=(0,T.default)(O.timestamp).valueOf();return N>=f-s&&N<=g+s}))||[];return{...l,recordMesgs:x}}))||[];return{...c,lapMesgs:d}})}}},k=class extends y{constructor(){super(...arguments);this.name="FileHeaderPlugin";this.priority=1}structureData(t,r){let{fileIdMesgs:n}=t;if(n!=null&&n.length&&n[0]){let i=n[0];r.fileHeader={type:i.type,manufacturer:i.manufacturer,product:i.product}}return{}}};var C=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 Q,new ee(e=>this.getConverters(e)),new te(()=>this.structurePlugins),new re]}async registerDefaultPlugins(){if(this.defaultPluginsRegistered)return;let e=[new k,new b,new I];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((n,i)=>(n.priority||100)-(i.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 i=(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(n=>n.name===e.name);t!==-1?this.middlewarePlugins[t]=e:(this.middlewarePlugins.push(e),this.middlewarePlugins.sort((n,i)=>(n.priority||100)-(i.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[n,i]of this.converterPlugins){let o=i.findIndex(s=>s.name===e);o!==-1&&(i.splice(o,1),i.length===0&&this.converterPlugins.delete(n))}let t=this.structurePlugins.findIndex(n=>n.name===e);t!==-1&&this.structurePlugins.splice(t,1);let r=this.middlewarePlugins.findIndex(n=>n.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 n of t)try{await((r=n.initialize)==null?void 0:r.call(n,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 n of t)try{await((r=n.destroy)==null?void 0:r.call(n,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 i;let n=t;for(let o of this.middlewarePlugins){let s=o[e];if(s)try{n=await s.call(o,n,r)||n}catch(a){r.errors.push(a),await((i=o.onError)==null?void 0:i.call(o,a,r))}}return n}async parseByBuffer(e,t={}){var n;await this.initialize();let r=this.createContext();r.rawData=e,r.userData=t.userData,r.metadata.set("decoder",this);try{for(let i of this.processors)try{switch(r=await i.process(r),i.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((n=s.onError)==null?void 0:n.call(s,o,r))}return r.result||{}}catch(i){throw i}}};var lt={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}},P=p=>{let e=lt[p];return{size:1,baseType:0,mapValue:t=>typeof t=="string"?e[t]??255:t,setValue:function(t,r){this.setUint8(t,r)}}},_e={enum_file:P("file"),enum_activity:P("sport"),enum_sport:P("sport"),enum_sub_sport:P("sport"),enum_event:P("event"),enum_event_type:P("event_type"),enum_course_point:P("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(je(p)),setValue:mt},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 We(p){return Array.from(je(p)).length+1}function*je(p){for(let e of ut(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*ut(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 mt(p,e){for(let t=0;t<e.length;t++)this.setUint8(p+t,e[t])}var Tt={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"}]}},ft=(p,e)=>p.map(t=>({...t,value:e[t.name]})).filter(({value:t})=>t!==void 0),oe=class p{static check(e,t,r,n){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 i=r.map(s=>s.name),o=Object.keys(n).filter(s=>!i.includes(s));if(o.length)throw new Error(`Message '${e}' has no field definitions named '${o}'`)}constructor(e,t,r){let n=Tt[t];if(!n)throw new Error(`Unknown message type: ${t}`);let{mesgNum:i,fieldDefns:o}=n;p.check(t,i,o,r),this.localNum=e,this.mesgNum=i,this.fields=ft(o,r)}get mesgDefn(){let e=this.fields.map(({number:t,type:r,value:n})=>{let i=_e[r];if(!i)throw new Error(`Unknown type: ${r}`);let{size:o,baseType:s}=i;return r==="string"?{number:t,size:We(n),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:n,mesgNum:i,fieldDefns:o}=this.mesgDefn;return i===e.mesgNum&&n===e.localNum&&r(o,e.fieldDefns)}get defnRecord(){let{localNum:e,mesgNum:t,fieldDefns:r}=this.mesgDefn,n=6+3*r.length,i=new DataView(new ArrayBuffer(n));i.setUint8(0,64|e),i.setUint8(2,1),i.setUint16(3,t),i.setUint8(5,r.length);let o=6;for(let s of r)i.setUint8(o++,s.number),i.setUint8(o++,s.size),i.setUint8(o++,s.baseType);return i.buffer}get dataRecord(){let{fieldDefns:e}=this.mesgDefn,t=1+e.reduce((i,{size:o})=>i+o,0),r=new DataView(new ArrayBuffer(t));r.setUint8(0,this.localNum);let n=1;for(let{number:i,type:o,value:s}of this.fields){let a=_e[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,n,l),n+=c}return r.buffer}};var gt=[0,52225,55297,5120,61441,15360,10240,58369,40961,27648,30720,46081,20480,39937,34817,17408],Ke=(p,e)=>(p>>>4^gt[p&15^e])&65535,ht=(p,e,t)=>Ke(Ke(p,e),t),yt=(p,e)=>ht(p,e&15,e>>>4);function Xe(p,e=0){let t=e,r=p instanceof ArrayBuffer?new Uint8Array(p):p;for(let n=0;n<r.length;n++)t=yt(t,r[n]);return t}var Ze=h(require("dayjs")),Ye=14,vt=16,xt=2078,Ct=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,n=[],i=[];for(let o of t){if(o.lapMesgs&&this.buildEventsFromLaps(o.lapMesgs,n),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,i)}n.forEach(o=>this.buildEvent(o)),i.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 n=[];for(let s of r.lapMesgs)s.recordMesgs&&n.push(...s.recordMesgs);n.sort((s,a)=>s.timestamp&&a.timestamp?new Date(s.timestamp).getTime()-new Date(a.timestamp).getTime():(s.distance||0)-(a.distance||0));let i=n[0],o=n[n.length-1];i.timestamp&&this.buildEvent({timestamp:i.timestamp,event:"timer",eventType:"start",eventGroup:0}),n.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 n;let r=((n=e.fileIdMesgs)==null?void 0:n[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,n)=>{r.startTime&&t.push({timestamp:r.startTime,event:"timer",eventType:"start",eventGroup:n}),r.timestamp&&t.push({timestamp:r.timestamp,event:"timer",eventType:n===e.length-1?"stop_all":"stop",eventGroup:n})})}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,Ze.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 n=this.localNum[e];n===void 0&&(n=this.localNum[e]=Object.keys(this.localNum).length);let i=new oe(n,e,r),o=this.mesgDefn[n];(!o||!i.isSameDefn(o))&&(this.messages.push(i.defnRecord),this.mesgDefn[n]=i.mesgDefn),this.messages.push(i.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)=>Xe(t,e),0)}get header(){let e=new DataView(new ArrayBuffer(Ye));return e.setUint8(0,Ye),e.setUint8(1,vt),e.setUint16(2,xt,!0),e.setUint32(4,this.dataLen,!0),e.setUint32(8,Ct),e.setUint16(12,Xe(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 v=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 n;return(n=e.attributes)==null?void 0:n[r]})}extractAttributes(e,t,r){e.attributes&&Object.entries(e.attributes).forEach(([n,i])=>{let o=r[n];o&&o in t&&(t[o]=String(i||""))})}processChildren(e,t,r){var n;(n=e.children)==null||n.forEach(i=>{let o=r[i.tag];o&&o(i,t)})}getChildValue(e,t){var n;let r=(n=e.children)==null?void 0:n.find(i=>i.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(n=>n.tag===t)}getChildrenByTag(e,t){var r;return((r=e.children)==null?void 0:r.filter(n=>n.tag===t))||[]}convertExtensions(e){var r;let t={};return(r=e.children)==null||r.forEach(n=>{t[n.tag]=this.convertExtensionContent(n)}),t}convertExtensionContent(e){var t;if((t=e.children)!=null&&t.length){let r={};return e.children.forEach(n=>{r[n.tag]=this.convertExtensionContent(n)}),r}else return e.value}},E=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 v{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(([n,i])=>{let o=r[n];o&&o in t&&typeof i<"u"&&(t[o]=this.parseFloat(i))})}},$=class extends E{async onError(e,t){t.warnings.push(`Middleware ${this.name} error: ${e.message}`)}};var se=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 n={lat:this.parseFloat(t.attributes.lat),lon:this.parseFloat(t.attributes.lon)};return this.extractAttributes(t,n,{lat:"lat",lon:"lon"}),this.processChildren(t,n,{ele:(i,o)=>o.ele=this.parseFloat(i.value),time:(i,o)=>o.time=new Date(this.parseString(i.value)),speed:(i,o)=>o.speed=this.parseFloat(i.value),course:(i,o)=>o.course=this.parseFloat(i.value),name:(i,o)=>o.name=this.parseString(i.value),cmt:(i,o)=>o.cmt=this.parseString(i.value),desc:(i,o)=>o.desc=this.parseString(i.value),src:(i,o)=>o.src=this.parseString(i.value),sym:(i,o)=>o.sym=this.parseString(i.value),type:(i,o)=>o.type=this.parseString(i.value),fix:(i,o)=>o.fix=this.parseString(i.value),sat:(i,o)=>o.sat=this.parseString(i.value),hdop:(i,o)=>o.hdop=this.parseFloat(i.value),vdop:(i,o)=>o.vdop=this.parseFloat(i.value),pdop:(i,o)=>o.pdop=this.parseFloat(i.value),ageofdgpsdata:(i,o)=>o.ageofdgpsdata=this.parseFloat(i.value),geoidheight:(i,o)=>o.geoidheight=this.parseFloat(i.value),magvar:(i,o)=>o.magvar=this.parseFloat(i.value),dgpsid:(i,o)=>o.dgpsid=this.parseFloat(i.value),extensions:(i,o)=>{let s=r.metadata.get("decoder");s&&(o.extensions=s.convertExtensions(i))},link:(i,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(i,r);a&&o.link&&o.link.push(a)}}),n}},ae=class extends u{constructor(){super(...arguments);this.name="rte-converter";this.supportedTags=["rte"]}convert(t,r){let n={rtept:[]};return this.processChildren(t,n,{name:(i,o)=>o.name=this.parseString(i.value),cmt:(i,o)=>o.cmt=this.parseString(i.value),desc:(i,o)=>o.desc=this.parseString(i.value),src:(i,o)=>o.src=this.parseString(i.value),number:(i,o)=>o.number=this.parseFloat(i.value),type:(i,o)=>o.type=this.parseString(i.value),rtept:(i,o)=>{var c;let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("wpt"))==null?void 0:c.convert(i,r);a&&o.rtept&&o.rtept.push(a)},extensions:(i,o)=>{let s=r.metadata.get("decoder");s&&(o.extensions=s.convertExtensions(i))},link:(i,o)=>{var a;o.link||(o.link=[]);let s=r.metadata.get("decoder");(a=i.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)})}}),n}},pe=class extends u{constructor(){super(...arguments);this.name="trk-converter";this.supportedTags=["trk"]}convert(t,r){let n={trkseg:[]};return this.processChildren(t,n,{name:(i,o)=>o.name=this.parseString(i.value),cmt:(i,o)=>o.cmt=this.parseString(i.value),desc:(i,o)=>o.desc=this.parseString(i.value),src:(i,o)=>o.src=this.parseString(i.value),number:(i,o)=>o.number=this.parseFloat(i.value),type:(i,o)=>o.type=this.parseString(i.value),trkseg:(i,o)=>{var c;let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("trkseg"))==null?void 0:c.convert(i,r);a&&o.trkseg&&o.trkseg.push(a)},extensions:(i,o)=>{let s=r.metadata.get("decoder");s&&(o.extensions=s.convertExtensions(i))},link:(i,o)=>{var a;o.link||(o.link=[]);let s=r.metadata.get("decoder");(a=i.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)})}}),n}},ce=class extends u{constructor(){super(...arguments);this.name="trkseg-converter";this.supportedTags=["trkseg"]}convert(t,r){let n={trkpt:[]};return this.processChildren(t,n,{trkpt:(i,o)=>{var c;let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("wpt"))==null?void 0:c.convert(i,r);a&&o.trkpt&&o.trkpt.push(a)},extensions:(i,o)=>{let s=r.metadata.get("decoder");s&&(o.extensions=s.convertExtensions(i))}}),n}},de=class extends u{constructor(){super(...arguments);this.name="link-converter";this.supportedTags=["link"]}convert(t,r){var i;let n={};return(i=t.attributes)!=null&&i.href&&(n.href=t.attributes.href),this.processChildren(t,n,{text:(o,s)=>s.text=this.parseString(o.value),type:(o,s)=>s.type=this.parseString(o.value)}),n}},le=class extends u{constructor(){super(...arguments);this.name="metadata-converter";this.supportedTags=["metadata"]}convert(t,r){let n={};return this.processChildren(t,n,{name:(i,o)=>o.name=this.parseString(i.value),desc:(i,o)=>o.desc=this.parseString(i.value),keywords:(i,o)=>o.keywords=this.parseString(i.value),time:(i,o)=>o.time=new Date(this.parseString(i.value)),author:(i,o)=>{var a;let s=r.metadata.get("decoder");o.author=(a=s==null?void 0:s.getConverter("author"))==null?void 0:a.convert(i,r)},copyright:(i,o)=>{var a;let s=r.metadata.get("decoder");o.copyright=(a=s==null?void 0:s.getConverter("copyright"))==null?void 0:a.convert(i,r)},bounds:(i,o)=>{var a;let s=r.metadata.get("decoder");o.bounds=(a=s==null?void 0:s.getConverter("bounds"))==null?void 0:a.convert(i,r)},extensions:(i,o)=>{let s=r.metadata.get("decoder");s&&(o.extensions=s.convertExtensions(i))},link:(i,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(i,r);a&&o.link&&o.link.push(a)}}),n}},ue=class extends u{constructor(){super(...arguments);this.name="person-converter";this.supportedTags=["author"]}convert(t,r){var i;let n={};return t.value&&!((i=t.children)!=null&&i.length)?(n.name=this.parseString(t.value),n):(this.processChildren(t,n,{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)}}),n)}},me=class extends u{constructor(){super(...arguments);this.name="email-converter";this.supportedTags=["email"]}convert(t,r){let n={};return this.processChildren(t,n,{id:(i,o)=>o.id=this.parseString(i.value),domain:(i,o)=>o.domain=this.parseString(i.value)}),n}},Te=class extends u{constructor(){super(...arguments);this.name="copyright-converter";this.supportedTags=["copyright"]}convert(t,r){var i;let n={};return(i=t.attributes)!=null&&i.author&&(n.author=t.attributes.author),this.processChildren(t,n,{year:(o,s)=>s.year=this.parseString(o.value),license:(o,s)=>s.license=this.parseString(o.value)}),n}},fe=class extends u{constructor(){super(...arguments);this.name="bounds-converter";this.supportedTags=["bounds"]}convert(t,r){let n={};return this.extractAttributes(t,n,{minlat:"minlat",minlon:"minlon",maxlat:"maxlat",maxlon:"maxlon"}),n}};var qe=require("htmlparser2"),xe=(n=>(n.TOKENIZE="tokenize",n.AST_GENERATE="ast_generate",n.CONVERT="convert",n.COMPLETE="complete",n))(xe||{}),ge=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=[],n=new qe.Parser({onopentag(i,o){r.push({type:"open",tag:i,attributes:o})},ontext(i){let o=i.replace(/\n/g,"").trim();o&&r.push({type:"text",tag:"text",value:o})},onclosetag(i){r.push({type:"close",tag:i})}},{xmlMode:!0});return n.write(e.xmlContent),n.end(),e.tokens=r,e.performance.tokenizeTime=Date.now()-t,e}},he=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=[],n,i=null;for(let s of e.tokens)if(s.type==="open"){let a={tag:s.tag,attributes:s.attributes||{},children:[]};n?i&&((o=i.children)==null||o.push(a)):n=a,r.push(a),i=a}else s.type==="text"&&i?i.value=s.value:s.type==="close"&&(r.pop(),i=r[r.length-1]||null);return e.ast=n,e.performance.astTime=Date.now()-t,e}},ye=class{constructor(e){this.getConverter=e;this.stage="convert"}async process(e){var n;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(([i,o])=>{i.startsWith("xmlns:")?r[i]=o.replace(/'/g,"'"):i==="xsi:schemaLocation"?r[i]=o.replace(/'/g,"'"):r[i]=o}),(n=e.ast.children)==null||n.forEach(i=>{let o=this.getConverter(i.tag);try{let s=o.convert(i,e);s&&this.assignResult(r,i.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}}},ve=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 F=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 ge,new he,new ye(e=>this.getConverter(e)),new ve]}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,new Te,new fe];for(let r of e)(t=r.supportedTags)==null||t.forEach(n=>{this.addConverterForTag(n,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((n,i)=>(n.priority||100)-(i.priority||100))}async registerConverter(e){var r,i;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})`:"";(i=e.supportedTags)==null||i.forEach(o=>{let a=(this.converterPlugins.get(o)||[]).map(c=>`${c.name}(${c.priority||100})`)})}async registerMiddleware(e){let t=this.middlewarePlugins.findIndex(n=>n.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,n]of this.converterPlugins){let i=n.findIndex(o=>o.name===e);i!==-1&&(t=n[i],n.splice(i,1),n.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(n=>({name:n.name,priority:n.priority||100})))}else for(let[r,n]of this.converterPlugins)t[r]=n.map(i=>({name:i.name,priority:i.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 n of t)try{await((r=n.initialize)==null?void 0:r.call(n,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 n of t)try{await((r=n.destroy)==null?void 0:r.call(n,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 i;let n=t;for(let o of this.middlewarePlugins){let s=o[e];if(s)try{n=await s.call(o,n,r)||n}catch(a){r.errors.push(a),await((i=o.onError)==null?void 0:i.call(o,a,r))}}return n}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 n of this.processors)try{switch(t=await n.process(t),n.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(i){t.errors.push(i);for(let o of this.middlewarePlugins)await((r=o.onError)==null?void 0:r.call(o,i,t))}return t.result}catch(n){throw n}}convertExtensions(e){var o,s;let t={},{attributes:r,tag:n,value:i}=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(i!==void 0)return i;return t}};var Le=h(require("dayjs")),Ne=h(require("dayjs/plugin/utc.js"));var Re={temperature:"atemp",wtemp:"wtemp",heartRate:"hr",cadence:"cad"};var Me={temperature:"Temperature",Depth:"Depth"};Le.default.extend(Ne.default);var A=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),i=`${t}${r}
|
|
2
|
+
</gpx>`;return this.compact?this.compressXML(i):i}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:n=[],trk:i=[]}=e,o=[];return t&&o.push(this.buildMetadata(t)),r.forEach(s=>{o.push(this.buildWaypoint(s,"wpt"))}),n.forEach(s=>{o.push(this.buildRoute(s))}),i.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()),
|
|
8
|
-
`)}addStandardWaypointElements(e,t){var r,i,
|
|
7
|
+
`)}buildBounds(e){let t=this.escapeXMLAttribute((e.minlat||0).toString()),r=this.escapeXMLAttribute((e.minlon||0).toString()),n=this.escapeXMLAttribute((e.maxlat||0).toString()),i=this.escapeXMLAttribute((e.maxlon||0).toString());return`<bounds minlat="${t}" minlon="${r}" maxlat="${n}" maxlon="${i}"/>`}buildWaypoint(e,t){var n,i,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",(n=e.ele)==null?void 0:n.toString(),this.formatElevation),e.time&&r.push(this.buildTimeElement(e.time)),this.addOptionalElement(r,"speed",(i=e.speed)==null?void 0:i.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,n,i,o,s,a,c;this.addOptionalElement(e,"magvar",(r=t.magvar)==null?void 0:r.toString()),this.addOptionalElement(e,"geoidheight",(n=t.geoidheight)==null?void 0:n.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",(i=t.hdop)==null?void 0:i.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(n=>{t.push(this.buildWaypoint(n,"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),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,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}escapeXMLAttribute(e){return typeof e!="string"?String(e||""):e.replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">").replace(/\r/g," ").replace(/\n/g," ").replace(/\t/g,"	")}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(
|
|
13
|
-
`+r.repeat(
|
|
14
|
-
</TrainingCenterDatabase>`;return this.compact?this.compressXML(
|
|
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),n=this.buildTrackPointExtension(e,t);Object.keys(n).length>0&&(r["gpxtpx:TrackPointExtension"]=n);let i=this.buildPowerExtension(e,t);Object.keys(i).length>0&&(r["gpxpx:PowerExtension"]=i);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"]||{}),n=Object.keys(Re);return Object.keys(e).filter(i=>n.includes(i)).forEach(i=>{let o=Re[i];o&&e[i]!==void 0&&(r[`gpxtpx:${o}`]=e[i])}),r}buildPowerExtension(e,t){return this.deepClone(t["gpxpx:PowerExtension"]||{})}buildGpxExtensions(e,t){let r=this.deepClone(t["gpxx:GpxExtensions"]||{}),n=Object.keys(Me);return Object.keys(e).filter(i=>n.includes(i)).forEach(i=>{let o=Me[i];o&&e[i]!==void 0&&(r[`gpxx:${o}`]=e[i])}),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 n=this.buildExtensionContent(r);return`<${t}>${n}</${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(n=>{e.push(this.buildLink(n))})}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,Le.default)(e).utc().format("YYYY-MM-DDTHH:mm:ss[Z]")}</time>`}addOptionalElement(e,t,r,n){if(r!=null&&r!==""){let i=n?n(r):this.escapeXML(r);e.push(`<${t}>${i}</${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,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}escapeXMLAttribute(e){return typeof e!="string"?String(e||""):e.replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">").replace(/\r/g," ").replace(/\n/g," ").replace(/\t/g,"	")}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 Oe=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 n=this.countNodes(t);return t}async onComplete(t,r){let n=r.metadata.get("performance");return t}countNodes(t){let r=1;if(t.children)for(let n of t.children)r+=this.countNodes(n);return r}},$e=class extends ${constructor(){super(...arguments);this.name="validation-middleware";this.description="Validate GPX data integrity"}async onComplete(t,r){let n=this.validateGPX(t);return n.length>0&&r.metadata.set("validation-errors",n),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 n of t.trk)if(n.trkseg){for(let i of n.trkseg)if(i.trkpt)for(let o of i.trkpt)(typeof o.lat!="number"||typeof o.lon!="number")&&r.push("Invalid track point coordinates")}}return r}};async function Je(p){let e=[new Oe,new $e];for(let t of e)await p.registerMiddleware(t)}var m=class extends v{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}},S=class extends E{async onError(e,t){t.warnings.push(`Middleware ${this.name} error: ${e.message}`)}};var G=class extends m{constructor(){super(...arguments);this.name="PositionConverter";this.supportedTags=["Position"]}convert(t,r){let n={};return this.processChildren(t,n,{LatitudeDegrees:(i,o)=>o.LatitudeDegrees=this.parseString(i.value),LongitudeDegrees:(i,o)=>o.LongitudeDegrees=this.parseString(i.value)}),n}},B=class extends m{constructor(){super(...arguments);this.name="TrackpointConverter";this.supportedTags=["Trackpoint"]}convert(t,r){let n={};return this.processChildren(t,n,{Time:(i,o)=>o.Time=this.parseString(i.value),Position:(i,o)=>{var a;let s=r.metadata.get("decoder");o.Position=(a=s==null?void 0:s.getConverter("Position"))==null?void 0:a.convert(i,r)},AltitudeMeters:(i,o)=>o.AltitudeMeters=this.parseFloat(i.value),DistanceMeters:(i,o)=>o.DistanceMeters=this.parseFloat(i.value),HeartRateBpm:(i,o)=>{if(i.value)o.HeartRateBpm=this.parseFloat(i.value);else{let s=this.getChildByTag(i,"Value");s!=null&&s.value&&(o.HeartRateBpm=this.parseFloat(s.value))}},Cadence:(i,o)=>{let s={Low:0,High:0};this.processChildren(i,s,{Low:(a,c)=>c.Low=this.parseFloat(a.value),High:(a,c)=>c.High=this.parseFloat(a.value)}),o.Cadence=s},SensorState:(i,o)=>o.SensorState=i.value,Extensions:(i,o)=>o.Extensions=this.convertExtensions(i)}),n}convertExtensions(t){var n;let r={};return(n=t.children)==null||n.forEach(i=>{r[i.tag]=this.convertExtensionContent(i)}),r}convertExtensionContent(t){var r;if((r=t.children)!=null&&r.length){let n={};return t.children.forEach(i=>{n[i.tag]=this.convertExtensionContent(i)}),n}else return t.value}},H=class extends m{constructor(){super(...arguments);this.name="TrackConverter";this.supportedTags=["Track"]}convert(t,r){let n={Trackpoint:[]};return this.processChildren(t,n,{Trackpoint:(i,o)=>{var c;let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("Trackpoint"))==null?void 0:c.convert(i,r);a&&o.Trackpoint&&o.Trackpoint.push(a)}}),n}},z=class extends m{constructor(){super(...arguments);this.name="ActivityLapConverter";this.supportedTags=["Lap"]}convert(t,r){let n={};return this.extractAttributes(t,n,{StartTime:"Id"}),this.processChildren(t,n,{TotalTimeSeconds:(i,o)=>o.TotalTimeSeconds=this.parseFloat(i.value),DistanceMeters:(i,o)=>o.DistanceMeters=this.parseFloat(i.value),MaximumSpeed:(i,o)=>o.MaximumSpeed=this.parseFloat(i.value),Calories:(i,o)=>o.Calories=this.parseFloat(i.value),AverageHeartRateBpm:(i,o)=>o.AverageHeartRateBpm=this.parseFloat(i.value),MaximumHeartRateBpm:(i,o)=>o.MaximumHeartRateBpm=this.parseFloat(i.value),Intensity:(i,o)=>o.Intensity=i.value,TriggerMethod:(i,o)=>o.TriggerMethod=i.value,Track:(i,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(i,r);a&&o.Track.push(a)},Notes:(i,o)=>o.Notes=this.parseString(i.value),Extensions:(i,o)=>o.Extensions=this.convertExtensions(i)}),n}convertExtensions(t){var n;let r={};return(n=t.children)==null||n.forEach(i=>{r[i.tag]=this.convertExtensionContent(i)}),r}convertExtensionContent(t){var r;if((r=t.children)!=null&&r.length){let n={};return t.children.forEach(i=>{n[i.tag]=this.convertExtensionContent(i)}),n}else return t.value}},V=class extends m{constructor(){super(...arguments);this.name="ActivityConverter";this.supportedTags=["Activity"]}convert(t,r){let n={Id:"",Lap:[]};return this.extractAttributes(t,n,{Sport:"Sport"}),this.processChildren(t,n,{Id:(i,o)=>o.Id=this.parseString(i.value),Lap:(i,o)=>{var c;let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("Lap"))==null?void 0:c.convert(i,r);a&&o.Lap.push(a)},Notes:(i,o)=>o.Notes=this.parseString(i.value),Training:(i,o)=>o.Training=this.convertTraining(i),Creator:(i,o)=>o.Creator=this.convertCreator(i),Extensions:(i,o)=>o.Extensions=this.convertExtensions(i)}),n}convertTraining(t){var n;let r={};return t.attributes&&Object.entries(t.attributes).forEach(([i,o])=>{r[i]=o}),(n=t.children)==null||n.forEach(i=>{r[i.tag]=this.convertExtensionContent(i)}),r}convertCreator(t){var n;let r={};return(n=t.children)==null||n.forEach(i=>{r[i.tag]=this.convertExtensionContent(i)}),r}convertExtensions(t){var n;let r={};return(n=t.children)==null||n.forEach(i=>{r[i.tag]=this.convertExtensionContent(i)}),r}convertExtensionContent(t){var r;if((r=t.children)!=null&&r.length){let n={};return t.children.forEach(i=>{n[i.tag]=this.convertExtensionContent(i)}),n}else return t.value}},U=class extends m{constructor(){super(...arguments);this.name="ActivityListConverter";this.supportedTags=["Activities"]}convert(t,r){let n={Activity:[],MultiSportSession:[]};return this.processChildren(t,n,{Activity:(i,o)=>{var c;let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("Activity"))==null?void 0:c.convert(i,r);a&&o.Activity&&o.Activity.push(a)},MultiSportSession:(i,o)=>{var c;let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("MultiSportSession"))==null?void 0:c.convert(i,r);a&&o.MultiSportSession&&o.MultiSportSession.push(a)}}),n}},W=class extends m{constructor(){super(...arguments);this.name="MultiSportSessionConverter";this.supportedTags=["MultiSportSession"]}convert(t,r){let n={};return this.processChildren(t,n,{Id:(i,o)=>o.Id=this.parseString(i.value),FirstSport:(i,o)=>{var a;let s=r.metadata.get("decoder");o.FirstSport=(a=s==null?void 0:s.getConverter("FirstSport"))==null?void 0:a.convert(i,r)},NextSport:(i,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(i,r);a&&o.NextSport.push(a)},Notes:(i,o)=>o.Notes=this.parseString(i.value)}),n}},j=class extends m{constructor(){super(...arguments);this.name="AbstractSourceConverter";this.supportedTags=["Author","Creator"]}convert(t,r){let n={};return this.processChildren(t,n,{Name:(i,o)=>o.Name=this.parseString(i.value)}),n}};var Ge=require("htmlparser2"),Ce=class{static tokenizeXML(e){let t=[],r=new Ge.Parser({onopentag(n,i){t.push({type:"open",tag:n,attributes:i})},ontext(n){let i=n.replace(/\n/g,"").trim();i&&t.push({type:"text",tag:"text",value:i})},onclosetag(n){t.push({type:"close",tag:n})}},{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),n="",i=0,o=!1;for(let s=0;s<e.length;s++){let a=e[s],c=e[s+1];a==="<"?(c==="/"?(i--,o||(n+=`
|
|
12
|
+
`+r.repeat(i))):c!=="?"&&c!=="!"&&(o||(n+=`
|
|
13
|
+
`+r.repeat(i)),i++),o=!0):a===">"&&(o=!1,c==="<"&&e[s+2]==="/"&&i--),n+=a}return n.trim()}static validateXML(e){try{let t=new Ge.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],n={},i=r.match(/version=["']([^"']+)["']/);i&&(n.version=i[1]);let o=r.match(/encoding=["']([^"']+)["']/);o&&(n.encoding=o[1]);let s=r.match(/standalone=["']([^"']+)["']/);return s&&(n.standalone=s[1]),n}static escapeXML(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}static unescapeXML(e){return e.replace(/</g,"<").replace(/>/g,">").replace(/"/g,'"').replace(/'/g,"'").replace(/&/g,"&")}};var Be=(n=>(n.TOKENIZE="tokenize",n.AST_GENERATE="ast-generate",n.CONVERT="convert",n.COMPLETE="complete",n))(Be||{}),K=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=Ce.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}},Y=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 n of e)if(n.type==="open"){let i={tag:n.tag,attributes:n.attributes,children:[]};r&&(r.children=r.children||[],r.children.push(i)),t.push(i),r=i,t.length||r||(r=i)}else n.type==="close"?(t.pop(),r=t[t.length-1]):n.type==="text"&&r&&n.value&&typeof n.value=="string"&&n.value.trim()&&(r.value=n.value.trim());return r}},Z=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(([n,i])=>{r[n]=i}),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(n=>{let i=this.convertAST(n,t);r[n.tag]?(Array.isArray(r[n.tag])||(r[n.tag]=[r[n.tag]]),r[n.tag].push(i)):r[n.tag]=i}),r}countElements(e){let t=1;if(e.children)for(let r of e.children)t+=this.countElements(r);return t}},q=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 D=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 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(n=>{this.addConverterForTag(n,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((n,i)=>(n.priority||100)-(i.priority||100))}async registerConverter(e){var r,i;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})`:"";(i=e.supportedTags)==null||i.forEach(o=>{let a=(this.converterPlugins.get(o)||[]).map(c=>`${c.name}(${c.priority||100})`)})}async registerMiddleware(e){let t=this.middlewarePlugins.findIndex(n=>n.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,n]of this.converterPlugins){let i=n.findIndex(o=>o.name===e);i!==-1&&(t=n[i],n.splice(i,1),n.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 n of t)try{await((r=n.initialize)==null?void 0:r.call(n,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 n of t)try{await((r=n.destroy)==null?void 0:r.call(n,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 i;let n=t;for(let o of this.middlewarePlugins){let s=o[e];if(s)try{n=await s.call(o,n,r)||n}catch(a){r.errors.push(a),await((i=o.onError)==null?void 0:i.call(o,a,r))}}return n}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 n of this.processors)try{switch(t=await n.process(t),n.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(i){t.errors.push(i);for(let o of this.middlewarePlugins)await((r=o.onError)==null?void 0:r.call(o,i,t))}return t.result}catch(n){throw n}}convertExtensions(e){var o,s;let t={},{attributes:r,tag:n,value:i}=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(i!==void 0)return i;return t}async parserByBuffer(e){return this.parseByBuffer(e)}async parseByString(e){let t=Buffer.from(e,"utf-8");return this.parseByBuffer(t)}};var He=h(require("dayjs")),Qe=h(require("dayjs/plugin/utc.js"));He.default.extend(Qe.default);var _=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),i=`${t}${r}
|
|
14
|
+
</TrainingCenterDatabase>`;return this.compact?this.compressXML(i):i}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",n=e.xmlns||"http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2",i=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(n)}"`,` xmlns:xsi="${this.escapeXMLAttribute(i)}"`,` xsi:schemaLocation="${this.escapeXMLAttribute(o)}">`].join(`
|
|
15
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
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
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
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(
|
|
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(n=>{r.push(this.buildActivityLap(n))}),this.addOptionalElement(r,"Notes",e.Notes),e.Training,e.Creator,e.Extensions&&r.push(this.buildExtensions(e.Extensions)),r.push("</Activity>"),r.join(`
|
|
20
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
21
|
`)}buildTrack(e){let t=["<Track>"];return e.Trackpoint&&e.Trackpoint.forEach(r=>{t.push(this.buildTrackpoint(r))}),t.push("</Track>"),t.join(`
|
|
22
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
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
24
|
`)}buildFirstSport(e){let t=["<FirstSport>"];return e.Activity&&t.push(this.buildActivity(e.Activity)),t.push("</FirstSport>"),t.join(`
|
|
25
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,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}escapeXMLAttribute(e){return typeof e!="string"?String(e||""):e.replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">").replace(/\r/g," ").replace(/\n/g," ").replace(/\t/g,"	")}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});
|
|
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 n=this.buildExtensionContent(r);return`<${t}>${n}</${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,He.default)(e).utc().format("YYYY-MM-DDTHH:mm:ss[Z]")}addOptionalElement(e,t,r,n){if(r!=null&&r!==""){let i=n?n(r):this.escapeXML(r);e.push(`<${t}>${i}</${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,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}escapeXMLAttribute(e){return typeof e!="string"?String(e||""):e.replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">").replace(/\r/g," ").replace(/\n/g," ").replace(/\t/g,"	")}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 Pe=class extends S{constructor(){super(...arguments);this.name="tcx-performance-middleware";this.description="Monitor TCX parsing performance"}async onTokenize(t,r){return t}async onAstGenerate(t,r){let n=this.countNodes(t);return t}async onComplete(t,r){let n=r.metadata.get("performance");return t}countNodes(t){let r=1;if(t.children)for(let n of t.children)r+=this.countNodes(n);return r}},we=class extends S{constructor(){super(...arguments);this.name="tcx-validation-middleware";this.description="Validate TCX data integrity"}async onComplete(t,r){let n=this.validateTCX(t);return n.length>0&&r.metadata.set("validation-errors",n),t}validateTCX(t){let r=[];if(t.version||r.push("Missing TCX version information"),t.creator||r.push("Missing TCX creator information"),t.Activities&&t.Activities.Activity){for(let n of t.Activities.Activity)if(n.Id||r.push("Activity missing ID information"),(!n.Lap||n.Lap.length===0)&&r.push("Activity must contain at least one Lap"),n.Lap){for(let i of n.Lap)if(i.Track){for(let o of i.Track)if(o.Trackpoint)for(let s of o.Trackpoint)s.Position&&(!s.Position.LatitudeDegrees||!s.Position.LongitudeDegrees)&&r.push("Invalid trackpoint coordinates")}}}return r}},Ee=class extends S{constructor(){super(...arguments);this.name="tcx-enhancement-middleware";this.description="Enhance TCX data with additional calculated fields"}async onComplete(t,r){if(t.Activities&&t.Activities.Activity)for(let n of t.Activities.Activity)n.totalDistance=this.calculateTotalDistance(n),n.totalDuration=this.calculateTotalDuration(n),n.totalDistance&&n.totalDuration&&(n.averageSpeed=n.totalDistance/n.totalDuration);return t}calculateTotalDistance(t){let r=0;if(t.Lap)for(let n of t.Lap)n.DistanceMeters&&(r+=n.DistanceMeters);return r}calculateTotalDuration(t){let r=0;if(t.Lap)for(let n of t.Lap)n.TotalTimeSeconds&&(r+=n.TotalTimeSeconds);return r}};async function Pt(p){let e=[new Pe,new we,new Ee];for(let t of e)await p.registerMiddleware(t)}var X=class extends v{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 n=e[r-1],i=e[r],o=6371e3,s=n.lat*Math.PI/180,a=i.lat*Math.PI/180,c=(i.lat-n.lat)*Math.PI/180,d=(i.lon-n.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 n,i;if(e.length<2)return;let t=(n=e[0])==null?void 0:n.time,r=(i=e[e.length-1])==null?void 0:i.time;if(!(!t||!r))return Math.round((r-t)/1e3)}},R=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 et={"gpxtpx:cad":"cadence","gpxtpx:hr":"heartRate","gpxtpx:temp":"temperature","gpxtpx:wtemp":"wtemp","gpxtpx:atemp":"atemp","gpxx:Temperature":"temperature","gpxx:Depth":"depth"},ze=p=>p*(180/Math.pow(2,31));var M=h(require("dayjs"));function tt(p,e=0){let t=Math.pow(10,e);return Math.round(p*t)/t}var Se=class extends X{constructor(){super(...arguments);this.name="gpx-to-sport-converter";this.supportedTags=["gpx"];this.convertGPXExtensions=t=>{let r={};return Object.entries(t).forEach(([n,i])=>{if(typeof i!="string"&&typeof i!="number")r={...r,...this.convertGPXExtensions(i)};else if(typeof i<"u"&&i!=="undefined"){let o=et[n]||n;r[o]=i}}),r}}convert(t,r){if(r.sourceFormat!=="gpx")return;let n=r.sourceData;return this.convertGPX(n)}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(n=>{var i;return{name:n.name,trackseg:((i=n.trkseg)==null?void 0:i.map(o=>({name:n.name,points:o.trkpt?this.convertWpts2Points(o.trkpt):[]})))||[]}})),t.rte&&(r.routes=t.rte.map(n=>({name:n.name,points:n.rtept?this.convertWpts2Points(n.rtept):[]}))),r}convertPoint(t){if(t.lat==null||t.lon==null||typeof t.lat!="number"||typeof t.lon!="number")return;let{extensions:r}=t,n=r?this.convertGPXExtensions(r):{};return{lat:t.lat,lon:t.lon,ele:t.ele,time:this.convertTime(t.time),...n}}convertWpts2Points(t){let r=[];for(let n=0;n<t.length;n++){let i=t[n];if(i.lat!=null&&i.lon!=null&&typeof i.lat=="number"&&typeof i.lon=="number"){let o=this.convertPoint(i);o&&r.push(o)}}return r}},be=class extends X{constructor(){super(...arguments);this.name="fit-to-sport-converter";this.supportedTags=["fit"]}convert(t,r){if(r.sourceFormat!=="fit")return;let n=r.sourceData;return this.convertFIT(n)}convertFIT(t){var n,i;let r={metadata:{originType:"FIT",fileType:"fit"}};if((n=t.sessionMesgs)!=null&&n.length){r.tracks=[];for(let o of t.sessionMesgs)r.tracks.push({name:o.event,startTime:o.startTime?(0,M.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((i=t.courseMesgs)!=null&&i.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:n,altitude:i,timestamp:o,heartRate:s,cadence:a,distance:c,power:d,enhancedAltitude:l,enhancedSpeed:f,temperature:g,...x}=t;if(!(r==null||n==null||typeof r!="number"||typeof n!="number"))return{lat:tt(ze(Number(n)),6),lon:tt(ze(Number(r)),6),ele:i,heart:s,power:d,cadence:a,temperature:g,time:o?(0,M.default)(o).valueOf():void 0,...x}}convertFITLap2Trackseg(t){var n;let r=[];if(!(t!=null&&t.length))return[];for(let i of t){let o=((n=i==null?void 0:i.recordMesgs)==null?void 0:n.map(s=>this.convertPoint(s)).filter(s=>s!==void 0))||[];r.push({points:o,duration:i.totalElapsedTime,distance:i.totalDistance,startTime:i.startTime?(0,M.default)(i.startTime).valueOf():void 0,endTime:i.startTime&&i.totalElapsedTime?(0,M.default)(i.startTime).add(i.totalElapsedTime,"second").valueOf():void 0,avgSpeed:i.avgSpeed,maxSpeed:i.maxSpeed,avgCadenceBpm:i.avgCadence,maxCadenceBpm:i.maxCadence,avgPower:i.avgPower,maxPower:i.maxPower,totalAscent:i.totalAscent,totalDescent:i.totalDescent,calories:i.totalCalories,__fit__lapMesgType:i})}return r}convertLap2Points(t){var n;let r=[];if(!(t!=null&&t.length))return[];for(let i of t){let o=((n=i.recordMesgs)==null?void 0:n.map(s=>this.convertPoint(s)).filter(s=>s!==void 0))||[];o.length&&(r=[...r,...o])}return r}},Ie=class extends X{constructor(){super(...arguments);this.name="tcx-to-sport-converter";this.supportedTags=["tcx"]}convert(t,r){if(r.sourceFormat!=="tcx")return;let n=r.sourceData;return this.convertTCX(n)}convertTCX(t){var n,i,o,s;let r={metadata:{originType:"TCX",fileType:"tcx"}};if((i=(n=t.Activities)==null?void 0:n.Activity)!=null&&i.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:n,DistanceMeters:i,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:n?(0,M.default)(n).valueOf():void 0,distance:i,ele:o}}convertLap2Trackseg(t){var n,i,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:(n=d==null?void 0:d[0])==null?void 0:n.time,endTime:(i=d==null?void 0:d[d.length-1])==null?void 0:i.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 rt(p){return Math.round(p*(Math.pow(2,31)/180))}var ke=class extends R{constructor(){super(...arguments);this.name="sport-to-gpx-encoder";this.supportedTags=["gpx"]}encode(t,r){var i,o,s,a;if(r.targetFormat!=="gpx")return;let n={version:"1.1",creator:((i=t.metadata)==null?void 0:i.creator)||"TrackSwap"};return(o=t.points)!=null&&o.length&&(n.wpt=this.convertPoints2Wpts(t.points)),(s=t.routes)!=null&&s.length&&(n.rte=t.routes.map(c=>this.convertRoute2GPXRoute(c))),(a=t.tracks)!=null&&a.length&&(n.trk=t.tracks.map(c=>this.convertTrack2GPXTrack(c))),n}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(n=>({trkpt:n.points?this.convertPoints2Wpts(n.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}},Fe=class extends R{constructor(){super(...arguments);this.name="sport-to-fit-encoder";this.supportedTags=["fit"]}encode(t,r){var i,o;if(r.targetFormat!=="fit")return;let n={};return(i=t.tracks)!=null&&i.length&&(n.sessionMesgs=t.tracks.map(s=>this.convertTrack2FITSession(s))),(o=t.routes)!=null&&o.length&&(n.courseMesgs=t.routes.map(s=>this.convertRoute2FITCourse(s))),n}convertTrack2FITSession(t){var n;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:((n=t.trackseg)==null?void 0:n.map(i=>this.convertSeg2FITLap(i)))||[]}}convertSeg2FITLap(t){var n;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:((n=t.points)==null?void 0:n.map(i=>this.convertPoint2FITRecord(i)))||[]}}convertPoint2FITRecord(t){return{timestamp:t.time?this.convertTimeToString(t.time):this.convertTimeToString(void 0),positionLat:rt(t.lat),positionLong:rt(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],n=t[t.length-1],i=r!=null&&r.time?this.convertTimeToString(r.time):this.convertTimeToString(void 0),o=r!=null&&r.time&&(n!=null&&n.time)?Math.round((n.time-r.time)/1e3):0,s=(n==null?void 0:n.distance)||0;return{startTime:i,totalElapsedTime:o,totalDistance:s,recordMesgs:t.map(a=>this.convertPoint2FITRecord(a))}}},Ae=class extends R{constructor(){super(...arguments);this.name="sport-to-tcx-encoder";this.supportedTags=["tcx"]}encode(t,r){var i,o,s;if(r.targetFormat!=="tcx")return;let n={Author:{Name:((i=t.metadata)==null?void 0:i.creator)||"TrackSwap"}};return(o=t.tracks)!=null&&o.length&&(n.Activities={Activity:t.tracks.map(a=>this.convertTrack2TCXActivity(a))}),(s=t.routes)!=null&&s.length&&(n.Courses={Course:t.routes.map(a=>this.convertRoute2TCXCourse(a))}),n}convertTrack2TCXActivity(t){var n;let r="Other";return(t.sport==="Running"||t.sport==="Biking")&&(r=t.sport),{Id:t.name||`Activity_${Date.now()}`,Sport:r,Lap:((n=t.trackseg)==null?void 0:n.map(i=>this.convertSeg2TCXLap(i)))||[]}}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 De=class{constructor(){this.converters=new Map;this.encoders=new Map;this.registerDefaultConverters(),this.registerDefaultEncoders()}registerDefaultConverters(){this.registerConverter(new Se),this.registerConverter(new be),this.registerConverter(new Ie)}registerDefaultEncoders(){this.registerEncoder(new ke),this.registerEncoder(new Fe),this.registerEncoder(new Ae)}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 n=this.findConverter(t);if(!n)throw new Error(`No converter found for format "${t}"`);let i=Date.now(),o=n.convert({},r);if(r.performance.convertTime=Date.now()-i,!o)throw new Error(`Converter "${n.name}" returned empty result`);return r.result=o,r.performance.endTime=Date.now(),r.stats.endTime=Date.now(),o}catch(n){throw r.errors.push(n),n}}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 n=this.findEncoder(t);if(!n)throw new Error(`No encoder found for format "${t}"`);let i=Date.now(),o=n.encode(e,r);if(r.performance.encodeTime=Date.now()-i,!o)throw new Error(`Encoder "${n.name}" returned empty result`);return r.result=o,r.performance.endTime=Date.now(),r.stats.endTime=Date.now(),o}catch(n){throw r.errors.push(n),n}}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 L=class{constructor(){this.gpxDecoder=new F,this.gpxEncoder=new A,this.fitDecoder=new C,this.fitEncoder=new w,this.tcxDecoder=new D,this.tcxEncoder=new _,this.sportProcessor=new De}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 n=r||this.detectFormat(e);if(n==="unknown")throw new Error("Unable to recognize source file format, please specify sourceType parameter");if(n===t)return e;let i;switch(n){case"gpx":let s=await this.parseGPX(e);if(!s)throw new Error("GPX file parsing failed");i=s;break;case"fit":i=await this.parseFIT(e);break;case"tcx":i=await this.parseTCX(e);break;default:throw new Error(`Unsupported source file format: ${n}`)}let o;switch(n){case"gpx":o=await this.convertGPXToSport(i);break;case"fit":o=await this.convertFITToSport(i);break;case"tcx":o=await this.convertTCXToSport(i);break;default:throw new Error(`Unsupported source file format conversion: ${n}`)}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(n){let i=r||"auto-detect";throw new Error(`${i} to ${t.toUpperCase()} failed: ${n.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 n=await this.parseGPX(e);if(!n)throw new Error("GPX parsing failed");return n;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 n=await this.parseGPX(e);if(!n)throw new Error("GPX parsing failed");return this.convertGPXToSport(n);case"fit":let i=await this.parseFIT(e);return this.convertFITToSport(i);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 wt=L;0&&(module.exports={AbstractSourceConverter,ActivityConverter,ActivityLapConverter,ActivityListConverter,AstGenerateProcessor,BaseFITMessageConverter,BaseFITMiddleware,BaseFITStructurePlugin,BaseTCXConverter,BaseTCXMiddleware,CompleteProcessor,ConvertProcessor,CourseStructurePlugin,FITDecoder,FITEncoder,FileHeaderPlugin,GPXDecoder,GPXEncoder,MultiSportSessionConverter,PipelineStage,PositionConverter,SessionStructurePlugin,TCXDecoder,TCXEncoder,TCXEnhancementMiddleware,TCXPerformanceMiddleware,TCXPipelineStage,TCXValidationMiddleware,TokenizeProcessor,TrackConverter,TrackSwap,TrackpointConverter,registerDefaultMiddlewares,registerDefaultTCXMiddlewares});
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
export * from "./types.js";
|
|
2
|
+
export * from "./FIT/index.js";
|
|
3
|
+
export * from "./GPX/index.js";
|
|
4
|
+
export * from "./TCX/index.js";
|
|
5
|
+
export { TrackSwap } from "./TrackSwap.js";
|
|
1
6
|
import { TrackSwap } from "./TrackSwap.js";
|
|
2
|
-
import GPXManager from "./GPX/index.js";
|
|
3
|
-
import { Token, TokenAST, AttributeType, LatitudeType, LongitudeType, DegreesType, ExtensionsType } from "./types.js";
|
|
4
|
-
export { TokenAST, AttributeType, LatitudeType, LongitudeType, DegreesType, ExtensionsType, Token, TrackSwap, };
|
|
5
|
-
export { GPXManager };
|
|
6
7
|
export default TrackSwap;
|
package/dist/index.js
CHANGED
|
@@ -1,26 +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 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(/'/g,"'"):n==="xsi:schemaLocation"?r[n]=o.replace(/'/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
|
-
</gpx>`;return this.compact?this.compressXML(
|
|
3
|
-
`)}buildGPXContent(e){let{metadata:t,wpt:r=[],rte:
|
|
1
|
+
var G=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"),n=r.fromBuffer(e);if(!t.isFIT(n))throw new Error("Not a valid FIT file");let i=new t(n),{messages:o,errors:s}=i.read();return s&&s.length>0,o}},B=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[n,i]of Object.entries(e.rawMessages)){if(!Array.isArray(i)||i.length===0){r[n]=i;continue}let o=this.getConverters(n);if(o.length===0)r[n]=i;else{let s=o[0];try{let a=s.convertMessages(i,e);r[n]=a}catch(a){e.errors.push(a),r[n]=i}}}return e.rawMessages=r,e.performance.extractTime=Date.now()-t,e}},H=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={},n=this.getStructurePlugins();for(let i of n)try{let o=i.structureData(e.rawMessages,e);r={...r,...o}}catch(o){e.errors.push(o)}return e.result=r,e.performance.structureTime=Date.now()-t,e}},z=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 g from"dayjs";var Ee=class{constructor(){this.version="1.0.0";this.priority=100}supports(e){return this.supportedMessageTypes.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}parseTimestamp(e){if(!e)return;let t=new Date(e);return isNaN(t.getTime())?void 0:t}calculateDuration(e,t){if(!e||!t)return 0;let r=new Date(e).getTime(),n=new Date(t).getTime();return Math.max(0,(n-r)/1e3)}filterMessagesByTimeRange(e,t,r,n=2e3){let i=new Date(t).getTime(),o=new Date(r).getTime();return e.filter(s=>{if(!s.timestamp)return!1;let a=new Date(s.timestamp).getTime();return a>=i-n&&a<=o+n})}groupMessagesByLap(e,t){return t.map(r=>{let n=this.filterMessagesByTimeRange(e,r.startTime,r.timestamp);return{lap:r,records:n}})}},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}},Se=class{constructor(){this.version="1.0.0";this.description="";this.priority=100}async initialize(e){}async destroy(e){}async validate(e){return!0}async onParse(e,t){return e}async onExtractMessages(e,t){return e}async onStructure(e,t){return e}async onComplete(e,t){return e}async onError(e,t){}};var k=class extends v{constructor(){super(...arguments);this.name="SessionStructurePlugin";this.priority=10}structureData(t,r){let{sessionMesgs:n,lapMesgs:i,recordMesgs:o}=t;return n!=null&&n.length?{sessionMesgs:n.map(a=>{let c=g(a.startTime).valueOf(),d=g(a.timestamp).valueOf(),T=((i==null?void 0:i.filter(f=>{let y=g(f.startTime).valueOf(),I=g(f.timestamp).valueOf();return y>=c&&I<=d}))||[]).map(f=>{let y=g(f.startTime).valueOf(),I=g(f.timestamp).valueOf(),$=(o==null?void 0:o.filter(Ze=>{let Oe=g(Ze.timestamp).valueOf();return Oe>=y&&Oe<=I}))||[];return{...f,recordMesgs:$}});return{...a,lapMesgs:T}})}:{}}},F=class extends v{constructor(){super(...arguments);this.name="CourseStructurePlugin";this.priority=10}structureData(t,r){let{courseMesgs:n,lapMesgs:i,recordMesgs:o}=t;if(!(n!=null&&n.length))return{};let s=2e3;return{courseMesgs:n.map(c=>{let d=(i==null?void 0:i.map(l=>{let T=g(l.startTime).valueOf(),f=g(l.timestamp).valueOf(),y=(o==null?void 0:o.filter(I=>{let $=g(I.timestamp).valueOf();return $>=T-s&&$<=f+s}))||[];return{...l,recordMesgs:y}}))||[];return{...c,lapMesgs:d}})}}},A=class extends v{constructor(){super(...arguments);this.name="FileHeaderPlugin";this.priority=1}structureData(t,r){let{fileIdMesgs:n}=t;if(n!=null&&n.length&&n[0]){let i=n[0];r.fileHeader={type:i.type,manufacturer:i.manufacturer,product:i.product}}return{}}};var P=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 G,new B(e=>this.getConverters(e)),new H(()=>this.structurePlugins),new z]}async registerDefaultPlugins(){if(this.defaultPluginsRegistered)return;let e=[new A,new k,new F];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((n,i)=>(n.priority||100)-(i.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 i=(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(n=>n.name===e.name);t!==-1?this.middlewarePlugins[t]=e:(this.middlewarePlugins.push(e),this.middlewarePlugins.sort((n,i)=>(n.priority||100)-(i.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[n,i]of this.converterPlugins){let o=i.findIndex(s=>s.name===e);o!==-1&&(i.splice(o,1),i.length===0&&this.converterPlugins.delete(n))}let t=this.structurePlugins.findIndex(n=>n.name===e);t!==-1&&this.structurePlugins.splice(t,1);let r=this.middlewarePlugins.findIndex(n=>n.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 n of t)try{await((r=n.initialize)==null?void 0:r.call(n,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 n of t)try{await((r=n.destroy)==null?void 0:r.call(n,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 i;let n=t;for(let o of this.middlewarePlugins){let s=o[e];if(s)try{n=await s.call(o,n,r)||n}catch(a){r.errors.push(a),await((i=o.onError)==null?void 0:i.call(o,a,r))}}return n}async parseByBuffer(e,t={}){var n;await this.initialize();let r=this.createContext();r.rawData=e,r.userData=t.userData,r.metadata.set("decoder",this);try{for(let i of this.processors)try{switch(r=await i.process(r),i.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((n=s.onError)==null?void 0:n.call(s,o,r))}return r.result||{}}catch(i){throw i}}};var qe={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=qe[p];return{size:1,baseType:0,mapValue:t=>typeof t=="string"?e[t]??255:t,setValue:function(t,r){this.setUint8(t,r)}}},be={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(Ge(p)),setValue:Je},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 $e(p){return Array.from(Ge(p)).length+1}function*Ge(p){for(let e of Ne(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*Ne(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 Je(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"}]}},et=(p,e)=>p.map(t=>({...t,value:e[t.name]})).filter(({value:t})=>t!==void 0),V=class p{static check(e,t,r,n){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 i=r.map(s=>s.name),o=Object.keys(n).filter(s=>!i.includes(s));if(o.length)throw new Error(`Message '${e}' has no field definitions named '${o}'`)}constructor(e,t,r){let n=Qe[t];if(!n)throw new Error(`Unknown message type: ${t}`);let{mesgNum:i,fieldDefns:o}=n;p.check(t,i,o,r),this.localNum=e,this.mesgNum=i,this.fields=et(o,r)}get mesgDefn(){let e=this.fields.map(({number:t,type:r,value:n})=>{let i=be[r];if(!i)throw new Error(`Unknown type: ${r}`);let{size:o,baseType:s}=i;return r==="string"?{number:t,size:$e(n),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:n,mesgNum:i,fieldDefns:o}=this.mesgDefn;return i===e.mesgNum&&n===e.localNum&&r(o,e.fieldDefns)}get defnRecord(){let{localNum:e,mesgNum:t,fieldDefns:r}=this.mesgDefn,n=6+3*r.length,i=new DataView(new ArrayBuffer(n));i.setUint8(0,64|e),i.setUint8(2,1),i.setUint16(3,t),i.setUint8(5,r.length);let o=6;for(let s of r)i.setUint8(o++,s.number),i.setUint8(o++,s.size),i.setUint8(o++,s.baseType);return i.buffer}get dataRecord(){let{fieldDefns:e}=this.mesgDefn,t=1+e.reduce((i,{size:o})=>i+o,0),r=new DataView(new ArrayBuffer(t));r.setUint8(0,this.localNum);let n=1;for(let{number:i,type:o,value:s}of this.fields){let a=be[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,n,l),n+=c}return r.buffer}};var tt=[0,52225,55297,5120,61441,15360,10240,58369,40961,27648,30720,46081,20480,39937,34817,17408],Be=(p,e)=>(p>>>4^tt[p&15^e])&65535,rt=(p,e,t)=>Be(Be(p,e),t),nt=(p,e)=>rt(p,e&15,e>>>4);function Ie(p,e=0){let t=e,r=p instanceof ArrayBuffer?new Uint8Array(p):p;for(let n=0;n<r.length;n++)t=nt(t,r[n]);return t}import it from"dayjs";var He=14,ot=16,st=2078,at=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,n=[],i=[];for(let o of t){if(o.lapMesgs&&this.buildEventsFromLaps(o.lapMesgs,n),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,i)}n.forEach(o=>this.buildEvent(o)),i.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 n=[];for(let s of r.lapMesgs)s.recordMesgs&&n.push(...s.recordMesgs);n.sort((s,a)=>s.timestamp&&a.timestamp?new Date(s.timestamp).getTime()-new Date(a.timestamp).getTime():(s.distance||0)-(a.distance||0));let i=n[0],o=n[n.length-1];i.timestamp&&this.buildEvent({timestamp:i.timestamp,event:"timer",eventType:"start",eventGroup:0}),n.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 n;let r=((n=e.fileIdMesgs)==null?void 0:n[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,n)=>{r.startTime&&t.push({timestamp:r.startTime,event:"timer",eventType:"start",eventGroup:n}),r.timestamp&&t.push({timestamp:r.timestamp,event:"timer",eventType:n===e.length-1?"stop_all":"stop",eventGroup:n})})}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:it(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 n=this.localNum[e];n===void 0&&(n=this.localNum[e]=Object.keys(this.localNum).length);let i=new V(n,e,r),o=this.mesgDefn[n];(!o||!i.isSameDefn(o))&&(this.messages.push(i.defnRecord),this.mesgDefn[n]=i.mesgDefn),this.messages.push(i.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)=>Ie(t,e),0)}get header(){let e=new DataView(new ArrayBuffer(He));return e.setUint8(0,He),e.setUint8(1,ot),e.setUint16(2,st,!0),e.setUint32(4,this.dataLen,!0),e.setUint32(8,at),e.setUint16(12,Ie(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 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 n;return(n=e.attributes)==null?void 0:n[r]})}extractAttributes(e,t,r){e.attributes&&Object.entries(e.attributes).forEach(([n,i])=>{let o=r[n];o&&o in t&&(t[o]=String(i||""))})}processChildren(e,t,r){var n;(n=e.children)==null||n.forEach(i=>{let o=r[i.tag];o&&o(i,t)})}getChildValue(e,t){var n;let r=(n=e.children)==null?void 0:n.find(i=>i.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(n=>n.tag===t)}getChildrenByTag(e,t){var r;return((r=e.children)==null?void 0:r.filter(n=>n.tag===t))||[]}convertExtensions(e){var r;let t={};return(r=e.children)==null||r.forEach(n=>{t[n.tag]=this.convertExtensionContent(n)}),t}convertExtensionContent(e){var t;if((t=e.children)!=null&&t.length){let r={};return e.children.forEach(n=>{r[n.tag]=this.convertExtensionContent(n)}),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 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(([n,i])=>{let o=r[n];o&&o in t&&typeof i<"u"&&(t[o]=this.parseFloat(i))})}},D=class extends C{async onError(e,t){t.warnings.push(`Middleware ${this.name} error: ${e.message}`)}};var U=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 n={lat:this.parseFloat(t.attributes.lat),lon:this.parseFloat(t.attributes.lon)};return this.extractAttributes(t,n,{lat:"lat",lon:"lon"}),this.processChildren(t,n,{ele:(i,o)=>o.ele=this.parseFloat(i.value),time:(i,o)=>o.time=new Date(this.parseString(i.value)),speed:(i,o)=>o.speed=this.parseFloat(i.value),course:(i,o)=>o.course=this.parseFloat(i.value),name:(i,o)=>o.name=this.parseString(i.value),cmt:(i,o)=>o.cmt=this.parseString(i.value),desc:(i,o)=>o.desc=this.parseString(i.value),src:(i,o)=>o.src=this.parseString(i.value),sym:(i,o)=>o.sym=this.parseString(i.value),type:(i,o)=>o.type=this.parseString(i.value),fix:(i,o)=>o.fix=this.parseString(i.value),sat:(i,o)=>o.sat=this.parseString(i.value),hdop:(i,o)=>o.hdop=this.parseFloat(i.value),vdop:(i,o)=>o.vdop=this.parseFloat(i.value),pdop:(i,o)=>o.pdop=this.parseFloat(i.value),ageofdgpsdata:(i,o)=>o.ageofdgpsdata=this.parseFloat(i.value),geoidheight:(i,o)=>o.geoidheight=this.parseFloat(i.value),magvar:(i,o)=>o.magvar=this.parseFloat(i.value),dgpsid:(i,o)=>o.dgpsid=this.parseFloat(i.value),extensions:(i,o)=>{let s=r.metadata.get("decoder");s&&(o.extensions=s.convertExtensions(i))},link:(i,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(i,r);a&&o.link&&o.link.push(a)}}),n}},W=class extends u{constructor(){super(...arguments);this.name="rte-converter";this.supportedTags=["rte"]}convert(t,r){let n={rtept:[]};return this.processChildren(t,n,{name:(i,o)=>o.name=this.parseString(i.value),cmt:(i,o)=>o.cmt=this.parseString(i.value),desc:(i,o)=>o.desc=this.parseString(i.value),src:(i,o)=>o.src=this.parseString(i.value),number:(i,o)=>o.number=this.parseFloat(i.value),type:(i,o)=>o.type=this.parseString(i.value),rtept:(i,o)=>{var c;let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("wpt"))==null?void 0:c.convert(i,r);a&&o.rtept&&o.rtept.push(a)},extensions:(i,o)=>{let s=r.metadata.get("decoder");s&&(o.extensions=s.convertExtensions(i))},link:(i,o)=>{var a;o.link||(o.link=[]);let s=r.metadata.get("decoder");(a=i.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)})}}),n}},j=class extends u{constructor(){super(...arguments);this.name="trk-converter";this.supportedTags=["trk"]}convert(t,r){let n={trkseg:[]};return this.processChildren(t,n,{name:(i,o)=>o.name=this.parseString(i.value),cmt:(i,o)=>o.cmt=this.parseString(i.value),desc:(i,o)=>o.desc=this.parseString(i.value),src:(i,o)=>o.src=this.parseString(i.value),number:(i,o)=>o.number=this.parseFloat(i.value),type:(i,o)=>o.type=this.parseString(i.value),trkseg:(i,o)=>{var c;let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("trkseg"))==null?void 0:c.convert(i,r);a&&o.trkseg&&o.trkseg.push(a)},extensions:(i,o)=>{let s=r.metadata.get("decoder");s&&(o.extensions=s.convertExtensions(i))},link:(i,o)=>{var a;o.link||(o.link=[]);let s=r.metadata.get("decoder");(a=i.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)})}}),n}},K=class extends u{constructor(){super(...arguments);this.name="trkseg-converter";this.supportedTags=["trkseg"]}convert(t,r){let n={trkpt:[]};return this.processChildren(t,n,{trkpt:(i,o)=>{var c;let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("wpt"))==null?void 0:c.convert(i,r);a&&o.trkpt&&o.trkpt.push(a)},extensions:(i,o)=>{let s=r.metadata.get("decoder");s&&(o.extensions=s.convertExtensions(i))}}),n}},Y=class extends u{constructor(){super(...arguments);this.name="link-converter";this.supportedTags=["link"]}convert(t,r){var i;let n={};return(i=t.attributes)!=null&&i.href&&(n.href=t.attributes.href),this.processChildren(t,n,{text:(o,s)=>s.text=this.parseString(o.value),type:(o,s)=>s.type=this.parseString(o.value)}),n}},Z=class extends u{constructor(){super(...arguments);this.name="metadata-converter";this.supportedTags=["metadata"]}convert(t,r){let n={};return this.processChildren(t,n,{name:(i,o)=>o.name=this.parseString(i.value),desc:(i,o)=>o.desc=this.parseString(i.value),keywords:(i,o)=>o.keywords=this.parseString(i.value),time:(i,o)=>o.time=new Date(this.parseString(i.value)),author:(i,o)=>{var a;let s=r.metadata.get("decoder");o.author=(a=s==null?void 0:s.getConverter("author"))==null?void 0:a.convert(i,r)},copyright:(i,o)=>{var a;let s=r.metadata.get("decoder");o.copyright=(a=s==null?void 0:s.getConverter("copyright"))==null?void 0:a.convert(i,r)},bounds:(i,o)=>{var a;let s=r.metadata.get("decoder");o.bounds=(a=s==null?void 0:s.getConverter("bounds"))==null?void 0:a.convert(i,r)},extensions:(i,o)=>{let s=r.metadata.get("decoder");s&&(o.extensions=s.convertExtensions(i))},link:(i,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(i,r);a&&o.link&&o.link.push(a)}}),n}},q=class extends u{constructor(){super(...arguments);this.name="person-converter";this.supportedTags=["author"]}convert(t,r){var i;let n={};return t.value&&!((i=t.children)!=null&&i.length)?(n.name=this.parseString(t.value),n):(this.processChildren(t,n,{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)}}),n)}},N=class extends u{constructor(){super(...arguments);this.name="email-converter";this.supportedTags=["email"]}convert(t,r){let n={};return this.processChildren(t,n,{id:(i,o)=>o.id=this.parseString(i.value),domain:(i,o)=>o.domain=this.parseString(i.value)}),n}},J=class extends u{constructor(){super(...arguments);this.name="copyright-converter";this.supportedTags=["copyright"]}convert(t,r){var i;let n={};return(i=t.attributes)!=null&&i.author&&(n.author=t.attributes.author),this.processChildren(t,n,{year:(o,s)=>s.year=this.parseString(o.value),license:(o,s)=>s.license=this.parseString(o.value)}),n}},Q=class extends u{constructor(){super(...arguments);this.name="bounds-converter";this.supportedTags=["bounds"]}convert(t,r){let n={};return this.extractAttributes(t,n,{minlat:"minlat",minlon:"minlon",maxlat:"maxlat",maxlon:"maxlon"}),n}};import{Parser as pt}from"htmlparser2";var ke=(n=>(n.TOKENIZE="tokenize",n.AST_GENERATE="ast_generate",n.CONVERT="convert",n.COMPLETE="complete",n))(ke||{}),ee=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=[],n=new pt({onopentag(i,o){r.push({type:"open",tag:i,attributes:o})},ontext(i){let o=i.replace(/\n/g,"").trim();o&&r.push({type:"text",tag:"text",value:o})},onclosetag(i){r.push({type:"close",tag:i})}},{xmlMode:!0});return n.write(e.xmlContent),n.end(),e.tokens=r,e.performance.tokenizeTime=Date.now()-t,e}},te=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=[],n,i=null;for(let s of e.tokens)if(s.type==="open"){let a={tag:s.tag,attributes:s.attributes||{},children:[]};n?i&&((o=i.children)==null||o.push(a)):n=a,r.push(a),i=a}else s.type==="text"&&i?i.value=s.value:s.type==="close"&&(r.pop(),i=r[r.length-1]||null);return e.ast=n,e.performance.astTime=Date.now()-t,e}},re=class{constructor(e){this.getConverter=e;this.stage="convert"}async process(e){var n;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(([i,o])=>{i.startsWith("xmlns:")?r[i]=o.replace(/'/g,"'"):i==="xsi:schemaLocation"?r[i]=o.replace(/'/g,"'"):r[i]=o}),(n=e.ast.children)==null||n.forEach(i=>{let o=this.getConverter(i.tag);try{let s=o.convert(i,e);s&&this.assignResult(r,i.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}}},ne=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 _=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 ee,new te,new re(e=>this.getConverter(e)),new ne]}async registerDefaultConverters(){var t;if(this.defaultConvertersRegistered)return;let e=[new U,new W,new j,new K,new Y,new Z,new q,new N,new J,new Q];for(let r of e)(t=r.supportedTags)==null||t.forEach(n=>{this.addConverterForTag(n,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((n,i)=>(n.priority||100)-(i.priority||100))}async registerConverter(e){var r,i;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})`:"";(i=e.supportedTags)==null||i.forEach(o=>{let a=(this.converterPlugins.get(o)||[]).map(c=>`${c.name}(${c.priority||100})`)})}async registerMiddleware(e){let t=this.middlewarePlugins.findIndex(n=>n.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,n]of this.converterPlugins){let i=n.findIndex(o=>o.name===e);i!==-1&&(t=n[i],n.splice(i,1),n.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(n=>({name:n.name,priority:n.priority||100})))}else for(let[r,n]of this.converterPlugins)t[r]=n.map(i=>({name:i.name,priority:i.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 n of t)try{await((r=n.initialize)==null?void 0:r.call(n,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 n of t)try{await((r=n.destroy)==null?void 0:r.call(n,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 i;let n=t;for(let o of this.middlewarePlugins){let s=o[e];if(s)try{n=await s.call(o,n,r)||n}catch(a){r.errors.push(a),await((i=o.onError)==null?void 0:i.call(o,a,r))}}return n}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 n of this.processors)try{switch(t=await n.process(t),n.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(i){t.errors.push(i);for(let o of this.middlewarePlugins)await((r=o.onError)==null?void 0:r.call(o,i,t))}return t.result}catch(n){throw n}}convertExtensions(e){var o,s;let t={},{attributes:r,tag:n,value:i}=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(i!==void 0)return i;return t}};import ze from"dayjs";import ct from"dayjs/plugin/utc.js";var Fe={temperature:"atemp",wtemp:"wtemp",heartRate:"hr",cadence:"cad"};var Ae={temperature:"Temperature",Depth:"Depth"};ze.extend(ct);var X=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),i=`${t}${r}
|
|
2
|
+
</gpx>`;return this.compact?this.compressXML(i):i}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:n=[],trk:i=[]}=e,o=[];return t&&o.push(this.buildMetadata(t)),r.forEach(s=>{o.push(this.buildWaypoint(s,"wpt"))}),n.forEach(s=>{o.push(this.buildRoute(s))}),i.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()),
|
|
8
|
-
`)}addStandardWaypointElements(e,t){var r,i,
|
|
7
|
+
`)}buildBounds(e){let t=this.escapeXMLAttribute((e.minlat||0).toString()),r=this.escapeXMLAttribute((e.minlon||0).toString()),n=this.escapeXMLAttribute((e.maxlat||0).toString()),i=this.escapeXMLAttribute((e.maxlon||0).toString());return`<bounds minlat="${t}" minlon="${r}" maxlat="${n}" maxlon="${i}"/>`}buildWaypoint(e,t){var n,i,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",(n=e.ele)==null?void 0:n.toString(),this.formatElevation),e.time&&r.push(this.buildTimeElement(e.time)),this.addOptionalElement(r,"speed",(i=e.speed)==null?void 0:i.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,n,i,o,s,a,c;this.addOptionalElement(e,"magvar",(r=t.magvar)==null?void 0:r.toString()),this.addOptionalElement(e,"geoidheight",(n=t.geoidheight)==null?void 0:n.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",(i=t.hdop)==null?void 0:i.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(n=>{t.push(this.buildWaypoint(n,"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),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,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}escapeXMLAttribute(e){return typeof e!="string"?String(e||""):e.replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">").replace(/\r/g," ").replace(/\n/g," ").replace(/\t/g,"	")}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(
|
|
13
|
-
`+r.repeat(
|
|
14
|
-
</TrainingCenterDatabase>`;return this.compact?this.compressXML(
|
|
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),n=this.buildTrackPointExtension(e,t);Object.keys(n).length>0&&(r["gpxtpx:TrackPointExtension"]=n);let i=this.buildPowerExtension(e,t);Object.keys(i).length>0&&(r["gpxpx:PowerExtension"]=i);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"]||{}),n=Object.keys(Fe);return Object.keys(e).filter(i=>n.includes(i)).forEach(i=>{let o=Fe[i];o&&e[i]!==void 0&&(r[`gpxtpx:${o}`]=e[i])}),r}buildPowerExtension(e,t){return this.deepClone(t["gpxpx:PowerExtension"]||{})}buildGpxExtensions(e,t){let r=this.deepClone(t["gpxx:GpxExtensions"]||{}),n=Object.keys(Ae);return Object.keys(e).filter(i=>n.includes(i)).forEach(i=>{let o=Ae[i];o&&e[i]!==void 0&&(r[`gpxx:${o}`]=e[i])}),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 n=this.buildExtensionContent(r);return`<${t}>${n}</${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(n=>{e.push(this.buildLink(n))})}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>${ze(e).utc().format("YYYY-MM-DDTHH:mm:ss[Z]")}</time>`}addOptionalElement(e,t,r,n){if(r!=null&&r!==""){let i=n?n(r):this.escapeXML(r);e.push(`<${t}>${i}</${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,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}escapeXMLAttribute(e){return typeof e!="string"?String(e||""):e.replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">").replace(/\r/g," ").replace(/\n/g," ").replace(/\t/g,"	")}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 De=class extends D{constructor(){super(...arguments);this.name="performance-middleware";this.description="Monitor parsing performance"}async onTokenize(t,r){return t}async onAstGenerate(t,r){let n=this.countNodes(t);return t}async onComplete(t,r){let n=r.metadata.get("performance");return t}countNodes(t){let r=1;if(t.children)for(let n of t.children)r+=this.countNodes(n);return r}},_e=class extends D{constructor(){super(...arguments);this.name="validation-middleware";this.description="Validate GPX data integrity"}async onComplete(t,r){let n=this.validateGPX(t);return n.length>0&&r.metadata.set("validation-errors",n),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 n of t.trk)if(n.trkseg){for(let i of n.trkseg)if(i.trkpt)for(let o of i.trkpt)(typeof o.lat!="number"||typeof o.lon!="number")&&r.push("Invalid track point coordinates")}}return r}};async function dt(p){let e=[new De,new _e];for(let t of e)await p.registerMiddleware(t)}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}},E=class extends C{async onError(e,t){t.warnings.push(`Middleware ${this.name} error: ${e.message}`)}};var ie=class extends m{constructor(){super(...arguments);this.name="PositionConverter";this.supportedTags=["Position"]}convert(t,r){let n={};return this.processChildren(t,n,{LatitudeDegrees:(i,o)=>o.LatitudeDegrees=this.parseString(i.value),LongitudeDegrees:(i,o)=>o.LongitudeDegrees=this.parseString(i.value)}),n}},oe=class extends m{constructor(){super(...arguments);this.name="TrackpointConverter";this.supportedTags=["Trackpoint"]}convert(t,r){let n={};return this.processChildren(t,n,{Time:(i,o)=>o.Time=this.parseString(i.value),Position:(i,o)=>{var a;let s=r.metadata.get("decoder");o.Position=(a=s==null?void 0:s.getConverter("Position"))==null?void 0:a.convert(i,r)},AltitudeMeters:(i,o)=>o.AltitudeMeters=this.parseFloat(i.value),DistanceMeters:(i,o)=>o.DistanceMeters=this.parseFloat(i.value),HeartRateBpm:(i,o)=>{if(i.value)o.HeartRateBpm=this.parseFloat(i.value);else{let s=this.getChildByTag(i,"Value");s!=null&&s.value&&(o.HeartRateBpm=this.parseFloat(s.value))}},Cadence:(i,o)=>{let s={Low:0,High:0};this.processChildren(i,s,{Low:(a,c)=>c.Low=this.parseFloat(a.value),High:(a,c)=>c.High=this.parseFloat(a.value)}),o.Cadence=s},SensorState:(i,o)=>o.SensorState=i.value,Extensions:(i,o)=>o.Extensions=this.convertExtensions(i)}),n}convertExtensions(t){var n;let r={};return(n=t.children)==null||n.forEach(i=>{r[i.tag]=this.convertExtensionContent(i)}),r}convertExtensionContent(t){var r;if((r=t.children)!=null&&r.length){let n={};return t.children.forEach(i=>{n[i.tag]=this.convertExtensionContent(i)}),n}else return t.value}},se=class extends m{constructor(){super(...arguments);this.name="TrackConverter";this.supportedTags=["Track"]}convert(t,r){let n={Trackpoint:[]};return this.processChildren(t,n,{Trackpoint:(i,o)=>{var c;let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("Trackpoint"))==null?void 0:c.convert(i,r);a&&o.Trackpoint&&o.Trackpoint.push(a)}}),n}},ae=class extends m{constructor(){super(...arguments);this.name="ActivityLapConverter";this.supportedTags=["Lap"]}convert(t,r){let n={};return this.extractAttributes(t,n,{StartTime:"Id"}),this.processChildren(t,n,{TotalTimeSeconds:(i,o)=>o.TotalTimeSeconds=this.parseFloat(i.value),DistanceMeters:(i,o)=>o.DistanceMeters=this.parseFloat(i.value),MaximumSpeed:(i,o)=>o.MaximumSpeed=this.parseFloat(i.value),Calories:(i,o)=>o.Calories=this.parseFloat(i.value),AverageHeartRateBpm:(i,o)=>o.AverageHeartRateBpm=this.parseFloat(i.value),MaximumHeartRateBpm:(i,o)=>o.MaximumHeartRateBpm=this.parseFloat(i.value),Intensity:(i,o)=>o.Intensity=i.value,TriggerMethod:(i,o)=>o.TriggerMethod=i.value,Track:(i,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(i,r);a&&o.Track.push(a)},Notes:(i,o)=>o.Notes=this.parseString(i.value),Extensions:(i,o)=>o.Extensions=this.convertExtensions(i)}),n}convertExtensions(t){var n;let r={};return(n=t.children)==null||n.forEach(i=>{r[i.tag]=this.convertExtensionContent(i)}),r}convertExtensionContent(t){var r;if((r=t.children)!=null&&r.length){let n={};return t.children.forEach(i=>{n[i.tag]=this.convertExtensionContent(i)}),n}else return t.value}},pe=class extends m{constructor(){super(...arguments);this.name="ActivityConverter";this.supportedTags=["Activity"]}convert(t,r){let n={Id:"",Lap:[]};return this.extractAttributes(t,n,{Sport:"Sport"}),this.processChildren(t,n,{Id:(i,o)=>o.Id=this.parseString(i.value),Lap:(i,o)=>{var c;let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("Lap"))==null?void 0:c.convert(i,r);a&&o.Lap.push(a)},Notes:(i,o)=>o.Notes=this.parseString(i.value),Training:(i,o)=>o.Training=this.convertTraining(i),Creator:(i,o)=>o.Creator=this.convertCreator(i),Extensions:(i,o)=>o.Extensions=this.convertExtensions(i)}),n}convertTraining(t){var n;let r={};return t.attributes&&Object.entries(t.attributes).forEach(([i,o])=>{r[i]=o}),(n=t.children)==null||n.forEach(i=>{r[i.tag]=this.convertExtensionContent(i)}),r}convertCreator(t){var n;let r={};return(n=t.children)==null||n.forEach(i=>{r[i.tag]=this.convertExtensionContent(i)}),r}convertExtensions(t){var n;let r={};return(n=t.children)==null||n.forEach(i=>{r[i.tag]=this.convertExtensionContent(i)}),r}convertExtensionContent(t){var r;if((r=t.children)!=null&&r.length){let n={};return t.children.forEach(i=>{n[i.tag]=this.convertExtensionContent(i)}),n}else return t.value}},ce=class extends m{constructor(){super(...arguments);this.name="ActivityListConverter";this.supportedTags=["Activities"]}convert(t,r){let n={Activity:[],MultiSportSession:[]};return this.processChildren(t,n,{Activity:(i,o)=>{var c;let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("Activity"))==null?void 0:c.convert(i,r);a&&o.Activity&&o.Activity.push(a)},MultiSportSession:(i,o)=>{var c;let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("MultiSportSession"))==null?void 0:c.convert(i,r);a&&o.MultiSportSession&&o.MultiSportSession.push(a)}}),n}},de=class extends m{constructor(){super(...arguments);this.name="MultiSportSessionConverter";this.supportedTags=["MultiSportSession"]}convert(t,r){let n={};return this.processChildren(t,n,{Id:(i,o)=>o.Id=this.parseString(i.value),FirstSport:(i,o)=>{var a;let s=r.metadata.get("decoder");o.FirstSport=(a=s==null?void 0:s.getConverter("FirstSport"))==null?void 0:a.convert(i,r)},NextSport:(i,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(i,r);a&&o.NextSport.push(a)},Notes:(i,o)=>o.Notes=this.parseString(i.value)}),n}},le=class extends m{constructor(){super(...arguments);this.name="AbstractSourceConverter";this.supportedTags=["Author","Creator"]}convert(t,r){let n={};return this.processChildren(t,n,{Name:(i,o)=>o.Name=this.parseString(i.value)}),n}};import{Parser as Ve}from"htmlparser2";var ue=class{static tokenizeXML(e){let t=[],r=new Ve({onopentag(n,i){t.push({type:"open",tag:n,attributes:i})},ontext(n){let i=n.replace(/\n/g,"").trim();i&&t.push({type:"text",tag:"text",value:i})},onclosetag(n){t.push({type:"close",tag:n})}},{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),n="",i=0,o=!1;for(let s=0;s<e.length;s++){let a=e[s],c=e[s+1];a==="<"?(c==="/"?(i--,o||(n+=`
|
|
12
|
+
`+r.repeat(i))):c!=="?"&&c!=="!"&&(o||(n+=`
|
|
13
|
+
`+r.repeat(i)),i++),o=!0):a===">"&&(o=!1,c==="<"&&e[s+2]==="/"&&i--),n+=a}return n.trim()}static validateXML(e){try{let t=new Ve({},{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],n={},i=r.match(/version=["']([^"']+)["']/);i&&(n.version=i[1]);let o=r.match(/encoding=["']([^"']+)["']/);o&&(n.encoding=o[1]);let s=r.match(/standalone=["']([^"']+)["']/);return s&&(n.standalone=s[1]),n}static escapeXML(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}static unescapeXML(e){return e.replace(/</g,"<").replace(/>/g,">").replace(/"/g,'"').replace(/'/g,"'").replace(/&/g,"&")}};var Ue=(n=>(n.TOKENIZE="tokenize",n.AST_GENERATE="ast-generate",n.CONVERT="convert",n.COMPLETE="complete",n))(Ue||{}),me=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=ue.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}},Te=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 n of e)if(n.type==="open"){let i={tag:n.tag,attributes:n.attributes,children:[]};r&&(r.children=r.children||[],r.children.push(i)),t.push(i),r=i,t.length||r||(r=i)}else n.type==="close"?(t.pop(),r=t[t.length-1]):n.type==="text"&&r&&n.value&&typeof n.value=="string"&&n.value.trim()&&(r.value=n.value.trim());return r}},fe=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(([n,i])=>{r[n]=i}),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(n=>{let i=this.convertAST(n,t);r[n.tag]?(Array.isArray(r[n.tag])||(r[n.tag]=[r[n.tag]]),r[n.tag].push(i)):r[n.tag]=i}),r}countElements(e){let t=1;if(e.children)for(let r of e.children)t+=this.countElements(r);return t}},ge=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 R=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 me,new Te,new fe(e=>this.getConverter(e)),new ge]}async registerDefaultConverters(){var t;if(this.defaultConvertersRegistered)return;let e=[new ie,new oe,new se,new ae,new pe,new ce,new de,new le];for(let r of e)(t=r.supportedTags)==null||t.forEach(n=>{this.addConverterForTag(n,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((n,i)=>(n.priority||100)-(i.priority||100))}async registerConverter(e){var r,i;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})`:"";(i=e.supportedTags)==null||i.forEach(o=>{let a=(this.converterPlugins.get(o)||[]).map(c=>`${c.name}(${c.priority||100})`)})}async registerMiddleware(e){let t=this.middlewarePlugins.findIndex(n=>n.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,n]of this.converterPlugins){let i=n.findIndex(o=>o.name===e);i!==-1&&(t=n[i],n.splice(i,1),n.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 n of t)try{await((r=n.initialize)==null?void 0:r.call(n,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 n of t)try{await((r=n.destroy)==null?void 0:r.call(n,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 i;let n=t;for(let o of this.middlewarePlugins){let s=o[e];if(s)try{n=await s.call(o,n,r)||n}catch(a){r.errors.push(a),await((i=o.onError)==null?void 0:i.call(o,a,r))}}return n}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 n of this.processors)try{switch(t=await n.process(t),n.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(i){t.errors.push(i);for(let o of this.middlewarePlugins)await((r=o.onError)==null?void 0:r.call(o,i,t))}return t.result}catch(n){throw n}}convertExtensions(e){var o,s;let t={},{attributes:r,tag:n,value:i}=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(i!==void 0)return i;return t}async parserByBuffer(e){return this.parseByBuffer(e)}async parseByString(e){let t=Buffer.from(e,"utf-8");return this.parseByBuffer(t)}};import We from"dayjs";import lt from"dayjs/plugin/utc.js";We.extend(lt);var M=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),i=`${t}${r}
|
|
14
|
+
</TrainingCenterDatabase>`;return this.compact?this.compressXML(i):i}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",n=e.xmlns||"http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2",i=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(n)}"`,` xmlns:xsi="${this.escapeXMLAttribute(i)}"`,` xsi:schemaLocation="${this.escapeXMLAttribute(o)}">`].join(`
|
|
15
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
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
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
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(
|
|
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(n=>{r.push(this.buildActivityLap(n))}),this.addOptionalElement(r,"Notes",e.Notes),e.Training,e.Creator,e.Extensions&&r.push(this.buildExtensions(e.Extensions)),r.push("</Activity>"),r.join(`
|
|
20
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
21
|
`)}buildTrack(e){let t=["<Track>"];return e.Trackpoint&&e.Trackpoint.forEach(r=>{t.push(this.buildTrackpoint(r))}),t.push("</Track>"),t.join(`
|
|
22
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
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
24
|
`)}buildFirstSport(e){let t=["<FirstSport>"];return e.Activity&&t.push(this.buildActivity(e.Activity)),t.push("</FirstSport>"),t.join(`
|
|
25
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: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,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}escapeXMLAttribute(e){return typeof e!="string"?String(e||""):e.replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">").replace(/\r/g," ").replace(/\n/g," ").replace(/\t/g,"	")}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};
|
|
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 n=this.buildExtensionContent(r);return`<${t}>${n}</${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:We(e).utc().format("YYYY-MM-DDTHH:mm:ss[Z]")}addOptionalElement(e,t,r,n){if(r!=null&&r!==""){let i=n?n(r):this.escapeXML(r);e.push(`<${t}>${i}</${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,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}escapeXMLAttribute(e){return typeof e!="string"?String(e||""):e.replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">").replace(/\r/g," ").replace(/\n/g," ").replace(/\t/g,"	")}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 Xe=class extends E{constructor(){super(...arguments);this.name="tcx-performance-middleware";this.description="Monitor TCX parsing performance"}async onTokenize(t,r){return t}async onAstGenerate(t,r){let n=this.countNodes(t);return t}async onComplete(t,r){let n=r.metadata.get("performance");return t}countNodes(t){let r=1;if(t.children)for(let n of t.children)r+=this.countNodes(n);return r}},Re=class extends E{constructor(){super(...arguments);this.name="tcx-validation-middleware";this.description="Validate TCX data integrity"}async onComplete(t,r){let n=this.validateTCX(t);return n.length>0&&r.metadata.set("validation-errors",n),t}validateTCX(t){let r=[];if(t.version||r.push("Missing TCX version information"),t.creator||r.push("Missing TCX creator information"),t.Activities&&t.Activities.Activity){for(let n of t.Activities.Activity)if(n.Id||r.push("Activity missing ID information"),(!n.Lap||n.Lap.length===0)&&r.push("Activity must contain at least one Lap"),n.Lap){for(let i of n.Lap)if(i.Track){for(let o of i.Track)if(o.Trackpoint)for(let s of o.Trackpoint)s.Position&&(!s.Position.LatitudeDegrees||!s.Position.LongitudeDegrees)&&r.push("Invalid trackpoint coordinates")}}}return r}},Me=class extends E{constructor(){super(...arguments);this.name="tcx-enhancement-middleware";this.description="Enhance TCX data with additional calculated fields"}async onComplete(t,r){if(t.Activities&&t.Activities.Activity)for(let n of t.Activities.Activity)n.totalDistance=this.calculateTotalDistance(n),n.totalDuration=this.calculateTotalDuration(n),n.totalDistance&&n.totalDuration&&(n.averageSpeed=n.totalDistance/n.totalDuration);return t}calculateTotalDistance(t){let r=0;if(t.Lap)for(let n of t.Lap)n.DistanceMeters&&(r+=n.DistanceMeters);return r}calculateTotalDuration(t){let r=0;if(t.Lap)for(let n of t.Lap)n.TotalTimeSeconds&&(r+=n.TotalTimeSeconds);return r}};async function Lr(p){let e=[new Xe,new Re,new Me];for(let t of e)await p.registerMiddleware(t)}var S=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 n=e[r-1],i=e[r],o=6371e3,s=n.lat*Math.PI/180,a=i.lat*Math.PI/180,c=(i.lat-n.lat)*Math.PI/180,d=(i.lon-n.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),T=2*Math.atan2(Math.sqrt(l),Math.sqrt(1-l));t+=o*T}return t}calculateDuration(e){var n,i;if(e.length<2)return;let t=(n=e[0])==null?void 0:n.time,r=(i=e[e.length-1])==null?void 0:i.time;if(!(!t||!r))return Math.round((r-t)/1e3)}},b=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 je={"gpxtpx:cad":"cadence","gpxtpx:hr":"heartRate","gpxtpx:temp":"temperature","gpxtpx:wtemp":"wtemp","gpxtpx:atemp":"atemp","gpxx:Temperature":"temperature","gpxx:Depth":"depth"},Le=p=>p*(180/Math.pow(2,31));import L from"dayjs";function Ke(p,e=0){let t=Math.pow(10,e);return Math.round(p*t)/t}var he=class extends S{constructor(){super(...arguments);this.name="gpx-to-sport-converter";this.supportedTags=["gpx"];this.convertGPXExtensions=t=>{let r={};return Object.entries(t).forEach(([n,i])=>{if(typeof i!="string"&&typeof i!="number")r={...r,...this.convertGPXExtensions(i)};else if(typeof i<"u"&&i!=="undefined"){let o=je[n]||n;r[o]=i}}),r}}convert(t,r){if(r.sourceFormat!=="gpx")return;let n=r.sourceData;return this.convertGPX(n)}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(n=>{var i;return{name:n.name,trackseg:((i=n.trkseg)==null?void 0:i.map(o=>({name:n.name,points:o.trkpt?this.convertWpts2Points(o.trkpt):[]})))||[]}})),t.rte&&(r.routes=t.rte.map(n=>({name:n.name,points:n.rtept?this.convertWpts2Points(n.rtept):[]}))),r}convertPoint(t){if(t.lat==null||t.lon==null||typeof t.lat!="number"||typeof t.lon!="number")return;let{extensions:r}=t,n=r?this.convertGPXExtensions(r):{};return{lat:t.lat,lon:t.lon,ele:t.ele,time:this.convertTime(t.time),...n}}convertWpts2Points(t){let r=[];for(let n=0;n<t.length;n++){let i=t[n];if(i.lat!=null&&i.lon!=null&&typeof i.lat=="number"&&typeof i.lon=="number"){let o=this.convertPoint(i);o&&r.push(o)}}return r}},ye=class extends S{constructor(){super(...arguments);this.name="fit-to-sport-converter";this.supportedTags=["fit"]}convert(t,r){if(r.sourceFormat!=="fit")return;let n=r.sourceData;return this.convertFIT(n)}convertFIT(t){var n,i;let r={metadata:{originType:"FIT",fileType:"fit"}};if((n=t.sessionMesgs)!=null&&n.length){r.tracks=[];for(let o of t.sessionMesgs)r.tracks.push({name:o.event,startTime:o.startTime?L(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((i=t.courseMesgs)!=null&&i.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:n,altitude:i,timestamp:o,heartRate:s,cadence:a,distance:c,power:d,enhancedAltitude:l,enhancedSpeed:T,temperature:f,...y}=t;if(!(r==null||n==null||typeof r!="number"||typeof n!="number"))return{lat:Ke(Le(Number(n)),6),lon:Ke(Le(Number(r)),6),ele:i,heart:s,power:d,cadence:a,temperature:f,time:o?L(o).valueOf():void 0,...y}}convertFITLap2Trackseg(t){var n;let r=[];if(!(t!=null&&t.length))return[];for(let i of t){let o=((n=i==null?void 0:i.recordMesgs)==null?void 0:n.map(s=>this.convertPoint(s)).filter(s=>s!==void 0))||[];r.push({points:o,duration:i.totalElapsedTime,distance:i.totalDistance,startTime:i.startTime?L(i.startTime).valueOf():void 0,endTime:i.startTime&&i.totalElapsedTime?L(i.startTime).add(i.totalElapsedTime,"second").valueOf():void 0,avgSpeed:i.avgSpeed,maxSpeed:i.maxSpeed,avgCadenceBpm:i.avgCadence,maxCadenceBpm:i.maxCadence,avgPower:i.avgPower,maxPower:i.maxPower,totalAscent:i.totalAscent,totalDescent:i.totalDescent,calories:i.totalCalories,__fit__lapMesgType:i})}return r}convertLap2Points(t){var n;let r=[];if(!(t!=null&&t.length))return[];for(let i of t){let o=((n=i.recordMesgs)==null?void 0:n.map(s=>this.convertPoint(s)).filter(s=>s!==void 0))||[];o.length&&(r=[...r,...o])}return r}},ve=class extends S{constructor(){super(...arguments);this.name="tcx-to-sport-converter";this.supportedTags=["tcx"]}convert(t,r){if(r.sourceFormat!=="tcx")return;let n=r.sourceData;return this.convertTCX(n)}convertTCX(t){var n,i,o,s;let r={metadata:{originType:"TCX",fileType:"tcx"}};if((i=(n=t.Activities)==null?void 0:n.Activity)!=null&&i.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:n,DistanceMeters:i,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:n?L(n).valueOf():void 0,distance:i,ele:o}}convertLap2Trackseg(t){var n,i,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(T=>this.convertPoint(T)).filter(T=>T!==void 0),l={duration:a.TotalTimeSeconds,distance:a.DistanceMeters,startTime:(n=d==null?void 0:d[0])==null?void 0:n.time,endTime:(i=d==null?void 0:d[d.length-1])==null?void 0:i.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 Ye(p){return Math.round(p*(Math.pow(2,31)/180))}var xe=class extends b{constructor(){super(...arguments);this.name="sport-to-gpx-encoder";this.supportedTags=["gpx"]}encode(t,r){var i,o,s,a;if(r.targetFormat!=="gpx")return;let n={version:"1.1",creator:((i=t.metadata)==null?void 0:i.creator)||"TrackSwap"};return(o=t.points)!=null&&o.length&&(n.wpt=this.convertPoints2Wpts(t.points)),(s=t.routes)!=null&&s.length&&(n.rte=t.routes.map(c=>this.convertRoute2GPXRoute(c))),(a=t.tracks)!=null&&a.length&&(n.trk=t.tracks.map(c=>this.convertTrack2GPXTrack(c))),n}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(n=>({trkpt:n.points?this.convertPoints2Wpts(n.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}},Ce=class extends b{constructor(){super(...arguments);this.name="sport-to-fit-encoder";this.supportedTags=["fit"]}encode(t,r){var i,o;if(r.targetFormat!=="fit")return;let n={};return(i=t.tracks)!=null&&i.length&&(n.sessionMesgs=t.tracks.map(s=>this.convertTrack2FITSession(s))),(o=t.routes)!=null&&o.length&&(n.courseMesgs=t.routes.map(s=>this.convertRoute2FITCourse(s))),n}convertTrack2FITSession(t){var n;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:((n=t.trackseg)==null?void 0:n.map(i=>this.convertSeg2FITLap(i)))||[]}}convertSeg2FITLap(t){var n;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:((n=t.points)==null?void 0:n.map(i=>this.convertPoint2FITRecord(i)))||[]}}convertPoint2FITRecord(t){return{timestamp:t.time?this.convertTimeToString(t.time):this.convertTimeToString(void 0),positionLat:Ye(t.lat),positionLong:Ye(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],n=t[t.length-1],i=r!=null&&r.time?this.convertTimeToString(r.time):this.convertTimeToString(void 0),o=r!=null&&r.time&&(n!=null&&n.time)?Math.round((n.time-r.time)/1e3):0,s=(n==null?void 0:n.distance)||0;return{startTime:i,totalElapsedTime:o,totalDistance:s,recordMesgs:t.map(a=>this.convertPoint2FITRecord(a))}}},Pe=class extends b{constructor(){super(...arguments);this.name="sport-to-tcx-encoder";this.supportedTags=["tcx"]}encode(t,r){var i,o,s;if(r.targetFormat!=="tcx")return;let n={Author:{Name:((i=t.metadata)==null?void 0:i.creator)||"TrackSwap"}};return(o=t.tracks)!=null&&o.length&&(n.Activities={Activity:t.tracks.map(a=>this.convertTrack2TCXActivity(a))}),(s=t.routes)!=null&&s.length&&(n.Courses={Course:t.routes.map(a=>this.convertRoute2TCXCourse(a))}),n}convertTrack2TCXActivity(t){var n;let r="Other";return(t.sport==="Running"||t.sport==="Biking")&&(r=t.sport),{Id:t.name||`Activity_${Date.now()}`,Sport:r,Lap:((n=t.trackseg)==null?void 0:n.map(i=>this.convertSeg2TCXLap(i)))||[]}}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 we=class{constructor(){this.converters=new Map;this.encoders=new Map;this.registerDefaultConverters(),this.registerDefaultEncoders()}registerDefaultConverters(){this.registerConverter(new he),this.registerConverter(new ye),this.registerConverter(new ve)}registerDefaultEncoders(){this.registerEncoder(new xe),this.registerEncoder(new Ce),this.registerEncoder(new Pe)}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 n=this.findConverter(t);if(!n)throw new Error(`No converter found for format "${t}"`);let i=Date.now(),o=n.convert({},r);if(r.performance.convertTime=Date.now()-i,!o)throw new Error(`Converter "${n.name}" returned empty result`);return r.result=o,r.performance.endTime=Date.now(),r.stats.endTime=Date.now(),o}catch(n){throw r.errors.push(n),n}}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 n=this.findEncoder(t);if(!n)throw new Error(`No encoder found for format "${t}"`);let i=Date.now(),o=n.encode(e,r);if(r.performance.encodeTime=Date.now()-i,!o)throw new Error(`Encoder "${n.name}" returned empty result`);return r.result=o,r.performance.endTime=Date.now(),r.stats.endTime=Date.now(),o}catch(n){throw r.errors.push(n),n}}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 _,this.gpxEncoder=new X,this.fitDecoder=new P,this.fitEncoder=new w,this.tcxDecoder=new R,this.tcxEncoder=new M,this.sportProcessor=new we}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 n=r||this.detectFormat(e);if(n==="unknown")throw new Error("Unable to recognize source file format, please specify sourceType parameter");if(n===t)return e;let i;switch(n){case"gpx":let s=await this.parseGPX(e);if(!s)throw new Error("GPX file parsing failed");i=s;break;case"fit":i=await this.parseFIT(e);break;case"tcx":i=await this.parseTCX(e);break;default:throw new Error(`Unsupported source file format: ${n}`)}let o;switch(n){case"gpx":o=await this.convertGPXToSport(i);break;case"fit":o=await this.convertFITToSport(i);break;case"tcx":o=await this.convertTCXToSport(i);break;default:throw new Error(`Unsupported source file format conversion: ${n}`)}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(n){let i=r||"auto-detect";throw new Error(`${i} to ${t.toUpperCase()} failed: ${n.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 n=await this.parseGPX(e);if(!n)throw new Error("GPX parsing failed");return n;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 n=await this.parseGPX(e);if(!n)throw new Error("GPX parsing failed");return this.convertGPXToSport(n);case"fit":let i=await this.parseFIT(e);return this.convertFITToSport(i);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 hn=O;export{le as AbstractSourceConverter,pe as ActivityConverter,ae as ActivityLapConverter,ce as ActivityListConverter,Te as AstGenerateProcessor,Ee as BaseFITMessageConverter,Se as BaseFITMiddleware,v as BaseFITStructurePlugin,m as BaseTCXConverter,E as BaseTCXMiddleware,ge as CompleteProcessor,fe as ConvertProcessor,F as CourseStructurePlugin,P as FITDecoder,w as FITEncoder,A as FileHeaderPlugin,_ as GPXDecoder,X as GPXEncoder,de as MultiSportSessionConverter,ke as PipelineStage,ie as PositionConverter,k as SessionStructurePlugin,R as TCXDecoder,M as TCXEncoder,Me as TCXEnhancementMiddleware,Xe as TCXPerformanceMiddleware,Ue as TCXPipelineStage,Re as TCXValidationMiddleware,me as TokenizeProcessor,se as TrackConverter,O as TrackSwap,oe as TrackpointConverter,hn as default,dt as registerDefaultMiddlewares,Lr as registerDefaultTCXMiddlewares};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "trackswap",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.6",
|
|
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
5
|
"main": "dist/index.cjs",
|
|
6
6
|
"module": "dist/index.js",
|