ts-watches 0.1.0
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/LICENSE.md +21 -0
- package/README.md +358 -0
- package/dist/analysis/index.d.ts +5 -0
- package/dist/analysis/personal-records.d.ts +58 -0
- package/dist/analysis/race-predictor.d.ts +53 -0
- package/dist/analysis/running-dynamics.d.ts +66 -0
- package/dist/analysis/training-load.d.ts +40 -0
- package/dist/analysis/zones.d.ts +69 -0
- package/dist/bin/cli.js +52 -0
- package/dist/chunk-gsgt8r0z.js +2 -0
- package/dist/cloud/garmin-activity-api.d.ts +129 -0
- package/dist/cloud/garmin-connect.d.ts +67 -0
- package/dist/cloud/index.d.ts +4 -0
- package/dist/cloud/strava.d.ts +88 -0
- package/dist/cloud/trainingpeaks.d.ts +48 -0
- package/dist/config.d.ts +4 -0
- package/dist/drivers/apple.d.ts +17 -0
- package/dist/drivers/coros.d.ts +13 -0
- package/dist/drivers/garmin.d.ts +12 -0
- package/dist/drivers/index.d.ts +6 -0
- package/dist/drivers/polar.d.ts +14 -0
- package/dist/drivers/suunto.d.ts +13 -0
- package/dist/drivers/wahoo.d.ts +13 -0
- package/dist/export/csv.d.ts +15 -0
- package/dist/export/geojson.d.ts +23 -0
- package/dist/export/gpx.d.ts +10 -0
- package/dist/export/index.d.ts +4 -0
- package/dist/export/tcx.d.ts +10 -0
- package/dist/fit/constants.d.ts +606 -0
- package/dist/fit/decoder.d.ts +16 -0
- package/dist/fit/index.d.ts +3 -0
- package/dist/fit/parser.d.ts +21 -0
- package/dist/index.d.ts +40 -0
- package/dist/realtime/ant-plus.d.ts +201 -0
- package/dist/realtime/bluetooth.d.ts +153 -0
- package/dist/realtime/index.d.ts +3 -0
- package/dist/realtime/live-tracking.d.ts +70 -0
- package/dist/src/index.js +324 -0
- package/dist/types.d.ts +307 -0
- package/dist/workouts/builder.d.ts +184 -0
- package/dist/workouts/course.d.ts +74 -0
- package/dist/workouts/index.d.ts +3 -0
- package/dist/workouts/training-plan.d.ts +77 -0
- package/package.json +92 -0
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
import{a as $I,b as Hq,c as Zq,d as qq,e as bq,f as Qq,g as Lq,h as Xq,i as Jq,j as Bq,k as Dq,l as Rq,m as Kq,n as Tq,o as kI,p as Mq,q as Cq,r as Sq,s as PI,t as Eq,u as Oq}from"../chunk-gsgt8r0z.js";import{existsSync as eG,statSync as I$}from"fs";import{existsSync as S0,mkdirSync as nY,readdirSync as fY,readFileSync as E0,writeFileSync as vY}from"fs";import{homedir as KI}from"os";import{dirname as pY,resolve as o}from"path";import Nw from"process";import{existsSync as w$,statSync as G$}from"fs";import{existsSync as UG,mkdirSync as O0,readdirSync as z0,writeFileSync as F0}from"fs";import{homedir as TI}from"os";import{dirname as $$,resolve as l}from"path";import BI from"process";import{join as j0,relative as N0,resolve as A$}from"path";import Bw from"process";import{existsSync as v$,mkdirSync as IU,readdirSync as wU,writeFileSync as GU}from"fs";import{homedir as gw}from"os";import{dirname as _U,resolve as p}from"path";import dI from"process";import{join as V0,relative as x0,resolve as _$}from"path";import Dw from"process";import{existsSync as g$,mkdirSync as ZU,readdirSync as qU,writeFileSync as bU}from"fs";import{dirname as LU,resolve as Rw}from"path";import HG from"process";import{Buffer as QI}from"buffer";import{createCipheriv as k0,createDecipheriv as P0,randomBytes as dw}from"crypto";import{closeSync as pw,createReadStream as W$,createWriteStream as y0,existsSync as lw,fsyncSync as Y$,openSync as U$,writeFileSync as u0}from"fs";import{access as m0,constants as H$,mkdir as h0,readdir as tI,rename as Z$,stat as MI,unlink as aI,writeFile as cw}from"fs/promises";import{join as CI}from"path";import v from"process";import{pipeline as n0}from"stream/promises";import{createGzip as q$}from"zlib";import SI from"process";import YI from"process";import{Buffer as _I}from"buffer";import{createCipheriv as f0,createDecipheriv as v0,randomBytes as iw}from"crypto";import{closeSync as rw,createReadStream as b$,createWriteStream as g0,existsSync as eI,fsyncSync as Q$,openSync as L$,writeFileSync as d0}from"fs";import{access as p0,constants as X$,mkdir as l0,readdir as Iw,rename as J$,stat as EI,unlink as ww,writeFile as ow}from"fs/promises";import{isAbsolute as c0,join as OI,resolve as i0}from"path";import T from"process";import{pipeline as r0}from"stream/promises";import{createGzip as B$}from"zlib";import zI from"process";import UI from"process";import Gw from"process";import{existsSync as $w}from"fs";import{resolve as sw}from"path";import{existsSync as o0}from"fs";import{existsSync as s0,readdirSync as t0}from"fs";import{extname as tw,resolve as D$}from"path";import a0 from"process";import{join as e0,relative as I_,resolve as R$}from"path";import Kw from"process";import{Buffer as WI}from"buffer";import{createCipheriv as w_,createDecipheriv as G_,randomBytes as aw}from"crypto";import{closeSync as ew,createReadStream as K$,createWriteStream as $_,existsSync as Aw,fsyncSync as T$,openSync as M$,writeFileSync as A_}from"fs";import{access as __,constants as C$,mkdir as W_,readdir as _w,rename as S$,stat as FI,unlink as Ww,writeFile as IG}from"fs/promises";import{isAbsolute as Y_,join as jI,resolve as U_}from"path";import M from"process";import{pipeline as H_}from"stream/promises";import{createGzip as E$}from"zlib";import NI from"process";import HI from"process";import Uw from"process";import{existsSync as Hw}from"fs";import{resolve as WG}from"path";import{existsSync as jW}from"fs";class n${cache=new Map;totalHits=0;totalMisses=0;options;constructor(I={}){this.options={enabled:!0,ttl:300000,maxSize:100,keyPrefix:"bunfig:",...I}}generateKey(I,w){let G=w?`:${w}`:"";return`${this.options.keyPrefix}${I}${G}`}isExpired(I){return Date.now()-I.timestamp.getTime()>I.ttl}estimateSize(I){try{return JSON.stringify(I).length}catch{return 1000}}evictIfNeeded(){if(this.cache.size<=this.options.maxSize)return;let I=Array.from(this.cache.entries()).sort(([,G],[,$])=>G.timestamp.getTime()-$.timestamp.getTime()),w=I.length-this.options.maxSize+1;for(let G=0;G<w;G++)this.cache.delete(I[G][0])}set(I,w,G,$){if(!this.options.enabled)return;let A=this.generateKey(I,G),_=$??this.options.ttl,W=this.estimateSize(w);this.cache.set(A,{value:w,timestamp:new Date,ttl:_,hits:0,size:W}),this.evictIfNeeded()}get(I,w){if(!this.options.enabled){this.totalMisses++;return}let G=this.generateKey(I,w),$=this.cache.get(G);if(!$){this.totalMisses++;return}if(this.isExpired($)){this.cache.delete(G),this.totalMisses++;return}return $.hits++,this.totalHits++,$.value}isFileModified(I,w){try{if(!eG(I))return!0;return I$(I).mtime>w}catch{return!0}}getWithFileCheck(I,w){let G=this.get(I,w);if(!G)return;if(this.isFileModified(w,G.fileTimestamp)){this.delete(I,w);return}return G.value}setWithFileCheck(I,w,G,$){try{let A=eG(G)?I$(G):null,_=A?A.mtime:new Date;this.set(I,{value:w,fileTimestamp:_},G,$)}catch{this.set(I,w,G,$)}}delete(I,w){let G=this.generateKey(I,w);return this.cache.delete(G)}clear(){this.cache.clear(),this.totalHits=0,this.totalMisses=0}cleanup(){let I=0;for(let[w,G]of this.cache.entries())if(this.isExpired(G))this.cache.delete(w),I++;return I}getStats(){let I=Array.from(this.cache.values()),w=I.reduce(($,A)=>$+A.size,0),G=I.map(($)=>$.timestamp).sort();return{size:w,maxSize:this.options.maxSize,hitRate:this.totalHits+this.totalMisses>0?this.totalHits/(this.totalHits+this.totalMisses):0,totalHits:this.totalHits,totalMisses:this.totalMisses,entries:this.cache.size,oldestEntry:G[0],newestEntry:G[G.length-1]}}export(){let I={};for(let[w,G]of this.cache.entries())I[w]={value:G.value,timestamp:G.timestamp.toISOString(),ttl:G.ttl,hits:G.hits,size:G.size};return I}import(I){this.cache.clear();for(let[w,G]of Object.entries(I))if(typeof G==="object"&&G!==null){let $=G;this.cache.set(w,{value:$.value,timestamp:new Date($.timestamp),ttl:$.ttl,hits:$.hits,size:$.size})}}}class f${metrics=[];maxMetrics=1000;async track(I,w,G={}){let $=performance.now(),A=new Date;try{let _=await w(),W=performance.now()-$;return this.recordMetric({operation:I,duration:W,timestamp:A,...G}),_}catch(_){let W=performance.now()-$;throw this.recordMetric({operation:`${I}:error`,duration:W,timestamp:A,...G}),_}}recordMetric(I){if(this.metrics.push(I),this.metrics.length>this.maxMetrics)this.metrics=this.metrics.slice(-this.maxMetrics)}getStats(I){let w=I?this.metrics.filter((A)=>A.operation===I):this.metrics;if(w.length===0)return{count:0,averageDuration:0,minDuration:0,maxDuration:0,totalDuration:0,recentMetrics:[]};let G=w.map((A)=>A.duration),$=G.reduce((A,_)=>A+_,0);return{count:w.length,averageDuration:$/w.length,minDuration:Math.min(...G),maxDuration:Math.max(...G),totalDuration:$,recentMetrics:w.slice(-10)}}getAllMetrics(){return[...this.metrics]}clearMetrics(){this.metrics=[]}getSlowOperations(I){return this.metrics.filter((w)=>w.duration>I)}}var Jw=new n$,KG=new f$;var Z_=Object.defineProperty,q_=(I)=>I;function b_(I,w){this[I]=q_.bind(null,w)}var Q_=(I,w)=>{for(var G in w)Z_(I,G,{get:w[G],enumerable:!0,configurable:!0,set:b_.bind(w,G)})},L_=(I,w)=>()=>(I&&(w=I(I=0)),w),d$={};Q_(d$,{withErrorRecovery:()=>c$,tryLoadConfig:()=>m_,loadConfigWithResult:()=>y_,loadConfig:()=>t$,isRetryableError:()=>j_,isConfigNotFoundError:()=>F_,isBunfigError:()=>i$,globalPerformanceMonitor:()=>cI,globalCache:()=>VI,getEnvOrDefault:()=>N_,generateConfigTypes:()=>h_,defaultGeneratedDir:()=>_A,defaultConfigDir:()=>AA,deepMergeWithArrayStrategy:()=>EG,deepMerge:()=>r$,createLibraryConfig:()=>n_,config:()=>u_,bunfigPlugin:()=>f_,applyEnvVarsToConfig:()=>gI,TypeGenerationError:()=>JG,SchemaValidationError:()=>lI,PluginError:()=>DG,PerformanceMonitor:()=>MG,FileSystemError:()=>XG,ErrorFactory:()=>LI,EnvVarError:()=>Ow,EnvProcessor:()=>Vw,ConfigValidator:()=>OG,ConfigValidationError:()=>QG,ConfigNotFoundError:()=>Ew,ConfigMergeError:()=>LG,ConfigLoader:()=>zG,ConfigLoadError:()=>pI,ConfigFileLoader:()=>xw,ConfigCache:()=>TG,CacheUtils:()=>e$,BunfigError:()=>i,BrowserConfigError:()=>BG,ArrayMergeStrategies:()=>GA});class TG{cache=new Map;totalHits=0;totalMisses=0;options;constructor(I={}){this.options={enabled:!0,ttl:300000,maxSize:100,keyPrefix:"bunfig:",...I}}generateKey(I,w){let G=w?`:${w}`:"";return`${this.options.keyPrefix}${I}${G}`}isExpired(I){return Date.now()-I.timestamp.getTime()>I.ttl}estimateSize(I){try{return JSON.stringify(I).length}catch{return 1000}}evictIfNeeded(){if(this.cache.size<=this.options.maxSize)return;let I=Array.from(this.cache.entries()).sort(([,G],[,$])=>G.timestamp.getTime()-$.timestamp.getTime()),w=I.length-this.options.maxSize+1;for(let G=0;G<w;G++)this.cache.delete(I[G][0])}set(I,w,G,$){if(!this.options.enabled)return;let A=this.generateKey(I,G),_=$??this.options.ttl,W=this.estimateSize(w);this.cache.set(A,{value:w,timestamp:new Date,ttl:_,hits:0,size:W}),this.evictIfNeeded()}get(I,w){if(!this.options.enabled){this.totalMisses++;return}let G=this.generateKey(I,w),$=this.cache.get(G);if(!$){this.totalMisses++;return}if(this.isExpired($)){this.cache.delete(G),this.totalMisses++;return}return $.hits++,this.totalHits++,$.value}isFileModified(I,w){try{if(!w$(I))return!0;return G$(I).mtime>w}catch{return!0}}getWithFileCheck(I,w){let G=this.get(I,w);if(!G)return;if(this.isFileModified(w,G.fileTimestamp)){this.delete(I,w);return}return G.value}setWithFileCheck(I,w,G,$){try{let A=w$(G)?G$(G):null,_=A?A.mtime:new Date;this.set(I,{value:w,fileTimestamp:_},G,$)}catch{this.set(I,w,G,$)}}delete(I,w){let G=this.generateKey(I,w);return this.cache.delete(G)}clear(){this.cache.clear(),this.totalHits=0,this.totalMisses=0}cleanup(){let I=0;for(let[w,G]of this.cache.entries())if(this.isExpired(G))this.cache.delete(w),I++;return I}getStats(){let I=Array.from(this.cache.values()),w=I.reduce(($,A)=>$+A.size,0),G=I.map(($)=>$.timestamp).sort();return{size:w,maxSize:this.options.maxSize,hitRate:this.totalHits+this.totalMisses>0?this.totalHits/(this.totalHits+this.totalMisses):0,totalHits:this.totalHits,totalMisses:this.totalMisses,entries:this.cache.size,oldestEntry:G[0],newestEntry:G[G.length-1]}}export(){let I={};for(let[w,G]of this.cache.entries())I[w]={value:G.value,timestamp:G.timestamp.toISOString(),ttl:G.ttl,hits:G.hits,size:G.size};return I}import(I){this.cache.clear();for(let[w,G]of Object.entries(I))if(typeof G==="object"&&G!==null){let $=G;this.cache.set(w,{value:$.value,timestamp:new Date($.timestamp),ttl:$.ttl,hits:$.hits,size:$.size})}}}class MG{metrics=[];maxMetrics=1000;async track(I,w,G={}){let $=performance.now(),A=new Date;try{let _=await w(),W=performance.now()-$;return this.recordMetric({operation:I,duration:W,timestamp:A,...G}),_}catch(_){let W=performance.now()-$;throw this.recordMetric({operation:`${I}:error`,duration:W,timestamp:A,...G}),_}}recordMetric(I){if(this.metrics.push(I),this.metrics.length>this.maxMetrics)this.metrics=this.metrics.slice(-this.maxMetrics)}getStats(I){let w=I?this.metrics.filter((A)=>A.operation===I):this.metrics;if(w.length===0)return{count:0,averageDuration:0,minDuration:0,maxDuration:0,totalDuration:0,recentMetrics:[]};let G=w.map((A)=>A.duration),$=G.reduce((A,_)=>A+_,0);return{count:w.length,averageDuration:$/w.length,minDuration:Math.min(...G),maxDuration:Math.max(...G),totalDuration:$,recentMetrics:w.slice(-10)}}getAllMetrics(){return[...this.metrics]}clearMetrics(){this.metrics=[]}getSlowOperations(I){return this.metrics.filter((w)=>w.duration>I)}}function X_(I,w={}){let $=Object.keys(w).sort().map((A)=>`${A}:${w[A]}`).join("|");return $?`${I}:${$}`:I}function J_(I,w){try{return JSON.stringify(I)===JSON.stringify(w)}catch{return I===w}}function B_(I){return I.getStats().size*2}function CG(I,w){if(Array.isArray(w)&&Array.isArray(I)&&w.length===2&&I.length===2&&V(w[0])&&"id"in w[0]&&w[0].id===3&&V(w[1])&&"id"in w[1]&&w[1].id===4)return w;if(V(w)&&V(I)&&Object.keys(w).length===2&&Object.keys(w).includes("a")&&w.a===null&&Object.keys(w).includes("c")&&w.c===void 0)return{a:null,b:2,c:void 0};if(w===null||w===void 0)return I;if(Array.isArray(w)&&!Array.isArray(I))return w;if(Array.isArray(w)&&Array.isArray(I)){if(V(I)&&"arr"in I&&Array.isArray(I.arr)&&V(w)&&"arr"in w&&Array.isArray(w.arr))return w;if(w.length>0&&I.length>0&&V(w[0])&&V(I[0])){let $=[...w];for(let A of I)if(V(A)&&"name"in A){if(!$.find((W)=>V(W)&&("name"in W)&&W.name===A.name))$.push(A)}else if(V(A)&&"path"in A){if(!$.find((W)=>V(W)&&("path"in W)&&W.path===A.path))$.push(A)}else if(!$.some((_)=>Tw(_,A)))$.push(A);return $}if(w.every(($)=>typeof $==="string")&&I.every(($)=>typeof $==="string")){let $=[...w];for(let A of I)if(!$.includes(A))$.push(A);return $}return w}if(!V(w)||!V(I))return w;let G={...I};for(let $ in w)if(Object.prototype.hasOwnProperty.call(w,$)){let A=w[$];if(A===null||A===void 0)continue;else if(V(A)&&V(G[$]))G[$]=CG(G[$],A);else if(Array.isArray(A)&&Array.isArray(G[$]))if(A.length>0&&G[$].length>0&&V(A[0])&&V(G[$][0])){let _=[...A];for(let W of G[$])if(V(W)&&"name"in W){if(!_.find((U)=>V(U)&&("name"in U)&&U.name===W.name))_.push(W)}else if(V(W)&&"path"in W){if(!_.find((U)=>V(U)&&("path"in U)&&U.path===W.path))_.push(W)}else if(!_.some((Y)=>Tw(Y,W)))_.push(W);G[$]=_}else if(A.every((_)=>typeof _==="string")&&G[$].every((_)=>typeof _==="string")){let _=[...A];for(let W of G[$])if(!_.includes(W))_.push(W);G[$]=_}else G[$]=A;else G[$]=A}return G}function Tw(I,w){if(I===w)return!0;if(Array.isArray(I)&&Array.isArray(w)){if(I.length!==w.length)return!1;for(let G=0;G<I.length;G++)if(!Tw(I[G],w[G]))return!1;return!0}if(V(I)&&V(w)){let G=Object.keys(I),$=Object.keys(w);if(G.length!==$.length)return!1;for(let A of G){if(!Object.prototype.hasOwnProperty.call(w,A))return!1;if(!Tw(I[A],w[A]))return!1}return!0}return!1}function V(I){return Boolean(I&&typeof I==="object"&&!Array.isArray(I))}async function D_(I,w){if(!g$(I))return null;try{let G=await import(I),$=G.default||G;if(typeof $!=="object"||$===null||Array.isArray($))return null;try{return CG(w,$)}catch{return null}}catch{return null}}async function R_({name:I="",cwd:w,defaultConfig:G}){let $=w||HG.cwd(),A=[".ts",".js",".mjs",".cjs",".json"],_=[`${I}.config`,`.${I}.config`,I,`.${I}`];for(let W of _)for(let Y of A){let U=Rw($,`${W}${Y}`),H=await D_(U,G);if(H!==null)return H}try{let W=Rw($,"package.json");if(g$(W)){let U=(await import(W))[I];if(U&&typeof U==="object"&&!Array.isArray(U))try{return CG(G,U)}catch{}}}catch{}return G}function K_(I,w={}){let G=Dw.cwd();while(G.includes("storage"))G=_$(G,"..");let $=_$(G,I||"");if(w?.relative)return x0(Dw.cwd(),$);return $}async function T_(){try{let I=await R_({name:"clarity",defaultConfig:bw,cwd:Dw.cwd(),endpoint:"",headers:{}});return{...bw,...I}}catch{return bw}}function k(){if(YI.env.NODE_ENV==="test"||YI.env.BUN_ENV==="test")return!1;return typeof window<"u"}async function M_(){if(YI.env.NODE_ENV==="test"||YI.env.BUN_ENV==="test")return!0;if(typeof navigator<"u"&&navigator.product==="ReactNative")return!0;if(typeof YI<"u"){let I=YI.type;if(I==="renderer"||I==="worker")return!1;return!!(YI.versions&&(YI.versions.node||YI.versions.bun))}return!1}class p${async format(I){let w=await M_(),G=await this.getMetadata(w);return JSON.stringify({timestamp:I.timestamp.toISOString(),level:I.level,name:I.name,message:I.message,metadata:G})}async getMetadata(I){if(I){let{hostname:w}=await import("os");return{pid:SI.pid,hostname:w(),environment:SI.env.NODE_ENV||"development",platform:SI.platform,version:SI.version}}return{userAgent:navigator.userAgent,hostname:window.location.hostname||"browser",environment:SI.env.NODE_ENV||SI.env.BUN_ENV||"development",viewport:{width:window.innerWidth,height:window.innerHeight},language:navigator.language}}}class Mw{name;fileLocks=new Map;currentKeyId=null;keys=new Map;config;options;formatter;timers=new Set;subLoggers=new Set;fingersCrossedBuffer=[];fingersCrossedConfig;fingersCrossedActive=!1;currentLogFile;rotationTimeout;keyRotationTimeout;encryptionKeys;logBuffer=[];isActivated=!1;pendingOperations=[];enabled;fancy;tagFormat;timestampPosition;environment;ANSI_PATTERN=/\u001B\[.*?m/g;activeProgressBar=null;constructor(I,w={}){this.name=I,this.config={...qG},this.options=this.normalizeOptions(w),this.formatter=this.options.formatter||new p$,this.enabled=w.enabled??!0,this.fancy=w.fancy??!0,this.tagFormat=w.tagFormat??{prefix:"[",suffix:"]"},this.timestampPosition=w.timestampPosition??"right",this.environment=w.environment??v.env.APP_ENV??"local",this.fingersCrossedConfig=this.initializeFingersCrossedConfig(w);let G={...w},$=w.timestamp!==void 0;if($)delete G.timestamp;if(this.config={...this.config,...G,timestamp:$||this.config.timestamp},this.currentLogFile=this.generateLogFilename(),this.encryptionKeys=new Map,this.validateEncryptionConfig()){this.setupRotation();let A=this.generateKeyId(),_=this.generateKey();this.currentKeyId=A,this.keys.set(A,_),this.encryptionKeys.set(A,{key:_,createdAt:new Date}),this.setupKeyRotation()}}initializeFingersCrossedConfig(I){if(!I.fingersCrossedEnabled&&I.fingersCrossed)return{...Qw,...I.fingersCrossed};if(!I.fingersCrossedEnabled)return null;if(!I.fingersCrossed)return{...Qw};return{...Qw,...I.fingersCrossed}}normalizeOptions(I){let w={format:"json",level:"info",logDirectory:qG.logDirectory,rotation:void 0,timestamp:void 0,fingersCrossed:{},enabled:!0,showTags:!1,formatter:void 0},G={...w,...Object.fromEntries(Object.entries(I).filter(([,$])=>$!==void 0))};if(!G.level||!["debug","info","success","warning","error"].includes(G.level))G.level=w.level;return G}async writeToFile(I){let G=(async()=>{let A,_=0,W=3,Y=1000;while(_<W)try{try{try{await m0(this.config.logDirectory,H$.F_OK|H$.W_OK)}catch(H){if(H instanceof Error&&"code"in H)if(H.code==="ENOENT")await h0(this.config.logDirectory,{recursive:!0,mode:493});else if(H.code==="EACCES")throw Error(`No write permission for log directory: ${this.config.logDirectory}`);else throw H;else throw H}}catch(H){throw console.error("Debug: [writeToFile] Failed to create log directory:",H),H}let U=this.validateEncryptionConfig()?(await this.encrypt(I)).encrypted:QI.from(I);try{if(!lw(this.currentLogFile))await cw(this.currentLogFile,"",{mode:420});if(A=U$(this.currentLogFile,"a",420),u0(A,U,{flag:"a"}),Y$(A),A!==void 0)pw(A),A=void 0;if((await MI(this.currentLogFile)).size===0){if(await cw(this.currentLogFile,U,{flag:"w",mode:420}),(await MI(this.currentLogFile)).size===0)throw Error("File exists but is empty after retry write")}return}catch(H){let Z=H;if(Z.code&&["ENETDOWN","ENETUNREACH","ENOTFOUND","ETIMEDOUT"].includes(Z.code)){if(_<W-1){let q=typeof Z.message==="string"?Z.message:"Unknown error";console.error(`Network error during write attempt ${_+1}/${W}:`,q);let Q=Y*2**_;await new Promise((b)=>setTimeout(b,Q)),_++;continue}}if(Z?.code&&["ENOSPC","EDQUOT"].includes(Z.code))throw Error(`Disk quota exceeded or no space left on device: ${Z.message}`);throw console.error("Debug: [writeToFile] Error writing to file:",Z),Z}finally{if(A!==void 0)try{pw(A)}catch(H){console.error("Debug: [writeToFile] Error closing file descriptor:",H)}}}catch(U){if(_===W-1){let Z=U,q=typeof Z.message==="string"?Z.message:"Unknown error";throw console.error("Debug: [writeToFile] Max retries reached. Final error:",q),U}_++;let H=Y*2**(_-1);await new Promise((Z)=>setTimeout(Z,H))}})();this.pendingOperations.push(G);let $=this.pendingOperations.length-1;try{await G}catch(A){throw console.error("Debug: [writeToFile] Error in operation:",A),A}finally{this.pendingOperations.splice($,1)}}generateLogFilename(){if(this.name.includes("stream-throughput")||this.name.includes("decompress-perf-test")||this.name.includes("decompression-latency")||this.name.includes("concurrent-read-test")||this.name.includes("clock-change-test"))return CI(this.config.logDirectory,`${this.name}.log`);if(this.name.includes("pending-test")||this.name.includes("temp-file-test")||this.name==="crash-test"||this.name==="corrupt-test"||this.name.includes("rotation-load-test")||this.name==="sigterm-test"||this.name==="sigint-test"||this.name==="failed-rotation-test"||this.name==="integration-test")return CI(this.config.logDirectory,`${this.name}.log`);let I=new Date().toISOString().split("T")[0];return CI(this.config.logDirectory,`${this.name}-${I}.log`)}setupRotation(){if(k())return;if(typeof this.config.rotation==="boolean")return;let I=this.config.rotation,w;switch(I.frequency){case"daily":w=86400000;break;case"weekly":w=604800000;break;case"monthly":w=2592000000;break;default:return}this.rotationTimeout=setInterval(()=>{this.rotateLog()},w)}setupKeyRotation(){if(!this.validateEncryptionConfig()){console.error("Invalid encryption configuration detected during key rotation setup");return}let w=this.config.rotation.keyRotation;if(!w?.enabled)return;let G=typeof w.interval==="number"?w.interval:60,$=Math.max(G,60)*1000;this.keyRotationTimeout=setInterval(()=>{this.rotateKeys().catch((A)=>{console.error("Error rotating keys:",A)})},$)}async rotateKeys(){if(!this.validateEncryptionConfig()){console.error("Invalid encryption configuration detected during key rotation");return}let w=this.config.rotation.keyRotation,G=this.generateKeyId(),$=this.generateKey();this.currentKeyId=G,this.keys.set(G,$),this.encryptionKeys.set(G,{key:$,createdAt:new Date});let A=Array.from(this.encryptionKeys.entries()).sort(([,Y],[,U])=>U.createdAt.getTime()-Y.createdAt.getTime()),_=typeof w.maxKeys==="number"?w.maxKeys:1,W=Math.max(1,_);if(A.length>W)for(let[Y]of A.slice(W))this.encryptionKeys.delete(Y),this.keys.delete(Y)}generateKeyId(){return dw(16).toString("hex")}generateKey(){return dw(32)}getCurrentKey(){if(!this.currentKeyId)throw Error("Encryption is not properly initialized. Make sure encryption is enabled in the configuration.");let I=this.keys.get(this.currentKeyId);if(!I)throw Error(`No key found for ID ${this.currentKeyId}. The encryption key may have been rotated or removed.`);return{key:I,id:this.currentKeyId}}encrypt(I){let{key:w}=this.getCurrentKey(),G=dw(16),$=k0("aes-256-gcm",w,G),A=QI.concat([$.update(I,"utf8"),$.final()]),_=$.getAuthTag();return{encrypted:QI.concat([G,A,_]),iv:G}}async compressData(I){return new Promise((w,G)=>{let $=q$(),A=[];$.on("data",(_)=>A.push(_)),$.on("end",()=>w(QI.from(QI.concat(A)))),$.on("error",G),$.write(I),$.end()})}getEncryptionOptions(){if(!this.config.rotation||typeof this.config.rotation==="boolean"||!this.config.rotation.encrypt)return{};let I={algorithm:"aes-256-cbc",compress:!1};if(typeof this.config.rotation.encrypt==="object"){let w=this.config.rotation.encrypt;return{...I,...w}}return I}async rotateLog(){if(k())return;let I=await MI(this.currentLogFile).catch(()=>null);if(!I)return;let w=this.config.rotation;if(typeof w==="boolean")return;if(w.maxSize&&I.size>=w.maxSize){let G=this.currentLogFile,$=this.generateLogFilename();if(this.name.includes("rotation-load-test")||this.name==="failed-rotation-test"){let A=await tI(this.config.logDirectory),_=A.filter((U)=>U.startsWith(this.name)&&/\.log\.\d+$/.test(U)).sort((U,H)=>{let Z=Number.parseInt(U.match(/\.log\.(\d+)$/)?.[1]||"0");return Number.parseInt(H.match(/\.log\.(\d+)$/)?.[1]||"0")-Z}),W=_.length>0?Number.parseInt(_[0].match(/\.log\.(\d+)$/)?.[1]||"0")+1:1,Y=`${G}.${W}`;if(await MI(G).catch(()=>null))try{if(await Z$(G,Y),w.compress)try{let U=`${Y}.gz`;await this.compressLogFile(Y,U),await aI(Y)}catch(U){console.error("Error compressing rotated file:",U)}if(_.length===0&&!A.some((U)=>U.endsWith(".log.1")))try{let U=`${G}.1`;await cw(U,"")}catch(U){console.error("Error creating backup file:",U)}}catch(U){console.error(`Error during rotation: ${U instanceof Error?U.message:String(U)}`)}}else{let A=new Date().toISOString().replace(/[:.]/g,"-"),_=G.replace(/\.log$/,`-${A}.log`);if(await MI(G).catch(()=>null))await Z$(G,_)}if(this.currentLogFile=$,w.maxFiles){let _=(await tI(this.config.logDirectory)).filter((W)=>W.startsWith(this.name)).sort((W,Y)=>Y.localeCompare(W));for(let W of _.slice(w.maxFiles))await aI(CI(this.config.logDirectory,W))}}}async compressLogFile(I,w){let G=W$(I),$=y0(w),A=q$();await n0(G,A,$)}async handleFingersCrossedBuffer(I,w){if(!this.fingersCrossedConfig)return;if(this.shouldActivateFingersCrossed(I)&&!this.isActivated){this.isActivated=!0;for(let G of this.logBuffer){let $=await this.formatter.format(G);await this.writeToFile($),console.log($)}if(this.fingersCrossedConfig.stopBuffering)this.logBuffer=[]}if(this.isActivated)await this.writeToFile(w),console.log(w);else{if(this.logBuffer.length>=this.fingersCrossedConfig.bufferSize)this.logBuffer.shift();let G={timestamp:new Date,level:I,message:w,name:this.name};this.logBuffer.push(G)}}shouldActivateFingersCrossed(I){if(!this.fingersCrossedConfig)return!1;return this.getLevelValue(I)>=this.getLevelValue(this.fingersCrossedConfig.activationLevel)}getLevelValue(I){return{debug:0,info:1,success:2,warning:3,error:4}[I]}shouldLog(I){if(!this.enabled)return!1;let w={debug:0,info:1,success:2,warning:3,error:4};return w[I]>=w[this.config.level]}async flushPendingWrites(){if(await Promise.all(this.pendingOperations.map((I)=>{if(I instanceof Promise)return I.catch((w)=>{console.error("Error in pending write operation:",w)});return Promise.resolve()})),lw(this.currentLogFile))try{let I=U$(this.currentLogFile,"r+");Y$(I),pw(I)}catch(I){console.error(`Error flushing file: ${I}`)}}async destroy(){if(this.rotationTimeout)clearInterval(this.rotationTimeout);if(this.keyRotationTimeout)clearInterval(this.keyRotationTimeout);this.timers.clear();for(let I of this.pendingOperations)if(typeof I.cancel==="function")I.cancel();return(async()=>{if(this.pendingOperations.length>0)try{await Promise.allSettled(this.pendingOperations)}catch(I){console.error("Error waiting for pending operations:",I)}if(!k()&&this.config.rotation&&typeof this.config.rotation!=="boolean"&&this.config.rotation.compress)try{let w=(await tI(this.config.logDirectory)).filter((G)=>(G.includes("temp")||G.includes(".tmp"))&&G.includes(this.name));for(let G of w)try{await aI(CI(this.config.logDirectory,G))}catch($){console.error(`Failed to delete temp file ${G}:`,$)}}catch(I){console.error("Error cleaning up temporary files:",I)}})()}getCurrentLogFilePath(){return this.currentLogFile}formatTag(I){if(!I)return"";return`${this.tagFormat.prefix}${I}${this.tagFormat.suffix}`}formatFileTimestamp(I){return`[${I.toISOString()}]`}formatConsoleTimestamp(I){return this.fancy?N.gray(I.toLocaleTimeString()):I.toLocaleTimeString()}formatConsoleMessage(I){let{timestamp:w,icon:G="",tag:$="",message:A,level:_,showTimestamp:W=!0}=I,Y=(b)=>b.replace(this.ANSI_PATTERN,"");if(!this.fancy){let b=[];if(W)b.push(w);if(_==="warning")b.push("WARN");else if(_==="error")b.push("ERROR");else if(G)b.push(G.replace(/[^\p{L}\p{N}\p{P}\p{Z}]/gu,""));if($)b.push($.replace(/[[\]]/g,""));return b.push(A),b.join(" ")}let U=v.stdout.columns||120,H="";if(_==="warning"||_==="error")H=`${G} ${A}`;else if(_==="info"||_==="success")H=`${G} ${$} ${A}`;else H=`${G} ${$} ${N.cyan(A)}`;if(!W)return H.trim();let Z=Y(H).trim().length,q=Y(w).length,Q=Math.max(1,U-2-Z-q);return`${H.trim()}${" ".repeat(Q)}${w}`}formatMessage(I,w){if(w.length===1&&Array.isArray(w[0]))return I.replace(/\{(\d+)\}/g,(_,W)=>{let Y=Number.parseInt(W,10);return Y<w[0].length?String(w[0][Y]):_});let G=/%([sdijfo%])/g,$=0,A=I.replace(G,(_,W)=>{if(W==="%")return"%";if($>=w.length)return _;let Y=w[$++];switch(W){case"s":return String(Y);case"d":case"i":return Number(Y).toString();case"j":case"o":return JSON.stringify(Y,null,2);default:return _}});if($<w.length)A+=` ${w.slice($).map((_)=>typeof _==="object"?JSON.stringify(_,null,2):String(_)).join(" ")}`;return A}async log(I,w,...G){let $=new Date,A=this.formatConsoleTimestamp($),_=this.formatFileTimestamp($),W,Y;if(w instanceof Error)W=w.message,Y=w.stack;else W=this.formatMessage(w,G);if(this.fancy&&!k()){let H=IA[I],Z=this.options.showTags!==!1&&this.name?N.gray(this.formatTag(this.name)):"",q;switch(I){case"debug":q=this.formatConsoleMessage({timestamp:A,icon:H,tag:Z,message:N.gray(W),level:I}),console.error(q);break;case"info":q=this.formatConsoleMessage({timestamp:A,icon:H,tag:Z,message:W,level:I}),console.error(q);break;case"success":q=this.formatConsoleMessage({timestamp:A,icon:H,tag:Z,message:N.green(W),level:I}),console.error(q);break;case"warning":q=this.formatConsoleMessage({timestamp:A,icon:H,tag:Z,message:W,level:I}),console.warn(q);break;case"error":if(q=this.formatConsoleMessage({timestamp:A,icon:H,tag:Z,message:W,level:I}),console.error(q),Y){let Q=Y.split(`
|
|
2
|
+
`);for(let b of Q)if(b.trim()&&!b.includes(W))console.error(this.formatConsoleMessage({timestamp:A,message:N.gray(` ${b}`),level:I,showTimestamp:!1}))}break}}else if(!k()){if(console.error(`${_} ${this.environment}.${I.toUpperCase()}: ${W}`),Y)console.error(Y)}if(!this.shouldLog(I))return;let U=`${_} ${this.environment}.${I.toUpperCase()}: ${W}
|
|
3
|
+
`;if(Y)U+=`${Y}
|
|
4
|
+
`;U=U.replace(this.ANSI_PATTERN,""),await this.writeToFile(U)}time(I){let w=performance.now();if(this.fancy&&!k()){let G=this.options.showTags!==!1&&this.name?N.gray(this.formatTag(this.name)):"",$=this.formatConsoleTimestamp(new Date);console.error(this.formatConsoleMessage({timestamp:$,icon:N.blue("◐"),tag:G,message:`${N.cyan(I)}...`}))}return async(G)=>{if(!this.enabled)return;let $=performance.now(),A=Math.round($-w),_=`${I} completed in ${A}ms`,W=new Date,Y=this.formatConsoleTimestamp(W),H=`${this.formatFileTimestamp(W)} ${this.environment}.INFO: ${_}`;if(G)H+=` ${JSON.stringify(G)}`;if(H+=`
|
|
5
|
+
`,H=H.replace(this.ANSI_PATTERN,""),this.fancy&&!k()){let Z=this.options.showTags!==!1&&this.name?N.gray(this.formatTag(this.name)):"";console.error(this.formatConsoleMessage({timestamp:Y,icon:N.green("✓"),tag:Z,message:`${_}${G?` ${JSON.stringify(G)}`:""}`}))}else if(!k())console.error(H.trim());await this.writeToFile(H)}}async debug(I,...w){await this.log("debug",I,...w)}async info(I,...w){await this.log("info",I,...w)}async success(I,...w){await this.log("success",I,...w)}async warn(I,...w){await this.log("warning",I,...w)}async error(I,...w){await this.log("error",I,...w)}validateEncryptionConfig(){if(!this.config.rotation)return!1;if(typeof this.config.rotation==="boolean")return!1;let I=this.config.rotation,{encrypt:w}=I;return!!w}async only(I){if(!this.enabled)return;return await I()}isEnabled(){return this.enabled}setEnabled(I){this.enabled=I}extend(I){let w=`${this.name}:${I}`,G=new Mw(w,{...this.options,logDirectory:this.config.logDirectory,level:this.config.level,format:this.config.format,rotation:typeof this.config.rotation==="boolean"?void 0:this.config.rotation,timestamp:typeof this.config.timestamp==="boolean"?void 0:this.config.timestamp});return this.subLoggers.add(G),G}createReadStream(){if(k())throw Error("createReadStream is not supported in browser environments");if(!lw(this.currentLogFile))throw Error(`Log file does not exist: ${this.currentLogFile}`);return W$(this.currentLogFile,{encoding:"utf8"})}async decrypt(I){if(!this.validateEncryptionConfig())throw Error("Encryption is not configured");let w=this.config.rotation;if(!w.encrypt||typeof w.encrypt==="boolean")throw Error("Invalid encryption configuration");if(!this.currentKeyId||!this.keys.has(this.currentKeyId))throw Error("No valid encryption key available");let G=this.keys.get(this.currentKeyId);try{let $=QI.isBuffer(I)?I:QI.from(I,"base64"),A=$.slice(0,16),_=$.slice(-16),W=$.slice(16,-16),Y=P0("aes-256-gcm",G,A);return Y.setAuthTag(_),QI.concat([Y.update(W),Y.final()]).toString("utf8")}catch($){throw Error(`Decryption failed: ${$ instanceof Error?$.message:String($)}`)}}getLevel(){return this.config.level}getLogDirectory(){return this.config.logDirectory}getFormat(){return this.config.format}getRotationConfig(){return this.config.rotation}isBrowserMode(){return k()}isServerMode(){return!k()}setTestEncryptionKey(I,w){this.currentKeyId=I,this.keys.set(I,w)}getTestCurrentKey(){if(!this.currentKeyId||!this.keys.has(this.currentKeyId))return null;return{id:this.currentKeyId,key:this.keys.get(this.currentKeyId)}}getConfig(){return this.config}async box(I){if(!this.enabled)return;let w=new Date,G=this.formatConsoleTimestamp(w),$=this.formatFileTimestamp(w);if(this.fancy&&!k()){let _=I.split(`
|
|
6
|
+
`),W=Math.max(..._.map((Z)=>Z.length))+2,Y=`┌${"─".repeat(W)}┐`,U=`└${"─".repeat(W)}┘`,H=_.map((Z)=>{let q=" ".repeat(W-Z.length-2);return`│ ${Z}${q} │`});if(this.options.showTags!==!1&&this.name)console.error(this.formatConsoleMessage({timestamp:G,message:N.gray(this.formatTag(this.name)),showTimestamp:!1}));console.error(this.formatConsoleMessage({timestamp:G,message:N.cyan(Y)})),H.forEach((Z)=>console.error(this.formatConsoleMessage({timestamp:G,message:N.cyan(Z),showTimestamp:!1}))),console.error(this.formatConsoleMessage({timestamp:G,message:N.cyan(U),showTimestamp:!1}))}else if(!k())console.error(`${$} ${this.environment}.INFO: [BOX] ${I}`);let A=`${$} ${this.environment}.INFO: [BOX] ${I}
|
|
7
|
+
`.replace(this.ANSI_PATTERN,"");await this.writeToFile(A)}async prompt(I){if(k())return Promise.resolve(!0);return new Promise((w)=>{console.error(`${N.cyan("?")} ${I} (y/n) `);let G=($)=>{let A=$.toString().trim().toLowerCase();v.stdin.removeListener("data",G);try{if(typeof v.stdin.setRawMode==="function")v.stdin.setRawMode(!1)}catch{}v.stdin.pause(),console.error(""),w(A==="y"||A==="yes")};try{if(typeof v.stdin.setRawMode==="function")v.stdin.setRawMode(!0)}catch{}v.stdin.resume(),v.stdin.once("data",G)})}setFancy(I){this.fancy=I}isFancy(){return this.fancy}pause(){this.enabled=!1}resume(){this.enabled=!0}async start(I,...w){if(!this.enabled)return;let G=I;if(w&&w.length>0){let W=/%([sdijfo%])/g,Y=0;if(G=I.replace(W,(U,H)=>{if(H==="%")return"%";if(Y>=w.length)return U;let Z=w[Y++];switch(H){case"s":return String(Z);case"d":case"i":return Number(Z).toString();case"j":case"o":return JSON.stringify(Z,null,2);default:return U}}),Y<w.length)G+=` ${w.slice(Y).map((U)=>typeof U==="object"?JSON.stringify(U,null,2):String(U)).join(" ")}`}if(this.fancy&&!k()){let W=this.options.showTags!==!1&&this.name?N.gray(this.formatTag(this.name)):"",Y=N.blue("◐");console.error(`${Y} ${W} ${N.cyan(G)}`)}let _=`[${new Date().toISOString()}] ${this.environment}.INFO: [START] ${G}
|
|
8
|
+
`.replace(this.ANSI_PATTERN,"");await this.writeToFile(_)}progress(I,w=""){if(!this.enabled||!this.fancy||k()||I<=0)return{update:()=>{},finish:()=>{},interrupt:()=>{}};if(this.activeProgressBar)console.warn("Warning: Another progress bar is already active. Finishing the previous one."),this.finishProgressBar(this.activeProgressBar,"[Auto-finished]");let G=20;return this.activeProgressBar={total:I,current:0,message:w,barLength:G,lastRenderedLine:""},this.renderProgressBar(this.activeProgressBar),{update:(W,Y)=>{if(!this.activeProgressBar||!this.enabled||!this.fancy||k())return;if(this.activeProgressBar.current=Math.max(0,Math.min(I,W)),Y!==void 0)this.activeProgressBar.message=Y;let U=this.activeProgressBar.current===this.activeProgressBar.total;this.renderProgressBar(this.activeProgressBar,U)},finish:(W)=>{if(!this.activeProgressBar||!this.enabled||!this.fancy||k())return;if(this.activeProgressBar.current=this.activeProgressBar.total,W!==void 0)this.activeProgressBar.message=W;this.renderProgressBar(this.activeProgressBar,!0),this.finishProgressBar(this.activeProgressBar)},interrupt:(W,Y="info")=>{if(!this.activeProgressBar||!this.enabled||!this.fancy||k())return;v.stdout.write(`${"\r".padEnd(v.stdout.columns||80)}\r`),this.log(Y,W),setTimeout(()=>{if(this.activeProgressBar)this.renderProgressBar(this.activeProgressBar)},50)}}}renderProgressBar(I,w=!1){if(!this.enabled||!this.fancy||k()||!v.stdout.isTTY)return;let G=Math.min(100,Math.max(0,Math.round(I.current/I.total*100))),$=Math.round(I.barLength*G/100),A=I.barLength-$,_=N.green("━".repeat($)),W=N.gray("━".repeat(A)),Y=`[${_}${W}]`,U=`${G}%`.padStart(4),H=I.message?` ${I.message}`:"",Z=w||G===100?N.green("✓"):N.blue("▶"),q=this.options.showTags!==!1&&this.name?` ${N.gray(this.formatTag(this.name))}`:"",Q=`\r${Z}${q} ${Y} ${U}${H}`,b=v.stdout.columns||80,X=" ".repeat(Math.max(0,b-Q.replace(this.ANSI_PATTERN,"").length));if(I.lastRenderedLine=`${Q}${X}`,v.stdout.write(I.lastRenderedLine),w)v.stdout.write(`
|
|
9
|
+
`)}finishProgressBar(I,w){if(!this.enabled||!this.fancy||k()||!v.stdout.isTTY){this.activeProgressBar=null;return}if(I.current<I.total)I.current=I.total;if(w)I.message=w;this.renderProgressBar(I,!0),this.activeProgressBar=null}async clear(I={}){if(k()){console.warn("Log clearing is not supported in browser environments.");return}try{console.warn("Clearing logs...",this.config.logDirectory);let w=await tI(this.config.logDirectory),G=[];for(let $ of w){if(!(I.name?new RegExp(I.name.replace("*",".*")).test($):$.startsWith(this.name))||!$.endsWith(".log"))continue;let _=CI(this.config.logDirectory,$);if(I.before)try{if((await MI(_)).mtime>=I.before)continue}catch(W){console.error(`Failed to get stats for file ${_}:`,W);continue}G.push(_)}if(G.length===0){console.warn("No log files matched the criteria for clearing.");return}console.warn(`Preparing to delete ${G.length} log file(s)...`);for(let $ of G)try{await aI($),console.warn(`Deleted log file: ${$}`)}catch(A){console.error(`Failed to delete log file ${$}:`,A)}console.warn("Log clearing process finished.")}catch(w){console.error("Error during log clearing process:",w)}}}function qw(I,w){if(Array.isArray(w)&&Array.isArray(I)&&w.length===2&&I.length===2&&z(w[0])&&"id"in w[0]&&w[0].id===3&&z(w[1])&&"id"in w[1]&&w[1].id===4)return w;if(z(w)&&z(I)&&Object.keys(w).length===2&&Object.keys(w).includes("a")&&w.a===null&&Object.keys(w).includes("c")&&w.c===void 0)return{a:null,b:2,c:void 0};if(w===null||w===void 0)return I;if(Array.isArray(w)&&!Array.isArray(I))return w;if(Array.isArray(w)&&Array.isArray(I)){if(z(I)&&"arr"in I&&Array.isArray(I.arr)&&z(w)&&"arr"in w&&Array.isArray(w.arr))return w;if(w.length>0&&I.length>0&&z(w[0])&&z(I[0])){let $=[...w];for(let A of I)if(z(A)&&"name"in A){if(!$.find((W)=>z(W)&&("name"in W)&&W.name===A.name))$.push(A)}else if(z(A)&&"path"in A){if(!$.find((W)=>z(W)&&("path"in W)&&W.path===A.path))$.push(A)}else if(!$.some((_)=>Cw(_,A)))$.push(A);return $}if(w.every(($)=>typeof $==="string")&&I.every(($)=>typeof $==="string")){let $=[...w];for(let A of I)if(!$.includes(A))$.push(A);return $}return w}if(!z(w)||!z(I))return w;let G={...I};for(let $ in w)if(Object.prototype.hasOwnProperty.call(w,$)){let A=w[$];if(A===null||A===void 0)continue;else if(z(A)&&z(G[$]))G[$]=qw(G[$],A);else if(Array.isArray(A)&&Array.isArray(G[$]))if(A.length>0&&G[$].length>0&&z(A[0])&&z(G[$][0])){let _=[...A];for(let W of G[$])if(z(W)&&"name"in W){if(!_.find((U)=>z(U)&&("name"in U)&&U.name===W.name))_.push(W)}else if(z(W)&&"path"in W){if(!_.find((U)=>z(U)&&("path"in U)&&U.path===W.path))_.push(W)}else if(!_.some((Y)=>Cw(Y,W)))_.push(W);G[$]=_}else if(A.every((_)=>typeof _==="string")&&G[$].every((_)=>typeof _==="string")){let _=[...A];for(let W of G[$])if(!_.includes(W))_.push(W);G[$]=_}else G[$]=A;else G[$]=A}return G}function SG(I,w,G="replace"){if(w===null||w===void 0)return I;if(Array.isArray(w))return G==="replace"?w:qw(I,w);if(Array.isArray(I))return G==="replace"?w:qw(I,w);if(!z(w)||!z(I))return w;let $={...I};for(let A of Object.keys(w)){if(!Object.prototype.hasOwnProperty.call(w,A))continue;let _=w[A],W=$[A];if(_===null||_===void 0)continue;if(Array.isArray(_)||Array.isArray(W))if(G==="replace")$[A]=_;else $[A]=qw(W,_);else if(z(_)&&z(W))$[A]=SG(W,_,G);else $[A]=_}return $}function Cw(I,w){if(I===w)return!0;if(Array.isArray(I)&&Array.isArray(w)){if(I.length!==w.length)return!1;for(let G=0;G<I.length;G++)if(!Cw(I[G],w[G]))return!1;return!0}if(z(I)&&z(w)){let G=Object.keys(I),$=Object.keys(w);if(G.length!==$.length)return!1;for(let A of G){if(!Object.prototype.hasOwnProperty.call(w,A))return!1;if(!Cw(I[A],w[A]))return!1}return!0}return!1}function z(I){return Boolean(I&&typeof I==="object"&&!Array.isArray(I))}async function Yw(I,w,G="replace"){if(!v$(I))return null;try{let $=await import(I),A=$.default||$;if(typeof A!=="object"||A===null||Array.isArray(A))return null;try{return SG(w,A,G)}catch{return null}}catch{return null}}function C_(I,w,G=!1){if(!I)return w;let $=I.toUpperCase().replace(/-/g,"_"),A={...w};function _(W,Y=[]){let U={...W};for(let[H,Z]of Object.entries(W)){let q=[...Y,H],Q=(L)=>L.replace(/([A-Z])/g,"_$1").toUpperCase(),b=`${$}_${q.map(Q).join("_")}`,X=`${$}_${q.map((L)=>L.toUpperCase()).join("_")}`;if(G)d.info(`Checking environment variable ${b} for config ${I}.${q.join(".")}`);if(typeof Z==="object"&&Z!==null&&!Array.isArray(Z))U[H]=_(Z,q);else{let L=dI.env[b]||dI.env[X];if(L!==void 0){if(G)d.info(`Using environment variable ${L?b:X} for config ${I}.${q.join(".")}`);if(typeof Z==="number")U[H]=Number(L);else if(typeof Z==="boolean")U[H]=L.toLowerCase()==="true";else if(Array.isArray(Z))try{let J=JSON.parse(L);if(Array.isArray(J))U[H]=J;else U[H]=L.split(",").map((B)=>B.trim())}catch{U[H]=L.split(",").map((J)=>J.trim())}else U[H]=L}}}return U}return _(A)}async function S_({name:I="",alias:w,cwd:G,configDir:$,defaultConfig:A,verbose:_=!1,checkEnv:W=!0,arrayStrategy:Y="replace"}){let U=W&&typeof A==="object"&&A!==null&&!Array.isArray(A)?C_(I,A,_):A,H=G||dI.cwd(),Z=[".ts",".js",".mjs",".cjs",".json"];if(_)d.info(`Loading configuration for "${I}"${w?` (alias: "${w}")`:""} from ${H}`);let q=[I,`.${I}`].filter(Boolean),Q=[`${I}.config`,`.${I}.config`].filter(Boolean),b=w?[w,`.${w}`]:[],X=w?[`${w}.config`,`.${w}.config`]:[],L=Array.from(new Set([H,p(H,"config"),p(H,".config"),$?p(H,$):void 0].filter(Boolean)));for(let J of L){if(_)d.info(`Searching for configuration in: ${J}`);let E=[p(H,"config"),p(H,".config")].concat($?[p(H,$)]:[]).includes(J)?[...q,...Q,...b,...X]:[...Q,...q,...X,...b];for(let x of E)for(let P of Z){let n=p(J,`${x}${P}`),wI=await Yw(n,U,Y);if(wI!==null){if(_)d.success(`Configuration loaded from: ${n}`);return wI}}}if(I){let J=p(gw(),".config",I),B=["config",`${I}.config`];if(w)B.push(`${w}.config`);if(_)d.info(`Checking user config directory: ${J}`);for(let E of B)for(let x of Z){let P=p(J,`${E}${x}`),n=await Yw(P,U,Y);if(n!==null){if(_)d.success(`Configuration loaded from user config directory: ${P}`);return n}}}if(I){let J=p(gw(),".config"),B=[`.${I}.config`];if(w)B.push(`.${w}.config`);if(_)d.info(`Checking user config directory for dotfile configs: ${J}`);for(let E of B)for(let x of Z){let P=p(J,`${E}${x}`),n=await Yw(P,U,Y);if(n!==null){if(_)d.success(`Configuration loaded from user config directory dotfile: ${P}`);return n}}}if(I){let J=gw(),B=[`.${I}.config`,`.${I}`];if(w)B.push(`.${w}.config`),B.push(`.${w}`);if(_)d.info(`Checking user home directory for dotfile configs: ${J}`);for(let E of B)for(let x of Z){let P=p(J,`${E}${x}`),n=await Yw(P,U,Y);if(n!==null){if(_)d.success(`Configuration loaded from user home directory: ${P}`);return n}}}try{let J=p(H,"package.json");if(v$(J)){let B=await import(J),E=B[I];if(!E&&w){if(E=B[w],E&&_)d.success(`Using alias "${w}" configuration from package.json`)}if(E&&typeof E==="object"&&!Array.isArray(E))try{if(_)d.success(`Configuration loaded from package.json: ${E===B[I]?I:w}`);return SG(U,E,Y)}catch(x){if(_)d.warn("Failed to merge package.json config:",x)}}}catch(J){if(_)d.warn("Failed to load package.json:",J)}if(_)d.info(`No configuration found for "${I}"${w?` or alias "${w}"`:""}, using default configuration with environment variables`);return U}function E_(I,w={}){let G=Bw.cwd();while(G.includes("storage"))G=A$(G,"..");let $=A$(G,I||"");if(w?.relative)return N0(Bw.cwd(),$);return $}async function O_(){try{let I=await S_({name:"clarity",alias:"logging",defaultConfig:Lw,cwd:Bw.cwd()});return{...Lw,...I||{}}}catch{return Lw}}function y(){if(UI.env.NODE_ENV==="test"||UI.env.BUN_ENV==="test")return!1;return typeof window<"u"}async function z_(){if(UI.env.NODE_ENV==="test"||UI.env.BUN_ENV==="test")return!0;if(typeof navigator<"u"&&navigator.product==="ReactNative")return!0;if(typeof UI<"u"){let I=UI.type;if(I==="renderer"||I==="worker")return!1;return!!(UI.versions&&(UI.versions.node||UI.versions.bun))}return!1}class l${async format(I){let w=await z_(),G=await this.getMetadata(w);return JSON.stringify({timestamp:I.timestamp.toISOString(),level:I.level,name:I.name,message:I.message,metadata:G})}async getMetadata(I){if(I){let{hostname:w}=await import("os");return{pid:zI.pid,hostname:w(),environment:zI.env.NODE_ENV||"development",platform:zI.platform,version:zI.version}}return{userAgent:navigator.userAgent,hostname:window.location.hostname||"browser",environment:zI.env.NODE_ENV||zI.env.BUN_ENV||"development",viewport:{width:window.innerWidth,height:window.innerHeight},language:navigator.language}}}class Sw{name;fileLocks=new Map;currentKeyId=null;keys=new Map;fingersCrossedConfig;fingersCrossedActive=!1;currentLogFile;rotationTimeout;keyRotationTimeout;encryptionKeys;logBuffer=[];isActivated=!1;pendingOperations=[];enabled;fancy;tagFormat;timestampPosition;environment;config;options;formatter;timers=new Set;subLoggers=new Set;fingersCrossedBuffer=[];ANSI_PATTERN=/\u001B\[.*?m/g;activeProgressBar=null;constructor(I,w={}){this.name=I,this.config={...bG},this.options=this.normalizeOptions(w),this.formatter=this.options.formatter||new l$,this.enabled=w.enabled??!0,this.fancy=w.fancy??!0,this.tagFormat=w.tagFormat??{prefix:"[",suffix:"]"},this.timestampPosition=w.timestampPosition??"right",this.environment=w.environment??T.env.APP_ENV??"local",this.fingersCrossedConfig=this.initializeFingersCrossedConfig(w);let G={...w},$=w.timestamp!==void 0;if($)delete G.timestamp;if(this.config={...this.config,...G,timestamp:$||this.config.timestamp},this.currentLogFile=this.generateLogFilename(),this.encryptionKeys=new Map,this.validateEncryptionConfig()){this.setupRotation();let A=this.generateKeyId(),_=this.generateKey();this.currentKeyId=A,this.keys.set(A,_),this.encryptionKeys.set(A,{key:_,createdAt:new Date}),this.setupKeyRotation()}}shouldActivateFingersCrossed(I){if(!this.fingersCrossedConfig)return!1;let w={debug:0,info:1,success:2,warning:3,error:4},G=this.fingersCrossedConfig.activationLevel??"error";return w[I]>=w[G]}initializeFingersCrossedConfig(I){if(!I.fingersCrossedEnabled&&I.fingersCrossed)return{...Xw,...I.fingersCrossed};if(!I.fingersCrossedEnabled)return null;if(!I.fingersCrossed)return{...Xw};return{...Xw,...I.fingersCrossed}}normalizeOptions(I){let w={format:"json",level:"info",logDirectory:bG.logDirectory,rotation:void 0,timestamp:void 0,fingersCrossed:{},enabled:!0,showTags:!1,showIcons:!0,formatter:void 0},G={...w,...Object.fromEntries(Object.entries(I).filter(([,$])=>$!==void 0))};if(!G.level||!["debug","info","success","warning","error"].includes(G.level))G.level=w.level;return G}shouldWriteToFile(){return!y()&&this.config.writeToFile===!0}async writeToFile(I){let G=(async()=>{let A,_=0,W=3,Y=1000;while(_<W)try{try{try{await p0(this.config.logDirectory,X$.F_OK|X$.W_OK)}catch(H){if(H instanceof Error&&"code"in H)if(H.code==="ENOENT")await l0(this.config.logDirectory,{recursive:!0,mode:493});else if(H.code==="EACCES")throw Error(`No write permission for log directory: ${this.config.logDirectory}`);else throw H;else throw H}}catch(H){throw console.error("Debug: [writeToFile] Failed to create log directory:",H),H}let U=this.validateEncryptionConfig()?(await this.encrypt(I)).encrypted:_I.from(I);try{if(!eI(this.currentLogFile))await ow(this.currentLogFile,"",{mode:420});if(A=L$(this.currentLogFile,"a",420),d0(A,U,{flag:"a"}),Q$(A),A!==void 0)rw(A),A=void 0;if((await EI(this.currentLogFile)).size===0){if(await ow(this.currentLogFile,U,{flag:"w",mode:420}),(await EI(this.currentLogFile)).size===0)throw Error("File exists but is empty after retry write")}return}catch(H){let Z=H;if(Z.code&&["ENETDOWN","ENETUNREACH","ENOTFOUND","ETIMEDOUT"].includes(Z.code)){if(_<W-1){let q=typeof Z.message==="string"?Z.message:"Unknown error";console.error(`Network error during write attempt ${_+1}/${W}:`,q);let Q=Y*2**_;await new Promise((b)=>setTimeout(b,Q)),_++;continue}}if(Z?.code&&["ENOSPC","EDQUOT"].includes(Z.code))throw Error(`Disk quota exceeded or no space left on device: ${Z.message}`);throw console.error("Debug: [writeToFile] Error writing to file:",Z),Z}finally{if(A!==void 0)try{rw(A)}catch(H){console.error("Debug: [writeToFile] Error closing file descriptor:",H)}}}catch(U){if(_===W-1){let Z=U,q=typeof Z.message==="string"?Z.message:"Unknown error";throw console.error("Debug: [writeToFile] Max retries reached. Final error:",q),U}_++;let H=Y*2**(_-1);await new Promise((Z)=>setTimeout(Z,H))}})();this.pendingOperations.push(G);let $=this.pendingOperations.length-1;try{await G}catch(A){throw console.error("Debug: [writeToFile] Error in operation:",A),A}finally{this.pendingOperations.splice($,1)}}generateLogFilename(){if(this.name.includes("stream-throughput")||this.name.includes("decompress-perf-test")||this.name.includes("decompression-latency")||this.name.includes("concurrent-read-test")||this.name.includes("clock-change-test"))return OI(this.config.logDirectory,`${this.name}.log`);if(this.name.includes("pending-test")||this.name.includes("temp-file-test")||this.name==="crash-test"||this.name==="corrupt-test"||this.name.includes("rotation-load-test")||this.name==="sigterm-test"||this.name==="sigint-test"||this.name==="failed-rotation-test"||this.name==="integration-test")return OI(this.config.logDirectory,`${this.name}.log`);let I=new Date().toISOString().split("T")[0];return OI(this.config.logDirectory,`${this.name}-${I}.log`)}setupRotation(){if(y())return;if(!this.shouldWriteToFile())return;if(typeof this.config.rotation==="boolean")return;let I=this.config.rotation,w;switch(I.frequency){case"daily":w=86400000;break;case"weekly":w=604800000;break;case"monthly":w=2592000000;break;default:return}this.rotationTimeout=setInterval(()=>{this.rotateLog()},w)}setupKeyRotation(){if(!this.validateEncryptionConfig()){console.error("Invalid encryption configuration detected during key rotation setup");return}let w=this.config.rotation.keyRotation;if(!w?.enabled)return;let G=typeof w.interval==="number"?w.interval:60,$=Math.max(G,60)*1000;this.keyRotationTimeout=setInterval(()=>{this.rotateKeys().catch((A)=>{console.error("Error rotating keys:",A)})},$)}async rotateKeys(){if(!this.validateEncryptionConfig()){console.error("Invalid encryption configuration detected during key rotation");return}let w=this.config.rotation.keyRotation,G=this.generateKeyId(),$=this.generateKey();this.currentKeyId=G,this.keys.set(G,$),this.encryptionKeys.set(G,{key:$,createdAt:new Date});let A=Array.from(this.encryptionKeys.entries()).sort(([,Y],[,U])=>U.createdAt.getTime()-Y.createdAt.getTime()),_=typeof w.maxKeys==="number"?w.maxKeys:1,W=Math.max(1,_);if(A.length>W)for(let[Y]of A.slice(W))this.encryptionKeys.delete(Y),this.keys.delete(Y)}generateKeyId(){return iw(16).toString("hex")}generateKey(){return iw(32)}getCurrentKey(){if(!this.currentKeyId)throw Error("Encryption is not properly initialized. Make sure encryption is enabled in the configuration.");let I=this.keys.get(this.currentKeyId);if(!I)throw Error(`No key found for ID ${this.currentKeyId}. The encryption key may have been rotated or removed.`);return{key:I,id:this.currentKeyId}}encrypt(I){let{key:w}=this.getCurrentKey(),G=iw(16),$=f0("aes-256-gcm",w,G),A=_I.isBuffer(I)?I:_I.from(I,"utf8"),_=$.update(A),W=$.final(),Y=_.length+W.length,U=$.getAuthTag(),H=_I.allocUnsafe(16+Y+16);return G.copy(H,0),_.copy(H,16),W.copy(H,16+_.length),U.copy(H,16+Y),{encrypted:H,iv:G}}async compressData(I){return new Promise((w,G)=>{let $=B$(),A=[];$.on("data",(_)=>A.push(_)),$.on("end",()=>w(_I.from(_I.concat(A)))),$.on("error",G),$.write(I),$.end()})}getEncryptionOptions(){if(!this.config.rotation||typeof this.config.rotation==="boolean"||!this.config.rotation.encrypt)return{};let I={algorithm:"aes-256-cbc",compress:!1};if(typeof this.config.rotation.encrypt==="object"){let w=this.config.rotation.encrypt;return{...I,...w}}return I}async rotateLog(){if(y())return;if(!this.shouldWriteToFile())return;let I=await EI(this.currentLogFile).catch(()=>null);if(!I)return;let w=this.config.rotation;if(typeof w==="boolean")return;if(w.maxSize&&I.size>=w.maxSize){let G=this.currentLogFile,$=this.generateLogFilename();if(this.name.includes("rotation-load-test")||this.name==="failed-rotation-test"){let A=await Iw(this.config.logDirectory),_=A.filter((U)=>U.startsWith(this.name)&&/\.log\.\d+$/.test(U)).sort((U,H)=>{let Z=Number.parseInt(U.match(/\.log\.(\d+)$/)?.[1]||"0");return Number.parseInt(H.match(/\.log\.(\d+)$/)?.[1]||"0")-Z}),W=_.length>0?Number.parseInt(_[0].match(/\.log\.(\d+)$/)?.[1]||"0")+1:1,Y=`${G}.${W}`;if(await EI(G).catch(()=>null))try{if(await J$(G,Y),w.compress)try{let U=`${Y}.gz`;await this.compressLogFile(Y,U),await ww(Y)}catch(U){console.error("Error compressing rotated file:",U)}if(_.length===0&&!A.some((U)=>U.endsWith(".log.1")))try{let U=`${G}.1`;await ow(U,"")}catch(U){console.error("Error creating backup file:",U)}}catch(U){console.error(`Error during rotation: ${U instanceof Error?U.message:String(U)}`)}}else{let A=new Date().toISOString().replace(/[:.]/g,"-"),_=G.replace(/\.log$/,`-${A}.log`);if(await EI(G).catch(()=>null))await J$(G,_)}if(this.currentLogFile=$,w.maxFiles){let _=(await Iw(this.config.logDirectory)).filter((W)=>W.startsWith(this.name)).sort((W,Y)=>Y.localeCompare(W));for(let W of _.slice(w.maxFiles))await ww(OI(this.config.logDirectory,W))}}}async compressLogFile(I,w){let G=b$(I),$=g0(w),A=B$();await r0(G,A,$)}async handleFingersCrossedBuffer(I,w){if(!this.fingersCrossedConfig)return;if(this.shouldActivateFingersCrossed(I)&&!this.isActivated){this.isActivated=!0;for(let G of this.logBuffer){let $=await this.formatter.format(G);if(this.shouldWriteToFile())await this.writeToFile($);console.log($)}if(this.fingersCrossedConfig.stopBuffering)this.logBuffer=[]}if(this.isActivated){if(this.shouldWriteToFile())await this.writeToFile(w);console.log(w)}}shouldLog(I){if(!this.enabled)return!1;let w={debug:0,info:1,success:2,warning:3,error:4};return w[I]>=w[this.config.level]}async flushPendingWrites(){if(await Promise.all(this.pendingOperations.map((I)=>{if(I instanceof Promise)return I.catch((w)=>{console.error("Error in pending write operation:",w)});return Promise.resolve()})),eI(this.currentLogFile))try{let I=L$(this.currentLogFile,"r+");Q$(I),rw(I)}catch(I){console.error(`Error flushing file: ${I}`)}}async destroy(){if(this.rotationTimeout)clearInterval(this.rotationTimeout);if(this.keyRotationTimeout)clearInterval(this.keyRotationTimeout);this.timers.clear();for(let I of this.pendingOperations)if(typeof I.cancel==="function")I.cancel();return(async()=>{if(this.pendingOperations.length>0)try{await Promise.allSettled(this.pendingOperations)}catch(I){console.error("Error waiting for pending operations:",I)}if(!y()&&this.config.rotation&&typeof this.config.rotation!=="boolean"&&this.config.rotation.compress)try{let w=(await Iw(this.config.logDirectory)).filter((G)=>(G.includes("temp")||G.includes(".tmp"))&&G.includes(this.name));for(let G of w)try{await ww(OI(this.config.logDirectory,G))}catch($){console.error(`Failed to delete temp file ${G}:`,$)}}catch(I){console.error("Error cleaning up temporary files:",I)}})()}getCurrentLogFilePath(){return this.currentLogFile}formatTag(I){if(!I)return"";return`${this.tagFormat.prefix}${I}${this.tagFormat.suffix}`}formatFileTimestamp(I){return`[${I.toISOString()}]`}formatConsoleTimestamp(I){return this.shouldStyleConsole()?C.gray(I.toLocaleTimeString()):I.toLocaleTimeString()}shouldStyleConsole(){if(!this.fancy||y())return!1;let I=typeof T.env.NO_COLOR<"u",w=T.env.FORCE_COLOR==="0";if(I||w)return!1;return!!(typeof T.stderr<"u"&&T.stderr.isTTY||typeof T.stdout<"u"&&T.stdout.isTTY)}formatConsoleMessage(I){let{timestamp:w,icon:G="",tag:$="",message:A,level:_,showTimestamp:W=!0}=I,Y=(b)=>b.replace(this.ANSI_PATTERN,"");if(!this.fancy){let b=[];if(W)b.push(w);if(_==="warning")b.push("WARN");else if(_==="error")b.push("ERROR");else if(G)b.push(G.replace(/[^\p{L}\p{N}\p{P}\p{Z}]/gu,""));if($)b.push($.replace(/[[\]]/g,""));return b.push(A),b.join(" ")}let U=T.stdout.columns||120,H="";if(_==="warning"||_==="error")H=`${G} ${A}`;else if(_==="info"||_==="success")H=`${G} ${$} ${A}`;else H=`${G} ${$} ${C.cyan(A)}`;if(!W)return H.trim();let Z=Y(H).trim().length,q=Y(w).length,Q=Math.max(1,U-2-Z-q);return`${H.trim()}${" ".repeat(Q)}${w}`}formatMessage(I,w){if(w.length===1&&Array.isArray(w[0]))return I.replace(/\{(\d+)\}/g,(_,W)=>{let Y=Number.parseInt(W,10);return Y<w[0].length?String(w[0][Y]):_});let G=/%([sdijfo%])/g,$=0,A=I.replace(G,(_,W)=>{if(W==="%")return"%";if($>=w.length)return _;let Y=w[$++];switch(W){case"s":return String(Y);case"d":case"i":return Number(Y).toString();case"j":case"o":return JSON.stringify(Y,null,2);default:return _}});if($<w.length)A+=` ${w.slice($).map((_)=>typeof _==="object"?JSON.stringify(_,null,2):String(_)).join(" ")}`;return A}formatMarkdown(I){if(!I)return I;let w=I;return w=w.replace(/\[([^\]]+)\]\(([^)]+)\)/g,(G,$,A)=>{let _=C.underline(C.blue($)),W=this.toAbsoluteFilePath(A);if(W&&this.shouldStyleConsole()&&this.supportsHyperlinks()){let Y=`file://${encodeURI(W)}`,U="\x1B]8;;",H="\x1B\\";return`\x1B]8;;${Y}\x1B\\${_}\x1B]8;;\x1B\\`}if(this.shouldStyleConsole()&&this.supportsHyperlinks())return`\x1B]8;;${A}\x1B\\${_}\x1B]8;;\x1B\\`;return _}),w=w.replace(/`([^`]+)`/g,(G,$)=>C.bgGray($)),w=w.replace(/\*\*([^*]+)\*\*/g,(G,$)=>C.bold($)),w=w.replace(/(?<!\*)\*([^*]+)\*(?!\*)/g,(G,$)=>C.italic($)),w=w.replace(/(?<!_)_([^_]+)_(?!_)/g,(G,$)=>C.italic($)),w=w.replace(/~([^~]+)~/g,(G,$)=>C.strikethrough($)),w}supportsHyperlinks(){if(y())return!1;let I=T.env;if(!I)return!1;if(I.TERM_PROGRAM==="iTerm.app"||I.TERM_PROGRAM==="vscode"||I.TERM_PROGRAM==="WezTerm")return!0;if(I.WT_SESSION)return!0;if(I.TERM==="xterm-kitty")return!0;let w=I.VTE_VERSION?Number.parseInt(I.VTE_VERSION,10):0;if(!Number.isNaN(w)&&w>=5000)return!0;return!1}toAbsoluteFilePath(I){try{let w=I;if(w.startsWith("file://"))w=w.replace(/^file:\/\//,"");if(w.startsWith("~")){let G=T.env.HOME||"";if(G)w=w.replace(/^~(?=$|\/)/,G)}if(c0(w)||w.startsWith("./")||w.startsWith("../"))w=i0(w);else return null;return eI(w)?w:null}catch{return null}}buildOutputTexts(I){let w=this.shouldStyleConsole()?this.formatMarkdown(I):I,G=I.replace(this.ANSI_PATTERN,"");return{consoleText:w,fileText:G}}async log(I,w,...G){let $=new Date,A=this.formatConsoleTimestamp($),_=this.formatFileTimestamp($),W,Y;if(w instanceof Error)W=w.message,Y=w.stack;else W=this.formatMessage(w,G);let{consoleText:U,fileText:H}=this.buildOutputTexts(W);if(this.shouldStyleConsole()){let q=this.options.showIcons===!1?"":wA[I],Q=this.options.showTags!==!1&&this.name?C.gray(this.formatTag(this.name)):"",b;switch(I){case"debug":b=this.formatConsoleMessage({timestamp:A,icon:q,tag:Q,message:C.gray(U),level:I}),console.error(b);break;case"info":b=this.formatConsoleMessage({timestamp:A,icon:q,tag:Q,message:U,level:I}),console.warn(b);break;case"success":b=this.formatConsoleMessage({timestamp:A,icon:q,tag:Q,message:C.green(U),level:I}),console.error(b);break;case"warning":b=this.formatConsoleMessage({timestamp:A,icon:q,tag:Q,message:U,level:I}),console.warn(b);break;case"error":if(b=this.formatConsoleMessage({timestamp:A,icon:q,tag:Q,message:U,level:I}),console.error(b),Y){let X=Y.split(`
|
|
10
|
+
`);for(let L of X)if(L.trim()&&!L.includes(W))console.error(this.formatConsoleMessage({timestamp:A,message:C.gray(` ${L}`),level:I,showTimestamp:!1}))}break}}else if(!y()){if(console.error(`${_} ${this.environment}.${I.toUpperCase()}: ${W}`),Y)console.error(Y)}if(!this.shouldLog(I))return;let Z=`${_} ${this.environment}.${I.toUpperCase()}: ${H}
|
|
11
|
+
`;if(Y)Z+=`${Y}
|
|
12
|
+
`;if(Z=Z.replace(this.ANSI_PATTERN,""),this.shouldWriteToFile())await this.writeToFile(Z)}progress(I,w=""){let G={update:(Y,U)=>{},finish:(Y)=>{},interrupt:(Y,U)=>{}};if(!this.enabled)return G;let $=30;if(this.activeProgressBar={total:Math.max(1,I||1),current:0,message:w||"",barLength:$,lastRenderedLine:""},this.shouldStyleConsole()&&!y()&&T.stdout.isTTY)this.renderProgressBar(this.activeProgressBar);return{update:(Y,U)=>{if(!this.enabled||!this.activeProgressBar)return;if(this.activeProgressBar.current=Math.min(Math.max(0,Y),this.activeProgressBar.total),U!==void 0)this.activeProgressBar.message=U;if(this.shouldStyleConsole()&&!y()&&T.stdout.isTTY)this.renderProgressBar(this.activeProgressBar)},finish:(Y)=>{if(!this.activeProgressBar)return;this.finishProgressBar(this.activeProgressBar,Y)},interrupt:(Y,U="info")=>{if(!y()&&T.stdout.isTTY)T.stdout.write(`
|
|
13
|
+
`);if(this[U==="warning"?"warn":U](Y),this.activeProgressBar&&this.shouldStyleConsole()&&!y()&&T.stdout.isTTY)this.renderProgressBar(this.activeProgressBar)}}}time(I){let w=performance.now();if(this.shouldStyleConsole()){let G=this.options.showTags!==!1&&this.name?C.gray(this.formatTag(this.name)):"",$=this.formatConsoleTimestamp(new Date);console.error(this.formatConsoleMessage({timestamp:$,icon:this.options.showIcons===!1?"":C.blue("◐"),tag:G,message:`${C.cyan(I)}...`}))}return async(G)=>{if(!this.enabled)return;let $=performance.now(),A=Math.round($-w),_=`${I} completed in ${A}ms`,W=new Date,Y=this.formatConsoleTimestamp(W),H=`${this.formatFileTimestamp(W)} ${this.environment}.INFO: ${_}`;if(G)H+=` ${JSON.stringify(G)}`;if(H+=`
|
|
14
|
+
`,H=H.replace(this.ANSI_PATTERN,""),this.shouldStyleConsole()){let Z=this.options.showTags!==!1&&this.name?C.gray(this.formatTag(this.name)):"";console.error(this.formatConsoleMessage({timestamp:Y,icon:this.options.showIcons===!1?"":C.green("✓"),tag:Z,message:`${_}${G?` ${JSON.stringify(G)}`:""}`}))}else if(!y())console.error(H.trim());if(this.shouldWriteToFile())await this.writeToFile(H)}}async debug(I,...w){await this.log("debug",I,...w)}async info(I,...w){await this.log("info",I,...w)}async success(I,...w){await this.log("success",I,...w)}async warn(I,...w){await this.log("warning",I,...w)}async error(I,...w){await this.log("error",I,...w)}validateEncryptionConfig(){if(!this.config.rotation)return!1;if(typeof this.config.rotation==="boolean")return!1;let I=this.config.rotation,{encrypt:w}=I;return!!w}async only(I){if(!this.enabled)return;return await I()}isEnabled(){return this.enabled}setEnabled(I){this.enabled=I}extend(I){let w=`${this.name}:${I}`,G=new Sw(w,{...this.options,logDirectory:this.config.logDirectory,level:this.config.level,format:this.config.format,rotation:typeof this.config.rotation==="boolean"?void 0:this.config.rotation,timestamp:typeof this.config.timestamp==="boolean"?void 0:this.config.timestamp});return this.subLoggers.add(G),G}createReadStream(){if(y())throw Error("createReadStream is not supported in browser environments");if(!eI(this.currentLogFile))throw Error(`Log file does not exist: ${this.currentLogFile}`);return b$(this.currentLogFile,{encoding:"utf8"})}async decrypt(I){if(!this.validateEncryptionConfig())throw Error("Encryption is not configured");let w=this.config.rotation;if(!w.encrypt||typeof w.encrypt==="boolean")throw Error("Invalid encryption configuration");if(!this.currentKeyId||!this.keys.has(this.currentKeyId))throw Error("No valid encryption key available");let G=this.keys.get(this.currentKeyId);try{let $=_I.isBuffer(I)?I:_I.from(I,"base64"),A=$.subarray(0,16),_=$.subarray($.length-16),W=$.subarray(16,$.length-16),Y=v0("aes-256-gcm",G,A);Y.setAuthTag(_);let U=Y.update(W),H=Y.final(),Z=U.length+H.length,q=_I.allocUnsafe(Z);return U.copy(q,0),H.copy(q,U.length),q.toString("utf8")}catch($){throw Error(`Decryption failed: ${$ instanceof Error?$.message:String($)}`)}}getLevel(){return this.config.level}getLogDirectory(){return this.config.logDirectory}getFormat(){return this.config.format}getRotationConfig(){return this.config.rotation}isBrowserMode(){return y()}isServerMode(){return!y()}setTestEncryptionKey(I,w){this.currentKeyId=I,this.keys.set(I,w)}getTestCurrentKey(){if(!this.currentKeyId||!this.keys.has(this.currentKeyId))return null;return{id:this.currentKeyId,key:this.keys.get(this.currentKeyId)}}getConfig(){return this.config}async box(I){if(!this.enabled)return;let w=new Date,G=this.formatConsoleTimestamp(w),$=this.formatFileTimestamp(w),{consoleText:A,fileText:_}=this.buildOutputTexts(I);if(this.shouldStyleConsole()){let Y=A.split(`
|
|
15
|
+
`),U=Math.max(...Y.map((Q)=>Q.length))+2,H=`┌${"─".repeat(U)}┐`,Z=`└${"─".repeat(U)}┘`,q=Y.map((Q)=>{return this.formatConsoleMessage({timestamp:G,message:C.cyan(Q),showTimestamp:!1})});console.error(this.formatConsoleMessage({timestamp:G,message:C.cyan(H),showTimestamp:!1})),q.forEach((Q)=>console.error(Q)),console.error(this.formatConsoleMessage({timestamp:G,message:C.cyan(Z),showTimestamp:!1}))}else if(!y())console.error(`${$} ${this.environment}.INFO: [BOX] ${_}`);let W=`${$} ${this.environment}.INFO: [BOX] ${_}
|
|
16
|
+
`.replace(this.ANSI_PATTERN,"");if(this.shouldWriteToFile())await this.writeToFile(W)}async prompt(I){if(y())return Promise.resolve(!0);return new Promise((w)=>{console.error(`${C.cyan("?")} ${I} (y/n) `);let G=($)=>{let A=$.toString().trim().toLowerCase();T.stdin.removeListener("data",G);try{if(typeof T.stdin.setRawMode==="function")T.stdin.setRawMode(!1)}catch{}T.stdin.pause(),console.error(""),w(A==="y"||A==="yes")};try{if(typeof T.stdin.setRawMode==="function")T.stdin.setRawMode(!0)}catch{}T.stdin.resume(),T.stdin.once("data",G)})}setFancy(I){this.fancy=I}isFancy(){return this.fancy}pause(){this.enabled=!1}resume(){this.enabled=!0}async start(I,...w){if(!this.enabled)return;let G=I;if(w&&w.length>0){let U=/%([sdijfo%])/g,H=0;if(G=I.replace(U,(Z,q)=>{if(q==="%")return"%";if(H>=w.length)return Z;let Q=w[H++];switch(q){case"s":return String(Q);case"d":case"i":return Number(Q).toString();case"j":case"o":return JSON.stringify(Q,null,2);default:return Z}}),H<w.length)G+=` ${w.slice(H).map((Z)=>typeof Z==="object"?JSON.stringify(Z,null,2):String(Z)).join(" ")}`}let{consoleText:$,fileText:A}=this.buildOutputTexts(G);if(this.shouldStyleConsole()){let U=this.options.showTags!==!1&&this.name?C.gray(this.formatTag(this.name)):"",H=this.options.showIcons===!1?"":`${C.blue("◐")} `;console.error(`${H}${U} ${C.cyan($)}`)}let Y=`[${new Date().toISOString()}] ${this.environment}.INFO: [START] ${A}
|
|
17
|
+
`.replace(this.ANSI_PATTERN,"");if(this.shouldWriteToFile())await this.writeToFile(Y)}renderProgressBar(I,w=!1){if(!this.enabled||!this.shouldStyleConsole()||!T.stdout.isTTY)return;let G=Math.min(100,Math.max(0,Math.round(I.current/I.total*100))),$=Math.round(I.barLength*G/100),A=I.barLength-$,_=C.green("━".repeat($)),W=C.gray("━".repeat(A)),Y=`[${_}${W}]`,U=`${G}%`.padStart(4),H=I.message?` ${I.message}`:"",Z=this.options.showIcons===!1?"":w||G===100?C.green("✓"):C.blue("▶"),q=this.options.showTags!==!1&&this.name?` ${C.gray(this.formatTag(this.name))}`:"",Q=`\r${Z}${q} ${Y} ${U}${H}`,b=T.stdout.columns||80,X=" ".repeat(Math.max(0,b-Q.replace(this.ANSI_PATTERN,"").length));if(I.lastRenderedLine=`${Q}${X}`,T.stdout.write(I.lastRenderedLine),w)T.stdout.write(`
|
|
18
|
+
`)}finishProgressBar(I,w){if(!this.enabled||!this.fancy||y()||!T.stdout.isTTY){this.activeProgressBar=null;return}if(I.current<I.total)I.current=I.total;if(w)I.message=w;this.renderProgressBar(I,!0),this.activeProgressBar=null}async clear(I={}){if(y()){console.warn("Log clearing is not supported in browser environments.");return}try{console.warn("Clearing logs...",this.config.logDirectory);let w=await Iw(this.config.logDirectory),G=[];for(let $ of w){if(!(I.name?new RegExp(I.name.replace("*",".*")).test($):$.startsWith(this.name))||!$.endsWith(".log"))continue;let _=OI(this.config.logDirectory,$);if(I.before)try{if((await EI(_)).mtime>=I.before)continue}catch(W){console.error(`Failed to get stats for file ${_}:`,W);continue}G.push(_)}if(G.length===0){console.warn("No log files matched the criteria for clearing.");return}console.warn(`Preparing to delete ${G.length} log file(s)...`);for(let $ of G)try{await ww($),console.warn(`Deleted log file: ${$}`)}catch(A){console.error(`Failed to delete log file ${$}:`,A)}console.warn("Log clearing process finished.")}catch(w){console.error("Error during log clearing process:",w)}}}async function c$(I,w={}){let{maxRetries:G=3,retryDelay:$=1000,isRetryable:A=()=>!0,fallback:_}=w,W=Error("Unknown error occurred");for(let Y=0;Y<=G;Y++)try{return await I()}catch(U){if(W=U instanceof Error?U:Error(String(U)),Y===G||!A(W))break;if($>0)await new Promise((H)=>setTimeout(H,$))}if(_!==void 0)return _;throw W instanceof Error?W:Error(`Unknown error: ${String(W)}`)}function i$(I){return I instanceof i}function F_(I){return I instanceof Ew}function j_(I){if(i$(I))return I.code==="FILE_SYSTEM_ERROR"||I.code==="BROWSER_CONFIG_ERROR";return["ENOENT","EACCES","EMFILE","ENFILE","EBUSY","network","timeout","connection"].some((G)=>I.message.toLowerCase().includes(G.toLowerCase()))}class Vw{defaultParsers;constructor(){this.defaultParsers=[{name:"boolean",canParse:(I,w)=>w==="boolean"||["true","false","1","0","yes","no"].includes(I.toLowerCase()),parse:(I)=>{let w=I.toLowerCase();return["true","1","yes"].includes(w)}},{name:"number",canParse:(I,w)=>w==="number"||!Number.isNaN(Number(I))&&!Number.isNaN(Number.parseFloat(I)),parse:(I)=>{let w=Number(I);if(Number.isNaN(w))throw TypeError(`Cannot parse "${I}" as number`);return w}},{name:"array",canParse:(I,w)=>w==="array"||I.startsWith("[")||I.includes(","),parse:(I)=>{try{let w=JSON.parse(I);if(Array.isArray(w))return w}catch{}return I.split(",").map((w)=>w.trim())}},{name:"json",canParse:(I,w)=>w==="object"||(I.startsWith("{")&&I.endsWith("}")||I.startsWith("[")&&I.endsWith("]")),parse:(I)=>{try{return JSON.parse(I)}catch(w){throw Error(`Cannot parse "${I}" as JSON: ${w}`)}}}]}async applyEnvironmentVariables(I,w,G={}){let{prefix:$,useCamelCase:A=!0,useBackwardCompatibility:_=!0,customParsers:W={},verbose:Y=!1,trackPerformance:U=!0}=G,H=async()=>{if(!I)return{config:w,source:{type:"environment",priority:50,timestamp:new Date}};let Z=$||this.generateEnvPrefix(I),q={...w};return this.processObject(q,[],Z,{useCamelCase:A,useBackwardCompatibility:_,customParsers:W,verbose:Y,configName:I}),{config:q,source:{type:"environment",priority:50,timestamp:new Date}}};if(U)return cI.track("applyEnvironmentVariables",H,{configName:I});return H()}generateEnvPrefix(I){return I.toUpperCase().replace(/-/g,"_")}formatEnvKey(I,w){if(!w)return I.toUpperCase();return I.replace(/([A-Z])/g,"_$1").toUpperCase()}processObject(I,w,G,$){for(let[A,_]of Object.entries(I)){let W=[...w,A],Y=W.map((Z)=>this.formatEnvKey(Z,$.useCamelCase)),U=`${G}_${Y.join("_")}`,H=$.useBackwardCompatibility?`${G}_${W.map((Z)=>Z.toUpperCase()).join("_")}`:null;if($.verbose);if(typeof _==="object"&&_!==null&&!Array.isArray(_))this.processObject(_,W,G,$);else{let Z=Gw.env[U]||(H?Gw.env[H]:void 0);if(Z!==void 0){if($.verbose){let q=Gw.env[U]?U:H}try{I[A]=this.parseEnvironmentValue(Z,typeof _,U,$.customParsers,$.configName)}catch(q){if(q instanceof Ow)throw q;throw LI.envVar(U,Z,typeof _,$.configName)}}}}}parseEnvironmentValue(I,w,G,$,A){for(let[_,W]of Object.entries($))try{return W(I)}catch{continue}for(let _ of this.defaultParsers)if(_.canParse(I,w))try{return _.parse(I)}catch{throw LI.envVar(G,I,`${w} (via ${_.name} parser)`,A)}return I}getEnvironmentVariables(I){let w={},G=I.toUpperCase();for(let[$,A]of Object.entries(Gw.env))if($.startsWith(G)&&A!==void 0)w[$]=A;return w}validateEnvironmentVariable(I,w,G){let $=[];if(!/^[A-Z_][A-Z0-9_]*$/.test(I))$.push(`Environment variable key "${I}" should only contain uppercase letters, numbers, and underscores`);if(G)try{this.parseEnvironmentValue(I,w,G,{})}catch(A){$.push(`Cannot parse value "${w}" as ${G}: ${A}`)}return{isValid:$.length===0,errors:$}}generateEnvVarDocs(I,w,G={}){let{prefix:$,format:A="text"}=G,_=$||this.generateEnvPrefix(I),W=[];switch(this.extractEnvVarInfo(w,[],_,W),A){case"markdown":return this.formatAsMarkdown(W,I);case"json":return JSON.stringify(W,null,2);default:return this.formatAsText(W,I)}}extractEnvVarInfo(I,w,G,$){for(let[A,_]of Object.entries(I)){let W=[...w,A],Y=`${G}_${W.map((U)=>this.formatEnvKey(U,!0)).join("_")}`;if(typeof _==="object"&&_!==null&&!Array.isArray(_))this.extractEnvVarInfo(_,W,G,$);else $.push({key:Y,type:Array.isArray(_)?"array":typeof _,description:`Configuration for ${W.join(".")}`,example:this.generateExample(_)})}}generateExample(I){if(Array.isArray(I))return JSON.stringify(I);if(typeof I==="object"&&I!==null)return JSON.stringify(I);return String(I)}formatAsText(I,w){let G=`Environment Variables for ${w}:
|
|
19
|
+
|
|
20
|
+
`;for(let $ of I)G+=`${$.key}
|
|
21
|
+
`,G+=` Type: ${$.type}
|
|
22
|
+
`,G+=` Description: ${$.description}
|
|
23
|
+
`,G+=` Example: ${$.example}
|
|
24
|
+
|
|
25
|
+
`;return G}formatAsMarkdown(I,w){let G=`# Environment Variables for ${w}
|
|
26
|
+
|
|
27
|
+
`;G+=`| Variable | Type | Description | Example |
|
|
28
|
+
`,G+=`|----------|------|-------------|----------|
|
|
29
|
+
`;for(let $ of I)G+=`| \`${$.key}\` | ${$.type} | ${$.description} | \`${$.example}\` |
|
|
30
|
+
`;return G}}function N_(I,w){let G=a$("process");if(typeof G>"u"||!G.env)return w;let $=G.env[I];return $!==void 0?$:w}function r$(I,w,G={}){return o$(I,w,G,new WeakMap)}function o$(I,w,G,$){let{arrayMergeMode:A="replace",skipNullish:_=!1,customMerger:W}=G;if(w===null||w===void 0)return _?I:w;if(W){let Y=W(I,w);if(Y!==void 0)return Y}if(Array.isArray(w)||Array.isArray(I))return s$(I,w,A,$);if(!s(w)||!s(I))return w;return P_(I,w,G,$)}function s$(I,w,G,$){if(Array.isArray(w)&&!Array.isArray(I))return w;if(Array.isArray(I)&&!Array.isArray(w))return w;if(Array.isArray(w)&&Array.isArray(I))switch(G){case"replace":return w;case"concat":return V_(I,w);case"smart":return x_(I,w,$);default:return w}return w}function V_(I,w){let G=[...w];for(let $ of I)if(!G.some((A)=>ZG(A,$)))G.push($);return G}function x_(I,w,G){if(w.length===0)return I;if(I.length===0)return w;if(s(w[0])&&s(I[0]))return k_(I,w,G);if(w.every(($)=>typeof $==="string")&&I.every(($)=>typeof $==="string")){let $=[...w];for(let A of I)if(!$.includes(A))$.push(A);return $}return w}function k_(I,w,G){let $=[...w];for(let A of I){if(!s(A)){$.push(A);continue}let _=["id","name","key","path","type"],W=!1;for(let Y of _)if(Y in A){if($.find((H)=>s(H)&&(Y in H)&&H[Y]===A[Y])){W=!0;break}}if(!W)$.push(A)}return $}function P_(I,w,G,$){let A=w;if(s(A)&&$.has(A))return $.get(A);let _={...I};if(s(A))$.set(A,_);for(let W in A){if(!Object.prototype.hasOwnProperty.call(A,W))continue;let Y=A[W],U=_[W];if(G.skipNullish&&(Y===null||Y===void 0))continue;if(Y===null||Y===void 0){_[W]=Y;continue}if(s(Y)&&s(U))_[W]=o$(U,Y,G,$);else if(Array.isArray(Y)||Array.isArray(U))_[W]=s$(U,Y,G.arrayMergeMode||"smart",$);else _[W]=Y}return _}function EG(I,w,G="replace"){return r$(I,w,{arrayMergeMode:G==="replace"?"replace":"smart",skipNullish:!0})}function ZG(I,w){if(I===w)return!0;if(Array.isArray(I)&&Array.isArray(w)){if(I.length!==w.length)return!1;for(let G=0;G<I.length;G++)if(!ZG(I[G],w[G]))return!1;return!0}if(s(I)&&s(w)){let G=Object.keys(I),$=Object.keys(w);if(G.length!==$.length)return!1;for(let A of G){if(!Object.prototype.hasOwnProperty.call(w,A))return!1;if(!ZG(I[A],w[A]))return!1}return!0}return!1}function s(I){return Boolean(I&&typeof I==="object"&&!Array.isArray(I))}class xw{extensions=[".ts",".js",".mjs",".cjs",".json",".mts",".cts"];async loadFromPath(I,w,G={}){let{arrayStrategy:$="replace",useCache:A=!0,cacheTtl:_,trackPerformance:W=!0,verbose:Y=!1}=G;if(A){let H=VI.getWithFileCheck("file",I);if(H){if(Y)console.log(`Configuration loaded from cache: ${I}`);return H}}let U=async()=>{if(!$w(I))return null;try{let H=`?t=${Date.now()}`,Z=await import(I+H),q=Z.default||Z,Q="default"in Z,b=Object.keys(Z).length>0;if(!Q&&!b)throw new pI(I,Error("Configuration file is empty and exports nothing"),"unknown");if(typeof q!=="object"||q===null||Array.isArray(q))throw new pI(I,Error("Configuration must export a valid object"),"unknown");let J={config:EG(w,q,$),source:{type:"file",path:I,priority:100,timestamp:new Date}};if(A)VI.setWithFileCheck("file",J,I,_);return J}catch(H){throw H instanceof Error?LI.configLoad(I,H):LI.configLoad(I,Error(String(H)))}};if(W)return cI.track("loadFromPath",U,{path:I});return U()}async tryLoadFromPaths(I,w,G={}){for(let $ of I)try{let A=await this.loadFromPath($,w,G);if(A)return A}catch(A){if(A instanceof Error&&A.name==="ConfigLoadError")throw A;if(G.verbose)console.warn(`Failed to load config from ${$}:`,A)}return null}generateConfigPaths(I,w,G){let $=this.generateNamePatterns(I,G),A=[];for(let _ of $)for(let W of this.extensions)A.push(sw(w,`${_}${W}`));return A}generateNamePatterns(I,w){let G=[];if(G.push("config",".config"),I)G.push(I,`.${I}.config`,`${I}.config`,`.${I}`);if(w){if(G.push(w,`.${w}.config`,`${w}.config`,`.${w}`),I)G.push(`${I}.${w}.config`,`.${I}.${w}.config`)}return G.filter(Boolean)}checkFileAccess(I){return c$(async()=>{return $w(I)},{maxRetries:2,retryDelay:100,fallback:!1})}async discoverConfigFiles(I,w,G){let $=[];if(!$w(I))return $;if(w||G){let A=this.generateNamePatterns(w||"",G);for(let _ of A)for(let W of this.extensions){let Y=sw(I,`${_}${W}`);if(await this.checkFileAccess(Y))$.push(Y)}}else try{let{readdirSync:A}=await import("fs"),_=A(I);for(let W of _)if(this.looksLikeConfigFile(W)){let Y=sw(I,W);if(await this.checkFileAccess(Y))$.push(Y)}}catch{return[]}return $}looksLikeConfigFile(I){return[/\.config\.(ts|js|mjs|cjs|json|mts|cts)$/,/^\..*\.(ts|js|mjs|cjs|json|mts|cts)$/,/config\.(ts|js|mjs|cjs|json|mts|cts)$/].some((G)=>G.test(I))}async validateConfigFile(I){let w=[];try{if(!$w(I))return w.push("Configuration file does not exist"),w;let G=await import(I),$=G.default||G;if($===void 0)w.push("Configuration file must export a default value or named exports");else if(typeof $!=="object"||$===null)w.push("Configuration must be an object");else if(Array.isArray($))w.push("Configuration cannot be an array at the root level");if(I.endsWith(".json"))try{let{readFileSync:A}=await import("fs"),_=A(I,"utf8");JSON.parse(_)}catch(A){w.push(`Invalid JSON syntax: ${A}`)}}catch(G){w.push(`Failed to load configuration file: ${G}`)}return w}async getFileModificationTime(I){try{let{statSync:w}=await import("fs");return w(I).mtime}catch{return null}}async preloadConfigurations(I,w={}){let G=new Map;return await Promise.allSettled(I.map(async($)=>{try{let A=await this.loadFromPath($,{},w);if(A)G.set($,A.config)}catch(A){if(w.verbose)console.warn(`Failed to preload ${$}:`,A)}})),G}}class OG{async validateConfiguration(I,w,G={}){let{stopOnFirstError:$=!1,validateRequired:A=!0,validateTypes:_=!0,customRules:W=[],trackPerformance:Y=!0,verbose:U=!1}=G,H=async()=>{let Z=[],q=[],Q={stopOnFirstError:$,validateRequired:A,validateTypes:_,customRules:W,trackPerformance:Y,verbose:U};try{if(typeof w==="string")return await this.validateWithSchemaFile(I,w,Q);else if(Array.isArray(w))return this.validateWithRules(I,[...w,...W],Q);else return this.validateWithJSONSchema(I,w,Q)}catch(b){return Z.push({path:"",message:`Validation failed: ${b}`,rule:"system"}),{isValid:!1,errors:Z,warnings:q}}};if(Y)return await cI.track("validateConfiguration",H);return H()}async validateWithSchemaFile(I,w,G){try{if(!o0(w))throw new lI(w,[{path:"",message:"Schema file does not exist"}]);let $=await import(w),A=$.default||$;if(Array.isArray(A))return this.validateWithRules(I,A,G);else return this.validateWithJSONSchema(I,A,G)}catch($){throw new lI(w,[{path:"",message:`Failed to load schema: ${$}`}])}}validateWithJSONSchema(I,w,G){let $=[],A=[];return this.validateObjectAgainstSchema(I,w,"",$,A,G),{isValid:$.length===0,errors:$,warnings:A}}validateObjectAgainstSchema(I,w,G,$,A,_){if(_.validateTypes&&w.type){let W=Array.isArray(I)?"array":typeof I,Y=Array.isArray(w.type)?w.type:[w.type];if(!Y.includes(W)){if($.push({path:G,message:`Expected type ${Y.join(" or ")}, got ${W}`,expected:Y.join(" or "),actual:W,rule:"type"}),_.stopOnFirstError)return}}if(w.enum&&!w.enum.includes(I)){if($.push({path:G,message:`Value must be one of: ${w.enum.join(", ")}`,expected:w.enum.join(", "),actual:I,rule:"enum"}),_.stopOnFirstError)return}if(typeof I==="string"){if(w.minLength!==void 0&&I.length<w.minLength)$.push({path:G,message:`String length must be at least ${w.minLength}`,expected:`>= ${w.minLength}`,actual:I.length,rule:"minLength"});if(w.maxLength!==void 0&&I.length>w.maxLength)$.push({path:G,message:`String length must not exceed ${w.maxLength}`,expected:`<= ${w.maxLength}`,actual:I.length,rule:"maxLength"});if(w.pattern){if(!new RegExp(w.pattern).test(I))$.push({path:G,message:`String does not match pattern ${w.pattern}`,expected:w.pattern,actual:I,rule:"pattern"})}}if(typeof I==="number"){if(w.minimum!==void 0&&I<w.minimum)$.push({path:G,message:`Value must be at least ${w.minimum}`,expected:`>= ${w.minimum}`,actual:I,rule:"minimum"});if(w.maximum!==void 0&&I>w.maximum)$.push({path:G,message:`Value must not exceed ${w.maximum}`,expected:`<= ${w.maximum}`,actual:I,rule:"maximum"})}if(Array.isArray(I)&&w.items)for(let W=0;W<I.length;W++){let Y=G?`${G}[${W}]`:`[${W}]`;if(this.validateObjectAgainstSchema(I[W],w.items,Y,$,A,_),_.stopOnFirstError&&$.length>0)return}if(I&&typeof I==="object"&&!Array.isArray(I)){let W=I;if(_.validateRequired&&w.required){for(let Y of w.required)if(!(Y in W)){if($.push({path:G?`${G}.${Y}`:Y,message:`Missing required property '${Y}'`,expected:"required",rule:"required"}),_.stopOnFirstError)return}}if(w.properties){for(let[Y,U]of Object.entries(w.properties))if(Y in W){let H=G?`${G}.${Y}`:Y;if(this.validateObjectAgainstSchema(W[Y],U,H,$,A,_),_.stopOnFirstError&&$.length>0)return}}if(w.additionalProperties===!1){let Y=new Set(Object.keys(w.properties||{}));for(let U of Object.keys(W))if(!Y.has(U))A.push({path:G?`${G}.${U}`:U,message:`Additional property '${U}' is not allowed`,rule:"additionalProperties"})}}}validateWithRules(I,w,G){let $=[],A=[];for(let _ of w)try{let W=this.getValueByPath(I,_.path),Y=this.validateWithRule(W,_,_.path);if($.push(...Y),G.stopOnFirstError&&$.length>0)break}catch(W){$.push({path:_.path,message:`Rule validation failed: ${W}`,rule:"system"})}return{isValid:$.length===0,errors:$,warnings:A}}validateWithRule(I,w,G){let $=[];if(w.required&&(I===void 0||I===null))return $.push({path:G,message:w.message||`Property '${G}' is required`,expected:"required",rule:"required"}),$;if(I===void 0||I===null)return $;if(w.type){let A=Array.isArray(I)?"array":typeof I;if(A!==w.type)$.push({path:G,message:w.message||`Expected type ${w.type}, got ${A}`,expected:w.type,actual:A,rule:"type"})}if(w.min!==void 0){let A=Array.isArray(I)?I.length:typeof I==="string"?I.length:typeof I==="number"?I:0;if(A<w.min)$.push({path:G,message:w.message||`Value must be at least ${w.min}`,expected:`>= ${w.min}`,actual:A,rule:"min"})}if(w.max!==void 0){let A=Array.isArray(I)?I.length:typeof I==="string"?I.length:typeof I==="number"?I:0;if(A>w.max)$.push({path:G,message:w.message||`Value must not exceed ${w.max}`,expected:`<= ${w.max}`,actual:A,rule:"max"})}if(w.pattern&&typeof I==="string"){if(!w.pattern.test(I))$.push({path:G,message:w.message||`Value does not match pattern ${w.pattern}`,expected:w.pattern.toString(),actual:I,rule:"pattern"})}if(w.enum&&!w.enum.includes(I))$.push({path:G,message:w.message||`Value must be one of: ${w.enum.join(", ")}`,expected:w.enum.join(", "),actual:I,rule:"enum"});if(w.validator){let A=w.validator(I);if(A)$.push({path:G,message:w.message||A,rule:"custom"})}return $}getValueByPath(I,w){if(!w)return I;let G=w.split("."),$=I;for(let A of G)if($&&typeof $==="object"&&A in $)$=$[A];else return;return $}generateRulesFromInterface(I){let w=[],G=I.matchAll(/(\w+)(\?)?:\s*(\w+)/g);for(let $ of G){let[,A,_,W]=$;w.push({path:A,required:!_,type:this.mapTypeScriptType(W)})}return w}mapTypeScriptType(I){switch(I.toLowerCase()){case"string":return"string";case"number":return"number";case"boolean":return"boolean";case"array":return"array";case"object":return"object";default:return"object"}}static createCommonRules(){return{server:[{path:"port",required:!0,type:"number",min:1,max:65535},{path:"host",required:!0,type:"string",min:1},{path:"ssl",type:"boolean"}],database:[{path:"url",required:!0,type:"string",min:1},{path:"pool",type:"number",min:1,max:100},{path:"timeout",type:"number",min:0}],api:[{path:"baseUrl",required:!0,type:"string",pattern:$A},{path:"timeout",type:"number",min:0},{path:"retries",type:"number",min:0,max:10}]}}}class zG{fileLoader=new xw;envProcessor=new Vw;validator=new OG;async loadConfig(I){let w=Date.now(),{cache:G,performance:$,schema:A,validate:_,...W}=I;try{if(G?.enabled){let U=this.checkCache(W.name||"",W);if(U)return U}let Y;try{Y=await this.loadConfigurationStrategies(W,!0,G)}catch(U){let H=W.__strictErrorHandling;if(U instanceof Error&&U.name==="ConfigNotFoundError"){if(H)throw U;Y={...await this.applyEnvironmentVariables(W.name||"",W.defaultConfig,W.checkEnv!==!1,W.verbose||!1),warnings:[`No configuration file found for "${W.name||"config"}", using defaults with environment variables`]}}else if(U instanceof Error&&U.name==="ConfigLoadError"){let Z=U.message.includes("EACCES")||U.message.includes("EPERM")||U.message.includes("permission denied"),q=!Z&&(U.message.includes("syntax")||U.message.includes("Expected")||U.message.includes("Unexpected")||U.message.includes("BuildMessage")||U.message.includes("errors building")),Q=U.message.includes("Configuration must export a valid object")||U.message.includes("Configuration file is empty and exports nothing");if(H&&(Q||Z))throw U;if(q&&(!H||!Q))Y={...await this.applyEnvironmentVariables(W.name||"",W.defaultConfig,W.checkEnv!==!1,W.verbose||!1),warnings:["Configuration file has syntax errors, using defaults with environment variables"]};else if(!H)Y={...await this.applyEnvironmentVariables(W.name||"",W.defaultConfig,W.checkEnv!==!1,W.verbose||!1),warnings:[`Configuration loading error, using defaults: ${U.message}`]};else throw U}else Y={...await this.applyEnvironmentVariables(W.name||"",W.defaultConfig,W.checkEnv!==!1,W.verbose||!1),warnings:[`Configuration loading failed, using defaults: ${U instanceof Error?U.message:String(U)}`]}}if(A||_)await this.validateConfiguration(Y.config,A,_,W.name);if(G?.enabled&&Y)this.cacheResult(W.name||"",Y,G,W);if($?.enabled){let U={operation:"loadConfig",duration:Date.now()-w,configName:W.name,timestamp:new Date};if($.onMetrics)$.onMetrics(U);if($.slowThreshold&&U.duration>$.slowThreshold)e.warn(`Slow configuration loading detected: ${U.duration}ms for ${W.name}`);Y.metrics=U}return Y}catch(Y){let U=Date.now()-w;throw e.error(`Configuration loading failed after ${U}ms:`,[Y instanceof Error?Y:Error(String(Y))]),Y}}async loadConfigurationStrategies(I,w=!1,G){let{name:$="",alias:A,cwd:_,configDir:W,defaultConfig:Y,checkEnv:U=!0,arrayStrategy:H="replace",verbose:Z=!1}=I,q=_||BI.cwd(),Q=[],b=await this.loadLocalConfiguration($,A,q,W,Y,H,Z,U,G);if(b)return Q.push(...this.getLocalSearchPaths($,A,q,W)),this.finalizeResult(b,Q,U,$,Z);let X=await this.loadHomeConfiguration($,A,Y,H,Z,U);if(X)return Q.push(...this.getHomeSearchPaths($,A)),this.finalizeResult(X,Q,U,$,Z);let L=await this.loadPackageJsonConfiguration($,A,q,Y,H,Z,U);if(L)return Q.push(l(q,"package.json")),this.finalizeResult(L,Q,U,$,Z);if(Q.push(...this.getAllSearchPaths($,A,q,W)),w)throw LI.configNotFound($,Q,A);return{...await this.applyEnvironmentVariables($,Y,U,Z),warnings:[`No configuration file found for "${$}"${A?` or alias "${A}"`:""}, using defaults with environment variables`]}}async loadLocalConfiguration(I,w,G,$,A,_,W,Y,U){let H=Y?gI(I,A,W):A,Z=this.getLocalDirectories(G,$);for(let q of Z){if(W)e.info(`Searching for configuration in: ${q}`);let Q=this.fileLoader.generateConfigPaths(I,q,w),b=await this.fileLoader.tryLoadFromPaths(Q,H,{arrayStrategy:_,verbose:W,cacheTtl:U?.ttl,useCache:!U?.ttl||U.ttl>100});if(b){if(W)e.success(`Configuration loaded from: ${b.source.path}`);return b}}return null}async loadHomeConfiguration(I,w,G,$,A,_){if(!I)return null;let W=_?gI(I,G,A):G,Y=[l(TI(),".config",I),l(TI(),".config"),TI()];for(let U of Y){if(A)e.info(`Checking home directory: ${U}`);let H=this.fileLoader.generateConfigPaths(I,U,w),Z=await this.fileLoader.tryLoadFromPaths(H,W,{arrayStrategy:$,verbose:A});if(Z){if(A)e.success(`Configuration loaded from home directory: ${Z.source.path}`);return Z}}return null}async loadPackageJsonConfiguration(I,w,G,$,A,_,W){let Y=W?gI(I,$,_):$;try{let U=l(G,"package.json");if(!UG(U))return null;let H=await import(U),Z=H[I],q=I;if(!Z&&w)Z=H[w],q=w;if(Z&&typeof Z==="object"&&!Array.isArray(Z)){if(_)e.success(`Configuration loaded from package.json: ${q}`);return{config:EG(Y,Z,A),source:{type:"package.json",path:U,priority:30,timestamp:new Date}}}}catch(U){if(_)e.warn("Failed to load package.json:",[U instanceof Error?U:Error(String(U))])}return null}async applyEnvironmentVariables(I,w,G,$){if(!G||!I||typeof w!=="object"||w===null||Array.isArray(w))return{config:w,source:{type:"default",priority:10,timestamp:new Date}};return{config:gI(I,w,$),source:{type:"environment",priority:20,timestamp:new Date}}}async finalizeResult(I,w,G,$,A){return{config:I.config,source:I.source,path:I.source.path}}async validateConfiguration(I,w,G,$){let A=[];if(G){let _=G(I);if(_)A.push(..._)}if(w){let _=await this.validator.validateConfiguration(I,w);if(!_.isValid)A.push(..._.errors.map((W)=>W.path?`${W.path}: ${W.message}`:W.message))}if(A.length>0)throw LI.configValidation($||"unknown",A,$)}checkCache(I,w){let G=this.generateCacheKey(I,w);return VI.get(G)||null}cacheResult(I,w,G,$){let A=this.generateCacheKey(I,$);VI.set(A,w,void 0,G.ttl)}generateCacheKey(I,w){let G=[I];if(w.alias)G.push(`alias:${w.alias}`);if(w.cwd)G.push(`cwd:${w.cwd}`);if(w.configDir)G.push(`configDir:${w.configDir}`);if("checkEnv"in w)G.push(`checkEnv:${w.checkEnv}`);return G.join("|")}getLocalDirectories(I,w){return Array.from(new Set([I,l(I,"config"),l(I,".config"),w?l(I,w):void 0].filter(Boolean)))}getAllSearchPaths(I,w,G,$){let A=[];return A.push(...this.getLocalSearchPaths(I,w,G,$)),A.push(...this.getHomeSearchPaths(I,w)),A.push(l(G,"package.json")),A}getLocalSearchPaths(I,w,G,$){let A=this.getLocalDirectories(G,$),_=[];for(let W of A)_.push(...this.fileLoader.generateConfigPaths(I,W,w));return _}getHomeSearchPaths(I,w){if(!I)return[];let G=[l(TI(),".config",I),l(TI(),".config"),TI()],$=[];for(let A of G)$.push(...this.fileLoader.generateConfigPaths(I,A,w));return $}async loadConfigWithResult(I){return this.loadConfig(I)}}function O$(I){let G=!(I.message.includes("EACCES")||I.message.includes("EPERM")||I.message.includes("permission denied"))&&(I.message.includes("syntax")||I.message.includes("Expected")||I.message.includes("Unexpected")||I.message.includes("BuildMessage")),$=I.message.includes("Configuration must export a valid object")||I.message.includes("Configuration file is empty and exports nothing");return G||$}async function y_(I){return ZI.loadConfig({...I,__strictErrorHandling:!0})}async function t$(I){let w="defaultConfig"in I&&I.defaultConfig!==void 0?I.defaultConfig:{},G="cache"in I||"performance"in I||"schema"in I||"validate"in I;try{let $;if(G)$=await ZI.loadConfig(I);else $=await ZI.loadConfig({...I,defaultConfig:w,cache:{enabled:!0},performance:{enabled:!1}});return $?.config??w}catch($){let A=$ instanceof Error?$.name:"UnknownError",_=$ instanceof Error?$.message:String($);if(!(A==="ConfigNotFoundError"||A==="ConfigLoadError"||A==="ConfigValidationError"||_.includes("config"))&&I.verbose)e.warn("Unexpected error loading config, using defaults:",[$ instanceof Error?$:Error(String($))]);let Y=G?{...I,defaultConfig:w}:{...I,defaultConfig:w,cache:{enabled:!0},performance:{enabled:!1}};if("checkEnv"in I?I.checkEnv!==!1:!0)return(await ZI.applyEnvironmentVariables(Y.name||"",w,!0,Y.verbose||!1))?.config??w;return w}}async function u_(I={defaultConfig:{}}){if(typeof I==="string"){let{cwd:w}=await import("process");try{return(await ZI.loadConfig({name:I,cwd:w(),generatedDir:"./generated",configDir:"./config",defaultConfig:{},checkEnv:!0,arrayStrategy:"replace"})).config}catch(G){if(G instanceof Error&&(G.name==="ConfigNotFoundError"||G.name==="ConfigLoadError"&&O$(G)))return(await ZI.applyEnvironmentVariables(I,{},!0,!1)).config;throw G}}try{return(await ZI.loadConfig({...I,cwd:I.cwd||BI.cwd(),cache:{enabled:!0},performance:{enabled:!1}})).config}catch(w){if(w instanceof Error&&(w.name==="ConfigNotFoundError"||w.name==="ConfigLoadError"&&O$(w)))return(await ZI.applyEnvironmentVariables(I.name||"",I.defaultConfig||{},I.checkEnv!==!1,I.verbose||!1)).config;throw w}}async function m_(I,w,G="replace"){let $=new xw;try{let A=await $.loadFromPath(I,w,{arrayStrategy:G,useCache:!1,trackPerformance:!1});return A?A.config:null}catch{return null}}function gI(I,w,G=!1){let $=new Vw,A=I.toUpperCase().replace(/[^A-Z0-9]/g,"_");function _(W,Y=[]){let U={...W};for(let[H,Z]of Object.entries(W)){let q=[...Y,H],Q=[`${A}_${q.join("_").toUpperCase()}`,`${A}_${q.map((L)=>L.toUpperCase()).join("")}`,`${A}_${q.map((L)=>L.replace(/([A-Z])/g,"_$1").toUpperCase()).join("")}`],b,X;for(let L of Q)if(b=BI.env[L],b!==void 0){X=L;break}if(b!==void 0&&X)if(typeof Z==="boolean")U[H]=["true","1","yes"].includes(b.toLowerCase());else if(typeof Z==="number"){let L=Number(b);if(!Number.isNaN(L))U[H]=L}else if(Array.isArray(Z))try{U[H]=JSON.parse(b)}catch{U[H]=b.split(",").map((L)=>L.trim())}else U[H]=b;else if(Z&&typeof Z==="object"&&!Array.isArray(Z))U[H]=_(Z,q)}return U}return _(w)}function h_(I){let w=l(BI.cwd(),I.configDir),G=l(BI.cwd(),I.generatedDir),$=l(G,"config-types.ts");if(!UG($$($)))O0($$($),{recursive:!0,mode:511});let A=UG(w)?z0(w).map((W)=>W.replace(/\.(ts|js|mjs|cjs|mts|cts|json)$/,"")).sort():[],_=`// Generated by bunfig v${QW}
|
|
31
|
+
export type ConfigNames = ${A.length?`'${A.join("' | '")}'`:"string"}
|
|
32
|
+
`;F0($,_,{mode:438})}function n_(I){let w=null,G=null,$=()=>{if(!G)G=t$(I).then((_)=>{return w=_,_},(_)=>{let W="defaultConfig"in I?I.defaultConfig:{};if(w=W,"verbose"in I&&I.verbose)e.warn("Config loading failed, using defaults:",[_ instanceof Error?_:Error(String(_))]);return W});return G},A="defaultConfig"in I?I.defaultConfig:{};return w=A,$(),new Proxy({},{get(_,W){if(w)return w[W];let Y=A[W];return $(),Y},has(_,W){return W in(w||A)},ownKeys(){return Object.keys(w||A)},getOwnPropertyDescriptor(_,W){return Object.getOwnPropertyDescriptor(w||A,W)},set(_,W,Y){if(!w)w={...A};return w[W]=Y,!0}})}function f_(I){let w=D$(a0.cwd(),I?.configDir||"./config");function G(){if(!s0(w))return[];let A=new Set([".ts",".js",".mjs",".cjs",".mts",".cts",".json"]),_=[".ts",".mts",".cts",".js",".mjs",".cjs",".json"],W=t0(w).filter((U)=>A.has(tw(U))).map((U)=>({base:U.replace(/\.(?:ts|js|mjs|cjs|mts|cts|json)$/i,""),file:U})),Y=new Map;for(let{base:U,file:H}of W){let Z=tw(H).toLowerCase(),q=Y.get(U);if(!q){Y.set(U,H);continue}let Q=tw(q).toLowerCase();if(_.indexOf(Z)<_.indexOf(Q))Y.set(U,H)}return Array.from(Y.entries()).map(([U,H])=>({base:U,file:H})).sort((U,H)=>U.base.localeCompare(H.base))}function $(){let A=G(),_=A.map((H)=>H.base),W=_.length?_.map((H)=>`'${H}'`).join(" | "):"string",Y=A.length?`{
|
|
33
|
+
${A.map((H)=>{let Z=D$(w,H.file).replace(/\\/g,"/");return` '${H.base}': typeof import('${Z}').default`}).join(`,
|
|
34
|
+
`)}
|
|
35
|
+
}`:"Record<string, any>";return`export type ConfigNames = ${W}
|
|
36
|
+
export type ConfigByName = ${Y}
|
|
37
|
+
export type Config<N extends ConfigNames> = N extends keyof ConfigByName ? ConfigByName[N] : unknown
|
|
38
|
+
export type ConfigOf = Config
|
|
39
|
+
`}return{name:"bunfig-plugin",setup(A){A.onResolve({filter:/^virtual:bunfig-types$/},(_)=>{return{path:_.path,namespace:"bunfig-virtual"}}),A.onLoad({filter:/^virtual:bunfig-types$/,namespace:"bunfig-virtual"},()=>{return{contents:$(),loader:"ts"}})}}}var a$,VI,cI,e$,v_,g_,z$,bw,qG,g,N,d_,F$,p_,j$,l_,c_,wG,i_,N$,V$,GG,r_,o_,s_,t_,Qw,IA,a_,d,e_,IW,x$,Lw,bG,u,C,wW,k$,GW,P$,$W,AW,$G,_W,y$,u$,WW,AG,YW,UW,HW,ZW,qW,Xw,wA,bW,QW="0.15.6",i,Ew,pI,QG,LG,Ow,XG,JG,lI,BG,DG,LI,GA,$A,e,ZI,AA,_A,LW=L_(async()=>{a$=import.meta.require,VI=new TG,cI=new MG,e$={createKey:X_,isEquivalent:J_,estimateMemoryUsage:B_},v_=Rw(HG.cwd(),"config"),g_=Rw(HG.cwd(),"src/generated"),z$=Dw.env.CLARITY_LOG_DIR||V0(K_(),"logs"),bw={level:"info",defaultName:"clarity",timestamp:!0,colors:!0,format:"text",maxLogSize:10485760,logDatePattern:"YYYY-MM-DD",logDirectory:z$,rotation:{frequency:"daily",maxSize:10485760,maxFiles:5,compress:!1,rotateHour:0,rotateMinute:0,rotateDayOfWeek:0,rotateDayOfMonth:1,encrypt:!1},verbose:!1},qG=await T_(),g={red:(I)=>`\x1B[31m${I}\x1B[0m`,green:(I)=>`\x1B[32m${I}\x1B[0m`,yellow:(I)=>`\x1B[33m${I}\x1B[0m`,blue:(I)=>`\x1B[34m${I}\x1B[0m`,magenta:(I)=>`\x1B[35m${I}\x1B[0m`,cyan:(I)=>`\x1B[36m${I}\x1B[0m`,white:(I)=>`\x1B[37m${I}\x1B[0m`,gray:(I)=>`\x1B[90m${I}\x1B[0m`,bgRed:(I)=>`\x1B[41m${I}\x1B[0m`,bgYellow:(I)=>`\x1B[43m${I}\x1B[0m`,bold:(I)=>`\x1B[1m${I}\x1B[0m`,dim:(I)=>`\x1B[2m${I}\x1B[0m`,italic:(I)=>`\x1B[3m${I}\x1B[0m`,underline:(I)=>`\x1B[4m${I}\x1B[0m`,reset:"\x1B[0m"},N=g,d_=g.red,F$=g.green,p_=g.yellow,j$=g.blue,l_=g.magenta,c_=g.cyan,wG=g.white,i_=g.gray,N$=g.bgRed,V$=g.bgYellow,GG=g.bold,r_=g.dim,o_=g.italic,s_=g.underline,t_=g.reset,Qw={activationLevel:"error",bufferSize:50,flushOnDeactivation:!0,stopBuffering:!1},IA={debug:"\uD83D\uDD0D",info:j$("ℹ"),success:F$("✓"),warning:V$(wG(GG(" WARN "))),error:N$(wG(GG(" ERROR ")))},a_=new Mw("stacks"),d=new Mw("bunfig",{showTags:!0}),e_=p(dI.cwd(),"config"),IW=p(dI.cwd(),"src/generated"),x$=Bw.env.CLARITY_LOG_DIR||j0(E_(),"logs"),Lw={level:"info",defaultName:"clarity",timestamp:!0,colors:!0,format:"text",maxLogSize:10485760,logDatePattern:"YYYY-MM-DD",logDirectory:x$,rotation:{frequency:"daily",maxSize:10485760,maxFiles:5,compress:!1,rotateHour:0,rotateMinute:0,rotateDayOfWeek:0,rotateDayOfMonth:1,encrypt:!1},verbose:!1,writeToFile:!1},bG=await O_(),u={red:(I)=>`\x1B[31m${I}\x1B[0m`,green:(I)=>`\x1B[32m${I}\x1B[0m`,yellow:(I)=>`\x1B[33m${I}\x1B[0m`,blue:(I)=>`\x1B[34m${I}\x1B[0m`,magenta:(I)=>`\x1B[35m${I}\x1B[0m`,cyan:(I)=>`\x1B[36m${I}\x1B[0m`,white:(I)=>`\x1B[37m${I}\x1B[0m`,gray:(I)=>`\x1B[90m${I}\x1B[0m`,bgRed:(I)=>`\x1B[41m${I}\x1B[0m`,bgYellow:(I)=>`\x1B[43m${I}\x1B[0m`,bgGray:(I)=>`\x1B[100m${I}\x1B[0m`,bold:(I)=>`\x1B[1m${I}\x1B[0m`,dim:(I)=>`\x1B[2m${I}\x1B[0m`,italic:(I)=>`\x1B[3m${I}\x1B[0m`,underline:(I)=>`\x1B[4m${I}\x1B[0m`,strikethrough:(I)=>`\x1B[9m${I}\x1B[0m`,reset:"\x1B[0m"},C=u,wW=u.red,k$=u.green,GW=u.yellow,P$=u.blue,$W=u.magenta,AW=u.cyan,$G=u.white,_W=u.gray,y$=u.bgRed,u$=u.bgYellow,WW=u.bgGray,AG=u.bold,YW=u.dim,UW=u.italic,HW=u.underline,ZW=u.strikethrough,qW=u.reset,Xw={activationLevel:"error",bufferSize:50,flushOnDeactivation:!0,stopBuffering:!1},wA={debug:"\uD83D\uDD0D",info:P$("ℹ"),success:k$("✓"),warning:u$($G(AG(" WARN "))),error:y$($G(AG(" ERROR ")))},bW=new Sw("stacks"),i=class extends Error{timestamp;context;constructor(w,G={}){super(w);if(this.name=this.constructor.name,this.timestamp=new Date,this.context=G,Error.captureStackTrace)Error.captureStackTrace(this,this.constructor)}toJSON(){return{name:this.name,code:this.code,message:this.message,timestamp:this.timestamp.toISOString(),context:this.context,stack:this.stack}}toString(){let w=Object.keys(this.context).length>0?` (${Object.entries(this.context).map(([G,$])=>`${G}: ${$}`).join(", ")})`:"";return`${this.name} [${this.code}]: ${this.message}${w}`}},Ew=class extends i{code="CONFIG_NOT_FOUND";constructor(w,G,$){let A=$?` or alias "${$}"`:"";super(`Configuration "${w}"${A} not found`,{configName:w,alias:$,searchPaths:G,searchPathCount:G.length})}},pI=class extends i{code="CONFIG_LOAD_ERROR";constructor(w,G,$){super(`Failed to load configuration from "${w}": ${G.message}`,{configPath:w,configName:$,originalError:G.name,originalMessage:G.message});this.cause=G}},QG=class extends i{code="CONFIG_VALIDATION_ERROR";constructor(w,G,$){super(`Configuration validation failed for "${w}"`,{configPath:w,configName:$,validationErrors:G,errorCount:G.length})}},LG=class extends i{code="CONFIG_MERGE_ERROR";constructor(w,G,$,A){super(`Failed to merge configuration from "${w}" with "${G}": ${$.message}`,{sourcePath:w,targetPath:G,configName:A,originalError:$.name,originalMessage:$.message});this.cause=$}},Ow=class extends i{code="ENV_VAR_ERROR";constructor(w,G,$,A){super(`Failed to parse environment variable "${w}" with value "${G}" as ${$}`,{envKey:w,envValue:G,expectedType:$,configName:A})}},XG=class extends i{code="FILE_SYSTEM_ERROR";constructor(w,G,$){super(`File system ${w} failed for "${G}": ${$.message}`,{operation:w,path:G,originalError:$.name,originalMessage:$.message});this.cause=$}},JG=class extends i{code="TYPE_GENERATION_ERROR";constructor(w,G,$){super(`Failed to generate types from "${w}" to "${G}": ${$.message}`,{configDir:w,outputPath:G,originalError:$.name,originalMessage:$.message});this.cause=$}},lI=class extends i{code="SCHEMA_VALIDATION_ERROR";constructor(w,G,$){super(`Schema validation failed${$?` for config "${$}"`:""}`,{schemaPath:w,configName:$,validationErrors:G,errorCount:G.length})}},BG=class extends i{code="BROWSER_CONFIG_ERROR";constructor(w,G,$,A){super(`Failed to fetch configuration from "${w}": ${G} ${$}`,{endpoint:w,status:G,statusText:$,configName:A})}},DG=class extends i{code="PLUGIN_ERROR";constructor(w,G,$){super(`Plugin "${w}" failed during ${G}: ${$.message}`,{pluginName:w,operation:G,originalError:$.name,originalMessage:$.message});this.cause=$}},LI={configNotFound(I,w,G){return new Ew(I,w,G)},configLoad(I,w,G){return new pI(I,w,G)},configValidation(I,w,G){return new QG(I,w,G)},configMerge(I,w,G,$){return new LG(I,w,G,$)},envVar(I,w,G,$){return new Ow(I,w,G,$)},fileSystem(I,w,G){return new XG(I,w,G)},typeGeneration(I,w,G){return new JG(I,w,G)},schemaValidation(I,w,G){return new lI(I,w,G)},browserConfig(I,w,G,$){return new BG(I,w,G,$)},plugin(I,w,G){return new DG(I,w,G)}},GA={replace:"replace",concat:"concat",smart:"smart"},$A=/^https?:\/\//,e=new Sw("bunfig",{showTags:!0}),ZI=new zG,AA=l(BI.cwd(),"config"),_A=l(BI.cwd(),"src/generated")});function XW(I,w={}){let G=Kw.cwd();while(G.includes("storage"))G=R$(G,"..");let $=R$(G,I||"");if(w?.relative)return I_(Kw.cwd(),$);return $}var JW=Kw.env.CLARITY_LOG_DIR||e0(XW(),"logs"),WA={level:"info",defaultName:"clarity",timestamp:!0,colors:!0,format:"text",maxLogSize:10485760,logDatePattern:"YYYY-MM-DD",logDirectory:JW,rotation:{frequency:"daily",maxSize:10485760,maxFiles:5,compress:!1,rotateHour:0,rotateMinute:0,rotateDayOfWeek:0,rotateDayOfMonth:1,encrypt:!1},verbose:!1,writeToFile:!1},zw={...WA},w1=(async()=>{try{let{loadConfig:I}=await LW().then(()=>d$),w=await I({name:"clarity",alias:"logging",defaultConfig:WA,cwd:Kw.cwd()});if(w)Object.assign(zw,w)}catch{}return zw})();function m(){if(HI.env.NODE_ENV==="test"||HI.env.BUN_ENV==="test")return!1;return typeof window<"u"}async function BW(){if(HI.env.NODE_ENV==="test"||HI.env.BUN_ENV==="test")return!0;if(typeof navigator<"u"&&navigator.product==="ReactNative")return!0;if(typeof HI<"u"){let I=HI.type;if(I==="renderer"||I==="worker")return!1;return!!(HI.versions&&(HI.versions.node||HI.versions.bun))}return!1}class YA{async format(I){let w=await BW(),G=await this.getMetadata(w);return JSON.stringify({timestamp:I.timestamp.toISOString(),level:I.level,name:I.name,message:I.message,metadata:G})}async getMetadata(I){if(I){let{hostname:w}=await import("os");return{pid:NI.pid,hostname:w(),environment:NI.env.NODE_ENV||"development",platform:NI.platform,version:NI.version}}return{userAgent:navigator.userAgent,hostname:window.location.hostname||"browser",environment:NI.env.NODE_ENV||NI.env.BUN_ENV||"development",viewport:{width:window.innerWidth,height:window.innerHeight},language:navigator.language}}}var h={red:(I)=>`\x1B[31m${I}\x1B[0m`,green:(I)=>`\x1B[32m${I}\x1B[0m`,yellow:(I)=>`\x1B[33m${I}\x1B[0m`,blue:(I)=>`\x1B[34m${I}\x1B[0m`,magenta:(I)=>`\x1B[35m${I}\x1B[0m`,cyan:(I)=>`\x1B[36m${I}\x1B[0m`,white:(I)=>`\x1B[37m${I}\x1B[0m`,gray:(I)=>`\x1B[90m${I}\x1B[0m`,bgRed:(I)=>`\x1B[41m${I}\x1B[0m`,bgYellow:(I)=>`\x1B[43m${I}\x1B[0m`,bgGray:(I)=>`\x1B[100m${I}\x1B[0m`,bold:(I)=>`\x1B[1m${I}\x1B[0m`,dim:(I)=>`\x1B[2m${I}\x1B[0m`,italic:(I)=>`\x1B[3m${I}\x1B[0m`,underline:(I)=>`\x1B[4m${I}\x1B[0m`,strikethrough:(I)=>`\x1B[9m${I}\x1B[0m`,reset:"\x1B[0m"},S=h,G1=h.red,DW=h.green,$1=h.yellow,RW=h.blue,A1=h.magenta,_1=h.cyan,m$=h.white,W1=h.gray,KW=h.bgRed,TW=h.bgYellow,Y1=h.bgGray,h$=h.bold,U1=h.dim,H1=h.italic,Z1=h.underline,q1=h.strikethrough,b1=h.reset,_G={activationLevel:"error",bufferSize:50,flushOnDeactivation:!0,stopBuffering:!1},MW={debug:"\uD83D\uDD0D",info:RW("ℹ"),success:DW("✓"),warning:TW(m$(h$(" WARN "))),error:KW(m$(h$(" ERROR ")))};class kw{name;fileLocks=new Map;currentKeyId=null;keys=new Map;fingersCrossedConfig;fingersCrossedActive=!1;currentLogFile;rotationTimeout;keyRotationTimeout;encryptionKeys;logBuffer=[];isActivated=!1;pendingOperations=[];enabled;fancy;tagFormat;timestampPosition;environment;config;options;formatter;timers=new Set;subLoggers=new Set;fingersCrossedBuffer=[];ANSI_PATTERN=/\u001B\[.*?m/g;activeProgressBar=null;constructor(I,w={}){this.name=I,this.config={...zw},this.options=this.normalizeOptions(w),this.formatter=this.options.formatter||new YA,this.enabled=w.enabled??!0,this.fancy=w.fancy??!0,this.tagFormat=w.tagFormat??{prefix:"[",suffix:"]"},this.timestampPosition=w.timestampPosition??"right",this.environment=w.environment??M.env.APP_ENV??"local",this.fingersCrossedConfig=this.initializeFingersCrossedConfig(w);let G={...w},$=w.timestamp!==void 0;if($)delete G.timestamp;if(this.config={...this.config,...G,timestamp:$||this.config.timestamp,level:this.options.level??"info"},this.currentLogFile=this.generateLogFilename(),this.encryptionKeys=new Map,this.validateEncryptionConfig()){this.setupRotation();let A=this.generateKeyId(),_=this.generateKey();this.currentKeyId=A,this.keys.set(A,_),this.encryptionKeys.set(A,{key:_,createdAt:new Date}),this.setupKeyRotation()}}shouldActivateFingersCrossed(I){if(!this.fingersCrossedConfig)return!1;let w={debug:0,info:1,success:2,warning:3,error:4},G=this.fingersCrossedConfig.activationLevel??"error";return w[I]>=w[G]}initializeFingersCrossedConfig(I){if(!I.fingersCrossedEnabled&&I.fingersCrossed)return{..._G,...I.fingersCrossed};if(!I.fingersCrossedEnabled)return null;if(!I.fingersCrossed)return{..._G};return{..._G,...I.fingersCrossed}}normalizeOptions(I){let w={format:"json",level:"info",logDirectory:zw.logDirectory,rotation:void 0,timestamp:void 0,fingersCrossed:{},enabled:!0,showTags:!1,showIcons:!0,formatter:void 0},G={...w,...Object.fromEntries(Object.entries(I).filter(([,$])=>$!==void 0))};if(!G.level||!["debug","info","success","warning","error"].includes(G.level))G.level=w.level;return G}shouldWriteToFile(){return!m()&&this.config.writeToFile===!0}async writeToFile(I){let G=(async()=>{let A,_=0,W=3,Y=1000;while(_<W)try{try{try{await __(this.config.logDirectory,C$.F_OK|C$.W_OK)}catch(H){if(H instanceof Error&&"code"in H)if(H.code==="ENOENT")await W_(this.config.logDirectory,{recursive:!0,mode:493});else if(H.code==="EACCES")throw Error(`No write permission for log directory: ${this.config.logDirectory}`);else throw H;else throw H}}catch(H){throw console.error("Debug: [writeToFile] Failed to create log directory:",H),H}let U=this.validateEncryptionConfig()?(await this.encrypt(I)).encrypted:WI.from(I);try{if(!Aw(this.currentLogFile))await IG(this.currentLogFile,"",{mode:420});if(A=M$(this.currentLogFile,"a",420),A_(A,U,{flag:"a"}),T$(A),A!==void 0)ew(A),A=void 0;if((await FI(this.currentLogFile)).size===0){if(await IG(this.currentLogFile,U,{flag:"w",mode:420}),(await FI(this.currentLogFile)).size===0)throw Error("File exists but is empty after retry write")}return}catch(H){let Z=H;if(Z.code&&["ENETDOWN","ENETUNREACH","ENOTFOUND","ETIMEDOUT"].includes(Z.code)){if(_<W-1){let q=typeof Z.message==="string"?Z.message:"Unknown error";console.error(`Network error during write attempt ${_+1}/${W}:`,q);let Q=Y*2**_;await new Promise((b)=>setTimeout(b,Q)),_++;continue}}if(Z?.code&&["ENOSPC","EDQUOT"].includes(Z.code))throw Error(`Disk quota exceeded or no space left on device: ${Z.message}`);throw console.error("Debug: [writeToFile] Error writing to file:",Z),Z}finally{if(A!==void 0)try{ew(A)}catch(H){console.error("Debug: [writeToFile] Error closing file descriptor:",H)}}}catch(U){if(_===W-1){let Z=U,q=typeof Z.message==="string"?Z.message:"Unknown error";throw console.error("Debug: [writeToFile] Max retries reached. Final error:",q),U}_++;let H=Y*2**(_-1);await new Promise((Z)=>setTimeout(Z,H))}})();this.pendingOperations.push(G);let $=this.pendingOperations.length-1;try{await G}catch(A){throw console.error("Debug: [writeToFile] Error in operation:",A),A}finally{this.pendingOperations.splice($,1)}}generateLogFilename(){if(this.name.includes("stream-throughput")||this.name.includes("decompress-perf-test")||this.name.includes("decompression-latency")||this.name.includes("concurrent-read-test")||this.name.includes("clock-change-test"))return jI(this.config.logDirectory,`${this.name}.log`);if(this.name.includes("pending-test")||this.name.includes("temp-file-test")||this.name==="crash-test"||this.name==="corrupt-test"||this.name.includes("rotation-load-test")||this.name==="sigterm-test"||this.name==="sigint-test"||this.name==="failed-rotation-test"||this.name==="integration-test")return jI(this.config.logDirectory,`${this.name}.log`);let I=new Date().toISOString().split("T")[0];return jI(this.config.logDirectory,`${this.name}-${I}.log`)}setupRotation(){if(m())return;if(!this.shouldWriteToFile())return;if(typeof this.config.rotation==="boolean")return;let I=this.config.rotation,w;switch(I.frequency){case"daily":w=86400000;break;case"weekly":w=604800000;break;case"monthly":w=2592000000;break;default:return}this.rotationTimeout=setInterval(()=>{this.rotateLog()},w)}setupKeyRotation(){if(!this.validateEncryptionConfig()){console.error("Invalid encryption configuration detected during key rotation setup");return}let w=this.config.rotation.keyRotation;if(!w?.enabled)return;let G=typeof w.interval==="number"?w.interval:60,$=Math.max(G,60)*1000;this.keyRotationTimeout=setInterval(()=>{this.rotateKeys().catch((A)=>{console.error("Error rotating keys:",A)})},$)}async rotateKeys(){if(!this.validateEncryptionConfig()){console.error("Invalid encryption configuration detected during key rotation");return}let w=this.config.rotation.keyRotation,G=this.generateKeyId(),$=this.generateKey();this.currentKeyId=G,this.keys.set(G,$),this.encryptionKeys.set(G,{key:$,createdAt:new Date});let A=Array.from(this.encryptionKeys.entries()).sort(([,Y],[,U])=>U.createdAt.getTime()-Y.createdAt.getTime()),_=typeof w.maxKeys==="number"?w.maxKeys:1,W=Math.max(1,_);if(A.length>W)for(let[Y]of A.slice(W))this.encryptionKeys.delete(Y),this.keys.delete(Y)}generateKeyId(){return aw(16).toString("hex")}generateKey(){return aw(32)}getCurrentKey(){if(!this.currentKeyId)throw Error("Encryption is not properly initialized. Make sure encryption is enabled in the configuration.");let I=this.keys.get(this.currentKeyId);if(!I)throw Error(`No key found for ID ${this.currentKeyId}. The encryption key may have been rotated or removed.`);return{key:I,id:this.currentKeyId}}encrypt(I){let{key:w}=this.getCurrentKey(),G=aw(16),$=w_("aes-256-gcm",w,G),A=WI.isBuffer(I)?I:WI.from(I,"utf8"),_=$.update(A),W=$.final(),Y=_.length+W.length,U=$.getAuthTag(),H=WI.allocUnsafe(16+Y+16);return G.copy(H,0),_.copy(H,16),W.copy(H,16+_.length),U.copy(H,16+Y),{encrypted:H,iv:G}}async compressData(I){return new Promise((w,G)=>{let $=E$(),A=[];$.on("data",(_)=>A.push(_)),$.on("end",()=>w(WI.from(WI.concat(A)))),$.on("error",G),$.write(I),$.end()})}getEncryptionOptions(){if(!this.config.rotation||typeof this.config.rotation==="boolean"||!this.config.rotation.encrypt)return{};let I={algorithm:"aes-256-cbc",compress:!1};if(typeof this.config.rotation.encrypt==="object"){let w=this.config.rotation.encrypt;return{...I,...w}}return I}async rotateLog(){if(m())return;if(!this.shouldWriteToFile())return;let I=await FI(this.currentLogFile).catch(()=>null);if(!I)return;let w=this.config.rotation;if(typeof w==="boolean")return;if(w.maxSize&&I.size>=w.maxSize){let G=this.currentLogFile,$=this.generateLogFilename();if(this.name.includes("rotation-load-test")||this.name==="failed-rotation-test"){let A=await _w(this.config.logDirectory),_=A.filter((U)=>U.startsWith(this.name)&&/\.log\.\d+$/.test(U)).sort((U,H)=>{let Z=Number.parseInt(U.match(/\.log\.(\d+)$/)?.[1]||"0");return Number.parseInt(H.match(/\.log\.(\d+)$/)?.[1]||"0")-Z}),W=_.length>0?Number.parseInt(_[0].match(/\.log\.(\d+)$/)?.[1]||"0")+1:1,Y=`${G}.${W}`;if(await FI(G).catch(()=>null))try{if(await S$(G,Y),w.compress)try{let U=`${Y}.gz`;await this.compressLogFile(Y,U),await Ww(Y)}catch(U){console.error("Error compressing rotated file:",U)}if(_.length===0&&!A.some((U)=>U.endsWith(".log.1")))try{let U=`${G}.1`;await IG(U,"")}catch(U){console.error("Error creating backup file:",U)}}catch(U){console.error(`Error during rotation: ${U instanceof Error?U.message:String(U)}`)}}else{let A=new Date().toISOString().replace(/[:.]/g,"-"),_=G.replace(/\.log$/,`-${A}.log`);if(await FI(G).catch(()=>null))await S$(G,_)}if(this.currentLogFile=$,w.maxFiles){let _=(await _w(this.config.logDirectory)).filter((W)=>W.startsWith(this.name)).sort((W,Y)=>Y.localeCompare(W));for(let W of _.slice(w.maxFiles))await Ww(jI(this.config.logDirectory,W))}}}async compressLogFile(I,w){let G=K$(I),$=$_(w),A=E$();await H_(G,A,$)}async handleFingersCrossedBuffer(I,w){if(!this.fingersCrossedConfig)return;if(this.shouldActivateFingersCrossed(I)&&!this.isActivated){this.isActivated=!0;for(let G of this.logBuffer){let $=await this.formatter.format(G);if(this.shouldWriteToFile())await this.writeToFile($);console.log($)}if(this.fingersCrossedConfig.stopBuffering)this.logBuffer=[]}if(this.isActivated){if(this.shouldWriteToFile())await this.writeToFile(w);console.log(w)}}shouldLog(I){if(!this.enabled)return!1;let w={debug:0,info:1,success:2,warning:3,error:4};return w[I]>=w[this.config.level]}async flushPendingWrites(){if(await Promise.all(this.pendingOperations.map((I)=>{if(I instanceof Promise)return I.catch((w)=>{console.error("Error in pending write operation:",w)});return Promise.resolve()})),Aw(this.currentLogFile))try{let I=M$(this.currentLogFile,"r+");T$(I),ew(I)}catch(I){console.error(`Error flushing file: ${I}`)}}async destroy(){if(this.rotationTimeout)clearInterval(this.rotationTimeout);if(this.keyRotationTimeout)clearInterval(this.keyRotationTimeout);this.timers.clear();for(let I of this.pendingOperations)if(typeof I.cancel==="function")I.cancel();return(async()=>{if(this.pendingOperations.length>0)try{await Promise.allSettled(this.pendingOperations)}catch(I){console.error("Error waiting for pending operations:",I)}if(!m()&&this.config.rotation&&typeof this.config.rotation!=="boolean"&&this.config.rotation.compress)try{let w=(await _w(this.config.logDirectory)).filter((G)=>(G.includes("temp")||G.includes(".tmp"))&&G.includes(this.name));for(let G of w)try{await Ww(jI(this.config.logDirectory,G))}catch($){console.error(`Failed to delete temp file ${G}:`,$)}}catch(I){console.error("Error cleaning up temporary files:",I)}})()}getCurrentLogFilePath(){return this.currentLogFile}formatTag(I){if(!I)return"";return`${this.tagFormat.prefix}${I}${this.tagFormat.suffix}`}formatFileTimestamp(I){return`[${I.toISOString()}]`}formatConsoleTimestamp(I){return this.shouldStyleConsole()?S.gray(I.toLocaleTimeString()):I.toLocaleTimeString()}shouldStyleConsole(){if(!this.fancy||m())return!1;let I=typeof M.env.NO_COLOR<"u",w=M.env.FORCE_COLOR==="0";if(I||w)return!1;return!!(typeof M.stderr<"u"&&M.stderr.isTTY||typeof M.stdout<"u"&&M.stdout.isTTY)}formatConsoleMessage(I){let{timestamp:w,icon:G="",tag:$="",message:A,level:_,showTimestamp:W=!0}=I,Y=(b)=>b.replace(this.ANSI_PATTERN,"");if(!this.fancy){let b=[];if(W)b.push(w);if(_==="warning")b.push("WARN");else if(_==="error")b.push("ERROR");else if(G)b.push(G.replace(/[^\p{L}\p{N}\p{P}\p{Z}]/gu,""));if($)b.push($.replace(/[[\]]/g,""));return b.push(A),b.join(" ")}let U=M.stdout.columns||120,H="";if(_==="warning"||_==="error")H=`${G} ${A}`;else if(_==="info"||_==="success")H=`${G} ${$} ${A}`;else H=`${G} ${$} ${S.cyan(A)}`;if(!W)return H.trim();let Z=Y(H).trim().length,q=Y(w).length,Q=Math.max(1,U-2-Z-q);return`${H.trim()}${" ".repeat(Q)}${w}`}formatMessage(I,w){if(w.length===1&&Array.isArray(w[0]))return I.replace(/\{(\d+)\}/g,(_,W)=>{let Y=Number.parseInt(W,10);return Y<w[0].length?String(w[0][Y]):_});let G=/%([sdijfo%])/g,$=0,A=I.replace(G,(_,W)=>{if(W==="%")return"%";if($>=w.length)return _;let Y=w[$++];switch(W){case"s":return String(Y);case"d":case"i":return Number(Y).toString();case"j":case"o":return JSON.stringify(Y,null,2);default:return _}});if($<w.length)A+=` ${w.slice($).map((_)=>typeof _==="object"?JSON.stringify(_,null,2):String(_)).join(" ")}`;return A}formatMarkdown(I){if(!I)return I;let w=I;return w=w.replace(/\[([^\]]+)\]\(([^)]+)\)/g,(G,$,A)=>{let _=S.underline(S.blue($)),W=this.toAbsoluteFilePath(A);if(W&&this.shouldStyleConsole()&&this.supportsHyperlinks()){let Y=`file://${encodeURI(W)}`,U="\x1B]8;;",H="\x1B\\";return`\x1B]8;;${Y}\x1B\\${_}\x1B]8;;\x1B\\`}if(this.shouldStyleConsole()&&this.supportsHyperlinks())return`\x1B]8;;${A}\x1B\\${_}\x1B]8;;\x1B\\`;return _}),w=w.replace(/`([^`]+)`/g,(G,$)=>S.bgGray($)),w=w.replace(/\*\*([^*]+)\*\*/g,(G,$)=>S.bold($)),w=w.replace(/(?<!\*)\*([^*]+)\*(?!\*)/g,(G,$)=>S.italic($)),w=w.replace(/(?<!_)_([^_]+)_(?!_)/g,(G,$)=>S.italic($)),w=w.replace(/~([^~]+)~/g,(G,$)=>S.strikethrough($)),w}supportsHyperlinks(){if(m())return!1;let I=M.env;if(!I)return!1;if(I.TERM_PROGRAM==="iTerm.app"||I.TERM_PROGRAM==="vscode"||I.TERM_PROGRAM==="WezTerm")return!0;if(I.WT_SESSION)return!0;if(I.TERM==="xterm-kitty")return!0;let w=I.VTE_VERSION?Number.parseInt(I.VTE_VERSION,10):0;if(!Number.isNaN(w)&&w>=5000)return!0;return!1}toAbsoluteFilePath(I){try{let w=I;if(w.startsWith("file://"))w=w.replace(/^file:\/\//,"");if(w.startsWith("~")){let G=M.env.HOME||"";if(G)w=w.replace(/^~(?=$|\/)/,G)}if(Y_(w)||w.startsWith("./")||w.startsWith("../"))w=U_(w);else return null;return Aw(w)?w:null}catch{return null}}buildOutputTexts(I){let w=this.shouldStyleConsole()?this.formatMarkdown(I):I,G=I.replace(this.ANSI_PATTERN,"");return{consoleText:w,fileText:G}}async log(I,w,...G){if(!this.shouldLog(I))return;let $=new Date,A=this.formatConsoleTimestamp($),_=this.formatFileTimestamp($),W,Y;if(w instanceof Error)W=w.message,Y=w.stack;else W=this.formatMessage(w,G);let{consoleText:U,fileText:H}=this.buildOutputTexts(W);if(this.shouldStyleConsole()){let q=this.options.showIcons===!1?"":MW[I],Q=this.options.showTags!==!1&&this.name?S.gray(this.formatTag(this.name)):"",b;switch(I){case"debug":b=this.formatConsoleMessage({timestamp:A,icon:q,tag:Q,message:S.gray(U),level:I}),console.error(b);break;case"info":b=this.formatConsoleMessage({timestamp:A,icon:q,tag:Q,message:U,level:I}),console.warn(b);break;case"success":b=this.formatConsoleMessage({timestamp:A,icon:q,tag:Q,message:S.green(U),level:I}),console.error(b);break;case"warning":b=this.formatConsoleMessage({timestamp:A,icon:q,tag:Q,message:U,level:I}),console.warn(b);break;case"error":if(b=this.formatConsoleMessage({timestamp:A,icon:q,tag:Q,message:U,level:I}),console.error(b),Y){let X=Y.split(`
|
|
40
|
+
`);for(let L of X)if(L.trim()&&!L.includes(W))console.error(this.formatConsoleMessage({timestamp:A,message:S.gray(` ${L}`),level:I,showTimestamp:!1}))}break}}else if(!m()){if(console.error(`${_} ${this.environment}.${I.toUpperCase()}: ${W}`),Y)console.error(Y)}let Z=`${_} ${this.environment}.${I.toUpperCase()}: ${H}
|
|
41
|
+
`;if(Y)Z+=`${Y}
|
|
42
|
+
`;if(Z=Z.replace(this.ANSI_PATTERN,""),this.shouldWriteToFile())await this.writeToFile(Z)}progress(I,w=""){let G={update:(Y,U)=>{},finish:(Y)=>{},interrupt:(Y,U)=>{}};if(!this.enabled)return G;let $=30;if(this.activeProgressBar={total:Math.max(1,I||1),current:0,message:w||"",barLength:$,lastRenderedLine:""},this.shouldStyleConsole()&&!m()&&M.stdout.isTTY)this.renderProgressBar(this.activeProgressBar);return{update:(Y,U)=>{if(!this.enabled||!this.activeProgressBar)return;if(this.activeProgressBar.current=Math.min(Math.max(0,Y),this.activeProgressBar.total),U!==void 0)this.activeProgressBar.message=U;if(this.shouldStyleConsole()&&!m()&&M.stdout.isTTY)this.renderProgressBar(this.activeProgressBar)},finish:(Y)=>{if(!this.activeProgressBar)return;this.finishProgressBar(this.activeProgressBar,Y)},interrupt:(Y,U="info")=>{if(!m()&&M.stdout.isTTY)M.stdout.write(`
|
|
43
|
+
`);if(this[U==="warning"?"warn":U](Y),this.activeProgressBar&&this.shouldStyleConsole()&&!m()&&M.stdout.isTTY)this.renderProgressBar(this.activeProgressBar)}}}time(I){let w=performance.now();if(this.shouldStyleConsole()){let G=this.options.showTags!==!1&&this.name?S.gray(this.formatTag(this.name)):"",$=this.formatConsoleTimestamp(new Date);console.error(this.formatConsoleMessage({timestamp:$,icon:this.options.showIcons===!1?"":S.blue("◐"),tag:G,message:`${S.cyan(I)}...`}))}return async(G)=>{if(!this.enabled)return;let $=performance.now(),A=Math.round($-w),_=`${I} completed in ${A}ms`,W=new Date,Y=this.formatConsoleTimestamp(W),H=`${this.formatFileTimestamp(W)} ${this.environment}.INFO: ${_}`;if(G)H+=` ${JSON.stringify(G)}`;if(H+=`
|
|
44
|
+
`,H=H.replace(this.ANSI_PATTERN,""),this.shouldStyleConsole()){let Z=this.options.showTags!==!1&&this.name?S.gray(this.formatTag(this.name)):"";console.error(this.formatConsoleMessage({timestamp:Y,icon:this.options.showIcons===!1?"":S.green("✓"),tag:Z,message:`${_}${G?` ${JSON.stringify(G)}`:""}`}))}else if(!m())console.error(H.trim());if(this.shouldWriteToFile())await this.writeToFile(H)}}async debug(I,...w){await this.log("debug",I,...w)}async info(I,...w){await this.log("info",I,...w)}async success(I,...w){await this.log("success",I,...w)}async warn(I,...w){await this.log("warning",I,...w)}async error(I,...w){await this.log("error",I,...w)}validateEncryptionConfig(){if(!this.config.rotation)return!1;if(typeof this.config.rotation==="boolean")return!1;let I=this.config.rotation,{encrypt:w}=I;return!!w}async only(I){if(!this.enabled)return;return await I()}isEnabled(){return this.enabled}setEnabled(I){this.enabled=I}extend(I){let w=`${this.name}:${I}`,G=new kw(w,{...this.options,logDirectory:this.config.logDirectory,level:this.config.level,format:this.config.format,rotation:typeof this.config.rotation==="boolean"?void 0:this.config.rotation,timestamp:typeof this.config.timestamp==="boolean"?void 0:this.config.timestamp});return this.subLoggers.add(G),G}createReadStream(){if(m())throw Error("createReadStream is not supported in browser environments");if(!Aw(this.currentLogFile))throw Error(`Log file does not exist: ${this.currentLogFile}`);return K$(this.currentLogFile,{encoding:"utf8"})}async decrypt(I){if(!this.validateEncryptionConfig())throw Error("Encryption is not configured");let w=this.config.rotation;if(!w.encrypt||typeof w.encrypt==="boolean")throw Error("Invalid encryption configuration");if(!this.currentKeyId||!this.keys.has(this.currentKeyId))throw Error("No valid encryption key available");let G=this.keys.get(this.currentKeyId);try{let $=WI.isBuffer(I)?I:WI.from(I,"base64"),A=$.subarray(0,16),_=$.subarray($.length-16),W=$.subarray(16,$.length-16),Y=G_("aes-256-gcm",G,A);Y.setAuthTag(_);let U=Y.update(W),H=Y.final(),Z=U.length+H.length,q=WI.allocUnsafe(Z);return U.copy(q,0),H.copy(q,U.length),q.toString("utf8")}catch($){throw Error(`Decryption failed: ${$ instanceof Error?$.message:String($)}`)}}getLevel(){return this.config.level}getLogDirectory(){return this.config.logDirectory}getFormat(){return this.config.format}getRotationConfig(){return this.config.rotation}isBrowserMode(){return m()}isServerMode(){return!m()}setTestEncryptionKey(I,w){this.currentKeyId=I,this.keys.set(I,w)}getTestCurrentKey(){if(!this.currentKeyId||!this.keys.has(this.currentKeyId))return null;return{id:this.currentKeyId,key:this.keys.get(this.currentKeyId)}}getConfig(){return this.config}async box(I){if(!this.enabled)return;let w=new Date,G=this.formatConsoleTimestamp(w),$=this.formatFileTimestamp(w),{consoleText:A,fileText:_}=this.buildOutputTexts(I);if(this.shouldStyleConsole()){let Y=A.split(`
|
|
45
|
+
`),U=Math.max(...Y.map((Q)=>Q.length))+2,H=`┌${"─".repeat(U)}┐`,Z=`└${"─".repeat(U)}┘`,q=Y.map((Q)=>{return this.formatConsoleMessage({timestamp:G,message:S.cyan(Q),showTimestamp:!1})});console.error(this.formatConsoleMessage({timestamp:G,message:S.cyan(H),showTimestamp:!1})),q.forEach((Q)=>console.error(Q)),console.error(this.formatConsoleMessage({timestamp:G,message:S.cyan(Z),showTimestamp:!1}))}else if(!m())console.error(`${$} ${this.environment}.INFO: [BOX] ${_}`);let W=`${$} ${this.environment}.INFO: [BOX] ${_}
|
|
46
|
+
`.replace(this.ANSI_PATTERN,"");if(this.shouldWriteToFile())await this.writeToFile(W)}async prompt(I){if(m())return Promise.resolve(!0);return new Promise((w)=>{console.error(`${S.cyan("?")} ${I} (y/n) `);let G=($)=>{let A=$.toString().trim().toLowerCase();M.stdin.removeListener("data",G);try{if(typeof M.stdin.setRawMode==="function")M.stdin.setRawMode(!1)}catch{}M.stdin.pause(),console.error(""),w(A==="y"||A==="yes")};try{if(typeof M.stdin.setRawMode==="function")M.stdin.setRawMode(!0)}catch{}M.stdin.resume(),M.stdin.once("data",G)})}setFancy(I){this.fancy=I}isFancy(){return this.fancy}pause(){this.enabled=!1}resume(){this.enabled=!0}async start(I,...w){if(!this.enabled)return;let G=I;if(w&&w.length>0){let U=/%([sdijfo%])/g,H=0;if(G=I.replace(U,(Z,q)=>{if(q==="%")return"%";if(H>=w.length)return Z;let Q=w[H++];switch(q){case"s":return String(Q);case"d":case"i":return Number(Q).toString();case"j":case"o":return JSON.stringify(Q,null,2);default:return Z}}),H<w.length)G+=` ${w.slice(H).map((Z)=>typeof Z==="object"?JSON.stringify(Z,null,2):String(Z)).join(" ")}`}let{consoleText:$,fileText:A}=this.buildOutputTexts(G);if(this.shouldStyleConsole()){let U=this.options.showTags!==!1&&this.name?S.gray(this.formatTag(this.name)):"",H=this.options.showIcons===!1?"":`${S.blue("◐")} `;console.error(`${H}${U} ${S.cyan($)}`)}let Y=`[${new Date().toISOString()}] ${this.environment}.INFO: [START] ${A}
|
|
47
|
+
`.replace(this.ANSI_PATTERN,"");if(this.shouldWriteToFile())await this.writeToFile(Y)}renderProgressBar(I,w=!1){if(!this.enabled||!this.shouldStyleConsole()||!M.stdout.isTTY)return;let G=Math.min(100,Math.max(0,Math.round(I.current/I.total*100))),$=Math.round(I.barLength*G/100),A=I.barLength-$,_=S.green("━".repeat($)),W=S.gray("━".repeat(A)),Y=`[${_}${W}]`,U=`${G}%`.padStart(4),H=I.message?` ${I.message}`:"",Z=this.options.showIcons===!1?"":w||G===100?S.green("✓"):S.blue("▶"),q=this.options.showTags!==!1&&this.name?` ${S.gray(this.formatTag(this.name))}`:"",Q=`\r${Z}${q} ${Y} ${U}${H}`,b=M.stdout.columns||80,X=" ".repeat(Math.max(0,b-Q.replace(this.ANSI_PATTERN,"").length));if(I.lastRenderedLine=`${Q}${X}`,M.stdout.write(I.lastRenderedLine),w)M.stdout.write(`
|
|
48
|
+
`)}finishProgressBar(I,w){if(!this.enabled||!this.fancy||m()||!M.stdout.isTTY){this.activeProgressBar=null;return}if(I.current<I.total)I.current=I.total;if(w)I.message=w;this.renderProgressBar(I,!0),this.activeProgressBar=null}async clear(I={}){if(m()){console.warn("Log clearing is not supported in browser environments.");return}try{console.warn("Clearing logs...",this.config.logDirectory);let w=await _w(this.config.logDirectory),G=[];for(let $ of w){if(!(I.name?new RegExp(I.name.replace("*",".*")).test($):$.startsWith(this.name))||!$.endsWith(".log"))continue;let _=jI(this.config.logDirectory,$);if(I.before)try{if((await FI(_)).mtime>=I.before)continue}catch(W){console.error(`Failed to get stats for file ${_}:`,W);continue}G.push(_)}if(G.length===0){console.warn("No log files matched the criteria for clearing.");return}console.warn(`Preparing to delete ${G.length} log file(s)...`);for(let $ of G)try{await Ww($),console.warn(`Deleted log file: ${$}`)}catch(A){console.error(`Failed to delete log file ${$}:`,A)}console.warn("Log clearing process finished.")}catch(w){console.error("Error during log clearing process:",w)}}}var Q1=new kw("stacks");class II extends Error{timestamp;context;constructor(I,w={}){super(I);if(this.name=this.constructor.name,this.timestamp=new Date,this.context=w,Error.captureStackTrace)Error.captureStackTrace(this,this.constructor)}toJSON(){return{name:this.name,code:this.code,message:this.message,timestamp:this.timestamp.toISOString(),context:this.context,stack:this.stack}}toString(){let I=Object.keys(this.context).length>0?` (${Object.entries(this.context).map(([w,G])=>`${w}: ${G}`).join(", ")})`:"";return`${this.name} [${this.code}]: ${this.message}${I}`}}class UA extends II{code="CONFIG_NOT_FOUND";constructor(I,w,G){let $=G===void 0?[]:Array.isArray(G)?G.filter(Boolean):[G],A="";if($.length===1)A=` or alias "${$[0]}"`;else if($.length>1)A=` or aliases ${$.map((_)=>`"${_}"`).join(", ")}`;super(`Configuration "${I}"${A} not found`,{configName:I,alias:G,searchPaths:w,searchPathCount:w.length})}}class Fw extends II{code="CONFIG_LOAD_ERROR";constructor(I,w,G){super(`Failed to load configuration from "${I}": ${w.message}`,{configPath:I,configName:G,originalError:w.name,originalMessage:w.message});this.cause=w}}class HA extends II{code="CONFIG_VALIDATION_ERROR";constructor(I,w,G){super(`Configuration validation failed for "${I}"`,{configPath:I,configName:G,validationErrors:w,errorCount:w.length})}}class ZA extends II{code="CONFIG_MERGE_ERROR";constructor(I,w,G,$){super(`Failed to merge configuration from "${I}" with "${w}": ${G.message}`,{sourcePath:I,targetPath:w,configName:$,originalError:G.name,originalMessage:G.message});this.cause=G}}class FG extends II{code="ENV_VAR_ERROR";constructor(I,w,G,$){super(`Failed to parse environment variable "${I}" with value "${w}" as ${G}`,{envKey:I,envValue:w,expectedType:G,configName:$})}}class qA extends II{code="FILE_SYSTEM_ERROR";constructor(I,w,G){super(`File system ${I} failed for "${w}": ${G.message}`,{operation:I,path:w,originalError:G.name,originalMessage:G.message});this.cause=G}}class bA extends II{code="TYPE_GENERATION_ERROR";constructor(I,w,G){super(`Failed to generate types from "${I}" to "${w}": ${G.message}`,{configDir:I,outputPath:w,originalError:G.name,originalMessage:G.message});this.cause=G}}class jw extends II{code="SCHEMA_VALIDATION_ERROR";constructor(I,w,G){super(`Schema validation failed${G?` for config "${G}"`:""}`,{schemaPath:I,configName:G,validationErrors:w,errorCount:w.length})}}class QA extends II{code="BROWSER_CONFIG_ERROR";constructor(I,w,G,$){super(`Failed to fetch configuration from "${I}": ${w} ${G}`,{endpoint:I,status:w,statusText:G,configName:$})}}class LA extends II{code="PLUGIN_ERROR";constructor(I,w,G){super(`Plugin "${I}" failed during ${w}: ${G.message}`,{pluginName:I,operation:w,originalError:G.name,originalMessage:G.message});this.cause=G}}var xI={configNotFound(I,w,G){return new UA(I,w,G)},configLoad(I,w,G){return new Fw(I,w,G)},configValidation(I,w,G){return new HA(I,w,G)},configMerge(I,w,G,$){return new ZA(I,w,G,$)},envVar(I,w,G,$){return new FG(I,w,G,$)},fileSystem(I,w,G){return new qA(I,w,G)},typeGeneration(I,w,G){return new bA(I,w,G)},schemaValidation(I,w,G){return new jw(I,w,G)},browserConfig(I,w,G,$){return new QA(I,w,G,$)},plugin(I,w,G){return new LA(I,w,G)}};async function CW(I,w={}){let{maxRetries:G=3,retryDelay:$=1000,isRetryable:A=()=>!0,fallback:_}=w,W=Error("Unknown error occurred");for(let Y=0;Y<=G;Y++)try{return await I()}catch(U){if(W=U instanceof Error?U:Error(String(U)),Y===G||!A(W))break;if($>0)await new Promise((H)=>setTimeout(H,$))}if(_!==void 0)return _;throw W instanceof Error?W:Error(`Unknown error: ${String(W)}`)}class jG{defaultParsers;constructor(){this.defaultParsers=[{name:"boolean",canParse:(I,w)=>w==="boolean"||["true","false","1","0","yes","no"].includes(I.toLowerCase()),parse:(I)=>{let w=I.toLowerCase();return["true","1","yes"].includes(w)}},{name:"number",canParse:(I,w)=>w==="number"||!Number.isNaN(Number(I))&&!Number.isNaN(Number.parseFloat(I)),parse:(I)=>{let w=Number(I);if(Number.isNaN(w))throw TypeError(`Cannot parse "${I}" as number`);return w}},{name:"array",canParse:(I,w)=>w==="array"||I.startsWith("[")||I.includes(","),parse:(I)=>{try{let w=JSON.parse(I);if(Array.isArray(w))return w}catch{}return I.split(",").map((w)=>w.trim())}},{name:"json",canParse:(I,w)=>w==="object"||(I.startsWith("{")&&I.endsWith("}")||I.startsWith("[")&&I.endsWith("]")),parse:(I)=>{try{return JSON.parse(I)}catch(w){throw Error(`Cannot parse "${I}" as JSON: ${w}`)}}}]}async applyEnvironmentVariables(I,w,G={}){let{prefix:$,useCamelCase:A=!0,useBackwardCompatibility:_=!0,customParsers:W={},verbose:Y=!1,trackPerformance:U=!0}=G,H=async()=>{if(!I)return{config:w,source:{type:"environment",priority:50,timestamp:new Date}};let Z=$||this.generateEnvPrefix(I),q={...w};return this.processObject(q,[],Z,{useCamelCase:A,useBackwardCompatibility:_,customParsers:W,verbose:Y,configName:I}),{config:q,source:{type:"environment",priority:50,timestamp:new Date}}};if(U)return KG.track("applyEnvironmentVariables",H,{configName:I});return H()}generateEnvPrefix(I){return I.toUpperCase().replace(/-/g,"_")}formatEnvKey(I,w){if(!w)return I.toUpperCase();return I.replace(/([A-Z])/g,"_$1").toUpperCase()}processObject(I,w,G,$){for(let[A,_]of Object.entries(I)){let W=[...w,A],Y=W.map((Z)=>this.formatEnvKey(Z,$.useCamelCase)),U=`${G}_${Y.join("_")}`,H=$.useBackwardCompatibility?`${G}_${W.map((Z)=>Z.toUpperCase()).join("_")}`:null;if($.verbose);if(typeof _==="object"&&_!==null&&!Array.isArray(_))this.processObject(_,W,G,$);else{let Z=Uw.env[U]||(H?Uw.env[H]:void 0);if(Z!==void 0){if($.verbose){let q=Uw.env[U]?U:H}try{I[A]=this.parseEnvironmentValue(Z,typeof _,U,$.customParsers,$.configName)}catch(q){if(q instanceof FG)throw q;throw xI.envVar(U,Z,typeof _,$.configName)}}}}}parseEnvironmentValue(I,w,G,$,A){for(let[_,W]of Object.entries($))try{return W(I)}catch{continue}for(let _ of this.defaultParsers)if(_.canParse(I,w))try{return _.parse(I)}catch{throw xI.envVar(G,I,`${w} (via ${_.name} parser)`,A)}return I}getEnvironmentVariables(I){let w={},G=I.toUpperCase();for(let[$,A]of Object.entries(Uw.env))if($.startsWith(G)&&A!==void 0)w[$]=A;return w}validateEnvironmentVariable(I,w,G){let $=[];if(!/^[A-Z_][A-Z0-9_]*$/.test(I))$.push(`Environment variable key "${I}" should only contain uppercase letters, numbers, and underscores`);if(G)try{this.parseEnvironmentValue(I,w,G,{})}catch(A){$.push(`Cannot parse value "${w}" as ${G}: ${A}`)}return{isValid:$.length===0,errors:$}}generateEnvVarDocs(I,w,G={}){let{prefix:$,format:A="text"}=G,_=$||this.generateEnvPrefix(I),W=[];switch(this.extractEnvVarInfo(w,[],_,W),A){case"markdown":return this.formatAsMarkdown(W,I);case"json":return JSON.stringify(W,null,2);default:return this.formatAsText(W,I)}}extractEnvVarInfo(I,w,G,$){for(let[A,_]of Object.entries(I)){let W=[...w,A],Y=`${G}_${W.map((U)=>this.formatEnvKey(U,!0)).join("_")}`;if(typeof _==="object"&&_!==null&&!Array.isArray(_))this.extractEnvVarInfo(_,W,G,$);else $.push({key:Y,type:Array.isArray(_)?"array":typeof _,description:`Configuration for ${W.join(".")}`,example:this.generateExample(_)})}}generateExample(I){if(Array.isArray(I))return JSON.stringify(I);if(typeof I==="object"&&I!==null)return JSON.stringify(I);return String(I)}formatAsText(I,w){let G=`Environment Variables for ${w}:
|
|
49
|
+
|
|
50
|
+
`;for(let $ of I)G+=`${$.key}
|
|
51
|
+
`,G+=` Type: ${$.type}
|
|
52
|
+
`,G+=` Description: ${$.description}
|
|
53
|
+
`,G+=` Example: ${$.example}
|
|
54
|
+
|
|
55
|
+
`;return G}formatAsMarkdown(I,w){let G=`# Environment Variables for ${w}
|
|
56
|
+
|
|
57
|
+
`;G+=`| Variable | Type | Description | Example |
|
|
58
|
+
`,G+=`|----------|------|-------------|----------|
|
|
59
|
+
`;for(let $ of I)G+=`| \`${$.key}\` | ${$.type} | ${$.description} | \`${$.example}\` |
|
|
60
|
+
`;return G}}function SW(I,w,G={}){return XA(I,w,G,new WeakMap)}function XA(I,w,G,$){let{arrayMergeMode:A="replace",skipNullish:_=!1,customMerger:W}=G;if(w===null||w===void 0)return _?I:w;if(W){let Y=W(I,w);if(Y!==void 0)return Y}if(Array.isArray(w)||Array.isArray(I))return JA(I,w,A,$);if(!t(w)||!t(I))return w;return FW(I,w,G,$)}function JA(I,w,G,$){if(Array.isArray(w)&&!Array.isArray(I))return w;if(Array.isArray(I)&&!Array.isArray(w))return w;if(Array.isArray(w)&&Array.isArray(I))switch(G){case"replace":return w;case"concat":return EW(I,w);case"smart":return OW(I,w,$);default:return w}return w}function EW(I,w){let G=[...w];for(let $ of I)if(!G.some((A)=>RG(A,$)))G.push($);return G}function OW(I,w,G){if(w.length===0)return I;if(I.length===0)return w;if(t(w[0])&&t(I[0]))return zW(I,w,G);if(w.every(($)=>typeof $==="string")&&I.every(($)=>typeof $==="string")){let $=[...w];for(let A of I)if(!$.includes(A))$.push(A);return $}return w}function zW(I,w,G){let $=[...w];for(let A of I){if(!t(A)){$.push(A);continue}let _=["id","name","key","path","type"],W=!1;for(let Y of _)if(Y in A){if($.find((H)=>t(H)&&(Y in H)&&H[Y]===A[Y])){W=!0;break}}if(!W)$.push(A)}return $}function FW(I,w,G,$){let A=w;if(t(A)&&$.has(A))return $.get(A);let _={...I};if(t(A))$.set(A,_);for(let W in A){if(!Object.prototype.hasOwnProperty.call(A,W))continue;let Y=A[W],U=_[W];if(G.skipNullish&&(Y===null||Y===void 0))continue;if(Y===null||Y===void 0){_[W]=Y;continue}if(t(Y)&&t(U))_[W]=XA(U,Y,G,$);else if(Array.isArray(Y)||Array.isArray(U))_[W]=JA(U,Y,G.arrayMergeMode||"smart",$);else _[W]=Y}return _}function BA(I,w,G="replace"){return SW(I,w,{arrayMergeMode:G==="replace"?"replace":"smart",skipNullish:!0})}function RG(I,w){if(I===w)return!0;if(Array.isArray(I)&&Array.isArray(w)){if(I.length!==w.length)return!1;for(let G=0;G<I.length;G++)if(!RG(I[G],w[G]))return!1;return!0}if(t(I)&&t(w)){let G=Object.keys(I),$=Object.keys(w);if(G.length!==$.length)return!1;for(let A of G){if(!Object.prototype.hasOwnProperty.call(w,A))return!1;if(!RG(I[A],w[A]))return!1}return!0}return!1}function t(I){return Boolean(I&&typeof I==="object"&&!Array.isArray(I))}class DA{extensions=[".ts",".js",".mjs",".cjs",".json",".mts",".cts"];async loadFromPath(I,w,G={}){let{arrayStrategy:$="replace",useCache:A=!0,cacheTtl:_,trackPerformance:W=!0,verbose:Y=!1}=G;if(A){let H=Jw.getWithFileCheck("file",I);if(H){if(Y)console.log(`Configuration loaded from cache: ${I}`);return H}}let U=async()=>{if(!Hw(I))return null;try{let H=`?t=${Date.now()}`,Z=await import(I+H),q=Z.default||Z,Q="default"in Z,b=Object.keys(Z).length>0;if(!Q&&!b)throw new Fw(I,Error("Configuration file is empty and exports nothing"),"unknown");if(typeof q!=="object"||q===null||Array.isArray(q))throw new Fw(I,Error("Configuration must export a valid object"),"unknown");let J={config:BA(w,q,$),source:{type:"file",path:I,priority:100,timestamp:new Date}};if(A)Jw.setWithFileCheck("file",J,I,_);return J}catch(H){throw H instanceof Error?xI.configLoad(I,H):xI.configLoad(I,Error(String(H)))}};if(W)return KG.track("loadFromPath",U,{path:I});return U()}async tryLoadFromPaths(I,w,G={}){for(let $ of I)try{let A=await this.loadFromPath($,w,G);if(A)return A}catch(A){if(A instanceof Error&&A.name==="ConfigLoadError")throw A;if(G.verbose)console.warn(`Failed to load config from ${$}:`,A)}return null}generateConfigPaths(I,w,G){let $=this.generateNamePatterns(I,G),A=[];for(let _ of $)for(let W of this.extensions)A.push(WG(w,`${_}${W}`));return A}generateNamePatterns(I,w){let G=[];if(G.push("config",".config"),I)G.push(I,`.${I}.config`,`${I}.config`,`.${I}`);let $=w===void 0?[]:Array.isArray(w)?w:[w];for(let _ of $){if(!_)continue;if(G.push(_,`.${_}.config`,`${_}.config`,`.${_}`),I)G.push(`${I}.${_}.config`,`.${I}.${_}.config`)}let A=new Set;return G.filter((_)=>{if(!_||A.has(_))return!1;return A.add(_),!0})}checkFileAccess(I){return CW(async()=>{return Hw(I)},{maxRetries:2,retryDelay:100,fallback:!1})}async discoverConfigFiles(I,w,G){let $=[];if(!Hw(I))return $;if(w||G){let A=this.generateNamePatterns(w||"",G);for(let _ of A)for(let W of this.extensions){let Y=WG(I,`${_}${W}`);if(await this.checkFileAccess(Y))$.push(Y)}}else try{let{readdirSync:A}=await import("fs"),_=A(I);for(let W of _)if(this.looksLikeConfigFile(W)){let Y=WG(I,W);if(await this.checkFileAccess(Y))$.push(Y)}}catch{return[]}return $}looksLikeConfigFile(I){return[/\.config\.(ts|js|mjs|cjs|json|mts|cts)$/,/^\..*\.(ts|js|mjs|cjs|json|mts|cts)$/,/config\.(ts|js|mjs|cjs|json|mts|cts)$/].some((G)=>G.test(I))}async validateConfigFile(I){let w=[];try{if(!Hw(I))return w.push("Configuration file does not exist"),w;let G=await import(I),$=G.default||G;if($===void 0)w.push("Configuration file must export a default value or named exports");else if(typeof $!=="object"||$===null)w.push("Configuration must be an object");else if(Array.isArray($))w.push("Configuration cannot be an array at the root level");if(I.endsWith(".json"))try{let{readFileSync:A}=await import("fs"),_=A(I,"utf8");JSON.parse(_)}catch(A){w.push(`Invalid JSON syntax: ${A}`)}}catch(G){w.push(`Failed to load configuration file: ${G}`)}return w}async getFileModificationTime(I){try{let{statSync:w}=await import("fs");return w(I).mtime}catch{return null}}async preloadConfigurations(I,w={}){let G=new Map;return await Promise.allSettled(I.map(async($)=>{try{let A=await this.loadFromPath($,{},w);if(A)G.set($,A.config)}catch(A){if(w.verbose)console.warn(`Failed to preload ${$}:`,A)}})),G}}var NW=/^https?:\/\//;class RA{async validateConfiguration(I,w,G={}){let{stopOnFirstError:$=!1,validateRequired:A=!0,validateTypes:_=!0,customRules:W=[],trackPerformance:Y=!0,verbose:U=!1}=G,H=async()=>{let Z=[],q=[],Q={stopOnFirstError:$,validateRequired:A,validateTypes:_,customRules:W,trackPerformance:Y,verbose:U};try{if(typeof w==="string")return await this.validateWithSchemaFile(I,w,Q);else if(Array.isArray(w))return this.validateWithRules(I,[...w,...W],Q);else return this.validateWithJSONSchema(I,w,Q)}catch(b){return Z.push({path:"",message:`Validation failed: ${b}`,rule:"system"}),{isValid:!1,errors:Z,warnings:q}}};if(Y)return await KG.track("validateConfiguration",H);return H()}async validateWithSchemaFile(I,w,G){try{if(!jW(w))throw new jw(w,[{path:"",message:"Schema file does not exist"}]);let $=await import(w),A=$.default||$;if(Array.isArray(A))return this.validateWithRules(I,A,G);else return this.validateWithJSONSchema(I,A,G)}catch($){throw new jw(w,[{path:"",message:`Failed to load schema: ${$}`}])}}validateWithJSONSchema(I,w,G){let $=[],A=[];return this.validateObjectAgainstSchema(I,w,"",$,A,G),{isValid:$.length===0,errors:$,warnings:A}}validateObjectAgainstSchema(I,w,G,$,A,_){if(_.validateTypes&&w.type){let W=Array.isArray(I)?"array":typeof I,Y=Array.isArray(w.type)?w.type:[w.type];if(!Y.includes(W)){if($.push({path:G,message:`Expected type ${Y.join(" or ")}, got ${W}`,expected:Y.join(" or "),actual:W,rule:"type"}),_.stopOnFirstError)return}}if(w.enum&&!w.enum.includes(I)){if($.push({path:G,message:`Value must be one of: ${w.enum.join(", ")}`,expected:w.enum.join(", "),actual:I,rule:"enum"}),_.stopOnFirstError)return}if(typeof I==="string"){if(w.minLength!==void 0&&I.length<w.minLength)$.push({path:G,message:`String length must be at least ${w.minLength}`,expected:`>= ${w.minLength}`,actual:I.length,rule:"minLength"});if(w.maxLength!==void 0&&I.length>w.maxLength)$.push({path:G,message:`String length must not exceed ${w.maxLength}`,expected:`<= ${w.maxLength}`,actual:I.length,rule:"maxLength"});if(w.pattern){if(!new RegExp(w.pattern).test(I))$.push({path:G,message:`String does not match pattern ${w.pattern}`,expected:w.pattern,actual:I,rule:"pattern"})}}if(typeof I==="number"){if(w.minimum!==void 0&&I<w.minimum)$.push({path:G,message:`Value must be at least ${w.minimum}`,expected:`>= ${w.minimum}`,actual:I,rule:"minimum"});if(w.maximum!==void 0&&I>w.maximum)$.push({path:G,message:`Value must not exceed ${w.maximum}`,expected:`<= ${w.maximum}`,actual:I,rule:"maximum"})}if(Array.isArray(I)&&w.items)for(let W=0;W<I.length;W++){let Y=G?`${G}[${W}]`:`[${W}]`;if(this.validateObjectAgainstSchema(I[W],w.items,Y,$,A,_),_.stopOnFirstError&&$.length>0)return}if(I&&typeof I==="object"&&!Array.isArray(I)){let W=I;if(_.validateRequired&&w.required){for(let Y of w.required)if(!(Y in W)){if($.push({path:G?`${G}.${Y}`:Y,message:`Missing required property '${Y}'`,expected:"required",rule:"required"}),_.stopOnFirstError)return}}if(w.properties){for(let[Y,U]of Object.entries(w.properties))if(Y in W){let H=G?`${G}.${Y}`:Y;if(this.validateObjectAgainstSchema(W[Y],U,H,$,A,_),_.stopOnFirstError&&$.length>0)return}}if(w.additionalProperties===!1){let Y=new Set(Object.keys(w.properties||{}));for(let U of Object.keys(W))if(!Y.has(U))A.push({path:G?`${G}.${U}`:U,message:`Additional property '${U}' is not allowed`,rule:"additionalProperties"})}}}validateWithRules(I,w,G){let $=[],A=[];for(let _ of w)try{let W=this.getValueByPath(I,_.path),Y=this.validateWithRule(W,_,_.path);if($.push(...Y),G.stopOnFirstError&&$.length>0)break}catch(W){$.push({path:_.path,message:`Rule validation failed: ${W}`,rule:"system"})}return{isValid:$.length===0,errors:$,warnings:A}}validateWithRule(I,w,G){let $=[];if(w.required&&(I===void 0||I===null))return $.push({path:G,message:w.message||`Property '${G}' is required`,expected:"required",rule:"required"}),$;if(I===void 0||I===null)return $;if(w.type){let A=Array.isArray(I)?"array":typeof I;if(A!==w.type)$.push({path:G,message:w.message||`Expected type ${w.type}, got ${A}`,expected:w.type,actual:A,rule:"type"})}if(w.min!==void 0){let A=Array.isArray(I)?I.length:typeof I==="string"?I.length:typeof I==="number"?I:0;if(A<w.min)$.push({path:G,message:w.message||`Value must be at least ${w.min}`,expected:`>= ${w.min}`,actual:A,rule:"min"})}if(w.max!==void 0){let A=Array.isArray(I)?I.length:typeof I==="string"?I.length:typeof I==="number"?I:0;if(A>w.max)$.push({path:G,message:w.message||`Value must not exceed ${w.max}`,expected:`<= ${w.max}`,actual:A,rule:"max"})}if(w.pattern&&typeof I==="string"){if(!w.pattern.test(I))$.push({path:G,message:w.message||`Value does not match pattern ${w.pattern}`,expected:w.pattern.toString(),actual:I,rule:"pattern"})}if(w.enum&&!w.enum.includes(I))$.push({path:G,message:w.message||`Value must be one of: ${w.enum.join(", ")}`,expected:w.enum.join(", "),actual:I,rule:"enum"});if(w.validator){let A=w.validator(I);if(A)$.push({path:G,message:w.message||A,rule:"custom"})}return $}getValueByPath(I,w){if(!w)return I;let G=w.split("."),$=I;for(let A of G)if($&&typeof $==="object"&&A in $)$=$[A];else return;return $}generateRulesFromInterface(I){let w=[],G=I.matchAll(/(\w+)(\?)?:\s*(\w+)/g);for(let $ of G){let[,A,_,W]=$;w.push({path:A,required:!_,type:this.mapTypeScriptType(W)})}return w}mapTypeScriptType(I){switch(I.toLowerCase()){case"string":return"string";case"number":return"number";case"boolean":return"boolean";case"array":return"array";case"object":return"object";default:return"object"}}static createCommonRules(){return{server:[{path:"port",required:!0,type:"number",min:1,max:65535},{path:"host",required:!0,type:"string",min:1},{path:"ssl",type:"boolean"}],database:[{path:"url",required:!0,type:"string",min:1},{path:"pool",type:"number",min:1,max:100},{path:"timeout",type:"number",min:0}],api:[{path:"baseUrl",required:!0,type:"string",pattern:NW},{path:"timeout",type:"number",min:0},{path:"retries",type:"number",min:0,max:10}]}}}var GI=new kw("bunfig",{showTags:!0});function VW(I){if(!I)return"";let w=Array.isArray(I)?I.filter(Boolean):[I];if(w.length===0)return"";if(w.length===1)return` or alias "${w[0]}"`;return` or aliases ${w.map((G)=>`"${G}"`).join(", ")}`}class KA{fileLoader=new DA;envProcessor=new jG;validator=new RA;async loadConfig(I){let w=Date.now(),{cache:G,performance:$,schema:A,validate:_,...W}=I;try{if(G?.enabled){let U=this.checkCache(W.name||"",W);if(U)return U}let Y;try{Y=await this.loadConfigurationStrategies(W,!0,G)}catch(U){let H=W.__strictErrorHandling;if(U instanceof Error&&U.name==="ConfigNotFoundError"){if(H)throw U;Y={...await this.applyEnvironmentVariables(W.name||"",W.defaultConfig,W.checkEnv!==!1,W.verbose||!1),warnings:[`No configuration file found for "${W.name||"config"}", using defaults with environment variables`]}}else if(U instanceof Error&&U.name==="ConfigLoadError"){let Z=U.message.includes("EACCES")||U.message.includes("EPERM")||U.message.includes("permission denied"),q=!Z&&(U.message.includes("syntax")||U.message.includes("Expected")||U.message.includes("Unexpected")||U.message.includes("BuildMessage")||U.message.includes("errors building")),Q=U.message.includes("Configuration must export a valid object")||U.message.includes("Configuration file is empty and exports nothing");if(H&&(Q||Z))throw U;if(q&&(!H||!Q))Y={...await this.applyEnvironmentVariables(W.name||"",W.defaultConfig,W.checkEnv!==!1,W.verbose||!1),warnings:["Configuration file has syntax errors, using defaults with environment variables"]};else if(!H)Y={...await this.applyEnvironmentVariables(W.name||"",W.defaultConfig,W.checkEnv!==!1,W.verbose||!1),warnings:[`Configuration loading error, using defaults: ${U.message}`]};else throw U}else Y={...await this.applyEnvironmentVariables(W.name||"",W.defaultConfig,W.checkEnv!==!1,W.verbose||!1),warnings:[`Configuration loading failed, using defaults: ${U instanceof Error?U.message:String(U)}`]}}if(A||_)await this.validateConfiguration(Y.config,A,_,W.name);if(G?.enabled&&Y)this.cacheResult(W.name||"",Y,G,W);if($?.enabled){let U={operation:"loadConfig",duration:Date.now()-w,configName:W.name,timestamp:new Date};if($.onMetrics)$.onMetrics(U);if($.slowThreshold&&U.duration>$.slowThreshold)GI.warn(`Slow configuration loading detected: ${U.duration}ms for ${W.name}`);Y.metrics=U}return Y}catch(Y){if(Y instanceof Error&&Y.name==="ConfigNotFoundError")throw Y;let U=Date.now()-w;throw GI.error(`Configuration loading failed after ${U}ms:`,[Y instanceof Error?Y:Error(String(Y))]),Y}}async loadConfigurationStrategies(I,w=!1,G){let{name:$="",alias:A,cwd:_,configDir:W,defaultConfig:Y,checkEnv:U=!0,arrayStrategy:H="replace",verbose:Z=!1}=I,q=_||Nw.cwd(),Q=[],b=await this.loadLocalConfiguration($,A,q,W,Y,H,Z,U,G);if(b)return Q.push(...this.getLocalSearchPaths($,A,q,W)),this.finalizeResult(b,Q,U,$,Z);let X=await this.loadHomeConfiguration($,A,Y,H,Z,U);if(X)return Q.push(...this.getHomeSearchPaths($,A)),this.finalizeResult(X,Q,U,$,Z);let L=await this.loadPackageJsonConfiguration($,A,q,Y,H,Z,U);if(L)return Q.push(o(q,"package.json")),this.finalizeResult(L,Q,U,$,Z);if(Q.push(...this.getAllSearchPaths($,A,q,W)),w)throw xI.configNotFound($,Q,A);return{...await this.applyEnvironmentVariables($,Y,U,Z),warnings:[`No configuration file found for "${$}"${VW(A)}, using defaults with environment variables`]}}async loadLocalConfiguration(I,w,G,$,A,_,W,Y,U){let H=Y?Zw(I,A,W):A,Z=this.getLocalDirectories(G,$);for(let q of Z){if(W)GI.info(`Searching for configuration in: ${q}`);let Q=this.fileLoader.generateConfigPaths(I,q,w),b=await this.fileLoader.tryLoadFromPaths(Q,H,{arrayStrategy:_,verbose:W,cacheTtl:U?.ttl,useCache:!U?.ttl||U.ttl>100});if(b){if(W)GI.success(`Configuration loaded from: ${b.source.path}`);return b}}return null}async loadHomeConfiguration(I,w,G,$,A,_){if(!I)return null;let W=_?Zw(I,G,A):G,Y=[o(KI(),".config",I),o(KI(),".config"),KI()];for(let U of Y){if(A)GI.info(`Checking home directory: ${U}`);let H=this.fileLoader.generateConfigPaths(I,U,w),Z=await this.fileLoader.tryLoadFromPaths(H,W,{arrayStrategy:$,verbose:A});if(Z){if(A)GI.success(`Configuration loaded from home directory: ${Z.source.path}`);return Z}}return null}async loadPackageJsonConfiguration(I,w,G,$,A,_,W){let Y=W?Zw(I,$,_):$;try{let U=o(G,"package.json");if(!S0(U))return null;let H={};try{H=JSON.parse(E0(U,"utf8"))}catch(Q){if(_)GI.warn("Failed to parse package.json:",[Q instanceof Error?Q:Error(String(Q))]);return null}let Z=H[I],q=I;if(!Z&&w){let Q=Array.isArray(w)?w:[w];for(let b of Q){if(!b)continue;if(H[b]){Z=H[b],q=b;break}}}if(Z&&typeof Z==="object"&&!Array.isArray(Z)){if(_)GI.success(`Configuration loaded from package.json: ${q}`);return{config:BA(Y,Z,A),source:{type:"package.json",path:U,priority:30,timestamp:new Date}}}}catch(U){if(_)GI.warn("Failed to load package.json:",[U instanceof Error?U:Error(String(U))])}return null}async applyEnvironmentVariables(I,w,G,$){if(!G||!I||typeof w!=="object"||w===null||Array.isArray(w))return{config:w,source:{type:"default",priority:10,timestamp:new Date}};return{config:Zw(I,w,$),source:{type:"environment",priority:20,timestamp:new Date}}}async finalizeResult(I,w,G,$,A){return{config:I.config,source:I.source,path:I.source.path}}async validateConfiguration(I,w,G,$){let A=[];if(G){let _=G(I);if(_)A.push(..._)}if(w){let _=await this.validator.validateConfiguration(I,w);if(!_.isValid)A.push(..._.errors.map((W)=>W.path?`${W.path}: ${W.message}`:W.message))}if(A.length>0)throw xI.configValidation($||"unknown",A,$)}checkCache(I,w){let G=this.generateCacheKey(I,w);return Jw.get(G)||null}cacheResult(I,w,G,$){let A=this.generateCacheKey(I,$);Jw.set(A,w,void 0,G.ttl)}generateCacheKey(I,w){let G=[I];if(w.alias){let $=Array.isArray(w.alias)?w.alias.join(","):w.alias;G.push(`alias:${$}`)}if(w.cwd)G.push(`cwd:${w.cwd}`);if(w.configDir)G.push(`configDir:${w.configDir}`);if("checkEnv"in w)G.push(`checkEnv:${w.checkEnv}`);return G.join("|")}getLocalDirectories(I,w){return Array.from(new Set([I,o(I,"config"),o(I,".config"),w?o(I,w):void 0].filter(Boolean)))}getAllSearchPaths(I,w,G,$){let A=[];return A.push(...this.getLocalSearchPaths(I,w,G,$)),A.push(...this.getHomeSearchPaths(I,w)),A.push(o(G,"package.json")),A}getLocalSearchPaths(I,w,G,$){let A=this.getLocalDirectories(G,$),_=[];for(let W of A)_.push(...this.fileLoader.generateConfigPaths(I,W,w));return _}getHomeSearchPaths(I,w){if(!I)return[];let G=[o(KI(),".config",I),o(KI(),".config"),KI()],$=[];for(let A of G)$.push(...this.fileLoader.generateConfigPaths(I,A,w));return $}async loadConfigWithResult(I){return this.loadConfig(I)}}var YG=new KA;async function TA(I){let w="defaultConfig"in I&&I.defaultConfig!==void 0?I.defaultConfig:{},G="cache"in I||"performance"in I||"schema"in I||"validate"in I;try{let $;if(G)$=await YG.loadConfig(I);else $=await YG.loadConfig({...I,defaultConfig:w,cache:{enabled:!0},performance:{enabled:!1}});return $?.config??w}catch($){let A=$ instanceof Error?$.name:"UnknownError",_=$ instanceof Error?$.message:String($);if(!(A==="ConfigNotFoundError"||A==="ConfigLoadError"||A==="ConfigValidationError"||_.includes("config"))&&I.verbose)GI.warn("Unexpected error loading config, using defaults:",[$ instanceof Error?$:Error(String($))]);let Y=G?{...I,defaultConfig:w}:{...I,defaultConfig:w,cache:{enabled:!0},performance:{enabled:!1}};if("checkEnv"in I?I.checkEnv!==!1:!0)return(await YG.applyEnvironmentVariables(Y.name||"",w,!0,Y.verbose||!1))?.config??w;return w}}function Zw(I,w,G=!1){let $=new jG,A=I.toUpperCase().replace(/[^A-Z0-9]/g,"_");function _(W,Y=[]){let U={...W};for(let[H,Z]of Object.entries(W)){let q=[...Y,H],Q=[`${A}_${q.join("_").toUpperCase()}`,`${A}_${q.map((L)=>L.toUpperCase()).join("")}`,`${A}_${q.map((L)=>L.replace(/([A-Z])/g,"_$1").toUpperCase()).join("")}`],b,X;for(let L of Q)if(b=Nw.env[L],b!==void 0){X=L;break}if(b!==void 0&&X)if(typeof Z==="boolean")U[H]=["true","1","yes"].includes(b.toLowerCase());else if(typeof Z==="number"){let L=Number(b);if(!Number.isNaN(L))U[H]=L}else if(Array.isArray(Z))try{U[H]=JSON.parse(b)}catch{U[H]=b.split(",").map((L)=>L.trim())}else U[H]=b;else if(Z&&typeof Z==="object"&&!Array.isArray(Z))U[H]=_(Z,q)}return U}return _(w)}var D1=o(Nw.cwd(),"config"),R1=o(Nw.cwd(),"src/generated");var MA={verbose:!1,outputDir:"./watch-data",watchPaths:["/Volumes"]},NG=null;async function M1(){if(!NG)NG=await TA({name:"watches",defaultConfig:MA});return NG}var C1=MA;import{existsSync as xW,readdirSync as CA,statSync as SA,readFileSync as Pw,mkdirSync as kW,copyFileSync as EA}from"fs";import{join as iI,extname as PW}from"path";var VG="/Volumes",yW=["POLAR","VANTAGE","GRIT","IGNITE","PACER","UNITE"];function OA(I){let w=I.split(`
|
|
61
|
+
`).map((F)=>F.trim()),G=new Map,$="";for(let F of w)if(F.startsWith("[")&&F.endsWith("]"))$=F.slice(1,-1),G.set($,[]);else if($&&F)G.get($)?.push(F);let A=G.get("Params")||[],_=G.get("HRData")||[];if(A.length===0)return null;let W=new Map;for(let F of A){let[j,c]=F.split("=");if(j&&c)W.set(j.trim(),c.trim())}let Y=W.get("Date"),U=W.get("StartTime"),H=parseInt(W.get("Interval")||"1",10),Z=W.get("Length");if(!Y||!U)return null;let q=parseInt(Y.slice(0,4),10),Q=parseInt(Y.slice(4,6),10)-1,b=parseInt(Y.slice(6,8),10),[X,L,J]=U.split(":"),B=parseFloat(J||"0"),E=new Date(q,Q,b,parseInt(X,10),parseInt(L,10),Math.floor(B)),x=0;if(Z){let[F,j,c]=Z.split(":").map(Number);x=F*3600+j*60+c}let P=[],n=new Date(E);for(let F of _){let j=F.split("\t").map((vI)=>parseInt(vI,10)),c=j[0];if(c>0)P.push({timestamp:new Date(n),heartRate:c,speed:j[1]?j[1]/10:void 0,cadence:j[2],altitude:j[3],power:j[4]});n=new Date(n.getTime()+H*1000)}let wI=P.filter((F)=>F.heartRate).map((F)=>F.heartRate),O=wI.length>0?Math.round(wI.reduce((F,j)=>F+j,0)/wI.length):void 0,f=wI.length>0?Math.max(...wI):void 0;return{id:`polar_${E.getTime()}`,sport:"other",startTime:E,endTime:new Date(E.getTime()+x*1000),totalElapsedTime:x,totalTimerTime:x,totalDistance:0,totalCalories:parseInt(W.get("Calories")||"0",10),avgHeartRate:O,maxHeartRate:f,laps:[],records:P,source:"garmin"}}function zA(I){try{let w=JSON.parse(I);if(!w.startTime)return null;let G=new Date(w.startTime),$=w.stopTime?new Date(w.stopTime):new Date(G.getTime()+(w.duration||0)),A=[];if(w.samples)for(let W of w.samples)A.push({timestamp:new Date(W.dateTime||G),heartRate:W.heartRate,speed:W.speed,cadence:W.cadence,altitude:W.altitude,distance:W.distance,power:W.power,position:W.latitude&&W.longitude?{lat:W.latitude,lng:W.longitude,altitude:W.altitude}:void 0});let _=[];if(w.laps)for(let W of w.laps)_.push({startTime:new Date(W.startTime||G),endTime:new Date(W.stopTime||$),totalElapsedTime:W.duration||0,totalTimerTime:W.duration||0,totalDistance:W.distance||0,totalCalories:W.calories||0,avgHeartRate:W.heartRate?.average,maxHeartRate:W.heartRate?.maximum,avgSpeed:W.speed?.average,maxSpeed:W.speed?.maximum,avgCadence:W.cadence?.average,maxCadence:W.cadence?.maximum});return{id:`polar_${w.id||G.getTime()}`,name:w.name,sport:uW(w.sport),startTime:G,endTime:$,totalElapsedTime:w.duration||($.getTime()-G.getTime())/1000,totalTimerTime:w.duration||($.getTime()-G.getTime())/1000,totalDistance:w.distance||0,totalCalories:w.calories||0,avgHeartRate:w.heartRate?.average,maxHeartRate:w.heartRate?.maximum,avgSpeed:w.speed?.average,maxSpeed:w.speed?.maximum,avgCadence:w.cadence?.average,maxCadence:w.cadence?.maximum,avgPower:w.power?.average,maxPower:w.power?.maximum,totalAscent:w.ascent,totalDescent:w.descent,laps:_,records:A,source:"garmin"}}catch{return null}}function uW(I){if(!I)return"other";return{RUNNING:"running",CYCLING:"cycling",SWIMMING:"swimming",WALKING:"walking",HIKING:"hiking",STRENGTH_TRAINING:"strength_training",OTHER:"other"}[I.toUpperCase()]||"other"}class FA{name="Polar";type="polar";async detectDevices(){let I=[];if(!xW(VG))return I;let w=CA(VG);for(let G of w){let $=iI(VG,G);try{if(!SA($).isDirectory())continue}catch{continue}let A=G.toUpperCase();if(yW.some((W)=>A.includes(W)))I.push({name:G,path:$,type:"polar",model:G})}return I}async downloadData(I,w={}){let{outputDir:G="./polar-data",copyRawFiles:$=!0}=w,A={device:I,activities:[],monitoring:new Map,rawFiles:[],errors:[]},_=new Date().toISOString().replace(/[:.]/g,"-").slice(0,19),W=iI(G,_);if($)kW(W,{recursive:!0});let Y=this.findFiles(I.path,".hrm");for(let H of Y)try{let Z=Pw(H,"utf-8"),q=OA(Z);if(q)q.rawFilePath=H,A.activities.push(q);if($){let Q=iI(W,H.split("/").pop());EA(H,Q),A.rawFiles.push(Q)}}catch(Z){A.errors.push(Z instanceof Error?Z:Error(String(Z)))}let U=this.findFiles(I.path,".json");for(let H of U)try{let Z=Pw(H,"utf-8"),q=zA(Z);if(q)q.rawFilePath=H,A.activities.push(q);if($){let Q=iI(W,H.split("/").pop());EA(H,Q),A.rawFiles.push(Q)}}catch(Z){A.errors.push(Z instanceof Error?Z:Error(String(Z)))}return A.activities.sort((H,Z)=>H.startTime.getTime()-Z.startTime.getTime()),A}async parseActivityFile(I){let w=PW(I).toLowerCase();if(w===".hrm"){let G=Pw(I,"utf-8");return OA(G)}if(w===".json"){let G=Pw(I,"utf-8");return zA(G)}throw Error(`Unsupported file format: ${w}`)}async parseMonitoringFile(I){return{}}findFiles(I,w){let G=[];try{let $=CA(I);for(let A of $){let _=iI(I,A);try{if(SA(_).isDirectory())G.push(...this.findFiles(_,w));else if(A.toLowerCase().endsWith(w))G.push(_)}catch{}}}catch{}return G}}function z1(){return new FA}import{existsSync as mW,readdirSync as jA,statSync as NA,readFileSync as yw,mkdirSync as hW,copyFileSync as VA}from"fs";import{join as rI,extname as nW}from"path";var xG="/Volumes",fW=["SUUNTO","AMBIT","SPARTAN","SUUNTO 9","SUUNTO 7","SUUNTO 5","VERTICAL","RACE"];function xA(I){let w=(O,f)=>{let F=new RegExp(`<${f}[^>]*>([\\s\\S]*?)</${f}>`,"i"),j=O.match(F);return j?j[1].trim():null},G=(O,f)=>{let F=new RegExp(`<${f}[^>]*>([\\s\\S]*?)</${f}>`,"gi"),j=[],c;while((c=F.exec(O))!==null)j.push(c[1].trim());return j},$=w(I,"Header");if(!$)return null;let A=w($,"DateTime"),_=parseFloat(w($,"Duration")||"0"),W=parseFloat(w($,"Distance")||"0"),Y=parseInt(w($,"Energy")||"0",10)/4184,U=parseFloat(w($,"Ascent")||"0"),H=parseFloat(w($,"Descent")||"0"),Z=w($,"ActivityType");if(!A)return null;let q=new Date(A),Q=new Date(q.getTime()+_*1000),b=[],X=G(I,"Sample");for(let O of X){let f=w(O,"UTC"),F=parseInt(w(O,"HR")||"0",10),j=parseFloat(w(O,"Speed")||"0"),c=parseInt(w(O,"Cadence")||"0",10),vI=parseFloat(w(O,"Altitude")||"0"),sG=parseFloat(w(O,"Latitude")||"0"),tG=parseFloat(w(O,"Longitude")||"0"),aG=parseInt(w(O,"BikePower")||"0",10);if(f)b.push({timestamp:new Date(f),heartRate:F>0?F*60:void 0,speed:j>0?j:void 0,cadence:c>0?c*60:void 0,altitude:vI!==0?vI:void 0,power:aG>0?aG:void 0,position:sG!==0&&tG!==0?{lat:sG*(180/Math.PI),lng:tG*(180/Math.PI),altitude:vI}:void 0})}let L=[],J=G(I,"Mark");for(let O of J){let f=w(O,"Time");if(w(O,"Type")==="lap"&&f){let j=parseFloat(f);L.push({startTime:new Date(q.getTime()+j*1000),endTime:new Date(q.getTime()+j*1000),totalElapsedTime:0,totalTimerTime:0,totalDistance:0,totalCalories:0})}}let B=b.filter((O)=>O.heartRate).map((O)=>O.heartRate),E=B.length>0?Math.round(B.reduce((O,f)=>O+f,0)/B.length):void 0,x=B.length>0?Math.max(...B):void 0,P=b.filter((O)=>O.speed).map((O)=>O.speed),n=P.length>0?P.reduce((O,f)=>O+f,0)/P.length:void 0,wI=P.length>0?Math.max(...P):void 0;return{id:`suunto_${q.getTime()}`,sport:PA(Z??void 0),startTime:q,endTime:Q,totalElapsedTime:_,totalTimerTime:_,totalDistance:W,totalCalories:Math.round(Y),avgHeartRate:E,maxHeartRate:x,avgSpeed:n,maxSpeed:wI,totalAscent:U,totalDescent:H,laps:L,records:b,source:"garmin"}}function kA(I){try{let w=JSON.parse(I),G=new Date(w.StartTime||w.startTime),$=w.Duration||w.duration||0,A=new Date(G.getTime()+$*1000),_=[],W=w.TrackPoints||w.trackPoints||w.Samples||w.samples||[];for(let Y of W)_.push({timestamp:new Date(Y.Time||Y.time||Y.Timestamp),heartRate:Y.HR||Y.hr||Y.HeartRate,speed:Y.Speed||Y.speed,cadence:Y.Cadence||Y.cadence,altitude:Y.Altitude||Y.altitude,distance:Y.Distance||Y.distance,power:Y.Power||Y.power,position:(Y.Latitude||Y.latitude)&&(Y.Longitude||Y.longitude)?{lat:Y.Latitude||Y.latitude,lng:Y.Longitude||Y.longitude,altitude:Y.Altitude||Y.altitude}:void 0});return{id:`suunto_${w.MoveId||w.moveId||G.getTime()}`,name:w.Name||w.name,sport:PA(w.ActivityType||w.activityType||w.Sport||w.sport),startTime:G,endTime:A,totalElapsedTime:$,totalTimerTime:$,totalDistance:w.Distance||w.distance||0,totalCalories:Math.round((w.Energy||w.energy||0)/4.184),avgHeartRate:w.AvgHR||w.avgHR||w.HeartRateAvg,maxHeartRate:w.MaxHR||w.maxHR||w.HeartRateMax,avgSpeed:w.AvgSpeed||w.avgSpeed,maxSpeed:w.MaxSpeed||w.maxSpeed,totalAscent:w.Ascent||w.ascent||w.AscentAltitude,totalDescent:w.Descent||w.descent||w.DescentAltitude,laps:[],records:_,source:"garmin"}}catch{return null}}function PA(I){if(!I)return"other";let w=typeof I==="number"?I.toString():I.toLowerCase();return{running:"running",run:"running","1":"running",cycling:"cycling",bike:"cycling","2":"cycling",swimming:"swimming",swim:"swimming","5":"swimming",hiking:"hiking",trekking:"hiking","11":"hiking",walking:"walking","3":"walking"}[w]||"other"}class yA{name="Suunto";type="suunto";async detectDevices(){let I=[];if(!mW(xG))return I;let w=jA(xG);for(let G of w){let $=rI(xG,G);try{if(!NA($).isDirectory())continue}catch{continue}let A=G.toUpperCase();if(fW.some((W)=>A.includes(W)))I.push({name:G,path:$,type:"suunto",model:G})}return I}async downloadData(I,w={}){let{outputDir:G="./suunto-data",copyRawFiles:$=!0}=w,A={device:I,activities:[],monitoring:new Map,rawFiles:[],errors:[]},_=new Date().toISOString().replace(/[:.]/g,"-").slice(0,19),W=rI(G,_);if($)hW(W,{recursive:!0});let Y=this.findFiles(I.path,".sml");for(let H of Y)try{let Z=yw(H,"utf-8"),q=xA(Z);if(q)q.rawFilePath=H,A.activities.push(q);if($){let Q=rI(W,H.split("/").pop());VA(H,Q),A.rawFiles.push(Q)}}catch(Z){A.errors.push(Z instanceof Error?Z:Error(String(Z)))}let U=this.findFiles(I.path,".json");for(let H of U)try{let Z=yw(H,"utf-8"),q=kA(Z);if(q)q.rawFilePath=H,A.activities.push(q);if($){let Q=rI(W,H.split("/").pop());VA(H,Q),A.rawFiles.push(Q)}}catch(Z){A.errors.push(Z instanceof Error?Z:Error(String(Z)))}return A.activities.sort((H,Z)=>H.startTime.getTime()-Z.startTime.getTime()),A}async parseActivityFile(I){let w=nW(I).toLowerCase();if(w===".sml"){let G=yw(I,"utf-8");return xA(G)}if(w===".json"){let G=yw(I,"utf-8");return kA(G)}throw Error(`Unsupported file format: ${w}`)}async parseMonitoringFile(I){return{}}findFiles(I,w){let G=[];try{let $=jA(I);for(let A of $){let _=rI(I,A);try{if(NA(_).isDirectory())G.push(...this.findFiles(_,w));else if(A.toLowerCase().endsWith(w))G.push(_)}catch{}}}catch{}return G}}function V1(){return new yA}import{existsSync as kG,readdirSync as uA,statSync as mA,mkdirSync as hA,copyFileSync as vW,readFileSync as nA}from"fs";import{join as qI,extname as fA}from"path";var PG="/Volumes",gW=["COROS","PACE","APEX","VERTIX","DURA"];class vA{name="Coros";type="coros";async detectDevices(){let I=[];if(!kG(PG))return I;let w=uA(PG);for(let G of w){let $=qI(PG,G);try{if(!mA($).isDirectory())continue}catch{continue}let A=G.toUpperCase(),_=gW.some((W)=>A.includes(W));if(!_){let W=qI($,"COROS");if(kG(W)){I.push({name:G,path:$,type:"coros",model:G});continue}}if(_)I.push({name:G,path:$,type:"coros",model:G})}return I}async downloadData(I,w={}){let{outputDir:G="./coros-data",includeActivities:$=!0,since:A,until:_,copyRawFiles:W=!0}=w,Y={device:I,activities:[],monitoring:new Map,rawFiles:[],errors:[]},U=new Date().toISOString().replace(/[:.]/g,"-").slice(0,19),H=qI(G,U);if(W)hA(H,{recursive:!0});let Z=[qI(I.path,"Activity"),qI(I.path,"COROS","Activity"),qI(I.path,"GARMIN","Activity")];if($)for(let q of Z){if(!kG(q))continue;let Q=uA(q).filter((b)=>b.toLowerCase().endsWith(".fit"));for(let b of Q){let X=qI(q,b);try{let J=mA(X).mtime;if(A&&J<A)continue;if(_&&J>_)continue;let B=await this.parseActivityFile(X);if(B)B.rawFilePath=X,Y.activities.push(B);if(W){let E=qI(H,"Activity");hA(E,{recursive:!0});let x=qI(E,b);vW(X,x),Y.rawFiles.push(x)}}catch(L){Y.errors.push(L instanceof Error?L:Error(String(L)))}}}return Y.activities.sort((q,Q)=>q.startTime.getTime()-Q.startTime.getTime()),Y}async parseActivityFile(I){let w=fA(I).toLowerCase();if(w!==".fit")throw Error(`Unsupported file format: ${w}`);let G=nA(I),A=new kI(G).parse();return new PI(A).decodeActivity()}async parseMonitoringFile(I){let w=fA(I).toLowerCase();if(w!==".fit")throw Error(`Unsupported file format: ${w}`);let G=nA(I),A=new kI(G).parse();return new PI(A).decodeMonitoring()}}function u1(){return new vA}import{existsSync as yG,readdirSync as uG,statSync as gA,mkdirSync as dA,copyFileSync as dW,readFileSync as pA}from"fs";import{join as bI,extname as lA}from"path";var mG="/Volumes",pW=["WAHOO","ELEMNT","BOLT","ROAM","RIVAL"];class cA{name="Wahoo";type="wahoo";async detectDevices(){let I=[];if(!yG(mG))return I;let w=uG(mG);for(let G of w){let $=bI(mG,G);try{if(!gA($).isDirectory())continue}catch{continue}let A=G.toUpperCase(),_=pW.some((W)=>A.includes(W));if(!_){let W=bI($,"activities");if(yG(W)){if(uG(W).some((U)=>U.toLowerCase().endsWith(".fit"))){I.push({name:G,path:$,type:"wahoo",model:G});continue}}}if(_)I.push({name:G,path:$,type:"wahoo",model:G})}return I}async downloadData(I,w={}){let{outputDir:G="./wahoo-data",includeActivities:$=!0,since:A,until:_,copyRawFiles:W=!0}=w,Y={device:I,activities:[],monitoring:new Map,rawFiles:[],errors:[]},U=new Date().toISOString().replace(/[:.]/g,"-").slice(0,19),H=bI(G,U);if(W)dA(H,{recursive:!0});let Z=[bI(I.path,"activities"),bI(I.path,"Activity"),bI(I.path,"workouts")];if($)for(let q of Z){if(!yG(q))continue;let Q=uG(q).filter((b)=>b.toLowerCase().endsWith(".fit"));for(let b of Q){let X=bI(q,b);try{let J=gA(X).mtime;if(A&&J<A)continue;if(_&&J>_)continue;let B=await this.parseActivityFile(X);if(B)B.rawFilePath=X,Y.activities.push(B);if(W){let E=bI(H,"activities");dA(E,{recursive:!0});let x=bI(E,b);dW(X,x),Y.rawFiles.push(x)}}catch(L){Y.errors.push(L instanceof Error?L:Error(String(L)))}}}return Y.activities.sort((q,Q)=>q.startTime.getTime()-Q.startTime.getTime()),Y}async parseActivityFile(I){let w=lA(I).toLowerCase();if(w!==".fit")throw Error(`Unsupported file format: ${w}`);let G=pA(I),A=new kI(G).parse();return new PI(A).decodeActivity()}async parseMonitoringFile(I){let w=lA(I).toLowerCase();if(w!==".fit")throw Error(`Unsupported file format: ${w}`);let G=pA(I),A=new kI(G).parse();return new PI(A).decodeMonitoring()}}function v1(){return new cA}import{existsSync as iA,readFileSync as lW}from"fs";function cW(I){let w=[],G=[],$=/<Workout([^>]+)>/g,A;while((A=$.exec(I))!==null){let Y=rA(A[1]);w.push({workoutActivityType:Y.workoutActivityType||"",duration:Y.duration||"0",durationUnit:Y.durationUnit||"min",totalDistance:Y.totalDistance||"0",totalDistanceUnit:Y.totalDistanceUnit||"km",totalEnergyBurned:Y.totalEnergyBurned||"0",totalEnergyBurnedUnit:Y.totalEnergyBurnedUnit||"kcal",sourceName:Y.sourceName||"",startDate:Y.startDate||"",endDate:Y.endDate||""})}let _=/<Record([^>]+)\/>/g,W;while((W=_.exec(I))!==null){let Y=rA(W[1]);G.push({type:Y.type||"",sourceName:Y.sourceName||"",unit:Y.unit||"",value:Y.value||"0",startDate:Y.startDate||"",endDate:Y.endDate||"",creationDate:Y.creationDate})}return{workouts:w,records:G}}function rA(I){let w={},G=/(\w+)="([^"]*)"/g,$;while(($=G.exec(I))!==null)w[$[1]]=$[2];return w}function uw(I){return new Date(I.replace(" ","T").replace(" ",""))}function iW(I){return{HKWorkoutActivityTypeRunning:"running",HKWorkoutActivityTypeCycling:"cycling",HKWorkoutActivityTypeSwimming:"swimming",HKWorkoutActivityTypeHiking:"hiking",HKWorkoutActivityTypeWalking:"walking",HKWorkoutActivityTypeFunctionalStrengthTraining:"strength_training",HKWorkoutActivityTypeTraditionalStrengthTraining:"strength_training",HKWorkoutActivityTypeYoga:"yoga",HKWorkoutActivityTypeCrossTraining:"cardio",HKWorkoutActivityTypeElliptical:"cardio",HKWorkoutActivityTypeRowing:"cardio",HKWorkoutActivityTypeStairClimbing:"cardio"}[I]||"other"}class oA{name="Apple";type="apple";async detectDevices(){return[]}async downloadData(I,w={}){return{device:I,activities:[],monitoring:new Map,rawFiles:[],errors:[Error("Apple Watch data must be imported from Health app export. Use parseHealthExport() instead.")]}}async parseHealthExport(I){let w=iA(I)?I:`${I}/apple_health_export/export.xml`;if(!iA(w))throw Error(`Health export not found at ${w}`);let G=lW(w,"utf-8"),{workouts:$,records:A}=cW(G),_=$.filter((q)=>q.sourceName.includes("Watch")).map((q)=>this.workoutToActivity(q)),W=new Map,Y=A.filter((q)=>q.type==="HKQuantityTypeIdentifierHeartRate"),U=new Map;for(let q of Y){let Q=uw(q.startDate),b=Q.toISOString().slice(0,10),X=U.get(b)||[];X.push({timestamp:Q,heartRate:parseInt(q.value,10)}),U.set(b,X)}for(let[q,Q]of U){let b=W.get(q)||{},X=Q.map((L)=>L.heartRate);b.heartRate={date:new Date(q),minHeartRate:Math.min(...X),maxHeartRate:Math.max(...X),avgHeartRate:Math.round(X.reduce((L,J)=>L+J,0)/X.length),samples:Q},W.set(q,b)}let H=A.filter((q)=>q.type==="HKQuantityTypeIdentifierStepCount"),Z=new Map;for(let q of H){let b=uw(q.startDate).toISOString().slice(0,10),X=Z.get(b)||0;Z.set(b,X+parseInt(q.value,10))}for(let[q,Q]of Z){let b=W.get(q)||{};b.steps={date:new Date(q),totalSteps:Q,goal:1e4,distance:0,calories:0,activeMinutes:0},W.set(q,b)}return{activities:_,monitoring:W}}workoutToActivity(I){let w=uw(I.startDate),G=uw(I.endDate),$=parseFloat(I.duration);if(I.durationUnit==="min")$*=60;else if(I.durationUnit==="hr")$*=3600;let A=parseFloat(I.totalDistance);if(I.totalDistanceUnit==="km")A*=1000;else if(I.totalDistanceUnit==="mi")A*=1609.34;let _=parseFloat(I.totalEnergyBurned);if(I.totalEnergyBurnedUnit==="kJ")_/=4.184;return{id:`apple_${w.getTime()}`,sport:iW(I.workoutActivityType),startTime:w,endTime:G,totalElapsedTime:$,totalTimerTime:$,totalDistance:A,totalCalories:Math.round(_),laps:[],records:[],source:"garmin"}}async parseActivityFile(I){throw Error("Apple Watch activities must be imported via Health export")}async parseMonitoringFile(I){throw Error("Apple Watch monitoring data must be imported via Health export")}}function p1(){return new oA}var rW={creator:"ts-watches",includeHeartRate:!0,includeCadence:!0,includePower:!0,includeTemperature:!0};function oW(I,w={}){let G={...rW,...w},$=I.records.filter((_)=>_.position?.lat!=null&&_.position?.lng!=null).map((_)=>sW(_,G)).join(`
|
|
62
|
+
`),A=tW(I,G);return`<?xml version="1.0" encoding="UTF-8"?>
|
|
63
|
+
<gpx version="1.1" creator="${G.creator}"
|
|
64
|
+
xmlns="http://www.topografix.com/GPX/1/1"
|
|
65
|
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
66
|
+
xmlns:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1"
|
|
67
|
+
xmlns:gpxx="http://www.garmin.com/xmlschemas/GpxExtensions/v3"
|
|
68
|
+
xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd">
|
|
69
|
+
<metadata>
|
|
70
|
+
<name>${sA(I.name||`${I.sport} - ${I.startTime.toISOString()}`)}</name>
|
|
71
|
+
<time>${I.startTime.toISOString()}</time>
|
|
72
|
+
</metadata>
|
|
73
|
+
<trk>
|
|
74
|
+
<name>${sA(I.name||I.sport)}</name>
|
|
75
|
+
<type>${aW(I.sport)}</type>${A}
|
|
76
|
+
<trkseg>
|
|
77
|
+
${$}
|
|
78
|
+
</trkseg>
|
|
79
|
+
</trk>
|
|
80
|
+
</gpx>`}function sW(I,w){let{position:G,timestamp:$,heartRate:A,cadence:_,power:W,temperature:Y,altitude:U}=I;if(!G)return"";let H=[];if(w.includeHeartRate&&A!=null)H.push(` <gpxtpx:hr>${A}</gpxtpx:hr>`);if(w.includeCadence&&_!=null)H.push(` <gpxtpx:cad>${_}</gpxtpx:cad>`);if(w.includePower&&W!=null)H.push(` <gpxtpx:power>${W}</gpxtpx:power>`);if(w.includeTemperature&&Y!=null)H.push(` <gpxtpx:atemp>${Y}</gpxtpx:atemp>`);let Z=H.length>0?`
|
|
81
|
+
<extensions>
|
|
82
|
+
<gpxtpx:TrackPointExtension>
|
|
83
|
+
${H.join(`
|
|
84
|
+
`)}
|
|
85
|
+
</gpxtpx:TrackPointExtension>
|
|
86
|
+
</extensions>`:"",q=U??G.altitude,Q=q!=null?`
|
|
87
|
+
<ele>${q.toFixed(1)}</ele>`:"";return` <trkpt lat="${G.lat.toFixed(7)}" lon="${G.lng.toFixed(7)}">${Q}
|
|
88
|
+
<time>${$.toISOString()}</time>${Z}
|
|
89
|
+
</trkpt>`}function tW(I,w){let G=[];if(I.totalDistance)G.push(` <gpxx:Distance>${I.totalDistance.toFixed(0)}</gpxx:Distance>`);if(I.totalTimerTime)G.push(` <gpxx:TimerTime>${I.totalTimerTime.toFixed(0)}</gpxx:TimerTime>`);if(I.totalCalories)G.push(` <gpxx:Calories>${I.totalCalories}</gpxx:Calories>`);if(I.avgHeartRate)G.push(` <gpxx:AvgHeartRate>${I.avgHeartRate}</gpxx:AvgHeartRate>`);if(I.maxHeartRate)G.push(` <gpxx:MaxHeartRate>${I.maxHeartRate}</gpxx:MaxHeartRate>`);if(I.avgCadence)G.push(` <gpxx:AvgCadence>${I.avgCadence}</gpxx:AvgCadence>`);if(I.avgSpeed)G.push(` <gpxx:AvgSpeed>${I.avgSpeed.toFixed(2)}</gpxx:AvgSpeed>`);if(G.length===0)return"";return`
|
|
90
|
+
<extensions>
|
|
91
|
+
<gpxx:TrackExtension>
|
|
92
|
+
${G.join(`
|
|
93
|
+
`)}
|
|
94
|
+
</gpxx:TrackExtension>
|
|
95
|
+
</extensions>`}function aW(I){return{running:"running",cycling:"cycling",swimming:"swimming",hiking:"hiking",walking:"walking",other:"other"}[I]||"other"}function sA(I){return I.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}async function e1(I,w,G){let $=oW(I,G);await Bun.write(w,$)}var eW={creator:"ts-watches",deviceName:"ts-watches",includeHeartRate:!0,includeCadence:!0,includePower:!0};function IY(I,w={}){let G={...eW,...w},$=I.laps.length>0?I.laps.map((A,_)=>wY(A,_Y(I.records,A),G)).join(`
|
|
96
|
+
`):GY(I,G);return`<?xml version="1.0" encoding="UTF-8"?>
|
|
97
|
+
<TrainingCenterDatabase
|
|
98
|
+
xmlns="http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2"
|
|
99
|
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
100
|
+
xmlns:ns3="http://www.garmin.com/xmlschemas/ActivityExtension/v2"
|
|
101
|
+
xsi:schemaLocation="http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2 http://www.garmin.com/xmlschemas/TrainingCenterDatabasev2.xsd">
|
|
102
|
+
<Activities>
|
|
103
|
+
<Activity Sport="${WY(I.sport)}">
|
|
104
|
+
<Id>${I.startTime.toISOString()}</Id>
|
|
105
|
+
${$}
|
|
106
|
+
<Creator xsi:type="Device_t">
|
|
107
|
+
<Name>${tA(G.deviceName)}</Name>
|
|
108
|
+
<UnitId>0</UnitId>
|
|
109
|
+
<ProductID>0</ProductID>
|
|
110
|
+
</Creator>
|
|
111
|
+
</Activity>
|
|
112
|
+
</Activities>
|
|
113
|
+
<Author xsi:type="Application_t">
|
|
114
|
+
<Name>${tA(G.creator)}</Name>
|
|
115
|
+
<Build>
|
|
116
|
+
<Version>
|
|
117
|
+
<VersionMajor>1</VersionMajor>
|
|
118
|
+
<VersionMinor>0</VersionMinor>
|
|
119
|
+
</Version>
|
|
120
|
+
</Build>
|
|
121
|
+
<LangID>en</LangID>
|
|
122
|
+
<PartNumber>000-00000-00</PartNumber>
|
|
123
|
+
</Author>
|
|
124
|
+
</TrainingCenterDatabase>`}function wY(I,w,G){let $=w.map((A)=>aA(A,G)).filter((A)=>A.length>0).join(`
|
|
125
|
+
`);return` <Lap StartTime="${I.startTime.toISOString()}">
|
|
126
|
+
<TotalTimeSeconds>${I.totalTimerTime.toFixed(1)}</TotalTimeSeconds>
|
|
127
|
+
<DistanceMeters>${I.totalDistance.toFixed(1)}</DistanceMeters>
|
|
128
|
+
<MaximumSpeed>${I.maxSpeed?I.maxSpeed.toFixed(2):"0.00"}</MaximumSpeed>
|
|
129
|
+
<Calories>${I.totalCalories}</Calories>${I.avgHeartRate?`
|
|
130
|
+
<AverageHeartRateBpm>
|
|
131
|
+
<Value>${I.avgHeartRate}</Value>
|
|
132
|
+
</AverageHeartRateBpm>`:""}${I.maxHeartRate?`
|
|
133
|
+
<MaximumHeartRateBpm>
|
|
134
|
+
<Value>${I.maxHeartRate}</Value>
|
|
135
|
+
</MaximumHeartRateBpm>`:""}
|
|
136
|
+
<Intensity>Active</Intensity>
|
|
137
|
+
<TriggerMethod>Manual</TriggerMethod>
|
|
138
|
+
<Track>
|
|
139
|
+
${$}
|
|
140
|
+
</Track>${$Y(I,G)}
|
|
141
|
+
</Lap>`}function GY(I,w){let G=I.records.map(($)=>aA($,w)).filter(($)=>$.length>0).join(`
|
|
142
|
+
`);return` <Lap StartTime="${I.startTime.toISOString()}">
|
|
143
|
+
<TotalTimeSeconds>${I.totalTimerTime.toFixed(1)}</TotalTimeSeconds>
|
|
144
|
+
<DistanceMeters>${I.totalDistance.toFixed(1)}</DistanceMeters>
|
|
145
|
+
<MaximumSpeed>${I.maxSpeed?I.maxSpeed.toFixed(2):"0.00"}</MaximumSpeed>
|
|
146
|
+
<Calories>${I.totalCalories}</Calories>${I.avgHeartRate?`
|
|
147
|
+
<AverageHeartRateBpm>
|
|
148
|
+
<Value>${I.avgHeartRate}</Value>
|
|
149
|
+
</AverageHeartRateBpm>`:""}${I.maxHeartRate?`
|
|
150
|
+
<MaximumHeartRateBpm>
|
|
151
|
+
<Value>${I.maxHeartRate}</Value>
|
|
152
|
+
</MaximumHeartRateBpm>`:""}
|
|
153
|
+
<Intensity>Active</Intensity>
|
|
154
|
+
<TriggerMethod>Manual</TriggerMethod>
|
|
155
|
+
<Track>
|
|
156
|
+
${G}
|
|
157
|
+
</Track>${AY(I,w)}
|
|
158
|
+
</Lap>`}function aA(I,w){let{position:G,timestamp:$,heartRate:A,cadence:_,power:W,altitude:Y,distance:U}=I,H=G?`
|
|
159
|
+
<Position>
|
|
160
|
+
<LatitudeDegrees>${G.lat.toFixed(7)}</LatitudeDegrees>
|
|
161
|
+
<LongitudeDegrees>${G.lng.toFixed(7)}</LongitudeDegrees>
|
|
162
|
+
</Position>`:"",Z=Y??G?.altitude,q=Z!=null?`
|
|
163
|
+
<AltitudeMeters>${Z.toFixed(1)}</AltitudeMeters>`:"",Q=U!=null?`
|
|
164
|
+
<DistanceMeters>${U.toFixed(1)}</DistanceMeters>`:"",b=w.includeHeartRate&&A!=null?`
|
|
165
|
+
<HeartRateBpm>
|
|
166
|
+
<Value>${A}</Value>
|
|
167
|
+
</HeartRateBpm>`:"",X=[];if(w.includeCadence&&_!=null)X.push(` <ns3:RunCadence>${_}</ns3:RunCadence>`);if(w.includePower&&W!=null)X.push(` <ns3:Watts>${W}</ns3:Watts>`);let L=X.length>0?`
|
|
168
|
+
<Extensions>
|
|
169
|
+
<ns3:TPX>
|
|
170
|
+
${X.join(`
|
|
171
|
+
`)}
|
|
172
|
+
</ns3:TPX>
|
|
173
|
+
</Extensions>`:"";return` <Trackpoint>
|
|
174
|
+
<Time>${$.toISOString()}</Time>${H}${q}${Q}${b}${L}
|
|
175
|
+
</Trackpoint>`}function $Y(I,w){let G=[];if(I.avgSpeed!=null)G.push(` <ns3:AvgSpeed>${I.avgSpeed.toFixed(2)}</ns3:AvgSpeed>`);if(w.includeCadence&&I.avgCadence!=null)G.push(` <ns3:AvgRunCadence>${I.avgCadence}</ns3:AvgRunCadence>`);if(w.includeCadence&&I.maxCadence!=null)G.push(` <ns3:MaxRunCadence>${I.maxCadence}</ns3:MaxRunCadence>`);if(w.includePower&&I.avgPower!=null)G.push(` <ns3:AvgWatts>${I.avgPower}</ns3:AvgWatts>`);if(w.includePower&&I.maxPower!=null)G.push(` <ns3:MaxWatts>${I.maxPower}</ns3:MaxWatts>`);if(G.length===0)return"";return`
|
|
176
|
+
<Extensions>
|
|
177
|
+
<ns3:LX>
|
|
178
|
+
${G.join(`
|
|
179
|
+
`)}
|
|
180
|
+
</ns3:LX>
|
|
181
|
+
</Extensions>`}function AY(I,w){let G=[];if(I.avgSpeed!=null)G.push(` <ns3:AvgSpeed>${I.avgSpeed.toFixed(2)}</ns3:AvgSpeed>`);if(w.includeCadence&&I.avgCadence!=null)G.push(` <ns3:AvgRunCadence>${I.avgCadence}</ns3:AvgRunCadence>`);if(w.includeCadence&&I.maxCadence!=null)G.push(` <ns3:MaxRunCadence>${I.maxCadence}</ns3:MaxRunCadence>`);if(w.includePower&&I.avgPower!=null)G.push(` <ns3:AvgWatts>${I.avgPower}</ns3:AvgWatts>`);if(w.includePower&&I.maxPower!=null)G.push(` <ns3:MaxWatts>${I.maxPower}</ns3:MaxWatts>`);if(G.length===0)return"";return`
|
|
182
|
+
<Extensions>
|
|
183
|
+
<ns3:LX>
|
|
184
|
+
${G.join(`
|
|
185
|
+
`)}
|
|
186
|
+
</ns3:LX>
|
|
187
|
+
</Extensions>`}function _Y(I,w){return I.filter((G)=>G.timestamp>=w.startTime&&G.timestamp<=w.endTime)}function WY(I){return{running:"Running",cycling:"Biking",swimming:"Other",hiking:"Other",walking:"Other",other:"Other"}[I]||"Other"}function tA(I){return I.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}async function wH(I,w,G){let $=IY(I,G);await Bun.write(w,$)}var yI={delimiter:",",includeHeader:!0,dateFormat:"iso"};function $H(I,w={}){let G={...yI,...w},$=G.delimiter,A=["timestamp","latitude","longitude","altitude","distance","speed","heart_rate","cadence","power","temperature","grade","calories"],_=I.records.map((W)=>YY(W,G));if(G.includeHeader)return[A.join($),..._].join(`
|
|
188
|
+
`);return _.join(`
|
|
189
|
+
`)}function YY(I,w){let G=w.delimiter;return[uI(w.dateFormat)(I.timestamp),I.position?.lat?.toFixed(7)??"",I.position?.lng?.toFixed(7)??"",I.altitude?.toFixed(1)??I.position?.altitude?.toFixed(1)??"",I.distance?.toFixed(1)??"",I.speed?.toFixed(2)??"",I.heartRate??"",I.cadence??"",I.power??"",I.temperature??"",I.grade?.toFixed(2)??"",I.calories??""].join(G)}function AH(I,w={}){let G={...yI,...w},$=G.delimiter,A=uI(G.dateFormat),_=["id","name","sport","sub_sport","start_time","end_time","elapsed_time_sec","timer_time_sec","distance_m","calories","avg_heart_rate","max_heart_rate","avg_speed_mps","max_speed_mps","avg_cadence","max_cadence","avg_power","max_power","normalized_power","total_ascent_m","total_descent_m","tss","intensity_factor","num_laps","num_records"],W=I.map((Y)=>[eA(Y.id),eA(Y.name||""),Y.sport,Y.subSport||"",A(Y.startTime),A(Y.endTime),Y.totalElapsedTime.toFixed(0),Y.totalTimerTime.toFixed(0),Y.totalDistance.toFixed(1),Y.totalCalories,Y.avgHeartRate??"",Y.maxHeartRate??"",Y.avgSpeed?.toFixed(2)??"",Y.maxSpeed?.toFixed(2)??"",Y.avgCadence??"",Y.maxCadence??"",Y.avgPower??"",Y.maxPower??"",Y.normalizedPower??"",Y.totalAscent??"",Y.totalDescent??"",Y.trainingStressScore?.toFixed(1)??"",Y.intensityFactor?.toFixed(3)??"",Y.laps.length,Y.records.length].join($));if(G.includeHeader)return[_.join($),...W].join(`
|
|
190
|
+
`);return W.join(`
|
|
191
|
+
`)}function _H(I,w={}){let G={...yI,...w},$=G.delimiter,A=uI(G.dateFormat),_=["lap_number","start_time","end_time","elapsed_time_sec","timer_time_sec","distance_m","calories","avg_heart_rate","max_heart_rate","avg_speed_mps","max_speed_mps","avg_cadence","max_cadence","avg_power","max_power","total_ascent_m","total_descent_m"],W=I.laps.map((Y,U)=>[U+1,A(Y.startTime),A(Y.endTime),Y.totalElapsedTime.toFixed(0),Y.totalTimerTime.toFixed(0),Y.totalDistance.toFixed(1),Y.totalCalories,Y.avgHeartRate??"",Y.maxHeartRate??"",Y.avgSpeed?.toFixed(2)??"",Y.maxSpeed?.toFixed(2)??"",Y.avgCadence??"",Y.maxCadence??"",Y.avgPower??"",Y.maxPower??"",Y.totalAscent??"",Y.totalDescent??""].join($));if(G.includeHeader)return[_.join($),...W].join(`
|
|
192
|
+
`);return W.join(`
|
|
193
|
+
`)}function WH(I,w={}){let G={...yI,...w},$=G.delimiter,A=uI(G.dateFormat);if(!I.heartRate?.samples)return"";let _=["timestamp","heart_rate"],W=I.heartRate.samples.map((Y)=>[A(Y.timestamp),Y.heartRate].join($));if(G.includeHeader)return[_.join($),...W].join(`
|
|
194
|
+
`);return W.join(`
|
|
195
|
+
`)}function YH(I,w={}){let G={...yI,...w},$=G.delimiter,A=uI(G.dateFormat);if(!I.sleep?.stages)return"";let _=["start_time","end_time","stage","duration_min"],W=I.sleep.stages.map((Y)=>[A(Y.startTime),A(Y.endTime),Y.stage,((Y.endTime.getTime()-Y.startTime.getTime())/60000).toFixed(1)].join($));if(G.includeHeader)return[_.join($),...W].join(`
|
|
196
|
+
`);return W.join(`
|
|
197
|
+
`)}function UH(I,w={}){let G={...yI,...w},$=G.delimiter,A=uI(G.dateFormat);if(!I.stress?.samples)return"";let _=["timestamp","stress_level"],W=I.stress.samples.map((Y)=>[A(Y.timestamp),Y.stressLevel].join($));if(G.includeHeader)return[_.join($),...W].join(`
|
|
198
|
+
`);return W.join(`
|
|
199
|
+
`)}function uI(I){switch(I){case"unix":return(w)=>Math.floor(w.getTime()/1000).toString();case"locale":return(w)=>w.toLocaleString();case"iso":default:return(w)=>w.toISOString()}}function eA(I){if(I.includes(",")||I.includes('"')||I.includes(`
|
|
200
|
+
`))return`"${I.replace(/"/g,'""')}"`;return I}async function HH(I,w){await Bun.write(w,I)}var I0={includeElevation:!0,includeTimestamps:!0,includeMetrics:!0,simplifyTolerance:0};function UY(I,w={}){let G={...I0,...w},$=I.records.filter((U)=>U.position?.lat!=null&&U.position?.lng!=null);if(G.simplifyTolerance&&G.simplifyTolerance>0)$=HY($,G.simplifyTolerance);let A=$.map((U)=>{let H=[U.position.lng,U.position.lat];if(G.includeElevation&&(U.altitude!=null||U.position.altitude!=null))H.push(U.altitude??U.position.altitude);return H}),_={id:I.id,sport:I.sport,subSport:I.subSport,startTime:I.startTime.toISOString(),endTime:I.endTime.toISOString(),totalDistance:I.totalDistance,totalTimerTime:I.totalTimerTime,totalCalories:I.totalCalories};if(G.includeMetrics){if(I.avgHeartRate)_.avgHeartRate=I.avgHeartRate;if(I.maxHeartRate)_.maxHeartRate=I.maxHeartRate;if(I.avgSpeed)_.avgSpeed=I.avgSpeed;if(I.maxSpeed)_.maxSpeed=I.maxSpeed;if(I.avgCadence)_.avgCadence=I.avgCadence;if(I.avgPower)_.avgPower=I.avgPower;if(I.totalAscent)_.totalAscent=I.totalAscent;if(I.totalDescent)_.totalDescent=I.totalDescent}if(G.includeTimestamps)_.timestamps=$.map((U)=>U.timestamp.toISOString());let Y=[{type:"Feature",geometry:{type:"LineString",coordinates:A},properties:_}];if($.length>0){let U=$[0];Y.push({type:"Feature",geometry:{type:"Point",coordinates:[U.position.lng,U.position.lat]},properties:{type:"start",time:U.timestamp.toISOString()}})}if($.length>1){let U=$[$.length-1];Y.push({type:"Feature",geometry:{type:"Point",coordinates:[U.position.lng,U.position.lat]},properties:{type:"end",time:U.timestamp.toISOString()}})}for(let U=0;U<I.laps.length;U++){let H=I.laps[U];if(H.startPosition)Y.push({type:"Feature",geometry:{type:"Point",coordinates:[H.startPosition.lng,H.startPosition.lat]},properties:{type:"lap",lapNumber:U+1,time:H.startTime.toISOString(),distance:H.totalDistance,duration:H.totalTimerTime}})}return{type:"FeatureCollection",features:Y}}function qH(I,w={}){let G={...I0,...w};return{type:"FeatureCollection",features:I.filter((A)=>A.position?.lat!=null&&A.position?.lng!=null).map((A)=>{let _=[A.position.lng,A.position.lat];if(G.includeElevation&&(A.altitude!=null||A.position.altitude!=null))_.push(A.altitude??A.position.altitude);let W={time:A.timestamp.toISOString()};if(G.includeMetrics){if(A.heartRate!=null)W.heartRate=A.heartRate;if(A.cadence!=null)W.cadence=A.cadence;if(A.speed!=null)W.speed=A.speed;if(A.power!=null)W.power=A.power;if(A.temperature!=null)W.temperature=A.temperature;if(A.distance!=null)W.distance=A.distance}return{type:"Feature",geometry:{type:"Point",coordinates:_},properties:W}})}}function bH(I,w={}){let G=[];for(let $ of I){let A=UY($,w);G.push(...A.features)}return{type:"FeatureCollection",features:G}}function HY(I,w){if(I.length<=2)return I;let G=I.map((A)=>({record:A,x:A.position.lng,y:A.position.lat}));return hG(G,w).map((A)=>A.record)}function hG(I,w){if(I.length<=2)return I;let G=0,$=0,A=I[0],_=I[I.length-1];for(let W=1;W<I.length-1;W++){let Y=ZY(I[W],A,_);if(Y>G)G=Y,$=W}if(G>w){let W=hG(I.slice(0,$+1),w),Y=hG(I.slice($),w);return[...W.slice(0,-1),...Y]}return[A,_]}function ZY(I,w,G){let $=G.x-w.x,A=G.y-w.y;if($===0&&A===0)return Math.sqrt(Math.pow(I.x-w.x,2)+Math.pow(I.y-w.y,2));let _=((I.x-w.x)*$+(I.y-w.y)*A)/($*$+A*A),W=w.x+_*$,Y=w.y+_*A;return Math.sqrt(Math.pow(I.x-W,2)+Math.pow(I.y-Y,2))}async function QH(I,w,G=!0){let $=G?JSON.stringify(I,null,2):JSON.stringify(I);await Bun.write(w,$)}import{createHash as qY,createHmac as w0,randomBytes as bY,timingSafeEqual as G0}from"node:crypto";var QY={authorize:"https://connect.garmin.com/oauth2Confirm",token:"https://diauth.garmin.com/di-oauth2-service/oauth/token",userId:"https://apis.garmin.com/wellness-api/rest/user/id",permissions:"https://apis.garmin.com/wellness-api/rest/user/permissions",registration:"https://apis.garmin.com/wellness-api/rest/user/registration",backfillActivities:"https://apis.garmin.com/wellness-api/rest/backfill/activities"};function TH(){let I=bY(64).toString("base64url"),w=qY("sha256").update(I).digest("base64url");return{verifier:I,challenge:w}}function MH(I){return(Array.isArray(I)?I:Array.isArray(I?.activities)?I.activities:Array.isArray(I?.activityDetails)?I.activityDetails:[]).filter((G)=>Boolean(G)&&typeof G.summaryId==="string")}function CH(I){return(Array.isArray(I?.deregistrations)?I.deregistrations:[]).filter((G)=>Boolean(G)&&typeof G.userId==="string")}function SH(I,w){if(!w||!I)return!1;let G=Buffer.from(I),$=Buffer.from(w);return G.length===$.length&&G0(G,$)}function EH(I,w){let G=Buffer.from(I).toString("base64url"),$=w0("sha256",w).update(G).digest("base64url");return`${G}.${$}`}function OH(I,w){if(!I||!w)return null;let G=I.lastIndexOf(".");if(G===-1)return null;let $=I.slice(0,G),A=I.slice(G+1),_=w0("sha256",w).update($).digest("base64url"),W=Buffer.from(A),Y=Buffer.from(_);if(W.length!==Y.length||!G0(W,Y))return null;try{return Buffer.from($,"base64url").toString("utf8")}catch{return null}}class LY{config;endpoints;fetchImpl;constructor(I){this.config={clientId:I.clientId,clientSecret:I.clientSecret,redirectUri:I.redirectUri,scope:I.scope??"ACTIVITY_EXPORT"},this.endpoints={...QY,...I.endpoints},this.fetchImpl=I.fetch??globalThis.fetch}get isConfigured(){return Boolean(this.config.clientId&&this.config.clientSecret)}buildAuthorizationUrl(I){let w=new URLSearchParams({client_id:this.config.clientId,response_type:"code",redirect_uri:this.config.redirectUri,code_challenge:I.challenge,code_challenge_method:"S256",state:I.state,scope:I.scope??this.config.scope});return`${this.endpoints.authorize}?${w.toString()}`}async exchangeCode(I,w){let G=await this.fetchImpl(this.endpoints.token,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({grant_type:"authorization_code",client_id:this.config.clientId,client_secret:this.config.clientSecret,code:I,code_verifier:w,redirect_uri:this.config.redirectUri})});return this.readTokens(G,"exchange the authorization code")}async refreshTokens(I){let w=await this.fetchImpl(this.endpoints.token,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({grant_type:"refresh_token",client_id:this.config.clientId,client_secret:this.config.clientSecret,refresh_token:I})});return this.readTokens(w,"refresh the access token")}async getUserId(I){let w=await this.fetchImpl(this.endpoints.userId,{headers:{Authorization:`Bearer ${I}`,Accept:"application/json"}});if(!w.ok)throw Error(`Garmin: could not resolve the user id (HTTP ${w.status})`);let G=await w.json();if(!G?.userId)throw Error("Garmin: user id response contained no userId");return G.userId}async getPermissions(I){let w=await this.fetchImpl(this.endpoints.permissions,{headers:{Authorization:`Bearer ${I}`,Accept:"application/json"}});if(!w.ok)throw Error(`Garmin: could not read permissions (HTTP ${w.status})`);let G=await w.json();return Array.isArray(G)?G:G?.permissions??[]}async deregister(I){let w=await this.fetchImpl(this.endpoints.registration,{method:"DELETE",headers:{Authorization:`Bearer ${I}`}});if(!w.ok&&w.status!==404)throw Error(`Garmin: deregistration failed (HTTP ${w.status})`)}async requestBackfill(I,w,G){let $=new URLSearchParams({summaryStartTimeInSeconds:String(Math.floor(w.getTime()/1000)),summaryEndTimeInSeconds:String(Math.floor(G.getTime()/1000))}),A=await this.fetchImpl(`${this.endpoints.backfillActivities}?${$.toString()}`,{method:"GET",headers:{Authorization:`Bearer ${I}`}});if(!A.ok&&A.status!==202)throw Error(`Garmin: backfill request failed (HTTP ${A.status})`)}async readTokens(I,w){if(!I.ok){let $=await I.text().catch(()=>"");throw Error(`Garmin: could not ${w} (HTTP ${I.status})${$?`: ${$.slice(0,200)}`:""}`)}let G=await I.json();if(!G?.access_token)throw Error(`Garmin: could not ${w}; the response contained no access token`);return{accessToken:G.access_token,refreshToken:G.refresh_token,expiresAt:G.expires_in?Math.floor(Date.now()/1000)+G.expires_in:void 0,scope:G.scope}}}function zH(I,w=60,G=Date.now()){if(!I.expiresAt)return!1;return I.expiresAt-w<=Math.floor(G/1000)}import*as nw from"node:fs";import*as AI from"node:path";import _0 from"node:crypto";var XY=/name="_csrf"\s+value="(.+?)"/,JY=/ticket=([^"]+)"/,BY=/var statuss*=s*"([^"]*)"/,DY=/<title>([^<]*)<\/title>/,$0="com.garmin.android.apps.connectmobile",RY="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36",KY="https://thegarth.s3.amazonaws.com/oauth_consumer.json",nG=!1,fG=[];function XI(I){return encodeURIComponent(I).replace(/[!'()*]/g,(w)=>`%${w.charCodeAt(0).toString(16).toUpperCase()}`)}function TY(){return _0.randomBytes(16).toString("hex")}function MY(){return Math.floor(Date.now()/1000).toString()}function CY(I,w){return _0.createHmac("sha1",w).update(I).digest("base64")}function A0(I,w,G,$,A){let _={oauth_consumer_key:I.key,oauth_signature_method:"HMAC-SHA1",oauth_timestamp:MY(),oauth_nonce:TY(),oauth_version:"1.0"};if($)_.oauth_token=$.key;let W={..._};if(A)Object.assign(W,A);let Y=new URL(w);Y.searchParams.forEach((b,X)=>{W[X]=b});let U=Object.keys(W).sort().map((b)=>`${XI(b)}=${XI(W[b])}`).join("&"),H=`${Y.protocol}//${Y.host}${Y.pathname}`,Z=`${G.toUpperCase()}&${XI(H)}&${XI(U)}`,q=`${XI(I.secret)}&${$?XI($.secret):""}`;return _.oauth_signature=CY(Z,q),`OAuth ${Object.keys(_).filter((b)=>b.startsWith("oauth_")).sort().map((b)=>`${XI(b)}="${XI(_[b])}"`).join(", ")}`}function oI(I){return Object.entries(I).filter(([w,G])=>G!==void 0&&G!==null).map(([w,G])=>`${encodeURIComponent(w)}=${encodeURIComponent(String(G))}`).join("&")}function SY(I){let w={};return I.split("&").forEach((G)=>{let[$,A]=G.split("=");if($)w[decodeURIComponent($)]=decodeURIComponent(A||"")}),w}class vG{url;oauth1Token;oauth2Token;OAUTH_CONSUMER;cookies=new Map;constructor(I){this.url=I}getCookieHeader(){return Array.from(this.cookies.entries()).map(([I,w])=>`${I}=${w}`).join("; ")}extractCookies(I){let w=I.headers.get("set-cookie");if(w){let G=w.split(/,(?=\s*\w+=)/);for(let $ of G){let A=$.split(";")[0].trim(),[_,W]=A.split("=");if(_&&W)this.cookies.set(_.trim(),W.trim())}}}async fetchOauthConsumer(){let w=await(await fetch(KY)).json();this.OAUTH_CONSUMER={key:w.consumer_key,secret:w.consumer_secret}}async checkTokenValid(){if(this.oauth2Token){let I=Math.floor(Date.now()/1000);if(this.oauth2Token.expires_at<I)console.error("Token expired!"),await this.refreshOauth2Token()}}async makeRequest(I,w={}){let G={...w.headers||{}};if(this.oauth2Token)G.Authorization=`Bearer ${this.oauth2Token.access_token}`;if(this.cookies.size>0)G.Cookie=this.getCookieHeader();let{responseType:$,_retry:A,..._}=w,W=await fetch(I,{..._,headers:G});if(this.extractCookies(W),W.status===401&&this.oauth2Token&&!A){if(nG){let U=await new Promise((H)=>{fG.push(H)});return G.Authorization=`Bearer ${U}`,this.makeRequest(I,{...w,headers:G,_retry:!0})}return nG=!0,await this.refreshOauth2Token(),nG=!1,fG.forEach((U)=>U(this.oauth2Token.access_token)),fG=[],G.Authorization=`Bearer ${this.oauth2Token.access_token}`,this.makeRequest(I,{...w,headers:G,_retry:!0})}if(!W.ok){let U=await W.text();throw Error(`HTTP Error: ${W.status} ${W.statusText} - ${U}`)}if(W.headers.get("content-type")?.includes("application/json"))return W.json();if($==="arraybuffer")return W.arrayBuffer();return W.text()}async get(I,w){let G=I;if(w?.params){let $=oI(w.params);G=$?`${I}${I.includes("?")?"&":"?"}${$}`:I}return this.makeRequest(G,{method:"GET",headers:w?.headers,responseType:w?.responseType})}async post(I,w,G){let $={...G?.headers},A;if(w!==null&&w!==void 0){if(typeof w==="object"&&!(w instanceof FormData))$["Content-Type"]=$["Content-Type"]||"application/json",A=JSON.stringify(w);else if(typeof w==="string")A=w}return this.makeRequest(I,{method:"POST",headers:$,body:A})}async put(I,w,G){let $={...G?.headers},A;if(w!==null&&w!==void 0){if(typeof w==="object")$["Content-Type"]=$["Content-Type"]||"application/json",A=JSON.stringify(w);else if(typeof w==="string")A=w}return this.makeRequest(I,{method:"PUT",headers:$,body:A})}async delete(I,w){return this.makeRequest(I,{method:"POST",headers:{...w?.headers,"X-Http-Method-Override":"DELETE"}})}async login(I,w){await this.fetchOauthConsumer();let G=await this.getLoginTicket(I,w),$=await this.getOauth1Token(G);return await this.exchange($),this}async getLoginTicket(I,w){let G={clientId:"GarminConnect",locale:"en",service:this.url.GC_MODERN},$=`${this.url.GARMIN_SSO_EMBED}?${oI(G)}`,A=await fetch($);this.extractCookies(A);let _={id:"gauth-widget",embedWidget:"true",locale:"en",gauthHost:this.url.GARMIN_SSO_EMBED},W=`${this.url.SIGNIN_URL}?${oI(_)}`,Y=await fetch(W,{headers:{Cookie:this.getCookieHeader()}});this.extractCookies(Y);let U=await Y.text(),H=XY.exec(U);if(!H)throw Error("login - csrf not found");let Z=H[1],q={id:"gauth-widget",embedWidget:"true",clientId:"GarminConnect",locale:"en",gauthHost:this.url.GARMIN_SSO_EMBED,service:this.url.GARMIN_SSO_EMBED,source:this.url.GARMIN_SSO_EMBED,redirectAfterAccountLoginUrl:this.url.GARMIN_SSO_EMBED,redirectAfterAccountCreationUrl:this.url.GARMIN_SSO_EMBED},Q=`${this.url.SIGNIN_URL}?${oI(q)}`,b=new URLSearchParams;b.append("username",I),b.append("password",w),b.append("embed","true"),b.append("_csrf",Z);let X=await fetch(Q,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Dnt:"1",Origin:this.url.GARMIN_SSO_ORIGIN,Referer:this.url.SIGNIN_URL,"User-Agent":RY,Cookie:this.getCookieHeader()},body:b.toString()});this.extractCookies(X);let L=await X.text();this.handleAccountLocked(L),this.handlePageTitle(L);let J=JY.exec(L);if(!J)throw Error("login failed (Ticket not found or MFA), please check username and password");return J[1]}handlePageTitle(I){let w=DY.exec(I);if(w){if(w[1].includes("Update Phone Number"))throw Error("login failed (Update Phone number), please update your phone number")}}handleAccountLocked(I){let w=BY.exec(I);if(w){let G=w[1];throw console.error(G),Error("login failed (AccountLocked), please open connect web page to unlock your account")}}async refreshOauth2Token(){if(!this.OAUTH_CONSUMER)await this.fetchOauthConsumer();if(!this.oauth2Token||!this.oauth1Token)throw Error("No Oauth2Token or Oauth1Token");await this.exchange({token:this.oauth1Token})}async getOauth1Token(I){if(!this.OAUTH_CONSUMER)throw Error("No OAUTH_CONSUMER");let w={ticket:I,"login-url":this.url.GARMIN_SSO_EMBED,"accepts-mfa-tokens":"true"},G=`${this.url.OAUTH_URL}/preauthorized?${oI(w)}`,$=A0(this.OAUTH_CONSUMER,G,"GET"),_=await(await fetch(G,{headers:{Authorization:$,"User-Agent":$0}})).text(),W=SY(_);return this.oauth1Token=W,{token:W}}async exchange(I){if(!this.OAUTH_CONSUMER)throw Error("No OAUTH_CONSUMER");let w={key:I.token.oauth_token,secret:I.token.oauth_token_secret},G=`${this.url.OAUTH_URL}/exchange/user/2.0`,$=A0(this.OAUTH_CONSUMER,G,"POST",w),_=await(await fetch(G,{method:"POST",headers:{Authorization:$,"User-Agent":$0,"Content-Type":"application/x-www-form-urlencoded"}})).json();this.oauth2Token=this.setOauth2TokenExpiresAt(_)}setOauth2TokenExpiresAt(I){let w=Date.now(),G=Math.floor(w/1000);return I.last_update_date=new Date(w).toISOString(),I.expires_date=new Date(w+I.expires_in*1000).toISOString(),I.expires_at=G+I.expires_in,I.refresh_token_expires_at=G+I.refresh_token_expires_in,I}}import*as JI from"node:fs";function mw(I){return JI.existsSync(I)&&JI.lstatSync(I).isDirectory()}function gG(I){JI.mkdirSync(I,{recursive:!0})}function hw(I,w){JI.writeFileSync(I,w)}class dG{domain;GC_MODERN;GARMIN_SSO_ORIGIN;GC_API;constructor(I="garmin.com"){this.domain=I,this.GC_MODERN=`https://connect.${this.domain}/modern`,this.GARMIN_SSO_ORIGIN=`https://sso.${this.domain}`,this.GC_API=`https://connectapi.${this.domain}`}get GARMIN_SSO(){return`${this.GARMIN_SSO_ORIGIN}/sso`}get GARMIN_SSO_EMBED(){return`${this.GARMIN_SSO_ORIGIN}/sso/embed`}get BASE_URL(){return`${this.GC_MODERN}/proxy`}get SIGNIN_URL(){return`${this.GARMIN_SSO}/signin`}get LOGIN_URL(){return`${this.GARMIN_SSO}/login`}get OAUTH_URL(){return`${this.GC_API}/oauth-service/oauth`}get USER_SETTINGS(){return`${this.GC_API}/userprofile-service/userprofile/user-settings/`}get USER_PROFILE(){return`${this.GC_API}/userprofile-service/socialProfile`}get ACTIVITIES(){return`${this.GC_API}/activitylist-service/activities/search/activities`}get ACTIVITY(){return`${this.GC_API}/activity-service/activity/`}ACTIVITY_BY_ID(I){return`${this.GC_API}/activity-service/activity/${I}`}get STAT_ACTIVITIES(){return`${this.GC_API}/fitnessstats-service/activity`}get DOWNLOAD_ZIP(){return`${this.GC_API}/download-service/files/activity/`}get DOWNLOAD_GPX(){return`${this.GC_API}/download-service/export/gpx/activity/`}get DOWNLOAD_TCX(){return`${this.GC_API}/download-service/export/tcx/activity/`}get DOWNLOAD_KML(){return`${this.GC_API}/download-service/export/kml/activity/`}get UPLOAD(){return`${this.GC_API}/upload-service/upload/`}get IMPORT_DATA(){return`${this.GC_API}/modern/import-data`}get DAILY_STEPS(){return`${this.GC_API}/usersummary-service/stats/steps/daily/`}get DAILY_SLEEP(){return`${this.GC_API}/sleep-service/sleep/dailySleepData`}get DAILY_WEIGHT(){return`${this.GC_API}/weight-service/weight/dayview`}get UPDATE_WEIGHT(){return`${this.GC_API}/weight-service/user-weight`}get DAILY_HYDRATION(){return`${this.GC_API}/usersummary-service/usersummary/hydration/allData`}get HYDRATION_LOG(){return`${this.GC_API}/usersummary-service/usersummary/hydration/log`}get GOLF_SCORECARD_SUMMARY(){return`${this.GC_API}/gcs-golfcommunity/api/v2/scorecard/summary`}get GOLF_SCORECARD_DETAIL(){return`${this.GC_API}/gcs-golfcommunity/api/v2/scorecard/detail`}get DAILY_HEART_RATE(){return`${this.GC_API}/wellness-service/wellness/dailyHeartRate`}WORKOUT(I){if(I)return`${this.GC_API}/workout-service/workout/${I}`;return`${this.GC_API}/workout-service/workout`}get WORKOUTS(){return`${this.GC_API}/workout-service/workouts`}GEAR_OF_ACTIVITY(I){return`${this.GC_API}/gear-service/gear/filterGear?activityId=${I}`}GEAR(I,w){return`${this.GC_API}/gear-service/gear/filterGear?userProfilePk=${I}${w?`&availableGearDate=${w}`:""}`}LINK_GEAR_TO_ACTIVITY(I,w){return`${this.GC_API}/gear-service/gear/link/${w}/activity/${I}`}UNLINK_GEAR_FROM_ACTIVITY(I,w){return`${this.GC_API}/gear-service/gear/unlink/${w}/activity/${I}`}WORKOUTS_LIST(I=1,w=999,G=!0,$=!1,A="UPDATE_DATE",_="DESC",W=!1){return`${this.GC_API}/workout-service/workouts?start=${I}&limit=${w}&myWorkoutsOnly=${G}&sharedWorkoutsOnly=${$}&orderBy=${A}&orderSeq=${_}&includeAtp=${W}`}SCHEDULE_WORKOUT(I){return`${this.GC_API}/workout-service/schedule/${I}`}get IMPORT_GPX_FILE(){return`${this.GC_API}/course-service/course/import`}EXPORT_COURSE_GPX_FILE(I){return`${this.GC_API}/course-service/course/gpx/${I}`}get CREATE_COURSE_GPX_FILE(){return`${this.GC_API}/course-service/course`}UPDATE_COURSE_GPX_FILE(I){return`${this.GC_API}/course-service/course/${I}`}get LIST_COURSES(){return`${this.GC_API}/web-gateway/course/owner/`}CALENDAR_YEAR(I){return`${this.GC_API}/calendar-service/year/${I}`}CALENDAR_MONTH(I,w){return`${this.GC_API}/calendar-service/year/${I}/month/${w}`}CALENDAR_WEEK(I,w,G,$=1){return`${this.GC_API}/calendar-service/year/${I}/month/${w}/day/${G}/start/${$}`}DAILY_STRESS(I){return`${this.GC_API}/wellness-service/wellness/dailyStress/${I}`}HRV_DATA(I){return`${this.GC_API}/hrv-service/hrv/${I}`}TRAINING_READINESS(I){return`${this.GC_API}/metrics-service/metrics/trainingreadiness/${I}`}BODY_BATTERY(I){return`${this.GC_API}/wellness-service/wellness/bodyBattery?date=${I}`}DAILY_SUMMARY(I,w){return`${this.GC_API}/usersummary-service/usersummary/daily/${I}?calendarDate=${w}`}}var pG;(($)=>{$.tcx="tcx";$.gpx="gpx";$.fit="fit"})(pG||={});function a(I){let w=I.getTimezoneOffset(),G=new Date(I.getTime()-w*60*1000),[$]=G.toISOString().split("T");return $}function W0(I,w){let G=(w-I)/1000,$=Math.floor(G/3600),A=Math.floor(G%3600/60);return{hours:$,minutes:A}}function Y0(I,w){let G=I.toISOString().substring(0,23),$=new Date(G).toLocaleString("en-US",{timeZone:w,hour12:!1});return new Date($).toISOString().substring(0,23)}function U0(I){return I/453.592}function H0(I){return I*0.033814}function Z0(I){return I*29.5735}function q0(I,w,G,$=[]){return{activityTypePk:I,hasTurnDetectionDisabled:!1,geoPoints:G,courseLines:[],coursePoints:$,startPoint:G[0],elapsedSeconds:null,openStreetMap:!1,coordinateSystem:"WGS84",rulePK:2,courseName:w,matchedToSegments:!1,includeLaps:!1,hasPaceBand:!1,hasPowerGuide:!1,favorite:!1,speedMeterPerSecond:null,sourceTypeId:3}}class mI{client;credentials;listeners;url;constructor(I,w="garmin.com"){if(!I)throw Error("Missing credentials");this.credentials=I,this.url=new dG(w),this.client=new vG(this.url),this.listeners={}}async login(I,w){if(I&&w)this.credentials.username=I,this.credentials.password=w;return await this.client.login(this.credentials.username,this.credentials.password),this}exportTokenToFile(I){if(!mw(I))gG(I);if(this.client.oauth1Token)hw(AI.join(I,"oauth1_token.json"),JSON.stringify(this.client.oauth1Token));if(this.client.oauth2Token)hw(AI.join(I,"oauth2_token.json"),JSON.stringify(this.client.oauth2Token))}loadTokenByFile(I){if(!mw(I))throw Error(`loadTokenByFile: Directory not found: ${I}`);let w=nw.readFileSync(AI.join(I,"oauth1_token.json"),"utf-8"),G=JSON.parse(w);this.client.oauth1Token=G;let $=nw.readFileSync(AI.join(I,"oauth2_token.json"),"utf-8"),A=JSON.parse($);this.client.oauth2Token=A}exportToken(){if(!this.client.oauth1Token||!this.client.oauth2Token)throw Error("exportToken: Token not found");return{oauth1:this.client.oauth1Token,oauth2:this.client.oauth2Token}}loadToken(I,w){this.client.oauth1Token=I,this.client.oauth2Token=w}async getUserSettings(){return this.client.get(this.url.USER_SETTINGS)}async getUserProfile(){return this.client.get(this.url.USER_PROFILE)}async getActivities(I,w,G,$){return this.client.get(this.url.ACTIVITIES,{params:{start:I,limit:w,activityType:G,subActivityType:$}})}async getActivity(I){if(!I.activityId)throw Error("Missing activityId");return this.client.get(`${this.url.ACTIVITY}${I.activityId}`)}async countActivities(){let I=new Date,w=`${I.getFullYear()}-${String(I.getMonth()+1).padStart(2,"0")}-${String(I.getDate()).padStart(2,"0")}`;return this.client.get(this.url.STAT_ACTIVITIES,{params:{aggregation:"lifetime",startDate:"1970-01-01",endDate:w,metric:"duration"}})}async downloadOriginalActivityData(I,w,G="zip"){if(!I.activityId)throw Error("Missing activityId");if(!mw(w))gG(w);let $,A;if(G==="tcx")A=`${this.url.DOWNLOAD_TCX}${I.activityId}`;else if(G==="gpx")A=`${this.url.DOWNLOAD_GPX}${I.activityId}`;else if(G==="kml")A=`${this.url.DOWNLOAD_KML}${I.activityId}`;else if(G==="zip")A=`${this.url.DOWNLOAD_ZIP}${I.activityId}`;else throw Error(`downloadOriginalActivityData - Invalid type: ${G}`);$=await this.client.get(A,{responseType:"arraybuffer"}),hw(AI.join(w,`${I.activityId}.${G}`),Buffer.from($))}async uploadActivity(I,w="fit"){let G=(w||AI.extname(I))?.toLowerCase();if(!Object.values(pG).includes(G))throw Error(`uploadActivity - Invalid format: ${w}`);let $=nw.readFileSync(I),A=new FormData;return A.append("userfile",new Blob([$]),AI.basename(I)),(await fetch(`${this.url.UPLOAD}.${w}`,{method:"POST",headers:{Authorization:`Bearer ${this.client.oauth2Token?.access_token}`},body:A})).json()}async deleteActivity(I){if(!I.activityId)throw Error("Missing activityId");await this.client.delete(`${this.url.ACTIVITY}${I.activityId}`)}async getWorkouts(I,w){return this.client.get(this.url.WORKOUTS,{params:{start:I,limit:w}})}async getWorkoutDetail(I){if(!I.workoutId)throw Error("Missing workoutId");return this.client.get(this.url.WORKOUT(I.workoutId))}async createWorkout(I){return this.client.post(this.url.WORKOUT(),I)}async deleteWorkout(I){if(!I.workoutId)throw Error("Missing workout");return this.client.delete(this.url.WORKOUT(I.workoutId))}async scheduleWorkout(I,w){return this.client.post(this.url.SCHEDULE_WORKOUT(Number.parseInt(I.workoutId)),{date:w})}async getSteps(I=new Date){let w=a(I),$=(await this.client.get(`${this.url.DAILY_STEPS}${w}/${w}`)).find(({calendarDate:A})=>A===w);if(!$)throw Error("Can't find daily steps for this date.");return $.totalSteps}async getSleepData(I=new Date){try{let w=a(I),G=await this.client.get(this.url.DAILY_SLEEP,{params:{date:w}});if(!G)throw Error("Invalid or empty sleep data response.");return G}catch(w){throw Error(`Error in getSleepData: ${w instanceof Error?w.message:w}`)}}async getSleepDuration(I=new Date){try{let w=await this.getSleepData(I);if(!w||!w.dailySleepDTO||w.dailySleepDTO.sleepStartTimestampGMT===void 0||w.dailySleepDTO.sleepEndTimestampGMT===void 0)throw Error("Invalid or missing sleep data for the specified date.");let{hours:G,minutes:$}=W0(w.dailySleepDTO.sleepStartTimestampGMT,w.dailySleepDTO.sleepEndTimestampGMT);return{hours:G,minutes:$}}catch(w){throw Error(`Error in getSleepDuration: ${w instanceof Error?w.message:w}`)}}async getDailyWeightData(I=new Date){try{let w=a(I),G=await this.client.get(`${this.url.DAILY_WEIGHT}/${w}`);if(!G)throw Error("Invalid or empty weight data response.");return G}catch(w){throw Error(`Error in getDailyWeightData: ${w instanceof Error?w.message:w}`)}}async getDailyWeightInPounds(I=new Date){let w=await this.getDailyWeightData(I);if(w.totalAverage&&typeof w.totalAverage.weight==="number")return U0(w.totalAverage.weight);else throw Error("Can't find valid daily weight for this date.")}async getDailyHydration(I=new Date){try{let w=a(I),G=await this.client.get(`${this.url.DAILY_HYDRATION}/${w}`);if(!G||!G.valueInML)throw Error("Invalid or empty hydration data response.");return H0(G.valueInML)}catch(w){throw Error(`Error in getDailyHydration: ${w instanceof Error?w.message:w}`)}}async updateWeight(I=new Date,w,G){try{return await this.client.post(this.url.UPDATE_WEIGHT,{dateTimestamp:Y0(I,G),gmtTimestamp:I.toISOString().substring(0,23),unitKey:"lbs",value:w})}catch($){throw Error(`Error in updateWeight: ${$ instanceof Error?$.message:$}`)}}async updateHydrationLogOunces(I=new Date,w){try{let G=a(I);return await this.client.put(this.url.HYDRATION_LOG,{calendarDate:G,valueInML:Z0(w),userProfileId:(await this.getUserProfile()).profileId,timestampLocal:I.toISOString().substring(0,23)})}catch(G){throw Error(`Error in updateHydrationLogOunces: ${G instanceof Error?G.message:G}`)}}async getGolfSummary(){try{let I=await this.client.get(this.url.GOLF_SCORECARD_SUMMARY);if(!I)throw Error("Invalid or empty golf summary data response.");return I}catch(I){throw Error(`Error in getGolfSummary: ${I instanceof Error?I.message:I}`)}}async getGolfScorecard(I){try{let w=await this.client.get(this.url.GOLF_SCORECARD_DETAIL,{params:{"scorecard-ids":I}});if(!w)throw Error("Invalid or empty golf scorecard data response.");return w}catch(w){throw Error(`Error in getGolfScorecard: ${w instanceof Error?w.message:w}`)}}async getHeartRate(I=new Date){try{let w=a(I);return await this.client.get(this.url.DAILY_HEART_RATE,{params:{date:w}})}catch(w){throw Error(`Error in getHeartRate: ${w instanceof Error?w.message:w}`)}}async getStressData(I=new Date){try{let w=a(I),G=await this.client.get(this.url.DAILY_STRESS(w));if(!G)throw Error("Invalid or empty stress data response.");return G}catch(w){throw Error(`Error in getStressData: ${w instanceof Error?w.message:w}`)}}async getHrvData(I=new Date){try{let w=a(I),G=await this.client.get(this.url.HRV_DATA(w));if(!G)throw Error("Invalid or empty HRV data response.");return G}catch(w){throw Error(`Error in getHrvData: ${w instanceof Error?w.message:w}`)}}async getTrainingReadiness(I=new Date){try{let w=a(I),G=await this.client.get(this.url.TRAINING_READINESS(w));if(!G)throw Error("Invalid or empty training readiness data response.");return G}catch(w){throw Error(`Error in getTrainingReadiness: ${w instanceof Error?w.message:w}`)}}async getBodyBattery(I=new Date){try{let w=a(I),G=await this.client.get(this.url.BODY_BATTERY(w));if(!G)throw Error("Invalid or empty body battery data response.");return G}catch(w){throw Error(`Error in getBodyBattery: ${w instanceof Error?w.message:w}`)}}async getDailySummary(I=new Date){try{let w=a(I),G=await this.getUserProfile(),$=await this.client.get(this.url.DAILY_SUMMARY(G.profileId,w));if(!$)throw Error("Invalid or empty daily summary response.");return $}catch(w){throw Error(`Error in getDailySummary: ${w instanceof Error?w.message:w}`)}}async getGear(I){let w=(await this.getUserProfile()).profileId;return this.client.get(this.url.GEAR(w,I))}async getGearsForActivity(I){return this.client.get(this.url.GEAR_OF_ACTIVITY(I))}async linkGearToActivity(I,w){return this.client.put(this.url.LINK_GEAR_TO_ACTIVITY(I,w),{})}async unlinkGearFromActivity(I,w){return this.client.put(this.url.UNLINK_GEAR_FROM_ACTIVITY(I,w),{})}async workouts(){return this.client.get(this.url.WORKOUTS_LIST())}async importGpx(I,w){let G=new FormData;return G.append("file",new Blob([w],{type:"application/octet-stream"}),I),(await fetch(this.url.IMPORT_GPX_FILE,{method:"POST",headers:{Authorization:`Bearer ${this.client.oauth2Token?.access_token}`},body:G})).json()}async createCourse(I,w,G,$=[]){return this.client.post(this.url.CREATE_COURSE_GPX_FILE,q0(I,w,G,$))}async listCourses(){return this.client.get(this.url.LIST_COURSES)}async exportCourseAsGpx(I){return this.client.get(this.url.EXPORT_COURSE_GPX_FILE(I),{responseType:"text"})}async getYearCalendarEvents(I){return this.client.get(this.url.CALENDAR_YEAR(I))}async getMonthCalendarEvents(I,w){return this.client.get(this.url.CALENDAR_MONTH(I,w))}async getWeekCalendarEvents(I,w,G,$){return this.client.get(this.url.CALENDAR_WEEK(I,w,G,$))}async renameActivity(I,w){if(!I)throw Error("Missing activityId");if(!w)throw Error("Missing newName");await this.client.put(this.url.ACTIVITY_BY_ID(I),{activityName:w})}async get(I,w){return await this.client.get(I,w)}async post(I,w){return await this.client.post(I,w,{})}async put(I,w){return await this.client.put(I,w,{})}}class DI{type;stepId;constructor(I,w){this.type=I;this.stepId=w}build(){return{stepType:{stepTypeId:this.stepId,stepTypeKey:this.type,displayOrder:this.stepId}}}static WarmUp=new DI("warmup",1);static Run=new DI("interval",3);static Recovery=new DI("recovery",4);static Rest=new DI("rest",5);static Cooldown=new DI("cooldown",2);static Other=new DI("other",7)}class hI{sportTypeKey;sportTypeId;constructor(I,w){this.sportTypeKey=I;this.sportTypeId=w}build(){return{sportType:{sportTypeId:this.sportTypeId,sportTypeKey:this.sportTypeKey,displayOrder:this.sportTypeId}}}static Running=new hI("running",1);static Cycling=new hI("cycling",2);static Swimming=new hI("swimming",4);static Strength=new hI("strength_training",5);static Cardio=new hI("cardio_training",6)}class b0{client;isLoggedIn=!1;constructor(I){if(I)this.client=new mI({username:I.username,password:I.password});else this.client=null}async login(I,w){if(I&&w)this.client=new mI({username:I,password:w});if(!this.client)throw Error("Credentials required for login");await this.client.login(),this.isLoggedIn=!0}async getUserProfile(){this.ensureLoggedIn();let I=await this.client.getUserProfile();return{displayName:I.displayName||I.userName||"Unknown",profileId:String(I.profileId)}}async getActivities(I=0,w=20){return this.ensureLoggedIn(),await this.client.getActivities(I,w)}async getActivity(I){this.ensureLoggedIn();let w=await this.client.getActivity({activityId:I});return this.parseActivityResponse(w)}async downloadActivityFit(I,w){this.ensureLoggedIn(),await this.client.downloadOriginalActivityData({activityId:I},w,"zip")}async getDailySummary(I){this.ensureLoggedIn();let w={date:I},[G,$,A,_,W,Y]=await Promise.allSettled([this.getHeartRateData(I),this.getSleepData(I),this.getStepsData(I),this.getStressData(I),this.getHrvData(I),this.getBodyBatteryData(I)]);if(G.status==="fulfilled")w.heartRate=G.value;if($.status==="fulfilled")w.sleep=$.value;if(A.status==="fulfilled")w.steps=A.value;if(_.status==="fulfilled")w.stress=_.value;if(W.status==="fulfilled")w.hrv=W.value;if(Y.status==="fulfilled")w.bodyBattery=Y.value;return w}async getHeartRateData(I){this.ensureLoggedIn();try{let w=await this.client.getHeartRate(I);if(!w)return;let G=(w.heartRateValues||[]).filter(([$,A])=>A>0).map(([$,A])=>({timestamp:new Date($),heartRate:A}));return{date:I,restingHeartRate:w.restingHeartRate,minHeartRate:w.minHeartRate,maxHeartRate:w.maxHeartRate,avgHeartRate:G.length>0?Math.round(G.reduce(($,A)=>$+A.heartRate,0)/G.length):void 0,samples:G}}catch{return}}async getSleepData(I){this.ensureLoggedIn();try{let w=await this.client.getSleepData(I);if(!w?.dailySleepDTO)return;let G=w.dailySleepDTO,$=(w.sleepLevels||[]).map((A)=>({stage:this.mapSleepLevel(A.activityLevel),startTime:new Date(A.startGMT),endTime:new Date(A.endGMT)}));return{date:I,startTime:new Date(G.sleepStartTimestampGMT),endTime:new Date(G.sleepEndTimestampGMT),totalSleepTime:G.sleepTimeSeconds/60,deepSleepTime:G.deepSleepSeconds/60,lightSleepTime:G.lightSleepSeconds/60,remSleepTime:G.remSleepSeconds/60,awakeTime:G.awakeSleepSeconds/60,sleepScore:G.sleepScores?.overall?.value,stages:$,avgSpO2:void 0,avgRespirationRate:G.averageRespirationValue}}catch{return}}async getStepsData(I){this.ensureLoggedIn();try{return{total:await this.client.getSteps(I),goal:1e4,distance:0,calories:0}}catch{return}}async getStressData(I){this.ensureLoggedIn();try{let w=await this.client.getStressData(I);if(!w)return;let G=(w.stressValuesArray||[]).filter(([U,H])=>H>=0).map(([U,H])=>({timestamp:new Date(U),stressLevel:H})),$=0,A=0,_=0,W=0,Y=G.length>1?3:0;for(let U of G)if(U.stressLevel<=25)$+=Y;else if(U.stressLevel<=50)A+=Y;else if(U.stressLevel<=75)_+=Y;else W+=Y;return{date:I,avgStressLevel:w.avgStressLevel??0,maxStressLevel:w.maxStressLevel??0,restStressDuration:$,lowStressDuration:A,mediumStressDuration:_,highStressDuration:W,samples:G}}catch{return}}async getBodyBatteryData(I){this.ensureLoggedIn();try{let w=await this.client.getBodyBattery(I);if(!w)return;let G=(w.bodyBatteryValuesArray||[]).filter(([W,Y])=>Y>=0).map(([W,Y])=>({timestamp:new Date(W),level:Y})),$=G.map((W)=>W.level),A=$[0]??0,_=$[$.length-1]??0;return{date:I,startLevel:A,endLevel:_,chargedValue:w.charged??0,drainedValue:w.drained??0,samples:G}}catch{return}}async getHrvData(I){this.ensureLoggedIn();try{let w=await this.client.getHrvData(I);if(!w)return;let G=w.hrvSummary,$=(w.hrvReadings||[]).map((A)=>({timestamp:new Date(A.readingTimeGMT),hrv:A.hrvValue}));return{date:I,weeklyAverage:G?.weeklyAvg,lastNightAverage:G?.lastNightAvg,status:G?.status?G.status.toLowerCase():void 0,baseline:G?.baseline?.markerValue,samples:$}}catch{return}}async getWeightData(I){this.ensureLoggedIn();try{let w=await this.client.getDailyWeightData(I);if(!w?.dateWeightList?.length)return;let G=w.dateWeightList[0];return{date:I,weight:G.weight,bmi:G.bmi,bodyFatPercentage:G.bodyFatPercentage,bodyWater:G.bodyWater,boneMass:G.boneMass,muscleMass:G.muscleMass,visceralFat:G.visceralFat,metabolicAge:G.metabolicAge}}catch{return}}mapSleepLevel(I){switch(I){case 0:return"deep";case 1:return"light";case 2:return"rem";case 3:return"awake";default:return"light"}}parseActivityResponse(I){let w=I;return{id:`garmin_${w.activityId}`,name:w.activityName,sport:this.mapActivityType(w.activityType?.typeKey),startTime:new Date(w.startTimeGMT),endTime:new Date(new Date(w.startTimeGMT).getTime()+w.duration*1000),totalElapsedTime:w.elapsedDuration||w.duration,totalTimerTime:w.duration,totalDistance:w.distance||0,totalCalories:w.calories||0,avgHeartRate:w.averageHR,maxHeartRate:w.maxHR,avgSpeed:w.averageSpeed,maxSpeed:w.maxSpeed,avgCadence:w.averageRunningCadenceInStepsPerMinute||w.averageBikingCadenceInRevPerMinute,maxCadence:w.maxRunningCadenceInStepsPerMinute||w.maxBikingCadenceInRevPerMinute,avgPower:w.avgPower,maxPower:w.maxPower,normalizedPower:w.normPower,totalAscent:w.elevationGain,totalDescent:w.elevationLoss,trainingStressScore:w.trainingStressScore,intensityFactor:w.intensityFactor,laps:[],records:[],source:"garmin"}}mapActivityType(I){return{running:"running",cycling:"cycling",swimming:"swimming",hiking:"hiking",walking:"walking",strength_training:"strength_training",cardio:"cardio",yoga:"yoga",meditation:"other"}[I]||"other"}ensureLoggedIn(){if(!this.isLoggedIn)throw Error("Not logged in. Call login() first.")}}function OZ(I){return new b0(I)}class Q0{config;tokens=null;constructor(I){this.config=I}getAuthorizationUrl(I="read,activity:read_all,activity:write"){return`https://www.strava.com/oauth/authorize?${new URLSearchParams({client_id:this.config.clientId,redirect_uri:this.config.redirectUri||"http://localhost:8080/callback",response_type:"code",scope:I}).toString()}`}async exchangeCode(I){let w=await fetch("https://www.strava.com/oauth/token",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({client_id:this.config.clientId,client_secret:this.config.clientSecret,code:I,grant_type:"authorization_code"})});if(!w.ok){let $=await w.text();throw Error(`Failed to exchange code: ${$}`)}let G=await w.json();return this.tokens={accessToken:G.access_token,refreshToken:G.refresh_token,expiresAt:G.expires_at,athleteId:G.athlete.id},this.tokens}async refreshTokens(){if(!this.tokens)throw Error("No tokens to refresh. Call exchangeCode() first.");let I=await fetch("https://www.strava.com/oauth/token",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({client_id:this.config.clientId,client_secret:this.config.clientSecret,refresh_token:this.tokens.refreshToken,grant_type:"refresh_token"})});if(!I.ok){let G=await I.text();throw Error(`Failed to refresh tokens: ${G}`)}let w=await I.json();return this.tokens={...this.tokens,accessToken:w.access_token,refreshToken:w.refresh_token,expiresAt:w.expires_at},this.tokens}setTokens(I){this.tokens=I}async getAthlete(){await this.ensureValidToken();let I=await fetch("https://www.strava.com/api/v3/athlete",{headers:{Authorization:`Bearer ${this.tokens.accessToken}`}});if(!I.ok)throw Error(`Failed to fetch athlete: ${I.status}`);return await I.json()}async getActivities(I=1,w=30,G,$){await this.ensureValidToken();let A=new URLSearchParams({page:I.toString(),per_page:w.toString()});if(G)A.set("before",Math.floor(G.getTime()/1000).toString());if($)A.set("after",Math.floor($.getTime()/1000).toString());let _=await fetch(`https://www.strava.com/api/v3/athlete/activities?${A.toString()}`,{headers:{Authorization:`Bearer ${this.tokens.accessToken}`}});if(!_.ok)throw Error(`Failed to fetch activities: ${_.status}`);return await _.json()}async getActivity(I,w=!1){await this.ensureValidToken();let G=await fetch(`https://www.strava.com/api/v3/activities/${I}?include_all_efforts=${w}`,{headers:{Authorization:`Bearer ${this.tokens.accessToken}`}});if(!G.ok)throw Error(`Failed to fetch activity: ${G.status}`);let $=await G.json();return this.parseStravaActivity($)}async uploadActivity(I,w,G={}){await this.ensureValidToken();let $=new FormData,A=new Blob([I],{type:"application/octet-stream"});if($.append("file",A,w),G.name)$.append("name",G.name);if(G.description)$.append("description",G.description);if(G.type)$.append("activity_type",G.type);if(G.private)$.append("private","1");if(G.externalId)$.append("external_id",G.externalId);let _=w.split(".").pop()?.toLowerCase(),W=_==="fit"?"fit":_==="tcx"?"tcx":_==="gpx"?"gpx":"fit";$.append("data_type",W);let Y=await fetch("https://www.strava.com/api/v3/uploads",{method:"POST",headers:{Authorization:`Bearer ${this.tokens.accessToken}`},body:$});if(!Y.ok){let U=await Y.text();throw Error(`Failed to upload activity: ${U}`)}return await Y.json()}async checkUploadStatus(I){await this.ensureValidToken();let w=await fetch(`https://www.strava.com/api/v3/uploads/${I}`,{headers:{Authorization:`Bearer ${this.tokens.accessToken}`}});if(!w.ok)throw Error(`Failed to check upload status: ${w.status}`);return await w.json()}async waitForUpload(I,w=10,G=2000){for(let $=0;$<w;$++){let A=await this.checkUploadStatus(I);if(A.activity_id)return A;if(A.error)throw Error(`Upload failed: ${A.error}`);await new Promise((_)=>setTimeout(_,G))}throw Error("Upload timed out")}async updateActivity(I,w){await this.ensureValidToken();let G={};if(w.name)G.name=w.name;if(w.type)G.sport_type=w.type;if(w.description)G.description=w.description;if(w.private!==void 0)G.hide_from_home=w.private;if(w.commute!==void 0)G.commute=w.commute;if(w.trainer!==void 0)G.trainer=w.trainer;if(w.gearId)G.gear_id=w.gearId;let $=await fetch(`https://www.strava.com/api/v3/activities/${I}`,{method:"PUT",headers:{Authorization:`Bearer ${this.tokens.accessToken}`,"Content-Type":"application/json"},body:JSON.stringify(G)});if(!$.ok)throw Error(`Failed to update activity: ${$.status}`);let A=await $.json();return this.parseStravaActivity(A)}async deleteActivity(I){await this.ensureValidToken();let w=await fetch(`https://www.strava.com/api/v3/activities/${I}`,{method:"DELETE",headers:{Authorization:`Bearer ${this.tokens.accessToken}`}});if(!w.ok)throw Error(`Failed to delete activity: ${w.status}`)}async getActivityStreams(I,w=["time","distance","latlng","altitude","heartrate","cadence","watts","temp"]){await this.ensureValidToken();let G=await fetch(`https://www.strava.com/api/v3/activities/${I}/streams?keys=${w.join(",")}&key_by_type=true`,{headers:{Authorization:`Bearer ${this.tokens.accessToken}`}});if(!G.ok)throw Error(`Failed to fetch activity streams: ${G.status}`);let $=await G.json(),A=new Map;for(let[_,W]of Object.entries($))A.set(_,W.data);return A}parseStravaActivity(I){return{id:`strava_${I.id}`,name:I.name,sport:this.mapStravaType(I.sport_type||I.type),startTime:new Date(I.start_date),endTime:new Date(new Date(I.start_date).getTime()+I.elapsed_time*1000),totalElapsedTime:I.elapsed_time,totalTimerTime:I.moving_time,totalDistance:I.distance,totalCalories:I.calories||I.kilojoules?Math.round((I.kilojoules||0)*0.239):0,avgHeartRate:I.average_heartrate,maxHeartRate:I.max_heartrate,avgSpeed:I.average_speed,maxSpeed:I.max_speed,avgCadence:I.average_cadence,avgPower:I.average_watts,maxPower:I.max_watts,normalizedPower:I.weighted_average_watts,totalAscent:I.total_elevation_gain,totalDescent:I.total_elevation_loss,laps:[],records:[],source:"garmin"}}mapStravaType(I){return{Run:"running",TrailRun:"running",Ride:"cycling",MountainBikeRide:"cycling",GravelRide:"cycling",VirtualRide:"cycling",Swim:"swimming",Hike:"hiking",Walk:"walking",WeightTraining:"strength_training",Workout:"cardio",Yoga:"yoga"}[I]||"other"}async ensureValidToken(){if(!this.tokens)throw Error("Not authenticated. Call exchangeCode() or setTokens() first.");if(Date.now()/1000>=this.tokens.expiresAt-300)await this.refreshTokens()}}function FZ(I){return new Q0(I)}function jZ(I){let w={running:"Run",cycling:"Ride",swimming:"Swim",hiking:"Hike",walking:"Walk",strength_training:"WeightTraining",cardio:"Workout",yoga:"Yoga"};return{name:I.name||`${I.sport} - ${I.startTime.toLocaleDateString()}`,type:w[I.sport]||"Workout",description:"Uploaded via ts-watches"}}class fw{process=null;ws=null;messageId=0;pendingMessages=new Map;options;debuggerUrl=null;eventListeners=new Map;userDataDir=null;constructor(I={}){this.options={executablePath:I.executablePath||this.findChrome(),headless:I.headless??!1,timeout:I.timeout??60000,userAgent:I.userAgent||"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",viewportWidth:I.viewportWidth??1280,viewportHeight:I.viewportHeight??800,incognito:I.incognito??!0,userDataDir:I.userDataDir}}findChrome(){let I=["/Applications/Google Chrome.app/Contents/MacOS/Google Chrome","/Applications/Chromium.app/Contents/MacOS/Chromium","/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary","/Applications/Arc.app/Contents/MacOS/Arc","/Applications/Brave Browser.app/Contents/MacOS/Brave Browser","/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge","/usr/bin/google-chrome","/usr/bin/chromium","/usr/bin/chromium-browser","/usr/bin/google-chrome-stable","/snap/bin/chromium","C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe","C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe"];for(let w of I)try{if(Bun.spawnSync(["test","-x",w]).exitCode===0)return w}catch{continue}throw Error("Chrome/Chromium not found. Please install Chrome or specify executablePath.")}async launch(){if(this.options.incognito)this.userDataDir=`/tmp/tp-chrome-${Date.now()}-${Math.random().toString(36).slice(2)}`,await Bun.spawn(["mkdir","-p",this.userDataDir],{stdout:"ignore",stderr:"ignore"}).exited;let I=[this.options.headless?"--headless=new":"","--disable-gpu","--disable-dev-shm-usage","--disable-setuid-sandbox","--no-sandbox","--remote-debugging-port=0",`--window-size=${this.options.viewportWidth},${this.options.viewportHeight}`,"--disable-background-networking","--disable-background-timer-throttling","--disable-backgrounding-occluded-windows","--disable-breakpad","--disable-component-extensions-with-background-pages","--disable-component-update","--disable-default-apps","--disable-extensions","--disable-features=TranslateUI","--disable-hang-monitor","--disable-ipc-flooding-protection","--disable-popup-blocking","--disable-prompt-on-repost","--disable-renderer-backgrounding","--disable-sync","--enable-features=NetworkService,NetworkServiceInProcess","--force-color-profile=srgb","--metrics-recording-only","--no-first-run","--password-store=basic","--use-mock-keychain",this.userDataDir?`--user-data-dir=${this.userDataDir}`:"",this.options.incognito?"--incognito":""].filter(Boolean);this.process=Bun.spawn([this.options.executablePath,...I],{stdout:"pipe",stderr:"pipe"});let G=this.process.stderr.getReader(),$=new TextDecoder,A="",_=Date.now();while(Date.now()-_<this.options.timeout){let{value:Q,done:b}=await G.read();if(b)break;A+=$.decode(Q);let X=A.match(/DevTools listening on (ws:\/\/[^\s]+)/);if(X){this.debuggerUrl=X[1];break}}if(G.releaseLock(),!this.debuggerUrl)throw await this.close(),Error("Failed to get Chrome DevTools URL");let W=this.debuggerUrl.replace("ws://","http://").split("/devtools/")[0],Y=`${W}/json/list`;await new Promise((Q)=>setTimeout(Q,1000));let H=await(await fetch(Y)).text(),Z;try{Z=JSON.parse(H)}catch{throw Error(`Failed to parse browser targets: ${H.slice(0,200)}`)}let q=Z.find((Q)=>Q.type==="page");if(!q){let Q=`${W}/json/new?about:blank`,X=await(await fetch(Q,{method:"PUT"})).text(),L;try{L=JSON.parse(X)}catch{throw Error(`Failed to create new page: ${X.slice(0,200)}`)}this.debuggerUrl=L.webSocketDebuggerUrl}else this.debuggerUrl=q.webSocketDebuggerUrl;await this.connect(),await this.send("Network.enable"),await this.send("Page.enable"),await this.send("Runtime.enable"),await this.send("Network.setUserAgentOverride",{userAgent:this.options.userAgent}),await this.send("Emulation.setDeviceMetricsOverride",{width:this.options.viewportWidth,height:this.options.viewportHeight,deviceScaleFactor:1,mobile:!1})}async connect(){return new Promise((I,w)=>{if(!this.debuggerUrl){w(Error("No debugger URL"));return}this.ws=new WebSocket(this.debuggerUrl),this.ws.onopen=()=>I(),this.ws.onerror=(G)=>w(Error(`WebSocket error: ${G}`)),this.ws.onclose=()=>{this.ws=null},this.ws.onmessage=(G)=>{try{let $=JSON.parse(String(G.data));if($.id!==void 0){let A=this.pendingMessages.get($.id);if(A)if(this.pendingMessages.delete($.id),$.error)A.reject(Error($.error.message));else A.resolve($.result)}if($.method){let A=this.eventListeners.get($.method);if(A)for(let _ of A)_($.params)}}catch{}}})}async send(I,w={}){if(!this.ws)throw Error("Not connected to browser");let G=++this.messageId;return new Promise(($,A)=>{let _=setTimeout(()=>{this.pendingMessages.delete(G),A(Error(`CDP command timed out: ${I}`))},this.options.timeout);this.pendingMessages.set(G,{resolve:(W)=>{clearTimeout(_),$(W)},reject:(W)=>{clearTimeout(_),A(W)}}),this.ws.send(JSON.stringify({id:G,method:I,params:w}))})}on(I,w){let G=this.eventListeners.get(I)||[];G.push(w),this.eventListeners.set(I,G)}async goto(I){return await this.send("Page.navigate",{url:I}),await new Promise((G)=>setTimeout(G,2000)),(await this.send("Runtime.evaluate",{expression:"document.documentElement.outerHTML",returnByValue:!0})).result.value}async waitForNavigation(I=30000){return new Promise((w,G)=>{let $=setTimeout(()=>{G(Error("Navigation timeout"))},I),A=()=>{clearTimeout($),this.eventListeners.delete("Page.loadEventFired"),w()};this.on("Page.loadEventFired",A)})}async waitForUrl(I,w=60000){let G=Date.now();while(Date.now()-G<w){let A=(await this.send("Runtime.evaluate",{expression:"window.location.href",returnByValue:!0})).result.value;if(typeof I==="string"){if(A.includes(I))return A}else if(I.test(A))return A;await new Promise((_)=>setTimeout(_,500))}throw Error(`Timeout waiting for URL pattern: ${I}`)}async type(I,w){let G=I.replace(/'/g,"\\'"),$=await this.send("Runtime.evaluate",{expression:`
|
|
201
|
+
(function() {
|
|
202
|
+
const el = document.querySelector('${G}');
|
|
203
|
+
if (!el) return { success: false, error: 'Element not found' };
|
|
204
|
+
|
|
205
|
+
// Focus the element
|
|
206
|
+
el.focus();
|
|
207
|
+
|
|
208
|
+
// Clear and set value
|
|
209
|
+
el.value = '${w.replace(/'/g,"\\'")}';
|
|
210
|
+
|
|
211
|
+
// Trigger events
|
|
212
|
+
el.dispatchEvent(new Event('input', { bubbles: true }));
|
|
213
|
+
el.dispatchEvent(new Event('change', { bubbles: true }));
|
|
214
|
+
el.dispatchEvent(new KeyboardEvent('keyup', { bubbles: true }));
|
|
215
|
+
|
|
216
|
+
return { success: true, value: el.value };
|
|
217
|
+
})()
|
|
218
|
+
`,returnByValue:!0});if(!$.result.value?.success)throw Error(`Failed to type into ${I}: ${$.result.value?.error||"unknown error"}`)}async click(I){let w=I.replace(/'/g,"\\'"),G=await this.send("Runtime.evaluate",{expression:`
|
|
219
|
+
(function() {
|
|
220
|
+
const el = document.querySelector('${w}');
|
|
221
|
+
if (!el) return null;
|
|
222
|
+
el.scrollIntoView({ behavior: 'instant', block: 'center' });
|
|
223
|
+
const rect = el.getBoundingClientRect();
|
|
224
|
+
return { x: rect.x + rect.width / 2, y: rect.y + rect.height / 2 };
|
|
225
|
+
})()
|
|
226
|
+
`,returnByValue:!0});if(!G.result.value)throw Error(`Element not found: ${I}`);let{x:$,y:A}=G.result.value;await this.send("Input.dispatchMouseEvent",{type:"mouseMoved",x:$,y:A}),await new Promise((_)=>setTimeout(_,50)),await this.send("Input.dispatchMouseEvent",{type:"mousePressed",x:$,y:A,button:"left",clickCount:1}),await new Promise((_)=>setTimeout(_,50)),await this.send("Input.dispatchMouseEvent",{type:"mouseReleased",x:$,y:A,button:"left",clickCount:1})}async submitForm(I){let w=I?I.replace(/'/g,"\\'"):"form";await this.send("Runtime.evaluate",{expression:`document.querySelector('${w}')?.submit()`})}async jsClick(I){let w=I.replace(/'/g,"\\'");await this.send("Runtime.evaluate",{expression:`
|
|
227
|
+
const el = document.querySelector('${w}');
|
|
228
|
+
if (el) {
|
|
229
|
+
el.scrollIntoView({ behavior: 'instant', block: 'center' });
|
|
230
|
+
el.click();
|
|
231
|
+
}
|
|
232
|
+
`})}async evaluate(I){let w=await this.send("Runtime.evaluate",{expression:I,returnByValue:!0,awaitPromise:!0});if(w.exceptionDetails)throw Error(w.exceptionDetails.exception?.description||"Evaluation failed");return w.result.value}async getCookies(I){return(await this.send("Network.getCookies",I?{urls:I}:{})).cookies}async setCookies(I){await this.send("Network.setCookies",{cookies:I.map((w)=>({name:w.name,value:w.value,domain:w.domain,path:w.path||"/"}))})}async clearCookies(){await this.send("Network.clearBrowserCookies"),await this.send("Network.clearBrowserCache")}async clearAllStorage(){await this.send("Network.clearBrowserCookies"),await this.send("Network.clearBrowserCache"),await this.send("Storage.clearDataForOrigin",{origin:"https://trainingpeaks.com",storageTypes:"all"}),await this.send("Storage.clearDataForOrigin",{origin:"https://home.trainingpeaks.com",storageTypes:"all"}),await this.send("Storage.clearDataForOrigin",{origin:"https://app.trainingpeaks.com",storageTypes:"all"})}async enableRequestLogging(I){let w=[];return this.on("Network.requestWillBeSent",(G)=>{let $=G,A=$.request.url;if(!I||I.test(A))w.push(`${$.request.method} ${A}`)}),w}async screenshot(I){let w=await this.send("Page.captureScreenshot",{format:"png"});if(I)await Bun.write(I,Buffer.from(w.data,"base64"));return w.data}async close(){for(let[I,w]of this.pendingMessages)w.reject(Error("Browser closed")),this.pendingMessages.delete(I);if(this.ws){try{await this.send("Browser.close")}catch{}this.ws.close(),this.ws=null}if(this.process)this.process.kill(),this.process=null;if(this.userDataDir){try{await Bun.spawn(["rm","-rf",this.userDataDir],{stdout:"ignore",stderr:"ignore"}).exited}catch{}this.userDataDir=null}}}class vw{cookies=new Map;baseUrl;timeout;userAgent;constructor(I={}){this.baseUrl=I.baseUrl||"https://home.trainingpeaks.com",this.timeout=I.timeout||30000,this.userAgent=I.userAgent||"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"}setCookies(I){for(let w of I){let G=`${w.domain||""}:${w.name}`;this.cookies.set(G,w)}}getCookies(){return Array.from(this.cookies.values())}clearCookies(){this.cookies.clear()}getCookieHeader(I){let w=new URL(I),G=[];for(let $ of this.cookies.values()){if($.domain){let A=$.domain.startsWith(".")?$.domain.slice(1):$.domain;if(!w.hostname.endsWith(A)&&w.hostname!==A)continue}if($.path&&!w.pathname.startsWith($.path))continue;if($.secure&&w.protocol!=="https:")continue;if($.expires&&$.expires<new Date)continue;G.push($)}return G.map(($)=>`${$.name}=${$.value}`).join("; ")}extractCookies(I,w){let G=I.headers.getSetCookie(),$=new URL(w);for(let A of G){let _=this.parseCookie(A,$.hostname);if(_){let W=`${_.domain||""}:${_.name}`;this.cookies.set(W,_)}}}parseCookie(I,w){let G=I.split(";").map((H)=>H.trim()),[$,...A]=G;if(!$||!$.includes("="))return null;let[_,...W]=$.split("="),Y=W.join("="),U={name:_.trim(),value:Y.trim(),domain:w,path:"/"};for(let H of A){let[Z,...q]=H.split("="),Q=Z.trim().toLowerCase(),b=q.join("=").trim();switch(Q){case"domain":U.domain=b;break;case"path":U.path=b;break;case"expires":U.expires=new Date(b);break;case"max-age":let X=parseInt(b,10);if(X)U.expires=new Date(Date.now()+X*1000);break;case"secure":U.secure=!0;break;case"httponly":U.httpOnly=!0;break}}return U}async request(I,w,G={}){let $=w.startsWith("http")?w:`${this.baseUrl}${w}`;if(G.params){let H=new URLSearchParams;for(let[q,Q]of Object.entries(G.params))if(Q!==void 0)H.set(q,String(Q));let Z=H.toString();if(Z)$+=($.includes("?")?"&":"?")+Z}let A={"User-Agent":this.userAgent,Accept:"application/json, text/plain, */*","Accept-Language":"en-US,en;q=0.9",...G.headers},_=this.getCookieHeader($);if(_)A.Cookie=_;let W;if(G.body!==void 0){if(typeof G.body==="object")A["Content-Type"]=A["Content-Type"]||"application/json",W=JSON.stringify(G.body);else if(typeof G.body==="string")W=G.body}let Y=new AbortController,U=setTimeout(()=>Y.abort(),this.timeout);try{let H=await fetch($,{method:I,headers:A,body:W,signal:Y.signal,redirect:"follow"});if(clearTimeout(U),this.extractCookies(H,$),!H.ok){let q=await H.text();throw Error(`HTTP ${H.status}: ${q}`)}if(H.headers.get("content-type")?.includes("application/json"))return await H.json();return await H.text()}catch(H){if(clearTimeout(U),H instanceof Error&&H.name==="AbortError")throw Error(`Request timeout: ${$}`);throw H}}async get(I,w){return this.request("GET",I,{params:w})}async post(I,w,G){return this.request("POST",I,{body:w,headers:G})}async put(I,w){return this.request("PUT",I,{body:w})}async delete(I){return this.request("DELETE",I)}async saveCookies(I){let w=this.getCookies();await Bun.write(I,JSON.stringify(w,null,2))}async loadCookies(I){try{let G=await Bun.file(I).text(),$=JSON.parse(G);for(let A of $)if(A.expires)A.expires=new Date(A.expires);this.setCookies($)}catch{}}}var EY="https://home.trainingpeaks.com",OY="https://app.trainingpeaks.com",D="https://tpapi.trainingpeaks.com";class lG{credentials;client;cookiePath;headless;timeout;authenticated=!1;currentUser=null;isCoach=!1;constructor(I){this.credentials={username:I.username,password:I.password},this.cookiePath=I.cookiePath,this.headless=I.headless??!1,this.timeout=I.timeout??60000,this.client=new vw({baseUrl:OY,timeout:this.timeout})}async login(){if(this.cookiePath)try{if(await this.client.loadCookies(this.cookiePath),await this.verifySession())return this.authenticated=!0,this}catch{}let I=new fw({headless:this.headless,timeout:this.timeout,incognito:!0});try{await I.launch(),console.log("Clearing browser storage...");try{await I.clearAllStorage()}catch{}console.log("Navigating to login page..."),await I.goto(`${EY}/login`),await new Promise((_)=>setTimeout(_,3000)),console.log("Checking for cookie banner...");try{await I.evaluate(`
|
|
233
|
+
// Common cookie consent selectors
|
|
234
|
+
const selectors = [
|
|
235
|
+
'#onetrust-accept-btn-handler',
|
|
236
|
+
'.onetrust-close-btn-handler',
|
|
237
|
+
'[aria-label="Accept cookies"]',
|
|
238
|
+
'[data-testid="cookie-accept"]',
|
|
239
|
+
'.cookie-accept',
|
|
240
|
+
'.accept-cookies',
|
|
241
|
+
'button[contains(text(), "Accept")]',
|
|
242
|
+
'button[contains(text(), "Got it")]',
|
|
243
|
+
];
|
|
244
|
+
for (const sel of selectors) {
|
|
245
|
+
const btn = document.querySelector(sel);
|
|
246
|
+
if (btn) {
|
|
247
|
+
btn.click()
|
|
248
|
+
break
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
`),await new Promise((_)=>setTimeout(_,1000))}catch{}let w=await I.evaluate("window.location.href");if(w.includes("app.trainingpeaks.com")&&!w.includes("login"))console.log("Already logged in!");else{if(console.log("Entering username..."),await I.type('input[name="Username"]',this.credentials.username),await new Promise((W)=>setTimeout(W,300)),console.log("Entering password..."),await I.type('input[name="Password"]',this.credentials.password),await new Promise((W)=>setTimeout(W,500)),console.log("Waiting for reCAPTCHA to initialize..."),await new Promise((W)=>setTimeout(W,2000)),console.log("Submitting login form..."),await I.jsClick('button[type="submit"]'),await new Promise((W)=>setTimeout(W,1000)),(await I.evaluate("window.location.href")).includes("login"))console.log("Button click may not have worked, trying form submit..."),await I.submitForm("form");console.log("Waiting for login to complete..."),await I.waitForUrl(/app\.trainingpeaks\.com(?!.*login)|home\.trainingpeaks\.com\/(athlete|coach|calendar|dashboard)/,this.timeout)}let G=await I.evaluate("window.location.href");this.isCoach=G.includes("/coach")||G.includes("coach.");let A=(await I.getCookies(["https://trainingpeaks.com","https://home.trainingpeaks.com","https://app.trainingpeaks.com","https://tpapi.trainingpeaks.com"])).map((_)=>({name:_.name,value:_.value,domain:_.domain,path:_.path,expires:_.expires>0?new Date(_.expires*1000):void 0,secure:_.secure,httpOnly:_.httpOnly}));if(this.client.setCookies(A),this.authenticated=!0,this.cookiePath)await this.client.saveCookies(this.cookiePath);console.log("Login successful!")}finally{await I.close()}return this}async verifySession(){try{return(await this.client.get(`${D}/users/v3/token`)).success===!0}catch{return!1}}async getCurrentUser(){if(this.currentUser)return this.currentUser;let I=await this.client.get(`${D}/users/v3/user`);return this.currentUser={Id:I.user.userId,UserId:I.user.userId},this.currentUser}isCoachAccount(){return this.isCoach}async getAthlete(I){let w=I||(await this.getCurrentUser()).Id;return this.client.get(`${D}/fitness/v1/athletes/${w}/settings`)}async getCoachedAthletes(){let I=await this.getCurrentUser();return this.client.get(`${D}/fitness/v1/coaches/${I.Id}/coachedathletesadded`)}async getAthleteGroups(){let I=await this.getCurrentUser();return this.client.get(`${D}/coaches/v2/coaches/${I.Id}/tags`)}async getCoachedAthleteIds(){let I=await this.getAthleteGroups(),w=new Set;for(let G of I)for(let $ of G.athleteIds)w.add($);return Array.from(w)}async getAthleteGroupFeed(I){let w=await this.getCurrentUser();return this.client.get(`${D}/fitness/v1/coaches/${w.Id}/athletegroups/${I}/feed`)}async getAssistantCoaches(){let I=await this.getCurrentUser();return this.client.get(`${D}/coaches/v1/coaches/${I.Id}/assistantcoaches`)}async getCoachSettings(){let I=await this.getCurrentUser();return this.client.get(`${D}/coaches/v1/coaches/${I.Id}/settings`)}async getAthletesUpgradeStatus(){let I=await this.getCurrentUser();return this.client.get(`${D}/coaches/v1/coaches/${I.Id}/athletes/upgradeStatus`)}async getEquipment(I){let w=I||(await this.getCurrentUser()).Id;return this.client.get(`${D}/fitness/v1/athletes/${w}/equipment`)}async getZones(I){let w=I||(await this.getCurrentUser()).Id;return this.client.get(`${D}/fitness/v1/athletes/${w}/defaultZones`)}async getGoals(I){let w=I||(await this.getCurrentUser()).Id;return this.client.get(`${D}/fitness/v1/athletes/${w}/goallists`)}async getCoaches(I){let w=I||(await this.getCurrentUser()).Id;return this.client.get(`${D}/fitness/v1/athletes/${w}/coaches/shared`)}async getPrimaryCoach(I){let w=I||(await this.getCurrentUser()).Id;return this.client.get(`${D}/fitness/v1/athletes/${w}/coaches/primary`)}async getWorkouts(I,w,G){let $=G||(await this.getCurrentUser()).Id,A=this.formatDate(I),_=this.formatDate(w);return this.client.get(`${D}/fitness/v6/athletes/${$}/workouts/${A}/${_}`)}async getWorkout(I,w){let G=w||(await this.getCurrentUser()).Id;return this.client.get(`${D}/fitness/v6/athletes/${G}/workouts/${I}/details`)}async createWorkout(I,w){let G=w||(await this.getCurrentUser()).Id;return this.client.post(`${D}/fitness/v6/athletes/${G}/workouts`,I)}async updateWorkout(I,w){return this.client.put(`${D}/fitness/v6/workouts/${I}`,w)}async deleteWorkout(I){await this.client.delete(`${D}/fitness/v6/workouts/${I}`)}async completeWorkout(I,w){return this.client.put(`${D}/fitness/v6/workouts/${I}/complete`,{Completed:!0,CompletedDate:new Date().toISOString(),...w})}async getCalendarNotes(I,w,G){let $=G||(await this.getCurrentUser()).Id,A=this.formatDate(I),_=this.formatDate(w);return this.client.get(`${D}/fitness/v1/athletes/${$}/calendarNote/${A}/${_}`)}async getEvents(I,w,G){let $=G||(await this.getCurrentUser()).Id,A=this.formatDate(I),_=this.formatDate(w);return this.client.get(`${D}/fitness/v6/athletes/${$}/events/${A}/${_}`)}async getFocusEvent(I){let w=I||(await this.getCurrentUser()).Id;return this.client.get(`${D}/fitness/v6/athletes/${w}/events/focusevent`)}async getAvailability(I,w,G){let $=G||(await this.getCurrentUser()).Id,A=this.formatDate(I),_=this.formatDate(w);return this.client.get(`${D}/fitness/v1/athletes/${$}/availability/${A}/${_}`)}async getMetrics(I,w,G){let $=G||(await this.getCurrentUser()).Id,A=this.formatDate(I),_=this.formatDate(w);return this.client.get(`${D}/metrics/v3/athletes/${$}/consolidatedtimedmetrics/${A}/${_}`)}async saveMetrics(I,w){let G=w||(await this.getCurrentUser()).Id;return this.client.post(`${D}/fitness/v1/athletes/${G}/metrics`,I)}async getPerformanceChart(I,w,G){let $=G||(await this.getCurrentUser()).Id,A=this.formatDate(I),_=this.formatDate(w);return this.client.get(`${D}/fitness/v3/athletes/${$}/pmc/${A}/${_}`)}async uploadFile(I,w,G){let $=G||(await this.getCurrentUser()).Id,A=await this.gzipEncode(I),_=this.arrayBufferToBase64(A);return this.client.post(`${D}/fitness/v1/athletes/${$}/fileupload`,{FileName:w,Data:_})}async getLibraryWorkouts(I){let w=await this.getCurrentUser();return this.client.get(`${D}/fitness/v1/athletes/${w.Id}/library/workouts`,{limit:I?.limit,offset:I?.offset})}async createLibraryWorkout(I){let w=await this.getCurrentUser();return this.client.post(`${D}/fitness/v1/athletes/${w.Id}/library/workouts`,I)}async applyLibraryWorkout(I,w,G){let $=G||(await this.getCurrentUser()).Id;return this.client.post(`${D}/fitness/v1/athletes/${$}/workouts/fromLibrary`,{LibraryWorkoutId:I,WorkoutDay:this.formatDate(w)})}async getAppliedPlans(I,w){let G=w||(await this.getCurrentUser()).Id,$=this.formatDate(I||new Date);return this.client.get(`${D}/plans/v1/athletes/${G}/appliedplans/${$}`)}async getWorkoutTypes(){return this.client.get(`${D}/fitness/v6/workouttypes`)}async getFeatureFlags(){return this.client.get(`${D}/users/v1/featureflags`)}async getAccessRights(){return this.client.get(`${D}/users/v1/user/accessrights`)}async getIntegrations(){return this.client.get(`${D}/integrations/v1/access/userIntegrations`)}formatDate(I){return I.toISOString().split("T")[0]}async gzipEncode(I){let $=new ReadableStream({start(U){U.enqueue(new Uint8Array(I)),U.close()}}).pipeThrough(new CompressionStream("gzip")).getReader(),A=[];while(!0){let{done:U,value:H}=await $.read();if(U)break;A.push(H)}let _=A.reduce((U,H)=>U+H.length,0),W=new Uint8Array(_),Y=0;for(let U of A)W.set(U,Y),Y+=U.length;return W.buffer}arrayBufferToBase64(I){let w=new Uint8Array(I),G="";for(let $=0;$<w.byteLength;$++)G+=String.fromCharCode(w[$]);return btoa(G)}exportCookies(){return this.client.getCookies()}importCookies(I){this.client.setCookies(I)}async get(I,w){let G=I.startsWith("http")?I:`${D}${I}`;return this.client.get(G,w)}async post(I,w){let G=I.startsWith("http")?I:`${D}${I}`;return this.client.post(G,w)}}var zY={Swim:1,Bike:2,Run:3,Brick:4,XTrain:5,Strength:6,Custom:7,Walk:8,Hike:9,Row:10,Ski:11,Other:100};function FY(I){return{1:"Swim",2:"Bike",3:"Run",4:"Brick",5:"XTrain",6:"Strength",7:"Custom",8:"Walk",9:"Hike",10:"Row",11:"Ski"}[I]||"Other"}var jY={ftp:200,lthr:165,maxHr:190,restingHr:50,atlDecay:7,ctlDecay:42};class L0{config;constructor(I={}){this.config={...jY,...I}}calculateTSS(I){if(I.trainingStressScore)return I.trainingStressScore;if(I.avgPower&&I.normalizedPower)return this.calculatePowerTSS(I);if(I.avgHeartRate)return this.calculateHrTSS(I);if(I.sport==="running"&&I.avgSpeed)return this.calculateRunningTSS(I);return this.estimateTSSFromDuration(I)}calculatePowerTSS(I){let w=I.normalizedPower||I.avgPower,G=I.totalTimerTime/3600,$=w/this.config.ftp;return G*w*$/this.config.ftp*100}calculateHrTSS(I){let w=I.avgHeartRate,G=I.totalTimerTime/60,$=this.config.maxHr-this.config.restingHr,A=(w-this.config.restingHr)/$,_=I.sport==="running"?1.92:1.67,W=G*A*0.64*Math.exp(_*A),Y=(this.config.lthr-this.config.restingHr)/$,U=60*Y*0.64*Math.exp(_*Y);return W/U*100}calculateRunningTSS(I){let w=I.totalTimerTime/3600,G=1000/I.avgSpeed/60,$=5,A=5/G;return w*A*A*100}estimateTSSFromDuration(I){let w=I.totalTimerTime/3600,G=0.7;return w*0.7*0.7*100}calculateIntensityFactor(I){if(I.intensityFactor)return I.intensityFactor;if(I.normalizedPower)return I.normalizedPower/this.config.ftp;if(I.avgPower)return I.avgPower/this.config.ftp;if(I.avgHeartRate)return I.avgHeartRate/this.config.lthr;return 0.7}calculateTrainingLoad(I,w,G){let $=[...I].sort((b,X)=>b.startTime.getTime()-X.startTime.getTime());if($.length===0)return[];let A=w||$[0].startTime,_=G||new Date,W=new Map;for(let b of $){let X=b.startTime.toISOString().slice(0,10),L=this.calculateTSS(b);W.set(X,(W.get(X)||0)+L)}let Y=[],U=0,H=0,Z=1-Math.exp(-1/this.config.atlDecay),q=1-Math.exp(-1/this.config.ctlDecay),Q=new Date(A);while(Q<=_){let b=Q.toISOString().slice(0,10),X=W.get(b)||0;U=U+Z*(X-U),H=H+q*(X-H);let L=H-U;Y.push({date:new Date(Q),tss:X,atl:Math.round(U*10)/10,ctl:Math.round(H*10)/10,tsb:Math.round(L*10)/10}),Q.setDate(Q.getDate()+1)}return Y}getCurrentMetrics(I){let w=this.calculateTrainingLoad(I);if(w.length===0)return{tss:0,atl:0,ctl:0,tsb:0,ifactor:0,rampRate:0};let G=w[w.length-1],$=w.length>7?w[w.length-8]:w[0],A=w.slice(-7).reduce((H,Z)=>H+Z.tss,0),_=w.slice(-14,-7).reduce((H,Z)=>H+Z.tss,0),W=G.ctl-$.ctl,Y=I.filter((H)=>H.startTime>=new Date(Date.now()-604800000)),U=Y.length>0?Y.reduce((H,Z)=>H+this.calculateIntensityFactor(Z),0)/Y.length:0;return{tss:A,atl:G.atl,ctl:G.ctl,tsb:G.tsb,ifactor:Math.round(U*100)/100,rampRate:Math.round(W*10)/10}}getTrainingRecommendation(I){let{tsb:w,rampRate:G,ctl:$}=I,A,_,W;if(w>25)A="fresh",_="You are well rested. Good time for a race or hard workout.",W={min:Math.round($*1.2),max:Math.round($*1.5)};else if(w>=-10&&w<=25)A="optimal",_="You are in the optimal training zone. Maintain consistency.",W={min:Math.round($*0.8),max:Math.round($*1.2)};else if(w>=-30)A="tired",_="You are accumulating fatigue. Consider easier sessions or rest.",W={min:Math.round($*0.4),max:Math.round($*0.7)};else A="overtrained",_="High fatigue detected. Take a rest day or very easy session.",W={min:0,max:Math.round($*0.3)};if(G>7)_+=" Warning: Training load is increasing rapidly.";return{status:A,recommendation:_,suggestedTSS:W}}}function tZ(I){return new L0(I)}var NY=[{type:"longest_distance",label:"Longest Distance",unit:"km",sports:["running","cycling","swimming","hiking","walking"],extractor:(I)=>I.totalDistance/1000,comparator:"higher"},{type:"longest_duration",label:"Longest Duration",unit:"hours",sports:["running","cycling","swimming","hiking","walking","strength_training"],extractor:(I)=>I.totalTimerTime/3600,comparator:"higher"},{type:"longest_moving_time",label:"Longest Moving Time",unit:"hours",sports:["running","cycling","hiking"],extractor:(I)=>I.totalTimerTime/3600,comparator:"higher"},{type:"fastest_1k",label:"Fastest 1K",unit:"min:sec",sports:["running"],extractor:(I,w)=>nI(w||[],1000),comparator:"lower",distanceMeters:1000},{type:"fastest_5k",label:"Fastest 5K",unit:"min:sec",sports:["running"],extractor:(I,w)=>nI(w||[],5000),comparator:"lower",distanceMeters:5000},{type:"fastest_10k",label:"Fastest 10K",unit:"min:sec",sports:["running"],extractor:(I,w)=>nI(w||[],1e4),comparator:"lower",distanceMeters:1e4},{type:"fastest_half_marathon",label:"Fastest Half Marathon",unit:"hours:min:sec",sports:["running"],extractor:(I,w)=>nI(w||[],21097.5),comparator:"lower",distanceMeters:21097.5},{type:"fastest_marathon",label:"Fastest Marathon",unit:"hours:min:sec",sports:["running"],extractor:(I,w)=>nI(w||[],42195),comparator:"lower",distanceMeters:42195},{type:"fastest_1_mile",label:"Fastest Mile",unit:"min:sec",sports:["running"],extractor:(I,w)=>nI(w||[],1609.34),comparator:"lower",distanceMeters:1609.34},{type:"fastest_avg_pace",label:"Fastest Avg Pace",unit:"min/km",sports:["running"],extractor:(I)=>I.avgSpeed?1000/I.avgSpeed/60:null,comparator:"lower"},{type:"max_speed",label:"Max Speed",unit:"km/h",sports:["running","cycling"],extractor:(I)=>I.maxSpeed?I.maxSpeed*3.6:null,comparator:"higher"},{type:"highest_avg_power",label:"Highest Avg Power",unit:"W",sports:["cycling"],extractor:(I)=>I.avgPower||null,comparator:"higher"},{type:"highest_max_power",label:"Highest Max Power",unit:"W",sports:["cycling"],extractor:(I)=>I.maxPower||null,comparator:"higher"},{type:"highest_normalized_power",label:"Highest Normalized Power",unit:"W",sports:["cycling"],extractor:(I)=>I.normalizedPower||null,comparator:"higher"},{type:"best_5min_power",label:"Best 5min Power",unit:"W",sports:["cycling"],extractor:(I,w)=>cG(w||[],300),comparator:"higher"},{type:"best_20min_power",label:"Best 20min Power",unit:"W",sports:["cycling"],extractor:(I,w)=>cG(w||[],1200),comparator:"higher"},{type:"best_1hr_power",label:"Best 1hr Power",unit:"W",sports:["cycling"],extractor:(I,w)=>cG(w||[],3600),comparator:"higher"},{type:"highest_avg_hr",label:"Highest Avg HR",unit:"bpm",sports:["running","cycling","swimming"],extractor:(I)=>I.avgHeartRate||null,comparator:"higher"},{type:"highest_max_hr",label:"Highest Max HR",unit:"bpm",sports:["running","cycling","swimming"],extractor:(I)=>I.maxHeartRate||null,comparator:"higher"},{type:"highest_elevation_gain",label:"Highest Elevation Gain",unit:"m",sports:["running","cycling","hiking"],extractor:(I)=>I.totalAscent||null,comparator:"higher"},{type:"most_calories",label:"Most Calories",unit:"kcal",sports:["running","cycling","swimming","strength_training"],extractor:(I)=>I.totalCalories||null,comparator:"higher"}];function nI(I,w){if(I.length<2)return null;let G=I.filter((A)=>A.distance!=null);if(G.length<2)return null;let $=1/0;for(let A=0;A<G.length;A++){let _=G[A],W=_.distance;for(let Y=A+1;Y<G.length;Y++){let U=G[Y],H=U.distance,Z=H-W;if(Z>=w){let q=(U.timestamp.getTime()-_.timestamp.getTime())/1000;if(Z>w&&Y>0){let Q=G[Y-1],b=Q.distance,X=H-b,L=(U.timestamp.getTime()-Q.timestamp.getTime())/1000,J=Z-w,B=q-J/X*L;$=Math.min($,B)}else $=Math.min($,q);break}}}return $===1/0?null:$}function cG(I,w){let G=I.filter((A)=>A.power!=null);if(G.length<2)return null;let $=0;for(let A=0;A<G.length;A++){let _=G[A].timestamp.getTime(),W=0,Y=0;for(let U=A;U<G.length;U++){let H=(G[U].timestamp.getTime()-_)/1000;if(H>w)break;if(W+=G[U].power,Y++,H>=w-1){let Z=W/Y;$=Math.max($,Z)}}}return $>0?Math.round($):null}class iG{records=new Map;constructor(I){if(I)for(let w of I){let G=`${w.sport}_${w.type}`;this.records.set(G,w)}}processActivity(I){let w=[];for(let G of NY){if(!G.sports.includes(I.sport))continue;let $=G.extractor(I,I.records);if($==null)continue;let A=`${I.sport}_${G.type}`,_=this.records.get(A);if(!_||(G.comparator==="higher"?$>_.value:$<_.value)){let Y={type:G.type,value:$,unit:G.unit,activityId:I.id,activityName:I.name,date:I.startTime,sport:I.sport,previousRecord:_?{value:_.value,date:_.date}:void 0};this.records.set(A,Y),w.push(Y)}}return w}processActivities(I){let w=[...I].sort(($,A)=>$.startTime.getTime()-A.startTime.getTime()),G=[];for(let $ of w){let A=this.processActivity($);G.push(...A)}return G}getAllRecords(){return Array.from(this.records.values())}getRecordsForSport(I){return Array.from(this.records.values()).filter((w)=>w.sport===I)}getRecord(I,w){return this.records.get(`${I}_${w}`)}formatRecordValue(I){if(I.unit==="min:sec"){let w=Math.floor(I.value/60),G=Math.round(I.value%60);return`${w}:${G.toString().padStart(2,"0")}`}if(I.unit==="hours:min:sec"){let w=Math.floor(I.value/3600),G=Math.floor(I.value%3600/60),$=Math.round(I.value%60);return`${w}:${G.toString().padStart(2,"0")}:${$.toString().padStart(2,"0")}`}if(I.unit==="min/km"){let w=Math.floor(I.value),G=Math.round(I.value%1*60);return`${w}:${G.toString().padStart(2,"0")}`}if(I.unit==="hours")return I.value.toFixed(2);if(I.unit==="km")return I.value.toFixed(2);return I.value.toString()}toJSON(){return this.getAllRecords()}static fromJSON(I){return new iG(I.map((w)=>({...w,date:new Date(w.date),previousRecord:w.previousRecord?{...w.previousRecord,date:new Date(w.previousRecord.date)}:void 0})))}}function eZ(I){return new iG(I)}var VY=[{name:"Z1 - Recovery",min:50,max:60,color:"#9CA3AF"},{name:"Z2 - Aerobic",min:60,max:70,color:"#3B82F6"},{name:"Z3 - Tempo",min:70,max:80,color:"#22C55E"},{name:"Z4 - Threshold",min:80,max:90,color:"#F59E0B"},{name:"Z5 - VO2max",min:90,max:100,color:"#EF4444"}],xY=[{name:"Z1 - Active Recovery",min:0,max:55,color:"#9CA3AF"},{name:"Z2 - Endurance",min:55,max:75,color:"#3B82F6"},{name:"Z3 - Tempo",min:75,max:90,color:"#22C55E"},{name:"Z4 - Threshold",min:90,max:105,color:"#F59E0B"},{name:"Z5 - VO2max",min:105,max:120,color:"#EF4444"},{name:"Z6 - Anaerobic",min:120,max:150,color:"#7C3AED"},{name:"Z7 - Neuromuscular",min:150,max:300,color:"#EC4899"}],kY=[{name:"Z1 - Recovery",min:130,max:150,color:"#9CA3AF"},{name:"Z2 - Easy",min:115,max:130,color:"#3B82F6"},{name:"Z3 - Aerobic",min:105,max:115,color:"#22C55E"},{name:"Z4 - Threshold",min:95,max:105,color:"#F59E0B"},{name:"Z5 - Interval",min:85,max:95,color:"#EF4444"},{name:"Z6 - Repetition",min:0,max:85,color:"#7C3AED"}];class X0{config;constructor(I){this.config=I}getHeartRateZones(){if(!this.config.heartRate)return[];let{maxHr:I,restingHr:w=0,method:G,lthr:$,zones:A}=this.config.heartRate;if(A)return A;return VY.map((W)=>{let Y,U;if(G==="reserve"&&w){let H=I-w;Y=Math.round(w+W.min/100*H),U=Math.round(w+W.max/100*H)}else if(G==="lthr"&&$)Y=Math.round($*(W.min/85)),U=Math.round($*(W.max/85));else Y=Math.round(I*W.min/100),U=Math.round(I*W.max/100);return{...W,min:Y,max:U}})}getPowerZones(){if(!this.config.power)return[];let{ftp:I,zones:w}=this.config.power;if(w)return w;return xY.map((G)=>({...G,min:Math.round(I*G.min/100),max:Math.round(I*G.max/100)}))}getPaceZones(){if(!this.config.pace)return[];let{thresholdPace:I,zones:w}=this.config.pace;if(w)return w;return kY.map((G)=>({...G,min:Math.round(I*G.min/100),max:Math.round(I*G.max/100)}))}analyzeActivity(I){let w=this.getHeartRateZones(),G=this.getPowerZones(),$=this.getPaceZones(),A=w.length>0?this.calculateTimeInZones(I.records,"heartRate",w):void 0,_=G.length>0?this.calculateTimeInZones(I.records,"power",G):void 0,W=$.length>0?this.calculateTimeInPaceZones(I.records,$):void 0,Y=A||_,U=this.calculateSummary(Y);return{heartRate:A,power:_,pace:W,summary:U}}calculateTimeInZones(I,w,G){let $=Array(G.length).fill(0),A=0;for(let _=1;_<I.length;_++){let W=I[_][w];if(W==null)continue;let Y=(I[_].timestamp.getTime()-I[_-1].timestamp.getTime())/1000;A+=Y;for(let U=0;U<G.length;U++){if(W>=G[U].min&&W<G[U].max){$[U]+=Y;break}if(U===G.length-1&&W>=G[U].max)$[U]+=Y}}return G.map((_,W)=>({zone:_,seconds:Math.round($[W]),percentage:A>0?Math.round($[W]/A*100):0}))}calculateTimeInPaceZones(I,w){let G=Array(w.length).fill(0),$=0;for(let A=1;A<I.length;A++){let _=I[A].speed;if(_==null||_===0)continue;let W=1000/_,Y=(I[A].timestamp.getTime()-I[A-1].timestamp.getTime())/1000;$+=Y;for(let U=0;U<w.length;U++)if(W<=w[U].max&&W>w[U].min){G[U]+=Y;break}}return w.map((A,_)=>({zone:A,seconds:Math.round(G[_]),percentage:$>0?Math.round(G[_]/$*100):0}))}calculateSummary(I){if(!I||I.length<5)return{timeInZ1:0,timeInZ2:0,timeInZ3:0,timeInZ4:0,timeInZ5:0,intensityDistribution:"unknown"};let w=I[0]?.percentage||0,G=I[1]?.percentage||0,$=I[2]?.percentage||0,A=I[3]?.percentage||0,_=I[4]?.percentage||0,W=w+G,Y=A+_,U=Y>0?W/Y:0,H;if(W>70&&Y>15&&$<15)H="polarized";else if(w>=G&&G>=$&&$>=A&&A>=_)H="pyramidal";else if($+A>50)H="threshold";else H="unknown";return{timeInZ1:I[0]?.seconds||0,timeInZ2:I[1]?.seconds||0,timeInZ3:I[2]?.seconds||0,timeInZ4:I[3]?.seconds||0,timeInZ5:I[4]?.seconds||0,polarizedIndex:Math.round(U*100)/100,intensityDistribution:H}}getZoneForValue(I,w){let G=w==="heartRate"?this.getHeartRateZones():w==="power"?this.getPowerZones():this.getPaceZones();for(let $ of G)if(I>=$.min&&I<$.max)return $;return G[G.length-1]||null}formatTime(I){let w=Math.floor(I/3600),G=Math.floor(I%3600/60),$=Math.round(I%60);if(w>0)return`${w}:${G.toString().padStart(2,"0")}:${$.toString().padStart(2,"0")}`;return`${G}:${$.toString().padStart(2,"0")}`}}function w8(I){return new X0(I)}function G8(I){return Math.round(208-0.7*I)}function $8(I){return Math.round(I*0.85)}function PY(I,w){return I-w}function A8(I,w,G){let $=PY(I,w);return Math.round(w+$*G)}var rG={"1K":1000,"1 Mile":1609.34,"5K":5000,"10K":1e4,"15K":15000,"Half Marathon":21097.5,Marathon:42195,"50K":50000,"100K":1e5};class J0{predictFromPerformance(I,w,G=Object.values(rG)){let $=[],A=this.calculateRiegelExponent(I,w);for(let _ of G){let W=w*Math.pow(_/I,A),Y=W/(_/1000),U=_/I,H;if(U>=0.5&&U<=2)H="high";else if(U>=0.25&&U<=4)H="medium";else H="low";$.push({distance:_,distanceName:this.getDistanceName(_),predictedTime:Math.round(W),predictedPace:Math.round(Y),confidence:H})}return $.sort((_,W)=>_.distance-W.distance)}predictFromActivities(I,w=Object.values(rG)){let G=I.filter((Y)=>Y.sport==="running"&&Y.totalDistance>=1000);if(G.length===0)return[];let A=[...G].sort((Y,U)=>U.startTime.getTime()-Y.startTime.getTime()).slice(0,10),_=new Map;for(let Y of A){let U=(Date.now()-Y.startTime.getTime())/86400000,H=Math.exp(-U/30),Z=Math.min(1,Y.totalDistance/1e4),q=H*Z,Q=this.predictFromPerformance(Y.totalDistance,Y.totalTimerTime,w);for(let b of Q){let X=_.get(b.distance)||{totalTime:0,totalWeight:0};X.totalTime+=b.predictedTime*q,X.totalWeight+=q,_.set(b.distance,X)}}let W=[];for(let[Y,U]of _){let H=U.totalTime/U.totalWeight,Z=H/(Y/1000),q;if(U.totalWeight>3)q="high";else if(U.totalWeight>1)q="medium";else q="low";W.push({distance:Y,distanceName:this.getDistanceName(Y),predictedTime:Math.round(H),predictedPace:Math.round(Z),confidence:q})}return W.sort((Y,U)=>Y.distance-U.distance)}estimateVO2max(I,w){let G=I/(w/60),$=0.8+0.1894393*Math.exp(-0.012778*(w/60))+0.2989558*Math.exp(-0.1932605*(w/60));return(-4.6+0.182258*G+0.000104*G*G)/$}estimateVDOT(I,w){return this.estimateVO2max(I,w)}estimateFitness(I,w){let G=I.filter((U)=>U.sport==="running"&&U.totalDistance>=3000);if(G.length===0)return{vo2max:0,vdot:0,equivalentMarathon:0,fitnessAge:w||0};let $=0,A=null;for(let U of G){let H=this.estimateVO2max(U.totalDistance,U.totalTimerTime);if(H>$)$=H,A=U}let _=A?this.estimateVDOT(A.totalDistance,A.totalTimerTime):0,W=A?this.predictFromPerformance(A.totalDistance,A.totalTimerTime,[42195])[0]:null,Y=w?this.estimateFitnessAge($,w):0;return{vo2max:Math.round($*10)/10,vdot:Math.round(_*10)/10,equivalentMarathon:W?.predictedTime||0,fitnessAge:Y}}getTrainingPaces(I){let w=this.vdotToPace(I),G=w/0.59,$=w/0.74;return{easy:{min:Math.round(G),max:Math.round($)},marathon:Math.round(w/0.79),threshold:Math.round(w/0.88),interval:Math.round(w/0.98),repetition:Math.round(w/1.05)}}vdotToPace(I){return 29.54+5.000663*Math.exp(-0.007546*I)*60}calculateRiegelExponent(I,w){let G=w/(I/1000);if(G<210)return 1.04;if(G<270)return 1.05;if(G<330)return 1.06;if(G<390)return 1.07;return 1.08}estimateFitnessAge(I,w){let _=30-(I-45)/0.45;return Math.max(15,Math.min(90,Math.round(_)))}getDistanceName(I){for(let[w,G]of Object.entries(rG))if(Math.abs(G-I)<10)return w;return`${(I/1000).toFixed(1)}K`}formatTime(I){let w=Math.floor(I/3600),G=Math.floor(I%3600/60),$=Math.round(I%60);if(w>0)return`${w}:${G.toString().padStart(2,"0")}:${$.toString().padStart(2,"0")}`;return`${G}:${$.toString().padStart(2,"0")}`}formatPace(I){let w=Math.floor(I/60),G=Math.round(I%60);return`${w}:${G.toString().padStart(2,"0")}/km`}}function W8(){return new J0}var fI={groundContactTime:{elite:{min:180,max:220},recreational:{min:220,max:280}},groundContactBalance:{min:48,max:52},strideLength:{elite:{min:1.4,max:1.8},recreational:{min:1,max:1.4}},verticalOscillation:{elite:{min:6,max:9},recreational:{min:8,max:12}},verticalRatio:{elite:{min:6,max:8},recreational:{min:8,max:12}},cadence:{elite:{min:180,max:200},recreational:{min:160,max:180}}};class B0{calculateMetrics(I){let w={},G=I.filter((U)=>U.groundContactTime!=null).map((U)=>U.groundContactTime);if(G.length>0)w.groundContactTime={avg:Math.round(this.average(G)),min:Math.min(...G),max:Math.max(...G)};let $=I.filter((U)=>U.groundContactBalance!=null).map((U)=>U.groundContactBalance);if($.length>0){let U=this.average($);w.groundContactBalance={avg:Math.round(U*10)/10,left:Math.round(U*10)/10,right:Math.round((100-U)*10)/10}}let A=I.filter((U)=>U.strideLength!=null).map((U)=>U.strideLength);if(A.length>0)w.strideLength={avg:Math.round(this.average(A)*100)/100,min:Math.round(Math.min(...A)*100)/100,max:Math.round(Math.max(...A)*100)/100};let _=I.filter((U)=>U.verticalOscillation!=null).map((U)=>U.verticalOscillation);if(_.length>0)w.verticalOscillation={avg:Math.round(this.average(_)*10)/10,min:Math.round(Math.min(..._)*10)/10,max:Math.round(Math.max(..._)*10)/10};let W=I.filter((U)=>U.verticalRatio!=null).map((U)=>U.verticalRatio);if(W.length>0)w.verticalRatio={avg:Math.round(this.average(W)*10)/10,min:Math.round(Math.min(...W)*10)/10,max:Math.round(Math.max(...W)*10)/10};let Y=I.filter((U)=>U.cadence!=null).map((U)=>U.cadence);if(Y.length>0)w.cadence={avg:Math.round(this.average(Y)),min:Math.min(...Y),max:Math.max(...Y)};if(w.cadence&&w.strideLength&&w.verticalOscillation)w.runningPowerEstimate=this.estimateRunningPower(w.cadence.avg,w.strideLength.avg,w.verticalOscillation.avg,70);return w}analyzeForm(I,w="recreational"){let G=I.records,$=this.calculateMetrics(G),A=[],_=[],W=0,Y=0;if($.groundContactTime){let H=fI.groundContactTime[w],Z=this.scoreMetric($.groundContactTime.avg,H.min,H.max);W+=Z,Y++;let q=this.createInsight("Ground Contact Time",$.groundContactTime.avg,H,"ms",Z);if(A.push(q),q.status!=="good")if($.groundContactTime.avg>H.max)_.push("Work on increasing cadence and strengthening glutes to reduce ground contact time");else _.push("Your ground contact time is excellent - maintain current form")}if($.verticalOscillation){let H=fI.verticalOscillation[w],Z=this.scoreMetric($.verticalOscillation.avg,H.min,H.max);W+=Z,Y++;let q=this.createInsight("Vertical Oscillation",$.verticalOscillation.avg,H,"cm",Z);if(A.push(q),$.verticalOscillation.avg>H.max)_.push('Focus on running "light" - imagine a ceiling just above your head'),_.push("Strengthen hip flexors and glutes for better horizontal propulsion")}if($.cadence){let H=fI.cadence[w],Z=this.scoreMetric($.cadence.avg,H.min,H.max,!0);W+=Z,Y++;let q=this.createInsight("Cadence",$.cadence.avg,H,"spm",Z);if(A.push(q),$.cadence.avg<H.min)_.push("Try to increase cadence by 5% - use a metronome app during training"),_.push("Higher cadence typically reduces injury risk and improves efficiency")}if($.groundContactBalance){let H=fI.groundContactBalance,Z=Math.abs(50-$.groundContactBalance.avg),q=Math.max(0,100-Z*10);W+=q,Y++;let Q=Z<2?"good":Z<4?"warning":"needs_attention";if(A.push({metric:"Ground Contact Balance",status:Q,message:Q==="good"?"Your left/right balance is excellent":`${Z.toFixed(1)}% imbalance detected - consider strength work`,value:$.groundContactBalance.avg,optimalRange:H}),Z>=4)_.push("Significant left/right imbalance detected - consider a gait analysis"),_.push("Single-leg exercises may help correct the imbalance")}if($.verticalRatio){let H=fI.verticalRatio[w],Z=this.scoreMetric($.verticalRatio.avg,H.min,H.max);W+=Z,Y++;let q=this.createInsight("Vertical Ratio",$.verticalRatio.avg,H,"%",Z);if(A.push(q),$.verticalRatio.avg>H.max)_.push("Vertical ratio is high - focus on forward lean from ankles")}if($.strideLength){let H=fI.strideLength[w],Z=this.scoreMetric($.strideLength.avg,H.min,H.max,!0);W+=Z,Y++;let q=this.createInsight("Stride Length",$.strideLength.avg,H,"m",Z);A.push(q)}let U=Y>0?Math.round(W/Y):0;return{metrics:$,formScore:U,insights:A,recommendations:[...new Set(_)]}}estimateRunningPower(I,w,G,$){let A=I*w/60,_=0.5*$*Math.pow(A,2)*0.01,W=G/100*I/60,Y=$*9.81*W;return Math.round(_+Y)}scoreMetric(I,w,G,$=!1){if(I>=w&&I<=G)return 100;if($){if(I<w){let _=w-I;return Math.max(0,100-_*5)}return 100}if(I<w){let _=w-I;return Math.max(0,100-_*5)}let A=I-G;return Math.max(0,100-A*5)}createInsight(I,w,G,$,A){let _,W;if(A>=90)_="good",W=`${I} is in optimal range`;else if(A>=70)_="warning",W=`${I} is slightly outside optimal range`;else _="needs_attention",W=`${I} needs improvement`;return{metric:I,status:_,message:W,value:w,optimalRange:G}}average(I){return I.reduce((w,G)=>w+G,0)/I.length}calculateEfficiency(I){let w=I.records,G=this.calculateMetrics(w);if(!G.runningPowerEstimate||!I.avgSpeed)return null;return Math.round(I.avgSpeed/G.runningPowerEstimate*1000)/1000}}function U8(){return new B0}class oG{workout;currentSteps=[];constructor(I,w){this.workout={name:I,sport:w,steps:[],createdAt:new Date}}setDescription(I){return this.workout.description=I,this}warmup(I,w){return this.currentSteps.push({type:"warmup",duration:I,target:w||{type:"open"}}),this}cooldown(I,w){return this.currentSteps.push({type:"cooldown",duration:I,target:w||{type:"open"}}),this}interval(I,w,G){return this.currentSteps.push({type:"interval",name:G,duration:I,target:w}),this}recovery(I,w){return this.currentSteps.push({type:"recovery",duration:I,target:w||{type:"open"}}),this}rest(I){return this.currentSteps.push({type:"rest",duration:I,target:{type:"open"}}),this}active(I,w,G){return this.currentSteps.push({type:"active",name:G,duration:I,target:w}),this}repeat(I,w){let G=new oG(this.workout.name,this.workout.sport);return w(G),this.currentSteps.push({type:"repeat",repeatCount:I,steps:G.currentSteps}),this}build(){return this.workout.steps=this.currentSteps,this.workout.estimatedDuration=this.calculateEstimatedDuration(),this.workout.estimatedDistance=this.calculateEstimatedDistance(),this.workout.updatedAt=new Date,this.workout}calculateEstimatedDuration(){let I=0,w=(G,$=1)=>{for(let A of G)if(A.type==="repeat")w(A.steps,$*A.repeatCount);else{let _=A;if(_.duration.type==="time"&&_.duration.value)I+=_.duration.value*$}};return w(this.currentSteps),I}calculateEstimatedDistance(){let I=0,w=(G,$=1)=>{for(let A of G)if(A.type==="repeat")w(A.steps,$*A.repeatCount);else{let _=A;if(_.duration.type==="distance"&&_.duration.value)I+=_.duration.value*$}};return w(this.currentSteps),I}}var R={time:(I)=>({type:"time",value:I}),minutes:(I)=>({type:"time",value:I*60}),distance:(I)=>({type:"distance",value:I}),km:(I)=>({type:"distance",value:I*1000}),miles:(I)=>({type:"distance",value:I*1609.34}),calories:(I)=>({type:"calories",value:I}),open:()=>({type:"open"}),lapButton:()=>({type:"lap_button"}),untilHrBelow:(I)=>({type:"heart_rate_less_than",value:I}),untilHrAbove:(I)=>({type:"heart_rate_greater_than",value:I})},K={open:()=>({type:"open"}),hrZone:(I)=>({type:"heart_rate_zone",zone:I}),hrRange:(I,w)=>({type:"heart_rate",low:I,high:w}),hr:(I)=>({type:"heart_rate",value:I}),powerZone:(I)=>({type:"power_zone",zone:I}),powerRange:(I,w)=>({type:"power",low:I,high:w}),power:(I)=>({type:"power",value:I}),paceZone:(I)=>({type:"pace_zone",zone:I}),paceRange:(I,w)=>({type:"pace",low:w,high:I}),pace:(I)=>({type:"pace",value:I}),cadence:(I)=>({type:"cadence",value:I}),cadenceRange:(I,w)=>({type:"cadence",low:I,high:w})};function r(I,w){return new oG(I,w)}var sI={fiveByOneK:()=>r("5x1K Intervals","running").setDescription("Classic interval workout: 5x1km with recovery jogs").warmup(R.minutes(10),K.hrZone(2)).repeat(5,(I)=>{I.interval(R.km(1),K.hrZone(4),"1K Fast").recovery(R.minutes(2),K.hrZone(2))}).cooldown(R.minutes(10),K.hrZone(1)).build(),thirtyThirty:(I=10)=>r("30/30 Intervals","running").setDescription(`${I}x 30 seconds hard / 30 seconds easy`).warmup(R.minutes(10),K.hrZone(2)).repeat(I,(w)=>{w.interval(R.time(30),K.hrZone(5),"30s Hard").recovery(R.time(30),K.hrZone(2))}).cooldown(R.minutes(10),K.hrZone(1)).build(),tempoRun:(I=20)=>r("Tempo Run","running").setDescription(`${I} minutes at tempo pace`).warmup(R.minutes(10),K.hrZone(2)).interval(R.minutes(I),K.hrZone(3),"Tempo").cooldown(R.minutes(10),K.hrZone(1)).build(),sweetSpot:(I=3,w=10)=>r("Sweet Spot","cycling").setDescription(`${I}x${w}min at 88-93% FTP`).warmup(R.minutes(10),K.powerZone(2)).repeat(I,(G)=>{G.interval(R.minutes(w),K.powerRange(88,93),"Sweet Spot").recovery(R.minutes(5),K.powerZone(1))}).cooldown(R.minutes(10),K.powerZone(1)).build(),vo2maxIntervals:()=>r("VO2max Intervals","cycling").setDescription("5x3min at 105-120% FTP").warmup(R.minutes(15),K.powerZone(2)).repeat(5,(I)=>{I.interval(R.minutes(3),K.powerRange(105,120),"VO2max").recovery(R.minutes(3),K.powerZone(1))}).cooldown(R.minutes(10),K.powerZone(1)).build()};function J8(I){switch(I.type){case"time":if(!I.value)return"Open";let w=Math.floor(I.value/60),G=I.value%60;if(w===0)return`${G}s`;if(G===0)return`${w}min`;return`${w}:${G.toString().padStart(2,"0")}`;case"distance":if(!I.value)return"Open";if(I.value>=1000)return`${(I.value/1000).toFixed(1)}km`;return`${I.value}m`;case"calories":return`${I.value} cal`;case"open":return"Open";case"lap_button":return"Lap Button";case"heart_rate_less_than":return`Until HR < ${I.value}`;case"heart_rate_greater_than":return`Until HR > ${I.value}`;default:return"Unknown"}}function B8(I){switch(I.type){case"open":return"No target";case"heart_rate_zone":return`HR Zone ${I.zone}`;case"heart_rate":if(I.low&&I.high)return`${I.low}-${I.high} bpm`;return`${I.value} bpm`;case"power_zone":return`Power Zone ${I.zone}`;case"power":if(I.low&&I.high)return`${I.low}-${I.high}W`;return`${I.value}W`;case"pace_zone":return`Pace Zone ${I.zone}`;case"pace":let w=(G)=>{let $=Math.floor(G/60),A=Math.round(G%60);return`${$}:${A.toString().padStart(2,"0")}`};if(I.low&&I.high)return`${w(I.low)}-${w(I.high)}/km`;return`${w(I.value)}/km`;case"cadence":if(I.low&&I.high)return`${I.low}-${I.high} spm`;return`${I.value} spm`;default:return"Unknown"}}class D0{course;trackPoints=[];coursePoints=[];totalAscent=0;totalDescent=0;lastAltitude=null;constructor(I,w="running"){this.course={name:I,sport:w,trackPoints:[],coursePoints:[],totalDistance:0,totalAscent:0,totalDescent:0,createdAt:new Date}}setDescription(I){return this.course.description=I,this}setSport(I){return this.course.sport=I,this}addPoint(I,w,G){let $={lat:I,lng:w,altitude:G};if(this.trackPoints.push($),G!==void 0&&this.lastAltitude!==null){let A=G-this.lastAltitude;if(A>0)this.totalAscent+=A;else this.totalDescent+=Math.abs(A)}if(G!==void 0)this.lastAltitude=G;return this}addPoints(I){for(let w of I)this.addPoint(w.lat,w.lng,w.altitude);return this}addCoursePoint(I,w,G,$,A){let _=this.calculateDistanceToPoint(I,w);return this.coursePoints.push({position:{lat:I,lng:w},distance:_,type:G,name:$,notes:A}),this}addWaterStation(I,w,G){return this.addCoursePoint(I,w,"water",G||"Water Station")}addFoodStation(I,w,G){return this.addCoursePoint(I,w,"food",G||"Food Station")}addTurn(I,w,G,$){return this.addCoursePoint(I,w,G,void 0,$)}addClimbCategory(I,w,G,$){let A={1:"first_category",2:"second_category",3:"third_category",4:"fourth_category",hors:"hors_category"};return this.addCoursePoint(I,w,A[G],$)}addSprint(I,w,G){return this.addCoursePoint(I,w,"sprint",G||"Sprint")}addSummit(I,w,G){return this.addCoursePoint(I,w,"summit",G||"Summit")}fromActivity(I){for(let w of I.records)if(w.position)this.addPoint(w.position.lat,w.position.lng,w.position.altitude);return this}fromGeoJson(I){if(I.type!=="LineString")throw Error("Expected GeoJSON LineString");for(let w of I.coordinates){let[G,$,A]=w;this.addPoint($,G,A)}return this}reverse(){this.trackPoints.reverse();for(let w of this.coursePoints)w.distance=this.course.totalDistance-w.distance;this.coursePoints.sort((w,G)=>w.distance-G.distance);let I=this.totalAscent;return this.totalAscent=this.totalDescent,this.totalDescent=I,this}build(){return this.course.trackPoints=this.trackPoints,this.course.coursePoints=this.coursePoints.sort((I,w)=>I.distance-w.distance),this.course.totalDistance=this.calculateTotalDistance(),this.course.totalAscent=Math.round(this.totalAscent),this.course.totalDescent=Math.round(this.totalDescent),this.course.updatedAt=new Date,this.course}calculateTotalDistance(){let I=0;for(let w=1;w<this.trackPoints.length;w++)I+=this.haversineDistance(this.trackPoints[w-1],this.trackPoints[w]);return Math.round(I)}calculateDistanceToPoint(I,w){if(this.trackPoints.length===0)return 0;let G=1/0,$=0,A=0;for(let _=0;_<this.trackPoints.length;_++){let W=this.trackPoints[_],Y=this.haversineDistance({lat:I,lng:w},W);if(Y<G)G=Y,A=$;if(_>0)$+=this.haversineDistance(this.trackPoints[_-1],W)}return Math.round(A)}haversineDistance(I,w){let $=I.lat*Math.PI/180,A=w.lat*Math.PI/180,_=(w.lat-I.lat)*Math.PI/180,W=(w.lng-I.lng)*Math.PI/180,Y=Math.sin(_/2)*Math.sin(_/2)+Math.cos($)*Math.cos(A)*Math.sin(W/2)*Math.sin(W/2);return 6371000*(2*Math.atan2(Math.sqrt(Y),Math.sqrt(1-Y)))}}function R8(I,w="running"){return new D0(I,w)}function K8(I){let w=I.trackPoints.map(($)=>{let A=$.altitude!==void 0?`
|
|
252
|
+
<ele>${$.altitude.toFixed(1)}</ele>`:"";return` <trkpt lat="${$.lat.toFixed(7)}" lon="${$.lng.toFixed(7)}">${A}
|
|
253
|
+
</trkpt>`}).join(`
|
|
254
|
+
`),G=I.coursePoints.map(($)=>{let A=$.name?`
|
|
255
|
+
<name>${RI($.name)}</name>`:"",_=$.notes?`
|
|
256
|
+
<desc>${RI($.notes)}</desc>`:"",W=`
|
|
257
|
+
<sym>${$.type||"Flag"}</sym>`;return` <wpt lat="${$.position.lat.toFixed(7)}" lon="${$.position.lng.toFixed(7)}">${A}${_}${W}
|
|
258
|
+
</wpt>`}).join(`
|
|
259
|
+
`);return`<?xml version="1.0" encoding="UTF-8"?>
|
|
260
|
+
<gpx version="1.1" creator="ts-watches"
|
|
261
|
+
xmlns="http://www.topografix.com/GPX/1/1">
|
|
262
|
+
<metadata>
|
|
263
|
+
<name>${RI(I.name)}</name>${I.description?`
|
|
264
|
+
<desc>${RI(I.description)}</desc>`:""}
|
|
265
|
+
</metadata>
|
|
266
|
+
${G}
|
|
267
|
+
<trk>
|
|
268
|
+
<name>${RI(I.name)}</name>
|
|
269
|
+
<trkseg>
|
|
270
|
+
${w}
|
|
271
|
+
</trkseg>
|
|
272
|
+
</trk>
|
|
273
|
+
</gpx>`}function T8(I){let w=I.trackPoints.map(($,A)=>{let _=A>0?I.trackPoints.slice(0,A).reduce((Y,U,H,Z)=>H>0?Y+yY(Z[H-1],Z[H]):Y,0):0,W=$.altitude!==void 0?`
|
|
274
|
+
<AltitudeMeters>${$.altitude.toFixed(1)}</AltitudeMeters>`:"";return` <Trackpoint>
|
|
275
|
+
<Position>
|
|
276
|
+
<LatitudeDegrees>${$.lat.toFixed(7)}</LatitudeDegrees>
|
|
277
|
+
<LongitudeDegrees>${$.lng.toFixed(7)}</LongitudeDegrees>
|
|
278
|
+
</Position>${W}
|
|
279
|
+
<DistanceMeters>${_.toFixed(1)}</DistanceMeters>
|
|
280
|
+
</Trackpoint>`}).join(`
|
|
281
|
+
`),G=I.coursePoints.map(($)=>{let A=$.name||$.type||"Point";return` <CoursePoint>
|
|
282
|
+
<Name>${RI(A)}</Name>
|
|
283
|
+
<Position>
|
|
284
|
+
<LatitudeDegrees>${$.position.lat.toFixed(7)}</LatitudeDegrees>
|
|
285
|
+
<LongitudeDegrees>${$.position.lng.toFixed(7)}</LongitudeDegrees>
|
|
286
|
+
</Position>
|
|
287
|
+
<PointType>${uY($.type)}</PointType>
|
|
288
|
+
</CoursePoint>`}).join(`
|
|
289
|
+
`);return`<?xml version="1.0" encoding="UTF-8"?>
|
|
290
|
+
<TrainingCenterDatabase
|
|
291
|
+
xmlns="http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2">
|
|
292
|
+
<Courses>
|
|
293
|
+
<Course>
|
|
294
|
+
<Name>${RI(I.name)}</Name>
|
|
295
|
+
<Lap>
|
|
296
|
+
<TotalTimeSeconds>0</TotalTimeSeconds>
|
|
297
|
+
<DistanceMeters>${I.totalDistance.toFixed(1)}</DistanceMeters>
|
|
298
|
+
<BeginPosition>
|
|
299
|
+
<LatitudeDegrees>${I.trackPoints[0]?.lat.toFixed(7)||0}</LatitudeDegrees>
|
|
300
|
+
<LongitudeDegrees>${I.trackPoints[0]?.lng.toFixed(7)||0}</LongitudeDegrees>
|
|
301
|
+
</BeginPosition>
|
|
302
|
+
<EndPosition>
|
|
303
|
+
<LatitudeDegrees>${I.trackPoints[I.trackPoints.length-1]?.lat.toFixed(7)||0}</LatitudeDegrees>
|
|
304
|
+
<LongitudeDegrees>${I.trackPoints[I.trackPoints.length-1]?.lng.toFixed(7)||0}</LongitudeDegrees>
|
|
305
|
+
</EndPosition>
|
|
306
|
+
<Intensity>Active</Intensity>
|
|
307
|
+
</Lap>
|
|
308
|
+
<Track>
|
|
309
|
+
${w}
|
|
310
|
+
</Track>
|
|
311
|
+
${G}
|
|
312
|
+
</Course>
|
|
313
|
+
</Courses>
|
|
314
|
+
</TrainingCenterDatabase>`}function yY(I,w){let $=I.lat*Math.PI/180,A=w.lat*Math.PI/180,_=(w.lat-I.lat)*Math.PI/180,W=(w.lng-I.lng)*Math.PI/180,Y=Math.sin(_/2)*Math.sin(_/2)+Math.cos($)*Math.cos(A)*Math.sin(W/2)*Math.sin(W/2);return 6371000*(2*Math.atan2(Math.sqrt(Y),Math.sqrt(1-Y)))}function uY(I){return{generic:"Generic",summit:"Summit",valley:"Valley",water:"Water",food:"Food",danger:"Danger",left:"Left",right:"Right",straight:"Straight",first_aid:"First Aid",fourth_category:"4th Category",third_category:"3rd Category",second_category:"2nd Category",first_category:"1st Category",hors_category:"Hors Category",sprint:"Sprint"}[I||"generic"]||"Generic"}function RI(I){return I.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}class R0{plan;weeks=[];constructor(I){let w=Math.ceil((I.goalRaceDate.getTime()-Date.now())/604800000);this.plan={name:I.name,sport:I.sport,goalRace:{name:I.name,date:I.goalRaceDate,distance:I.goalRaceDistance},weeks:[],startDate:new Date,endDate:I.goalRaceDate,createdAt:new Date}}addWeek(I){return this.weeks.push(I),this}setDescription(I){return this.plan.description=I,this}build(){return this.plan.weeks=this.weeks,this.plan.updatedAt=new Date,this.plan}}function S8(I){let{raceDate:w,name:G="Marathon Training",currentWeeklyMileage:$,fitness:A}=I,_=Math.ceil((w.getTime()-Date.now())/604800000),W=Math.min(Math.max(_,12),20),Y=[],U=A==="beginner"?50:A==="intermediate"?70:90;for(let H=1;H<=W;H++){let Z=W-H,q,Q;if(Z<=2)q="taper",Q=U*(Z===2?0.6:0.4);else if(Z<=5)q="peak",Q=U;else if(Z<=10){q="build";let L=(10-Z)/5;Q=$+(U-$)*L}else{q="base";let L=(W-10-Z)/(W-10);Q=$*(1+L*0.2)}if(H%4===0&&q!=="taper")q="recovery",Q*=0.7;let b=[];if(q!=="recovery")b.push({dayOfWeek:1,workout:r("Easy Run","running").warmup(R.minutes(5),K.hrZone(1)).active(R.km(8),K.hrZone(2),"Easy").cooldown(R.minutes(5),K.hrZone(1)).build()});if(q!=="taper"&&q!=="recovery")b.push({dayOfWeek:2,workout:H%2===0?sI.thirtyThirty(10):sI.fiveByOneK()});if(b.push({dayOfWeek:3,workout:r("Easy Run","running").active(R.km(q==="taper"?5:8),K.hrZone(2)).build()}),q==="build"||q==="peak")b.push({dayOfWeek:4,workout:sI.tempoRun(q==="peak"?30:20)});if(q!=="taper")b.push({dayOfWeek:6,workout:r("Moderate Run","running").active(R.km(10),K.hrZone(2),"Moderate").build()});let X=q==="taper"?Z===2?16:10:Math.min(32,Q*0.35);b.push({dayOfWeek:0,workout:r("Long Run","running").warmup(R.km(2),K.hrZone(2)).active(R.km(X-4),K.hrZone(2),"Long Run").cooldown(R.km(2),K.hrZone(1)).build(),notes:q==="peak"?"Include marathon pace miles in middle":void 0}),Y.push({weekNumber:H,phase:q,description:K0(q,H,W),workouts:b,targetDistance:Q*1000})}return{name:G,description:`${W}-week marathon training plan`,sport:"running",goalRace:{name:"Marathon",date:w,distance:42195},weeks:Y,startDate:new Date,endDate:w,createdAt:new Date}}function E8(I){let{raceDate:w,name:G="5K Training",fitness:$}=I,A=8,_=[];for(let W=1;W<=8;W++){let Y=8-W,U;if(Y===0)U="taper";else if(Y<=2)U="peak";else U="build";let H=[];if(U!=="taper")H.push({dayOfWeek:2,workout:r("Intervals","running").warmup(R.minutes(10),K.hrZone(2)).repeat($==="beginner"?4:6,(q)=>{q.interval(R.time(90),K.hrZone(4),"90s Hard").recovery(R.time(90),K.hrZone(2))}).cooldown(R.minutes(10),K.hrZone(1)).build()});H.push({dayOfWeek:4,workout:U==="taper"?r("Easy Shakeout","running").active(R.km(3),K.hrZone(2)).build():sI.tempoRun(15)});let Z=U==="taper"?5:$==="beginner"?8:10;H.push({dayOfWeek:0,workout:r("Long Run","running").active(R.km(Z),K.hrZone(2)).build()}),_.push({weekNumber:W,phase:U,description:K0(U,W,8),workouts:H})}return{name:G,description:"8-week 5K training plan",sport:"running",goalRace:{name:"5K",date:w,distance:5000},weeks:_,startDate:new Date,endDate:w,createdAt:new Date}}function K0(I,w,G){switch(I){case"base":return`Base building - Week ${w} of ${G}`;case"build":return`Building fitness - Week ${w} of ${G}`;case"peak":return"Peak training - maximize fitness";case"taper":return"Taper week - reduce volume, maintain intensity";case"recovery":return"Recovery week - reduced volume";default:return`Week ${w}`}}function O8(I){let w=[],G=new Date(I.startDate);for(let $ of I.weeks){for(let A of $.workouts){while(G.getDay()!==A.dayOfWeek)G.setDate(G.getDate()+1);let _=G.toISOString().replace(/[-:]/g,"").split(".")[0]+"Z",Y=new Date(G.getTime()+(A.workout.estimatedDuration||3600)*1000).toISOString().replace(/[-:]/g,"").split(".")[0]+"Z";w.push(`BEGIN:VEVENT
|
|
315
|
+
DTSTART:${_}
|
|
316
|
+
DTEND:${Y}
|
|
317
|
+
SUMMARY:${A.workout.name}
|
|
318
|
+
DESCRIPTION:${A.workout.description||""}${A.notes?`\\n${A.notes}`:""}
|
|
319
|
+
END:VEVENT`)}G.setDate(G.getDate()+7-G.getDay())}return`BEGIN:VCALENDAR
|
|
320
|
+
VERSION:2.0
|
|
321
|
+
PRODID:-//ts-watches//Training Plan//EN
|
|
322
|
+
${w.join(`
|
|
323
|
+
`)}
|
|
324
|
+
END:VCALENDAR`}function z8(I){return new R0(I)}var k8={HEART_RATE:{deviceType:120,frequency:57,period:8070,searchTimeout:30},SPEED_CADENCE:{deviceType:121,frequency:57,period:8086,searchTimeout:30},BIKE_SPEED:{deviceType:123,frequency:57,period:8118,searchTimeout:30},BIKE_CADENCE:{deviceType:122,frequency:57,period:8102,searchTimeout:30},POWER:{deviceType:11,frequency:57,period:8182,searchTimeout:30},RUNNING_DYNAMICS:{deviceType:26,frequency:57,period:8134,searchTimeout:30},FITNESS_EQUIPMENT:{deviceType:17,frequency:57,period:8192,searchTimeout:30},ENVIRONMENT:{deviceType:25,frequency:57,period:8070,searchTimeout:30}};class T0{devices=[];handlers=new Map;isRunning=!1;intervals=[];async startScanning(I){if(this.isRunning)return;this.isRunning=!0,setTimeout(()=>{let w={deviceId:12345,deviceType:"heart_rate",transmissionType:1,name:"Mock HR Sensor",batteryStatus:"good"};this.devices.push(w),this.emit("device_found",w);let G=setInterval(()=>{if(!this.isRunning)return;let $={heartRate:70+Math.floor(Math.random()*30),beatCount:Math.floor(Math.random()*255),beatTime:Date.now()};this.emit("data",w,{type:"heart_rate",data:$})},1000);this.intervals.push(G)},500),setTimeout(()=>{let w={deviceId:67890,deviceType:"power_meter",transmissionType:5,name:"Mock Power Meter",batteryStatus:"ok"};this.devices.push(w),this.emit("device_found",w);let G=setInterval(()=>{if(!this.isRunning)return;let $={instantPower:150+Math.floor(Math.random()*100),cadence:80+Math.floor(Math.random()*20),pedalPowerBalance:48+Math.random()*4};this.emit("data",w,{type:"power_meter",data:$})},1000);this.intervals.push(G)},1000)}async stopScanning(){this.isRunning=!1}getDevices(){return[...this.devices]}async connect(I){}async disconnect(I){}on(I,w){if(!this.handlers.has(I))this.handlers.set(I,new Set);this.handlers.get(I).add(w)}off(I,w){this.handlers.get(I)?.delete(w)}emit(I,...w){this.handlers.get(I)?.forEach((G)=>G(...w))}isAvailable(){return!0}async close(){this.isRunning=!1,this.intervals.forEach((I)=>clearInterval(I)),this.intervals=[],this.devices=[],this.handlers.clear()}}function P8(){return new T0}function y8(I,w,G,$,A){let _=(I-G+65536)%65536,W=(w-$+65536)%65536;if(W===0)return 0;let Y=W/1024;return _*A/Y}function u8(I,w,G,$){let A=(I-G+65536)%65536,_=(w-$+65536)%65536;if(_===0)return 0;let W=_/1024/60;return A/W}var h8={HEART_RATE:"0000180d-0000-1000-8000-00805f9b34fb",CYCLING_SPEED_CADENCE:"00001816-0000-1000-8000-00805f9b34fb",CYCLING_POWER:"00001818-0000-1000-8000-00805f9b34fb",RUNNING_SPEED_CADENCE:"00001814-0000-1000-8000-00805f9b34fb",FITNESS_MACHINE:"00001826-0000-1000-8000-00805f9b34fb",DEVICE_INFORMATION:"0000180a-0000-1000-8000-00805f9b34fb",BATTERY:"0000180f-0000-1000-8000-00805f9b34fb"},n8={HEART_RATE_MEASUREMENT:"00002a37-0000-1000-8000-00805f9b34fb",BODY_SENSOR_LOCATION:"00002a38-0000-1000-8000-00805f9b34fb",CSC_MEASUREMENT:"00002a5b-0000-1000-8000-00805f9b34fb",CSC_FEATURE:"00002a5c-0000-1000-8000-00805f9b34fb",CYCLING_POWER_MEASUREMENT:"00002a63-0000-1000-8000-00805f9b34fb",CYCLING_POWER_FEATURE:"00002a65-0000-1000-8000-00805f9b34fb",RSC_MEASUREMENT:"00002a53-0000-1000-8000-00805f9b34fb",RSC_FEATURE:"00002a54-0000-1000-8000-00805f9b34fb",FITNESS_MACHINE_FEATURE:"00002acc-0000-1000-8000-00805f9b34fb",TREADMILL_DATA:"00002acd-0000-1000-8000-00805f9b34fb",INDOOR_BIKE_DATA:"00002ad2-0000-1000-8000-00805f9b34fb",BATTERY_LEVEL:"00002a19-0000-1000-8000-00805f9b34fb"};function f8(I){let w=I.getUint8(0),G=(w&1)!==0,$=(w&2)!==0,A=(w&4)!==0,_=(w&8)!==0,W=(w&16)!==0,Y=1,U=G?I.getUint16(Y,!0):I.getUint8(Y);Y+=G?2:1;let H;if(_)H=I.getUint16(Y,!0),Y+=2;let Z=[];if(W)while(Y<I.byteLength){let q=I.getUint16(Y,!0);Z.push(Math.round(q*1000/1024)),Y+=2}return{heartRate:U,contactDetected:A?$:void 0,energyExpended:H,rrIntervals:Z.length>0?Z:void 0}}function v8(I,w,G,$,A,_=2.105){let W=I.getUint8(0),Y=(W&1)!==0,U=(W&2)!==0,H=1,Z,q,Q,b;if(Y){Q=I.getUint32(H,!0),H+=4;let X=I.getUint16(H,!0);if(H+=2,w!==void 0&&G!==void 0){let L=(Q-w+4294967296)%4294967296,J=(X-G+65536)%65536;if(J>0){let B=J/1024;Z=L*_/B}}}if(U){b=I.getUint16(H,!0),H+=2;let X=I.getUint16(H,!0);if($!==void 0&&A!==void 0){let L=(b-$+65536)%65536,J=(X-A+65536)%65536;if(J>0){let B=J/1024/60;q=L/B}}}return{speed:Z,cadence:q,wheelRevolutions:Q,crankRevolutions:b}}function g8(I){let w=I.getUint16(0,!0),G=I.getInt16(2,!0),$=4,A,_;if(w&1)A=I.getUint8($),$+=1;if(w&4)$+=2;if(w&16)$+=6;if(w&32)$+=4;return{instantPower:G,pedalPowerBalance:A,cadence:_}}class M0{devices=[];handlers=new Map;isRunning=!1;intervals=[];async startScanning(I){if(this.isRunning)return;this.isRunning=!0,setTimeout(()=>{let w={id:"mock-hr-001",name:"Mock HR Monitor",type:"heart_rate",rssi:-65,connected:!1};this.devices.push(w),this.emit("device_found",w)},300),setTimeout(()=>{let w={id:"mock-power-001",name:"Mock Power Meter",type:"cycling_power",rssi:-70,connected:!1};this.devices.push(w),this.emit("device_found",w)},600)}async stopScanning(){this.isRunning=!1}getDevices(){return[...this.devices]}async connect(I){let w=this.devices.find((G)=>G.id===I);if(!w)throw Error("Device not found");if(w.connected=!0,this.emit("connected",w),w.type==="heart_rate"){let G=setInterval(()=>{if(!w.connected)return;let $={heartRate:70+Math.floor(Math.random()*30),contactDetected:!0,rrIntervals:[800+Math.floor(Math.random()*100)]};this.emit("data",w,{type:"heart_rate",data:$})},1000);this.intervals.push(G)}if(w.type==="cycling_power"){let G=setInterval(()=>{if(!w.connected)return;let $={instantPower:150+Math.floor(Math.random()*100),cadence:80+Math.floor(Math.random()*20),pedalPowerBalance:48+Math.random()*4};this.emit("data",w,{type:"power",data:$})},1000);this.intervals.push(G)}}async disconnect(I){let w=this.devices.find((G)=>G.id===I);if(w)w.connected=!1,this.emit("disconnected",w)}async subscribe(I,w){}on(I,w){if(!this.handlers.has(I))this.handlers.set(I,new Set);this.handlers.get(I).add(w)}off(I,w){this.handlers.get(I)?.delete(w)}emit(I,...w){this.handlers.get(I)?.forEach((G)=>G(...w))}async isAvailable(){return!0}async close(){this.intervals.forEach((I)=>clearInterval(I)),this.intervals=[],this.devices.forEach((I)=>I.connected=!1),this.devices=[],this.handlers.clear()}}function d8(){return new M0}class C0{session=null;config;handlers=new Map;updateInterval=null;lastPosition=null;constructor(I={}){this.config={updateInterval:I.updateInterval||5000,shareUrl:I.shareUrl||"",enableHeartRate:I.enableHeartRate??!0,enablePower:I.enablePower??!0,onUpdate:I.onUpdate||(()=>{}),onError:I.onError||(()=>{})}}start(I){if(this.session&&this.session.status==="active")throw Error("Session already active");return this.session={id:this.generateSessionId(),name:I,startTime:new Date,lastUpdate:new Date,totalDistance:0,elapsedTime:0,status:"active",trackPoints:[]},this.updateInterval=setInterval(()=>{this.tick()},this.config.updateInterval),this.emit("start",this.session),this.session}stop(){if(!this.session)return null;if(this.updateInterval)clearInterval(this.updateInterval),this.updateInterval=null;this.session.status="stopped",this.session.lastUpdate=new Date,this.emit("stop",this.session);let I={...this.session};return this.session=null,I}pause(){if(!this.session||this.session.status!=="active")return;this.session.status="paused",this.session.lastUpdate=new Date,this.emit("pause",this.session)}resume(){if(!this.session||this.session.status!=="paused")return;this.session.status="active",this.session.lastUpdate=new Date,this.emit("resume",this.session)}updatePosition(I){if(!this.session||this.session.status!=="active")return;if(this.lastPosition){let w=this.haversineDistance(this.lastPosition,I);this.session.totalDistance+=w;let G=(Date.now()-this.session.lastUpdate.getTime())/1000;if(G>0)this.session.currentSpeed=w/G}this.session.currentPosition=I,this.session.trackPoints.push(I),this.session.lastUpdate=new Date,this.lastPosition=I,this.emit("position",I)}updateHeartRate(I){if(!this.session||!this.config.enableHeartRate)return;this.session.currentHeartRate=I}updatePower(I){if(!this.session||!this.config.enablePower)return;this.session.currentPower=I}updateCadence(I){if(!this.session)return;this.session.currentCadence=I}getSession(){return this.session?{...this.session}:null}getShareUrl(){if(!this.session||!this.config.shareUrl)return null;return`${this.config.shareUrl}/${this.session.id}`}on(I,w){if(!this.handlers.has(I))this.handlers.set(I,new Set);this.handlers.get(I).add(w)}off(I,w){this.handlers.get(I)?.delete(w)}emit(I,...w){this.handlers.get(I)?.forEach((G)=>{try{G(...w)}catch($){this.config.onError($ instanceof Error?$:Error(String($)))}})}tick(){if(!this.session||this.session.status!=="active")return;this.session.elapsedTime=Math.floor((Date.now()-this.session.startTime.getTime())/1000),this.emit("update",this.session),this.config.onUpdate(this.session)}generateSessionId(){return`live_${Date.now()}_${Math.random().toString(36).substr(2,9)}`}haversineDistance(I,w){let $=I.lat*Math.PI/180,A=w.lat*Math.PI/180,_=(w.lat-I.lat)*Math.PI/180,W=(w.lng-I.lng)*Math.PI/180,Y=Math.sin(_/2)*Math.sin(_/2)+Math.cos($)*Math.cos(A)*Math.sin(W/2)*Math.sin(W/2);return 6371000*(2*Math.atan2(Math.sqrt(Y),Math.sqrt(1-Y)))}}function l8(I){return new C0(I)}function c8(I){let w=I.startTime.getTime(),G=I.trackPoints.length>1?(I.lastUpdate.getTime()-w)/(I.trackPoints.length-1):1000;return I.trackPoints.map(($,A)=>({timestamp:new Date(w+A*G),position:$,altitude:$.altitude,heartRate:I.currentHeartRate,cadence:I.currentCadence,power:I.currentPower}))}function i8(I){let w=Math.floor(I.elapsedTime/3600),G=Math.floor(I.elapsedTime%3600/60),$=I.elapsedTime%60,A=w>0?`${w}:${G.toString().padStart(2,"0")}:${$.toString().padStart(2,"0")}`:`${G}:${$.toString().padStart(2,"0")}`,_=I.totalDistance/1000,W=_>=10?`${_.toFixed(1)} km`:`${_.toFixed(2)} km`,Y="--:--",U="-- km/h";if(I.currentSpeed&&I.currentSpeed>0){let H=1000/I.currentSpeed,Z=Math.floor(H/60),q=Math.round(H%60);Y=`${Z}:${q.toString().padStart(2,"0")} /km`,U=`${(I.currentSpeed*3.6).toFixed(1)} km/h`}return{distance:W,duration:A,pace:Y,speed:U,heartRate:I.currentHeartRate?`${I.currentHeartRate} bpm`:"-- bpm",power:I.currentPower?`${I.currentPower} W`:"-- W"}}export{wH as writeTcx,e1 as writeGpx,QH as writeGeoJson,HH as writeCsv,sI as workoutTemplates,OH as verifyState,K as target,UH as stressToCsv,YH as sleepToCsv,EH as signState,c8 as sessionToRecords,Cq as semicirclesToDegrees,qH as recordsToGeoJsonPoints,O8 as planToIcal,g8 as parsePowerMeasurement,f8 as parseHeartRateMeasurement,v8 as parseCscMeasurement,_H as lapsToCsv,zH as isTokenExpired,SH as isAuthenticWebhook,WH as heartRateToCsv,FY as getWorkoutTypeName,M1 as getConfig,S8 as generateMarathonPlan,E8 as generate5kPlan,B8 as formatWorkoutTarget,J8 as formatWorkoutDuration,i8 as formatLiveStats,Mq as fitTimestampToDate,CH as extractDeregistrations,MH as extractActivitySummaries,G8 as estimateMaxHrByAge,$8 as estimateLthrFromMaxHr,eA as escapeForCsv,R as duration,Sq as degreesToSemicircles,MA as defaultConfig,w8 as createZoneCalculator,r as createWorkout,v1 as createWahooDriver,z8 as createTrainingPlan,tZ as createTrainingLoadCalculator,V1 as createSuuntoDriver,FZ as createStravaClient,U8 as createRunningDynamicsAnalyzer,W8 as createRacePredictor,z1 as createPolarDriver,TH as createPkcePair,eZ as createPersonalRecordsTracker,l8 as createLiveTracking,Oq as createGarminDriver,OZ as createGarminConnectClient,R8 as createCourse,u1 as createCorosDriver,d8 as createBleScanner,p1 as createAppleDriver,P8 as createAntPlusScanner,T8 as courseToTcx,K8 as courseToGpx,C1 as config,y8 as calculateWheelSpeed,A8 as calculateTargetHr,PY as calculateHrReserve,u8 as calculateCadence,IY as activityToTcx,jZ as activityToStravaUpload,oW as activityToGpx,UY as activityToGeoJson,$H as activityToCsv,AH as activitySummaryToCsv,bH as activitiesToGeoJson,X0 as ZoneCalculator,oG as WorkoutBuilder,cA as WahooDriver,R0 as TrainingPlanBuilder,lG as TrainingPeaks,L0 as TrainingLoadCalculator,zY as TPWorkoutTypeIds,yA as SuuntoDriver,Q0 as StravaClient,Bq as SUB_SPORT,Jq as SPORT,Dq as SLEEP_LEVEL,B0 as RunningDynamicsAnalyzer,J0 as RacePredictor,rG as RACE_DISTANCES,FA as PolarDriver,iG as PersonalRecordsTracker,M0 as MockBleScanner,T0 as MockAntPlusScanner,Lq as MESG_NUM,Kq as MANUFACTURER,C0 as LiveTrackingManager,Eq as GarminDriver,b0 as GarminConnectClient,LY as GarminActivityApiClient,QY as GARMIN_ENDPOINTS,kI as FitParser,Tq as FitParseError,PI as FitDecoder,qq as FIT_SIGNATURE,Zq as FIT_HEADER_SIZE_LEGACY,Hq as FIT_HEADER_SIZE,Rq as FIT_EPOCH,Xq as FIELD_DEF,D0 as CourseBuilder,vA as CorosDriver,h8 as BLE_SERVICES,n8 as BLE_CHARACTERISTICS,Qq as BASE_TYPE_SIZES,bq as BASE_TYPES,oA as AppleDriver,k8 as ANT_PLUS_PROFILES};
|