@stacksjs/mobile 0.75.226 → 0.75.229

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -5,6 +5,15 @@ native capability detection, readiness, haptics, location, camera, sharing,
5
5
  secure storage, lifecycle, health, Live Activities, and watch connectivity
6
6
  behind one browser-safe interface.
7
7
 
8
+ Native STX screens are bundled into the installed app and rendered as UIKit or
9
+ Android views by Craft. The phone website uses the browser renderer with the
10
+ same STX screen source. Screen and native-code changes arrive in a new app
11
+ build; account and training data refresh through the application's API.
12
+
13
+ Recording ownership, atomic durable storage and secure system UUIDs require
14
+ `craft-native >=0.0.238` and a native host built with those capabilities. Check
15
+ capabilities and request the permissions each feature needs before starting it.
16
+
8
17
  ```ts
9
18
  import { haptics, isNativeMobile, location } from '@stacksjs/mobile'
10
19
 
@@ -25,7 +34,8 @@ building blocks, for a bridge API this package does not wrap yet.
25
34
 
26
35
  ## Beyond the core services
27
36
 
28
- Each with a web fallback, and none throwing for being unsupported:
37
+ Browser behavior varies by service. Check support before a device-only call
38
+ and handle permission and availability errors. Additional services include:
29
39
  `dialog` (alert, confirm, actionSheet; HTML stand-ins in a browser),
30
40
  `confirmAction`, `useActionSheet`, `contextMenu`, `browser.open` (in-app
31
41
  Safari or an auth session), `symbols.image` (SF Symbols, cached), `statusBar`,
@@ -283,12 +293,36 @@ const recorder = createRouteRecorder({
283
293
  onUpdate: stats => console.log(stats.distanceM, paceLabel(stats.paceSPerKm)),
284
294
  })
285
295
 
286
- await recorder.attach() ?? await recorder.start() // pick up a recording that outlived the app
296
+ if (savedRecordingId) await recorder.attach({ expectedId: savedRecordingId })
297
+ else await recorder.start()
287
298
  await recorder.pause()
288
299
  await recorder.resume()
289
300
  const fixes = await recorder.stop() // every fix, for the server to keep
290
301
  ```
291
302
 
303
+ `savedRecordingId` must come from the signed-in account's workout draft. Save
304
+ `recorder.recordingId` after a successful start and keep it with that draft.
305
+ An unknown ID or another active recording is a conflict, never permission to
306
+ adopt or replace the global recording. The ID remains available after stopping
307
+ so a delayed completion can be kept for its original account. An explicitly
308
+ owned completed recording can also be attached and stopped again after a lost
309
+ acknowledgement; check the attached state's `active` before pausing or resuming.
310
+ Guarded metadata, reads and stop resolve that recording's retained archive even
311
+ when a different athlete has since started a new route.
312
+
313
+ When the controller also records heart rate, persist
314
+ `recorder.heartRateRecordingId` and recover it with
315
+ `attach({ expectedId, expectedHeartRateId })`. Omitting the heart-rate ID leaves
316
+ the existing heart-rate recording untouched. Both the SDK adapter and native
317
+ host must support recording ownership; guarded operations otherwise reject with
318
+ `RECORDING_OWNERSHIP_UNSUPPORTED`. A changed recording rejects with
319
+ `RECORDING_CONFLICT` before reading or changing its data. The recorder never
320
+ automatically releases native data. After durably keeping the result under its
321
+ original account, call `location.acknowledgeRecording({ expectedId })` (and
322
+ `heartRate.acknowledgeRecording` for a bundled strap). A failed checkpoint must
323
+ leave that native copy available; acknowledge a discarded recording only after
324
+ the account's discard is durable.
325
+
292
326
  `routeStats(fixes)` is the arithmetic on its own: distance counted from an
293
327
  anchor so GPS drift while standing still adds nothing, fixes less accurate than
294
328
  25 m left out, a gap of more than `ROUTE_GAP_S` (a pause) not counted as ground
@@ -439,3 +473,51 @@ The `/testing` entrypoint is for Bun build/test tools and is excluded from brows
439
473
  exports. The ordinary `@stacksjs/mobile` entrypoint stays browser-safe. Extend
440
474
  Craft's shared host and typed APIs for new platform features instead of editing
441
475
  generated sources.
476
+
477
+
478
+ ### Durable conditional storage
479
+
480
+ `storage` uses the named `craft-native/mobile` adapter. Basic calls require the
481
+ host's storage service and reject with `STORAGE_UNSUPPORTED` when unavailable. Check
482
+ `storage.supportsCompareAndSet()` before recording an owned native session.
483
+ `storage.supportsSetIfAbsent()` must also be true before recording. Use
484
+ `await storage.setIfAbsent(key, value)` to register an absent initial intent
485
+ durably before a sensor starts. It creates a new key atomically; any existing
486
+ value, including JSON null, returns `false`. A competing creation requires a
487
+ fresh read and validation of that intent, never an unconditional set. Older
488
+ hosts reject creation with `STORAGE_SET_IF_ABSENT_UNSUPPORTED`.
489
+ For a later checkpoint, read with `await storage.get(key)`, merge
490
+ that fresh value, and call `await storage.compareAndSet(key, expected, next)`.
491
+ The comparison and durable write are one native operation. A missing or changed
492
+ value returns `false` and never creates a key; I/O errors throw. Re-read and
493
+ retry a same-owner conflict a bounded number of times. A cached `getSync` value
494
+ and a plain `set` cannot replace CAS for a late recording response.
495
+
496
+ Older hosts reject conditional writes with
497
+ `STORAGE_COMPARE_AND_SET_UNSUPPORTED`; there is no get-and-set fallback. This
498
+ facade requires the normally published SDK that provides the named `storage`
499
+ export. Recording acknowledgement belongs after a successful checkpoint, or
500
+ an explicitly confirmed discard of that proven recording.
501
+
502
+ ### Registering an identity before a native recording starts
503
+
504
+ For recovery across a lost start response or a full disk, generate distinct
505
+ UUIDs for GPS and heart rate, and durably register them with the captured
506
+ account's workout intent before starting either sensor. `await crypto.randomUUID()`
507
+ uses the system UUID service through the named SDK adapter; native hosts without
508
+ it reject with `CRYPTO_UNSUPPORTED`. Await ID allocation inside the same shared
509
+ preparation promise as registration, and recheck the captured owner afterward.
510
+ Check each service's
511
+ `supportsRecordingIntentIdentity()` first. Start GPS with
512
+ `location.startRecording({ recordingId })`, a route with
513
+ `recorder.start({ recordingId, heartRateRecordingId })`, or heart rate with
514
+ `heartRate.startRecording({ recordingId })`. The host uses that exact ID;
515
+ the SDK and this facade reject a different response ID. An older host or
516
+ adapter rejects supplied IDs with `RECORDING_INTENT_IDENTITY_UNSUPPORTED`
517
+ before making a native start call.
518
+
519
+ After reopening, recover only the ID saved in that account's intent. A
520
+ planned ID whose sensor never started does not authorize adopting another
521
+ native recording. Native start refuses active, archived, or acknowledged
522
+ ID reuse. The ordinary no-ID API remains available for legacy callers;
523
+ owned workout recovery requires the registered-ID protocol.
@@ -0,0 +1,2 @@
1
+ import type { CryptoApi } from './types';
2
+ export declare const crypto: CryptoApi;
package/dist/index.d.ts CHANGED
@@ -1,12 +1,18 @@
1
1
  /**
2
2
  * Bundled TypeScript declarations
3
- * Generated from 19 source files
3
+ * Generated from 21 source files
4
4
  */
5
5
 
6
6
  import { BugHQClient, Breadcrumb, BugHQConfig } from '@bughq/sdk';
7
7
  import { NativeTab } from 'craft-native/mobile';
8
8
 
9
9
  // From: src/index.ts
10
+ declare function locationRecordingOwnership(): boolean;
11
+ declare function heartRateRecordingOwnership(): boolean;
12
+ declare function locationRecordingIntentIdentity(): boolean;
13
+ declare function heartRateRecordingIntentIdentity(): boolean;
14
+ declare function recordingStartCall<T extends { id: string | null }>(options: { recordingId?: string } | undefined, supported: () => boolean, call: () => Promise<T>): Promise<T>;
15
+ declare function recordingCall<T>(options: { expectedId?: string } | undefined, supported: () => boolean, call: () => Promise<T>): Promise<T>;
10
16
  declare function normalizeDeepLinkURL(value: unknown): string | null;
11
17
  declare function host(): CraftHost | undefined;
12
18
  /** Reads the current host, including a bridge injected after this module loaded. */
@@ -560,14 +566,16 @@ declare interface RouteRecorderOptions extends RouteStatsOptions {
560
566
  heartRate?: HeartRateRecordingApi
561
567
  }
562
568
  declare interface RouteRecorder {
563
- start: () => Promise<RouteStats>
564
- attach: () => Promise<LocationRecordingState | null>
569
+ start: (intent?: { recordingId: string, heartRateRecordingId?: string }) => Promise<RouteStats>
570
+ attach: (options: { expectedId: string, expectedHeartRateId?: string }) => Promise<LocationRecordingState | null>
565
571
  pause: () => Promise<void>
566
572
  resume: () => Promise<void>
567
573
  stop: () => Promise<RouteFix[]>
568
574
  refresh: () => Promise<RouteStats>
569
575
  dispose: () => void
570
576
  readonly stats: RouteStats
577
+ readonly recordingId: string | null
578
+ readonly heartRateRecordingId: string | null
571
579
  readonly heartRate: HeartRateSample[]
572
580
  }
573
581
 
@@ -1355,8 +1363,15 @@ declare interface CraftMobileCapabilities {
1355
1363
  biometric?: boolean
1356
1364
  pushNotifications?: boolean
1357
1365
  secureStorage?: boolean
1366
+ storageCompareAndSet?: boolean
1367
+ storageSetIfAbsent?: boolean
1368
+ crypto?: boolean
1358
1369
  geolocation?: boolean
1359
1370
  backgroundLocation?: boolean
1371
+ locationRecordingOwnership?: boolean
1372
+ locationRecordingIntentIdentity?: boolean
1373
+ heartRateRecordingIntentIdentity?: boolean
1374
+ heartRateRecordingOwnership?: boolean
1360
1375
  healthKit?: boolean
1361
1376
  health?: boolean
1362
1377
  liveActivities?: boolean
@@ -1413,6 +1428,8 @@ declare interface MobileApi {
1413
1428
  notifications: NotificationsApi
1414
1429
  permissions: PermissionsApi
1415
1430
  secureStorage: SecureStorageApi
1431
+ storage: StorageApi
1432
+ crypto: CryptoApi
1416
1433
  share: ShareApi
1417
1434
  appReview: AppReviewApi
1418
1435
  deepLinks: DeepLinksApi
@@ -1508,6 +1525,11 @@ declare interface LocationRecordingState {
1508
1525
  startedAt: number | null
1509
1526
  sampleCount?: number
1510
1527
  }
1528
+ /** An identity already registered durably by the caller before native start. */
1529
+ declare interface RecordingStartOptions {
1530
+ recordingId?: string
1531
+ }
1532
+ declare interface LocationRecordingOptions extends LocationOptions, RecordingStartOptions {}
1511
1533
  declare interface LocationRecordingResult extends LocationRecordingState {
1512
1534
  locations: Location[]
1513
1535
  }
@@ -1559,22 +1581,45 @@ declare interface BiometricsApi {
1559
1581
  getBiometricType: () => Promise<BiometricType | null>
1560
1582
  authenticate: (reason: string) => Promise<boolean>
1561
1583
  }
1584
+ /** Native durable storage. CAS changes an existing value only; false never creates it. */
1585
+ declare interface StorageApi {
1586
+ supportsCompareAndSet: () => boolean
1587
+ supportsSetIfAbsent: () => boolean
1588
+ get: <T = unknown>(key: string) => Promise<T | null>
1589
+ set: (key: string, value: unknown) => Promise<boolean>
1590
+ remove: (key: string) => Promise<boolean>
1591
+ clear: () => Promise<boolean>
1592
+ keys: () => Promise<string[]>
1593
+ setIfAbsent: (key: string, value: unknown) => Promise<boolean>
1594
+ compareAndSet: (key: string, expectedValue: unknown, nextValue: unknown) => Promise<boolean>
1595
+ }
1596
+ /** Secure system UUID generation also works in native asynchronous JS hosts. */
1597
+ declare interface CryptoApi {
1598
+ randomUUID: () => Promise<string>
1599
+ }
1562
1600
  declare interface SecureStorageApi {
1563
1601
  set: (key: string, value: string) => Promise<void>
1564
1602
  get: (key: string) => Promise<string | null>
1565
1603
  delete: (key: string) => Promise<void>
1566
1604
  clear: () => Promise<void>
1567
1605
  }
1606
+ /** Native checks this ID before reading or changing a recording. */
1607
+ declare interface RecordingOwnershipOptions {
1608
+ expectedId: string
1609
+ }
1568
1610
  declare interface LocationApi {
1611
+ supportsRecordingOwnership: () => boolean
1612
+ supportsRecordingIntentIdentity: () => boolean
1613
+ acknowledgeRecording: (options: RecordingOwnershipOptions) => Promise<boolean>
1569
1614
  getCurrentPosition: (options?: LocationOptions) => Promise<Location>
1570
1615
  watchPosition: (callback: (location: Location) => void, options?: LocationOptions) => number
1571
1616
  clearWatch: (watchId: number) => void
1572
- startRecording: (options?: LocationOptions) => Promise<LocationRecordingState>
1573
- pauseRecording: () => Promise<LocationRecordingState>
1574
- resumeRecording: () => Promise<LocationRecordingState>
1575
- stopRecording: () => Promise<LocationRecordingResult>
1576
- getRecordingState: () => Promise<LocationRecordingState>
1577
- readRecording: () => Promise<Location[]>
1617
+ startRecording: (options?: LocationRecordingOptions) => Promise<LocationRecordingState>
1618
+ pauseRecording: (options?: RecordingOwnershipOptions) => Promise<LocationRecordingState>
1619
+ resumeRecording: (options?: RecordingOwnershipOptions) => Promise<LocationRecordingState>
1620
+ stopRecording: (options?: RecordingOwnershipOptions) => Promise<LocationRecordingResult>
1621
+ getRecordingState: (options?: RecordingOwnershipOptions) => Promise<LocationRecordingState>
1622
+ readRecording: (options?: RecordingOwnershipOptions) => Promise<Location[]>
1578
1623
  }
1579
1624
  declare interface ShareApi {
1580
1625
  share: (options: ShareOptions) => Promise<boolean>
@@ -1678,12 +1723,15 @@ declare interface HeartRateSample {
1678
1723
  /** The recording half of HeartRateApi: what a route recorder drives. */
1679
1724
  declare interface HeartRateRecordingApi {
1680
1725
  isAvailable: () => boolean
1681
- startRecording: () => Promise<HeartRateRecordingState>
1682
- pauseRecording: () => Promise<HeartRateRecordingState>
1683
- resumeRecording: () => Promise<HeartRateRecordingState>
1684
- stopRecording: () => Promise<HeartRateRecordingState & { samples: HeartRateSample[] }>
1685
- getRecordingState: () => Promise<HeartRateRecordingState>
1686
- readRecording: (options?: { since?: number }) => Promise<HeartRateSample[]>
1726
+ supportsRecordingOwnership: () => boolean
1727
+ supportsRecordingIntentIdentity: () => boolean
1728
+ acknowledgeRecording: (options: RecordingOwnershipOptions) => Promise<boolean>
1729
+ startRecording: (options?: RecordingStartOptions) => Promise<HeartRateRecordingState>
1730
+ pauseRecording: (options?: RecordingOwnershipOptions) => Promise<HeartRateRecordingState>
1731
+ resumeRecording: (options?: RecordingOwnershipOptions) => Promise<HeartRateRecordingState>
1732
+ stopRecording: (options?: RecordingOwnershipOptions) => Promise<HeartRateRecordingState & { samples: HeartRateSample[] }>
1733
+ getRecordingState: (options?: RecordingOwnershipOptions) => Promise<HeartRateRecordingState>
1734
+ readRecording: (options?: { since?: number, expectedId?: string }) => Promise<HeartRateSample[]>
1687
1735
  }
1688
1736
  declare interface HeartRateApi extends HeartRateRecordingApi {
1689
1737
  isAvailable: () => boolean
@@ -1928,7 +1976,7 @@ type BluetoothState = 'poweredOn' | 'poweredOff' | 'unauthorized' | 'unsupported
1928
1976
  /** A strap that drops out is asked for again (`reconnecting`) until `disconnect()`. */
1929
1977
  type HeartRateConnection = 'disconnected' | 'connecting' | 'connected' | 'reconnecting';
1930
1978
  type HeartRateMethod = 'getState' | 'requestAuthorization' | 'scan' | 'stopScan' | 'getDevices' | 'connect' | 'reconnect' | 'disconnect'
1931
- | 'startRecording' | 'pauseRecording' | 'resumeRecording' | 'stopRecording' | 'getRecordingState' | 'readRecording';
1979
+ | 'startRecording' | 'pauseRecording' | 'resumeRecording' | 'stopRecording' | 'getRecordingState' | 'readRecording' | 'acknowledgeRecording';
1932
1980
  type HealthDataType = | 'steps'
1933
1981
  | 'heartRate'
1934
1982
  | 'activeEnergy'
@@ -1958,6 +2006,14 @@ type HealthSleepStage = 'inBed' | 'awake' | 'asleep' | 'core' | 'deep' | 'rem';
1958
2006
  type HealthReadMethod = 'getWorkouts' | 'getDailyStatistics' | 'getHeartRateSamples' | 'getSleepIntervals' | 'saveMindfulSession' | 'getMindfulSessions'
1959
2007
  | 'startHeartRateUpdates' | 'stopHeartRateUpdates';
1960
2008
 
1961
- export { normalizeDeepLinkURL, getNativeMobileBridge, isNativeMobile, whenNativeMobile, onMobileReady, withNativeFeedback, biometrics, camera, device, lifecycle, location, notifications, permissions, secureStorage, share, appReview, haptics, deepLinks, snapshots, keepAwake, brightness, music, heartRate, speech, network, pushNotifications, health, liveActivities, watchConnectivity, splash, mobile, craftHost, craftRoot, hasNativeMobileHost, bridgePending, whenBridgeReady, nativeFunctionNow, nativeFunction, callNative, afterBridge, subscribeWhenReady, onCraftEvent, BRIDGE_WAIT_MS, CraftHost, CallNativeOptions, observeLongPress, segmentAt, observeSegmentScrub, segmentForKey, focusSegment, installPressables, LongPressOptions, SegmentScrubOptions, keepBreadcrumb, crashReporting, CrashReportingOptions, currentAppearance, normalizeAppearance, onAppearance, onResume, onMemoryWarning, onSilentPush, onBackgroundRefresh, NativeAppearance, pageScrollTop, observePageScroll, pullDistance, observePullToRefresh, largeTitleMetrics, observeLargeTitle, resolveScrollHost, ScrollHost, PullToRefreshOptions, LargeTitleMetrics, LargeTitleOptions, canGoBack, goBack, enterNavTrail, backLabelFor, navTrail, previousScreenPath, goBackToTabRoot, trailEntryFor, deepLinkPath, followDeepLinks, HistoryHost, NavTrailEntry, TabRootHost, attachHeartRate, fixDistance, usableFixes, routeStats, paceLabel, speedLabel, createRouteRecorder, HEART_RATE_MATCH_MS, ROUTE_GAP_S, RouteFix, RouteStats, RouteStatsOptions, RouteRecorderOptions, RouteRecorder, scheduledWorkoutsUnsupported, normalizeScheduledWorkout, scheduledWorkouts, AppleWorkoutStep, AppleIntervalBlock, AppleCustomWorkout, AppleWorkoutPlan, ScheduledWorkout, ScheduleWorkoutResult, ScheduledWorkoutsApi, ScheduledWorkoutsAuthorization, AppleWorkoutGoal, AppleWorkoutAlert, ScheduledWorkoutsMethod, startSessionClock, pauseSessionClock, resumeSessionClock, sessionClockElapsed, SessionClock, indoorVerdict, typedDistanceKm, INDOOR_CHECK_AFTER_S, IndoorFix, IndoorVerdict, toNativeRect, useActionSheet, confirmAction, showContextMenuFor, dialog, contextMenu, browser, symbols, statusBar, chrome, refresh, background, clipboard, db, files, shortcuts, widgets, orientation, auth, storeKit, DialogApi, ConfirmActionOptions, ContextMenuApi, BrowserOpenOptions, BrowserResult, BrowserApi, SymbolOptions, SymbolsApi, StatusBarApi, ChromeApi, RefreshApi, BackgroundApi, ClipboardApi, DatabaseExecuteResult, DatabaseApi, PickedFile, ScannedCode, FilesApi, HomeScreenShortcut, ShortcutsApi, WidgetsApi, OrientationApi, AppleSignInResult, AppleSignInOptions, AuthApi, StoreProduct, StoreTransaction, StoreKitApi, StatusBarStyle, OrientationLock, ActionSheetOptions, AlertOptions, ChoiceOptions, ConfirmOptions, ContextMenuItem, ContextMenuOptions, DialogAction, DialogActionStyle, NativeRect, isShown, observeNativeRefresh, NativeRefreshOptions, sheetStops, settleSheet, rubberBand, observeSheetDrag, liftToBody, presentPageAsCard, SHEET_FLICK_VELOCITY, SheetStop, SheetDragOptions, SheetDetent, SheetSettle, presentChoice, presentAlert, presentConfirm, presentActionSheet, placeMenu, presentContextMenu, applyAppearance, pageBackground, pageIsDark, installNativeChrome, NativeChromeOptions, readSpotlightKinds, spotlightKind, spotlightAction, spotlightSlot, spotlightActions, spotlightActivityTypes, spotlightTitle, placeSpotlightItem, removeSpotlightItem, spotlightRoute, readSpotlightEntries, spotlightBridge, createSpotlightIndex, onSpotlightTap, MAX_SPOTLIGHT_SLOTS_PER_KIND, SpotlightKind, SpotlightKindInput, SpotlightItem, SpotlightEntry, SpotlightKindsResult, SpotlightPlacement, SpotlightBridge, SpotlightIndexOptions, SpotlightIndex, readTabLinks, nativeTabs, routerHandlesTabs, handleTabReselect, coverTabBar, mirrorTabBar, tabBar, TAB_BAR_COVER_EVENT, TabBarApi, TabLink, TabReselectOptions, MirrorTabBarOptions, CraftMobileCapabilities, CraftMobileBridge, CraftReadyEvent, MobileApi, DeviceInfo, DeviceCapabilities, CameraOptions, PhotoResult, Location, LocationOptions, LocationRecordingState, LocationRecordingResult, ShareOptions, NotificationOptions, DeviceApi, HapticsApi, PermissionsApi, CameraApi, BiometricsApi, SecureStorageApi, LocationApi, ShareApi, LifecycleApi, NotificationsApi, KeepAwakeApi, BrightnessApi, SpeechOptions, SpeechApi, NowPlaying, MusicSkipOptions, HeartRateDevice, HeartRateRecordingState, HeartRateState, HeartRateReading, HeartRateSample, HeartRateRecordingApi, HeartRateApi, MusicApi, DeepLinksApi, SnapshotsApi, NetworkStatus, NetworkApi, AppReviewApi, PushNotificationsApi, HealthDataOptions, HealthDataResult, HealthWorkoutLocation, HealthWorkout, HealthWorkoutResult, HealthWorkoutQuery, HealthWorkoutSample, HealthDailyValue, HealthSampleQuery, HealthHeartRateQuery, HealthHeartRateSample, HealthSleepInterval, HealthMindfulSession, HealthMindfulSessionResult, HealthMindfulSessionQuery, HealthMindfulSample, HealthHeartRateUpdatesOptions, HealthAuthorizationOptions, HealthApi, LiveActivityState, LiveActivityOptions, LiveActivitiesApi, WatchConnectivityApi, HapticStyle, HapticNotificationType, PermissionType, PermissionStatus, BiometricType, AppState, HapticKind, MusicAuthorization, MusicPlaybackState, MusicMethod, HeartRateAuthorization, BluetoothState, HeartRateConnection, HeartRateMethod, HealthDataType, HealthDailyType, HealthWorkoutType, HealthWorkoutActivity, HealthSleepStage, HealthReadMethod };
2009
+ // From: src/storage.ts
2010
+ declare function supportsCompareAndSet(): boolean;
2011
+ declare function supportsSetIfAbsent(): boolean;
2012
+ declare const storage: StorageApi;
2013
+
2014
+ // From: src/crypto.ts
2015
+ declare const crypto: CryptoApi;
2016
+
2017
+ export { normalizeDeepLinkURL, getNativeMobileBridge, isNativeMobile, whenNativeMobile, onMobileReady, withNativeFeedback, biometrics, camera, device, lifecycle, location, notifications, permissions, secureStorage, share, appReview, haptics, deepLinks, snapshots, keepAwake, brightness, music, heartRate, speech, network, pushNotifications, health, liveActivities, watchConnectivity, splash, mobile, craftHost, craftRoot, hasNativeMobileHost, bridgePending, whenBridgeReady, nativeFunctionNow, nativeFunction, callNative, afterBridge, subscribeWhenReady, onCraftEvent, BRIDGE_WAIT_MS, CraftHost, CallNativeOptions, observeLongPress, segmentAt, observeSegmentScrub, segmentForKey, focusSegment, installPressables, LongPressOptions, SegmentScrubOptions, keepBreadcrumb, crashReporting, CrashReportingOptions, currentAppearance, normalizeAppearance, onAppearance, onResume, onMemoryWarning, onSilentPush, onBackgroundRefresh, NativeAppearance, pageScrollTop, observePageScroll, pullDistance, observePullToRefresh, largeTitleMetrics, observeLargeTitle, resolveScrollHost, ScrollHost, PullToRefreshOptions, LargeTitleMetrics, LargeTitleOptions, canGoBack, goBack, enterNavTrail, backLabelFor, navTrail, previousScreenPath, goBackToTabRoot, trailEntryFor, deepLinkPath, followDeepLinks, HistoryHost, NavTrailEntry, TabRootHost, attachHeartRate, fixDistance, usableFixes, routeStats, paceLabel, speedLabel, createRouteRecorder, HEART_RATE_MATCH_MS, ROUTE_GAP_S, RouteFix, RouteStats, RouteStatsOptions, RouteRecorderOptions, RouteRecorder, scheduledWorkoutsUnsupported, normalizeScheduledWorkout, scheduledWorkouts, AppleWorkoutStep, AppleIntervalBlock, AppleCustomWorkout, AppleWorkoutPlan, ScheduledWorkout, ScheduleWorkoutResult, ScheduledWorkoutsApi, ScheduledWorkoutsAuthorization, AppleWorkoutGoal, AppleWorkoutAlert, ScheduledWorkoutsMethod, startSessionClock, pauseSessionClock, resumeSessionClock, sessionClockElapsed, SessionClock, indoorVerdict, typedDistanceKm, INDOOR_CHECK_AFTER_S, IndoorFix, IndoorVerdict, toNativeRect, useActionSheet, confirmAction, showContextMenuFor, dialog, contextMenu, browser, symbols, statusBar, chrome, refresh, background, clipboard, db, files, shortcuts, widgets, orientation, auth, storeKit, DialogApi, ConfirmActionOptions, ContextMenuApi, BrowserOpenOptions, BrowserResult, BrowserApi, SymbolOptions, SymbolsApi, StatusBarApi, ChromeApi, RefreshApi, BackgroundApi, ClipboardApi, DatabaseExecuteResult, DatabaseApi, PickedFile, ScannedCode, FilesApi, HomeScreenShortcut, ShortcutsApi, WidgetsApi, OrientationApi, AppleSignInResult, AppleSignInOptions, AuthApi, StoreProduct, StoreTransaction, StoreKitApi, StatusBarStyle, OrientationLock, ActionSheetOptions, AlertOptions, ChoiceOptions, ConfirmOptions, ContextMenuItem, ContextMenuOptions, DialogAction, DialogActionStyle, NativeRect, isShown, observeNativeRefresh, NativeRefreshOptions, sheetStops, settleSheet, rubberBand, observeSheetDrag, liftToBody, presentPageAsCard, SHEET_FLICK_VELOCITY, SheetStop, SheetDragOptions, SheetDetent, SheetSettle, presentChoice, presentAlert, presentConfirm, presentActionSheet, placeMenu, presentContextMenu, applyAppearance, pageBackground, pageIsDark, installNativeChrome, NativeChromeOptions, readSpotlightKinds, spotlightKind, spotlightAction, spotlightSlot, spotlightActions, spotlightActivityTypes, spotlightTitle, placeSpotlightItem, removeSpotlightItem, spotlightRoute, readSpotlightEntries, spotlightBridge, createSpotlightIndex, onSpotlightTap, MAX_SPOTLIGHT_SLOTS_PER_KIND, SpotlightKind, SpotlightKindInput, SpotlightItem, SpotlightEntry, SpotlightKindsResult, SpotlightPlacement, SpotlightBridge, SpotlightIndexOptions, SpotlightIndex, readTabLinks, nativeTabs, routerHandlesTabs, handleTabReselect, coverTabBar, mirrorTabBar, tabBar, TAB_BAR_COVER_EVENT, TabBarApi, TabLink, TabReselectOptions, MirrorTabBarOptions, CraftMobileCapabilities, CraftMobileBridge, CraftReadyEvent, MobileApi, DeviceInfo, DeviceCapabilities, CameraOptions, PhotoResult, Location, LocationOptions, LocationRecordingState, RecordingStartOptions, LocationRecordingOptions, LocationRecordingResult, ShareOptions, NotificationOptions, DeviceApi, HapticsApi, PermissionsApi, CameraApi, BiometricsApi, StorageApi, CryptoApi, SecureStorageApi, RecordingOwnershipOptions, LocationApi, ShareApi, LifecycleApi, NotificationsApi, KeepAwakeApi, BrightnessApi, SpeechOptions, SpeechApi, NowPlaying, MusicSkipOptions, HeartRateDevice, HeartRateRecordingState, HeartRateState, HeartRateReading, HeartRateSample, HeartRateRecordingApi, HeartRateApi, MusicApi, DeepLinksApi, SnapshotsApi, NetworkStatus, NetworkApi, AppReviewApi, PushNotificationsApi, HealthDataOptions, HealthDataResult, HealthWorkoutLocation, HealthWorkout, HealthWorkoutResult, HealthWorkoutQuery, HealthWorkoutSample, HealthDailyValue, HealthSampleQuery, HealthHeartRateQuery, HealthHeartRateSample, HealthSleepInterval, HealthMindfulSession, HealthMindfulSessionResult, HealthMindfulSessionQuery, HealthMindfulSample, HealthHeartRateUpdatesOptions, HealthAuthorizationOptions, HealthApi, LiveActivityState, LiveActivityOptions, LiveActivitiesApi, WatchConnectivityApi, HapticStyle, HapticNotificationType, PermissionType, PermissionStatus, BiometricType, AppState, HapticKind, MusicAuthorization, MusicPlaybackState, MusicMethod, HeartRateAuthorization, BluetoothState, HeartRateConnection, HeartRateMethod, HealthDataType, HealthDailyType, HealthWorkoutType, HealthWorkoutActivity, HealthSleepStage, HealthReadMethod, storage, crypto };
1962
2018
  export { NativeTab } from 'craft-native/mobile';
1963
2019
  export { NativeTabBarOptions } from 'craft-native/mobile';
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import{appReview as Bn,biometrics as Le,brightness as le,camera as ce,deepLinks as wt,device as D,haptics as ue,health as J,heartRate as A,keepAwake as At,lifecycle as _n,liveActivities as Pe,location as H,music as O,network as kt,notifications as de,permissions as Z,pushNotifications as Me,secureStorage as pe,share as Rt,speech as Ce,snapshots as fe,splash as Dn,watchConnectivity as ee}from"craft-native/mobile";var cr=2500;function S(){if(typeof window>"u")return;return window}function be(){let e=S()?.craft;return e&&typeof e==="object"?e:void 0}function Lt(){return typeof navigator>"u"?"":navigator.userAgent||""}function q(){let e=S();if(!e)return!1;if(e.CraftAndroid)return!0;return Boolean(e.webkit?.messageHandlers?.craft)&&/iPhone|iPad|iPod/.test(Lt())}function te(){let e=S();if(!e||e.craft)return!1;return q()||Boolean(e.webkit?.messageHandlers?.craft)}function F(e=15000){let t=S();if(t?.craft)return Promise.resolve(!0);if(!t||!te())return Promise.resolve(!1);return new Promise((n)=>{let r=()=>{clearTimeout(o),t.removeEventListener("craftReady",r),n(Boolean(t.craft))},o=setTimeout(r,e);t.addEventListener("craftReady",r)})}function Pt(e,t){if(!e)return null;let n=t.split("."),r=e;for(let i of n.slice(0,-1))if(r=r?.[i],!r||typeof r!=="object"&&typeof r!=="function")return null;let o=r?.[n[n.length-1]];return typeof o==="function"?o.bind(r):null}function L(e){return Pt(be(),e)}async function Mt(e,t=2500){let n=L(e);if(n||!te())return n;return await F(t),L(e)}async function b(e,t,n,r={}){let o=await Mt(e,r.timeoutMs);if(!o)return n();try{return await o(...t)}catch(i){if(r.fallbackOnError)return n();throw i}}async function c(e,t=2500){if(te())await F(t);return e()}function _(e,t=2500){let n,r=!1;if(!te())n=e();else F(t).then(()=>{if(!r)n=e()});return()=>{if(r=!0,typeof n==="function")n()}}function M(e,t){let n=S();if(!n)return()=>{};let r=(o)=>t(o.detail??{});return n.addEventListener(e,r),()=>n.removeEventListener(e,r)}var Ne="native-dialog-styles",Ct=`
1
+ import{appReview as Qn,biometrics as De,brightness as be,camera as ve,deepLinks as Mt,device as Y,haptics as ye,health as se,heartRate as R,keepAwake as Nt,lifecycle as Jn,liveActivities as _e,location as N,music as B,network as Ht,notifications as Se,permissions as le,pushNotifications as Be,secureStorage as we,share as Dt,speech as Fe,snapshots as xe,splash as Zn,watchConnectivity as ce}from"craft-native/mobile";var Rr=2500;function A(){if(typeof window>"u")return;return window}function V(){let e=A()?.craft;return e&&typeof e==="object"?e:void 0}function $t(){return typeof navigator>"u"?"":navigator.userAgent||""}function ee(){let e=A();if(!e)return!1;if(e.CraftAndroid)return!0;return Boolean(e.webkit?.messageHandlers?.craft)&&/iPhone|iPad|iPod/.test($t())}function ue(){let e=A();if(!e||e.craft)return!1;return ee()||Boolean(e.webkit?.messageHandlers?.craft)}function X(e=15000){let t=A();if(t?.craft)return Promise.resolve(!0);if(!t||!ue())return Promise.resolve(!1);return new Promise((n)=>{let r=()=>{clearTimeout(o),t.removeEventListener("craftReady",r),n(Boolean(t.craft))},o=setTimeout(r,e);t.addEventListener("craftReady",r)})}function Kt(e,t){if(!e)return null;let n=t.split("."),r=e;for(let i of n.slice(0,-1))if(r=r?.[i],!r||typeof r!=="object"&&typeof r!=="function")return null;let o=r?.[n[n.length-1]];return typeof o==="function"?o.bind(r):null}function C(e){return Kt(V(),e)}async function jt(e,t=2500){let n=C(e);if(n||!ue())return n;return await X(t),C(e)}async function b(e,t,n,r={}){let o=await jt(e,r.timeoutMs);if(!o)return n();try{return await o(...t)}catch(i){if(r.fallbackOnError)return n();throw i}}async function u(e,t=2500){if(ue())await X(t);return e()}function G(e,t=2500){let n,r=!1;if(!ue())n=e();else X(t).then(()=>{if(!r)n=e()});return()=>{if(r=!0,typeof n==="function")n()}}function D(e,t){let n=A();if(!n)return()=>{};let r=(o)=>t(o.detail??{});return n.addEventListener(e,r),()=>n.removeEventListener(e,r)}var Ue="native-dialog-styles",qt=`
2
2
  .native-dialog { position: fixed; inset: 0; z-index: 2147483000; font-size: var(--native-font-size, 17px); font-family: var(--native-font-family, -apple-system, system-ui, sans-serif); -webkit-tap-highlight-color: transparent; }
3
3
  .native-dialog-backdrop { position: absolute; inset: 0; background: rgb(0 0 0 / 0.3); opacity: 0; transition: opacity 220ms ease; }
4
4
  .native-dialog--menu .native-dialog-backdrop { background: rgb(0 0 0 / 0.12); -webkit-backdrop-filter: blur(14px) saturate(140%); backdrop-filter: blur(14px) saturate(140%); }
@@ -52,4 +52,4 @@ import{appReview as Bn,biometrics as Le,brightness as le,camera as ce,deepLinks
52
52
  .native-dialog-group, .native-menu { -webkit-backdrop-filter: none; backdrop-filter: none; background: var(--native-dialog-solid, rgb(242 242 247)); }
53
53
  .dark .native-dialog-group, .dark .native-menu { background: var(--native-dialog-solid-dark, rgb(44 44 46)); }
54
54
  }
55
- `;function Ie(){return S()?.document}function Ot(e){if(e.getElementById(Ne))return;let t=e.createElement("style");t.id=Ne,t.textContent=Ct,(e.head??e.documentElement).appendChild(t)}var Nt=0;function R(e,t,n,r){let o=e.createElement(t);if(o.className=n,r!==void 0)o.textContent=r;return o}function He(){return S()?.stx?.overlays}var Ht=0;function Be(e,t,n,r){Ot(e);let o=S(),i=`native-dialog-layer-${++Ht}`,a=R(e,"div",`native-dialog native-dialog--${t}`);return a.setAttribute("data-native-dialog",t),a.appendChild(R(e,"div","native-dialog-backdrop")),new Promise((s)=>{let l=!1,f=(u)=>{if(l)return;l=!0,a.classList.remove("is-open"),He()?.close(i),setTimeout(()=>a.remove(),260),s(u)},p=n({root:a,settle:f});a.appendChild(p),e.body.appendChild(a),He()?.open(i,{panel:p,root:a,onEscape:()=>f(r())});let d=o;(typeof d?.requestAnimationFrame==="function"?(u)=>d.requestAnimationFrame(()=>d.requestAnimationFrame(u)):(u)=>setTimeout(u,16))(()=>{if(!l)a.classList.add("is-open")})})}function ve(e){let t=Ie();if(!t?.body)return Promise.resolve(null);let n=`native-dialog-${++Nt}`,r=e.actions.find((a)=>a.style==="cancel"),o=e.variant==="sheet"?e.actions.filter((a)=>a.style!=="cancel"):e.actions,i=e.variant==="sheet"?r??{id:"__cancel",title:e.cancelLabel||"Cancel",style:"cancel"}:void 0;return Be(t,e.variant,({root:a,settle:s})=>{let l=(u)=>u.style==="cancel"?null:u.id,f=R(t,"div","native-dialog-panel");f.setAttribute("role","alertdialog"),f.setAttribute("aria-modal","true"),f.tabIndex=-1;let p=R(t,"div","native-dialog-group");if(e.title||e.message){let u=R(t,"div","native-dialog-header");if(e.title){let m=R(t,"p","native-dialog-title",e.title);m.id=`${n}-title`,u.appendChild(m),f.setAttribute("aria-labelledby",m.id)}if(e.message){let m=R(t,"p","native-dialog-message",e.message);m.id=`${n}-message`,u.appendChild(m),f.setAttribute("aria-describedby",m.id)}p.appendChild(u)}let d=R(t,"div","native-dialog-actions");if(e.variant==="alert"&&o.length===2)d.classList.add("is-row");for(let u of o){let m=R(t,"button",`native-dialog-action${u.style==="destructive"?" is-destructive":""}${u.style==="cancel"?" is-cancel":""}`,u.title);m.type="button",m.setAttribute("data-action-id",u.id),m.addEventListener("click",()=>s(l(u))),d.appendChild(m)}if(p.appendChild(d),f.appendChild(p),i){let u=R(t,"div","native-dialog-group"),m=R(t,"button","native-dialog-action is-cancel",i.title);m.type="button",m.setAttribute("data-action-id",i.id),m.addEventListener("click",()=>s(null)),u.appendChild(m),f.appendChild(u)}let g=a.querySelector(".native-dialog-backdrop");if(e.variant==="sheet")g?.addEventListener("click",()=>s(null));return f},()=>{if(e.variant==="sheet")return null;if(r)return null;return o.length===1?o[0].id:null})}async function _e(e){await ve({variant:"alert",title:e.title,message:e.message,actions:[{id:"ok",title:e.okLabel||"OK"}]})}async function De(e){return await ve({variant:"alert",title:e.title,message:e.message,actions:[{id:"cancel",title:e.cancelLabel||"Cancel",style:"cancel"},{id:"confirm",title:e.confirmLabel||"OK",style:e.destructive?"destructive":"default"}]})==="confirm"}function Fe(e){return ve({variant:"sheet",title:e.title,message:e.message,actions:e.actions,cancelLabel:e.cancelLabel})}function It(e,t,n){let i=Math.max(12,Math.min(e.x,n.width-t.width-12)),a=e.y+e.height+8,s=a+t.height<=n.height-12,l=e.y-8-t.height,f=s||l<12?Math.max(12,Math.min(a,n.height-t.height-12)):l,p=e.x+e.width/2>n.width/2?"right":"left";return{top:f,left:i,origin:`${s||l<12?"top":"bottom"} ${p}`}}function We(e){let t=Ie();if(!t?.body)return Promise.resolve(null);let n=S();return Be(t,"menu",({root:r,settle:o})=>{let i=R(t,"div","native-menu native-dialog-panel");if(i.setAttribute("role","menu"),e.title)i.appendChild(R(t,"p","native-menu-title",e.title)),i.setAttribute("aria-label",e.title);for(let a of e.items){let s=R(t,"button",`native-menu-item${a.destructive?" is-destructive":""}`);if(s.type="button",s.setAttribute("role","menuitem"),s.setAttribute("data-action-id",a.id),a.disabled)s.disabled=!0;if(s.appendChild(R(t,"span","native-menu-label",a.title)),a.icon){let l=R(t,"i",`native-menu-icon ${a.icon}`);l.setAttribute("aria-hidden","true"),s.appendChild(l)}s.addEventListener("click",()=>o(a.id)),i.appendChild(s)}return r.querySelector(".native-dialog-backdrop")?.addEventListener("click",()=>o(null)),queueMicrotask(()=>{let a=i.getBoundingClientRect?.(),s=It(e.anchor,{width:a?.width||248,height:a?.height||e.items.length*44},{width:n?.innerWidth||390,height:n?.innerHeight||844});i.style.top=`${s.top}px`,i.style.left=`${s.left}px`,i.style.setProperty("--native-menu-origin",s.origin)}),i},()=>null)}var Ue=()=>!0,T=()=>!1,C=()=>null;function $e(){return S()?.navigator??(typeof navigator>"u"?void 0:navigator)}function we(e){return{x:Math.round(e.x??e.left??0),y:Math.round(e.y??e.top??0),width:Math.round(e.width),height:Math.round(e.height)}}var j={alert:(e)=>b("dialog.alert",[e],()=>_e(e),{fallbackOnError:!0}).then(()=>{}),confirm:(e)=>b("dialog.confirm",[e],()=>De(e),{fallbackOnError:!0}).then(Boolean),actionSheet:async(e)=>{let t={...e,anchor:e.anchor?we(e.anchor):void 0},n=await b("dialog.actionSheet",[t],()=>Fe(e),{fallbackOnError:!0});if(typeof n!=="string")return null;return e.actions.find((r)=>r.id===n)?.style==="cancel"?null:n}};function gr(){return(e)=>j.actionSheet(e)}async function hr(e){if((e.style??(e.destructive?"sheet":"alert"))==="alert")return j.confirm(e);return await j.actionSheet({title:e.title,message:e.message,anchor:e.anchor,actions:[{id:"confirm",title:e.confirmLabel||"OK",style:e.destructive?"destructive":"default"},{id:"cancel",title:e.cancelLabel||"Cancel",style:"cancel"}]})==="confirm"}var Ae={show:async(e)=>{let t={title:e.title,anchor:we(e.anchor),items:e.items.map(({id:r,title:o,symbol:i,destructive:a,disabled:s})=>({id:r,title:o,symbol:i,destructive:a,disabled:s}))},n=await b("contextMenu.show",[t],()=>We(e),{fallbackOnError:!0});return typeof n==="string"?n:null}};function br(e,t){return Ae.show({...t,anchor:we(e.getBoundingClientRect())})}function Bt(e,t){let n=S();if(!n)return{cancelled:!0};if(typeof n.craft?.openURL==="function")return Promise.resolve(n.craft.openURL(e)).catch(()=>{}),{cancelled:!1};if(t.mode==="auth")return n.location?.assign(e),{cancelled:!1};if(!(typeof n.open==="function"?n.open(e,"_blank","noopener"):null))n.location?.assign(e);return{cancelled:!1}}var qe={open:async(e,t={})=>{let n=await b("browser.open",[e,t],()=>Bt(e,t),{fallbackOnError:!0});if(!n||typeof n!=="object")return{cancelled:!1};let{url:r,cancelled:o}=n;return typeof r==="string"?{url:r,cancelled:Boolean(o)}:{cancelled:Boolean(o)}}},ye=new Map,Se=new Map;function Ke(e,t){return`${e}|${t.pointSize??""}|${t.weight??""}|${t.color??""}|${t.scale??""}`}var je={isAvailable:()=>L("symbols.image")!==null,image:(e,t={})=>{let n=Ke(e,t),r=ye.get(n);if(r)return r;let o=b("symbols.image",[e,t],C).then((i)=>typeof i==="string"&&i.startsWith("data:")?i:null,C).then((i)=>(Se.set(n,i),i));return ye.set(n,o),o},cached:(e,t={})=>Se.get(Ke(e,t)),clearCache:()=>{ye.clear(),Se.clear()}},ne={setStyle:(e)=>b("statusBar.setStyle",[e],T,{fallbackOnError:!0}).then((t)=>t!==!1)},Y={setUnderPageColor:(e)=>b("chrome.setUnderPageColor",[e],T,{fallbackOnError:!0}).then((t)=>t!==!1),setKeyboardAccessory:(e)=>b("chrome.setKeyboardAccessory",[e],T,{fallbackOnError:!0}).then((t)=>t!==!1)},I={isAvailable:()=>L("refresh.enable")!==null,enable:(e)=>b("refresh.enable",[e??{}],T,{fallbackOnError:!0}).then((t)=>t!==!1),disable:()=>b("refresh.disable",[],T,{fallbackOnError:!0}).then((e)=>e!==!1),end:()=>b("refresh.end",[],T,{fallbackOnError:!0}).then((e)=>e!==!1),onRefresh:(e)=>M("craftRefresh",()=>e())},G={complete:(e)=>b("background.complete",[e],T,{fallbackOnError:!0}).then((t)=>t!==!1)},Ye={write:(e)=>b("clipboard.write",[e],async()=>{let t=$e()?.clipboard;if(!t?.writeText)return!1;return t.writeText(e).then(Ue,T)},{fallbackOnError:!0}).then((t)=>t!==!1),read:()=>b("clipboard.read",[],async()=>{let e=$e()?.clipboard;if(!e?.readText)return null;return e.readText().catch(C)},{fallbackOnError:!0}).then((e)=>typeof e==="string"?e:null)},Ge={isAvailable:()=>L("db.query")!==null,query:(e,t=[])=>b("db.query",[e,t],C).then((n)=>Array.isArray(n)?n:null),execute:(e,t=[])=>b("db.execute",[e,t],C).then((n)=>{if(!n||typeof n!=="object")return null;let{rowsAffected:r,lastInsertId:o}=n;return{rowsAffected:Number(r)||0,lastInsertId:Number(o)||0}})};function xe(e,t){let n=S()?.document;if(!n?.body)return null;let r=n.createElement("a");return r.href=e,r.download=t,r.rel="noopener",r.style.display="none",n.body.appendChild(r),r.click(),r.remove(),t}function _t(e){let t=S()?.document;if(!t?.body)return Promise.resolve(null);return new Promise((n)=>{let r=t.createElement("input");if(r.type="file",r.style.display="none",e.length)r.accept=e.map((i)=>i.includes("/")||i.startsWith(".")?i:`.${i}`).join(",");let o=(i)=>{r.remove(),n(i)};r.addEventListener("cancel",()=>o(null)),r.addEventListener("change",()=>{let i=r.files?.[0];if(!i)return o(null);let a=new FileReader;a.onload=()=>o({name:i.name,mimeType:i.type||void 0,data:typeof a.result==="string"?a.result:void 0}),a.onerror=()=>o({name:i.name,mimeType:i.type||void 0}),a.readAsDataURL(i)}),t.body.appendChild(r),r.click()})}var Ve={openPDF:(e,t=0)=>b("openPDF",[e,t],()=>{let n=S();return Boolean(n?.open?.(e,"_blank","noopener"))}).then((n)=>n!==!1),takeScreenshot:()=>b("takeScreenshot",[],C,{fallbackOnError:!0}).then((e)=>typeof e==="string"?e:null),scanQRCode:()=>b("scanQRCode",[],C).then((e)=>{if(!e||typeof e!=="object")return null;let{type:t,data:n}=e;return typeof n==="string"?{type:String(t??""),data:n}:null},C),pickFile:(e=[])=>b("pickFile",[e],()=>_t(e)).then((t)=>{if(!t||typeof t!=="object")return null;let n=t;if(typeof n.name!=="string")return null;return{name:n.name,path:typeof n.path==="string"?n.path:void 0,data:typeof n.data==="string"?n.data:void 0,mimeType:typeof n.mimeType==="string"?n.mimeType:void 0}},C),saveFile:(e,t,n)=>b("saveFile",[e,t,n],()=>{if(e.startsWith("data:"))return xe(e,t);let r=new Blob([e],{type:n||"text/plain"}),o=URL.createObjectURL(r),i=xe(o,t);return setTimeout(()=>URL.revokeObjectURL(o),1000),i}).then((r)=>typeof r==="string"?r:null),downloadFile:(e,t)=>b("downloadFile",[e,t],()=>xe(e,t)).then((n)=>typeof n==="string"?n:null)},Xe={set:(e)=>b("shortcuts.set",[e.map(({symbol:t,...n})=>t?{...n,iconName:t}:n)],T).then((t)=>t!==!1),clear:()=>b("shortcuts.clear",[],T).then((e)=>e!==!1),onShortcut:(e)=>M("craftShortcut",(t)=>{if(typeof t.type==="string")e(t.type)})},Qe={update:(e)=>b("widget.update",[e],T).then((t)=>t!==!1),reload:()=>b("widget.reload",[],T).then((e)=>e!==!1)},Dt={portrait:"portrait-primary",portraitUpsideDown:"portrait-secondary",landscape:"landscape",landscapeLeft:"landscape-primary",landscapeRight:"landscape-secondary"};function ze(){return S()?.screen?.orientation}var Je={lock:(e)=>b("lockOrientation",[e],()=>{let t=ze();return t?.lock?t.lock(Dt[e]).then(Ue,T):!1}).then((t)=>t!==!1),unlock:()=>b("unlockOrientation",[],()=>(ze()?.unlock?.(),!0)).then((e)=>e!==!1)},Ze={signInWithApple:(e={})=>b("signInWithApple",e.nonce?[{nonce:e.nonce}]:[],C).then((t)=>{if(!t||typeof t!=="object"||typeof t.userId!=="string")return null;return t})},et={isAvailable:()=>L("iap.purchase")!==null,products:(e)=>b("iap.getProducts",[e],()=>[]).then((t)=>Array.isArray(t)?t:[]),purchase:(e)=>b("iap.purchase",[e],C).then((t)=>t&&typeof t==="object"?t:null,(t)=>{if(/cancel/i.test(String(t?.message??t)))return null;throw t}),restore:()=>b("iap.restore",[],()=>[]).then((e)=>Array.isArray(e)?e:[])};var Ft=["authorized","denied","notDetermined","restricted","unsupported"];function re(){let e=be(),t=e?.scheduledWorkouts;if(!t||typeof t!=="object"||e?.capabilities?.scheduledWorkouts!==!0)return;return t}function Wt(){return Object.assign(Error("unsupported"),{code:"UNSUPPORTED"})}function tt(e){return Ft.includes(e)?e:"unsupported"}function $t(e){if(!e||typeof e!=="object")return null;let t=e;if(typeof t.id!=="string"||!t.id||typeof t.date!=="string"||!/^\d{4}-\d{2}-\d{2}$/.test(t.date))return null;let n={id:t.id.toLowerCase(),date:t.date,complete:t.complete===!0};if(typeof t.hour==="number"&&Number.isFinite(t.hour))n.hour=t.hour;if(typeof t.minute==="number"&&Number.isFinite(t.minute))n.minute=t.minute;return n}function W(e,t,...n){return c(async()=>{let r=re();if(typeof r?.[e]!=="function")throw Wt();return t(await r[e](...n))})}var nt={isAvailable:()=>typeof re()?.isSupported==="function",supports:(e)=>typeof re()?.[e]==="function",isSupported:()=>c(async()=>{let e=re();if(typeof e?.isSupported!=="function")return!1;try{return await e.isSupported()===!0}catch{return!1}}),authorization:()=>W("authorization",tt),requestAuthorization:()=>W("requestAuthorization",tt),list:()=>W("list",(e)=>Array.isArray(e)?e.map($t).filter((t)=>t!==null):[]),schedule:(e)=>{if(!e||typeof e!=="object"||typeof e.id!=="string")return Promise.reject(Object.assign(Error("schedule needs a plan with an id"),{code:"INVALID_ARGUMENT"}));return W("schedule",(t)=>{let n=t&&typeof t==="object"?t:{},r={id:(typeof n.id==="string"?n.id:e.id).toLowerCase()};if(Array.isArray(n.droppedAlerts)&&n.droppedAlerts.length)r.droppedAlerts=n.droppedAlerts.filter((o)=>typeof o==="string");return r},e)},remove:(e)=>W("remove",(t)=>t===!0,e),removeAll:()=>W("removeAll",(e)=>typeof e==="number"&&Number.isFinite(e)?e:0)};function wr(e,t){let n=t.delay??500,r=t.tolerance??10,o=null,i=null,a=!1,s=()=>{if(o)clearTimeout(o);if(o=null,i&&!a)t.onPressEnd?.();i=null},l=(g)=>{let u=g;if(u.button!==void 0&&u.button!==0)return;a=!1,i={x:u.clientX,y:u.clientY},t.onPressStart?.(),o=setTimeout(()=>{if(o=null,!i)return;a=!0,t.onLongPress({...i}),i=null},n)},f=(g)=>{if(!i)return;let u=g;if(Math.hypot(u.clientX-i.x,u.clientY-i.y)>r)s()},p=(g)=>{if(!a)return;a=!1,g.preventDefault(),g.stopPropagation()},d=(g)=>g.preventDefault();return e.addEventListener("pointerdown",l),e.addEventListener("pointermove",f),e.addEventListener("pointerup",s),e.addEventListener("pointercancel",s),e.addEventListener("pointerleave",s),e.addEventListener("click",p,!0),e.addEventListener("contextmenu",d),()=>{s(),e.removeEventListener("pointerdown",l),e.removeEventListener("pointermove",f),e.removeEventListener("pointerup",s),e.removeEventListener("pointercancel",s),e.removeEventListener("pointerleave",s),e.removeEventListener("click",p,!0),e.removeEventListener("contextmenu",d)}}function Kt(e,t,n){if(n<=1||t.width<=0)return 0;let r=Math.floor((e-t.left)/t.width*n);return Math.max(0,Math.min(n-1,r))}function Ar(e,t){let n=null,r=null,o=!1,i=0,a=(u)=>{let m=e.getBoundingClientRect();return Kt(u,{left:m.left+2,width:m.width-4},t.count())},s=(u)=>{let m=u;if(m.button!==void 0&&m.button!==0)return;let v=a(m.clientX);if(v!==t.selected())return;n=v,i=v,o=!1,r=m.pointerId;try{e.setPointerCapture?.(m.pointerId)}catch{}t.onPress?.(!0)},l=(u)=>{if(n===null)return;let m=a(u.clientX);if(m===i)return;o=!0,i=m,t.onScrub(m)},f=(u)=>{if(n===null)return;if(r!==null)try{e.releasePointerCapture?.(r)}catch{}if(t.onPress?.(!1),u&&o)t.onCommit(i);else if(o)t.onScrub(n);n=null,r=null},p=(u)=>{if(!o)return;o=!1,u.preventDefault(),u.stopPropagation()},d=()=>f(!0),g=()=>f(!1);return e.addEventListener("pointerdown",s),e.addEventListener("pointermove",l),e.addEventListener("pointerup",d),e.addEventListener("pointercancel",g),e.addEventListener("click",p,!0),()=>{e.removeEventListener("pointerdown",s),e.removeEventListener("pointermove",l),e.removeEventListener("pointerup",d),e.removeEventListener("pointercancel",g),e.removeEventListener("click",p,!0)}}function kr(e,t,n){if(n<=0)return null;switch(e){case"ArrowRight":case"ArrowDown":return(t+1)%n;case"ArrowLeft":case"ArrowUp":return(t-1+n)%n;case"Home":return 0;case"End":return n-1;default:return null}}function Rr(e,t){e.querySelectorAll('[role="tab"]')[t]?.focus()}function Er(e){let t=(n)=>{if(!n.target?.closest?.("[data-native-pressable]"))return;let o=L("haptics.prepare");if(o)Promise.resolve().then(()=>o("impact")).catch(()=>{})};return e.addEventListener("touchstart",t,{passive:!0,capture:!0}),()=>e.removeEventListener("touchstart",t,{capture:!0})}import{BugHQClient as zt}from"@bughq/sdk";import{crashReporter as K}from"craft-native/mobile";var P=null;function Ut(e){if(e.type!=="http")return!0;let t=e.data??{},n=typeof t.status==="number"?t.status:0;return t.error===!0||n>=400||n===0}function rt(){return K.isAvailable()}function qt(e){return async(t)=>{if(!rt())return!e;return K.capture(t)}}var Cr={start(e={}){if(P)return P;let t=q()||rt();if(!t&&!e.key&&!e.dsn)return null;let n=e.beforeBreadcrumb;return P=new zt({framework:"stacks-mobile",sdkName:"bughq.stacks.mobile",autoInstrument:{navigation:!0,fetch:!0,xhr:!0},...e,heartbeat:t?!1:e.heartbeat,transport:t?qt(Boolean(e.key||e.dsn)):void 0,beforeBreadcrumb(r){if(!Ut(r))return null;let o=n?n(r):r;if(o===null)return null;let i=o||r;if(t)K.addBreadcrumb(i);return i}}),P},async setUser(e){let t=e===null||e===void 0||e===""?null:String(e);P?.setUser(t===null?null:{id:t}),await K.setUser(t)},capture(e,t){P?.captureException(e,t)},addBreadcrumb(e){if(P)P.addBreadcrumb(e);else K.addBreadcrumb(e)},async flush(){await Promise.all([P?.flush(),K.flush()])},client(){return P},stop(){P?.close(),P=null}};function ke(e){let t=S();try{return Boolean(t?.matchMedia?.(e).matches)}catch{return!1}}function ot(e){return e!==null&&e!==void 0&&e!=="false"&&e!=="0"}function it(){let e=S()?.document?.documentElement,t=Number.parseFloat(e?.style?.getPropertyValue("--craft-font-scale")||"");return{fontScale:Number.isFinite(t)&&t>0?t:1,reduceMotion:ot(e?.getAttribute("data-craft-reduce-motion"))||ke("(prefers-reduced-motion: reduce)"),reduceTransparency:ot(e?.getAttribute("data-craft-reduce-transparency"))||ke("(prefers-reduced-transparency: reduce)"),colorScheme:e?.classList?.contains("dark")||ke("(prefers-color-scheme: dark)")?"dark":"light"}}function jt(e){let t=it(),n=Number(e?.fontScale);return{contentSizeCategory:typeof e?.contentSizeCategory==="string"?e.contentSizeCategory:void 0,fontScale:Number.isFinite(n)&&n>0?n:t.fontScale,reduceMotion:typeof e?.reduceMotion==="boolean"?e.reduceMotion:t.reduceMotion,reduceTransparency:typeof e?.reduceTransparency==="boolean"?e.reduceTransparency:t.reduceTransparency,colorScheme:e?.colorScheme==="dark"||e?.colorScheme==="light"?e.colorScheme:t.colorScheme}}function at(e,t={}){if(t.immediate!==!1)e(it());return M("craftAppearance",(n)=>e(jt(n)))}function Ir(e){return M("craftResume",(t)=>e({backgroundedMs:Number(t.backgroundedMs)||0}))}function Br(e){return M("craftMemoryWarning",()=>e())}function st(e){return(t)=>{Promise.resolve().then(()=>e(t)).then(()=>G.complete(!0),()=>G.complete(!1))}}function _r(e){let t=st(e);return M("craftSilentPush",(n)=>t(n.payload??{}))}function Dr(e){let t=st(()=>e());return M("craftBackgroundRefresh",()=>t(void 0))}import{haptics as Yt}from"craft-native/mobile";function Re(){if(typeof window>"u")return;return window}function V(e=Re()){if(!e)return 0;if(typeof e.scrollY==="number")return e.scrollY;if(typeof e.scrollTop==="number")return e.scrollTop;return e.document?.scrollingElement?.scrollTop??0}function Gt(e,t=Re()){if(!t)return()=>{};let n=!1,r=typeof requestAnimationFrame==="function"?requestAnimationFrame:(i)=>setTimeout(i,16),o=()=>{if(n)return;n=!0,r(()=>{n=!1,e(V(t))})};return e(V(t)),t.addEventListener("scroll",o,{passive:!0}),()=>t.removeEventListener("scroll",o)}function Vt(e,t){let n=Math.max(0,-e),r=e<=0?Math.max(0,t)*0.5:0;return Math.round(Math.max(n,r))}function $r(e){let t=e.host??Re();if(!t)return()=>{};let n=e.threshold??72,r=null,o=!1,i=!1,a=typeof requestAnimationFrame==="function"?requestAnimationFrame:(v)=>setTimeout(v,16),s=null,l=(v)=>{s=null,e.onPull?.(v,o,{bounce:Math.min(v,Math.max(0,-V(t)))})},f=(v)=>{let k=s!==null;if(s=v,k)return;a(()=>{if(s!==null)l(s)})},p=(v)=>{let k=v.touches?.[0];return k?k.clientY:null},d=(v)=>{if(i||V(t)>0)return;r=p(v),o=!1},g=(v)=>{if(r===null)return;let k=p(v);if(k===null)return;let N=Vt(V(t),k-r);if(!o&&N>=n)o=!0,Promise.resolve(Yt.impact("medium")).catch(()=>{});else if(o&&N<n*0.8)o=!1;f(N)},u=async()=>{if(r===null)return;if(r=null,!o){l(0);return}o=!1,i=!0,l(n);try{await e.onRefresh()}finally{i=!1,l(0)}},m=()=>{if(r===null)return;r=null,o=!1,l(0)};return t.addEventListener("touchstart",d,{passive:!0}),t.addEventListener("touchmove",g,{passive:!0}),t.addEventListener("touchend",u),t.addEventListener("touchcancel",m),()=>{s=null,t.removeEventListener("touchstart",d),t.removeEventListener("touchmove",g),t.removeEventListener("touchend",u),t.removeEventListener("touchcancel",m)}}function Xt(e,t=52){let n=Math.max(1,t),r=Math.min(1,Math.max(0,e/n)),o=e<0?1+Math.min(0.1,-e/600):1;return{progress:Math.round(r*1000)/1000,stretch:Math.round(o*1000)/1000}}function Kr(e,t={}){let n="",r=()=>t.title?.offsetHeight||t.height||52;return Gt((o)=>{let i=Xt(o,r()),a=`${i.progress}|${i.stretch}`;if(a===n)return;n=a,e.style.setProperty("--native-nav-progress",String(i.progress)),e.style.setProperty("--native-nav-stretch",String(i.stretch)),t.onChange?.(i)},t.host)}function zr(e){if(!e||typeof window>"u")return;let t=window.document?.querySelector(e);return t?t:void 0}function ut(){if(typeof window>"u")return;return window}var lt="__stxPushed",Qt="__stxScroll";function Jt(e=ut()){let t=e?.history?.state;if(t===null||t===void 0)return!1;if(typeof t!=="object")return!0;let n=t;if(lt in n)return n[lt]===!0;return!(Qt in n)}function qr(e=ut()){if(!Jt(e))return!1;return e.history.back(),!0}function jr(e,t,n=50){let r=e[e.length-1];if(e.length>=2&&e[e.length-2].path===t)e.pop();else if(!r||r.path!==t)e.push({path:t,title:""});if(e.length>n)e.splice(0,e.length-n);return{current:e[e.length-1],previous:e[e.length-2]??null}}function Yr(e,t,n=12){let r=e?.title.trim()??"";return r&&r.length<=n?r:t}function Gr(){if(typeof window>"u")return[];let e=window;return e.__stacksNavTrail??=[]}function Zt(e){try{let t=new URL(e,"http://local");return`${t.pathname}${t.search}`}catch{return e}}function Vr(){if(typeof window>"u")return;let e=window.stxRouter;if(typeof e?.screens!=="function")return;let t=e.screens(),n=t.find((o)=>o.active);if(!n)return;let r=t.filter((o)=>o.tab===n.tab&&o.depth<n.depth);if(!r.length)return null;return Zt(r.reduce((o,i)=>i.depth>o.depth?i:o).url)}function Xr(e=typeof window>"u"?void 0:window){let t=e?.stxRouter;if(typeof t?.screens!=="function"||typeof e?.history?.go!=="function")return!1;let n=t.screens(),r=n.find((a)=>a.active);if(!r)return!1;let o=n.filter((a)=>a.tab===r.tab&&a.depth<r.depth);if(!o.length)return!1;let i=o.reduce((a,s)=>s.depth<a.depth?s:a);return e.history.go(i.depth-r.depth),!0}function Qr(e,t){for(let n=e.length-1;n>=0;n--)if(e[n].path===t)return e[n];return null}function en(e,t=tn()){let n;try{n=new URL(e)}catch{return null}let r=`${n.search}${n.hash}`;if(n.protocol==="http:"||n.protocol==="https:"){if(!t||n.origin!==t)return null;return`${n.pathname||"/"}${r}`}return`${`/${[n.host,n.pathname.replace(/^\/+/,"")].filter(Boolean).join("/")}`}${r}`}function tn(){if(typeof window>"u")return;return window.location?.origin}var ct="stacks-mobile-deep-link";function Jr(e,t){let n=(r)=>{let o=en(r);if(o)e(o)};return t.getInitialURL().then((r)=>{if(!r)return;try{if(sessionStorage.getItem(ct)===r)return;sessionStorage.setItem(ct,r)}catch{}n(r)}).catch(()=>{}),t.onLink((r,o)=>{if(o?.initial)return;n(r)})}var eo=5000;function nn(e,t,n=5000){let r=t.filter((o)=>Number.isFinite(o.timestamp)&&Number.isFinite(o.bpm)&&o.bpm>0).slice().sort((o,i)=>o.timestamp-i.timestamp);if(!r.length)return e.slice();return e.map((o)=>{let i=0,a=r.length;while(i<a){let p=i+a>>1;if(r[p].timestamp<o.timestamp)i=p+1;else a=p}let s=r[i],l=r[i-1],f=!s?l:!l?s:o.timestamp-l.timestamp<=s.timestamp-o.timestamp?l:s;if(!f||Math.abs(f.timestamp-o.timestamp)>n)return o;return{...o,heartRate:Math.round(f.bpm)}})}var rn=6371008.8,on=30,an=on;function sn(e,t){let n=Math.PI/180,r=(t.latitude-e.latitude)*n,o=(t.longitude-e.longitude)*n,i=Math.sin(r/2)**2+Math.cos(e.latitude*n)*Math.cos(t.latitude*n)*Math.sin(o/2)**2;return 2*rn*Math.asin(Math.min(1,Math.sqrt(i)))}function ln(e,t=25){let n=new Set;return e.filter((r)=>Number.isFinite(r.latitude)&&Number.isFinite(r.longitude)&&Number.isFinite(r.timestamp)&&Math.abs(r.latitude)<=90&&Math.abs(r.longitude)<=180&&Number.isFinite(r.accuracy)&&r.accuracy>=0&&r.accuracy<=t).sort((r,o)=>r.timestamp-o.timestamp).filter((r)=>{if(n.has(r.timestamp))return!1;return n.add(r.timestamp),!0})}function dt(e,t={}){let n=ln(e,t.maxAccuracyM??25),r=t.paceWindowS??30,o=[],i=0,a=0,s=null;for(let d of n){let g=o[o.length-1],u=s?(d.timestamp-s.timestamp)/1000:0;if(s=d,!g){o.push({fix:d,cumM:0});continue}if(u>an){o.push({fix:d,cumM:i});continue}let m=(d.timestamp-g.fix.timestamp)/1000,v=sn(g.fix,d),k=Math.min(10,Math.max(3,g.fix.accuracy,d.accuracy));if(v<k)continue;if(i+=v,m>0&&v/m>=0.5)a+=m;o.push({fix:d,cumM:i})}let l=o[o.length-1],f=null,p=null;if(l&&n.at(-1).timestamp-l.fix.timestamp<=r*1000){let d=l.fix.timestamp-r*1000,g=o.find((v)=>v.fix.timestamp>=d)??l,u=l.cumM-g.cumM,m=(l.fix.timestamp-g.fix.timestamp)/1000;if(u>=20&&m>0)p=u/m,f=m/(u/1000)}return{distanceM:i,movingS:a,paceSPerKm:f,averagePaceSPerKm:i>=50&&a>0?a/(i/1000):null,speedMps:p,accuracyM:n.length?n[n.length-1].accuracy:e.length?e[e.length-1].accuracy??null:null,fixes:n.length}}function to(e){if(e==null||e<=0||!Number.isFinite(e)||e>3600)return"–";let t=Math.round(e);return`${Math.floor(t/60)}:${String(t%60).padStart(2,"0")}`}function no(e){return e!=null&&e>0&&Number.isFinite(e)?(e*3.6).toFixed(1):"–"}var pt={distanceM:0,movingS:0,paceSPerKm:null,averagePaceSPerKm:null,speedMps:null,accuracyM:null,fixes:0};function ro(e){let t=e.location,n=e.intervalMs??3000,r=pt,o=null,i=e.heartRate,a=!1,s=[],l=()=>typeof document<"u"&&document.visibilityState==="hidden",f=0,p=null,d=Promise.resolve(),g=null,u=!1;function m(x){let h=d.then(x);return d=h.then(()=>{},()=>{}),h}function v(){if(p)return p;let x=f;return p=(async()=>{let h=await t.readRecording();if(x===f&&!u)r=dt(h,e),e.onUpdate?.(r);return r})().finally(()=>{p=null}),p}function k(){if(N(),u)return;o=setInterval(()=>{if(!l())v().catch(()=>{})},n)}function N(){if(o)clearInterval(o);o=null}async function z(x){if(!i||!a)return;await x(i).catch(()=>{})}return{get stats(){return r},get heartRate(){return s},start(){return g=null,m(async()=>{if(await t.startRecording({enableHighAccuracy:!0,...e.locationOptions}),s=[],a=!!i?.isAvailable(),await z((x)=>x.startRecording()),f++,r={...pt},!u)e.onUpdate?.(r);return k(),r})},attach(){return m(async()=>{let x=await t.getRecordingState();if(!x?.active)return null;if(i?.isAvailable())a=!!(await i.getRecordingState().catch(()=>null))?.active;if(await v().catch(()=>{}),!x.paused)k();return x})},pause(){return m(async()=>{await t.pauseRecording(),await z((x)=>x.pauseRecording()),N(),await v().catch(()=>{})})},resume(){return m(async()=>{await t.resumeRecording(),await z((x)=>x.resumeRecording()),k()})},stop(){if(g)return g;return g=m(async()=>{N(),f++;let h=(await t.stopRecording())?.locations??[];if(i&&a){let y=await i.stopRecording().catch(()=>null);a=!1,s=y?.samples??[],h=nn(h,s)}if(r=dt(h,e),!u)e.onUpdate?.(r);return h}).catch((x)=>{throw g=null,x}),g},dispose(){u=!0,f++,N()},refresh:v}}function io(e){return{startedAt:Number.isFinite(e)?e:null,pausedAt:null,pausedMs:0}}function ao(e,t){return e.startedAt===null||e.pausedAt!==null||!Number.isFinite(t)?e:{...e,pausedAt:Math.max(e.startedAt,t)}}function so(e,t){return e.pausedAt===null||!Number.isFinite(t)?e:{...e,pausedAt:null,pausedMs:e.pausedMs+Math.max(0,t-e.pausedAt)}}function lo(e,t){if(e.startedAt===null)return 0;let n=((e.pausedAt??t)-e.startedAt-e.pausedMs)/1000;return Number.isFinite(n)?Math.max(0,n):0}var uo=150;function cn(e,t){let n=Math.PI/180,r=(t.latitude-e.latitude)*n,o=(t.longitude-e.longitude)*n,i=Math.sin(r/2)**2+Math.cos(e.latitude*n)*Math.cos(t.latitude*n)*Math.sin(o/2)**2;return 12742017.6*Math.asin(Math.min(1,Math.sqrt(i)))}function oe(e,t){let n=[...e].sort((r,o)=>r-o);return n[Math.min(n.length-1,Math.floor(t*n.length))]}function po(e,t){let n=(e||[]).filter((a)=>Number.isFinite(a?.latitude)&&Number.isFinite(a?.longitude)&&Math.abs(a.latitude)<=90&&Math.abs(a.longitude)<=180),r=n.filter((a)=>a.accuracy!=null).map((a)=>Number(a.accuracy)).filter((a)=>Number.isFinite(a)&&a>=0),o=r.length?oe(r,0.5):Number.POSITIVE_INFINITY,i=0;if(n.length){let a={latitude:oe(n.map((s)=>s.latitude),0.5),longitude:oe(n.map((s)=>s.longitude),0.5)};i=oe(n.map((s)=>cn(a,s)),0.8)}if(n.length>=10&&i>150&&o<=15)return"outside";if(t<150)return"unsure";if(n.length<3||o>30||i<25)return"indoors";if(i<50&&o>10)return"indoors";return"unsure"}function fo(e,t={}){let r=String(e||"").trim().toLowerCase().replace(",",".").match(/^(\d+(?:\.\d*)?|\.\d+)\s*(km|k|m|mi)?$/);if(!r)return null;let o=Number(r[1]),i=r[2]||t.defaultUnit||(o>100?"m":"km"),a=i==="m"?o/1000:i==="mi"?o*1.609344:o;return Number.isFinite(a)&&a>=0&&a<=2000?Math.round(a*1000)/1000:null}var se=new Set,ft=!1,ie=null;function un(e){return e.isConnected&&e.getClientRects().length>0}function mt(){return[...se].find((e)=>un(e.element))}function ae(){let e=mt(),t=Boolean(e);if(t===ft)return;if(ft=t,t)I.enable(e?.tintColor?{tintColor:e.tintColor}:{});else I.disable()}function dn(){let e=mt();if(!e){I.end();return}Promise.resolve().then(()=>e.run()).catch(()=>{}).finally(()=>I.end())}function ho(e,t){let n={element:e,tintColor:t.tintColor,run:t.onRefresh};se.add(n);let r=e.ownerDocument?.defaultView;if(!ie){let o=I.onRefresh(dn),i=()=>ae();r?.addEventListener("stx:load",i),ie=()=>{o(),r?.removeEventListener("stx:load",i)}}return ae(),r?.requestAnimationFrame?.(()=>ae()),()=>{if(se.delete(n),se.size===0)ie?.(),ie=null;ae()}}var vo=0.5;function pn(e,t,n){let r=[];if(n.includes("large")||n.length===0)r.push({name:"large",y:0});if(n.includes("medium"))r.push({name:"medium",y:Math.max(0,Math.round(e-t*0.5))});return r.push({name:"dismiss",y:Math.max(1,e)}),r.sort((o,i)=>o.y-i.y)}function fn(e){let{y:t,velocity:n,stops:r}=e,o=r.filter((s)=>s.name!=="dismiss"),i=r.find((s)=>s.name==="dismiss");if(o.length===0)return"dismiss";if(n>0.5)return(r.filter((l)=>l.y>t+1)[0]??i).name;if(n<-0.5){let s=o.filter((l)=>l.y<t-1);return(s[s.length-1]??o[0]).name}let a=o[o.length-1];if(t>a.y+(i.y-a.y)*0.5)return"dismiss";return o.reduce((s,l)=>Math.abs(l.y-t)<Math.abs(s.y-t)?l:s).name}function mn(e,t=400){if(e<=0)return 0;return e*t*0.55/(t+e*0.55)}function yo(e){let{panel:t}=e,n=null,r=[],o=0,i=()=>e.viewport?.()??t.ownerDocument?.defaultView?.innerHeight??800,a=()=>pn(t.offsetHeight||t.getBoundingClientRect().height,i(),e.detents()),s=(p)=>{let d=p;if(d.button!==void 0&&d.button!==0)return;if(d.target?.closest?.("button, a, input, select, textarea, [role=button]"))return;let g=a().find((u)=>u.name===e.detent())?.y??0;n={y:d.clientY,base:g,pointerId:d.pointerId},o=g,r=[{y:g,t:d.timeStamp}],t.classList.add("is-dragging");try{p.currentTarget?.setPointerCapture?.(d.pointerId)}catch{}},l=(p)=>{if(!n)return;let d=p,g=n.base+d.clientY-n.y;o=g<0?-mn(-g):g,r.push({y:o,t:d.timeStamp});while(r.length>2&&d.timeStamp-r[0].t>100)r.shift();t.style.transform=`translateY(${o}px)`;let u=t.offsetHeight||1;t.parentElement?.style.setProperty("--native-sheet-presence",String(Math.max(0,Math.min(1,1-o/u))))},f=(p)=>{if(!n)return;let d=p;n=null;let g=r[0],u=Math.max(1,d.timeStamp-g.t),m=(o-g.y)/u;t.classList.remove("is-dragging"),t.style.transform="",t.parentElement?.style.removeProperty("--native-sheet-presence"),e.onSettle(fn({y:o,velocity:m,stops:a()}))};for(let p of e.handles)p.addEventListener("pointerdown",s),p.addEventListener("pointermove",l),p.addEventListener("pointerup",f),p.addEventListener("pointercancel",f);return()=>{for(let p of e.handles)p.removeEventListener("pointerdown",s),p.removeEventListener("pointermove",l),p.removeEventListener("pointerup",f),p.removeEventListener("pointercancel",f)}}function So(e){let t=e.ownerDocument;if(e.parentElement===t.body)return()=>{};let n=t.createComment("native-sheet");return e.parentNode?.insertBefore(n,e),t.body.appendChild(e),()=>{if(n.parentNode)n.parentNode.insertBefore(e,n);else e.remove();n.remove()}}var Ee=new WeakMap;function xo(e,t){let n=e.documentElement,r=Ee.get(e)??0;if(!t){let a=Math.max(0,r-1);if(Ee.set(e,a),a===0)n.removeAttribute("data-native-sheet-card");return}if(Ee.set(e,r+1),r>0)return;let o=e.defaultView,i=(o?.scrollY??0)+(o?.innerHeight??800)/2;n.style.setProperty("--native-sheet-card-origin",`${Math.round(i)}px`),n.setAttribute("data-native-sheet-card","")}function gn(e,t){e.style.setProperty("--native-font-scale",String(t.fontScale)),e.toggleAttribute("data-native-reduce-motion",t.reduceMotion),e.toggleAttribute("data-native-reduce-transparency",t.reduceTransparency)}function hn(e){let t=e.replace(/\s+/g,"").toLowerCase();return!t||t==="transparent"||/^rgba\(\d+,\d+,\d+,0(\.0+)?\)$/.test(t)||/\/0(\.0+)?\)$/.test(t)}function bn(e){let t=e.defaultView;if(!t?.getComputedStyle)return null;for(let n of[e.body,e.documentElement]){if(!n)continue;let r=t.getComputedStyle(n).backgroundColor;if(r&&!hn(r))return r}return null}function vn(e){if(e.documentElement.classList.contains("dark"))return!0;if(e.documentElement.classList.contains("light"))return!1;return Boolean(e.defaultView?.matchMedia?.("(prefers-color-scheme: dark)").matches)}function Ro(e,t={}){let n=t.root??e.documentElement;Y.setKeyboardAccessory(t.keyboardAccessory===!0);let r="",o="",i=()=>{let p=bn(e);if(p&&p!==r)r=p,Y.setUnderPageColor(p);let d=vn(e)?"light":"dark";if(d!==o)o=d,ne.setStyle(d)},a=at((p)=>{gn(n,p),i()}),s=e.defaultView,l=typeof s?.MutationObserver==="function"?new s.MutationObserver(i):null;l?.observe(e.documentElement,{attributes:!0,attributeFilter:["class","style","data-theme"]});let f=s?.matchMedia?.("(prefers-color-scheme: dark)");return f?.addEventListener?.("change",i),s?.addEventListener("stx:load",i),i(),()=>{a(),l?.disconnect(),f?.removeEventListener?.("change",i),s?.removeEventListener("stx:load",i)}}var To=64;var yn=/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/,Sn=/^(?:0|[1-9]\d*)$/;function ht(e){let t=[],n=[],r=e&&typeof e==="object"&&!Array.isArray(e)?e:{};for(let[o,i]of Object.entries(r)){let a=i&&typeof i==="object"?i:null;if(!a){n.push(`spotlight kind "${o}" is not an object`);continue}let{slots:s,route:l}=a,f=typeof a.noun==="string"&&a.noun.trim()?a.noun.trim():"Item";if(!yn.test(o)||o.includes("-slot-")){n.push(`spotlight kind "${o}" is not a usable name: lowercase letters, digits and single dashes, and never "-slot-"`);continue}if(typeof s!=="number"||!Number.isInteger(s)||s<=0||s>64){n.push(`spotlight kind "${o}" needs slots between 1 and 64, not ${String(s)}`);continue}if(typeof l!=="string"||!l.startsWith("/")||!l.includes(":id")){n.push(`spotlight kind "${o}" needs a route starting with "/" and carrying ":id", not ${String(l)}`);continue}t.push({name:o,slots:s,route:l,noun:f})}return{kinds:t,problems:n}}function Q(e,t){return e.find((n)=>n.name===t)??null}function X(e,t,n){let r=Q(e,t);if(!r||!Number.isInteger(n)||n<0||n>=r.slots)return null;return`${t}-slot-${n}`}function xn(e,t){if(typeof t!=="string")return null;let n=t.lastIndexOf("-slot-");if(n<=0)return null;let r=t.slice(0,n),o=t.slice(n+6);if(!Sn.test(o))return null;let i=Number(o);return X(e,r,i)===t?{kind:r,slot:i}:null}function bt(e){return e.flatMap((t)=>Array.from({length:t.slots},(n,r)=>`${t.name}-slot-${r}`))}function Lo(e,t){let n=e&&typeof e==="object"?e:{};if(n.enabled===!1)return[];let o=[...(Array.isArray(n.activityTypes)?n.activityTypes.filter((i)=>typeof i==="string"&&i.trim().length>0):[]).map((i)=>i.trim()),...bt(ht(n.kinds).kinds)];return[...new Set(o)].map((i)=>`${t}.${i}`)}function vt(e,t,n){let r=typeof n.name==="string"?n.name.replace(/\s+/g," ").trim():"";if(!r)return`${Q(e,t)?.noun??"Item"} #${n.id}`;return r.length>120?`${r.slice(0,119).trimEnd()}…`:r}function wn(e,t,n,r,o=Date.now()){let i=Q(e,n);if(!i||!Number.isInteger(r.id)||r.id<=0)return null;let a=t.filter((m)=>m.kind===n),s=vt(e,n,r),l=a.find((m)=>m.itemId===r.id)??null,f=l?null:En(a,i.slots),p=l||f!==null?null:Tn(a),d=l?.slot??f??p?.slot;if(d===void 0||d===null)return null;let g={kind:n,slot:d,itemId:r.id,title:s,donatedAt:o},u=t.filter((m)=>m.kind!==n||m.slot!==d&&m.itemId!==r.id);return{entries:yt(e,[...u,g]),entry:g,evicted:p,changed:!l||l.title!==s}}function An(e,t,n){let r=e.find((o)=>o.kind===t&&o.itemId===n)??null;return{entries:r?e.filter((o)=>o!==r):[...e],removed:r}}function kn(e,t,n){let r=xn(e,n);if(!r)return null;let o=t.find((a)=>a.kind===r.kind&&a.slot===r.slot),i=Q(e,r.kind)?.route;return o&&i?i.replace(":id",String(o.itemId)):null}function Rn(e,t){if(!Array.isArray(t))return[];let n=new Map,r=new Set;for(let o of t){if(!o||typeof o!=="object")continue;let i=o,{kind:a,slot:s,itemId:l,title:f,donatedAt:p}=i;if(typeof a!=="string"||typeof s!=="number"||X(e,a,s)===null)continue;if(typeof l!=="number"||!Number.isInteger(l)||l<=0)continue;let d=`${a}-slot-${s}`,g=`${a}#${l}`;if(n.has(d)||r.has(g))continue;n.set(d,{kind:a,slot:s,itemId:l,title:typeof f==="string"&&f.trim()?f:vt(e,a,{id:l}),donatedAt:typeof p==="number"&&Number.isFinite(p)&&p>0?p:0}),r.add(g)}return yt(e,[...n.values()])}function yt(e,t){let n=new Map(e.map((r,o)=>[r.name,o]));return[...t].sort((r,o)=>(n.get(r.kind)??0)-(n.get(o.kind)??0)||r.slot-o.slot)}function En(e,t){let n=new Set(e.map((r)=>r.slot));for(let r=0;r<t;r++)if(!n.has(r))return r;return null}function Tn(e){return e.reduce((t,n)=>!t||n.donatedAt<t.donatedAt?n:t,null)}function Ln(){let e=globalThis.craft;return e&&typeof e==="object"?e.siri:void 0}var Pn="stacks_spotlight_index",Mn=3000;function Po(e){let t=e.onProblem??((h)=>console.warn(`[spotlight] ${h}`)),n=Array.isArray(e.kinds)?{kinds:[...e.kinds],problems:[]}:ht(e.kinds);for(let h of n.problems)t(h);let r=e.enabled===!1?[]:n.kinds,o=e.storageKey??Pn,i=e.legacyStorageKeys??[],a=e.timeoutMs??Mn,s=e.now??(()=>Date.now()),l=e.bridge??Ln,f=null;function p(){try{return typeof localStorage>"u"?null:localStorage}catch{return null}}function d(){if(f)return f;f=[];let h=p();if(!h)return f;try{let y=[o,...i].map((w)=>h.getItem(w)).find((w)=>w);f=y?Rn(r,JSON.parse(y)):[]}catch{f=[]}return f}function g(h){f=h;let y=p();if(!y)return;try{y.setItem(o,JSON.stringify(h));for(let w of i)y.removeItem(w)}catch{}}async function u(h){if(!h)return null;let y;try{return await Promise.race([h,new Promise((w)=>{y=setTimeout(()=>w(null),a)})])}catch{return null}finally{if(y!==void 0)clearTimeout(y)}}let m=Promise.resolve();function v(h){let y=m.then(h,h);return m=y.catch(()=>{return}),y}async function k(h,y){let w=l()?.register;if(!w||r.length===0)return!1;return v(async()=>{let E=wn(r,d(),h,y,s()),B=E&&X(r,h,E.entry.slot);if(!E||!B)return!1;if(!E.changed)return g(E.entries),!0;let U=await u(w(E.entry.title,B))!==null;if(U)g(E.entries);return U})}async function N(h,y){let w=l()?.remove;if(!w)return!1;return v(async()=>{let{entries:E,removed:B}=An(d(),h,y);if(!B)return!1;let U=X(r,h,B.slot),Tt=U?await u(w(U))!==null:!1;return g(E),Tt})}async function z(h,y){let w=Q(r,h)?.slots;if(!w||!l()?.register)return 0;let E=0;for(let B of[...y].slice(0,w).reverse())if(await k(h,B))E++;return E}async function x(){let h=l()?.remove;if(!h)return g([]),0;return v(async()=>{let y=0;for(let w of d()){let E=X(r,w.kind,w.slot);if(E&&await u(h(E))!==null)y++}return g([]),y})}return{kinds:r,index:k,sync:z,remove:N,clear:x,routeFor:(h)=>kn(r,d(),h),entries:()=>d(),activityTypes:(h)=>bt(r).map((y)=>`${h}.${y}`),reset:()=>{f=null}}}var gt=["craftShortcut","craftSiriShortcut"];function Mo(e,t){let n=(r)=>{let o=r.detail,i=typeof o==="string"?o:o&&typeof o==="object"?o.action??o.type:null,a=typeof i==="string"?e.routeFor(i):null;if(a)t(a)};if(typeof globalThis.addEventListener!=="function")return()=>{};for(let r of gt)globalThis.addEventListener(r,n);return()=>{for(let r of gt)globalThis.removeEventListener(r,n)}}import{tabBar as Cn}from"craft-native/mobile";var On=Cn;function Nn(e){return Array.from(e.querySelectorAll("a[data-native-tab]")).map((t)=>({id:t.getAttribute("href")||"",title:t.getAttribute("data-native-tab")||t.getAttribute("aria-label")||"",symbol:t.getAttribute("data-native-tab-symbol")||"circle",badge:(t.querySelector(".native-tab-badge")?.textContent||"").trim(),current:t.hasAttribute("data-stx-nav-current")||t.classList.contains("is-active")})).filter((t)=>t.id&&t.title)}function Hn(e){return{tabs:e.map(({id:n,title:r,symbol:o,badge:i})=>i?{id:n,title:r,symbol:o,badge:i}:{id:n,title:r,symbol:o}),selected:e.find((n)=>n.current)?.id}}function xt(){if(typeof window>"u")return;let e=window.stxRouter;return e&&typeof e==="object"?e:void 0}function In(){return typeof xt()?.selectTab==="function"}function No(e,t={}){let n=(r)=>{if(In()||r.defaultPrevented)return;let o=r.target?.closest?.("a[data-native-tab]");if(!o||!e.contains(o))return;if(!o.hasAttribute("data-stx-nav-current")&&!o.classList.contains("is-active")&&o.getAttribute("aria-current")!=="page")return;r.preventDefault();let i=e.ownerDocument.defaultView;if(t.scrollToTop)t.scrollToTop();else i?.scrollTo?.({top:0,behavior:i.matchMedia?.("(prefers-reduced-motion: reduce)").matches?"auto":"smooth"});i?.dispatchEvent(new CustomEvent("stx:tabreselect",{detail:{href:o.getAttribute("href")||""}}))};return e.addEventListener("click",n),()=>e.removeEventListener("click",n)}function St(e){let t=e.trim();return/^#[0-9a-f]{6}$/i.test(t)?t:void 0}var Te="stacks:tab-bar-cover";function Ho(e,t){if(t)e.setAttribute("data-native-covers-tab-bar","");else e.removeAttribute("data-native-covers-tab-bar");e.ownerDocument?.defaultView?.dispatchEvent(new Event(Te))}function Io(e,t={}){let n=t.api??On;if(!n.isAvailable())return null;let r=t.hidden??(()=>Boolean(e.ownerDocument?.querySelector("[data-native-hide-tab-bar], [data-native-covers-tab-bar]"))),o=typeof getComputedStyle==="function"?getComputedStyle(e):null,i=St(o?.getPropertyValue("--native-tab-active")||""),a=St(o?.getPropertyValue("--native-tab-active-dark")||""),s="",l=()=>{if(r()){if(s!=="hidden")n.hide();s="hidden";return}let{tabs:g,selected:u}=Hn(Nn(e)),m=JSON.stringify({tabs:g,selected:u});if(m===s)return;let v=s&&s!=="hidden"?JSON.parse(s):null;if(v&&u&&JSON.stringify(v.tabs)===JSON.stringify(g))n.select(u);else n.set(g,{selected:u,tint:i,tintDark:a});s=m},f=typeof MutationObserver==="function"?new MutationObserver(l):null;f?.observe(e,{attributes:!0,attributeFilter:["data-stx-nav-current","class"],childList:!0,subtree:!0,characterData:!0});let p=n.onSelect((g)=>{let u=xt();if(u?.selectTab){u.selectTab(g);return}Array.from(e.querySelectorAll("a[data-native-tab]")).find((v)=>v.getAttribute("href")===g)?.click()}),d=()=>l();if(typeof window<"u")window.addEventListener("stx:load",d),window.addEventListener("stx:screen-shown",d),window.addEventListener(Te,d);return l(),()=>{if(f?.disconnect(),p(),typeof window<"u")window.removeEventListener("stx:load",d),window.removeEventListener("stx:screen-shown",d),window.removeEventListener(Te,d);n.hide()}}var Fn={isAvailable:()=>c(()=>Le.isAvailable()),getBiometricType:()=>c(()=>Le.getBiometricType()),authenticate:(e)=>c(()=>Le.authenticate(e))},Wn={takePicture:(e)=>c(()=>ce.takePicture(e)),pickImage:()=>c(()=>ce.pickImage()),pickMultiple:(e)=>c(()=>ce.pickMultiple(e)),isAvailable:()=>c(()=>ce.isAvailable())},$n={getInfo:()=>c(()=>D.getInfo()),getCapabilities:()=>c(()=>D.getCapabilities()),isMobile:()=>D.isMobile(),isIOS:()=>D.isIOS(),isAndroid:()=>D.isAndroid(),getLocale:()=>D.getLocale(),getTimezone:()=>D.getTimezone()},Kn=_n,zn={getCurrentPosition:(e)=>c(()=>H.getCurrentPosition(e)),watchPosition:(e,t)=>H.watchPosition(e,t),clearWatch:(e)=>H.clearWatch(e),startRecording:(e)=>c(()=>H.startRecording(e)),pauseRecording:()=>c(()=>H.pauseRecording()),resumeRecording:()=>c(()=>H.resumeRecording()),stopRecording:()=>c(()=>H.stopRecording()),getRecordingState:()=>c(()=>H.getRecordingState()),readRecording:()=>c(()=>H.readRecording())},Un={show:(e)=>c(()=>de.show(e)),schedule:(e)=>c(()=>de.schedule(e)),cancelAll:()=>c(()=>de.cancelAll()),setBadge:(e)=>c(()=>de.setBadge(e))},qn={check:(e)=>c(()=>Z.check(e)),request:(e)=>c(()=>Z.request(e)),checkMultiple:(e)=>c(()=>Z.checkMultiple(e)),requestMultiple:(e)=>c(()=>Z.requestMultiple(e)),openSettings:()=>c(()=>Z.openSettings())},jn={set:(e,t)=>c(()=>pe.set(e,t)),get:(e)=>c(()=>pe.get(e)),delete:(e)=>c(()=>pe.delete(e)),clear:()=>c(()=>pe.clear())},Yn={share:(e)=>c(()=>Rt.share(e)),isAvailable:()=>Rt.isAvailable()},Gn={request:()=>c(()=>Bn.request())},me={impact:(e)=>Promise.resolve().then(()=>ue.impact(e)).catch(()=>{}),notification:(e)=>Promise.resolve().then(()=>ue.notification(e)).catch(()=>{}),selection:()=>Promise.resolve().then(()=>ue.selection()).catch(()=>{}),vibrate:(e)=>Promise.resolve().then(()=>ue.vibrate(e)).catch(()=>{}),prepare:(e)=>{let t=L("haptics.prepare");return t?Promise.resolve().then(()=>t(e)).then(()=>{},()=>{}):Promise.resolve()}};function Et(e){if(typeof e==="string")return e.trim()||null;if(!e||typeof e!=="object")return null;let t=e.url;return typeof t==="string"&&t.trim()?t:null}var Vn={async getInitialURL(){if(!await F())return null;return Et(await wt.getInitialURL?.())},onLink(e){let t=null,n=!1,r=()=>{if(n)return;t=wt.onLink?.((o,i)=>{let a=Et(o);if(a)e(a,{initial:i?.initial===!0})})??null};if(he()?.craft)r();else F().then(r);return()=>{n=!0,t?.()}}},$o={isAvailable:()=>fe.isAvailable(),set:(e,t)=>fe.set(e,t),remove:(e)=>fe.remove(e),clear:()=>fe.clear()},Xn={enable:()=>c(()=>At.enable()),disable:()=>c(()=>At.disable())},Qn={isAvailable:()=>le.isAvailable(),get:()=>c(()=>le.get()),set:(e)=>c(()=>le.set(e)),restore:()=>c(()=>le.restore())},Jn={isAvailable:()=>O.isAvailable(),supports:(e)=>O.supports(e),getAuthorizationStatus:()=>c(()=>O.getAuthorizationStatus()),requestAuthorization:()=>c(()=>O.requestAuthorization()),getNowPlaying:()=>c(()=>O.getNowPlaying()),play:()=>c(()=>O.play()),pause:()=>c(()=>O.pause()),togglePlayPause:()=>c(()=>O.togglePlayPause()),skipToNext:()=>c(()=>O.skipToNext()),skipToPrevious:(e)=>c(()=>O.skipToPrevious(e)),onChange:(e)=>_(()=>O.onChange(e))},Zn={isAvailable:()=>A.isAvailable(),supports:(e)=>A.supports(e),getState:()=>c(()=>A.getState()),requestAuthorization:()=>c(()=>A.requestAuthorization()),scan:(e)=>c(()=>A.scan(e)),stopScan:()=>c(()=>A.stopScan()),getDevices:()=>c(()=>A.getDevices()),connect:(e)=>c(()=>A.connect(e)),reconnect:()=>c(()=>A.reconnect()),disconnect:(e)=>c(()=>A.disconnect(e)),startRecording:()=>c(()=>A.startRecording()),pauseRecording:()=>c(()=>A.pauseRecording()),resumeRecording:()=>c(()=>A.resumeRecording()),stopRecording:()=>c(()=>A.stopRecording()),getRecordingState:()=>c(()=>A.getRecordingState()),readRecording:(e)=>c(()=>A.readRecording(e)),onReading:(e)=>_(()=>A.onReading(e)),onDevice:(e)=>_(()=>A.onDevice(e)),onState:(e)=>_(()=>A.onState(e))},er={isAvailable:()=>Ce.isAvailable(),speak:(e,t)=>c(()=>Ce.speak(e,t)),stop:()=>c(()=>Ce.stop())},tr={getStatus:()=>c(()=>kt.getStatus()),onChange:(e)=>_(()=>kt.onChange(e))},nr={register:()=>c(()=>Me.register()),onToken:(e)=>Me.onToken(e),onNotification:(e)=>_(()=>Me.onNotification(e))},rr={requestAuthorization:(e,t)=>c(()=>J.requestAuthorization(e,t)),getData:(e,t)=>c(()=>J.getData(e,t)),saveWorkout:(e)=>c(()=>J.saveWorkout(e)),getWorkouts:(e)=>c(()=>J.getWorkouts(e)),getDailyStatistics:(e,t)=>c(()=>J.getDailyStatistics(e,t)),getHeartRateSamples:(e)=>b("health.getHeartRateSamples",[e??{}],()=>[]).then((t)=>Array.isArray(t)?t:[]),getSleepIntervals:(e)=>b("health.getSleepIntervals",[e??{}],()=>[]).then((t)=>Array.isArray(t)?t:[]),saveMindfulSession:(e)=>b("health.saveMindfulSession",[e],()=>null).then((t)=>t??null),getMindfulSessions:(e)=>b("health.getMindfulSessions",[e??{}],()=>[]).then((t)=>Array.isArray(t)?t:[]),startHeartRateUpdates:(e)=>b("health.startHeartRateUpdates",[e??{}],()=>!1).then((t)=>t!==!1),stopHeartRateUpdates:()=>b("health.stopHeartRateUpdates",[],()=>!0).then(()=>!0),onHeartRate:(e)=>M("craftHealthHeartRate",(t)=>{if(Array.isArray(t.samples)&&t.samples.length)e(t.samples)}),supports:(e)=>L(`health.${e}`)!==null},or={start:(e)=>c(()=>Pe.start(e)),update:(e)=>c(()=>Pe.update(e)),end:()=>c(()=>Pe.end())},ir={send:(e)=>c(()=>ee.send(e)),updateContext:(e)=>c(()=>ee.updateContext(e)),isReachable:()=>c(()=>ee.isReachable()),onMessage:(e)=>ee.onMessage(e),onReachabilityChange:(e)=>ee.onReachabilityChange(e)},Ko=Dn;function he(){return S()}function ge(){let e=he()?.craft;if(!e||typeof e!=="object")return null;if(!("platform"in e)||e.platform!=="ios"&&e.platform!=="android")return null;let t="capabilities"in e?e.capabilities:void 0,n=t&&typeof t==="object"&&!Array.isArray(t)?Object.fromEntries(Object.entries(t).filter(([,r])=>typeof r==="boolean")):{};return{platform:e.platform,capabilities:n}}function Oe(){return ge()!==null}function ar(e=2000){if(Oe()||q())return Promise.resolve(!0);let t=he();if(!t||!(t.craft||t.webkit?.messageHandlers?.craft))return Promise.resolve(!1);return new Promise((n)=>{let r=()=>{clearTimeout(o),t.removeEventListener("craftReady",r),n(Oe())},o=setTimeout(r,e);t.addEventListener("craftReady",r,{once:!0})})}function sr(e){let t=he();if(!t)return()=>{};if(ge()){let r=!1;return queueMicrotask(()=>{if(!r)e(new Event("craftReady"))}),()=>{r=!0}}let n=(r)=>{if(!ge())return;t.removeEventListener("craftReady",n),e(r)};return t.addEventListener("craftReady",n),()=>t.removeEventListener("craftReady",n)}async function lr(e){await me.impact("light");try{let t=await e();return await me.notification("success"),t}catch(t){throw await me.notification("error"),t}}var zo={get nativeBridge(){return ge()},biometrics:Fn,camera:Wn,device:$n,haptics:me,lifecycle:Kn,location:zn,notifications:Un,permissions:qn,secureStorage:jn,share:Yn,appReview:Gn,deepLinks:Vn,keepAwake:Xn,brightness:Qn,music:Jn,heartRate:Zn,scheduledWorkouts:nt,speech:er,network:tr,pushNotifications:nr,health:rr,liveActivities:or,watchConnectivity:ir,dialog:j,contextMenu:Ae,browser:qe,symbols:je,statusBar:ne,chrome:Y,refresh:I,background:G,clipboard:Ye,db:Ge,files:Ve,shortcuts:Xe,widgets:Qe,orientation:Je,auth:Ze,storeKit:et,isNativeMobile:Oe,whenNative:ar,onReady:sr,withFeedback:lr};export{cr as BRIDGE_WAIT_MS,eo as HEART_RATE_MATCH_MS,uo as INDOOR_CHECK_AFTER_S,To as MAX_SPOTLIGHT_SLOTS_PER_KIND,on as ROUTE_GAP_S,vo as SHEET_FLICK_VELOCITY,Te as TAB_BAR_COVER_EVENT,c as afterBridge,Gn as appReview,gn as applyAppearance,nn as attachHeartRate,Ze as auth,Yr as backLabelFor,G as background,Fn as biometrics,te as bridgePending,Qn as brightness,qe as browser,b as callNative,Wn as camera,Jt as canGoBack,Y as chrome,Ye as clipboard,hr as confirmAction,Ae as contextMenu,Ho as coverTabBar,S as craftHost,be as craftRoot,Cr as crashReporting,ro as createRouteRecorder,Po as createSpotlightIndex,it as currentAppearance,Ge as db,en as deepLinkPath,Vn as deepLinks,$n as device,j as dialog,jr as enterNavTrail,Ve as files,sn as fixDistance,Rr as focusSegment,Jr as followDeepLinks,ge as getNativeMobileBridge,qr as goBack,Xr as goBackToTabRoot,No as handleTabReselect,me as haptics,q as hasNativeMobileHost,rr as health,Zn as heartRate,po as indoorVerdict,Ro as installNativeChrome,Er as installPressables,Oe as isNativeMobile,un as isShown,Xn as keepAwake,Ut as keepBreadcrumb,Xt as largeTitleMetrics,Kn as lifecycle,So as liftToBody,or as liveActivities,zn as location,Io as mirrorTabBar,zo as mobile,Jn as music,Mt as nativeFunction,L as nativeFunctionNow,Hn as nativeTabs,Gr as navTrail,tr as network,jt as normalizeAppearance,Et as normalizeDeepLinkURL,$t as normalizeScheduledWorkout,Un as notifications,Kr as observeLargeTitle,wr as observeLongPress,ho as observeNativeRefresh,Gt as observePageScroll,$r as observePullToRefresh,Ar as observeSegmentScrub,yo as observeSheetDrag,at as onAppearance,Dr as onBackgroundRefresh,M as onCraftEvent,Br as onMemoryWarning,sr as onMobileReady,Ir as onResume,_r as onSilentPush,Mo as onSpotlightTap,Je as orientation,to as paceLabel,bn as pageBackground,vn as pageIsDark,V as pageScrollTop,ao as pauseSessionClock,qn as permissions,It as placeMenu,wn as placeSpotlightItem,Fe as presentActionSheet,_e as presentAlert,ve as presentChoice,De as presentConfirm,We as presentContextMenu,xo as presentPageAsCard,Vr as previousScreenPath,Vt as pullDistance,nr as pushNotifications,Rn as readSpotlightEntries,ht as readSpotlightKinds,Nn as readTabLinks,I as refresh,An as removeSpotlightItem,zr as resolveScrollHost,so as resumeSessionClock,dt as routeStats,In as routerHandlesTabs,mn as rubberBand,nt as scheduledWorkouts,Wt as scheduledWorkoutsUnsupported,jn as secureStorage,Kt as segmentAt,kr as segmentForKey,lo as sessionClockElapsed,fn as settleSheet,Yn as share,pn as sheetStops,Xe as shortcuts,br as showContextMenuFor,$o as snapshots,er as speech,no as speedLabel,Ko as splash,X as spotlightAction,bt as spotlightActions,Lo as spotlightActivityTypes,Ln as spotlightBridge,Q as spotlightKind,kn as spotlightRoute,xn as spotlightSlot,vt as spotlightTitle,io as startSessionClock,ne as statusBar,et as storeKit,_ as subscribeWhenReady,je as symbols,On as tabBar,we as toNativeRect,Qr as trailEntryFor,fo as typedDistanceKm,ln as usableFixes,gr as useActionSheet,ir as watchConnectivity,F as whenBridgeReady,ar as whenNativeMobile,Qe as widgets,lr as withNativeFeedback};
55
+ `;function Ke(){return A()?.document}function zt(e){if(e.getElementById(Ue))return;let t=e.createElement("style");t.id=Ue,t.textContent=qt,(e.head??e.documentElement).appendChild(t)}var Gt=0;function I(e,t,n,r){let o=e.createElement(t);if(o.className=n,r!==void 0)o.textContent=r;return o}function $e(){return A()?.stx?.overlays}var Yt=0;function je(e,t,n,r){zt(e);let o=A(),i=`native-dialog-layer-${++Yt}`,a=I(e,"div",`native-dialog native-dialog--${t}`);return a.setAttribute("data-native-dialog",t),a.appendChild(I(e,"div","native-dialog-backdrop")),new Promise((s)=>{let l=!1,m=(c)=>{if(l)return;l=!0,a.classList.remove("is-open"),$e()?.close(i),setTimeout(()=>a.remove(),260),s(c)},f=n({root:a,settle:m});a.appendChild(f),e.body.appendChild(a),$e()?.open(i,{panel:f,root:a,onEscape:()=>m(r())});let d=o;(typeof d?.requestAnimationFrame==="function"?(c)=>d.requestAnimationFrame(()=>d.requestAnimationFrame(c)):(c)=>setTimeout(c,16))(()=>{if(!l)a.classList.add("is-open")})})}function ke(e){let t=Ke();if(!t?.body)return Promise.resolve(null);let n=`native-dialog-${++Gt}`,r=e.actions.find((a)=>a.style==="cancel"),o=e.variant==="sheet"?e.actions.filter((a)=>a.style!=="cancel"):e.actions,i=e.variant==="sheet"?r??{id:"__cancel",title:e.cancelLabel||"Cancel",style:"cancel"}:void 0;return je(t,e.variant,({root:a,settle:s})=>{let l=(c)=>c.style==="cancel"?null:c.id,m=I(t,"div","native-dialog-panel");m.setAttribute("role","alertdialog"),m.setAttribute("aria-modal","true"),m.tabIndex=-1;let f=I(t,"div","native-dialog-group");if(e.title||e.message){let c=I(t,"div","native-dialog-header");if(e.title){let p=I(t,"p","native-dialog-title",e.title);p.id=`${n}-title`,c.appendChild(p),m.setAttribute("aria-labelledby",p.id)}if(e.message){let p=I(t,"p","native-dialog-message",e.message);p.id=`${n}-message`,c.appendChild(p),m.setAttribute("aria-describedby",p.id)}f.appendChild(c)}let d=I(t,"div","native-dialog-actions");if(e.variant==="alert"&&o.length===2)d.classList.add("is-row");for(let c of o){let p=I(t,"button",`native-dialog-action${c.style==="destructive"?" is-destructive":""}${c.style==="cancel"?" is-cancel":""}`,c.title);p.type="button",p.setAttribute("data-action-id",c.id),p.addEventListener("click",()=>s(l(c))),d.appendChild(p)}if(f.appendChild(d),m.appendChild(f),i){let c=I(t,"div","native-dialog-group"),p=I(t,"button","native-dialog-action is-cancel",i.title);p.type="button",p.setAttribute("data-action-id",i.id),p.addEventListener("click",()=>s(null)),c.appendChild(p),m.appendChild(c)}let g=a.querySelector(".native-dialog-backdrop");if(e.variant==="sheet")g?.addEventListener("click",()=>s(null));return m},()=>{if(e.variant==="sheet")return null;if(r)return null;return o.length===1?o[0].id:null})}async function qe(e){await ke({variant:"alert",title:e.title,message:e.message,actions:[{id:"ok",title:e.okLabel||"OK"}]})}async function ze(e){return await ke({variant:"alert",title:e.title,message:e.message,actions:[{id:"cancel",title:e.cancelLabel||"Cancel",style:"cancel"},{id:"confirm",title:e.confirmLabel||"OK",style:e.destructive?"destructive":"default"}]})==="confirm"}function Ge(e){return ke({variant:"sheet",title:e.title,message:e.message,actions:e.actions,cancelLabel:e.cancelLabel})}function Vt(e,t,n){let i=Math.max(12,Math.min(e.x,n.width-t.width-12)),a=e.y+e.height+8,s=a+t.height<=n.height-12,l=e.y-8-t.height,m=s||l<12?Math.max(12,Math.min(a,n.height-t.height-12)):l,f=e.x+e.width/2>n.width/2?"right":"left";return{top:m,left:i,origin:`${s||l<12?"top":"bottom"} ${f}`}}function Ye(e){let t=Ke();if(!t?.body)return Promise.resolve(null);let n=A();return je(t,"menu",({root:r,settle:o})=>{let i=I(t,"div","native-menu native-dialog-panel");if(i.setAttribute("role","menu"),e.title)i.appendChild(I(t,"p","native-menu-title",e.title)),i.setAttribute("aria-label",e.title);for(let a of e.items){let s=I(t,"button",`native-menu-item${a.destructive?" is-destructive":""}`);if(s.type="button",s.setAttribute("role","menuitem"),s.setAttribute("data-action-id",a.id),a.disabled)s.disabled=!0;if(s.appendChild(I(t,"span","native-menu-label",a.title)),a.icon){let l=I(t,"i",`native-menu-icon ${a.icon}`);l.setAttribute("aria-hidden","true"),s.appendChild(l)}s.addEventListener("click",()=>o(a.id)),i.appendChild(s)}return r.querySelector(".native-dialog-backdrop")?.addEventListener("click",()=>o(null)),queueMicrotask(()=>{let a=i.getBoundingClientRect?.(),s=Vt(e.anchor,{width:a?.width||248,height:a?.height||e.items.length*44},{width:n?.innerWidth||390,height:n?.innerHeight||844});i.style.top=`${s.top}px`,i.style.left=`${s.left}px`,i.style.setProperty("--native-menu-origin",s.origin)}),i},()=>null)}var Je=()=>!0,P=()=>!1,_=()=>null;function Ve(){return A()?.navigator??(typeof navigator>"u"?void 0:navigator)}function Oe(e){return{x:Math.round(e.x??e.left??0),y:Math.round(e.y??e.top??0),width:Math.round(e.width),height:Math.round(e.height)}}var te={alert:(e)=>b("dialog.alert",[e],()=>qe(e),{fallbackOnError:!0}).then(()=>{}),confirm:(e)=>b("dialog.confirm",[e],()=>ze(e),{fallbackOnError:!0}).then(Boolean),actionSheet:async(e)=>{let t={...e,anchor:e.anchor?Oe(e.anchor):void 0},n=await b("dialog.actionSheet",[t],()=>Ge(e),{fallbackOnError:!0});if(typeof n!=="string")return null;return e.actions.find((r)=>r.id===n)?.style==="cancel"?null:n}};function Pr(){return(e)=>te.actionSheet(e)}async function Lr(e){if((e.style??(e.destructive?"sheet":"alert"))==="alert")return te.confirm(e);return await te.actionSheet({title:e.title,message:e.message,anchor:e.anchor,actions:[{id:"confirm",title:e.confirmLabel||"OK",style:e.destructive?"destructive":"default"},{id:"cancel",title:e.cancelLabel||"Cancel",style:"cancel"}]})==="confirm"}var Pe={show:async(e)=>{let t={title:e.title,anchor:Oe(e.anchor),items:e.items.map(({id:r,title:o,symbol:i,destructive:a,disabled:s})=>({id:r,title:o,symbol:i,destructive:a,disabled:s}))},n=await b("contextMenu.show",[t],()=>Ye(e),{fallbackOnError:!0});return typeof n==="string"?n:null}};function Cr(e,t){return Pe.show({...t,anchor:Oe(e.getBoundingClientRect())})}function Xt(e,t){let n=A();if(!n)return{cancelled:!0};if(typeof n.craft?.openURL==="function")return Promise.resolve(n.craft.openURL(e)).catch(()=>{}),{cancelled:!1};if(t.mode==="auth")return n.location?.assign(e),{cancelled:!1};if(!(typeof n.open==="function"?n.open(e,"_blank","noopener"):null))n.location?.assign(e);return{cancelled:!1}}var Ze={open:async(e,t={})=>{let n=await b("browser.open",[e,t],()=>Xt(e,t),{fallbackOnError:!0});if(!n||typeof n!=="object")return{cancelled:!1};let{url:r,cancelled:o}=n;return typeof r==="string"?{url:r,cancelled:Boolean(o)}:{cancelled:Boolean(o)}}},Ee=new Map,Te=new Map;function Xe(e,t){return`${e}|${t.pointSize??""}|${t.weight??""}|${t.color??""}|${t.scale??""}`}var et={isAvailable:()=>C("symbols.image")!==null,image:(e,t={})=>{let n=Xe(e,t),r=Ee.get(n);if(r)return r;let o=b("symbols.image",[e,t],_).then((i)=>typeof i==="string"&&i.startsWith("data:")?i:null,_).then((i)=>(Te.set(n,i),i));return Ee.set(n,o),o},cached:(e,t={})=>Te.get(Xe(e,t)),clearCache:()=>{Ee.clear(),Te.clear()}},de={setStyle:(e)=>b("statusBar.setStyle",[e],P,{fallbackOnError:!0}).then((t)=>t!==!1)},ne={setUnderPageColor:(e)=>b("chrome.setUnderPageColor",[e],P,{fallbackOnError:!0}).then((t)=>t!==!1),setKeyboardAccessory:(e)=>b("chrome.setKeyboardAccessory",[e],P,{fallbackOnError:!0}).then((t)=>t!==!1)},U={isAvailable:()=>C("refresh.enable")!==null,enable:(e)=>b("refresh.enable",[e??{}],P,{fallbackOnError:!0}).then((t)=>t!==!1),disable:()=>b("refresh.disable",[],P,{fallbackOnError:!0}).then((e)=>e!==!1),end:()=>b("refresh.end",[],P,{fallbackOnError:!0}).then((e)=>e!==!1),onRefresh:(e)=>D("craftRefresh",()=>e())},re={complete:(e)=>b("background.complete",[e],P,{fallbackOnError:!0}).then((t)=>t!==!1)},tt={write:(e)=>b("clipboard.write",[e],async()=>{let t=Ve()?.clipboard;if(!t?.writeText)return!1;return t.writeText(e).then(Je,P)},{fallbackOnError:!0}).then((t)=>t!==!1),read:()=>b("clipboard.read",[],async()=>{let e=Ve()?.clipboard;if(!e?.readText)return null;return e.readText().catch(_)},{fallbackOnError:!0}).then((e)=>typeof e==="string"?e:null)},nt={isAvailable:()=>C("db.query")!==null,query:(e,t=[])=>b("db.query",[e,t],_).then((n)=>Array.isArray(n)?n:null),execute:(e,t=[])=>b("db.execute",[e,t],_).then((n)=>{if(!n||typeof n!=="object")return null;let{rowsAffected:r,lastInsertId:o}=n;return{rowsAffected:Number(r)||0,lastInsertId:Number(o)||0}})};function Ie(e,t){let n=A()?.document;if(!n?.body)return null;let r=n.createElement("a");return r.href=e,r.download=t,r.rel="noopener",r.style.display="none",n.body.appendChild(r),r.click(),r.remove(),t}function Qt(e){let t=A()?.document;if(!t?.body)return Promise.resolve(null);return new Promise((n)=>{let r=t.createElement("input");if(r.type="file",r.style.display="none",e.length)r.accept=e.map((i)=>i.includes("/")||i.startsWith(".")?i:`.${i}`).join(",");let o=(i)=>{r.remove(),n(i)};r.addEventListener("cancel",()=>o(null)),r.addEventListener("change",()=>{let i=r.files?.[0];if(!i)return o(null);let a=new FileReader;a.onload=()=>o({name:i.name,mimeType:i.type||void 0,data:typeof a.result==="string"?a.result:void 0}),a.onerror=()=>o({name:i.name,mimeType:i.type||void 0}),a.readAsDataURL(i)}),t.body.appendChild(r),r.click()})}var rt={openPDF:(e,t=0)=>b("openPDF",[e,t],()=>{let n=A();return Boolean(n?.open?.(e,"_blank","noopener"))}).then((n)=>n!==!1),takeScreenshot:()=>b("takeScreenshot",[],_,{fallbackOnError:!0}).then((e)=>typeof e==="string"?e:null),scanQRCode:()=>b("scanQRCode",[],_).then((e)=>{if(!e||typeof e!=="object")return null;let{type:t,data:n}=e;return typeof n==="string"?{type:String(t??""),data:n}:null},_),pickFile:(e=[])=>b("pickFile",[e],()=>Qt(e)).then((t)=>{if(!t||typeof t!=="object")return null;let n=t;if(typeof n.name!=="string")return null;return{name:n.name,path:typeof n.path==="string"?n.path:void 0,data:typeof n.data==="string"?n.data:void 0,mimeType:typeof n.mimeType==="string"?n.mimeType:void 0}},_),saveFile:(e,t,n)=>b("saveFile",[e,t,n],()=>{if(e.startsWith("data:"))return Ie(e,t);let r=new Blob([e],{type:n||"text/plain"}),o=URL.createObjectURL(r),i=Ie(o,t);return setTimeout(()=>URL.revokeObjectURL(o),1000),i}).then((r)=>typeof r==="string"?r:null),downloadFile:(e,t)=>b("downloadFile",[e,t],()=>Ie(e,t)).then((n)=>typeof n==="string"?n:null)},ot={set:(e)=>b("shortcuts.set",[e.map(({symbol:t,...n})=>t?{...n,iconName:t}:n)],P).then((t)=>t!==!1),clear:()=>b("shortcuts.clear",[],P).then((e)=>e!==!1),onShortcut:(e)=>D("craftShortcut",(t)=>{if(typeof t.type==="string")e(t.type)})},it={update:(e)=>b("widget.update",[e],P).then((t)=>t!==!1),reload:()=>b("widget.reload",[],P).then((e)=>e!==!1)},Jt={portrait:"portrait-primary",portraitUpsideDown:"portrait-secondary",landscape:"landscape",landscapeLeft:"landscape-primary",landscapeRight:"landscape-secondary"};function Qe(){return A()?.screen?.orientation}var at={lock:(e)=>b("lockOrientation",[e],()=>{let t=Qe();return t?.lock?t.lock(Jt[e]).then(Je,P):!1}).then((t)=>t!==!1),unlock:()=>b("unlockOrientation",[],()=>(Qe()?.unlock?.(),!0)).then((e)=>e!==!1)},st={signInWithApple:(e={})=>b("signInWithApple",e.nonce?[{nonce:e.nonce}]:[],_).then((t)=>{if(!t||typeof t!=="object"||typeof t.userId!=="string")return null;return t})},lt={isAvailable:()=>C("iap.purchase")!==null,products:(e)=>b("iap.getProducts",[e],()=>[]).then((t)=>Array.isArray(t)?t:[]),purchase:(e)=>b("iap.purchase",[e],_).then((t)=>t&&typeof t==="object"?t:null,(t)=>{if(/cancel/i.test(String(t?.message??t)))return null;throw t}),restore:()=>b("iap.restore",[],()=>[]).then((e)=>Array.isArray(e)?e:[])};import{storage as W}from"craft-native/mobile";function ct(){return V()?.capabilities?.storageCompareAndSet===!0&&W.supportsCompareAndSet?.()===!0}function ut(){return V()?.capabilities?.storageSetIfAbsent===!0&&W.supportsSetIfAbsent?.()===!0}var dt={supportsCompareAndSet:ct,supportsSetIfAbsent:ut,get:(e)=>u(()=>W.get(e)),set:(e,t)=>u(()=>W.set(e,t)),remove:(e)=>u(()=>W.remove(e)),clear:()=>u(()=>W.clear()),keys:()=>u(()=>W.keys()),setIfAbsent:(e,t)=>u(()=>{if(!ut())throw Object.assign(Error("This host or adapter cannot create storage atomically"),{code:"STORAGE_SET_IF_ABSENT_UNSUPPORTED"});return W.setIfAbsent(e,t)}),compareAndSet:(e,t,n)=>u(()=>{if(!ct())throw Object.assign(Error("This host or adapter cannot compare storage atomically"),{code:"STORAGE_COMPARE_AND_SET_UNSUPPORTED"});return W.compareAndSet(e,t,n)})};import{crypto as Zt}from"craft-native/mobile";var pt={randomUUID:()=>u(()=>Zt.randomUUID())};var en=["authorized","denied","notDetermined","restricted","unsupported"];function pe(){let e=V(),t=e?.scheduledWorkouts;if(!t||typeof t!=="object"||e?.capabilities?.scheduledWorkouts!==!0)return;return t}function tn(){return Object.assign(Error("unsupported"),{code:"UNSUPPORTED"})}function ft(e){return en.includes(e)?e:"unsupported"}function nn(e){if(!e||typeof e!=="object")return null;let t=e;if(typeof t.id!=="string"||!t.id||typeof t.date!=="string"||!/^\d{4}-\d{2}-\d{2}$/.test(t.date))return null;let n={id:t.id.toLowerCase(),date:t.date,complete:t.complete===!0};if(typeof t.hour==="number"&&Number.isFinite(t.hour))n.hour=t.hour;if(typeof t.minute==="number"&&Number.isFinite(t.minute))n.minute=t.minute;return n}function Q(e,t,...n){return u(async()=>{let r=pe();if(typeof r?.[e]!=="function")throw tn();return t(await r[e](...n))})}var mt={isAvailable:()=>typeof pe()?.isSupported==="function",supports:(e)=>typeof pe()?.[e]==="function",isSupported:()=>u(async()=>{let e=pe();if(typeof e?.isSupported!=="function")return!1;try{return await e.isSupported()===!0}catch{return!1}}),authorization:()=>Q("authorization",ft),requestAuthorization:()=>Q("requestAuthorization",ft),list:()=>Q("list",(e)=>Array.isArray(e)?e.map(nn).filter((t)=>t!==null):[]),schedule:(e)=>{if(!e||typeof e!=="object"||typeof e.id!=="string")return Promise.reject(Object.assign(Error("schedule needs a plan with an id"),{code:"INVALID_ARGUMENT"}));return Q("schedule",(t)=>{let n=t&&typeof t==="object"?t:{},r={id:(typeof n.id==="string"?n.id:e.id).toLowerCase()};if(Array.isArray(n.droppedAlerts)&&n.droppedAlerts.length)r.droppedAlerts=n.droppedAlerts.filter((o)=>typeof o==="string");return r},e)},remove:(e)=>Q("remove",(t)=>t===!0,e),removeAll:()=>Q("removeAll",(e)=>typeof e==="number"&&Number.isFinite(e)?e:0)};function Kr(e,t){let n=t.delay??500,r=t.tolerance??10,o=null,i=null,a=!1,s=()=>{if(o)clearTimeout(o);if(o=null,i&&!a)t.onPressEnd?.();i=null},l=(g)=>{let c=g;if(c.button!==void 0&&c.button!==0)return;a=!1,i={x:c.clientX,y:c.clientY},t.onPressStart?.(),o=setTimeout(()=>{if(o=null,!i)return;a=!0,t.onLongPress({...i}),i=null},n)},m=(g)=>{if(!i)return;let c=g;if(Math.hypot(c.clientX-i.x,c.clientY-i.y)>r)s()},f=(g)=>{if(!a)return;a=!1,g.preventDefault(),g.stopPropagation()},d=(g)=>g.preventDefault();return e.addEventListener("pointerdown",l),e.addEventListener("pointermove",m),e.addEventListener("pointerup",s),e.addEventListener("pointercancel",s),e.addEventListener("pointerleave",s),e.addEventListener("click",f,!0),e.addEventListener("contextmenu",d),()=>{s(),e.removeEventListener("pointerdown",l),e.removeEventListener("pointermove",m),e.removeEventListener("pointerup",s),e.removeEventListener("pointercancel",s),e.removeEventListener("pointerleave",s),e.removeEventListener("click",f,!0),e.removeEventListener("contextmenu",d)}}function rn(e,t,n){if(n<=1||t.width<=0)return 0;let r=Math.floor((e-t.left)/t.width*n);return Math.max(0,Math.min(n-1,r))}function jr(e,t){let n=null,r=null,o=!1,i=0,a=(c)=>{let p=e.getBoundingClientRect();return rn(c,{left:p.left+2,width:p.width-4},t.count())},s=(c)=>{let p=c;if(p.button!==void 0&&p.button!==0)return;let v=a(p.clientX);if(v!==t.selected())return;n=v,i=v,o=!1,r=p.pointerId;try{e.setPointerCapture?.(p.pointerId)}catch{}t.onPress?.(!0)},l=(c)=>{if(n===null)return;let p=a(c.clientX);if(p===i)return;o=!0,i=p,t.onScrub(p)},m=(c)=>{if(n===null)return;if(r!==null)try{e.releasePointerCapture?.(r)}catch{}if(t.onPress?.(!1),c&&o)t.onCommit(i);else if(o)t.onScrub(n);n=null,r=null},f=(c)=>{if(!o)return;o=!1,c.preventDefault(),c.stopPropagation()},d=()=>m(!0),g=()=>m(!1);return e.addEventListener("pointerdown",s),e.addEventListener("pointermove",l),e.addEventListener("pointerup",d),e.addEventListener("pointercancel",g),e.addEventListener("click",f,!0),()=>{e.removeEventListener("pointerdown",s),e.removeEventListener("pointermove",l),e.removeEventListener("pointerup",d),e.removeEventListener("pointercancel",g),e.removeEventListener("click",f,!0)}}function qr(e,t,n){if(n<=0)return null;switch(e){case"ArrowRight":case"ArrowDown":return(t+1)%n;case"ArrowLeft":case"ArrowUp":return(t-1+n)%n;case"Home":return 0;case"End":return n-1;default:return null}}function zr(e,t){e.querySelectorAll('[role="tab"]')[t]?.focus()}function Gr(e){let t=(n)=>{if(!n.target?.closest?.("[data-native-pressable]"))return;let o=C("haptics.prepare");if(o)Promise.resolve().then(()=>o("impact")).catch(()=>{})};return e.addEventListener("touchstart",t,{passive:!0,capture:!0}),()=>e.removeEventListener("touchstart",t,{capture:!0})}import{BugHQClient as on}from"@bughq/sdk";import{crashReporter as J}from"craft-native/mobile";var M=null;function an(e){if(e.type!=="http")return!0;let t=e.data??{},n=typeof t.status==="number"?t.status:0;return t.error===!0||n>=400||n===0}function gt(){return J.isAvailable()}function sn(e){return async(t)=>{if(!gt())return!e;return J.capture(t)}}var Jr={start(e={}){if(M)return M;let t=ee()||gt();if(!t&&!e.key&&!e.dsn)return null;let n=e.beforeBreadcrumb;return M=new on({framework:"stacks-mobile",sdkName:"bughq.stacks.mobile",autoInstrument:{navigation:!0,fetch:!0,xhr:!0},...e,heartbeat:t?!1:e.heartbeat,transport:t?sn(Boolean(e.key||e.dsn)):void 0,beforeBreadcrumb(r){if(!an(r))return null;let o=n?n(r):r;if(o===null)return null;let i=o||r;if(t)J.addBreadcrumb(i);return i}}),M},async setUser(e){let t=e===null||e===void 0||e===""?null:String(e);M?.setUser(t===null?null:{id:t}),await J.setUser(t)},capture(e,t){M?.captureException(e,t)},addBreadcrumb(e){if(M)M.addBreadcrumb(e);else J.addBreadcrumb(e)},async flush(){await Promise.all([M?.flush(),J.flush()])},client(){return M},stop(){M?.close(),M=null}};function Le(e){let t=A();try{return Boolean(t?.matchMedia?.(e).matches)}catch{return!1}}function ht(e){return e!==null&&e!==void 0&&e!=="false"&&e!=="0"}function bt(){let e=A()?.document?.documentElement,t=Number.parseFloat(e?.style?.getPropertyValue("--craft-font-scale")||"");return{fontScale:Number.isFinite(t)&&t>0?t:1,reduceMotion:ht(e?.getAttribute("data-craft-reduce-motion"))||Le("(prefers-reduced-motion: reduce)"),reduceTransparency:ht(e?.getAttribute("data-craft-reduce-transparency"))||Le("(prefers-reduced-transparency: reduce)"),colorScheme:e?.classList?.contains("dark")||Le("(prefers-color-scheme: dark)")?"dark":"light"}}function ln(e){let t=bt(),n=Number(e?.fontScale);return{contentSizeCategory:typeof e?.contentSizeCategory==="string"?e.contentSizeCategory:void 0,fontScale:Number.isFinite(n)&&n>0?n:t.fontScale,reduceMotion:typeof e?.reduceMotion==="boolean"?e.reduceMotion:t.reduceMotion,reduceTransparency:typeof e?.reduceTransparency==="boolean"?e.reduceTransparency:t.reduceTransparency,colorScheme:e?.colorScheme==="dark"||e?.colorScheme==="light"?e.colorScheme:t.colorScheme}}function vt(e,t={}){if(t.immediate!==!1)e(bt());return D("craftAppearance",(n)=>e(ln(n)))}function no(e){return D("craftResume",(t)=>e({backgroundedMs:Number(t.backgroundedMs)||0}))}function ro(e){return D("craftMemoryWarning",()=>e())}function yt(e){return(t)=>{Promise.resolve().then(()=>e(t)).then(()=>re.complete(!0),()=>re.complete(!1))}}function oo(e){let t=yt(e);return D("craftSilentPush",(n)=>t(n.payload??{}))}function io(e){let t=yt(()=>e());return D("craftBackgroundRefresh",()=>t(void 0))}import{haptics as cn}from"craft-native/mobile";function Ce(){if(typeof window>"u")return;return window}function oe(e=Ce()){if(!e)return 0;if(typeof e.scrollY==="number")return e.scrollY;if(typeof e.scrollTop==="number")return e.scrollTop;return e.document?.scrollingElement?.scrollTop??0}function un(e,t=Ce()){if(!t)return()=>{};let n=!1,r=typeof requestAnimationFrame==="function"?requestAnimationFrame:(i)=>setTimeout(i,16),o=()=>{if(n)return;n=!0,r(()=>{n=!1,e(oe(t))})};return e(oe(t)),t.addEventListener("scroll",o,{passive:!0}),()=>t.removeEventListener("scroll",o)}function dn(e,t){let n=Math.max(0,-e),r=e<=0?Math.max(0,t)*0.5:0;return Math.round(Math.max(n,r))}function lo(e){let t=e.host??Ce();if(!t)return()=>{};let n=e.threshold??72,r=null,o=!1,i=!1,a=typeof requestAnimationFrame==="function"?requestAnimationFrame:(v)=>setTimeout(v,16),s=null,l=(v)=>{s=null,e.onPull?.(v,o,{bounce:Math.min(v,Math.max(0,-oe(t)))})},m=(v)=>{let k=s!==null;if(s=v,k)return;a(()=>{if(s!==null)l(s)})},f=(v)=>{let k=v.touches?.[0];return k?k.clientY:null},d=(v)=>{if(i||oe(t)>0)return;r=f(v),o=!1},g=(v)=>{if(r===null)return;let k=f(v);if(k===null)return;let F=dn(oe(t),k-r);if(!o&&F>=n)o=!0,Promise.resolve(cn.impact("medium")).catch(()=>{});else if(o&&F<n*0.8)o=!1;m(F)},c=async()=>{if(r===null)return;if(r=null,!o){l(0);return}o=!1,i=!0,l(n);try{await e.onRefresh()}finally{i=!1,l(0)}},p=()=>{if(r===null)return;r=null,o=!1,l(0)};return t.addEventListener("touchstart",d,{passive:!0}),t.addEventListener("touchmove",g,{passive:!0}),t.addEventListener("touchend",c),t.addEventListener("touchcancel",p),()=>{s=null,t.removeEventListener("touchstart",d),t.removeEventListener("touchmove",g),t.removeEventListener("touchend",c),t.removeEventListener("touchcancel",p)}}function pn(e,t=52){let n=Math.max(1,t),r=Math.min(1,Math.max(0,e/n)),o=e<0?1+Math.min(0.1,-e/600):1;return{progress:Math.round(r*1000)/1000,stretch:Math.round(o*1000)/1000}}function co(e,t={}){let n="",r=()=>t.title?.offsetHeight||t.height||52;return un((o)=>{let i=pn(o,r()),a=`${i.progress}|${i.stretch}`;if(a===n)return;n=a,e.style.setProperty("--native-nav-progress",String(i.progress)),e.style.setProperty("--native-nav-stretch",String(i.stretch)),t.onChange?.(i)},t.host)}function uo(e){if(!e||typeof window>"u")return;let t=window.document?.querySelector(e);return t?t:void 0}function xt(){if(typeof window>"u")return;return window}var St="__stxPushed",fn="__stxScroll";function mn(e=xt()){let t=e?.history?.state;if(t===null||t===void 0)return!1;if(typeof t!=="object")return!0;let n=t;if(St in n)return n[St]===!0;return!(fn in n)}function fo(e=xt()){if(!mn(e))return!1;return e.history.back(),!0}function mo(e,t,n=50){let r=e[e.length-1];if(e.length>=2&&e[e.length-2].path===t)e.pop();else if(!r||r.path!==t)e.push({path:t,title:""});if(e.length>n)e.splice(0,e.length-n);return{current:e[e.length-1],previous:e[e.length-2]??null}}function go(e,t,n=12){let r=e?.title.trim()??"";return r&&r.length<=n?r:t}function ho(){if(typeof window>"u")return[];let e=window;return e.__stacksNavTrail??=[]}function gn(e){try{let t=new URL(e,"http://local");return`${t.pathname}${t.search}`}catch{return e}}function bo(){if(typeof window>"u")return;let e=window.stxRouter;if(typeof e?.screens!=="function")return;let t=e.screens(),n=t.find((o)=>o.active);if(!n)return;let r=t.filter((o)=>o.tab===n.tab&&o.depth<n.depth);if(!r.length)return null;return gn(r.reduce((o,i)=>i.depth>o.depth?i:o).url)}function vo(e=typeof window>"u"?void 0:window){let t=e?.stxRouter;if(typeof t?.screens!=="function"||typeof e?.history?.go!=="function")return!1;let n=t.screens(),r=n.find((a)=>a.active);if(!r)return!1;let o=n.filter((a)=>a.tab===r.tab&&a.depth<r.depth);if(!o.length)return!1;let i=o.reduce((a,s)=>s.depth<a.depth?s:a);return e.history.go(i.depth-r.depth),!0}function yo(e,t){for(let n=e.length-1;n>=0;n--)if(e[n].path===t)return e[n];return null}function hn(e,t=bn()){let n;try{n=new URL(e)}catch{return null}let r=`${n.search}${n.hash}`;if(n.protocol==="http:"||n.protocol==="https:"){if(!t||n.origin!==t)return null;return`${n.pathname||"/"}${r}`}return`${`/${[n.host,n.pathname.replace(/^\/+/,"")].filter(Boolean).join("/")}`}${r}`}function bn(){if(typeof window>"u")return;return window.location?.origin}var wt="stacks-mobile-deep-link";function So(e,t){let n=(r)=>{let o=hn(r);if(o)e(o)};return t.getInitialURL().then((r)=>{if(!r)return;try{if(sessionStorage.getItem(wt)===r)return;sessionStorage.setItem(wt,r)}catch{}n(r)}).catch(()=>{}),t.onLink((r,o)=>{if(o?.initial)return;n(r)})}var xo=5000;function vn(e,t,n=5000){let r=t.filter((o)=>Number.isFinite(o.timestamp)&&Number.isFinite(o.bpm)&&o.bpm>0).slice().sort((o,i)=>o.timestamp-i.timestamp);if(!r.length)return e.slice();return e.map((o)=>{let i=0,a=r.length;while(i<a){let f=i+a>>1;if(r[f].timestamp<o.timestamp)i=f+1;else a=f}let s=r[i],l=r[i-1],m=!s?l:!l?s:o.timestamp-l.timestamp<=s.timestamp-o.timestamp?l:s;if(!m||Math.abs(m.timestamp-o.timestamp)>n)return o;return{...o,heartRate:Math.round(m.bpm)}})}var yn=6371008.8,Sn=30,wn=Sn;function xn(e,t){let n=Math.PI/180,r=(t.latitude-e.latitude)*n,o=(t.longitude-e.longitude)*n,i=Math.sin(r/2)**2+Math.cos(e.latitude*n)*Math.cos(t.latitude*n)*Math.sin(o/2)**2;return 2*yn*Math.asin(Math.min(1,Math.sqrt(i)))}function An(e,t=25){let n=new Set;return e.filter((r)=>Number.isFinite(r.latitude)&&Number.isFinite(r.longitude)&&Number.isFinite(r.timestamp)&&Math.abs(r.latitude)<=90&&Math.abs(r.longitude)<=180&&Number.isFinite(r.accuracy)&&r.accuracy>=0&&r.accuracy<=t).sort((r,o)=>r.timestamp-o.timestamp).filter((r)=>{if(n.has(r.timestamp))return!1;return n.add(r.timestamp),!0})}function Me(e,t={}){let n=An(e,t.maxAccuracyM??25),r=t.paceWindowS??30,o=[],i=0,a=0,s=null;for(let d of n){let g=o[o.length-1],c=s?(d.timestamp-s.timestamp)/1000:0;if(s=d,!g){o.push({fix:d,cumM:0});continue}if(c>wn){o.push({fix:d,cumM:i});continue}let p=(d.timestamp-g.fix.timestamp)/1000,v=xn(g.fix,d),k=Math.min(10,Math.max(3,g.fix.accuracy,d.accuracy));if(v<k)continue;if(i+=v,p>0&&v/p>=0.5)a+=p;o.push({fix:d,cumM:i})}let l=o[o.length-1],m=null,f=null;if(l&&n.at(-1).timestamp-l.fix.timestamp<=r*1000){let d=l.fix.timestamp-r*1000,g=o.find((v)=>v.fix.timestamp>=d)??l,c=l.cumM-g.cumM,p=(l.fix.timestamp-g.fix.timestamp)/1000;if(c>=20&&p>0)f=c/p,m=p/(c/1000)}return{distanceM:i,movingS:a,paceSPerKm:m,averagePaceSPerKm:i>=50&&a>0?a/(i/1000):null,speedMps:f,accuracyM:n.length?n[n.length-1].accuracy:e.length?e[e.length-1].accuracy??null:null,fixes:n.length}}function Ao(e){if(e==null||e<=0||!Number.isFinite(e)||e>3600)return"–";let t=Math.round(e);return`${Math.floor(t/60)}:${String(t%60).padStart(2,"0")}`}function Ro(e){return e!=null&&e>0&&Number.isFinite(e)?(e*3.6).toFixed(1):"–"}var At={distanceM:0,movingS:0,paceSPerKm:null,averagePaceSPerKm:null,speedMps:null,accuracyM:null,fixes:0};function ko(e){let t=e.location,n=e.intervalMs??3000,r=At,o=null,i=e.heartRate,a=!1,s=null,l=[],m=()=>typeof document<"u"&&document.visibilityState==="hidden",f=0,d=null,g=Promise.resolve(),c=null,p=!1,v=null;function k(){if(p)throw Object.assign(Error("The recording screen is no longer active"),{code:"RECORDING_CONFLICT"});if(t.supportsRecordingOwnership?.()!==!0)throw Object.assign(Error("This host cannot protect native recording ownership"),{code:"RECORDING_OWNERSHIP_UNSUPPORTED"})}function F(){if(k(),!v)throw Object.assign(Error("A saved recording ID is required"),{code:"RECORDING_CONFLICT"});return v}function z(h){let S=g.then(h);return g=S.then(()=>{},()=>{}),S}function Z(){if(d)return d;let h=f,S=v,T=(async()=>{if(k(),!S)throw Object.assign(Error("A saved recording ID is required"),{code:"RECORDING_CONFLICT"});let O=await t.readRecording({expectedId:S}),L=Me(O,e);if(h===f&&!p)r=L,e.onUpdate?.(r);return L})().finally(()=>{if(d===T)d=null});return d=T,T}function y(){if(w(),p)return;o=setInterval(()=>{if(!m())Z().catch(()=>{})},n)}function w(){if(o)clearInterval(o);o=null}function x(h,S,T){if(w(),f++,d=null,v=h,s=S,a=S!==null,l=[],r=T,!p)e.onUpdate?.(r)}async function E(h){if(!i||!a||!s||p||i.supportsRecordingOwnership?.()!==!0)return;await h(i,s).catch(()=>{})}return{get stats(){return r},get recordingId(){return v},get heartRateRecordingId(){return s},get heartRate(){return l},start(h){return c=null,z(async()=>{if(k(),h&&t.supportsRecordingIntentIdentity?.()!==!0)throw Object.assign(Error("This host cannot start a registered route identity"),{code:"RECORDING_INTENT_IDENTITY_UNSUPPORTED"});if(h&&(typeof h.recordingId!=="string"||!h.recordingId.trim()))throw Object.assign(Error("A registered recording ID is required"),{code:"INVALID_ARGUMENT"});let S=await t.startRecording({enableHighAccuracy:!0,...e.locationOptions,...h?{recordingId:h.recordingId}:{}});if(!S?.active||typeof S.id!=="string"||!S.id.trim())throw Object.assign(Error("The native recording did not provide an ID"),{code:"RECORDING_CONFLICT"});if(h&&S.id!==h.recordingId)throw Object.assign(Error("The native route did not start with its registered ID"),{code:"RECORDING_CONFLICT"});let T=null;if(!p&&i?.isAvailable()&&i.supportsRecordingOwnership?.()===!0&&(!h||h.heartRateRecordingId&&i.supportsRecordingIntentIdentity?.()===!0))try{let O=await i.startRecording(h?{recordingId:h.heartRateRecordingId}:void 0);if(h&&O.id!==h.heartRateRecordingId)throw Object.assign(Error("The native heart rate did not start with its registered ID"),{code:"RECORDING_CONFLICT"});if(O.active&&typeof O.id==="string"&&O.id.trim())T=O.id}catch{}return x(S.id,T,{...At}),y(),r})},attach(h){return c=null,z(async()=>{if(typeof h?.expectedId!=="string"||!h.expectedId.trim())throw Object.assign(Error("A saved recording ID is required"),{code:"RECORDING_CONFLICT"});k();let S=await t.getRecordingState({expectedId:h.expectedId});if(k(),!S?.id)return null;if(S.id!==h.expectedId)throw Object.assign(Error("The recording belongs to another session"),{code:"RECORDING_CONFLICT"});let T=null;if(h.expectedHeartRateId!==void 0){let L=h.expectedHeartRateId;if(typeof L!=="string"||!L.trim())throw Object.assign(Error("A saved heart-rate recording ID is required"),{code:"RECORDING_CONFLICT"});if(!i?.isAvailable()||i.supportsRecordingOwnership?.()!==!0)throw Object.assign(Error("This host cannot protect heart-rate recording ownership"),{code:"RECORDING_OWNERSHIP_UNSUPPORTED"});let Ut=await i.getRecordingState({expectedId:L});if(k(),Ut.id!==L)throw Object.assign(Error("The heart-rate recording belongs to another session"),{code:"RECORDING_CONFLICT"});await i.readRecording({expectedId:L,since:Date.now()}),k(),T=L}let O=await t.readRecording({expectedId:h.expectedId});if(k(),x(h.expectedId,T,Me(O,e)),S.active&&!S.paused)y();return S})},pause(){return z(async()=>{await t.pauseRecording({expectedId:F()}),await E((h,S)=>h.pauseRecording({expectedId:S})),w(),await Z().catch(()=>{})})},resume(){return z(async()=>{await t.resumeRecording({expectedId:F()}),await E((h,S)=>h.resumeRecording({expectedId:S})),y()})},stop(){if(c)return c;let h=z(async()=>{w(),f++;let S=F(),T=await t.stopRecording({expectedId:S});if(T.id!==S)throw Object.assign(Error("The native recording identity changed"),{code:"RECORDING_CONFLICT"});let O=T?.locations??[];if(!p&&i&&a&&s&&i.supportsRecordingOwnership?.()===!0){let L=await i.stopRecording({expectedId:s}).catch(()=>null);a=!1,l=L?.id===s?L.samples:[],O=vn(O,l)}if(r=Me(O,e),!p)e.onUpdate?.(r);return O}).catch((S)=>{if(c===h)c=null;throw S});return c=h,h},dispose(){p=!0,f++,d=null,w()},refresh:Z}}function To(e){return{startedAt:Number.isFinite(e)?e:null,pausedAt:null,pausedMs:0}}function Io(e,t){return e.startedAt===null||e.pausedAt!==null||!Number.isFinite(t)?e:{...e,pausedAt:Math.max(e.startedAt,t)}}function Oo(e,t){return e.pausedAt===null||!Number.isFinite(t)?e:{...e,pausedAt:null,pausedMs:e.pausedMs+Math.max(0,t-e.pausedAt)}}function Po(e,t){if(e.startedAt===null)return 0;let n=((e.pausedAt??t)-e.startedAt-e.pausedMs)/1000;return Number.isFinite(n)?Math.max(0,n):0}var Co=150;function Rn(e,t){let n=Math.PI/180,r=(t.latitude-e.latitude)*n,o=(t.longitude-e.longitude)*n,i=Math.sin(r/2)**2+Math.cos(e.latitude*n)*Math.cos(t.latitude*n)*Math.sin(o/2)**2;return 12742017.6*Math.asin(Math.min(1,Math.sqrt(i)))}function fe(e,t){let n=[...e].sort((r,o)=>r-o);return n[Math.min(n.length-1,Math.floor(t*n.length))]}function Mo(e,t){let n=(e||[]).filter((a)=>Number.isFinite(a?.latitude)&&Number.isFinite(a?.longitude)&&Math.abs(a.latitude)<=90&&Math.abs(a.longitude)<=180),r=n.filter((a)=>a.accuracy!=null).map((a)=>Number(a.accuracy)).filter((a)=>Number.isFinite(a)&&a>=0),o=r.length?fe(r,0.5):Number.POSITIVE_INFINITY,i=0;if(n.length){let a={latitude:fe(n.map((s)=>s.latitude),0.5),longitude:fe(n.map((s)=>s.longitude),0.5)};i=fe(n.map((s)=>Rn(a,s)),0.8)}if(n.length>=10&&i>150&&o<=15)return"outside";if(t<150)return"unsure";if(n.length<3||o>30||i<25)return"indoors";if(i<50&&o>10)return"indoors";return"unsure"}function No(e,t={}){let r=String(e||"").trim().toLowerCase().replace(",",".").match(/^(\d+(?:\.\d*)?|\.\d+)\s*(km|k|m|mi)?$/);if(!r)return null;let o=Number(r[1]),i=r[2]||t.defaultUnit||(o>100?"m":"km"),a=i==="m"?o/1000:i==="mi"?o*1.609344:o;return Number.isFinite(a)&&a>=0&&a<=2000?Math.round(a*1000)/1000:null}var he=new Set,Rt=!1,me=null;function kn(e){return e.isConnected&&e.getClientRects().length>0}function kt(){return[...he].find((e)=>kn(e.element))}function ge(){let e=kt(),t=Boolean(e);if(t===Rt)return;if(Rt=t,t)U.enable(e?.tintColor?{tintColor:e.tintColor}:{});else U.disable()}function En(){let e=kt();if(!e){U.end();return}Promise.resolve().then(()=>e.run()).catch(()=>{}).finally(()=>U.end())}function _o(e,t){let n={element:e,tintColor:t.tintColor,run:t.onRefresh};he.add(n);let r=e.ownerDocument?.defaultView;if(!me){let o=U.onRefresh(En),i=()=>ge();r?.addEventListener("stx:load",i),me=()=>{o(),r?.removeEventListener("stx:load",i)}}return ge(),r?.requestAnimationFrame?.(()=>ge()),()=>{if(he.delete(n),he.size===0)me?.(),me=null;ge()}}var Fo=0.5;function Tn(e,t,n){let r=[];if(n.includes("large")||n.length===0)r.push({name:"large",y:0});if(n.includes("medium"))r.push({name:"medium",y:Math.max(0,Math.round(e-t*0.5))});return r.push({name:"dismiss",y:Math.max(1,e)}),r.sort((o,i)=>o.y-i.y)}function In(e){let{y:t,velocity:n,stops:r}=e,o=r.filter((s)=>s.name!=="dismiss"),i=r.find((s)=>s.name==="dismiss");if(o.length===0)return"dismiss";if(n>0.5)return(r.filter((l)=>l.y>t+1)[0]??i).name;if(n<-0.5){let s=o.filter((l)=>l.y<t-1);return(s[s.length-1]??o[0]).name}let a=o[o.length-1];if(t>a.y+(i.y-a.y)*0.5)return"dismiss";return o.reduce((s,l)=>Math.abs(l.y-t)<Math.abs(s.y-t)?l:s).name}function On(e,t=400){if(e<=0)return 0;return e*t*0.55/(t+e*0.55)}function Wo(e){let{panel:t}=e,n=null,r=[],o=0,i=()=>e.viewport?.()??t.ownerDocument?.defaultView?.innerHeight??800,a=()=>Tn(t.offsetHeight||t.getBoundingClientRect().height,i(),e.detents()),s=(f)=>{let d=f;if(d.button!==void 0&&d.button!==0)return;if(d.target?.closest?.("button, a, input, select, textarea, [role=button]"))return;let g=a().find((c)=>c.name===e.detent())?.y??0;n={y:d.clientY,base:g,pointerId:d.pointerId},o=g,r=[{y:g,t:d.timeStamp}],t.classList.add("is-dragging");try{f.currentTarget?.setPointerCapture?.(d.pointerId)}catch{}},l=(f)=>{if(!n)return;let d=f,g=n.base+d.clientY-n.y;o=g<0?-On(-g):g,r.push({y:o,t:d.timeStamp});while(r.length>2&&d.timeStamp-r[0].t>100)r.shift();t.style.transform=`translateY(${o}px)`;let c=t.offsetHeight||1;t.parentElement?.style.setProperty("--native-sheet-presence",String(Math.max(0,Math.min(1,1-o/c))))},m=(f)=>{if(!n)return;let d=f;n=null;let g=r[0],c=Math.max(1,d.timeStamp-g.t),p=(o-g.y)/c;t.classList.remove("is-dragging"),t.style.transform="",t.parentElement?.style.removeProperty("--native-sheet-presence"),e.onSettle(In({y:o,velocity:p,stops:a()}))};for(let f of e.handles)f.addEventListener("pointerdown",s),f.addEventListener("pointermove",l),f.addEventListener("pointerup",m),f.addEventListener("pointercancel",m);return()=>{for(let f of e.handles)f.removeEventListener("pointerdown",s),f.removeEventListener("pointermove",l),f.removeEventListener("pointerup",m),f.removeEventListener("pointercancel",m)}}function Uo(e){let t=e.ownerDocument;if(e.parentElement===t.body)return()=>{};let n=t.createComment("native-sheet");return e.parentNode?.insertBefore(n,e),t.body.appendChild(e),()=>{if(n.parentNode)n.parentNode.insertBefore(e,n);else e.remove();n.remove()}}var Ne=new WeakMap;function $o(e,t){let n=e.documentElement,r=Ne.get(e)??0;if(!t){let a=Math.max(0,r-1);if(Ne.set(e,a),a===0)n.removeAttribute("data-native-sheet-card");return}if(Ne.set(e,r+1),r>0)return;let o=e.defaultView,i=(o?.scrollY??0)+(o?.innerHeight??800)/2;n.style.setProperty("--native-sheet-card-origin",`${Math.round(i)}px`),n.setAttribute("data-native-sheet-card","")}function Pn(e,t){e.style.setProperty("--native-font-scale",String(t.fontScale)),e.toggleAttribute("data-native-reduce-motion",t.reduceMotion),e.toggleAttribute("data-native-reduce-transparency",t.reduceTransparency)}function Ln(e){let t=e.replace(/\s+/g,"").toLowerCase();return!t||t==="transparent"||/^rgba\(\d+,\d+,\d+,0(\.0+)?\)$/.test(t)||/\/0(\.0+)?\)$/.test(t)}function Cn(e){let t=e.defaultView;if(!t?.getComputedStyle)return null;for(let n of[e.body,e.documentElement]){if(!n)continue;let r=t.getComputedStyle(n).backgroundColor;if(r&&!Ln(r))return r}return null}function Mn(e){if(e.documentElement.classList.contains("dark"))return!0;if(e.documentElement.classList.contains("light"))return!1;return Boolean(e.defaultView?.matchMedia?.("(prefers-color-scheme: dark)").matches)}function zo(e,t={}){let n=t.root??e.documentElement;ne.setKeyboardAccessory(t.keyboardAccessory===!0);let r="",o="",i=()=>{let f=Cn(e);if(f&&f!==r)r=f,ne.setUnderPageColor(f);let d=Mn(e)?"light":"dark";if(d!==o)o=d,de.setStyle(d)},a=vt((f)=>{Pn(n,f),i()}),s=e.defaultView,l=typeof s?.MutationObserver==="function"?new s.MutationObserver(i):null;l?.observe(e.documentElement,{attributes:!0,attributeFilter:["class","style","data-theme"]});let m=s?.matchMedia?.("(prefers-color-scheme: dark)");return m?.addEventListener?.("change",i),s?.addEventListener("stx:load",i),i(),()=>{a(),l?.disconnect(),m?.removeEventListener?.("change",i),s?.removeEventListener("stx:load",i)}}var Yo=64;var Nn=/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/,Hn=/^(?:0|[1-9]\d*)$/;function Tt(e){let t=[],n=[],r=e&&typeof e==="object"&&!Array.isArray(e)?e:{};for(let[o,i]of Object.entries(r)){let a=i&&typeof i==="object"?i:null;if(!a){n.push(`spotlight kind "${o}" is not an object`);continue}let{slots:s,route:l}=a,m=typeof a.noun==="string"&&a.noun.trim()?a.noun.trim():"Item";if(!Nn.test(o)||o.includes("-slot-")){n.push(`spotlight kind "${o}" is not a usable name: lowercase letters, digits and single dashes, and never "-slot-"`);continue}if(typeof s!=="number"||!Number.isInteger(s)||s<=0||s>64){n.push(`spotlight kind "${o}" needs slots between 1 and 64, not ${String(s)}`);continue}if(typeof l!=="string"||!l.startsWith("/")||!l.includes(":id")){n.push(`spotlight kind "${o}" needs a route starting with "/" and carrying ":id", not ${String(l)}`);continue}t.push({name:o,slots:s,route:l,noun:m})}return{kinds:t,problems:n}}function ae(e,t){return e.find((n)=>n.name===t)??null}function ie(e,t,n){let r=ae(e,t);if(!r||!Number.isInteger(n)||n<0||n>=r.slots)return null;return`${t}-slot-${n}`}function Dn(e,t){if(typeof t!=="string")return null;let n=t.lastIndexOf("-slot-");if(n<=0)return null;let r=t.slice(0,n),o=t.slice(n+6);if(!Hn.test(o))return null;let i=Number(o);return ie(e,r,i)===t?{kind:r,slot:i}:null}function It(e){return e.flatMap((t)=>Array.from({length:t.slots},(n,r)=>`${t.name}-slot-${r}`))}function Vo(e,t){let n=e&&typeof e==="object"?e:{};if(n.enabled===!1)return[];let o=[...(Array.isArray(n.activityTypes)?n.activityTypes.filter((i)=>typeof i==="string"&&i.trim().length>0):[]).map((i)=>i.trim()),...It(Tt(n.kinds).kinds)];return[...new Set(o)].map((i)=>`${t}.${i}`)}function Ot(e,t,n){let r=typeof n.name==="string"?n.name.replace(/\s+/g," ").trim():"";if(!r)return`${ae(e,t)?.noun??"Item"} #${n.id}`;return r.length>120?`${r.slice(0,119).trimEnd()}…`:r}function _n(e,t,n,r,o=Date.now()){let i=ae(e,n);if(!i||!Number.isInteger(r.id)||r.id<=0)return null;let a=t.filter((p)=>p.kind===n),s=Ot(e,n,r),l=a.find((p)=>p.itemId===r.id)??null,m=l?null:Un(a,i.slots),f=l||m!==null?null:$n(a),d=l?.slot??m??f?.slot;if(d===void 0||d===null)return null;let g={kind:n,slot:d,itemId:r.id,title:s,donatedAt:o},c=t.filter((p)=>p.kind!==n||p.slot!==d&&p.itemId!==r.id);return{entries:Pt(e,[...c,g]),entry:g,evicted:f,changed:!l||l.title!==s}}function Bn(e,t,n){let r=e.find((o)=>o.kind===t&&o.itemId===n)??null;return{entries:r?e.filter((o)=>o!==r):[...e],removed:r}}function Fn(e,t,n){let r=Dn(e,n);if(!r)return null;let o=t.find((a)=>a.kind===r.kind&&a.slot===r.slot),i=ae(e,r.kind)?.route;return o&&i?i.replace(":id",String(o.itemId)):null}function Wn(e,t){if(!Array.isArray(t))return[];let n=new Map,r=new Set;for(let o of t){if(!o||typeof o!=="object")continue;let i=o,{kind:a,slot:s,itemId:l,title:m,donatedAt:f}=i;if(typeof a!=="string"||typeof s!=="number"||ie(e,a,s)===null)continue;if(typeof l!=="number"||!Number.isInteger(l)||l<=0)continue;let d=`${a}-slot-${s}`,g=`${a}#${l}`;if(n.has(d)||r.has(g))continue;n.set(d,{kind:a,slot:s,itemId:l,title:typeof m==="string"&&m.trim()?m:Ot(e,a,{id:l}),donatedAt:typeof f==="number"&&Number.isFinite(f)&&f>0?f:0}),r.add(g)}return Pt(e,[...n.values()])}function Pt(e,t){let n=new Map(e.map((r,o)=>[r.name,o]));return[...t].sort((r,o)=>(n.get(r.kind)??0)-(n.get(o.kind)??0)||r.slot-o.slot)}function Un(e,t){let n=new Set(e.map((r)=>r.slot));for(let r=0;r<t;r++)if(!n.has(r))return r;return null}function $n(e){return e.reduce((t,n)=>!t||n.donatedAt<t.donatedAt?n:t,null)}function Kn(){let e=globalThis.craft;return e&&typeof e==="object"?e.siri:void 0}var jn="stacks_spotlight_index",qn=3000;function Xo(e){let t=e.onProblem??((y)=>console.warn(`[spotlight] ${y}`)),n=Array.isArray(e.kinds)?{kinds:[...e.kinds],problems:[]}:Tt(e.kinds);for(let y of n.problems)t(y);let r=e.enabled===!1?[]:n.kinds,o=e.storageKey??jn,i=e.legacyStorageKeys??[],a=e.timeoutMs??qn,s=e.now??(()=>Date.now()),l=e.bridge??Kn,m=null;function f(){try{return typeof localStorage>"u"?null:localStorage}catch{return null}}function d(){if(m)return m;m=[];let y=f();if(!y)return m;try{let w=[o,...i].map((x)=>y.getItem(x)).find((x)=>x);m=w?Wn(r,JSON.parse(w)):[]}catch{m=[]}return m}function g(y){m=y;let w=f();if(!w)return;try{w.setItem(o,JSON.stringify(y));for(let x of i)w.removeItem(x)}catch{}}async function c(y){if(!y)return null;let w;try{return await Promise.race([y,new Promise((x)=>{w=setTimeout(()=>x(null),a)})])}catch{return null}finally{if(w!==void 0)clearTimeout(w)}}let p=Promise.resolve();function v(y){let w=p.then(y,y);return p=w.catch(()=>{return}),w}async function k(y,w){let x=l()?.register;if(!x||r.length===0)return!1;return v(async()=>{let E=_n(r,d(),y,w,s()),h=E&&ie(r,y,E.entry.slot);if(!E||!h)return!1;if(!E.changed)return g(E.entries),!0;let S=await c(x(E.entry.title,h))!==null;if(S)g(E.entries);return S})}async function F(y,w){let x=l()?.remove;if(!x)return!1;return v(async()=>{let{entries:E,removed:h}=Bn(d(),y,w);if(!h)return!1;let S=ie(r,y,h.slot),T=S?await c(x(S))!==null:!1;return g(E),T})}async function z(y,w){let x=ae(r,y)?.slots;if(!x||!l()?.register)return 0;let E=0;for(let h of[...w].slice(0,x).reverse())if(await k(y,h))E++;return E}async function Z(){let y=l()?.remove;if(!y)return g([]),0;return v(async()=>{let w=0;for(let x of d()){let E=ie(r,x.kind,x.slot);if(E&&await c(y(E))!==null)w++}return g([]),w})}return{kinds:r,index:k,sync:z,remove:F,clear:Z,routeFor:(y)=>Fn(r,d(),y),entries:()=>d(),activityTypes:(y)=>It(r).map((w)=>`${y}.${w}`),reset:()=>{m=null}}}var Et=["craftShortcut","craftSiriShortcut"];function Qo(e,t){let n=(r)=>{let o=r.detail,i=typeof o==="string"?o:o&&typeof o==="object"?o.action??o.type:null,a=typeof i==="string"?e.routeFor(i):null;if(a)t(a)};if(typeof globalThis.addEventListener!=="function")return()=>{};for(let r of Et)globalThis.addEventListener(r,n);return()=>{for(let r of Et)globalThis.removeEventListener(r,n)}}import{tabBar as zn}from"craft-native/mobile";var Gn=zn;function Yn(e){return Array.from(e.querySelectorAll("a[data-native-tab]")).map((t)=>({id:t.getAttribute("href")||"",title:t.getAttribute("data-native-tab")||t.getAttribute("aria-label")||"",symbol:t.getAttribute("data-native-tab-symbol")||"circle",badge:(t.querySelector(".native-tab-badge")?.textContent||"").trim(),current:t.hasAttribute("data-stx-nav-current")||t.classList.contains("is-active")})).filter((t)=>t.id&&t.title)}function Vn(e){return{tabs:e.map(({id:n,title:r,symbol:o,badge:i})=>i?{id:n,title:r,symbol:o,badge:i}:{id:n,title:r,symbol:o}),selected:e.find((n)=>n.current)?.id}}function Ct(){if(typeof window>"u")return;let e=window.stxRouter;return e&&typeof e==="object"?e:void 0}function Xn(){return typeof Ct()?.selectTab==="function"}function ei(e,t={}){let n=(r)=>{if(Xn()||r.defaultPrevented)return;let o=r.target?.closest?.("a[data-native-tab]");if(!o||!e.contains(o))return;if(!o.hasAttribute("data-stx-nav-current")&&!o.classList.contains("is-active")&&o.getAttribute("aria-current")!=="page")return;r.preventDefault();let i=e.ownerDocument.defaultView;if(t.scrollToTop)t.scrollToTop();else i?.scrollTo?.({top:0,behavior:i.matchMedia?.("(prefers-reduced-motion: reduce)").matches?"auto":"smooth"});i?.dispatchEvent(new CustomEvent("stx:tabreselect",{detail:{href:o.getAttribute("href")||""}}))};return e.addEventListener("click",n),()=>e.removeEventListener("click",n)}function Lt(e){let t=e.trim();return/^#[0-9a-f]{6}$/i.test(t)?t:void 0}var He="stacks:tab-bar-cover";function ti(e,t){if(t)e.setAttribute("data-native-covers-tab-bar","");else e.removeAttribute("data-native-covers-tab-bar");e.ownerDocument?.defaultView?.dispatchEvent(new Event(He))}function ni(e,t={}){let n=t.api??Gn;if(!n.isAvailable())return null;let r=t.hidden??(()=>Boolean(e.ownerDocument?.querySelector("[data-native-hide-tab-bar], [data-native-covers-tab-bar]"))),o=typeof getComputedStyle==="function"?getComputedStyle(e):null,i=Lt(o?.getPropertyValue("--native-tab-active")||""),a=Lt(o?.getPropertyValue("--native-tab-active-dark")||""),s="",l=()=>{if(r()){if(s!=="hidden")n.hide();s="hidden";return}let{tabs:g,selected:c}=Vn(Yn(e)),p=JSON.stringify({tabs:g,selected:c});if(p===s)return;let v=s&&s!=="hidden"?JSON.parse(s):null;if(v&&c&&JSON.stringify(v.tabs)===JSON.stringify(g))n.select(c);else n.set(g,{selected:c,tint:i,tintDark:a});s=p},m=typeof MutationObserver==="function"?new MutationObserver(l):null;m?.observe(e,{attributes:!0,attributeFilter:["data-stx-nav-current","class"],childList:!0,subtree:!0,characterData:!0});let f=n.onSelect((g)=>{let c=Ct();if(c?.selectTab){c.selectTab(g);return}Array.from(e.querySelectorAll("a[data-native-tab]")).find((v)=>v.getAttribute("href")===g)?.click()}),d=()=>l();if(typeof window<"u")window.addEventListener("stx:load",d),window.addEventListener("stx:screen-shown",d),window.addEventListener(He,d);return l(),()=>{if(m?.disconnect(),f(),typeof window<"u")window.removeEventListener("stx:load",d),window.removeEventListener("stx:screen-shown",d),window.removeEventListener(He,d);n.hide()}}var er={isAvailable:()=>u(()=>De.isAvailable()),getBiometricType:()=>u(()=>De.getBiometricType()),authenticate:(e)=>u(()=>De.authenticate(e))},tr={takePicture:(e)=>u(()=>ve.takePicture(e)),pickImage:()=>u(()=>ve.pickImage()),pickMultiple:(e)=>u(()=>ve.pickMultiple(e)),isAvailable:()=>u(()=>ve.isAvailable())},nr={getInfo:()=>u(()=>Y.getInfo()),getCapabilities:()=>u(()=>Y.getCapabilities()),isMobile:()=>Y.isMobile(),isIOS:()=>Y.isIOS(),isAndroid:()=>Y.isAndroid(),getLocale:()=>Y.getLocale(),getTimezone:()=>Y.getTimezone()},rr=Jn;function K(){return q()?.capabilities.locationRecordingOwnership===!0&&N.supportsRecordingOwnership?.()===!0}function j(){return q()?.capabilities.heartRateRecordingOwnership===!0&&R.supportsRecordingOwnership?.()===!0}function _t(){return K()&&q()?.capabilities.locationRecordingIntentIdentity===!0&&N.supportsRecordingIntentIdentity?.()===!0}function Bt(){return j()&&q()?.capabilities.heartRateRecordingIntentIdentity===!0&&R.supportsRecordingIntentIdentity?.()===!0}function Wt(e,t,n){return u(async()=>{let r=e&&Object.hasOwn(e,"recordingId");if(r){if(!t())throw Object.assign(Error("This host or adapter cannot start a registered recording identity"),{code:"RECORDING_INTENT_IDENTITY_UNSUPPORTED"});if(typeof e.recordingId!=="string"||!e.recordingId.trim())throw Object.assign(Error("A registered recording ID is required"),{code:"INVALID_ARGUMENT"})}let o=await n();if(r&&o.id!==e.recordingId)throw Object.assign(Error("The native recording identity changed at start"),{code:"RECORDING_CONFLICT"});return o})}function H(e,t,n){return u(()=>{if(e&&Object.hasOwn(e,"expectedId")){if(!t())throw Object.assign(Error("This host or adapter cannot protect recording ownership"),{code:"RECORDING_OWNERSHIP_UNSUPPORTED"});if(typeof e.expectedId!=="string"||!e.expectedId.trim())throw Object.assign(Error("A saved recording ID is required"),{code:"RECORDING_CONFLICT"})}return n()})}var or={supportsRecordingOwnership:K,supportsRecordingIntentIdentity:_t,acknowledgeRecording:(e)=>H({expectedId:e?.expectedId},K,()=>N.acknowledgeRecording(e)),getCurrentPosition:(e)=>u(()=>N.getCurrentPosition(e)),watchPosition:(e,t)=>N.watchPosition(e,t),clearWatch:(e)=>N.clearWatch(e),startRecording:(e)=>Wt(e,_t,()=>N.startRecording(e)),pauseRecording:(e)=>H(e,K,()=>N.pauseRecording(e)),resumeRecording:(e)=>H(e,K,()=>N.resumeRecording(e)),stopRecording:(e)=>H(e,K,()=>N.stopRecording(e)),getRecordingState:(e)=>H(e,K,()=>N.getRecordingState(e)),readRecording:(e)=>H(e,K,()=>N.readRecording(e))},ir={show:(e)=>u(()=>Se.show(e)),schedule:(e)=>u(()=>Se.schedule(e)),cancelAll:()=>u(()=>Se.cancelAll()),setBadge:(e)=>u(()=>Se.setBadge(e))},ar={check:(e)=>u(()=>le.check(e)),request:(e)=>u(()=>le.request(e)),checkMultiple:(e)=>u(()=>le.checkMultiple(e)),requestMultiple:(e)=>u(()=>le.requestMultiple(e)),openSettings:()=>u(()=>le.openSettings())},sr={set:(e,t)=>u(()=>we.set(e,t)),get:(e)=>u(()=>we.get(e)),delete:(e)=>u(()=>we.delete(e)),clear:()=>u(()=>we.clear())},lr={share:(e)=>u(()=>Dt.share(e)),isAvailable:()=>Dt.isAvailable()},cr={request:()=>u(()=>Qn.request())},Ae={impact:(e)=>Promise.resolve().then(()=>ye.impact(e)).catch(()=>{}),notification:(e)=>Promise.resolve().then(()=>ye.notification(e)).catch(()=>{}),selection:()=>Promise.resolve().then(()=>ye.selection()).catch(()=>{}),vibrate:(e)=>Promise.resolve().then(()=>ye.vibrate(e)).catch(()=>{}),prepare:(e)=>{let t=C("haptics.prepare");return t?Promise.resolve().then(()=>t(e)).then(()=>{},()=>{}):Promise.resolve()}};function Ft(e){if(typeof e==="string")return e.trim()||null;if(!e||typeof e!=="object")return null;let t=e.url;return typeof t==="string"&&t.trim()?t:null}var ur={async getInitialURL(){if(!await X())return null;return Ft(await Mt.getInitialURL?.())},onLink(e){let t=null,n=!1,r=()=>{if(n)return;t=Mt.onLink?.((o,i)=>{let a=Ft(o);if(a)e(a,{initial:i?.initial===!0})})??null};if(Re()?.craft)r();else X().then(r);return()=>{n=!0,t?.()}}},ui={isAvailable:()=>xe.isAvailable(),set:(e,t)=>xe.set(e,t),remove:(e)=>xe.remove(e),clear:()=>xe.clear()},dr={enable:()=>u(()=>Nt.enable()),disable:()=>u(()=>Nt.disable())},pr={isAvailable:()=>be.isAvailable(),get:()=>u(()=>be.get()),set:(e)=>u(()=>be.set(e)),restore:()=>u(()=>be.restore())},fr={isAvailable:()=>B.isAvailable(),supports:(e)=>B.supports(e),getAuthorizationStatus:()=>u(()=>B.getAuthorizationStatus()),requestAuthorization:()=>u(()=>B.requestAuthorization()),getNowPlaying:()=>u(()=>B.getNowPlaying()),play:()=>u(()=>B.play()),pause:()=>u(()=>B.pause()),togglePlayPause:()=>u(()=>B.togglePlayPause()),skipToNext:()=>u(()=>B.skipToNext()),skipToPrevious:(e)=>u(()=>B.skipToPrevious(e)),onChange:(e)=>G(()=>B.onChange(e))},mr={supportsRecordingOwnership:j,supportsRecordingIntentIdentity:Bt,acknowledgeRecording:(e)=>H({expectedId:e?.expectedId},j,()=>R.acknowledgeRecording(e)),isAvailable:()=>R.isAvailable(),supports:(e)=>R.supports(e),getState:()=>u(()=>R.getState()),requestAuthorization:()=>u(()=>R.requestAuthorization()),scan:(e)=>u(()=>R.scan(e)),stopScan:()=>u(()=>R.stopScan()),getDevices:()=>u(()=>R.getDevices()),connect:(e)=>u(()=>R.connect(e)),reconnect:()=>u(()=>R.reconnect()),disconnect:(e)=>u(()=>R.disconnect(e)),startRecording:(e)=>Wt(e,Bt,()=>R.startRecording(e)),pauseRecording:(e)=>H(e,j,()=>R.pauseRecording(e)),resumeRecording:(e)=>H(e,j,()=>R.resumeRecording(e)),stopRecording:(e)=>H(e,j,()=>R.stopRecording(e)),getRecordingState:(e)=>H(e,j,()=>R.getRecordingState(e)),readRecording:(e)=>H(e,j,()=>R.readRecording(e)),onReading:(e)=>G(()=>R.onReading(e)),onDevice:(e)=>G(()=>R.onDevice(e)),onState:(e)=>G(()=>R.onState(e))},gr={isAvailable:()=>Fe.isAvailable(),speak:(e,t)=>u(()=>Fe.speak(e,t)),stop:()=>u(()=>Fe.stop())},hr={getStatus:()=>u(()=>Ht.getStatus()),onChange:(e)=>G(()=>Ht.onChange(e))},br={register:()=>u(()=>Be.register()),onToken:(e)=>Be.onToken(e),onNotification:(e)=>G(()=>Be.onNotification(e))},vr={requestAuthorization:(e,t)=>u(()=>se.requestAuthorization(e,t)),getData:(e,t)=>u(()=>se.getData(e,t)),saveWorkout:(e)=>u(()=>se.saveWorkout(e)),getWorkouts:(e)=>u(()=>se.getWorkouts(e)),getDailyStatistics:(e,t)=>u(()=>se.getDailyStatistics(e,t)),getHeartRateSamples:(e)=>b("health.getHeartRateSamples",[e??{}],()=>[]).then((t)=>Array.isArray(t)?t:[]),getSleepIntervals:(e)=>b("health.getSleepIntervals",[e??{}],()=>[]).then((t)=>Array.isArray(t)?t:[]),saveMindfulSession:(e)=>b("health.saveMindfulSession",[e],()=>null).then((t)=>t??null),getMindfulSessions:(e)=>b("health.getMindfulSessions",[e??{}],()=>[]).then((t)=>Array.isArray(t)?t:[]),startHeartRateUpdates:(e)=>b("health.startHeartRateUpdates",[e??{}],()=>!1).then((t)=>t!==!1),stopHeartRateUpdates:()=>b("health.stopHeartRateUpdates",[],()=>!0).then(()=>!0),onHeartRate:(e)=>D("craftHealthHeartRate",(t)=>{if(Array.isArray(t.samples)&&t.samples.length)e(t.samples)}),supports:(e)=>C(`health.${e}`)!==null},yr={start:(e)=>u(()=>_e.start(e)),update:(e)=>u(()=>_e.update(e)),end:()=>u(()=>_e.end())},Sr={send:(e)=>u(()=>ce.send(e)),updateContext:(e)=>u(()=>ce.updateContext(e)),isReachable:()=>u(()=>ce.isReachable()),onMessage:(e)=>ce.onMessage(e),onReachabilityChange:(e)=>ce.onReachabilityChange(e)},di=Zn;function Re(){return A()}function q(){let e=Re()?.craft;if(!e||typeof e!=="object")return null;if(!("platform"in e)||e.platform!=="ios"&&e.platform!=="android")return null;let t="capabilities"in e?e.capabilities:void 0,n=t&&typeof t==="object"&&!Array.isArray(t)?Object.fromEntries(Object.entries(t).filter(([,r])=>typeof r==="boolean")):{};return{platform:e.platform,capabilities:n}}function We(){return q()!==null}function wr(e=2000){if(We()||ee())return Promise.resolve(!0);let t=Re();if(!t||!(t.craft||t.webkit?.messageHandlers?.craft))return Promise.resolve(!1);return new Promise((n)=>{let r=()=>{clearTimeout(o),t.removeEventListener("craftReady",r),n(We())},o=setTimeout(r,e);t.addEventListener("craftReady",r,{once:!0})})}function xr(e){let t=Re();if(!t)return()=>{};if(q()){let r=!1;return queueMicrotask(()=>{if(!r)e(new Event("craftReady"))}),()=>{r=!0}}let n=(r)=>{if(!q())return;t.removeEventListener("craftReady",n),e(r)};return t.addEventListener("craftReady",n),()=>t.removeEventListener("craftReady",n)}async function Ar(e){await Ae.impact("light");try{let t=await e();return await Ae.notification("success"),t}catch(t){throw await Ae.notification("error"),t}}var pi={get nativeBridge(){return q()},biometrics:er,camera:tr,device:nr,haptics:Ae,lifecycle:rr,location:or,notifications:ir,permissions:ar,secureStorage:sr,storage:dt,crypto:pt,share:lr,appReview:cr,deepLinks:ur,keepAwake:dr,brightness:pr,music:fr,heartRate:mr,scheduledWorkouts:mt,speech:gr,network:hr,pushNotifications:br,health:vr,liveActivities:yr,watchConnectivity:Sr,dialog:te,contextMenu:Pe,browser:Ze,symbols:et,statusBar:de,chrome:ne,refresh:U,background:re,clipboard:tt,db:nt,files:rt,shortcuts:ot,widgets:it,orientation:at,auth:st,storeKit:lt,isNativeMobile:We,whenNative:wr,onReady:xr,withFeedback:Ar};export{Rr as BRIDGE_WAIT_MS,xo as HEART_RATE_MATCH_MS,Co as INDOOR_CHECK_AFTER_S,Yo as MAX_SPOTLIGHT_SLOTS_PER_KIND,Sn as ROUTE_GAP_S,Fo as SHEET_FLICK_VELOCITY,He as TAB_BAR_COVER_EVENT,u as afterBridge,cr as appReview,Pn as applyAppearance,vn as attachHeartRate,st as auth,go as backLabelFor,re as background,er as biometrics,ue as bridgePending,pr as brightness,Ze as browser,b as callNative,tr as camera,mn as canGoBack,ne as chrome,tt as clipboard,Lr as confirmAction,Pe as contextMenu,ti as coverTabBar,A as craftHost,V as craftRoot,Jr as crashReporting,ko as createRouteRecorder,Xo as createSpotlightIndex,pt as crypto,bt as currentAppearance,nt as db,hn as deepLinkPath,ur as deepLinks,nr as device,te as dialog,mo as enterNavTrail,rt as files,xn as fixDistance,zr as focusSegment,So as followDeepLinks,q as getNativeMobileBridge,fo as goBack,vo as goBackToTabRoot,ei as handleTabReselect,Ae as haptics,ee as hasNativeMobileHost,vr as health,mr as heartRate,Mo as indoorVerdict,zo as installNativeChrome,Gr as installPressables,We as isNativeMobile,kn as isShown,dr as keepAwake,an as keepBreadcrumb,pn as largeTitleMetrics,rr as lifecycle,Uo as liftToBody,yr as liveActivities,or as location,ni as mirrorTabBar,pi as mobile,fr as music,jt as nativeFunction,C as nativeFunctionNow,Vn as nativeTabs,ho as navTrail,hr as network,ln as normalizeAppearance,Ft as normalizeDeepLinkURL,nn as normalizeScheduledWorkout,ir as notifications,co as observeLargeTitle,Kr as observeLongPress,_o as observeNativeRefresh,un as observePageScroll,lo as observePullToRefresh,jr as observeSegmentScrub,Wo as observeSheetDrag,vt as onAppearance,io as onBackgroundRefresh,D as onCraftEvent,ro as onMemoryWarning,xr as onMobileReady,no as onResume,oo as onSilentPush,Qo as onSpotlightTap,at as orientation,Ao as paceLabel,Cn as pageBackground,Mn as pageIsDark,oe as pageScrollTop,Io as pauseSessionClock,ar as permissions,Vt as placeMenu,_n as placeSpotlightItem,Ge as presentActionSheet,qe as presentAlert,ke as presentChoice,ze as presentConfirm,Ye as presentContextMenu,$o as presentPageAsCard,bo as previousScreenPath,dn as pullDistance,br as pushNotifications,Wn as readSpotlightEntries,Tt as readSpotlightKinds,Yn as readTabLinks,U as refresh,Bn as removeSpotlightItem,uo as resolveScrollHost,Oo as resumeSessionClock,Me as routeStats,Xn as routerHandlesTabs,On as rubberBand,mt as scheduledWorkouts,tn as scheduledWorkoutsUnsupported,sr as secureStorage,rn as segmentAt,qr as segmentForKey,Po as sessionClockElapsed,In as settleSheet,lr as share,Tn as sheetStops,ot as shortcuts,Cr as showContextMenuFor,ui as snapshots,gr as speech,Ro as speedLabel,di as splash,ie as spotlightAction,It as spotlightActions,Vo as spotlightActivityTypes,Kn as spotlightBridge,ae as spotlightKind,Fn as spotlightRoute,Dn as spotlightSlot,Ot as spotlightTitle,To as startSessionClock,de as statusBar,dt as storage,lt as storeKit,G as subscribeWhenReady,et as symbols,Gn as tabBar,Oe as toNativeRect,yo as trailEntryFor,No as typedDistanceKm,An as usableFixes,Pr as useActionSheet,Sr as watchConnectivity,X as whenBridgeReady,wr as whenNativeMobile,it as widgets,Ar as withNativeFeedback};
package/dist/route.d.ts CHANGED
@@ -61,13 +61,15 @@ export declare interface RouteRecorderOptions extends RouteStatsOptions {
61
61
  heartRate?: HeartRateRecordingApi
62
62
  }
63
63
  export declare interface RouteRecorder {
64
- start: () => Promise<RouteStats>
65
- attach: () => Promise<LocationRecordingState | null>
64
+ start: (intent?: { recordingId: string, heartRateRecordingId?: string }) => Promise<RouteStats>
65
+ attach: (options: { expectedId: string, expectedHeartRateId?: string }) => Promise<LocationRecordingState | null>
66
66
  pause: () => Promise<void>
67
67
  resume: () => Promise<void>
68
68
  stop: () => Promise<RouteFix[]>
69
69
  refresh: () => Promise<RouteStats>
70
70
  dispose: () => void
71
71
  readonly stats: RouteStats
72
+ readonly recordingId: string | null
73
+ readonly heartRateRecordingId: string | null
72
74
  readonly heartRate: HeartRateSample[]
73
75
  }
@@ -0,0 +1,4 @@
1
+ import type { StorageApi } from './types';
2
+ declare function supportsCompareAndSet(): boolean;
3
+ declare function supportsSetIfAbsent(): boolean;
4
+ export declare const storage: StorageApi;
package/dist/testing.d.ts CHANGED
@@ -3,7 +3,7 @@
3
3
  * Generated from 4 source files
4
4
  */
5
5
 
6
- import { IosMobileConfig } from '@stacksjs/types';
6
+ import { IosMobileConfig } from '@stacksjs/types/mobile';
7
7
 
8
8
  // From: src/testing.ts
9
9
  /** Bun-only build/test entrypoint. The browser runtime never imports the iOS builder. */
package/dist/types.d.ts CHANGED
@@ -7,8 +7,15 @@ export declare interface CraftMobileCapabilities {
7
7
  biometric?: boolean
8
8
  pushNotifications?: boolean
9
9
  secureStorage?: boolean
10
+ storageCompareAndSet?: boolean
11
+ storageSetIfAbsent?: boolean
12
+ crypto?: boolean
10
13
  geolocation?: boolean
11
14
  backgroundLocation?: boolean
15
+ locationRecordingOwnership?: boolean
16
+ locationRecordingIntentIdentity?: boolean
17
+ heartRateRecordingIntentIdentity?: boolean
18
+ heartRateRecordingOwnership?: boolean
12
19
  healthKit?: boolean
13
20
  health?: boolean
14
21
  liveActivities?: boolean
@@ -65,6 +72,8 @@ export declare interface MobileApi {
65
72
  notifications: NotificationsApi
66
73
  permissions: PermissionsApi
67
74
  secureStorage: SecureStorageApi
75
+ storage: StorageApi
76
+ crypto: CryptoApi
68
77
  share: ShareApi
69
78
  appReview: AppReviewApi
70
79
  deepLinks: DeepLinksApi
@@ -160,6 +169,11 @@ export declare interface LocationRecordingState {
160
169
  startedAt: number | null
161
170
  sampleCount?: number
162
171
  }
172
+ /** An identity already registered durably by the caller before native start. */
173
+ export declare interface RecordingStartOptions {
174
+ recordingId?: string
175
+ }
176
+ export declare interface LocationRecordingOptions extends LocationOptions, RecordingStartOptions {}
163
177
  export declare interface LocationRecordingResult extends LocationRecordingState {
164
178
  locations: Location[]
165
179
  }
@@ -211,22 +225,45 @@ export declare interface BiometricsApi {
211
225
  getBiometricType: () => Promise<BiometricType | null>
212
226
  authenticate: (reason: string) => Promise<boolean>
213
227
  }
228
+ /** Native durable storage. CAS changes an existing value only; false never creates it. */
229
+ export declare interface StorageApi {
230
+ supportsCompareAndSet: () => boolean
231
+ supportsSetIfAbsent: () => boolean
232
+ get: <T = unknown>(key: string) => Promise<T | null>
233
+ set: (key: string, value: unknown) => Promise<boolean>
234
+ remove: (key: string) => Promise<boolean>
235
+ clear: () => Promise<boolean>
236
+ keys: () => Promise<string[]>
237
+ setIfAbsent: (key: string, value: unknown) => Promise<boolean>
238
+ compareAndSet: (key: string, expectedValue: unknown, nextValue: unknown) => Promise<boolean>
239
+ }
240
+ /** Secure system UUID generation also works in native asynchronous JS hosts. */
241
+ export declare interface CryptoApi {
242
+ randomUUID: () => Promise<string>
243
+ }
214
244
  export declare interface SecureStorageApi {
215
245
  set: (key: string, value: string) => Promise<void>
216
246
  get: (key: string) => Promise<string | null>
217
247
  delete: (key: string) => Promise<void>
218
248
  clear: () => Promise<void>
219
249
  }
250
+ /** Native checks this ID before reading or changing a recording. */
251
+ export declare interface RecordingOwnershipOptions {
252
+ expectedId: string
253
+ }
220
254
  export declare interface LocationApi {
255
+ supportsRecordingOwnership: () => boolean
256
+ supportsRecordingIntentIdentity: () => boolean
257
+ acknowledgeRecording: (options: RecordingOwnershipOptions) => Promise<boolean>
221
258
  getCurrentPosition: (options?: LocationOptions) => Promise<Location>
222
259
  watchPosition: (callback: (location: Location) => void, options?: LocationOptions) => number
223
260
  clearWatch: (watchId: number) => void
224
- startRecording: (options?: LocationOptions) => Promise<LocationRecordingState>
225
- pauseRecording: () => Promise<LocationRecordingState>
226
- resumeRecording: () => Promise<LocationRecordingState>
227
- stopRecording: () => Promise<LocationRecordingResult>
228
- getRecordingState: () => Promise<LocationRecordingState>
229
- readRecording: () => Promise<Location[]>
261
+ startRecording: (options?: LocationRecordingOptions) => Promise<LocationRecordingState>
262
+ pauseRecording: (options?: RecordingOwnershipOptions) => Promise<LocationRecordingState>
263
+ resumeRecording: (options?: RecordingOwnershipOptions) => Promise<LocationRecordingState>
264
+ stopRecording: (options?: RecordingOwnershipOptions) => Promise<LocationRecordingResult>
265
+ getRecordingState: (options?: RecordingOwnershipOptions) => Promise<LocationRecordingState>
266
+ readRecording: (options?: RecordingOwnershipOptions) => Promise<Location[]>
230
267
  }
231
268
  export declare interface ShareApi {
232
269
  share: (options: ShareOptions) => Promise<boolean>
@@ -330,12 +367,15 @@ export declare interface HeartRateSample {
330
367
  /** The recording half of HeartRateApi: what a route recorder drives. */
331
368
  export declare interface HeartRateRecordingApi {
332
369
  isAvailable: () => boolean
333
- startRecording: () => Promise<HeartRateRecordingState>
334
- pauseRecording: () => Promise<HeartRateRecordingState>
335
- resumeRecording: () => Promise<HeartRateRecordingState>
336
- stopRecording: () => Promise<HeartRateRecordingState & { samples: HeartRateSample[] }>
337
- getRecordingState: () => Promise<HeartRateRecordingState>
338
- readRecording: (options?: { since?: number }) => Promise<HeartRateSample[]>
370
+ supportsRecordingOwnership: () => boolean
371
+ supportsRecordingIntentIdentity: () => boolean
372
+ acknowledgeRecording: (options: RecordingOwnershipOptions) => Promise<boolean>
373
+ startRecording: (options?: RecordingStartOptions) => Promise<HeartRateRecordingState>
374
+ pauseRecording: (options?: RecordingOwnershipOptions) => Promise<HeartRateRecordingState>
375
+ resumeRecording: (options?: RecordingOwnershipOptions) => Promise<HeartRateRecordingState>
376
+ stopRecording: (options?: RecordingOwnershipOptions) => Promise<HeartRateRecordingState & { samples: HeartRateSample[] }>
377
+ getRecordingState: (options?: RecordingOwnershipOptions) => Promise<HeartRateRecordingState>
378
+ readRecording: (options?: { since?: number, expectedId?: string }) => Promise<HeartRateSample[]>
339
379
  }
340
380
  export declare interface HeartRateApi extends HeartRateRecordingApi {
341
381
  isAvailable: () => boolean
@@ -580,7 +620,7 @@ export type BluetoothState = 'poweredOn' | 'poweredOff' | 'unauthorized' | 'unsu
580
620
  /** A strap that drops out is asked for again (`reconnecting`) until `disconnect()`. */
581
621
  export type HeartRateConnection = 'disconnected' | 'connecting' | 'connected' | 'reconnecting';
582
622
  export type HeartRateMethod = 'getState' | 'requestAuthorization' | 'scan' | 'stopScan' | 'getDevices' | 'connect' | 'reconnect' | 'disconnect'
583
- | 'startRecording' | 'pauseRecording' | 'resumeRecording' | 'stopRecording' | 'getRecordingState' | 'readRecording';
623
+ | 'startRecording' | 'pauseRecording' | 'resumeRecording' | 'stopRecording' | 'getRecordingState' | 'readRecording' | 'acknowledgeRecording';
584
624
  export type HealthDataType = | 'steps'
585
625
  | 'heartRate'
586
626
  | 'activeEnergy'
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@stacksjs/mobile",
3
3
  "type": "module",
4
4
  "sideEffects": false,
5
- "version": "0.75.226",
5
+ "version": "0.75.229",
6
6
  "description": "Craft-powered native mobile runtime for Stacks and STX applications",
7
7
  "author": "Chris Breuer",
8
8
  "license": "MIT",
@@ -39,11 +39,11 @@
39
39
  },
40
40
  "dependencies": {
41
41
  "@bughq/sdk": "^0.3.0",
42
- "@stacksjs/types": "0.75.226",
43
- "craft-native": ">=0.0.179"
42
+ "@stacksjs/types": "0.75.229",
43
+ "craft-native": ">=0.0.238"
44
44
  },
45
45
  "devDependencies": {
46
- "@stacksjs/build": "0.75.226",
46
+ "@stacksjs/build": "0.75.229",
47
47
  "better-dx": "^0.2.24"
48
48
  }
49
49
  }