garmin-connect-client 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.
@@ -0,0 +1,440 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.HttpClient = void 0;
7
+ // HTTP client for Garmin Connect API requests.
8
+ //
9
+ // Handles authentication, token management, and HTTP requests. This class:
10
+ // - Performs OAuth 1.0/2.0 authentication flow
11
+ // - Manages OAuth token storage and lifecycle
12
+ // - Automatically refreshes expired tokens
13
+ // - Makes authenticated HTTP requests to the Garmin Connect API
14
+ //
15
+ // The authentication flow follows the standard Garmin SSO process:
16
+ // 1. Submit credentials and handle MFA if required
17
+ // 2. Exchange login ticket for OAuth 1.0 token
18
+ // 3. Exchange OAuth 1.0 token for OAuth 2.0 bearer token
19
+ const node_crypto_1 = __importDefault(require("node:crypto"));
20
+ const axios_1 = __importDefault(require("axios"));
21
+ const axios_cookiejar_support_1 = require("axios-cookiejar-support");
22
+ const oauth_1_0a_1 = __importDefault(require("oauth-1.0a"));
23
+ const tough_cookie_1 = require("tough-cookie");
24
+ const zod_1 = require("zod");
25
+ const errors_1 = require("./errors");
26
+ // Zod schemas for API responses
27
+ const LoginResponseSchema = zod_1.z
28
+ .object({
29
+ serviceURL: zod_1.z.string().nullable().optional(),
30
+ serviceTicketId: zod_1.z.string().nullable().optional(),
31
+ responseStatus: zod_1.z
32
+ .object({
33
+ type: zod_1.z.string(),
34
+ message: zod_1.z.string().optional(),
35
+ httpStatus: zod_1.z.string().optional(),
36
+ })
37
+ .optional(),
38
+ responseReason: zod_1.z.string().nullable().optional(),
39
+ customerMfaInfo: zod_1.z
40
+ .object({
41
+ mfaLastMethodUsed: zod_1.z.string().optional(),
42
+ email: zod_1.z.string().optional(),
43
+ phoneNumber: zod_1.z.string().nullable().optional(),
44
+ defaultMfaMethod: zod_1.z.string().nullable().optional(),
45
+ mfaUISetting: zod_1.z
46
+ .object({
47
+ allowPhoneOption: zod_1.z.boolean().optional(),
48
+ allowAddEmailAddress: zod_1.z.boolean().optional(),
49
+ chooseDifferentWayShown: zod_1.z.boolean().optional(),
50
+ })
51
+ .optional(),
52
+ })
53
+ .nullable()
54
+ .optional(),
55
+ consentTypeList: zod_1.z.array(zod_1.z.unknown()).nullable().optional(),
56
+ captchaAlreadyPassed: zod_1.z.boolean().optional(),
57
+ samlResponse: zod_1.z.string().nullable().optional(),
58
+ authType: zod_1.z.string().nullable().optional(),
59
+ })
60
+ .passthrough();
61
+ // User agent string for Garmin Connect Mobile app
62
+ const USER_AGENT_CONNECTMOBILE = 'com.garmin.android.apps.connectmobile';
63
+ // User agent string for iOS mobile browser
64
+ const USER_AGENT_MOBILE_IOS = 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148';
65
+ // OAuth 1.0 consumer credentials
66
+ // These are public values used for authentication and can be safely included in client applications
67
+ const OAUTH_CONSUMER_KEY = 'fc3e99d2-118c-44b8-8ae3-03370dde24c0';
68
+ const OAUTH_CONSUMER_SECRET = 'E08WAR897WEy2knn7aFBrvegVAf0AFdWBBF';
69
+ class HttpClient {
70
+ constructor(urls, mfaCodeProvider) {
71
+ // Flag to prevent concurrent token refresh attempts
72
+ this.isRefreshing = false;
73
+ this.urls = urls;
74
+ this.mfaCodeProvider = mfaCodeProvider;
75
+ const jar = new tough_cookie_1.CookieJar();
76
+ this.client = (0, axios_cookiejar_support_1.wrapper)(axios_1.default.create({ jar }));
77
+ this.appOauthIdentity = {
78
+ key: OAUTH_CONSUMER_KEY,
79
+ secret: OAUTH_CONSUMER_SECRET,
80
+ };
81
+ // Response interceptor: automatically refreshes expired tokens
82
+ // When a request fails with 401 (Unauthorized), the token is refreshed
83
+ // and the original request is retried transparently
84
+ this.client.interceptors.response.use(response => response, async (error) => {
85
+ // Convert axios errors to HttpError immediately to ensure serializability
86
+ if (axios_1.default.isAxiosError(error)) {
87
+ const originalRequest = error.config;
88
+ const status = error.response?.status;
89
+ const statusText = error.response?.statusText;
90
+ const data = error.response?.data;
91
+ if (status === 401 && originalRequest && !originalRequest._retry) {
92
+ if (!this.oauth2Token || !this.oauth1Token) {
93
+ throw new errors_1.HttpError(`HTTP request failed: ${error.message}`, status, statusText, data);
94
+ }
95
+ originalRequest._retry = true;
96
+ const newToken = await this.refreshToken();
97
+ originalRequest.headers.Authorization = `Bearer ${newToken}`;
98
+ return this.client(originalRequest);
99
+ }
100
+ throw new errors_1.HttpError(`HTTP request failed: ${error.message}`, status, statusText, data);
101
+ }
102
+ throw error;
103
+ });
104
+ // Request interceptor: automatically adds Bearer token to all requests
105
+ // Ensures all API calls are authenticated without manual token management
106
+ this.client.interceptors.request.use(async (config) => {
107
+ if (this.oauth2Token) {
108
+ config.headers.Authorization = `Bearer ${this.oauth2Token.access_token}`;
109
+ }
110
+ return config;
111
+ });
112
+ }
113
+ // Performs the complete authentication flow
114
+ //
115
+ // This method orchestrates the OAuth authentication process:
116
+ // 1. Obtains a login ticket from Garmin SSO (handles MFA if required)
117
+ // 2. Exchanges the ticket for an OAuth 1.0 token
118
+ // 3. Exchanges the OAuth 1.0 token for an OAuth 2.0 bearer token
119
+ //
120
+ // Returns both OAuth tokens (OAuth 1.0 is needed for refresh, OAuth 2.0 for API calls)
121
+ // Throws InvalidCredentialsError if credentials are invalid
122
+ // Throws MfaRequiredError if MFA is required but no provider is configured
123
+ // Throws MfaCodeError if MFA code is missing or empty
124
+ // Throws MfaCodeInvalidError if MFA code is invalid
125
+ async authenticate(username, password) {
126
+ const ticket = await this.getLoginTicket(username, password);
127
+ const oauth1Token = await this.getOauth1Token(ticket);
128
+ const oauth2Token = await this.exchange(oauth1Token);
129
+ this.oauth1Token = oauth1Token;
130
+ this.oauth2Token = oauth2Token;
131
+ return {
132
+ oauth1Token,
133
+ oauth2Token,
134
+ };
135
+ }
136
+ // Obtains a login ticket from Garmin SSO
137
+ //
138
+ // Submits credentials and handles MFA if required. Returns a login ticket
139
+ // that can be exchanged for OAuth tokens.
140
+ //
141
+ // Throws InvalidCredentialsError if credentials are invalid
142
+ // Throws MfaRequiredError if MFA is required but no provider is configured
143
+ // Throws MfaCodeError if MFA code is missing or empty
144
+ // Throws MfaCodeInvalidError if MFA code is invalid
145
+ async getLoginTicket(username, password) {
146
+ // First, visit the sign-in page to establish a session and get cookies
147
+ const signInUrl = this.urls.SIGN_IN_PAGE();
148
+ await this.get(signInUrl, {
149
+ headers: {
150
+ Accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
151
+ 'User-Agent': USER_AGENT_MOBILE_IOS,
152
+ 'Accept-Language': 'en-US,en;q=0.9',
153
+ 'Accept-Encoding': 'gzip, deflate, br',
154
+ },
155
+ });
156
+ const loginUrl = this.urls.LOGIN_API();
157
+ const loginBody = {
158
+ username,
159
+ password,
160
+ rememberMe: false,
161
+ captchaToken: '',
162
+ };
163
+ let loginResponse;
164
+ try {
165
+ const response = await this.post(loginUrl, loginBody, {
166
+ headers: {
167
+ 'Content-Type': 'application/json',
168
+ Accept: 'application/json, text/plain, */*',
169
+ Origin: this.urls.GARMIN_SSO_ORIGIN,
170
+ Referer: this.urls.SIGN_IN_REFERER(),
171
+ 'User-Agent': USER_AGENT_MOBILE_IOS,
172
+ 'Accept-Language': 'en-US,en;q=0.9',
173
+ 'Accept-Encoding': 'gzip, deflate, br',
174
+ },
175
+ });
176
+ loginResponse = LoginResponseSchema.parse(response);
177
+ }
178
+ catch (error) {
179
+ if (error instanceof errors_1.HttpError && error.responseData) {
180
+ // Try to parse the error response to get responseStatus information
181
+ const errorResponse = LoginResponseSchema.safeParse(error.responseData);
182
+ if (errorResponse.success) {
183
+ const responseStatus = errorResponse.data.responseStatus;
184
+ if (responseStatus?.type === 'INVALID_USERNAME_PASSWORD') {
185
+ throw new errors_1.InvalidCredentialsError('Invalid username or password');
186
+ }
187
+ }
188
+ // Fallback to status code check if responseStatus not available
189
+ if (error.statusCode === 401 || error.statusCode === 403) {
190
+ throw new errors_1.InvalidCredentialsError('Invalid username or password');
191
+ }
192
+ }
193
+ throw error;
194
+ }
195
+ // Try to extract ticket first - if present, login was successful
196
+ if (loginResponse.serviceTicketId) {
197
+ return loginResponse.serviceTicketId;
198
+ }
199
+ // No ticket found - check if MFA is required
200
+ let requiresMfa = false;
201
+ let mfaMethod = 'email';
202
+ // Check for MFA_REQUIRED in responseStatus.type
203
+ if (loginResponse.responseStatus?.type === 'MFA_REQUIRED') {
204
+ requiresMfa = true;
205
+ mfaMethod = loginResponse.customerMfaInfo?.mfaLastMethodUsed || 'email';
206
+ }
207
+ if (requiresMfa) {
208
+ if (!this.mfaCodeProvider) {
209
+ throw new errors_1.MfaRequiredError();
210
+ }
211
+ const mfaCode = await this.mfaCodeProvider.getMfaCode();
212
+ if (!mfaCode || mfaCode.trim().length === 0) {
213
+ throw new errors_1.MfaCodeError();
214
+ }
215
+ const mfaResult = await this.verifyMfaCode(mfaCode.trim(), mfaMethod);
216
+ if (mfaResult.serviceTicketId) {
217
+ return mfaResult.serviceTicketId;
218
+ }
219
+ throw new errors_1.MfaCodeInvalidError('MFA code submitted but ticket not found - please check your MFA code');
220
+ }
221
+ throw new errors_1.InvalidCredentialsError('login failed (Ticket not found or MFA), please check username and password');
222
+ }
223
+ // Verifies a multi-factor authentication code
224
+ // Returns the authentication response containing the login ticket
225
+ // Throws MfaCodeInvalidError if the MFA code is invalid or expired
226
+ async verifyMfaCode(mfaCode, mfaMethod = 'email') {
227
+ const mfaUrl = this.urls.MFA_VERIFY_API();
228
+ const mfaBody = {
229
+ mfaMethod,
230
+ mfaVerificationCode: mfaCode,
231
+ rememberMyBrowser: false,
232
+ reconsentList: [],
233
+ mfaSetup: false,
234
+ };
235
+ try {
236
+ const response = await this.post(mfaUrl, mfaBody, {
237
+ headers: {
238
+ 'Content-Type': 'application/json',
239
+ Accept: 'application/json, text/plain, */*',
240
+ Origin: this.urls.GARMIN_SSO_ORIGIN,
241
+ Referer: this.urls.MFA_REFERER(),
242
+ 'User-Agent': USER_AGENT_MOBILE_IOS,
243
+ 'Accept-Language': 'en-US,en;q=0.9',
244
+ 'Accept-Encoding': 'gzip, deflate, br',
245
+ },
246
+ });
247
+ const result = LoginResponseSchema.parse(response);
248
+ // Check for MFA_CODE_INVALID in response status (can occur even with 200 OK)
249
+ if (result.responseStatus?.type === 'MFA_CODE_INVALID') {
250
+ throw new errors_1.MfaCodeInvalidError(result.responseStatus.message || 'Invalid MFA code. Please check your code and try again.');
251
+ }
252
+ return result;
253
+ }
254
+ catch (error) {
255
+ if (error instanceof errors_1.HttpError) {
256
+ // Check responseStatus.type for MFA-specific errors if available
257
+ if (error.responseData) {
258
+ const errorResponse = LoginResponseSchema.safeParse(error.responseData);
259
+ if (errorResponse.success && errorResponse.data.responseStatus) {
260
+ const responseStatus = errorResponse.data.responseStatus;
261
+ if (responseStatus.type === 'SESSION_EXPIRED') {
262
+ throw new errors_1.MfaCodeInvalidError('Session expired. Please try logging in again.');
263
+ }
264
+ }
265
+ }
266
+ // Fallback to status code check
267
+ if (error.statusCode === 401 || error.statusCode === 403) {
268
+ throw new errors_1.MfaCodeInvalidError('Invalid MFA code');
269
+ }
270
+ // Handle 409 Conflict (session expired)
271
+ if (error.statusCode === 409) {
272
+ throw new errors_1.MfaCodeInvalidError('Session expired. Please try logging in again.');
273
+ }
274
+ }
275
+ throw error;
276
+ }
277
+ }
278
+ // Exchanges a login ticket for an OAuth 1.0 token
279
+ // Uses OAuth 1.0a signing to authenticate the request
280
+ // Returns OAuth 1.0 token containing oauth_token and oauth_token_secret
281
+ async getOauth1Token(ticket) {
282
+ const oauthParameters = {
283
+ ticket,
284
+ 'login-url': this.urls.MOBILE_SERVICE,
285
+ 'accepts-mfa-tokens': true,
286
+ };
287
+ const oauth = this.getOauthClient(this.appOauthIdentity);
288
+ const baseUrl = this.urls.OAUTH_PREAUTHORIZED_BASE();
289
+ const requestData = {
290
+ url: baseUrl,
291
+ method: 'GET',
292
+ data: oauthParameters,
293
+ };
294
+ const authData = oauth.authorize(requestData);
295
+ // Convert Authorization object to plain object for URL building
296
+ const authParameters = { ...authData };
297
+ const url = this.urls.OAUTH_PREAUTHORIZED(oauthParameters, authParameters);
298
+ const response = await this.get(url, {
299
+ headers: {
300
+ 'User-Agent': USER_AGENT_CONNECTMOBILE,
301
+ },
302
+ });
303
+ // Parse the query string response (format: "oauth_token=xxx&oauth_token_secret=yyy")
304
+ const responseParameters = new URLSearchParams(response);
305
+ const token = {
306
+ oauth_token: responseParameters.get('oauth_token') || '',
307
+ oauth_token_secret: responseParameters.get('oauth_token_secret') || '',
308
+ };
309
+ return token;
310
+ }
311
+ getOauthClient(appIdentity) {
312
+ return new oauth_1_0a_1.default({
313
+ consumer: appIdentity,
314
+ signature_method: 'HMAC-SHA1',
315
+ hash_function(base_string, key) {
316
+ return node_crypto_1.default.createHmac('sha1', key).update(base_string).digest('base64');
317
+ },
318
+ });
319
+ }
320
+ // Exchanges an OAuth 1.0 token for an OAuth 2.0 bearer token
321
+ //
322
+ // This is the final step in the authentication flow. The OAuth 2.0 token
323
+ // is used for all subsequent API requests via Bearer authentication.
324
+ // Returns OAuth 2.0 bearer token with expiration metadata
325
+ async exchange(oauth1Token) {
326
+ const oauth = this.getOauthClient(this.appOauthIdentity);
327
+ const token = {
328
+ key: oauth1Token.oauth_token,
329
+ secret: oauth1Token.oauth_token_secret,
330
+ };
331
+ const baseUrl = this.urls.OAUTH_EXCHANGE_BASE();
332
+ const requestData = {
333
+ url: baseUrl,
334
+ method: 'POST',
335
+ };
336
+ const step5AuthData = oauth.authorize(requestData, token);
337
+ // Convert Authorization object to plain object for URL building
338
+ const oauthParameters = { ...step5AuthData };
339
+ const url = this.urls.OAUTH_EXCHANGE(oauthParameters);
340
+ const response = await this.post(url, undefined, {
341
+ headers: {
342
+ 'User-Agent': USER_AGENT_CONNECTMOBILE,
343
+ 'Content-Type': 'application/x-www-form-urlencoded',
344
+ },
345
+ });
346
+ return this.setOauth2TokenExpiresAt(response);
347
+ }
348
+ // Adds expiration timestamps to an OAuth 2.0 token
349
+ //
350
+ // Converts relative expiration times (expires_in in seconds) to absolute
351
+ // timestamps for easier expiration checking
352
+ setOauth2TokenExpiresAt(token) {
353
+ const now = Math.floor(Date.now() / 1000);
354
+ const expiresAt = now + token.expires_in;
355
+ const refreshExpiresAt = now + token.refresh_token_expires_in;
356
+ token.last_update_date = new Date().toISOString();
357
+ token.expires_date = new Date(expiresAt * 1000).toISOString();
358
+ token.expires_at = expiresAt;
359
+ token.refresh_token_expires_at = refreshExpiresAt;
360
+ return token;
361
+ }
362
+ // Refreshes the OAuth 2.0 token using the existing OAuth 1.0 token
363
+ //
364
+ // This method is called automatically by the response interceptor when
365
+ // a 401 error is encountered. Uses promise sharing to prevent concurrent
366
+ // refresh attempts - if a refresh is already in progress, all requests
367
+ // wait for the same promise to avoid duplicate refresh API calls.
368
+ // Throws OAuthTokenError if no OAuth 1.0 token is available for refresh
369
+ async refreshToken() {
370
+ if (!this.oauth1Token) {
371
+ throw new errors_1.OAuthTokenError('No OAuth1 token available for refresh');
372
+ }
373
+ if (this.isRefreshing && this.refreshPromise) {
374
+ return this.refreshPromise;
375
+ }
376
+ this.isRefreshing = true;
377
+ this.refreshPromise = (async () => {
378
+ try {
379
+ const newToken = await this.exchange(this.oauth1Token);
380
+ this.oauth2Token = newToken;
381
+ return newToken.access_token;
382
+ }
383
+ finally {
384
+ this.isRefreshing = false;
385
+ this.refreshPromise = undefined;
386
+ }
387
+ })();
388
+ return this.refreshPromise;
389
+ }
390
+ // Performs an HTTP GET request
391
+ // The Bearer token is automatically added via the request interceptor
392
+ // Throws HttpError if the request fails
393
+ async get(url, config) {
394
+ const response = await this.client.get(url, config);
395
+ return response.data;
396
+ }
397
+ // Performs an HTTP POST request
398
+ // The Bearer token is automatically added via the request interceptor
399
+ // Throws HttpError if the request fails
400
+ async post(url, data, config) {
401
+ const response = await this.client.post(url, data, config);
402
+ return response.data;
403
+ }
404
+ // Performs an HTTP PUT request
405
+ // The Bearer token is automatically added via the request interceptor
406
+ // Throws HttpError if the request fails
407
+ async put(url, data, config) {
408
+ const response = await this.client.put(url, data, config);
409
+ return response.data;
410
+ }
411
+ // Performs an HTTP DELETE request
412
+ //
413
+ // Note: The Garmin API uses POST with X-Http-Method-Override header for DELETE requests.
414
+ // The Bearer token is automatically added via the request interceptor.
415
+ // Throws HttpError if the request fails
416
+ async delete(url, config) {
417
+ const response = await this.client.post(url, undefined, {
418
+ ...config,
419
+ headers: {
420
+ ...config?.headers,
421
+ 'X-Http-Method-Override': 'DELETE',
422
+ },
423
+ });
424
+ return response.data;
425
+ }
426
+ // Converts an axios response error to an HttpError
427
+ // Always throws an HttpError
428
+ handleError(response) {
429
+ const { status, statusText, data } = response;
430
+ const message = `ERROR: (${status}), ${statusText}, ${JSON.stringify(data)}`;
431
+ throw new errors_1.HttpError(message, status, statusText, data);
432
+ }
433
+ // Checks if the client is authenticated (has valid OAuth tokens)
434
+ // Returns true if both OAuth 1.0 and 2.0 tokens are present
435
+ isAuthenticated() {
436
+ return !!(this.oauth1Token && this.oauth2Token);
437
+ }
438
+ }
439
+ exports.HttpClient = HttpClient;
440
+ //# sourceMappingURL=http-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-client.js","sourceRoot":"","sources":["../src/http-client.ts"],"names":[],"mappings":";;;;;;AAAA,+CAA+C;AAC/C,EAAE;AACF,2EAA2E;AAC3E,+CAA+C;AAC/C,8CAA8C;AAC9C,2CAA2C;AAC3C,gEAAgE;AAChE,EAAE;AACF,mEAAmE;AACnE,mDAAmD;AACnD,+CAA+C;AAC/C,yDAAyD;AACzD,8DAAiC;AAEjC,kDAA4G;AAC5G,qEAAkD;AAClD,4DAA+B;AAC/B,+CAAyC;AACzC,6BAAwB;AAExB,qCAOkB;AAIlB,gCAAgC;AAChC,MAAM,mBAAmB,GAAG,OAAC;KAC1B,MAAM,CAAC;IACN,UAAU,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IAC5C,eAAe,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IACjD,cAAc,EAAE,OAAC;SACd,MAAM,CAAC;QACN,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE;QAChB,OAAO,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC9B,UAAU,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;KAClC,CAAC;SACD,QAAQ,EAAE;IACb,cAAc,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IAChD,eAAe,EAAE,OAAC;SACf,MAAM,CAAC;QACN,iBAAiB,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QACxC,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC5B,WAAW,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;QAC7C,gBAAgB,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;QAClD,YAAY,EAAE,OAAC;aACZ,MAAM,CAAC;YACN,gBAAgB,EAAE,OAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;YACxC,oBAAoB,EAAE,OAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;YAC5C,uBAAuB,EAAE,OAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;SAChD,CAAC;aACD,QAAQ,EAAE;KACd,CAAC;SACD,QAAQ,EAAE;SACV,QAAQ,EAAE;IACb,eAAe,EAAE,OAAC,CAAC,KAAK,CAAC,OAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IAC3D,oBAAoB,EAAE,OAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IAC5C,YAAY,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IAC9C,QAAQ,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;CAC3C,CAAC;KACD,WAAW,EAAE,CAAC;AAIjB,kDAAkD;AAClD,MAAM,wBAAwB,GAAG,uCAAuC,CAAC;AAEzE,2CAA2C;AAC3C,MAAM,qBAAqB,GACzB,+GAA+G,CAAC;AAElH,iCAAiC;AACjC,oGAAoG;AACpG,MAAM,kBAAkB,GAAG,sCAAsC,CAAC;AAClE,MAAM,qBAAqB,GAAG,qCAAqC,CAAC;AAEpE,MAAa,UAAU;IAgBrB,YAAY,IAAgB,EAAE,eAAiC;QAL/D,oDAAoD;QAC5C,iBAAY,GAAG,KAAK,CAAC;QAK3B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,eAAe,GAAG,eAAe,CAAC;QACvC,MAAM,GAAG,GAAG,IAAI,wBAAS,EAAE,CAAC;QAC5B,IAAI,CAAC,MAAM,GAAG,IAAA,iCAAO,EAAC,eAAK,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;QAC7C,IAAI,CAAC,gBAAgB,GAAG;YACtB,GAAG,EAAE,kBAAkB;YACvB,MAAM,EAAE,qBAAqB;SAC9B,CAAC;QAEF,+DAA+D;QAC/D,uEAAuE;QACvE,oDAAoD;QACpD,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC,GAAG,CACnC,QAAQ,CAAC,EAAE,CAAC,QAAQ,EACpB,KAAK,EAAC,KAAK,EAAC,EAAE;YACZ,0EAA0E;YAC1E,IAAI,eAAK,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC9B,MAAM,eAAe,GAAG,KAAK,CAAC,MAA2D,CAAC;gBAC1F,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC;gBACtC,MAAM,UAAU,GAAG,KAAK,CAAC,QAAQ,EAAE,UAAU,CAAC;gBAC9C,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,EAAE,IAAI,CAAC;gBAElC,IAAI,MAAM,KAAK,GAAG,IAAI,eAAe,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,CAAC;oBACjE,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;wBAC3C,MAAM,IAAI,kBAAS,CAAC,wBAAwB,KAAK,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC;oBACzF,CAAC;oBAED,eAAe,CAAC,MAAM,GAAG,IAAI,CAAC;oBAC9B,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;oBAC3C,eAAe,CAAC,OAAO,CAAC,aAAa,GAAG,UAAU,QAAQ,EAAE,CAAC;oBAC7D,OAAO,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;gBACtC,CAAC;gBAED,MAAM,IAAI,kBAAS,CAAC,wBAAwB,KAAK,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC;YACzF,CAAC;YAED,MAAM,KAAK,CAAC;QACd,CAAC,CACF,CAAC;QAEF,uEAAuE;QACvE,0EAA0E;QAC1E,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAC,MAAM,EAAC,EAAE;YAClD,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;gBACrB,MAAM,CAAC,OAAO,CAAC,aAAa,GAAG,UAAU,IAAI,CAAC,WAAW,CAAC,YAAY,EAAE,CAAC;YAC3E,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC,CAAC,CAAC;IACL,CAAC;IAED,4CAA4C;IAC5C,EAAE;IACF,6DAA6D;IAC7D,sEAAsE;IACtE,iDAAiD;IACjD,iEAAiE;IACjE,EAAE;IACF,uFAAuF;IACvF,4DAA4D;IAC5D,2EAA2E;IAC3E,sDAAsD;IACtD,oDAAoD;IACpD,KAAK,CAAC,YAAY,CAChB,QAAgB,EAChB,QAAgB;QAEhB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAC7D,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;QACtD,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;QACrD,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,OAAO;YACL,WAAW;YACX,WAAW;SACZ,CAAC;IACJ,CAAC;IAED,yCAAyC;IACzC,EAAE;IACF,0EAA0E;IAC1E,0CAA0C;IAC1C,EAAE;IACF,4DAA4D;IAC5D,2EAA2E;IAC3E,sDAAsD;IACtD,oDAAoD;IAC5C,KAAK,CAAC,cAAc,CAAC,QAAgB,EAAE,QAAgB;QAC7D,uEAAuE;QACvE,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;QAE3C,MAAM,IAAI,CAAC,GAAG,CAAS,SAAS,EAAE;YAChC,OAAO,EAAE;gBACP,MAAM,EAAE,iEAAiE;gBACzE,YAAY,EAAE,qBAAqB;gBACnC,iBAAiB,EAAE,gBAAgB;gBACnC,iBAAiB,EAAE,mBAAmB;aACvC;SACF,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;QAEvC,MAAM,SAAS,GAAG;YAChB,QAAQ;YACR,QAAQ;YACR,UAAU,EAAE,KAAK;YACjB,YAAY,EAAE,EAAE;SACjB,CAAC;QAEF,IAAI,aAA4B,CAAC;QACjC,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE;gBACpD,OAAO,EAAE;oBACP,cAAc,EAAE,kBAAkB;oBAClC,MAAM,EAAE,mCAAmC;oBAC3C,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,iBAAiB;oBACnC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE;oBACpC,YAAY,EAAE,qBAAqB;oBACnC,iBAAiB,EAAE,gBAAgB;oBACnC,iBAAiB,EAAE,mBAAmB;iBACvC;aACF,CAAC,CAAC;YACH,aAAa,GAAG,mBAAmB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACtD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,kBAAS,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;gBACrD,oEAAoE;gBACpE,MAAM,aAAa,GAAG,mBAAmB,CAAC,SAAS,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;gBACxE,IAAI,aAAa,CAAC,OAAO,EAAE,CAAC;oBAC1B,MAAM,cAAc,GAAG,aAAa,CAAC,IAAI,CAAC,cAAc,CAAC;oBACzD,IAAI,cAAc,EAAE,IAAI,KAAK,2BAA2B,EAAE,CAAC;wBACzD,MAAM,IAAI,gCAAuB,CAAC,8BAA8B,CAAC,CAAC;oBACpE,CAAC;gBACH,CAAC;gBACD,gEAAgE;gBAChE,IAAI,KAAK,CAAC,UAAU,KAAK,GAAG,IAAI,KAAK,CAAC,UAAU,KAAK,GAAG,EAAE,CAAC;oBACzD,MAAM,IAAI,gCAAuB,CAAC,8BAA8B,CAAC,CAAC;gBACpE,CAAC;YACH,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;QAED,iEAAiE;QACjE,IAAI,aAAa,CAAC,eAAe,EAAE,CAAC;YAClC,OAAO,aAAa,CAAC,eAAe,CAAC;QACvC,CAAC;QAED,6CAA6C;QAC7C,IAAI,WAAW,GAAG,KAAK,CAAC;QACxB,IAAI,SAAS,GAAG,OAAO,CAAC;QAExB,gDAAgD;QAChD,IAAI,aAAa,CAAC,cAAc,EAAE,IAAI,KAAK,cAAc,EAAE,CAAC;YAC1D,WAAW,GAAG,IAAI,CAAC;YACnB,SAAS,GAAG,aAAa,CAAC,eAAe,EAAE,iBAAiB,IAAI,OAAO,CAAC;QAC1E,CAAC;QAED,IAAI,WAAW,EAAE,CAAC;YAChB,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC;gBAC1B,MAAM,IAAI,yBAAgB,EAAE,CAAC;YAC/B,CAAC;YAED,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,UAAU,EAAE,CAAC;YACxD,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC5C,MAAM,IAAI,qBAAY,EAAE,CAAC;YAC3B,CAAC;YAED,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,SAAS,CAAC,CAAC;YAEtE,IAAI,SAAS,CAAC,eAAe,EAAE,CAAC;gBAC9B,OAAO,SAAS,CAAC,eAAe,CAAC;YACnC,CAAC;YAED,MAAM,IAAI,4BAAmB,CAAC,sEAAsE,CAAC,CAAC;QACxG,CAAC;QAED,MAAM,IAAI,gCAAuB,CAAC,4EAA4E,CAAC,CAAC;IAClH,CAAC;IAED,8CAA8C;IAC9C,kEAAkE;IAClE,mEAAmE;IAC3D,KAAK,CAAC,aAAa,CAAC,OAAe,EAAE,YAAoB,OAAO;QACtE,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;QAE1C,MAAM,OAAO,GAAG;YACd,SAAS;YACT,mBAAmB,EAAE,OAAO;YAC5B,iBAAiB,EAAE,KAAK;YACxB,aAAa,EAAE,EAAE;YACjB,QAAQ,EAAE,KAAK;SAChB,CAAC;QAEF,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,CAAU,MAAM,EAAE,OAAO,EAAE;gBACzD,OAAO,EAAE;oBACP,cAAc,EAAE,kBAAkB;oBAClC,MAAM,EAAE,mCAAmC;oBAC3C,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,iBAAiB;oBACnC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE;oBAChC,YAAY,EAAE,qBAAqB;oBACnC,iBAAiB,EAAE,gBAAgB;oBACnC,iBAAiB,EAAE,mBAAmB;iBACvC;aACF,CAAC,CAAC;YACH,MAAM,MAAM,GAAG,mBAAmB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YAEnD,6EAA6E;YAC7E,IAAI,MAAM,CAAC,cAAc,EAAE,IAAI,KAAK,kBAAkB,EAAE,CAAC;gBACvD,MAAM,IAAI,4BAAmB,CAC3B,MAAM,CAAC,cAAc,CAAC,OAAO,IAAI,yDAAyD,CAC3F,CAAC;YACJ,CAAC;YAED,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,kBAAS,EAAE,CAAC;gBAC/B,iEAAiE;gBACjE,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;oBACvB,MAAM,aAAa,GAAG,mBAAmB,CAAC,SAAS,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;oBACxE,IAAI,aAAa,CAAC,OAAO,IAAI,aAAa,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;wBAC/D,MAAM,cAAc,GAAG,aAAa,CAAC,IAAI,CAAC,cAAc,CAAC;wBACzD,IAAI,cAAc,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;4BAC9C,MAAM,IAAI,4BAAmB,CAAC,+CAA+C,CAAC,CAAC;wBACjF,CAAC;oBACH,CAAC;gBACH,CAAC;gBACD,gCAAgC;gBAChC,IAAI,KAAK,CAAC,UAAU,KAAK,GAAG,IAAI,KAAK,CAAC,UAAU,KAAK,GAAG,EAAE,CAAC;oBACzD,MAAM,IAAI,4BAAmB,CAAC,kBAAkB,CAAC,CAAC;gBACpD,CAAC;gBACD,wCAAwC;gBACxC,IAAI,KAAK,CAAC,UAAU,KAAK,GAAG,EAAE,CAAC;oBAC7B,MAAM,IAAI,4BAAmB,CAAC,+CAA+C,CAAC,CAAC;gBACjF,CAAC;YACH,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED,kDAAkD;IAClD,sDAAsD;IACtD,wEAAwE;IAChE,KAAK,CAAC,cAAc,CAAC,MAAc;QACzC,MAAM,eAAe,GAAG;YACtB,MAAM;YACN,WAAW,EAAE,IAAI,CAAC,IAAI,CAAC,cAAc;YACrC,oBAAoB,EAAE,IAAI;SAC3B,CAAC;QAEF,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QACzD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,wBAAwB,EAAE,CAAC;QAErD,MAAM,WAAW,GAAG;YAClB,GAAG,EAAE,OAAO;YACZ,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,eAAe;SACtB,CAAC;QACF,MAAM,QAAQ,GAAG,KAAK,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QAC9C,gEAAgE;QAChE,MAAM,cAAc,GAAG,EAAE,GAAG,QAAQ,EAA6B,CAAC;QAClE,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,eAAe,EAAE,cAAc,CAAC,CAAC;QAE3E,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,GAAG,CAAS,GAAG,EAAE;YAC3C,OAAO,EAAE;gBACP,YAAY,EAAE,wBAAwB;aACvC;SACF,CAAC,CAAC;QACH,qFAAqF;QACrF,MAAM,kBAAkB,GAAG,IAAI,eAAe,CAAC,QAAQ,CAAC,CAAC;QACzD,MAAM,KAAK,GAAgB;YACzB,WAAW,EAAE,kBAAkB,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,EAAE;YACxD,kBAAkB,EAAE,kBAAkB,CAAC,GAAG,CAAC,oBAAoB,CAAC,IAAI,EAAE;SACvE,CAAC;QACF,OAAO,KAAK,CAAC;IACf,CAAC;IAEO,cAAc,CAAC,WAA8B;QACnD,OAAO,IAAI,oBAAK,CAAC;YACf,QAAQ,EAAE,WAAW;YACrB,gBAAgB,EAAE,WAAW;YAC7B,aAAa,CAAC,WAAmB,EAAE,GAAW;gBAC5C,OAAO,qBAAM,CAAC,UAAU,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC7E,CAAC;SACF,CAAC,CAAC;IACL,CAAC;IAED,6DAA6D;IAC7D,EAAE;IACF,yEAAyE;IACzE,qEAAqE;IACrE,0DAA0D;IAClD,KAAK,CAAC,QAAQ,CAAC,WAAwB;QAC7C,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QACzD,MAAM,KAAK,GAAG;YACZ,GAAG,EAAE,WAAW,CAAC,WAAW;YAC5B,MAAM,EAAE,WAAW,CAAC,kBAAkB;SACvC,CAAC;QAEF,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAChD,MAAM,WAAW,GAAG;YAClB,GAAG,EAAE,OAAO;YACZ,MAAM,EAAE,MAAM;SACf,CAAC;QAEF,MAAM,aAAa,GAAG,KAAK,CAAC,SAAS,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;QAC1D,gEAAgE;QAChE,MAAM,eAAe,GAAG,EAAE,GAAG,aAAa,EAA6B,CAAC;QACxE,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC;QACtD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,CAAc,GAAG,EAAE,SAAS,EAAE;YAC5D,OAAO,EAAE;gBACP,YAAY,EAAE,wBAAwB;gBACtC,cAAc,EAAE,mCAAmC;aACpD;SACF,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,uBAAuB,CAAC,QAAQ,CAAC,CAAC;IAChD,CAAC;IAED,mDAAmD;IACnD,EAAE;IACF,yEAAyE;IACzE,4CAA4C;IACpC,uBAAuB,CAAC,KAAkB;QAChD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;QAC1C,MAAM,SAAS,GAAG,GAAG,GAAG,KAAK,CAAC,UAAU,CAAC;QACzC,MAAM,gBAAgB,GAAG,GAAG,GAAG,KAAK,CAAC,wBAAwB,CAAC;QAE9D,KAAK,CAAC,gBAAgB,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAClD,KAAK,CAAC,YAAY,GAAG,IAAI,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;QAC9D,KAAK,CAAC,UAAU,GAAG,SAAS,CAAC;QAC7B,KAAK,CAAC,wBAAwB,GAAG,gBAAgB,CAAC;QAClD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,mEAAmE;IACnE,EAAE;IACF,uEAAuE;IACvE,yEAAyE;IACzE,uEAAuE;IACvE,kEAAkE;IAClE,wEAAwE;IAChE,KAAK,CAAC,YAAY;QACxB,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACtB,MAAM,IAAI,wBAAe,CAAC,uCAAuC,CAAC,CAAC;QACrE,CAAC;QAED,IAAI,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YAC7C,OAAO,IAAI,CAAC,cAAc,CAAC;QAC7B,CAAC;QAED,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,IAAI,CAAC,cAAc,GAAG,CAAC,KAAK,IAAI,EAAE;YAChC,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAY,CAAC,CAAC;gBACxD,IAAI,CAAC,WAAW,GAAG,QAAQ,CAAC;gBAC5B,OAAO,QAAQ,CAAC,YAAY,CAAC;YAC/B,CAAC;oBAAS,CAAC;gBACT,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;gBAC1B,IAAI,CAAC,cAAc,GAAG,SAAS,CAAC;YAClC,CAAC;QACH,CAAC,CAAC,EAAE,CAAC;QAEL,OAAO,IAAI,CAAC,cAAc,CAAC;IAC7B,CAAC;IAED,+BAA+B;IAC/B,sEAAsE;IACtE,wCAAwC;IACxC,KAAK,CAAC,GAAG,CAAI,GAAW,EAAE,MAA2B;QACnD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAI,GAAG,EAAE,MAAM,CAAC,CAAC;QACvD,OAAO,QAAQ,CAAC,IAAI,CAAC;IACvB,CAAC;IAED,gCAAgC;IAChC,sEAAsE;IACtE,wCAAwC;IACxC,KAAK,CAAC,IAAI,CAAI,GAAW,EAAE,IAAa,EAAE,MAA2B;QACnE,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAI,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QAC9D,OAAO,QAAQ,CAAC,IAAI,CAAC;IACvB,CAAC;IAED,+BAA+B;IAC/B,sEAAsE;IACtE,wCAAwC;IACxC,KAAK,CAAC,GAAG,CAAI,GAAW,EAAE,IAAa,EAAE,MAA2B;QAClE,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAI,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QAC7D,OAAO,QAAQ,CAAC,IAAI,CAAC;IACvB,CAAC;IAED,kCAAkC;IAClC,EAAE;IACF,yFAAyF;IACzF,uEAAuE;IACvE,wCAAwC;IACxC,KAAK,CAAC,MAAM,CAAI,GAAW,EAAE,MAA2B;QACtD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAI,GAAG,EAAE,SAAS,EAAE;YACzD,GAAG,MAAM;YACT,OAAO,EAAE;gBACP,GAAG,MAAM,EAAE,OAAO;gBAClB,wBAAwB,EAAE,QAAQ;aACnC;SACF,CAAC,CAAC;QACH,OAAO,QAAQ,CAAC,IAAI,CAAC;IACvB,CAAC;IAED,mDAAmD;IACnD,6BAA6B;IAC7B,WAAW,CAAC,QAAuB;QACjC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,GAAG,QAAQ,CAAC;QAC9C,MAAM,OAAO,GAAG,WAAW,MAAM,MAAM,UAAU,KAAK,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7E,MAAM,IAAI,kBAAS,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC;IACzD,CAAC;IAED,iEAAiE;IACjE,4DAA4D;IAC5D,eAAe;QACb,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,WAAW,CAAC,CAAC;IAClD,CAAC;CACF;AAjbD,gCAibC"}
@@ -0,0 +1,6 @@
1
+ import type { GarminConnectClient, GarminConnectClientConfig } from './types';
2
+ export type { Activity, ActivityType, AcuteTrainingLoadDTO, BodyBattery, BodyBatteryActivityEvent, BodyBatteryDynamicFeedbackEvent, Calories, EventType, Floors, GolfActivityHole, GolfActivitiesResponse, GolfCourseSnapshot, GolfCourseSnapshotResponse, GolfDrivingRangeActivity, GolfScorecardActivity, GarminConnectClient, GarminConnectClientConfig, HeartRate, HeartRateZoneScalar, Hydration, IntensityMinutes, MfaCodeProvider, Movement, Privacy, PulseOx, RecordedDevice, Respiration, Steps, Stress, TrainingStatusData, TrainingStatusDailyScalar, TrainingStatusWeeklyScalar, UserDailySummary, WellnessChronology, } from './types';
3
+ export { ActivityTypeKey, EventTypeKey, PrivacyTypeKey, StressQualifier, BodyBatteryLevel, TrainingStatus, FitnessTrend, AcwrStatus, TrainingStatusFeedbackPhrase, AcwrStatusFeedback, BodyBatteryFeedbackType, BodyBatteryShortFeedback, BodyBatteryEventType, HrvStatus, Sport, SubSport, ChangeState, TrainingMethod, ActivitySchema, ActivityTypeSchema, EventTypeSchema, PrivacySchema, GolfActivityHoleSchema, GolfActivitiesResponseSchema, GolfCourseSnapshotSchema, GolfCourseSnapshotResponseSchema, GolfDrivingRangeActivitySchema, GolfScorecardActivitySchema, StepsSchema, FloorsSchema, MovementSchema, CaloriesSchema, HeartRateSchema, IntensityMinutesSchema, StressSchema, BodyBatteryDynamicFeedbackEventSchema, BodyBatteryActivityEventSchema, BodyBatterySchema, HydrationSchema, RespirationSchema, PulseOxSchema, WellnessChronologySchema, UserDailySummarySchema, AcuteTrainingLoadDTOSchema, TrainingStatusDataSchema, RecordedDeviceSchema, TrainingStatusDailyScalarSchema, TrainingStatusWeeklyScalarSchema, HeartRateZoneScalarSchema, } from './types';
4
+ export { AuthenticationError, ClientError, CsrfTokenError, GarminConnectError, HttpError, InvalidCredentialsError, MfaCodeError, MfaCodeInvalidError, MfaError, MfaRequiredError, NotAuthenticatedError, NotImplementedError, OAuthError, OAuthIdentityError, OAuthTokenError, } from './errors';
5
+ export declare function create(config: GarminConnectClientConfig): Promise<GarminConnectClient>;
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,MAAM,SAAS,CAAC;AAE9E,YAAY,EACV,QAAQ,EACR,YAAY,EACZ,oBAAoB,EACpB,WAAW,EACX,wBAAwB,EACxB,+BAA+B,EAC/B,QAAQ,EACR,SAAS,EACT,MAAM,EACN,gBAAgB,EAChB,sBAAsB,EACtB,kBAAkB,EAClB,0BAA0B,EAC1B,wBAAwB,EACxB,qBAAqB,EACrB,mBAAmB,EACnB,yBAAyB,EACzB,SAAS,EACT,mBAAmB,EACnB,SAAS,EACT,gBAAgB,EAChB,eAAe,EACf,QAAQ,EACR,OAAO,EACP,OAAO,EACP,cAAc,EACd,WAAW,EACX,KAAK,EACL,MAAM,EACN,kBAAkB,EAClB,yBAAyB,EACzB,0BAA0B,EAC1B,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,SAAS,CAAC;AAEjB,OAAO,EACL,eAAe,EACf,YAAY,EACZ,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,YAAY,EACZ,UAAU,EACV,4BAA4B,EAC5B,kBAAkB,EAClB,uBAAuB,EACvB,wBAAwB,EACxB,oBAAoB,EACpB,SAAS,EACT,KAAK,EACL,QAAQ,EACR,WAAW,EACX,cAAc,EAEd,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,aAAa,EACb,sBAAsB,EACtB,4BAA4B,EAC5B,wBAAwB,EACxB,gCAAgC,EAChC,8BAA8B,EAC9B,2BAA2B,EAC3B,WAAW,EACX,YAAY,EACZ,cAAc,EACd,cAAc,EACd,eAAe,EACf,sBAAsB,EACtB,YAAY,EACZ,qCAAqC,EACrC,8BAA8B,EAC9B,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,wBAAwB,EACxB,sBAAsB,EACtB,0BAA0B,EAC1B,wBAAwB,EACxB,oBAAoB,EACpB,+BAA+B,EAC/B,gCAAgC,EAChC,yBAAyB,GAC1B,MAAM,SAAS,CAAC;AAGjB,OAAO,EACL,mBAAmB,EACnB,WAAW,EACX,cAAc,EACd,kBAAkB,EAClB,SAAS,EACT,uBAAuB,EACvB,YAAY,EACZ,mBAAmB,EACnB,QAAQ,EACR,gBAAgB,EAChB,qBAAqB,EACrB,mBAAmB,EACnB,UAAU,EACV,kBAAkB,EAClB,eAAe,GAChB,MAAM,UAAU,CAAC;AAKlB,wBAAsB,MAAM,CAAC,MAAM,EAAE,yBAAyB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAE5F"}
package/dist/index.js ADDED
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AuthenticationError = exports.HeartRateZoneScalarSchema = exports.TrainingStatusWeeklyScalarSchema = exports.TrainingStatusDailyScalarSchema = exports.RecordedDeviceSchema = exports.TrainingStatusDataSchema = exports.AcuteTrainingLoadDTOSchema = exports.UserDailySummarySchema = exports.WellnessChronologySchema = exports.PulseOxSchema = exports.RespirationSchema = exports.HydrationSchema = exports.BodyBatterySchema = exports.BodyBatteryActivityEventSchema = exports.BodyBatteryDynamicFeedbackEventSchema = exports.StressSchema = exports.IntensityMinutesSchema = exports.HeartRateSchema = exports.CaloriesSchema = exports.MovementSchema = exports.FloorsSchema = exports.StepsSchema = exports.GolfScorecardActivitySchema = exports.GolfDrivingRangeActivitySchema = exports.GolfCourseSnapshotResponseSchema = exports.GolfCourseSnapshotSchema = exports.GolfActivitiesResponseSchema = exports.GolfActivityHoleSchema = exports.PrivacySchema = exports.EventTypeSchema = exports.ActivityTypeSchema = exports.ActivitySchema = exports.TrainingMethod = exports.ChangeState = exports.SubSport = exports.Sport = exports.HrvStatus = exports.BodyBatteryEventType = exports.BodyBatteryShortFeedback = exports.BodyBatteryFeedbackType = exports.AcwrStatusFeedback = exports.TrainingStatusFeedbackPhrase = exports.AcwrStatus = exports.FitnessTrend = exports.TrainingStatus = exports.BodyBatteryLevel = exports.StressQualifier = exports.PrivacyTypeKey = exports.EventTypeKey = exports.ActivityTypeKey = void 0;
4
+ exports.OAuthTokenError = exports.OAuthIdentityError = exports.OAuthError = exports.NotImplementedError = exports.NotAuthenticatedError = exports.MfaRequiredError = exports.MfaError = exports.MfaCodeInvalidError = exports.MfaCodeError = exports.InvalidCredentialsError = exports.HttpError = exports.GarminConnectError = exports.CsrfTokenError = exports.ClientError = void 0;
5
+ exports.create = create;
6
+ const client_1 = require("./client");
7
+ var types_1 = require("./types");
8
+ Object.defineProperty(exports, "ActivityTypeKey", { enumerable: true, get: function () { return types_1.ActivityTypeKey; } });
9
+ Object.defineProperty(exports, "EventTypeKey", { enumerable: true, get: function () { return types_1.EventTypeKey; } });
10
+ Object.defineProperty(exports, "PrivacyTypeKey", { enumerable: true, get: function () { return types_1.PrivacyTypeKey; } });
11
+ Object.defineProperty(exports, "StressQualifier", { enumerable: true, get: function () { return types_1.StressQualifier; } });
12
+ Object.defineProperty(exports, "BodyBatteryLevel", { enumerable: true, get: function () { return types_1.BodyBatteryLevel; } });
13
+ Object.defineProperty(exports, "TrainingStatus", { enumerable: true, get: function () { return types_1.TrainingStatus; } });
14
+ Object.defineProperty(exports, "FitnessTrend", { enumerable: true, get: function () { return types_1.FitnessTrend; } });
15
+ Object.defineProperty(exports, "AcwrStatus", { enumerable: true, get: function () { return types_1.AcwrStatus; } });
16
+ Object.defineProperty(exports, "TrainingStatusFeedbackPhrase", { enumerable: true, get: function () { return types_1.TrainingStatusFeedbackPhrase; } });
17
+ Object.defineProperty(exports, "AcwrStatusFeedback", { enumerable: true, get: function () { return types_1.AcwrStatusFeedback; } });
18
+ Object.defineProperty(exports, "BodyBatteryFeedbackType", { enumerable: true, get: function () { return types_1.BodyBatteryFeedbackType; } });
19
+ Object.defineProperty(exports, "BodyBatteryShortFeedback", { enumerable: true, get: function () { return types_1.BodyBatteryShortFeedback; } });
20
+ Object.defineProperty(exports, "BodyBatteryEventType", { enumerable: true, get: function () { return types_1.BodyBatteryEventType; } });
21
+ Object.defineProperty(exports, "HrvStatus", { enumerable: true, get: function () { return types_1.HrvStatus; } });
22
+ Object.defineProperty(exports, "Sport", { enumerable: true, get: function () { return types_1.Sport; } });
23
+ Object.defineProperty(exports, "SubSport", { enumerable: true, get: function () { return types_1.SubSport; } });
24
+ Object.defineProperty(exports, "ChangeState", { enumerable: true, get: function () { return types_1.ChangeState; } });
25
+ Object.defineProperty(exports, "TrainingMethod", { enumerable: true, get: function () { return types_1.TrainingMethod; } });
26
+ // Zod schemas for runtime validation
27
+ Object.defineProperty(exports, "ActivitySchema", { enumerable: true, get: function () { return types_1.ActivitySchema; } });
28
+ Object.defineProperty(exports, "ActivityTypeSchema", { enumerable: true, get: function () { return types_1.ActivityTypeSchema; } });
29
+ Object.defineProperty(exports, "EventTypeSchema", { enumerable: true, get: function () { return types_1.EventTypeSchema; } });
30
+ Object.defineProperty(exports, "PrivacySchema", { enumerable: true, get: function () { return types_1.PrivacySchema; } });
31
+ Object.defineProperty(exports, "GolfActivityHoleSchema", { enumerable: true, get: function () { return types_1.GolfActivityHoleSchema; } });
32
+ Object.defineProperty(exports, "GolfActivitiesResponseSchema", { enumerable: true, get: function () { return types_1.GolfActivitiesResponseSchema; } });
33
+ Object.defineProperty(exports, "GolfCourseSnapshotSchema", { enumerable: true, get: function () { return types_1.GolfCourseSnapshotSchema; } });
34
+ Object.defineProperty(exports, "GolfCourseSnapshotResponseSchema", { enumerable: true, get: function () { return types_1.GolfCourseSnapshotResponseSchema; } });
35
+ Object.defineProperty(exports, "GolfDrivingRangeActivitySchema", { enumerable: true, get: function () { return types_1.GolfDrivingRangeActivitySchema; } });
36
+ Object.defineProperty(exports, "GolfScorecardActivitySchema", { enumerable: true, get: function () { return types_1.GolfScorecardActivitySchema; } });
37
+ Object.defineProperty(exports, "StepsSchema", { enumerable: true, get: function () { return types_1.StepsSchema; } });
38
+ Object.defineProperty(exports, "FloorsSchema", { enumerable: true, get: function () { return types_1.FloorsSchema; } });
39
+ Object.defineProperty(exports, "MovementSchema", { enumerable: true, get: function () { return types_1.MovementSchema; } });
40
+ Object.defineProperty(exports, "CaloriesSchema", { enumerable: true, get: function () { return types_1.CaloriesSchema; } });
41
+ Object.defineProperty(exports, "HeartRateSchema", { enumerable: true, get: function () { return types_1.HeartRateSchema; } });
42
+ Object.defineProperty(exports, "IntensityMinutesSchema", { enumerable: true, get: function () { return types_1.IntensityMinutesSchema; } });
43
+ Object.defineProperty(exports, "StressSchema", { enumerable: true, get: function () { return types_1.StressSchema; } });
44
+ Object.defineProperty(exports, "BodyBatteryDynamicFeedbackEventSchema", { enumerable: true, get: function () { return types_1.BodyBatteryDynamicFeedbackEventSchema; } });
45
+ Object.defineProperty(exports, "BodyBatteryActivityEventSchema", { enumerable: true, get: function () { return types_1.BodyBatteryActivityEventSchema; } });
46
+ Object.defineProperty(exports, "BodyBatterySchema", { enumerable: true, get: function () { return types_1.BodyBatterySchema; } });
47
+ Object.defineProperty(exports, "HydrationSchema", { enumerable: true, get: function () { return types_1.HydrationSchema; } });
48
+ Object.defineProperty(exports, "RespirationSchema", { enumerable: true, get: function () { return types_1.RespirationSchema; } });
49
+ Object.defineProperty(exports, "PulseOxSchema", { enumerable: true, get: function () { return types_1.PulseOxSchema; } });
50
+ Object.defineProperty(exports, "WellnessChronologySchema", { enumerable: true, get: function () { return types_1.WellnessChronologySchema; } });
51
+ Object.defineProperty(exports, "UserDailySummarySchema", { enumerable: true, get: function () { return types_1.UserDailySummarySchema; } });
52
+ Object.defineProperty(exports, "AcuteTrainingLoadDTOSchema", { enumerable: true, get: function () { return types_1.AcuteTrainingLoadDTOSchema; } });
53
+ Object.defineProperty(exports, "TrainingStatusDataSchema", { enumerable: true, get: function () { return types_1.TrainingStatusDataSchema; } });
54
+ Object.defineProperty(exports, "RecordedDeviceSchema", { enumerable: true, get: function () { return types_1.RecordedDeviceSchema; } });
55
+ Object.defineProperty(exports, "TrainingStatusDailyScalarSchema", { enumerable: true, get: function () { return types_1.TrainingStatusDailyScalarSchema; } });
56
+ Object.defineProperty(exports, "TrainingStatusWeeklyScalarSchema", { enumerable: true, get: function () { return types_1.TrainingStatusWeeklyScalarSchema; } });
57
+ Object.defineProperty(exports, "HeartRateZoneScalarSchema", { enumerable: true, get: function () { return types_1.HeartRateZoneScalarSchema; } });
58
+ // Export all custom exceptions
59
+ var errors_1 = require("./errors");
60
+ Object.defineProperty(exports, "AuthenticationError", { enumerable: true, get: function () { return errors_1.AuthenticationError; } });
61
+ Object.defineProperty(exports, "ClientError", { enumerable: true, get: function () { return errors_1.ClientError; } });
62
+ Object.defineProperty(exports, "CsrfTokenError", { enumerable: true, get: function () { return errors_1.CsrfTokenError; } });
63
+ Object.defineProperty(exports, "GarminConnectError", { enumerable: true, get: function () { return errors_1.GarminConnectError; } });
64
+ Object.defineProperty(exports, "HttpError", { enumerable: true, get: function () { return errors_1.HttpError; } });
65
+ Object.defineProperty(exports, "InvalidCredentialsError", { enumerable: true, get: function () { return errors_1.InvalidCredentialsError; } });
66
+ Object.defineProperty(exports, "MfaCodeError", { enumerable: true, get: function () { return errors_1.MfaCodeError; } });
67
+ Object.defineProperty(exports, "MfaCodeInvalidError", { enumerable: true, get: function () { return errors_1.MfaCodeInvalidError; } });
68
+ Object.defineProperty(exports, "MfaError", { enumerable: true, get: function () { return errors_1.MfaError; } });
69
+ Object.defineProperty(exports, "MfaRequiredError", { enumerable: true, get: function () { return errors_1.MfaRequiredError; } });
70
+ Object.defineProperty(exports, "NotAuthenticatedError", { enumerable: true, get: function () { return errors_1.NotAuthenticatedError; } });
71
+ Object.defineProperty(exports, "NotImplementedError", { enumerable: true, get: function () { return errors_1.NotImplementedError; } });
72
+ Object.defineProperty(exports, "OAuthError", { enumerable: true, get: function () { return errors_1.OAuthError; } });
73
+ Object.defineProperty(exports, "OAuthIdentityError", { enumerable: true, get: function () { return errors_1.OAuthIdentityError; } });
74
+ Object.defineProperty(exports, "OAuthTokenError", { enumerable: true, get: function () { return errors_1.OAuthTokenError; } });
75
+ // Creates a new Garmin Connect client and performs login
76
+ // @param config - Configuration with username and password
77
+ // @returns Promise resolving to an authenticated client instance
78
+ async function create(config) {
79
+ return client_1.GarminConnectClientImpl.createAuthenticated(config);
80
+ }
81
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;AAmHA,wBAEC;AArHD,qCAAmD;AAwCnD,iCAmDiB;AAlDf,wGAAA,eAAe,OAAA;AACf,qGAAA,YAAY,OAAA;AACZ,uGAAA,cAAc,OAAA;AACd,wGAAA,eAAe,OAAA;AACf,yGAAA,gBAAgB,OAAA;AAChB,uGAAA,cAAc,OAAA;AACd,qGAAA,YAAY,OAAA;AACZ,mGAAA,UAAU,OAAA;AACV,qHAAA,4BAA4B,OAAA;AAC5B,2GAAA,kBAAkB,OAAA;AAClB,gHAAA,uBAAuB,OAAA;AACvB,iHAAA,wBAAwB,OAAA;AACxB,6GAAA,oBAAoB,OAAA;AACpB,kGAAA,SAAS,OAAA;AACT,8FAAA,KAAK,OAAA;AACL,iGAAA,QAAQ,OAAA;AACR,oGAAA,WAAW,OAAA;AACX,uGAAA,cAAc,OAAA;AACd,qCAAqC;AACrC,uGAAA,cAAc,OAAA;AACd,2GAAA,kBAAkB,OAAA;AAClB,wGAAA,eAAe,OAAA;AACf,sGAAA,aAAa,OAAA;AACb,+GAAA,sBAAsB,OAAA;AACtB,qHAAA,4BAA4B,OAAA;AAC5B,iHAAA,wBAAwB,OAAA;AACxB,yHAAA,gCAAgC,OAAA;AAChC,uHAAA,8BAA8B,OAAA;AAC9B,oHAAA,2BAA2B,OAAA;AAC3B,oGAAA,WAAW,OAAA;AACX,qGAAA,YAAY,OAAA;AACZ,uGAAA,cAAc,OAAA;AACd,uGAAA,cAAc,OAAA;AACd,wGAAA,eAAe,OAAA;AACf,+GAAA,sBAAsB,OAAA;AACtB,qGAAA,YAAY,OAAA;AACZ,8HAAA,qCAAqC,OAAA;AACrC,uHAAA,8BAA8B,OAAA;AAC9B,0GAAA,iBAAiB,OAAA;AACjB,wGAAA,eAAe,OAAA;AACf,0GAAA,iBAAiB,OAAA;AACjB,sGAAA,aAAa,OAAA;AACb,iHAAA,wBAAwB,OAAA;AACxB,+GAAA,sBAAsB,OAAA;AACtB,mHAAA,0BAA0B,OAAA;AAC1B,iHAAA,wBAAwB,OAAA;AACxB,6GAAA,oBAAoB,OAAA;AACpB,wHAAA,+BAA+B,OAAA;AAC/B,yHAAA,gCAAgC,OAAA;AAChC,kHAAA,yBAAyB,OAAA;AAG3B,+BAA+B;AAC/B,mCAgBkB;AAfhB,6GAAA,mBAAmB,OAAA;AACnB,qGAAA,WAAW,OAAA;AACX,wGAAA,cAAc,OAAA;AACd,4GAAA,kBAAkB,OAAA;AAClB,mGAAA,SAAS,OAAA;AACT,iHAAA,uBAAuB,OAAA;AACvB,sGAAA,YAAY,OAAA;AACZ,6GAAA,mBAAmB,OAAA;AACnB,kGAAA,QAAQ,OAAA;AACR,0GAAA,gBAAgB,OAAA;AAChB,+GAAA,qBAAqB,OAAA;AACrB,6GAAA,mBAAmB,OAAA;AACnB,oGAAA,UAAU,OAAA;AACV,4GAAA,kBAAkB,OAAA;AAClB,yGAAA,eAAe,OAAA;AAGjB,yDAAyD;AACzD,2DAA2D;AAC3D,iEAAiE;AAC1D,KAAK,UAAU,MAAM,CAAC,MAAiC;IAC5D,OAAO,gCAAuB,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC;AAC7D,CAAC"}