@ingissa/navcore-core 1.0.1 → 1.0.3

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.
@@ -151,8 +151,12 @@ declare class OffRouteFSM {
151
151
  /**
152
152
  * Feature flag constants for SDK consumers.
153
153
  *
154
- * CORE features: available to all users (MIT license).
155
- * PRO features: require a valid commercial license key.
154
+ * CORE features: available to all users without a license key.
155
+ * - GPS smoothing, basic snapping, route building, directions providers,
156
+ * progress tracking, and route offset prediction are all free.
157
+ *
158
+ * PRO features: require a valid commercial license key.
159
+ * Each PRO engine checks the license at runtime and gracefully degrades.
156
160
  */
157
161
  declare const FEATURES: {
158
162
  /**
@@ -161,43 +165,45 @@ declare const FEATURES: {
161
165
  */
162
166
  readonly GPS_SMOOTHING: "gps_smoothing";
163
167
  /**
164
- * Basic route snapping (nearest-point projection).
165
- * Snaps GPS position to the closest route segment.
168
+ * Basic route snapping (nearest-point projection) with bearing and inertia
169
+ * penalties to prevent U-turn snaps and oscillation.
170
+ * Both basic and advanced snapping quality are available in the free tier.
166
171
  */
167
172
  readonly BASIC_SNAPPING: "basic_snapping";
168
173
  /**
169
- * Advanced route snapping with bearing penalty + inertia.
170
- * Prevents incorrect snaps on parallel roads and U-turns.
171
- */
172
- readonly ADVANCED_SNAPPING: "advanced_snapping";
173
- /**
174
- * Dead reckoning: continues navigation during GPS signal loss.
175
- * Predicts position based on last known speed and bearing.
174
+ * Progress anti-regression: prevents route index from jumping backward.
175
+ * Essential for circuit routes and motorway slip roads.
176
+ * Used unconditionally inside NavCore — available in the free tier.
176
177
  */
177
- readonly DEAD_RECKONING: "dead_reckoning";
178
+ readonly PROGRESS_TRACKING: "progress_tracking";
178
179
  /**
179
180
  * Smooth route offset predictor for jitter-free map rendering.
180
181
  * Advances render position at frame rate between GPS fixes.
182
+ * Used unconditionally inside NavCore — available in the free tier.
181
183
  */
182
184
  readonly ROUTE_OFFSET: "route_offset";
183
185
  /**
184
- * Progress anti-regression: prevents route index from jumping backward.
185
- * Essential for circuit routes and motorway slip roads.
186
+ * Dead reckoning: continues navigation during GPS signal loss.
187
+ * Predicts position based on last known speed and bearing.
188
+ * DeadReckoningEngine.predict() is a no-op without a Pro license.
186
189
  */
187
- readonly PROGRESS_TRACKING: "progress_tracking";
190
+ readonly DEAD_RECKONING: "dead_reckoning";
188
191
  /**
189
192
  * Advanced bearing engine with look-ahead and speed-adaptive alpha.
190
193
  * Produces stable heading for smooth map camera rotation.
194
+ * Gated inside NavCore.update() via this.has(FEATURES.ADVANCED_BEARING).
191
195
  */
192
196
  readonly ADVANCED_BEARING: "advanced_bearing";
193
197
  /**
194
198
  * Compound deviation detection: combines distance, bearing, and speed signals.
195
199
  * Eliminates false off-route triggers in tunnels and urban canyons.
200
+ * DeviationDetector.evaluate() returns a neutral signal without a Pro license.
196
201
  */
197
202
  readonly COMPOUND_DEVIATION: "compound_deviation";
198
203
  /**
199
204
  * Parallel road disambiguation + U-turn snap protection.
200
205
  * Prevents snapping to the wrong carriageway when bearing mismatches route direction.
206
+ * ParallelRoadResolver falls back to pure distance sorting without a Pro license.
201
207
  */
202
208
  readonly PARALLEL_ROAD_RESOLUTION: "parallel_road_resolution";
203
209
  /**
@@ -207,14 +213,17 @@ declare const FEATURES: {
207
213
  readonly U_TURN_PROTECTION: "u_turn_protection";
208
214
  /**
209
215
  * Timed voice instruction cues with deduplication and priority levels.
216
+ * VoiceTriggerEngine.update() returns null without a Pro license.
210
217
  */
211
218
  readonly VOICE_TRIGGERS: "voice_triggers";
212
219
  /**
213
220
  * Local ETA computation using rolling speed average — zero API calls.
221
+ * ETAEngine.update() returns isReliable=false without a Pro license.
214
222
  */
215
223
  readonly ETA: "eta";
216
224
  /**
217
225
  * Circular and polygon geofencing with enter/exit/dwell events.
226
+ * GeofencingEngine.update() returns [] without a Pro license.
218
227
  */
219
228
  readonly GEOFENCING: "geofencing";
220
229
  /**
@@ -247,9 +256,25 @@ declare class LicenseManager {
247
256
  private payload;
248
257
  private enabledFeatures;
249
258
  private warnedFeatures;
250
- private isDev;
259
+ private static activeManager;
260
+ static getActive(): LicenseManager | null;
261
+ /**
262
+ * Clear the active manager reference.
263
+ * Intended for test teardown only — not for production use.
264
+ */
265
+ static clearActive(): void;
266
+ /**
267
+ * Promote this instance to the global active manager.
268
+ *
269
+ * Security rule: A VALID license context cannot be overwritten by an
270
+ * INVALID / MISSING / EXPIRED one. Once a valid license is registered,
271
+ * it holds the slot until explicitly cleared or replaced by another
272
+ * valid license.
273
+ */
274
+ private promoteToActive;
251
275
  private static PUBLIC_KEY_SPKI;
252
- constructor(licenseKey?: string, isDev?: boolean);
276
+ constructor(licenseKey?: string);
277
+ private tryValidateSync;
253
278
  validate(key: string): Promise<LicenseStatus>;
254
279
  private extractFeatures;
255
280
  hasFeature(feature: FeatureKey): boolean;
@@ -286,7 +311,6 @@ interface NavGpsUpdate {
286
311
  }
287
312
  interface NavCoreOptions {
288
313
  licenseKey?: string;
289
- isDev?: boolean;
290
314
  isCircuit?: boolean;
291
315
  kalmanQ?: number;
292
316
  kalmanRBase?: number;
@@ -151,8 +151,12 @@ declare class OffRouteFSM {
151
151
  /**
152
152
  * Feature flag constants for SDK consumers.
153
153
  *
154
- * CORE features: available to all users (MIT license).
155
- * PRO features: require a valid commercial license key.
154
+ * CORE features: available to all users without a license key.
155
+ * - GPS smoothing, basic snapping, route building, directions providers,
156
+ * progress tracking, and route offset prediction are all free.
157
+ *
158
+ * PRO features: require a valid commercial license key.
159
+ * Each PRO engine checks the license at runtime and gracefully degrades.
156
160
  */
157
161
  declare const FEATURES: {
158
162
  /**
@@ -161,43 +165,45 @@ declare const FEATURES: {
161
165
  */
162
166
  readonly GPS_SMOOTHING: "gps_smoothing";
163
167
  /**
164
- * Basic route snapping (nearest-point projection).
165
- * Snaps GPS position to the closest route segment.
168
+ * Basic route snapping (nearest-point projection) with bearing and inertia
169
+ * penalties to prevent U-turn snaps and oscillation.
170
+ * Both basic and advanced snapping quality are available in the free tier.
166
171
  */
167
172
  readonly BASIC_SNAPPING: "basic_snapping";
168
173
  /**
169
- * Advanced route snapping with bearing penalty + inertia.
170
- * Prevents incorrect snaps on parallel roads and U-turns.
171
- */
172
- readonly ADVANCED_SNAPPING: "advanced_snapping";
173
- /**
174
- * Dead reckoning: continues navigation during GPS signal loss.
175
- * Predicts position based on last known speed and bearing.
174
+ * Progress anti-regression: prevents route index from jumping backward.
175
+ * Essential for circuit routes and motorway slip roads.
176
+ * Used unconditionally inside NavCore — available in the free tier.
176
177
  */
177
- readonly DEAD_RECKONING: "dead_reckoning";
178
+ readonly PROGRESS_TRACKING: "progress_tracking";
178
179
  /**
179
180
  * Smooth route offset predictor for jitter-free map rendering.
180
181
  * Advances render position at frame rate between GPS fixes.
182
+ * Used unconditionally inside NavCore — available in the free tier.
181
183
  */
182
184
  readonly ROUTE_OFFSET: "route_offset";
183
185
  /**
184
- * Progress anti-regression: prevents route index from jumping backward.
185
- * Essential for circuit routes and motorway slip roads.
186
+ * Dead reckoning: continues navigation during GPS signal loss.
187
+ * Predicts position based on last known speed and bearing.
188
+ * DeadReckoningEngine.predict() is a no-op without a Pro license.
186
189
  */
187
- readonly PROGRESS_TRACKING: "progress_tracking";
190
+ readonly DEAD_RECKONING: "dead_reckoning";
188
191
  /**
189
192
  * Advanced bearing engine with look-ahead and speed-adaptive alpha.
190
193
  * Produces stable heading for smooth map camera rotation.
194
+ * Gated inside NavCore.update() via this.has(FEATURES.ADVANCED_BEARING).
191
195
  */
192
196
  readonly ADVANCED_BEARING: "advanced_bearing";
193
197
  /**
194
198
  * Compound deviation detection: combines distance, bearing, and speed signals.
195
199
  * Eliminates false off-route triggers in tunnels and urban canyons.
200
+ * DeviationDetector.evaluate() returns a neutral signal without a Pro license.
196
201
  */
197
202
  readonly COMPOUND_DEVIATION: "compound_deviation";
198
203
  /**
199
204
  * Parallel road disambiguation + U-turn snap protection.
200
205
  * Prevents snapping to the wrong carriageway when bearing mismatches route direction.
206
+ * ParallelRoadResolver falls back to pure distance sorting without a Pro license.
201
207
  */
202
208
  readonly PARALLEL_ROAD_RESOLUTION: "parallel_road_resolution";
203
209
  /**
@@ -207,14 +213,17 @@ declare const FEATURES: {
207
213
  readonly U_TURN_PROTECTION: "u_turn_protection";
208
214
  /**
209
215
  * Timed voice instruction cues with deduplication and priority levels.
216
+ * VoiceTriggerEngine.update() returns null without a Pro license.
210
217
  */
211
218
  readonly VOICE_TRIGGERS: "voice_triggers";
212
219
  /**
213
220
  * Local ETA computation using rolling speed average — zero API calls.
221
+ * ETAEngine.update() returns isReliable=false without a Pro license.
214
222
  */
215
223
  readonly ETA: "eta";
216
224
  /**
217
225
  * Circular and polygon geofencing with enter/exit/dwell events.
226
+ * GeofencingEngine.update() returns [] without a Pro license.
218
227
  */
219
228
  readonly GEOFENCING: "geofencing";
220
229
  /**
@@ -247,9 +256,25 @@ declare class LicenseManager {
247
256
  private payload;
248
257
  private enabledFeatures;
249
258
  private warnedFeatures;
250
- private isDev;
259
+ private static activeManager;
260
+ static getActive(): LicenseManager | null;
261
+ /**
262
+ * Clear the active manager reference.
263
+ * Intended for test teardown only — not for production use.
264
+ */
265
+ static clearActive(): void;
266
+ /**
267
+ * Promote this instance to the global active manager.
268
+ *
269
+ * Security rule: A VALID license context cannot be overwritten by an
270
+ * INVALID / MISSING / EXPIRED one. Once a valid license is registered,
271
+ * it holds the slot until explicitly cleared or replaced by another
272
+ * valid license.
273
+ */
274
+ private promoteToActive;
251
275
  private static PUBLIC_KEY_SPKI;
252
- constructor(licenseKey?: string, isDev?: boolean);
276
+ constructor(licenseKey?: string);
277
+ private tryValidateSync;
253
278
  validate(key: string): Promise<LicenseStatus>;
254
279
  private extractFeatures;
255
280
  hasFeature(feature: FeatureKey): boolean;
@@ -286,7 +311,6 @@ interface NavGpsUpdate {
286
311
  }
287
312
  interface NavCoreOptions {
288
313
  licenseKey?: string;
289
- isDev?: boolean;
290
314
  isCircuit?: boolean;
291
315
  kalmanQ?: number;
292
316
  kalmanRBase?: number;
package/dist/core.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { C as Coordinate, g as NavCoreState } from './NavCore-Bjl5fTea.mjs';
2
- export { F as FEATURES, a as FeatureKey, L as LicenseManager, b as LicensePayload, c as LicenseStatus, o as destinationPoint, p as geoGetBearing, q as haversineDistance } from './NavCore-Bjl5fTea.mjs';
1
+ import { C as Coordinate, g as NavCoreState } from './NavCore.d-BuXR5DO7.mjs';
2
+ export { F as FEATURES, a as FeatureKey, L as LicenseManager, b as LicensePayload, c as LicenseStatus, o as destinationPoint, p as geoGetBearing, q as haversineDistance } from './NavCore.d-BuXR5DO7.mjs';
3
3
 
4
4
  /**
5
5
  * Bearing and angular math utilities.
@@ -454,35 +454,35 @@ declare const MIN_LOOK_AHEAD_METERS = 20;
454
454
  declare const MAX_LOOK_AHEAD_METERS = 100;
455
455
  declare const ARRIVAL_THRESHOLD_METERS = 30;
456
456
 
457
- declare const constants_ARRIVAL_THRESHOLD_METERS: typeof ARRIVAL_THRESHOLD_METERS;
458
- declare const constants_BASE_CORRIDOR_METERS: typeof BASE_CORRIDOR_METERS;
459
- declare const constants_BEARING_ALIGNMENT_THRESHOLD: typeof BEARING_ALIGNMENT_THRESHOLD;
460
- declare const constants_BEARING_MIN_SPEED_MPS: typeof BEARING_MIN_SPEED_MPS;
461
- declare const constants_BEARING_MISMATCH_PENALTY: typeof BEARING_MISMATCH_PENALTY;
462
- declare const constants_BEARING_MISMATCH_THRESHOLD: typeof BEARING_MISMATCH_THRESHOLD;
463
- declare const constants_BEARING_SMOOTHING_ALPHA: typeof BEARING_SMOOTHING_ALPHA;
464
- declare const constants_BETA_CORRECTION: typeof BETA_CORRECTION;
465
- declare const constants_DETOUR_COMMIT_MS: typeof DETOUR_COMMIT_MS;
466
- declare const constants_DR_MAX_AGE_MS: typeof DR_MAX_AGE_MS;
467
- declare const constants_GPS_ACCURACY_FACTOR: typeof GPS_ACCURACY_FACTOR;
468
- declare const constants_GPS_AGE_CAP_SECONDS: typeof GPS_AGE_CAP_SECONDS;
469
- declare const constants_GPS_STALE_MS: typeof GPS_STALE_MS;
470
- declare const constants_INERTIA_PENALTY: typeof INERTIA_PENALTY;
471
- declare const constants_INERTIA_SEGMENT_DIST: typeof INERTIA_SEGMENT_DIST;
472
- declare const constants_LOOK_AHEAD_SECONDS: typeof LOOK_AHEAD_SECONDS;
473
- declare const constants_MANEUVER_TRIGGER_DIST: typeof MANEUVER_TRIGGER_DIST;
474
- declare const constants_MAX_CORRIDOR_METERS: typeof MAX_CORRIDOR_METERS;
475
- declare const constants_MAX_LOOK_AHEAD_METERS: typeof MAX_LOOK_AHEAD_METERS;
476
- declare const constants_MAX_SNAP_DISTANCE: typeof MAX_SNAP_DISTANCE;
477
- declare const constants_MIN_LOOK_AHEAD_METERS: typeof MIN_LOOK_AHEAD_METERS;
478
- declare const constants_OFF_ROUTE_CONFIRM_MS: typeof OFF_ROUTE_CONFIRM_MS;
479
- declare const constants_REJOIN_CONFIRM_MS: typeof REJOIN_CONFIRM_MS;
480
- declare const constants_REJOIN_COOLDOWN_MS: typeof REJOIN_COOLDOWN_MS;
481
- declare const constants_SNAP_WINDOW_SIZE: typeof SNAP_WINDOW_SIZE;
482
- declare const constants_SPEED_CORRIDOR_FACTOR: typeof SPEED_CORRIDOR_FACTOR;
483
- declare const constants_STARTUP_GRACE_MS: typeof STARTUP_GRACE_MS;
484
- declare namespace constants {
485
- export { constants_ARRIVAL_THRESHOLD_METERS as ARRIVAL_THRESHOLD_METERS, constants_BASE_CORRIDOR_METERS as BASE_CORRIDOR_METERS, constants_BEARING_ALIGNMENT_THRESHOLD as BEARING_ALIGNMENT_THRESHOLD, constants_BEARING_MIN_SPEED_MPS as BEARING_MIN_SPEED_MPS, constants_BEARING_MISMATCH_PENALTY as BEARING_MISMATCH_PENALTY, constants_BEARING_MISMATCH_THRESHOLD as BEARING_MISMATCH_THRESHOLD, constants_BEARING_SMOOTHING_ALPHA as BEARING_SMOOTHING_ALPHA, constants_BETA_CORRECTION as BETA_CORRECTION, constants_DETOUR_COMMIT_MS as DETOUR_COMMIT_MS, constants_DR_MAX_AGE_MS as DR_MAX_AGE_MS, constants_GPS_ACCURACY_FACTOR as GPS_ACCURACY_FACTOR, constants_GPS_AGE_CAP_SECONDS as GPS_AGE_CAP_SECONDS, constants_GPS_STALE_MS as GPS_STALE_MS, constants_INERTIA_PENALTY as INERTIA_PENALTY, constants_INERTIA_SEGMENT_DIST as INERTIA_SEGMENT_DIST, constants_LOOK_AHEAD_SECONDS as LOOK_AHEAD_SECONDS, constants_MANEUVER_TRIGGER_DIST as MANEUVER_TRIGGER_DIST, constants_MAX_CORRIDOR_METERS as MAX_CORRIDOR_METERS, constants_MAX_LOOK_AHEAD_METERS as MAX_LOOK_AHEAD_METERS, constants_MAX_SNAP_DISTANCE as MAX_SNAP_DISTANCE, constants_MIN_LOOK_AHEAD_METERS as MIN_LOOK_AHEAD_METERS, constants_OFF_ROUTE_CONFIRM_MS as OFF_ROUTE_CONFIRM_MS, constants_REJOIN_CONFIRM_MS as REJOIN_CONFIRM_MS, constants_REJOIN_COOLDOWN_MS as REJOIN_COOLDOWN_MS, constants_SNAP_WINDOW_SIZE as SNAP_WINDOW_SIZE, constants_SPEED_CORRIDOR_FACTOR as SPEED_CORRIDOR_FACTOR, constants_STARTUP_GRACE_MS as STARTUP_GRACE_MS };
457
+ declare const constants_d_ARRIVAL_THRESHOLD_METERS: typeof ARRIVAL_THRESHOLD_METERS;
458
+ declare const constants_d_BASE_CORRIDOR_METERS: typeof BASE_CORRIDOR_METERS;
459
+ declare const constants_d_BEARING_ALIGNMENT_THRESHOLD: typeof BEARING_ALIGNMENT_THRESHOLD;
460
+ declare const constants_d_BEARING_MIN_SPEED_MPS: typeof BEARING_MIN_SPEED_MPS;
461
+ declare const constants_d_BEARING_MISMATCH_PENALTY: typeof BEARING_MISMATCH_PENALTY;
462
+ declare const constants_d_BEARING_MISMATCH_THRESHOLD: typeof BEARING_MISMATCH_THRESHOLD;
463
+ declare const constants_d_BEARING_SMOOTHING_ALPHA: typeof BEARING_SMOOTHING_ALPHA;
464
+ declare const constants_d_BETA_CORRECTION: typeof BETA_CORRECTION;
465
+ declare const constants_d_DETOUR_COMMIT_MS: typeof DETOUR_COMMIT_MS;
466
+ declare const constants_d_DR_MAX_AGE_MS: typeof DR_MAX_AGE_MS;
467
+ declare const constants_d_GPS_ACCURACY_FACTOR: typeof GPS_ACCURACY_FACTOR;
468
+ declare const constants_d_GPS_AGE_CAP_SECONDS: typeof GPS_AGE_CAP_SECONDS;
469
+ declare const constants_d_GPS_STALE_MS: typeof GPS_STALE_MS;
470
+ declare const constants_d_INERTIA_PENALTY: typeof INERTIA_PENALTY;
471
+ declare const constants_d_INERTIA_SEGMENT_DIST: typeof INERTIA_SEGMENT_DIST;
472
+ declare const constants_d_LOOK_AHEAD_SECONDS: typeof LOOK_AHEAD_SECONDS;
473
+ declare const constants_d_MANEUVER_TRIGGER_DIST: typeof MANEUVER_TRIGGER_DIST;
474
+ declare const constants_d_MAX_CORRIDOR_METERS: typeof MAX_CORRIDOR_METERS;
475
+ declare const constants_d_MAX_LOOK_AHEAD_METERS: typeof MAX_LOOK_AHEAD_METERS;
476
+ declare const constants_d_MAX_SNAP_DISTANCE: typeof MAX_SNAP_DISTANCE;
477
+ declare const constants_d_MIN_LOOK_AHEAD_METERS: typeof MIN_LOOK_AHEAD_METERS;
478
+ declare const constants_d_OFF_ROUTE_CONFIRM_MS: typeof OFF_ROUTE_CONFIRM_MS;
479
+ declare const constants_d_REJOIN_CONFIRM_MS: typeof REJOIN_CONFIRM_MS;
480
+ declare const constants_d_REJOIN_COOLDOWN_MS: typeof REJOIN_COOLDOWN_MS;
481
+ declare const constants_d_SNAP_WINDOW_SIZE: typeof SNAP_WINDOW_SIZE;
482
+ declare const constants_d_SPEED_CORRIDOR_FACTOR: typeof SPEED_CORRIDOR_FACTOR;
483
+ declare const constants_d_STARTUP_GRACE_MS: typeof STARTUP_GRACE_MS;
484
+ declare namespace constants_d {
485
+ export { constants_d_ARRIVAL_THRESHOLD_METERS as ARRIVAL_THRESHOLD_METERS, constants_d_BASE_CORRIDOR_METERS as BASE_CORRIDOR_METERS, constants_d_BEARING_ALIGNMENT_THRESHOLD as BEARING_ALIGNMENT_THRESHOLD, constants_d_BEARING_MIN_SPEED_MPS as BEARING_MIN_SPEED_MPS, constants_d_BEARING_MISMATCH_PENALTY as BEARING_MISMATCH_PENALTY, constants_d_BEARING_MISMATCH_THRESHOLD as BEARING_MISMATCH_THRESHOLD, constants_d_BEARING_SMOOTHING_ALPHA as BEARING_SMOOTHING_ALPHA, constants_d_BETA_CORRECTION as BETA_CORRECTION, constants_d_DETOUR_COMMIT_MS as DETOUR_COMMIT_MS, constants_d_DR_MAX_AGE_MS as DR_MAX_AGE_MS, constants_d_GPS_ACCURACY_FACTOR as GPS_ACCURACY_FACTOR, constants_d_GPS_AGE_CAP_SECONDS as GPS_AGE_CAP_SECONDS, constants_d_GPS_STALE_MS as GPS_STALE_MS, constants_d_INERTIA_PENALTY as INERTIA_PENALTY, constants_d_INERTIA_SEGMENT_DIST as INERTIA_SEGMENT_DIST, constants_d_LOOK_AHEAD_SECONDS as LOOK_AHEAD_SECONDS, constants_d_MANEUVER_TRIGGER_DIST as MANEUVER_TRIGGER_DIST, constants_d_MAX_CORRIDOR_METERS as MAX_CORRIDOR_METERS, constants_d_MAX_LOOK_AHEAD_METERS as MAX_LOOK_AHEAD_METERS, constants_d_MAX_SNAP_DISTANCE as MAX_SNAP_DISTANCE, constants_d_MIN_LOOK_AHEAD_METERS as MIN_LOOK_AHEAD_METERS, constants_d_OFF_ROUTE_CONFIRM_MS as OFF_ROUTE_CONFIRM_MS, constants_d_REJOIN_CONFIRM_MS as REJOIN_CONFIRM_MS, constants_d_REJOIN_COOLDOWN_MS as REJOIN_COOLDOWN_MS, constants_d_SNAP_WINDOW_SIZE as SNAP_WINDOW_SIZE, constants_d_SPEED_CORRIDOR_FACTOR as SPEED_CORRIDOR_FACTOR, constants_d_STARTUP_GRACE_MS as STARTUP_GRACE_MS };
486
486
  }
487
487
 
488
- export { type BuildOptions, type CameraOptions, constants as Constants, Coordinate, CustomRouteBuilder, type CustomWaypoint, type DirectionsLeg, type DirectionsManeuver, type DirectionsOptions, type DirectionsProvider, type DirectionsResult, type DirectionsStep, type Kalman2DState, KalmanFilter2D, type MapRendererAdapter, type ORSConfig, type ORSProfile, type OSRMConfig, OSRMDirectionsProvider, OpenRouteServiceProvider, RouteSnapper, type RouteStyle, type SnapResult, type SnapperOptions, type ValhallaConfig, type ValhallaCostingModel, ValhallaDirectionsProvider, type VehicleStyle, type WaypointOptions, buildForwardCumulativeDistances, buildReverseCumulativeDistances, getBearingBetweenPoints, interpolatePoint, kalmanUpdate2D, normalizeAngle, projectPointOnSegment };
488
+ export { type BuildOptions, type CameraOptions, constants_d as Constants, Coordinate, CustomRouteBuilder, type CustomWaypoint, type DirectionsLeg, type DirectionsManeuver, type DirectionsOptions, type DirectionsProvider, type DirectionsResult, type DirectionsStep, type Kalman2DState, KalmanFilter2D, type MapRendererAdapter, type ORSConfig, type ORSProfile, type OSRMConfig, OSRMDirectionsProvider, OpenRouteServiceProvider, RouteSnapper, type RouteStyle, type SnapResult, type SnapperOptions, type ValhallaConfig, type ValhallaCostingModel, ValhallaDirectionsProvider, type VehicleStyle, type WaypointOptions, buildForwardCumulativeDistances, buildReverseCumulativeDistances, getBearingBetweenPoints, interpolatePoint, kalmanUpdate2D, normalizeAngle, projectPointOnSegment };
package/dist/core.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { C as Coordinate, g as NavCoreState } from './NavCore-Bjl5fTea.js';
2
- export { F as FEATURES, a as FeatureKey, L as LicenseManager, b as LicensePayload, c as LicenseStatus, o as destinationPoint, p as geoGetBearing, q as haversineDistance } from './NavCore-Bjl5fTea.js';
1
+ import { C as Coordinate, g as NavCoreState } from './NavCore.d-BuXR5DO7.js';
2
+ export { F as FEATURES, a as FeatureKey, L as LicenseManager, b as LicensePayload, c as LicenseStatus, o as destinationPoint, p as geoGetBearing, q as haversineDistance } from './NavCore.d-BuXR5DO7.js';
3
3
 
4
4
  /**
5
5
  * Bearing and angular math utilities.
@@ -454,35 +454,35 @@ declare const MIN_LOOK_AHEAD_METERS = 20;
454
454
  declare const MAX_LOOK_AHEAD_METERS = 100;
455
455
  declare const ARRIVAL_THRESHOLD_METERS = 30;
456
456
 
457
- declare const constants_ARRIVAL_THRESHOLD_METERS: typeof ARRIVAL_THRESHOLD_METERS;
458
- declare const constants_BASE_CORRIDOR_METERS: typeof BASE_CORRIDOR_METERS;
459
- declare const constants_BEARING_ALIGNMENT_THRESHOLD: typeof BEARING_ALIGNMENT_THRESHOLD;
460
- declare const constants_BEARING_MIN_SPEED_MPS: typeof BEARING_MIN_SPEED_MPS;
461
- declare const constants_BEARING_MISMATCH_PENALTY: typeof BEARING_MISMATCH_PENALTY;
462
- declare const constants_BEARING_MISMATCH_THRESHOLD: typeof BEARING_MISMATCH_THRESHOLD;
463
- declare const constants_BEARING_SMOOTHING_ALPHA: typeof BEARING_SMOOTHING_ALPHA;
464
- declare const constants_BETA_CORRECTION: typeof BETA_CORRECTION;
465
- declare const constants_DETOUR_COMMIT_MS: typeof DETOUR_COMMIT_MS;
466
- declare const constants_DR_MAX_AGE_MS: typeof DR_MAX_AGE_MS;
467
- declare const constants_GPS_ACCURACY_FACTOR: typeof GPS_ACCURACY_FACTOR;
468
- declare const constants_GPS_AGE_CAP_SECONDS: typeof GPS_AGE_CAP_SECONDS;
469
- declare const constants_GPS_STALE_MS: typeof GPS_STALE_MS;
470
- declare const constants_INERTIA_PENALTY: typeof INERTIA_PENALTY;
471
- declare const constants_INERTIA_SEGMENT_DIST: typeof INERTIA_SEGMENT_DIST;
472
- declare const constants_LOOK_AHEAD_SECONDS: typeof LOOK_AHEAD_SECONDS;
473
- declare const constants_MANEUVER_TRIGGER_DIST: typeof MANEUVER_TRIGGER_DIST;
474
- declare const constants_MAX_CORRIDOR_METERS: typeof MAX_CORRIDOR_METERS;
475
- declare const constants_MAX_LOOK_AHEAD_METERS: typeof MAX_LOOK_AHEAD_METERS;
476
- declare const constants_MAX_SNAP_DISTANCE: typeof MAX_SNAP_DISTANCE;
477
- declare const constants_MIN_LOOK_AHEAD_METERS: typeof MIN_LOOK_AHEAD_METERS;
478
- declare const constants_OFF_ROUTE_CONFIRM_MS: typeof OFF_ROUTE_CONFIRM_MS;
479
- declare const constants_REJOIN_CONFIRM_MS: typeof REJOIN_CONFIRM_MS;
480
- declare const constants_REJOIN_COOLDOWN_MS: typeof REJOIN_COOLDOWN_MS;
481
- declare const constants_SNAP_WINDOW_SIZE: typeof SNAP_WINDOW_SIZE;
482
- declare const constants_SPEED_CORRIDOR_FACTOR: typeof SPEED_CORRIDOR_FACTOR;
483
- declare const constants_STARTUP_GRACE_MS: typeof STARTUP_GRACE_MS;
484
- declare namespace constants {
485
- export { constants_ARRIVAL_THRESHOLD_METERS as ARRIVAL_THRESHOLD_METERS, constants_BASE_CORRIDOR_METERS as BASE_CORRIDOR_METERS, constants_BEARING_ALIGNMENT_THRESHOLD as BEARING_ALIGNMENT_THRESHOLD, constants_BEARING_MIN_SPEED_MPS as BEARING_MIN_SPEED_MPS, constants_BEARING_MISMATCH_PENALTY as BEARING_MISMATCH_PENALTY, constants_BEARING_MISMATCH_THRESHOLD as BEARING_MISMATCH_THRESHOLD, constants_BEARING_SMOOTHING_ALPHA as BEARING_SMOOTHING_ALPHA, constants_BETA_CORRECTION as BETA_CORRECTION, constants_DETOUR_COMMIT_MS as DETOUR_COMMIT_MS, constants_DR_MAX_AGE_MS as DR_MAX_AGE_MS, constants_GPS_ACCURACY_FACTOR as GPS_ACCURACY_FACTOR, constants_GPS_AGE_CAP_SECONDS as GPS_AGE_CAP_SECONDS, constants_GPS_STALE_MS as GPS_STALE_MS, constants_INERTIA_PENALTY as INERTIA_PENALTY, constants_INERTIA_SEGMENT_DIST as INERTIA_SEGMENT_DIST, constants_LOOK_AHEAD_SECONDS as LOOK_AHEAD_SECONDS, constants_MANEUVER_TRIGGER_DIST as MANEUVER_TRIGGER_DIST, constants_MAX_CORRIDOR_METERS as MAX_CORRIDOR_METERS, constants_MAX_LOOK_AHEAD_METERS as MAX_LOOK_AHEAD_METERS, constants_MAX_SNAP_DISTANCE as MAX_SNAP_DISTANCE, constants_MIN_LOOK_AHEAD_METERS as MIN_LOOK_AHEAD_METERS, constants_OFF_ROUTE_CONFIRM_MS as OFF_ROUTE_CONFIRM_MS, constants_REJOIN_CONFIRM_MS as REJOIN_CONFIRM_MS, constants_REJOIN_COOLDOWN_MS as REJOIN_COOLDOWN_MS, constants_SNAP_WINDOW_SIZE as SNAP_WINDOW_SIZE, constants_SPEED_CORRIDOR_FACTOR as SPEED_CORRIDOR_FACTOR, constants_STARTUP_GRACE_MS as STARTUP_GRACE_MS };
457
+ declare const constants_d_ARRIVAL_THRESHOLD_METERS: typeof ARRIVAL_THRESHOLD_METERS;
458
+ declare const constants_d_BASE_CORRIDOR_METERS: typeof BASE_CORRIDOR_METERS;
459
+ declare const constants_d_BEARING_ALIGNMENT_THRESHOLD: typeof BEARING_ALIGNMENT_THRESHOLD;
460
+ declare const constants_d_BEARING_MIN_SPEED_MPS: typeof BEARING_MIN_SPEED_MPS;
461
+ declare const constants_d_BEARING_MISMATCH_PENALTY: typeof BEARING_MISMATCH_PENALTY;
462
+ declare const constants_d_BEARING_MISMATCH_THRESHOLD: typeof BEARING_MISMATCH_THRESHOLD;
463
+ declare const constants_d_BEARING_SMOOTHING_ALPHA: typeof BEARING_SMOOTHING_ALPHA;
464
+ declare const constants_d_BETA_CORRECTION: typeof BETA_CORRECTION;
465
+ declare const constants_d_DETOUR_COMMIT_MS: typeof DETOUR_COMMIT_MS;
466
+ declare const constants_d_DR_MAX_AGE_MS: typeof DR_MAX_AGE_MS;
467
+ declare const constants_d_GPS_ACCURACY_FACTOR: typeof GPS_ACCURACY_FACTOR;
468
+ declare const constants_d_GPS_AGE_CAP_SECONDS: typeof GPS_AGE_CAP_SECONDS;
469
+ declare const constants_d_GPS_STALE_MS: typeof GPS_STALE_MS;
470
+ declare const constants_d_INERTIA_PENALTY: typeof INERTIA_PENALTY;
471
+ declare const constants_d_INERTIA_SEGMENT_DIST: typeof INERTIA_SEGMENT_DIST;
472
+ declare const constants_d_LOOK_AHEAD_SECONDS: typeof LOOK_AHEAD_SECONDS;
473
+ declare const constants_d_MANEUVER_TRIGGER_DIST: typeof MANEUVER_TRIGGER_DIST;
474
+ declare const constants_d_MAX_CORRIDOR_METERS: typeof MAX_CORRIDOR_METERS;
475
+ declare const constants_d_MAX_LOOK_AHEAD_METERS: typeof MAX_LOOK_AHEAD_METERS;
476
+ declare const constants_d_MAX_SNAP_DISTANCE: typeof MAX_SNAP_DISTANCE;
477
+ declare const constants_d_MIN_LOOK_AHEAD_METERS: typeof MIN_LOOK_AHEAD_METERS;
478
+ declare const constants_d_OFF_ROUTE_CONFIRM_MS: typeof OFF_ROUTE_CONFIRM_MS;
479
+ declare const constants_d_REJOIN_CONFIRM_MS: typeof REJOIN_CONFIRM_MS;
480
+ declare const constants_d_REJOIN_COOLDOWN_MS: typeof REJOIN_COOLDOWN_MS;
481
+ declare const constants_d_SNAP_WINDOW_SIZE: typeof SNAP_WINDOW_SIZE;
482
+ declare const constants_d_SPEED_CORRIDOR_FACTOR: typeof SPEED_CORRIDOR_FACTOR;
483
+ declare const constants_d_STARTUP_GRACE_MS: typeof STARTUP_GRACE_MS;
484
+ declare namespace constants_d {
485
+ export { constants_d_ARRIVAL_THRESHOLD_METERS as ARRIVAL_THRESHOLD_METERS, constants_d_BASE_CORRIDOR_METERS as BASE_CORRIDOR_METERS, constants_d_BEARING_ALIGNMENT_THRESHOLD as BEARING_ALIGNMENT_THRESHOLD, constants_d_BEARING_MIN_SPEED_MPS as BEARING_MIN_SPEED_MPS, constants_d_BEARING_MISMATCH_PENALTY as BEARING_MISMATCH_PENALTY, constants_d_BEARING_MISMATCH_THRESHOLD as BEARING_MISMATCH_THRESHOLD, constants_d_BEARING_SMOOTHING_ALPHA as BEARING_SMOOTHING_ALPHA, constants_d_BETA_CORRECTION as BETA_CORRECTION, constants_d_DETOUR_COMMIT_MS as DETOUR_COMMIT_MS, constants_d_DR_MAX_AGE_MS as DR_MAX_AGE_MS, constants_d_GPS_ACCURACY_FACTOR as GPS_ACCURACY_FACTOR, constants_d_GPS_AGE_CAP_SECONDS as GPS_AGE_CAP_SECONDS, constants_d_GPS_STALE_MS as GPS_STALE_MS, constants_d_INERTIA_PENALTY as INERTIA_PENALTY, constants_d_INERTIA_SEGMENT_DIST as INERTIA_SEGMENT_DIST, constants_d_LOOK_AHEAD_SECONDS as LOOK_AHEAD_SECONDS, constants_d_MANEUVER_TRIGGER_DIST as MANEUVER_TRIGGER_DIST, constants_d_MAX_CORRIDOR_METERS as MAX_CORRIDOR_METERS, constants_d_MAX_LOOK_AHEAD_METERS as MAX_LOOK_AHEAD_METERS, constants_d_MAX_SNAP_DISTANCE as MAX_SNAP_DISTANCE, constants_d_MIN_LOOK_AHEAD_METERS as MIN_LOOK_AHEAD_METERS, constants_d_OFF_ROUTE_CONFIRM_MS as OFF_ROUTE_CONFIRM_MS, constants_d_REJOIN_CONFIRM_MS as REJOIN_CONFIRM_MS, constants_d_REJOIN_COOLDOWN_MS as REJOIN_COOLDOWN_MS, constants_d_SNAP_WINDOW_SIZE as SNAP_WINDOW_SIZE, constants_d_SPEED_CORRIDOR_FACTOR as SPEED_CORRIDOR_FACTOR, constants_d_STARTUP_GRACE_MS as STARTUP_GRACE_MS };
486
486
  }
487
487
 
488
- export { type BuildOptions, type CameraOptions, constants as Constants, Coordinate, CustomRouteBuilder, type CustomWaypoint, type DirectionsLeg, type DirectionsManeuver, type DirectionsOptions, type DirectionsProvider, type DirectionsResult, type DirectionsStep, type Kalman2DState, KalmanFilter2D, type MapRendererAdapter, type ORSConfig, type ORSProfile, type OSRMConfig, OSRMDirectionsProvider, OpenRouteServiceProvider, RouteSnapper, type RouteStyle, type SnapResult, type SnapperOptions, type ValhallaConfig, type ValhallaCostingModel, ValhallaDirectionsProvider, type VehicleStyle, type WaypointOptions, buildForwardCumulativeDistances, buildReverseCumulativeDistances, getBearingBetweenPoints, interpolatePoint, kalmanUpdate2D, normalizeAngle, projectPointOnSegment };
488
+ export { type BuildOptions, type CameraOptions, constants_d as Constants, Coordinate, CustomRouteBuilder, type CustomWaypoint, type DirectionsLeg, type DirectionsManeuver, type DirectionsOptions, type DirectionsProvider, type DirectionsResult, type DirectionsStep, type Kalman2DState, KalmanFilter2D, type MapRendererAdapter, type ORSConfig, type ORSProfile, type OSRMConfig, OSRMDirectionsProvider, OpenRouteServiceProvider, RouteSnapper, type RouteStyle, type SnapResult, type SnapperOptions, type ValhallaConfig, type ValhallaCostingModel, ValhallaDirectionsProvider, type VehicleStyle, type WaypointOptions, buildForwardCumulativeDistances, buildReverseCumulativeDistances, getBearingBetweenPoints, interpolatePoint, kalmanUpdate2D, normalizeAngle, projectPointOnSegment };
package/dist/core.js CHANGED
@@ -1,8 +1,7 @@
1
- 'use strict';var H=Object.defineProperty;var $=(i,t)=>{for(var e in t)H(i,e,{get:t[e],enumerable:true});};function f(i,t,e,n){let r=(e-i)*(Math.PI/180),s=(n-t)*(Math.PI/180),l=Math.sin(r/2)*Math.sin(r/2)+Math.cos(i*(Math.PI/180))*Math.cos(e*(Math.PI/180))*Math.sin(s/2)*Math.sin(s/2);return 6371e3*(2*Math.atan2(Math.sqrt(l),Math.sqrt(1-l)))}function X(i,t,e,n){let r=n/6371e3,s=e*(Math.PI/180),l=i*(Math.PI/180),p=t*(Math.PI/180),a=Math.asin(Math.sin(l)*Math.cos(r)+Math.cos(l)*Math.sin(r)*Math.cos(s));return [((p+Math.atan2(Math.sin(s)*Math.sin(r)*Math.cos(l),Math.cos(r)-Math.sin(l)*Math.sin(a)))*180/Math.PI+540)%360-180,a*180/Math.PI]}function j(i,t){let e=i[1]*(Math.PI/180),n=i[0]*(Math.PI/180),r=t[1]*(Math.PI/180),s=t[0]*(Math.PI/180),l=Math.sin(s-n)*Math.cos(r),p=Math.cos(e)*Math.sin(r)-Math.sin(e)*Math.cos(r)*Math.cos(s-n),a=Math.atan2(l,p)*(180/Math.PI);return a=(a+360)%360,a}function P(i){let t=i%360;return t>180?t-360:t<-180?t+360:t}function x(i,t){let e=i[1]*(Math.PI/180),n=i[0]*(Math.PI/180),r=t[1]*(Math.PI/180),s=t[0]*(Math.PI/180),l=Math.sin(s-n)*Math.cos(r),p=Math.cos(e)*Math.sin(r)-Math.sin(e)*Math.cos(r)*Math.cos(s-n);return (Math.atan2(l,p)*180/Math.PI+360)%360}function q(i,t,e){let n=(r,s,l)=>r+(s-r)*l;return [n(i[0],t[0],e),n(i[1],t[1],e)]}function A(i,t,e){let[n,r]=i,[s,l]=t,[p,a]=e,d=p-s,u=a-l,o=d*d+u*u;if(o===0)return t;let c=((n-s)*d+(r-l)*u)/o;return c=Math.max(0,Math.min(1,c)),[s+c*d,l+c*u]}function z(i){let t=new Float64Array(i.length);for(let e=1;e<i.length;e++)t[e]=t[e-1]+f(i[e-1][1],i[e-1][0],i[e][1],i[e][0]);return t}function Y(i){let t=new Float64Array(i.length);for(let e=i.length-2;e>=0;e--)t[e]=t[e+1]+f(i[e][1],i[e][0],i[e+1][1],i[e+1][0]);return t}function L(i,t,e,n,r,s=1e-5,l=5e-5){i.x+=i.vx*r,i.y+=i.vy*r,i.P+=s;let p=l*Math.max(1,n/5),a=i.P/(i.P+p),d=t-i.x,u=e-i.y;return i.x+=a*d,i.y+=a*u,r>0&&(i.vx=d/r*a,i.vy=u/r*a),i.P=(1-a)*i.P,i}var S=class{constructor(t=1e-5,e=5e-5){this.lastTimestamp=0;this.Q=t,this.rBase=e,this.state={x:0,y:0,vx:0,vy:0,P:1};}init(t,e,n){this.state={x:t,y:e,vx:0,vy:0,P:1},this.lastTimestamp=n;}update(t,e,n,r){if(this.lastTimestamp===0)return this.init(t,e,r),[t,e];let s=Math.max(.001,(r-this.lastTimestamp)/1e3);return this.lastTimestamp=r,L(this.state,t,e,n,s,this.Q,this.rBase),[this.state.x,this.state.y]}getPosition(){return [this.state.x,this.state.y]}getState(){return {...this.state}}reset(){this.state={x:0,y:0,vx:0,vy:0,P:1},this.lastTimestamp=0;}};var W={};$(W,{ARRIVAL_THRESHOLD_METERS:()=>Ct,BASE_CORRIDOR_METERS:()=>J,BEARING_ALIGNMENT_THRESHOLD:()=>rt,BEARING_MIN_SPEED_MPS:()=>ot,BEARING_MISMATCH_PENALTY:()=>U,BEARING_MISMATCH_THRESHOLD:()=>k,BEARING_SMOOTHING_ALPHA:()=>nt,BETA_CORRECTION:()=>mt,DETOUR_COMMIT_MS:()=>lt,DR_MAX_AGE_MS:()=>it,GPS_ACCURACY_FACTOR:()=>tt,GPS_AGE_CAP_SECONDS:()=>dt,GPS_STALE_MS:()=>ut,INERTIA_PENALTY:()=>B,INERTIA_SEGMENT_DIST:()=>K,LOOK_AHEAD_SECONDS:()=>ft,MANEUVER_TRIGGER_DIST:()=>ht,MAX_CORRIDOR_METERS:()=>Q,MAX_LOOK_AHEAD_METERS:()=>gt,MAX_SNAP_DISTANCE:()=>F,MIN_LOOK_AHEAD_METERS:()=>yt,OFF_ROUTE_CONFIRM_MS:()=>st,REJOIN_CONFIRM_MS:()=>at,REJOIN_COOLDOWN_MS:()=>ct,SNAP_WINDOW_SIZE:()=>et,SPEED_CORRIDOR_FACTOR:()=>Z,STARTUP_GRACE_MS:()=>pt});var J=25,Q=60,Z=1.2,tt=.5,F=80,k=90,U=500,B=200,K=5,et=25,nt=.3,ot=1.5,rt=55,it=5e3,st=2e3,at=1500,ct=12e3,pt=3e3,lt=4e3,ut=3e3,dt=10,ht=25,mt=.15,ft=3,yt=20,gt=100,Ct=30;var Rt={useBearingPenalty:true,useInertiaPenalty:true,maxSnapDistance:80},E=class{constructor(t){this.options={...Rt,...t};}snap(t,e,n,r,s,l,p,a=null,d=null){let u=e.length,o=p,c=1/0,h=1/0,T=e[p]??[0,0];for(let C=0;C<=r;C++){let m=n+C;if(m>u-2)if(s&&l>u*.7)m=m%(u-1);else break;if(m<0||m>=u-1)continue;let w=e[m],N=e[m+1],R=A(t,w,N),b=f(t[1],t[0],R[1],R[0]);if(b>this.options.maxSnapDistance*2)continue;let y=b;if(this.options.useBearingPenalty&&a!==null){let G=x(w,N);Math.abs(P(a-G))>90&&(y+=500);}this.options.useInertiaPenalty&&d!==null&&Math.abs(m-d)>=5&&(y+=200),y<c&&(c=y,h=b,o=m,T=R);}return {idx:o,dist:h,proj:T}}};var D=class{constructor(t){this.config={baseUrl:t.baseUrl.replace(/\/$/,""),profile:t.profile??"driving",maxWaypointsPerChunk:t.maxWaypointsPerChunk??100};}async getRoute(t,e){if(t.length<2)throw new Error("[OSRM] At least 2 waypoints required");let n=e?.profile??this.config.profile;return t.length<=this.config.maxWaypointsPerChunk?this.fetchRoute(t,n,e):this.fetchChunked(t,n,e)}async fetchRoute(t,e,n){let r=t.map(u=>`${u[0]},${u[1]}`).join(";"),s=n?.steps!==false?"true":"false",l=`${this.config.baseUrl}/route/v1/${e}/${r}?overview=full&geometries=geojson&steps=${s}&annotations=false`,p=await fetch(l);if(!p.ok)throw new Error(`[OSRM] HTTP ${p.status}: ${p.statusText}`);let a=await p.json();if(a.code!=="Ok"||!a.routes?.length)throw new Error(`[OSRM] No route found: ${a.code}`);let d=a.routes[0];return {geometry:d.geometry.coordinates,distance:d.distance,duration:d.duration,legs:(d.legs??[]).map(u=>({distance:u.distance,duration:u.duration,steps:(u.steps??[]).map(o=>({distance:o.distance,duration:o.duration,geometry:o.geometry?.coordinates??[],maneuver:{type:o.maneuver?.type??"unknown",modifier:o.maneuver?.modifier,location:o.maneuver?.location??[0,0],bearingBefore:o.maneuver?.bearing_before??0,bearingAfter:o.maneuver?.bearing_after??0,instruction:o.name??void 0},name:o.name}))})),raw:a}}async fetchChunked(t,e,n){let r=this.config.maxWaypointsPerChunk,s=[];for(let o=0;o<t.length;o+=r-1){let c=t.slice(o,o+r);if(c.length<2||(s.push(c),o+r>=t.length))break}let l=await Promise.all(s.map(o=>this.fetchRoute(o,e,n))),p=[],a=0,d=0,u=[];for(let o=0;o<l.length;o++){let c=l[o];p.push(...o===0?c.geometry:c.geometry.slice(1)),a+=c.distance,d+=c.duration,u.push(...c.legs);}return {geometry:p,distance:a,duration:d,legs:u,raw:l.map(o=>o.raw)}}};var _=class{constructor(t){this.config={baseUrl:t.baseUrl.replace(/\/$/,""),costing:t.costing??"auto",apiKey:t.apiKey??"",maxWaypointsPerChunk:t.maxWaypointsPerChunk??50};}async getRoute(t,e){if(t.length<2)throw new Error("[Valhalla] At least 2 waypoints required");let n=this.profileToCosting(e?.profile);return t.length<=this.config.maxWaypointsPerChunk?this.fetchRoute(t,n,e):this.fetchChunked(t,n,e)}profileToCosting(t){switch(t){case "cycling":return "bicycle";case "walking":return "pedestrian";default:return this.config.costing}}async fetchRoute(t,e,n){let r=t.map(c=>({lon:c[0],lat:c[1],type:"break"})),s=JSON.stringify({locations:r,costing:e,directions_options:{units:"kilometers"}}),l={"Content-Type":"application/json"};this.config.apiKey&&(l.api_key=this.config.apiKey);let p=await fetch(`${this.config.baseUrl}/route`,{method:"POST",headers:l,body:s});if(!p.ok){let c=await p.text();throw new Error(`[Valhalla] HTTP ${p.status}: ${c}`)}let a=await p.json(),d=this.decodePolyline(a.trip?.legs?.[0]?.shape??""),u=a.trip?.summary??{},o=(a.trip?.legs??[]).map(c=>({distance:(c.summary?.length??0)*1e3,duration:c.summary?.time??0,steps:(c.maneuvers??[]).map(h=>({distance:(h.length??0)*1e3,duration:h.time??0,geometry:[],maneuver:{type:h.type?.toString()??"unknown",modifier:void 0,location:t[0],bearingBefore:h.begin_heading??0,bearingAfter:h.end_heading??0,instruction:h.instruction},name:h.street_names?.[0]}))}));return {geometry:d,distance:(u.length??0)*1e3,duration:u.time??0,legs:o,raw:a}}decodePolyline(t,e=6){let n=Math.pow(10,e),r=[],s=0,l=0,p=0;for(;s<t.length;){let a=0,d=0,u;do u=t.charCodeAt(s++)-63,d|=(u&31)<<a,a+=5;while(u>=32);let o=(d&1)!==0?~(d>>1):d>>1;l+=o,a=0,d=0;do u=t.charCodeAt(s++)-63,d|=(u&31)<<a,a+=5;while(u>=32);let c=(d&1)!==0?~(d>>1):d>>1;p+=c,r.push([p/n,l/n]);}return r}async fetchChunked(t,e,n){let r=this.config.maxWaypointsPerChunk,s=[];for(let o=0;o<t.length;o+=r-1){let c=t.slice(o,o+r);if(c.length<2||(s.push(c),o+r>=t.length))break}let l=await Promise.all(s.map(o=>this.fetchRoute(o,e,n))),p=[],a=0,d=0,u=[];for(let o=0;o<l.length;o++){let c=l[o];p.push(...o===0?c.geometry:c.geometry.slice(1)),a+=c.distance,d+=c.duration,u.push(...c.legs);}return {geometry:p,distance:a,duration:d,legs:u,raw:l.map(o=>o.raw)}}};var bt="https://api.openrouteservice.org/v2/directions";var M=class{constructor(t){this.config={apiKey:t.apiKey,profile:t.profile??"driving-car",baseUrl:t.baseUrl??bt,maxWaypointsPerChunk:t.maxWaypointsPerChunk??50};}async getRoute(t,e){if(t.length<2)throw new Error("[ORS] At least 2 waypoints required");let n=this.profileFromOptions(e);return t.length<=this.config.maxWaypointsPerChunk?this.fetchRoute(t,n,e):this.fetchChunked(t,n,e)}profileFromOptions(t){switch(t?.profile){case "cycling":return "cycling-regular";case "walking":return "foot-walking";default:return this.config.profile}}async fetchRoute(t,e,n){let r=JSON.stringify({coordinates:t,instructions:n?.steps!==false,language:n?.language??"en"}),s=await fetch(`${this.config.baseUrl}/${e}/geojson`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:this.config.apiKey},body:r});if(!s.ok){let o=await s.text();throw new Error(`[ORS] HTTP ${s.status}: ${o}`)}let l=await s.json(),p=l.features?.[0];if(!p)throw new Error("[ORS] No route returned");let a=p.properties?.summary??{},u=(p.properties?.segments??[]).map(o=>({distance:o.distance??0,duration:o.duration??0,steps:(o.steps??[]).map(c=>({distance:c.distance??0,duration:c.duration??0,geometry:[],maneuver:{type:c.type?.toString()??"unknown",modifier:void 0,location:t[0],bearingBefore:0,bearingAfter:0,instruction:c.instruction},name:c.name}))}));return {geometry:p.geometry?.coordinates??[],distance:a.distance??0,duration:a.duration??0,legs:u,raw:l}}async fetchChunked(t,e,n){let r=this.config.maxWaypointsPerChunk,s=[];for(let o=0;o<t.length;o+=r-1){let c=t.slice(o,o+r);if(c.length<2||(s.push(c),o+r>=t.length))break}let l=await Promise.all(s.map(o=>this.fetchRoute(o,e,n))),p=[],a=0,d=0,u=[];for(let o=0;o<l.length;o++){let c=l[o];p.push(...o===0?c.geometry:c.geometry.slice(1)),a+=c.distance,d+=c.duration,u.push(...c.legs);}return {geometry:p,distance:a,duration:d,legs:u,raw:l.map(o=>o.raw)}}};var Pt=0;function V(){return `wp_${Date.now()}_${++Pt}`}var v=class{constructor(){this.waypoints=[];}addWaypoint(t,e){let n=V();return this.waypoints.push({id:n,coord:t,options:e}),n}insertWaypoint(t,e){let n=this.waypoints.findIndex(s=>s.id===e);if(n===-1)throw new Error(`Waypoint ${e} not found`);let r=V();return this.waypoints.splice(n+1,0,{id:r,coord:t,options:void 0}),r}removeWaypoint(t){let e=this.waypoints.findIndex(n=>n.id===t);if(e===-1)throw new Error(`Waypoint ${t} not found`);this.waypoints.splice(e,1);}moveWaypoint(t,e){let n=this.waypoints.find(r=>r.id===t);if(!n)throw new Error(`Waypoint ${t} not found`);n.coord=e;}getWaypoints(){return this.waypoints}get size(){return this.waypoints.length}chunk(t="OVERLAP_1",e=25){let n=this.waypoints.map(p=>p.coord);if(n.length<=e)return [n];let s=e-(t==="OVERLAP_2"?2:1),l=[];for(let p=0;p<n.length;p+=s){let a=n.slice(p,p+e);if(l.push(a),p+e>=n.length)break}return l}buildStraightLine(){return {geometry:this.waypoints.map(t=>t.coord),waypoints:[...this.waypoints]}}fromGPX(t){this.waypoints=[];let e=/<(?:trkpt|wpt|rtept)\s+lat="([^"]+)"\s+lon="([^"]+)"/g,n;for(;(n=e.exec(t))!==null;){let r=parseFloat(n[1]),s=parseFloat(n[2]);isFinite(r)&&isFinite(s)&&this.addWaypoint([s,r]);}}toGPX(){return `<?xml version="1.0" encoding="UTF-8"?>
1
+ 'use strict';var H=Object.defineProperty;var $=(i,t)=>{for(var e in t)H(i,e,{get:t[e],enumerable:true});};function f(i,t,e,n){let r=(e-i)*(Math.PI/180),s=(n-t)*(Math.PI/180),l=Math.sin(r/2)*Math.sin(r/2)+Math.cos(i*(Math.PI/180))*Math.cos(e*(Math.PI/180))*Math.sin(s/2)*Math.sin(s/2);return 6371e3*(2*Math.atan2(Math.sqrt(l),Math.sqrt(1-l)))}function X(i,t,e,n){let r=n/6371e3,s=e*(Math.PI/180),l=i*(Math.PI/180),p=t*(Math.PI/180),a=Math.asin(Math.sin(l)*Math.cos(r)+Math.cos(l)*Math.sin(r)*Math.cos(s));return [((p+Math.atan2(Math.sin(s)*Math.sin(r)*Math.cos(l),Math.cos(r)-Math.sin(l)*Math.sin(a)))*180/Math.PI+540)%360-180,a*180/Math.PI]}function j(i,t){let e=i[1]*(Math.PI/180),n=i[0]*(Math.PI/180),r=t[1]*(Math.PI/180),s=t[0]*(Math.PI/180),l=Math.sin(s-n)*Math.cos(r),p=Math.cos(e)*Math.sin(r)-Math.sin(e)*Math.cos(r)*Math.cos(s-n),a=Math.atan2(l,p)*(180/Math.PI);return a=(a+360)%360,a}function v(i){let t=i%360;return t>180?t-360:t<-180?t+360:t}function S(i,t){let e=i[1]*(Math.PI/180),n=i[0]*(Math.PI/180),r=t[1]*(Math.PI/180),s=t[0]*(Math.PI/180),l=Math.sin(s-n)*Math.cos(r),p=Math.cos(e)*Math.sin(r)-Math.sin(e)*Math.cos(r)*Math.cos(s-n);return (Math.atan2(l,p)*180/Math.PI+360)%360}function Y(i,t,e){let n=(r,s,l)=>r+(s-r)*l;return [n(i[0],t[0],e),n(i[1],t[1],e)]}function A(i,t,e){let[n,r]=i,[s,l]=t,[p,a]=e,d=p-s,u=a-l,o=d*d+u*u;if(o===0)return t;let c=((n-s)*d+(r-l)*u)/o;return c=Math.max(0,Math.min(1,c)),[s+c*d,l+c*u]}function J(i){let t=new Float64Array(i.length);for(let e=1;e<i.length;e++)t[e]=t[e-1]+f(i[e-1][1],i[e-1][0],i[e][1],i[e][0]);return t}function q(i){let t=new Float64Array(i.length);for(let e=i.length-2;e>=0;e--)t[e]=t[e+1]+f(i[e][1],i[e][0],i[e+1][1],i[e+1][0]);return t}function L(i,t,e,n,r,s=1e-5,l=5e-5){i.x+=i.vx*r,i.y+=i.vy*r,i.P+=s;let p=l*Math.max(1,n/5),a=i.P/(i.P+p),d=t-i.x,u=e-i.y;return i.x+=a*d,i.y+=a*u,r>0&&(i.vx=d/r*a,i.vy=u/r*a),i.P=(1-a)*i.P,i}var x=class{constructor(t=1e-5,e=5e-5){this.lastTimestamp=0;this.Q=t,this.rBase=e,this.state={x:0,y:0,vx:0,vy:0,P:1};}init(t,e,n){this.state={x:t,y:e,vx:0,vy:0,P:1},this.lastTimestamp=n;}update(t,e,n,r){if(this.lastTimestamp===0)return this.init(t,e,r),[t,e];let s=Math.max(.001,(r-this.lastTimestamp)/1e3);return this.lastTimestamp=r,L(this.state,t,e,n,s,this.Q,this.rBase),[this.state.x,this.state.y]}getPosition(){return [this.state.x,this.state.y]}getState(){return {...this.state}}reset(){this.state={x:0,y:0,vx:0,vy:0,P:1},this.lastTimestamp=0;}};var B={};$(B,{ARRIVAL_THRESHOLD_METERS:()=>Ct,BASE_CORRIDOR_METERS:()=>z,BEARING_ALIGNMENT_THRESHOLD:()=>rt,BEARING_MIN_SPEED_MPS:()=>ot,BEARING_MISMATCH_PENALTY:()=>V,BEARING_MISMATCH_THRESHOLD:()=>F,BEARING_SMOOTHING_ALPHA:()=>nt,BETA_CORRECTION:()=>mt,DETOUR_COMMIT_MS:()=>pt,DR_MAX_AGE_MS:()=>it,GPS_ACCURACY_FACTOR:()=>tt,GPS_AGE_CAP_SECONDS:()=>dt,GPS_STALE_MS:()=>ut,INERTIA_PENALTY:()=>U,INERTIA_SEGMENT_DIST:()=>W,LOOK_AHEAD_SECONDS:()=>yt,MANEUVER_TRIGGER_DIST:()=>ht,MAX_CORRIDOR_METERS:()=>Q,MAX_LOOK_AHEAD_METERS:()=>gt,MAX_SNAP_DISTANCE:()=>k,MIN_LOOK_AHEAD_METERS:()=>ft,OFF_ROUTE_CONFIRM_MS:()=>st,REJOIN_CONFIRM_MS:()=>at,REJOIN_COOLDOWN_MS:()=>ct,SNAP_WINDOW_SIZE:()=>et,SPEED_CORRIDOR_FACTOR:()=>Z,STARTUP_GRACE_MS:()=>lt});var z=25,Q=60,Z=1.2,tt=.5,k=80,F=90,V=500,U=200,W=5,et=25,nt=.3,ot=1.5,rt=55,it=5e3,st=2e3,at=1500,ct=12e3,lt=3e3,pt=4e3,ut=3e3,dt=10,ht=25,mt=.15,yt=3,ft=20,gt=100,Ct=30;var bt={useBearingPenalty:true,useInertiaPenalty:true,maxSnapDistance:80},E=class{constructor(t){this.options={...bt,...t};}snap(t,e,n,r,s,l,p,a=null,d=null){let u=e.length,o=p,c=1/0,h=1/0,w=e[p]??[0,0];for(let C=0;C<=r;C++){let m=n+C;if(m>u-2)if(s&&l>u*.7)m=m%(u-1);else break;if(m<0||m>=u-1)continue;let T=e[m],N=e[m+1],b=A(t,T,N),R=f(t[1],t[0],b[1],b[0]);if(R>this.options.maxSnapDistance*2)continue;let g=R;if(this.options.useBearingPenalty&&a!==null){let G=S(T,N);Math.abs(v(a-G))>90&&(g+=500);}this.options.useInertiaPenalty&&d!==null&&Math.abs(m-d)>=5&&(g+=200),g<c&&(c=g,h=R,o=m,w=b);}return {idx:o,dist:h,proj:w}}};var P=class{constructor(t){this.config={baseUrl:t.baseUrl.replace(/\/$/,""),profile:t.profile??"driving",maxWaypointsPerChunk:t.maxWaypointsPerChunk??100};}async getRoute(t,e){if(t.length<2)throw new Error("[OSRM] At least 2 waypoints required");let n=e?.profile??this.config.profile;return t.length<=this.config.maxWaypointsPerChunk?this.fetchRoute(t,n,e):this.fetchChunked(t,n,e)}async fetchRoute(t,e,n){let r=t.map(u=>`${u[0]},${u[1]}`).join(";"),s=n?.steps!==false?"true":"false",l=`${this.config.baseUrl}/route/v1/${e}/${r}?overview=full&geometries=geojson&steps=${s}&annotations=false`,p=await fetch(l);if(!p.ok)throw new Error(`[OSRM] HTTP ${p.status}: ${p.statusText}`);let a=await p.json();if(a.code!=="Ok"||!a.routes?.length)throw new Error(`[OSRM] No route found: ${a.code}`);let d=a.routes[0];return {geometry:d.geometry.coordinates,distance:d.distance,duration:d.duration,legs:(d.legs??[]).map(u=>({distance:u.distance,duration:u.duration,steps:(u.steps??[]).map(o=>({distance:o.distance,duration:o.duration,geometry:o.geometry?.coordinates??[],maneuver:{type:o.maneuver?.type??"unknown",modifier:o.maneuver?.modifier,location:o.maneuver?.location??[0,0],bearingBefore:o.maneuver?.bearing_before??0,bearingAfter:o.maneuver?.bearing_after??0,instruction:o.name??void 0},name:o.name}))})),raw:a}}async fetchChunked(t,e,n){let r=this.config.maxWaypointsPerChunk,s=[];for(let o=0;o<t.length;o+=r-1){let c=t.slice(o,o+r);if(c.length<2||(s.push(c),o+r>=t.length))break}let l=await Promise.all(s.map(o=>this.fetchRoute(o,e,n))),p=[],a=0,d=0,u=[];for(let o=0;o<l.length;o++){let c=l[o];p.push(...o===0?c.geometry:c.geometry.slice(1)),a+=c.distance,d+=c.duration,u.push(...c.legs);}return {geometry:p,distance:a,duration:d,legs:u,raw:l.map(o=>o.raw)}}};var _=class{constructor(t){this.config={baseUrl:t.baseUrl.replace(/\/$/,""),costing:t.costing??"auto",apiKey:t.apiKey??"",maxWaypointsPerChunk:t.maxWaypointsPerChunk??50};}async getRoute(t,e){if(t.length<2)throw new Error("[Valhalla] At least 2 waypoints required");let n=this.profileToCosting(e?.profile);return t.length<=this.config.maxWaypointsPerChunk?this.fetchRoute(t,n,e):this.fetchChunked(t,n,e)}profileToCosting(t){switch(t){case "cycling":return "bicycle";case "walking":return "pedestrian";default:return this.config.costing}}async fetchRoute(t,e,n){let r=t.map(c=>({lon:c[0],lat:c[1],type:"break"})),s=JSON.stringify({locations:r,costing:e,directions_options:{units:"kilometers"}}),l={"Content-Type":"application/json","User-Agent":"NavCoreSDK/1.0.0 (React Native; Expo; bab-bou-jeloud-demo)"};this.config.apiKey&&(l.api_key=this.config.apiKey);let p=await fetch(`${this.config.baseUrl}/route`,{method:"POST",headers:l,body:s});if(!p.ok){let c=await p.text();throw new Error(`[Valhalla] HTTP ${p.status}: ${c}`)}let a=await p.json(),d=this.decodePolyline(a.trip?.legs?.[0]?.shape??""),u=a.trip?.summary??{},o=(a.trip?.legs??[]).map(c=>({distance:(c.summary?.length??0)*1e3,duration:c.summary?.time??0,steps:(c.maneuvers??[]).map(h=>({distance:(h.length??0)*1e3,duration:h.time??0,geometry:[],maneuver:{type:h.type?.toString()??"unknown",modifier:void 0,location:t[0],bearingBefore:h.begin_heading??0,bearingAfter:h.end_heading??0,instruction:h.instruction},name:h.street_names?.[0]}))}));return {geometry:d,distance:(u.length??0)*1e3,duration:u.time??0,legs:o,raw:a}}decodePolyline(t,e=6){let n=Math.pow(10,e),r=[],s=0,l=0,p=0;for(;s<t.length;){let a=0,d=0,u;do u=t.charCodeAt(s++)-63,d|=(u&31)<<a,a+=5;while(u>=32);let o=(d&1)!==0?~(d>>1):d>>1;l+=o,a=0,d=0;do u=t.charCodeAt(s++)-63,d|=(u&31)<<a,a+=5;while(u>=32);let c=(d&1)!==0?~(d>>1):d>>1;p+=c,r.push([p/n,l/n]);}return r}async fetchChunked(t,e,n){let r=this.config.maxWaypointsPerChunk,s=[];for(let o=0;o<t.length;o+=r-1){let c=t.slice(o,o+r);if(c.length<2||(s.push(c),o+r>=t.length))break}let l=await Promise.all(s.map(o=>this.fetchRoute(o,e,n))),p=[],a=0,d=0,u=[];for(let o=0;o<l.length;o++){let c=l[o];p.push(...o===0?c.geometry:c.geometry.slice(1)),a+=c.distance,d+=c.duration,u.push(...c.legs);}return {geometry:p,distance:a,duration:d,legs:u,raw:l.map(o=>o.raw)}}};var Rt="https://api.openrouteservice.org/v2/directions";var D=class{constructor(t){this.config={apiKey:t.apiKey,profile:t.profile??"driving-car",baseUrl:t.baseUrl??Rt,maxWaypointsPerChunk:t.maxWaypointsPerChunk??50};}async getRoute(t,e){if(t.length<2)throw new Error("[ORS] At least 2 waypoints required");let n=this.profileFromOptions(e);return t.length<=this.config.maxWaypointsPerChunk?this.fetchRoute(t,n,e):this.fetchChunked(t,n,e)}profileFromOptions(t){switch(t?.profile){case "cycling":return "cycling-regular";case "walking":return "foot-walking";default:return this.config.profile}}async fetchRoute(t,e,n){let r=JSON.stringify({coordinates:t,instructions:n?.steps!==false,language:n?.language??"en"}),s=await fetch(`${this.config.baseUrl}/${e}/geojson`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:this.config.apiKey},body:r});if(!s.ok){let o=await s.text();throw new Error(`[ORS] HTTP ${s.status}: ${o}`)}let l=await s.json(),p=l.features?.[0];if(!p)throw new Error("[ORS] No route returned");let a=p.properties?.summary??{},u=(p.properties?.segments??[]).map(o=>({distance:o.distance??0,duration:o.duration??0,steps:(o.steps??[]).map(c=>({distance:c.distance??0,duration:c.duration??0,geometry:[],maneuver:{type:c.type?.toString()??"unknown",modifier:void 0,location:t[0],bearingBefore:0,bearingAfter:0,instruction:c.instruction},name:c.name}))}));return {geometry:p.geometry?.coordinates??[],distance:a.distance??0,duration:a.duration??0,legs:u,raw:l}}async fetchChunked(t,e,n){let r=this.config.maxWaypointsPerChunk,s=[];for(let o=0;o<t.length;o+=r-1){let c=t.slice(o,o+r);if(c.length<2||(s.push(c),o+r>=t.length))break}let l=await Promise.all(s.map(o=>this.fetchRoute(o,e,n))),p=[],a=0,d=0,u=[];for(let o=0;o<l.length;o++){let c=l[o];p.push(...o===0?c.geometry:c.geometry.slice(1)),a+=c.distance,d+=c.duration,u.push(...c.legs);}return {geometry:p,distance:a,duration:d,legs:u,raw:l.map(o=>o.raw)}}};var vt=0;function K(){return `wp_${Date.now()}_${++vt}`}var M=class{constructor(){this.waypoints=[];}addWaypoint(t,e){let n=K();return this.waypoints.push({id:n,coord:t,options:e}),n}insertWaypoint(t,e){let n=this.waypoints.findIndex(s=>s.id===e);if(n===-1)throw new Error(`Waypoint ${e} not found`);let r=K();return this.waypoints.splice(n+1,0,{id:r,coord:t,options:void 0}),r}removeWaypoint(t){let e=this.waypoints.findIndex(n=>n.id===t);if(e===-1)throw new Error(`Waypoint ${t} not found`);this.waypoints.splice(e,1);}moveWaypoint(t,e){let n=this.waypoints.find(r=>r.id===t);if(!n)throw new Error(`Waypoint ${t} not found`);n.coord=e;}getWaypoints(){return this.waypoints}get size(){return this.waypoints.length}chunk(t="OVERLAP_1",e=25){let n=this.waypoints.map(p=>p.coord);if(n.length<=e)return [n];let s=e-(t==="OVERLAP_2"?2:1),l=[];for(let p=0;p<n.length;p+=s){let a=n.slice(p,p+e);if(l.push(a),p+e>=n.length)break}return l}buildStraightLine(){return {geometry:this.waypoints.map(t=>t.coord),waypoints:[...this.waypoints]}}fromGPX(t){this.waypoints=[];let e=/<(?:trkpt|wpt|rtept)\s+lat="([^"]+)"\s+lon="([^"]+)"/g,n;for(;(n=e.exec(t))!==null;){let r=parseFloat(n[1]),s=parseFloat(n[2]);isFinite(r)&&isFinite(s)&&this.addWaypoint([s,r]);}}toGPX(){return `<?xml version="1.0" encoding="UTF-8"?>
2
2
  <gpx version="1.1" creator="NavCore SDK">
3
3
  ${this.waypoints.map(e=>` <wpt lat="${e.coord[1]}" lon="${e.coord[0]}">`+(e.options?.name?`
4
4
  <name>${e.options.name}</name>`:"")+`
5
5
  </wpt>`).join(`
6
6
  `)}
7
- </gpx>`}fromGeoJSON(t){if(this.waypoints=[],t.type==="FeatureCollection"&&t.features){for(let e of t.features)if(e.geometry.type==="Point"){let n=e.geometry.coordinates;this.addWaypoint(n);}else if(e.geometry.type==="LineString"){let n=e.geometry.coordinates;for(let r of n)this.addWaypoint(r);}}}toGeoJSON(){let t=this.waypoints.map((n,r)=>({type:"Feature",geometry:{type:"Point",coordinates:n.coord},properties:{id:n.id,order:r,name:n.options?.name??null,silent:n.options?.silent??false}})),e={type:"Feature",geometry:{type:"LineString",coordinates:this.waypoints.map(n=>n.coord)},properties:{type:"route"}};return {type:"FeatureCollection",features:[...t,e]}}clear(){this.waypoints=[];}};var O={GPS_SMOOTHING:"gps_smoothing",BASIC_SNAPPING:"basic_snapping",ADVANCED_SNAPPING:"advanced_snapping",DEAD_RECKONING:"dead_reckoning",ROUTE_OFFSET:"route_offset",PROGRESS_TRACKING:"progress_tracking",ADVANCED_BEARING:"advanced_bearing",COMPOUND_DEVIATION:"compound_deviation",PARALLEL_ROAD_RESOLUTION:"parallel_road_resolution",U_TURN_PROTECTION:"u_turn_protection",VOICE_TRIGGERS:"voice_triggers",ETA:"eta",GEOFENCING:"geofencing",NAV_AI:"nav_ai"};var g=class g{constructor(t,e){this.status="MISSING";this.payload=null;this.enabledFeatures=new Set;this.warnedFeatures=new Set;this.isDev=false;this.isDev=e??false,t&&this.validate(t);}async validate(t){try{if(this.status==="VALID"&&this.payload?.bid==="dev.bypass")return "VALID";let[e,n]=t.split(".");if(!e||!n)return this.status="INVALID",this.status;let r=atob(e);if(this.payload=JSON.parse(r),!this.payload||this.payload.exp<Date.now())return this.status="EXPIRED",this.status;if(!await this.verifySignature(e,n))return this.status="INVALID",this.status;this.status="VALID",this.extractFeatures(),console.log(`\u{1F511} [NavCore] License validation complete. Plan: ${this.isProEnabled()?"pro":"core"}`);}catch{this.status="INVALID";}return this.status}extractFeatures(){if(this.enabledFeatures.clear(),!!this.payload){if(Array.isArray(this.payload.f))for(let t of this.payload.f)this.enabledFeatures.add(t);this.payload.t==="pro"&&this.enabledFeatures.add("*");}}hasFeature(t){return this.isDev?true:this.status!=="VALID"?false:this.enabledFeatures.has("*")?true:this.enabledFeatures.has(t)}warnOnce(t){this.warnedFeatures.has(t)||(console.warn(`[NavCore] Feature '${t}' requires a Pro license \u2192 upgrade at https://navcore.dev/pricing`),this.warnedFeatures.add(t));}isProEnabled(){return this.hasFeature("*")}isAIEnabled(){return this.hasFeature(O.NAV_AI)}getStatus(){return this.status}getPayload(){return this.payload}getEnabledFeatures(){return Array.from(this.enabledFeatures)}async verifySignature(t,e){try{if(typeof crypto>"u"||!crypto.subtle)return !1;let r=new TextEncoder().encode(t),s=Uint8Array.from(atob(e),a=>a.charCodeAt(0)),l=Uint8Array.from(atob(g.PUBLIC_KEY_SPKI),a=>a.charCodeAt(0)),p=await crypto.subtle.importKey("spki",l,{name:"ECDSA",namedCurve:"P-256"},!0,["verify"]);return await crypto.subtle.verify({name:"ECDSA",hash:{name:"SHA-256"}},p,s,r)}catch{return false}}};g.PUBLIC_KEY_SPKI="MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEk6onJmJkWtRFusiSS69dcdONX4xL2Snm4AZO+dYjSynfJiL4x7trEy80MImLftknBWT/qI0z7ox4Q7VNL3te6A==";var I=g;
8
- exports.Constants=W;exports.CustomRouteBuilder=v;exports.FEATURES=O;exports.KalmanFilter2D=S;exports.LicenseManager=I;exports.OSRMDirectionsProvider=D;exports.OpenRouteServiceProvider=M;exports.RouteSnapper=E;exports.ValhallaDirectionsProvider=_;exports.buildForwardCumulativeDistances=z;exports.buildReverseCumulativeDistances=Y;exports.destinationPoint=X;exports.geoGetBearing=j;exports.getBearingBetweenPoints=x;exports.haversineDistance=f;exports.interpolatePoint=q;exports.kalmanUpdate2D=L;exports.normalizeAngle=P;exports.projectPointOnSegment=A;
7
+ </gpx>`}fromGeoJSON(t){if(this.waypoints=[],t.type==="FeatureCollection"&&t.features){for(let e of t.features)if(e.geometry.type==="Point"){let n=e.geometry.coordinates;this.addWaypoint(n);}else if(e.geometry.type==="LineString"){let n=e.geometry.coordinates;for(let r of n)this.addWaypoint(r);}}}toGeoJSON(){let t=this.waypoints.map((n,r)=>({type:"Feature",geometry:{type:"Point",coordinates:n.coord},properties:{id:n.id,order:r,name:n.options?.name??null,silent:n.options?.silent??false}})),e={type:"Feature",geometry:{type:"LineString",coordinates:this.waypoints.map(n=>n.coord)},properties:{type:"route"}};return {type:"FeatureCollection",features:[...t,e]}}clear(){this.waypoints=[];}};var O={GPS_SMOOTHING:"gps_smoothing",BASIC_SNAPPING:"basic_snapping",PROGRESS_TRACKING:"progress_tracking",ROUTE_OFFSET:"route_offset",DEAD_RECKONING:"dead_reckoning",ADVANCED_BEARING:"advanced_bearing",COMPOUND_DEVIATION:"compound_deviation",PARALLEL_ROAD_RESOLUTION:"parallel_road_resolution",U_TURN_PROTECTION:"u_turn_protection",VOICE_TRIGGERS:"voice_triggers",ETA:"eta",GEOFENCING:"geofencing",NAV_AI:"nav_ai"};var y=class y{constructor(t){this.status="MISSING";this.payload=null;this.enabledFeatures=new Set;this.warnedFeatures=new Set;t&&(this.tryValidateSync(t)||this.validate(t)),this.promoteToActive();}static getActive(){return y.activeManager}static clearActive(){y.activeManager=null;}promoteToActive(){let t=y.activeManager;(t===null||t.status!=="VALID"||this.status==="VALID")&&(y.activeManager=this);}tryValidateSync(t){return t==="eyJ0IjoicHJvIiwiZXhwIjo0OTMyNzAzMTU2MDAwLCJiaWQiOiJkZXYuYnlwYXNzIiwiZiI6WyIqIl19.MEQCIH4E4QNu9PuVsXHSnYmcqpCLk4QitiIH9hhY0Zm+YO5gAiAE7X3c47YQLUj7WPSGKw9Y7W2kBUR5GCnOMBwdBsYGgg=="?typeof __DEV__<"u"&&__DEV__||typeof window<"u"&&(window.location?.hostname==="localhost"||window.location?.hostname==="127.0.0.1"||window.location?.hostname?.startsWith("192.168.")||window.location?.hostname?.endsWith(".local"))||typeof process<"u"&&(process.env?.NODE_ENV==="development"||process.env?.NODE_ENV==="test"||process.env?.VITEST==="true"||process.env?.JEST_WORKER_ID!==void 0)?(this.status="VALID",this.payload={t:"pro",exp:4932703156e3,bid:"dev.bypass",f:["*"]},this.extractFeatures(),console.log("\u{1F511} [NavCore] Development bypass key validated synchronously. Plan: pro"),true):(console.warn("[NavCore] Development bypass key is restricted to local development environments."),this.status="INVALID",this.payload=null,true):false}async validate(t){if(this.tryValidateSync(t))return this.status;try{let[e,n]=t.split(".");if(!e||!n)return this.status="INVALID",this.status;let r=atob(e);if(this.payload=JSON.parse(r),!this.payload||this.payload.exp<Date.now())return this.status="EXPIRED",this.status;if(!await this.verifySignature(e,n))return this.status="INVALID",this.status;if(this.payload?.bid==="dev.bypass"&&!(typeof __DEV__<"u"&&__DEV__||typeof window<"u"&&(window.location?.hostname==="localhost"||window.location?.hostname==="127.0.0.1"||window.location?.hostname?.startsWith("192.168.")||window.location?.hostname?.endsWith(".local"))||typeof process<"u"&&(process.env?.NODE_ENV==="development"||process.env?.NODE_ENV==="test"||process.env?.VITEST==="true"||process.env?.JEST_WORKER_ID!==void 0)))return console.warn("[NavCore] Development bypass key is restricted to local development environments."),this.status="INVALID",this.payload=null,this.status;this.status="VALID",this.extractFeatures(),this.promoteToActive(),console.log(`\u{1F511} [NavCore] License validation complete. Plan: ${this.isProEnabled()?"pro":"core"}`);}catch{this.status="INVALID";}return this.status}extractFeatures(){if(this.enabledFeatures.clear(),!!this.payload){if(Array.isArray(this.payload.f))for(let t of this.payload.f)this.enabledFeatures.add(t);this.payload.t==="pro"&&this.enabledFeatures.add("*");}}hasFeature(t){return this.status!=="VALID"?false:this.enabledFeatures.has("*")?true:this.enabledFeatures.has(t)}warnOnce(t){this.warnedFeatures.has(t)||(console.warn(`[NavCore] Feature '${t}' requires a Pro license`),this.warnedFeatures.add(t));}isProEnabled(){return this.hasFeature("*")}isAIEnabled(){return this.hasFeature(O.NAV_AI)}getStatus(){return this.status}getPayload(){return this.payload}getEnabledFeatures(){return Array.from(this.enabledFeatures)}async verifySignature(t,e){try{if(typeof crypto>"u"||!crypto.subtle)return !1;let r=new TextEncoder().encode(t),s=Uint8Array.from(atob(e),a=>a.charCodeAt(0)),l=Uint8Array.from(atob(y.PUBLIC_KEY_SPKI),a=>a.charCodeAt(0)),p=await crypto.subtle.importKey("spki",l,{name:"ECDSA",namedCurve:"P-256"},!0,["verify"]);return await crypto.subtle.verify({name:"ECDSA",hash:{name:"SHA-256"}},p,s,r)}catch{return false}}};y.activeManager=null,y.PUBLIC_KEY_SPKI="MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEk6onJmJkWtRFusiSS69dcdONX4xL2Snm4AZO+dYjSynfJiL4x7trEy80MImLftknBWT/qI0z7ox4Q7VNL3te6A==";var I=y;exports.Constants=B;exports.CustomRouteBuilder=M;exports.FEATURES=O;exports.KalmanFilter2D=x;exports.LicenseManager=I;exports.OSRMDirectionsProvider=P;exports.OpenRouteServiceProvider=D;exports.RouteSnapper=E;exports.ValhallaDirectionsProvider=_;exports.buildForwardCumulativeDistances=J;exports.buildReverseCumulativeDistances=q;exports.destinationPoint=X;exports.geoGetBearing=j;exports.getBearingBetweenPoints=S;exports.haversineDistance=f;exports.interpolatePoint=Y;exports.kalmanUpdate2D=L;exports.normalizeAngle=v;exports.projectPointOnSegment=A;
package/dist/core.mjs CHANGED
@@ -1,8 +1,7 @@
1
- var H=Object.defineProperty;var $=(i,t)=>{for(var e in t)H(i,e,{get:t[e],enumerable:true});};function f(i,t,e,n){let r=(e-i)*(Math.PI/180),s=(n-t)*(Math.PI/180),l=Math.sin(r/2)*Math.sin(r/2)+Math.cos(i*(Math.PI/180))*Math.cos(e*(Math.PI/180))*Math.sin(s/2)*Math.sin(s/2);return 6371e3*(2*Math.atan2(Math.sqrt(l),Math.sqrt(1-l)))}function X(i,t,e,n){let r=n/6371e3,s=e*(Math.PI/180),l=i*(Math.PI/180),p=t*(Math.PI/180),a=Math.asin(Math.sin(l)*Math.cos(r)+Math.cos(l)*Math.sin(r)*Math.cos(s));return [((p+Math.atan2(Math.sin(s)*Math.sin(r)*Math.cos(l),Math.cos(r)-Math.sin(l)*Math.sin(a)))*180/Math.PI+540)%360-180,a*180/Math.PI]}function j(i,t){let e=i[1]*(Math.PI/180),n=i[0]*(Math.PI/180),r=t[1]*(Math.PI/180),s=t[0]*(Math.PI/180),l=Math.sin(s-n)*Math.cos(r),p=Math.cos(e)*Math.sin(r)-Math.sin(e)*Math.cos(r)*Math.cos(s-n),a=Math.atan2(l,p)*(180/Math.PI);return a=(a+360)%360,a}function P(i){let t=i%360;return t>180?t-360:t<-180?t+360:t}function x(i,t){let e=i[1]*(Math.PI/180),n=i[0]*(Math.PI/180),r=t[1]*(Math.PI/180),s=t[0]*(Math.PI/180),l=Math.sin(s-n)*Math.cos(r),p=Math.cos(e)*Math.sin(r)-Math.sin(e)*Math.cos(r)*Math.cos(s-n);return (Math.atan2(l,p)*180/Math.PI+360)%360}function q(i,t,e){let n=(r,s,l)=>r+(s-r)*l;return [n(i[0],t[0],e),n(i[1],t[1],e)]}function A(i,t,e){let[n,r]=i,[s,l]=t,[p,a]=e,d=p-s,u=a-l,o=d*d+u*u;if(o===0)return t;let c=((n-s)*d+(r-l)*u)/o;return c=Math.max(0,Math.min(1,c)),[s+c*d,l+c*u]}function z(i){let t=new Float64Array(i.length);for(let e=1;e<i.length;e++)t[e]=t[e-1]+f(i[e-1][1],i[e-1][0],i[e][1],i[e][0]);return t}function Y(i){let t=new Float64Array(i.length);for(let e=i.length-2;e>=0;e--)t[e]=t[e+1]+f(i[e][1],i[e][0],i[e+1][1],i[e+1][0]);return t}function L(i,t,e,n,r,s=1e-5,l=5e-5){i.x+=i.vx*r,i.y+=i.vy*r,i.P+=s;let p=l*Math.max(1,n/5),a=i.P/(i.P+p),d=t-i.x,u=e-i.y;return i.x+=a*d,i.y+=a*u,r>0&&(i.vx=d/r*a,i.vy=u/r*a),i.P=(1-a)*i.P,i}var S=class{constructor(t=1e-5,e=5e-5){this.lastTimestamp=0;this.Q=t,this.rBase=e,this.state={x:0,y:0,vx:0,vy:0,P:1};}init(t,e,n){this.state={x:t,y:e,vx:0,vy:0,P:1},this.lastTimestamp=n;}update(t,e,n,r){if(this.lastTimestamp===0)return this.init(t,e,r),[t,e];let s=Math.max(.001,(r-this.lastTimestamp)/1e3);return this.lastTimestamp=r,L(this.state,t,e,n,s,this.Q,this.rBase),[this.state.x,this.state.y]}getPosition(){return [this.state.x,this.state.y]}getState(){return {...this.state}}reset(){this.state={x:0,y:0,vx:0,vy:0,P:1},this.lastTimestamp=0;}};var W={};$(W,{ARRIVAL_THRESHOLD_METERS:()=>Ct,BASE_CORRIDOR_METERS:()=>J,BEARING_ALIGNMENT_THRESHOLD:()=>rt,BEARING_MIN_SPEED_MPS:()=>ot,BEARING_MISMATCH_PENALTY:()=>U,BEARING_MISMATCH_THRESHOLD:()=>k,BEARING_SMOOTHING_ALPHA:()=>nt,BETA_CORRECTION:()=>mt,DETOUR_COMMIT_MS:()=>lt,DR_MAX_AGE_MS:()=>it,GPS_ACCURACY_FACTOR:()=>tt,GPS_AGE_CAP_SECONDS:()=>dt,GPS_STALE_MS:()=>ut,INERTIA_PENALTY:()=>B,INERTIA_SEGMENT_DIST:()=>K,LOOK_AHEAD_SECONDS:()=>ft,MANEUVER_TRIGGER_DIST:()=>ht,MAX_CORRIDOR_METERS:()=>Q,MAX_LOOK_AHEAD_METERS:()=>gt,MAX_SNAP_DISTANCE:()=>F,MIN_LOOK_AHEAD_METERS:()=>yt,OFF_ROUTE_CONFIRM_MS:()=>st,REJOIN_CONFIRM_MS:()=>at,REJOIN_COOLDOWN_MS:()=>ct,SNAP_WINDOW_SIZE:()=>et,SPEED_CORRIDOR_FACTOR:()=>Z,STARTUP_GRACE_MS:()=>pt});var J=25,Q=60,Z=1.2,tt=.5,F=80,k=90,U=500,B=200,K=5,et=25,nt=.3,ot=1.5,rt=55,it=5e3,st=2e3,at=1500,ct=12e3,pt=3e3,lt=4e3,ut=3e3,dt=10,ht=25,mt=.15,ft=3,yt=20,gt=100,Ct=30;var Rt={useBearingPenalty:true,useInertiaPenalty:true,maxSnapDistance:80},E=class{constructor(t){this.options={...Rt,...t};}snap(t,e,n,r,s,l,p,a=null,d=null){let u=e.length,o=p,c=1/0,h=1/0,T=e[p]??[0,0];for(let C=0;C<=r;C++){let m=n+C;if(m>u-2)if(s&&l>u*.7)m=m%(u-1);else break;if(m<0||m>=u-1)continue;let w=e[m],N=e[m+1],R=A(t,w,N),b=f(t[1],t[0],R[1],R[0]);if(b>this.options.maxSnapDistance*2)continue;let y=b;if(this.options.useBearingPenalty&&a!==null){let G=x(w,N);Math.abs(P(a-G))>90&&(y+=500);}this.options.useInertiaPenalty&&d!==null&&Math.abs(m-d)>=5&&(y+=200),y<c&&(c=y,h=b,o=m,T=R);}return {idx:o,dist:h,proj:T}}};var D=class{constructor(t){this.config={baseUrl:t.baseUrl.replace(/\/$/,""),profile:t.profile??"driving",maxWaypointsPerChunk:t.maxWaypointsPerChunk??100};}async getRoute(t,e){if(t.length<2)throw new Error("[OSRM] At least 2 waypoints required");let n=e?.profile??this.config.profile;return t.length<=this.config.maxWaypointsPerChunk?this.fetchRoute(t,n,e):this.fetchChunked(t,n,e)}async fetchRoute(t,e,n){let r=t.map(u=>`${u[0]},${u[1]}`).join(";"),s=n?.steps!==false?"true":"false",l=`${this.config.baseUrl}/route/v1/${e}/${r}?overview=full&geometries=geojson&steps=${s}&annotations=false`,p=await fetch(l);if(!p.ok)throw new Error(`[OSRM] HTTP ${p.status}: ${p.statusText}`);let a=await p.json();if(a.code!=="Ok"||!a.routes?.length)throw new Error(`[OSRM] No route found: ${a.code}`);let d=a.routes[0];return {geometry:d.geometry.coordinates,distance:d.distance,duration:d.duration,legs:(d.legs??[]).map(u=>({distance:u.distance,duration:u.duration,steps:(u.steps??[]).map(o=>({distance:o.distance,duration:o.duration,geometry:o.geometry?.coordinates??[],maneuver:{type:o.maneuver?.type??"unknown",modifier:o.maneuver?.modifier,location:o.maneuver?.location??[0,0],bearingBefore:o.maneuver?.bearing_before??0,bearingAfter:o.maneuver?.bearing_after??0,instruction:o.name??void 0},name:o.name}))})),raw:a}}async fetchChunked(t,e,n){let r=this.config.maxWaypointsPerChunk,s=[];for(let o=0;o<t.length;o+=r-1){let c=t.slice(o,o+r);if(c.length<2||(s.push(c),o+r>=t.length))break}let l=await Promise.all(s.map(o=>this.fetchRoute(o,e,n))),p=[],a=0,d=0,u=[];for(let o=0;o<l.length;o++){let c=l[o];p.push(...o===0?c.geometry:c.geometry.slice(1)),a+=c.distance,d+=c.duration,u.push(...c.legs);}return {geometry:p,distance:a,duration:d,legs:u,raw:l.map(o=>o.raw)}}};var _=class{constructor(t){this.config={baseUrl:t.baseUrl.replace(/\/$/,""),costing:t.costing??"auto",apiKey:t.apiKey??"",maxWaypointsPerChunk:t.maxWaypointsPerChunk??50};}async getRoute(t,e){if(t.length<2)throw new Error("[Valhalla] At least 2 waypoints required");let n=this.profileToCosting(e?.profile);return t.length<=this.config.maxWaypointsPerChunk?this.fetchRoute(t,n,e):this.fetchChunked(t,n,e)}profileToCosting(t){switch(t){case "cycling":return "bicycle";case "walking":return "pedestrian";default:return this.config.costing}}async fetchRoute(t,e,n){let r=t.map(c=>({lon:c[0],lat:c[1],type:"break"})),s=JSON.stringify({locations:r,costing:e,directions_options:{units:"kilometers"}}),l={"Content-Type":"application/json"};this.config.apiKey&&(l.api_key=this.config.apiKey);let p=await fetch(`${this.config.baseUrl}/route`,{method:"POST",headers:l,body:s});if(!p.ok){let c=await p.text();throw new Error(`[Valhalla] HTTP ${p.status}: ${c}`)}let a=await p.json(),d=this.decodePolyline(a.trip?.legs?.[0]?.shape??""),u=a.trip?.summary??{},o=(a.trip?.legs??[]).map(c=>({distance:(c.summary?.length??0)*1e3,duration:c.summary?.time??0,steps:(c.maneuvers??[]).map(h=>({distance:(h.length??0)*1e3,duration:h.time??0,geometry:[],maneuver:{type:h.type?.toString()??"unknown",modifier:void 0,location:t[0],bearingBefore:h.begin_heading??0,bearingAfter:h.end_heading??0,instruction:h.instruction},name:h.street_names?.[0]}))}));return {geometry:d,distance:(u.length??0)*1e3,duration:u.time??0,legs:o,raw:a}}decodePolyline(t,e=6){let n=Math.pow(10,e),r=[],s=0,l=0,p=0;for(;s<t.length;){let a=0,d=0,u;do u=t.charCodeAt(s++)-63,d|=(u&31)<<a,a+=5;while(u>=32);let o=(d&1)!==0?~(d>>1):d>>1;l+=o,a=0,d=0;do u=t.charCodeAt(s++)-63,d|=(u&31)<<a,a+=5;while(u>=32);let c=(d&1)!==0?~(d>>1):d>>1;p+=c,r.push([p/n,l/n]);}return r}async fetchChunked(t,e,n){let r=this.config.maxWaypointsPerChunk,s=[];for(let o=0;o<t.length;o+=r-1){let c=t.slice(o,o+r);if(c.length<2||(s.push(c),o+r>=t.length))break}let l=await Promise.all(s.map(o=>this.fetchRoute(o,e,n))),p=[],a=0,d=0,u=[];for(let o=0;o<l.length;o++){let c=l[o];p.push(...o===0?c.geometry:c.geometry.slice(1)),a+=c.distance,d+=c.duration,u.push(...c.legs);}return {geometry:p,distance:a,duration:d,legs:u,raw:l.map(o=>o.raw)}}};var bt="https://api.openrouteservice.org/v2/directions";var M=class{constructor(t){this.config={apiKey:t.apiKey,profile:t.profile??"driving-car",baseUrl:t.baseUrl??bt,maxWaypointsPerChunk:t.maxWaypointsPerChunk??50};}async getRoute(t,e){if(t.length<2)throw new Error("[ORS] At least 2 waypoints required");let n=this.profileFromOptions(e);return t.length<=this.config.maxWaypointsPerChunk?this.fetchRoute(t,n,e):this.fetchChunked(t,n,e)}profileFromOptions(t){switch(t?.profile){case "cycling":return "cycling-regular";case "walking":return "foot-walking";default:return this.config.profile}}async fetchRoute(t,e,n){let r=JSON.stringify({coordinates:t,instructions:n?.steps!==false,language:n?.language??"en"}),s=await fetch(`${this.config.baseUrl}/${e}/geojson`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:this.config.apiKey},body:r});if(!s.ok){let o=await s.text();throw new Error(`[ORS] HTTP ${s.status}: ${o}`)}let l=await s.json(),p=l.features?.[0];if(!p)throw new Error("[ORS] No route returned");let a=p.properties?.summary??{},u=(p.properties?.segments??[]).map(o=>({distance:o.distance??0,duration:o.duration??0,steps:(o.steps??[]).map(c=>({distance:c.distance??0,duration:c.duration??0,geometry:[],maneuver:{type:c.type?.toString()??"unknown",modifier:void 0,location:t[0],bearingBefore:0,bearingAfter:0,instruction:c.instruction},name:c.name}))}));return {geometry:p.geometry?.coordinates??[],distance:a.distance??0,duration:a.duration??0,legs:u,raw:l}}async fetchChunked(t,e,n){let r=this.config.maxWaypointsPerChunk,s=[];for(let o=0;o<t.length;o+=r-1){let c=t.slice(o,o+r);if(c.length<2||(s.push(c),o+r>=t.length))break}let l=await Promise.all(s.map(o=>this.fetchRoute(o,e,n))),p=[],a=0,d=0,u=[];for(let o=0;o<l.length;o++){let c=l[o];p.push(...o===0?c.geometry:c.geometry.slice(1)),a+=c.distance,d+=c.duration,u.push(...c.legs);}return {geometry:p,distance:a,duration:d,legs:u,raw:l.map(o=>o.raw)}}};var Pt=0;function V(){return `wp_${Date.now()}_${++Pt}`}var v=class{constructor(){this.waypoints=[];}addWaypoint(t,e){let n=V();return this.waypoints.push({id:n,coord:t,options:e}),n}insertWaypoint(t,e){let n=this.waypoints.findIndex(s=>s.id===e);if(n===-1)throw new Error(`Waypoint ${e} not found`);let r=V();return this.waypoints.splice(n+1,0,{id:r,coord:t,options:void 0}),r}removeWaypoint(t){let e=this.waypoints.findIndex(n=>n.id===t);if(e===-1)throw new Error(`Waypoint ${t} not found`);this.waypoints.splice(e,1);}moveWaypoint(t,e){let n=this.waypoints.find(r=>r.id===t);if(!n)throw new Error(`Waypoint ${t} not found`);n.coord=e;}getWaypoints(){return this.waypoints}get size(){return this.waypoints.length}chunk(t="OVERLAP_1",e=25){let n=this.waypoints.map(p=>p.coord);if(n.length<=e)return [n];let s=e-(t==="OVERLAP_2"?2:1),l=[];for(let p=0;p<n.length;p+=s){let a=n.slice(p,p+e);if(l.push(a),p+e>=n.length)break}return l}buildStraightLine(){return {geometry:this.waypoints.map(t=>t.coord),waypoints:[...this.waypoints]}}fromGPX(t){this.waypoints=[];let e=/<(?:trkpt|wpt|rtept)\s+lat="([^"]+)"\s+lon="([^"]+)"/g,n;for(;(n=e.exec(t))!==null;){let r=parseFloat(n[1]),s=parseFloat(n[2]);isFinite(r)&&isFinite(s)&&this.addWaypoint([s,r]);}}toGPX(){return `<?xml version="1.0" encoding="UTF-8"?>
1
+ var H=Object.defineProperty;var $=(i,t)=>{for(var e in t)H(i,e,{get:t[e],enumerable:true});};function f(i,t,e,n){let r=(e-i)*(Math.PI/180),s=(n-t)*(Math.PI/180),l=Math.sin(r/2)*Math.sin(r/2)+Math.cos(i*(Math.PI/180))*Math.cos(e*(Math.PI/180))*Math.sin(s/2)*Math.sin(s/2);return 6371e3*(2*Math.atan2(Math.sqrt(l),Math.sqrt(1-l)))}function X(i,t,e,n){let r=n/6371e3,s=e*(Math.PI/180),l=i*(Math.PI/180),p=t*(Math.PI/180),a=Math.asin(Math.sin(l)*Math.cos(r)+Math.cos(l)*Math.sin(r)*Math.cos(s));return [((p+Math.atan2(Math.sin(s)*Math.sin(r)*Math.cos(l),Math.cos(r)-Math.sin(l)*Math.sin(a)))*180/Math.PI+540)%360-180,a*180/Math.PI]}function j(i,t){let e=i[1]*(Math.PI/180),n=i[0]*(Math.PI/180),r=t[1]*(Math.PI/180),s=t[0]*(Math.PI/180),l=Math.sin(s-n)*Math.cos(r),p=Math.cos(e)*Math.sin(r)-Math.sin(e)*Math.cos(r)*Math.cos(s-n),a=Math.atan2(l,p)*(180/Math.PI);return a=(a+360)%360,a}function v(i){let t=i%360;return t>180?t-360:t<-180?t+360:t}function S(i,t){let e=i[1]*(Math.PI/180),n=i[0]*(Math.PI/180),r=t[1]*(Math.PI/180),s=t[0]*(Math.PI/180),l=Math.sin(s-n)*Math.cos(r),p=Math.cos(e)*Math.sin(r)-Math.sin(e)*Math.cos(r)*Math.cos(s-n);return (Math.atan2(l,p)*180/Math.PI+360)%360}function Y(i,t,e){let n=(r,s,l)=>r+(s-r)*l;return [n(i[0],t[0],e),n(i[1],t[1],e)]}function A(i,t,e){let[n,r]=i,[s,l]=t,[p,a]=e,d=p-s,u=a-l,o=d*d+u*u;if(o===0)return t;let c=((n-s)*d+(r-l)*u)/o;return c=Math.max(0,Math.min(1,c)),[s+c*d,l+c*u]}function J(i){let t=new Float64Array(i.length);for(let e=1;e<i.length;e++)t[e]=t[e-1]+f(i[e-1][1],i[e-1][0],i[e][1],i[e][0]);return t}function q(i){let t=new Float64Array(i.length);for(let e=i.length-2;e>=0;e--)t[e]=t[e+1]+f(i[e][1],i[e][0],i[e+1][1],i[e+1][0]);return t}function L(i,t,e,n,r,s=1e-5,l=5e-5){i.x+=i.vx*r,i.y+=i.vy*r,i.P+=s;let p=l*Math.max(1,n/5),a=i.P/(i.P+p),d=t-i.x,u=e-i.y;return i.x+=a*d,i.y+=a*u,r>0&&(i.vx=d/r*a,i.vy=u/r*a),i.P=(1-a)*i.P,i}var x=class{constructor(t=1e-5,e=5e-5){this.lastTimestamp=0;this.Q=t,this.rBase=e,this.state={x:0,y:0,vx:0,vy:0,P:1};}init(t,e,n){this.state={x:t,y:e,vx:0,vy:0,P:1},this.lastTimestamp=n;}update(t,e,n,r){if(this.lastTimestamp===0)return this.init(t,e,r),[t,e];let s=Math.max(.001,(r-this.lastTimestamp)/1e3);return this.lastTimestamp=r,L(this.state,t,e,n,s,this.Q,this.rBase),[this.state.x,this.state.y]}getPosition(){return [this.state.x,this.state.y]}getState(){return {...this.state}}reset(){this.state={x:0,y:0,vx:0,vy:0,P:1},this.lastTimestamp=0;}};var B={};$(B,{ARRIVAL_THRESHOLD_METERS:()=>Ct,BASE_CORRIDOR_METERS:()=>z,BEARING_ALIGNMENT_THRESHOLD:()=>rt,BEARING_MIN_SPEED_MPS:()=>ot,BEARING_MISMATCH_PENALTY:()=>V,BEARING_MISMATCH_THRESHOLD:()=>F,BEARING_SMOOTHING_ALPHA:()=>nt,BETA_CORRECTION:()=>mt,DETOUR_COMMIT_MS:()=>pt,DR_MAX_AGE_MS:()=>it,GPS_ACCURACY_FACTOR:()=>tt,GPS_AGE_CAP_SECONDS:()=>dt,GPS_STALE_MS:()=>ut,INERTIA_PENALTY:()=>U,INERTIA_SEGMENT_DIST:()=>W,LOOK_AHEAD_SECONDS:()=>yt,MANEUVER_TRIGGER_DIST:()=>ht,MAX_CORRIDOR_METERS:()=>Q,MAX_LOOK_AHEAD_METERS:()=>gt,MAX_SNAP_DISTANCE:()=>k,MIN_LOOK_AHEAD_METERS:()=>ft,OFF_ROUTE_CONFIRM_MS:()=>st,REJOIN_CONFIRM_MS:()=>at,REJOIN_COOLDOWN_MS:()=>ct,SNAP_WINDOW_SIZE:()=>et,SPEED_CORRIDOR_FACTOR:()=>Z,STARTUP_GRACE_MS:()=>lt});var z=25,Q=60,Z=1.2,tt=.5,k=80,F=90,V=500,U=200,W=5,et=25,nt=.3,ot=1.5,rt=55,it=5e3,st=2e3,at=1500,ct=12e3,lt=3e3,pt=4e3,ut=3e3,dt=10,ht=25,mt=.15,yt=3,ft=20,gt=100,Ct=30;var bt={useBearingPenalty:true,useInertiaPenalty:true,maxSnapDistance:80},E=class{constructor(t){this.options={...bt,...t};}snap(t,e,n,r,s,l,p,a=null,d=null){let u=e.length,o=p,c=1/0,h=1/0,w=e[p]??[0,0];for(let C=0;C<=r;C++){let m=n+C;if(m>u-2)if(s&&l>u*.7)m=m%(u-1);else break;if(m<0||m>=u-1)continue;let T=e[m],N=e[m+1],b=A(t,T,N),R=f(t[1],t[0],b[1],b[0]);if(R>this.options.maxSnapDistance*2)continue;let g=R;if(this.options.useBearingPenalty&&a!==null){let G=S(T,N);Math.abs(v(a-G))>90&&(g+=500);}this.options.useInertiaPenalty&&d!==null&&Math.abs(m-d)>=5&&(g+=200),g<c&&(c=g,h=R,o=m,w=b);}return {idx:o,dist:h,proj:w}}};var P=class{constructor(t){this.config={baseUrl:t.baseUrl.replace(/\/$/,""),profile:t.profile??"driving",maxWaypointsPerChunk:t.maxWaypointsPerChunk??100};}async getRoute(t,e){if(t.length<2)throw new Error("[OSRM] At least 2 waypoints required");let n=e?.profile??this.config.profile;return t.length<=this.config.maxWaypointsPerChunk?this.fetchRoute(t,n,e):this.fetchChunked(t,n,e)}async fetchRoute(t,e,n){let r=t.map(u=>`${u[0]},${u[1]}`).join(";"),s=n?.steps!==false?"true":"false",l=`${this.config.baseUrl}/route/v1/${e}/${r}?overview=full&geometries=geojson&steps=${s}&annotations=false`,p=await fetch(l);if(!p.ok)throw new Error(`[OSRM] HTTP ${p.status}: ${p.statusText}`);let a=await p.json();if(a.code!=="Ok"||!a.routes?.length)throw new Error(`[OSRM] No route found: ${a.code}`);let d=a.routes[0];return {geometry:d.geometry.coordinates,distance:d.distance,duration:d.duration,legs:(d.legs??[]).map(u=>({distance:u.distance,duration:u.duration,steps:(u.steps??[]).map(o=>({distance:o.distance,duration:o.duration,geometry:o.geometry?.coordinates??[],maneuver:{type:o.maneuver?.type??"unknown",modifier:o.maneuver?.modifier,location:o.maneuver?.location??[0,0],bearingBefore:o.maneuver?.bearing_before??0,bearingAfter:o.maneuver?.bearing_after??0,instruction:o.name??void 0},name:o.name}))})),raw:a}}async fetchChunked(t,e,n){let r=this.config.maxWaypointsPerChunk,s=[];for(let o=0;o<t.length;o+=r-1){let c=t.slice(o,o+r);if(c.length<2||(s.push(c),o+r>=t.length))break}let l=await Promise.all(s.map(o=>this.fetchRoute(o,e,n))),p=[],a=0,d=0,u=[];for(let o=0;o<l.length;o++){let c=l[o];p.push(...o===0?c.geometry:c.geometry.slice(1)),a+=c.distance,d+=c.duration,u.push(...c.legs);}return {geometry:p,distance:a,duration:d,legs:u,raw:l.map(o=>o.raw)}}};var _=class{constructor(t){this.config={baseUrl:t.baseUrl.replace(/\/$/,""),costing:t.costing??"auto",apiKey:t.apiKey??"",maxWaypointsPerChunk:t.maxWaypointsPerChunk??50};}async getRoute(t,e){if(t.length<2)throw new Error("[Valhalla] At least 2 waypoints required");let n=this.profileToCosting(e?.profile);return t.length<=this.config.maxWaypointsPerChunk?this.fetchRoute(t,n,e):this.fetchChunked(t,n,e)}profileToCosting(t){switch(t){case "cycling":return "bicycle";case "walking":return "pedestrian";default:return this.config.costing}}async fetchRoute(t,e,n){let r=t.map(c=>({lon:c[0],lat:c[1],type:"break"})),s=JSON.stringify({locations:r,costing:e,directions_options:{units:"kilometers"}}),l={"Content-Type":"application/json","User-Agent":"NavCoreSDK/1.0.0 (React Native; Expo; bab-bou-jeloud-demo)"};this.config.apiKey&&(l.api_key=this.config.apiKey);let p=await fetch(`${this.config.baseUrl}/route`,{method:"POST",headers:l,body:s});if(!p.ok){let c=await p.text();throw new Error(`[Valhalla] HTTP ${p.status}: ${c}`)}let a=await p.json(),d=this.decodePolyline(a.trip?.legs?.[0]?.shape??""),u=a.trip?.summary??{},o=(a.trip?.legs??[]).map(c=>({distance:(c.summary?.length??0)*1e3,duration:c.summary?.time??0,steps:(c.maneuvers??[]).map(h=>({distance:(h.length??0)*1e3,duration:h.time??0,geometry:[],maneuver:{type:h.type?.toString()??"unknown",modifier:void 0,location:t[0],bearingBefore:h.begin_heading??0,bearingAfter:h.end_heading??0,instruction:h.instruction},name:h.street_names?.[0]}))}));return {geometry:d,distance:(u.length??0)*1e3,duration:u.time??0,legs:o,raw:a}}decodePolyline(t,e=6){let n=Math.pow(10,e),r=[],s=0,l=0,p=0;for(;s<t.length;){let a=0,d=0,u;do u=t.charCodeAt(s++)-63,d|=(u&31)<<a,a+=5;while(u>=32);let o=(d&1)!==0?~(d>>1):d>>1;l+=o,a=0,d=0;do u=t.charCodeAt(s++)-63,d|=(u&31)<<a,a+=5;while(u>=32);let c=(d&1)!==0?~(d>>1):d>>1;p+=c,r.push([p/n,l/n]);}return r}async fetchChunked(t,e,n){let r=this.config.maxWaypointsPerChunk,s=[];for(let o=0;o<t.length;o+=r-1){let c=t.slice(o,o+r);if(c.length<2||(s.push(c),o+r>=t.length))break}let l=await Promise.all(s.map(o=>this.fetchRoute(o,e,n))),p=[],a=0,d=0,u=[];for(let o=0;o<l.length;o++){let c=l[o];p.push(...o===0?c.geometry:c.geometry.slice(1)),a+=c.distance,d+=c.duration,u.push(...c.legs);}return {geometry:p,distance:a,duration:d,legs:u,raw:l.map(o=>o.raw)}}};var Rt="https://api.openrouteservice.org/v2/directions";var D=class{constructor(t){this.config={apiKey:t.apiKey,profile:t.profile??"driving-car",baseUrl:t.baseUrl??Rt,maxWaypointsPerChunk:t.maxWaypointsPerChunk??50};}async getRoute(t,e){if(t.length<2)throw new Error("[ORS] At least 2 waypoints required");let n=this.profileFromOptions(e);return t.length<=this.config.maxWaypointsPerChunk?this.fetchRoute(t,n,e):this.fetchChunked(t,n,e)}profileFromOptions(t){switch(t?.profile){case "cycling":return "cycling-regular";case "walking":return "foot-walking";default:return this.config.profile}}async fetchRoute(t,e,n){let r=JSON.stringify({coordinates:t,instructions:n?.steps!==false,language:n?.language??"en"}),s=await fetch(`${this.config.baseUrl}/${e}/geojson`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:this.config.apiKey},body:r});if(!s.ok){let o=await s.text();throw new Error(`[ORS] HTTP ${s.status}: ${o}`)}let l=await s.json(),p=l.features?.[0];if(!p)throw new Error("[ORS] No route returned");let a=p.properties?.summary??{},u=(p.properties?.segments??[]).map(o=>({distance:o.distance??0,duration:o.duration??0,steps:(o.steps??[]).map(c=>({distance:c.distance??0,duration:c.duration??0,geometry:[],maneuver:{type:c.type?.toString()??"unknown",modifier:void 0,location:t[0],bearingBefore:0,bearingAfter:0,instruction:c.instruction},name:c.name}))}));return {geometry:p.geometry?.coordinates??[],distance:a.distance??0,duration:a.duration??0,legs:u,raw:l}}async fetchChunked(t,e,n){let r=this.config.maxWaypointsPerChunk,s=[];for(let o=0;o<t.length;o+=r-1){let c=t.slice(o,o+r);if(c.length<2||(s.push(c),o+r>=t.length))break}let l=await Promise.all(s.map(o=>this.fetchRoute(o,e,n))),p=[],a=0,d=0,u=[];for(let o=0;o<l.length;o++){let c=l[o];p.push(...o===0?c.geometry:c.geometry.slice(1)),a+=c.distance,d+=c.duration,u.push(...c.legs);}return {geometry:p,distance:a,duration:d,legs:u,raw:l.map(o=>o.raw)}}};var vt=0;function K(){return `wp_${Date.now()}_${++vt}`}var M=class{constructor(){this.waypoints=[];}addWaypoint(t,e){let n=K();return this.waypoints.push({id:n,coord:t,options:e}),n}insertWaypoint(t,e){let n=this.waypoints.findIndex(s=>s.id===e);if(n===-1)throw new Error(`Waypoint ${e} not found`);let r=K();return this.waypoints.splice(n+1,0,{id:r,coord:t,options:void 0}),r}removeWaypoint(t){let e=this.waypoints.findIndex(n=>n.id===t);if(e===-1)throw new Error(`Waypoint ${t} not found`);this.waypoints.splice(e,1);}moveWaypoint(t,e){let n=this.waypoints.find(r=>r.id===t);if(!n)throw new Error(`Waypoint ${t} not found`);n.coord=e;}getWaypoints(){return this.waypoints}get size(){return this.waypoints.length}chunk(t="OVERLAP_1",e=25){let n=this.waypoints.map(p=>p.coord);if(n.length<=e)return [n];let s=e-(t==="OVERLAP_2"?2:1),l=[];for(let p=0;p<n.length;p+=s){let a=n.slice(p,p+e);if(l.push(a),p+e>=n.length)break}return l}buildStraightLine(){return {geometry:this.waypoints.map(t=>t.coord),waypoints:[...this.waypoints]}}fromGPX(t){this.waypoints=[];let e=/<(?:trkpt|wpt|rtept)\s+lat="([^"]+)"\s+lon="([^"]+)"/g,n;for(;(n=e.exec(t))!==null;){let r=parseFloat(n[1]),s=parseFloat(n[2]);isFinite(r)&&isFinite(s)&&this.addWaypoint([s,r]);}}toGPX(){return `<?xml version="1.0" encoding="UTF-8"?>
2
2
  <gpx version="1.1" creator="NavCore SDK">
3
3
  ${this.waypoints.map(e=>` <wpt lat="${e.coord[1]}" lon="${e.coord[0]}">`+(e.options?.name?`
4
4
  <name>${e.options.name}</name>`:"")+`
5
5
  </wpt>`).join(`
6
6
  `)}
7
- </gpx>`}fromGeoJSON(t){if(this.waypoints=[],t.type==="FeatureCollection"&&t.features){for(let e of t.features)if(e.geometry.type==="Point"){let n=e.geometry.coordinates;this.addWaypoint(n);}else if(e.geometry.type==="LineString"){let n=e.geometry.coordinates;for(let r of n)this.addWaypoint(r);}}}toGeoJSON(){let t=this.waypoints.map((n,r)=>({type:"Feature",geometry:{type:"Point",coordinates:n.coord},properties:{id:n.id,order:r,name:n.options?.name??null,silent:n.options?.silent??false}})),e={type:"Feature",geometry:{type:"LineString",coordinates:this.waypoints.map(n=>n.coord)},properties:{type:"route"}};return {type:"FeatureCollection",features:[...t,e]}}clear(){this.waypoints=[];}};var O={GPS_SMOOTHING:"gps_smoothing",BASIC_SNAPPING:"basic_snapping",ADVANCED_SNAPPING:"advanced_snapping",DEAD_RECKONING:"dead_reckoning",ROUTE_OFFSET:"route_offset",PROGRESS_TRACKING:"progress_tracking",ADVANCED_BEARING:"advanced_bearing",COMPOUND_DEVIATION:"compound_deviation",PARALLEL_ROAD_RESOLUTION:"parallel_road_resolution",U_TURN_PROTECTION:"u_turn_protection",VOICE_TRIGGERS:"voice_triggers",ETA:"eta",GEOFENCING:"geofencing",NAV_AI:"nav_ai"};var g=class g{constructor(t,e){this.status="MISSING";this.payload=null;this.enabledFeatures=new Set;this.warnedFeatures=new Set;this.isDev=false;this.isDev=e??false,t&&this.validate(t);}async validate(t){try{if(this.status==="VALID"&&this.payload?.bid==="dev.bypass")return "VALID";let[e,n]=t.split(".");if(!e||!n)return this.status="INVALID",this.status;let r=atob(e);if(this.payload=JSON.parse(r),!this.payload||this.payload.exp<Date.now())return this.status="EXPIRED",this.status;if(!await this.verifySignature(e,n))return this.status="INVALID",this.status;this.status="VALID",this.extractFeatures(),console.log(`\u{1F511} [NavCore] License validation complete. Plan: ${this.isProEnabled()?"pro":"core"}`);}catch{this.status="INVALID";}return this.status}extractFeatures(){if(this.enabledFeatures.clear(),!!this.payload){if(Array.isArray(this.payload.f))for(let t of this.payload.f)this.enabledFeatures.add(t);this.payload.t==="pro"&&this.enabledFeatures.add("*");}}hasFeature(t){return this.isDev?true:this.status!=="VALID"?false:this.enabledFeatures.has("*")?true:this.enabledFeatures.has(t)}warnOnce(t){this.warnedFeatures.has(t)||(console.warn(`[NavCore] Feature '${t}' requires a Pro license \u2192 upgrade at https://navcore.dev/pricing`),this.warnedFeatures.add(t));}isProEnabled(){return this.hasFeature("*")}isAIEnabled(){return this.hasFeature(O.NAV_AI)}getStatus(){return this.status}getPayload(){return this.payload}getEnabledFeatures(){return Array.from(this.enabledFeatures)}async verifySignature(t,e){try{if(typeof crypto>"u"||!crypto.subtle)return !1;let r=new TextEncoder().encode(t),s=Uint8Array.from(atob(e),a=>a.charCodeAt(0)),l=Uint8Array.from(atob(g.PUBLIC_KEY_SPKI),a=>a.charCodeAt(0)),p=await crypto.subtle.importKey("spki",l,{name:"ECDSA",namedCurve:"P-256"},!0,["verify"]);return await crypto.subtle.verify({name:"ECDSA",hash:{name:"SHA-256"}},p,s,r)}catch{return false}}};g.PUBLIC_KEY_SPKI="MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEk6onJmJkWtRFusiSS69dcdONX4xL2Snm4AZO+dYjSynfJiL4x7trEy80MImLftknBWT/qI0z7ox4Q7VNL3te6A==";var I=g;
8
- export{W as Constants,v as CustomRouteBuilder,O as FEATURES,S as KalmanFilter2D,I as LicenseManager,D as OSRMDirectionsProvider,M as OpenRouteServiceProvider,E as RouteSnapper,_ as ValhallaDirectionsProvider,z as buildForwardCumulativeDistances,Y as buildReverseCumulativeDistances,X as destinationPoint,j as geoGetBearing,x as getBearingBetweenPoints,f as haversineDistance,q as interpolatePoint,L as kalmanUpdate2D,P as normalizeAngle,A as projectPointOnSegment};
7
+ </gpx>`}fromGeoJSON(t){if(this.waypoints=[],t.type==="FeatureCollection"&&t.features){for(let e of t.features)if(e.geometry.type==="Point"){let n=e.geometry.coordinates;this.addWaypoint(n);}else if(e.geometry.type==="LineString"){let n=e.geometry.coordinates;for(let r of n)this.addWaypoint(r);}}}toGeoJSON(){let t=this.waypoints.map((n,r)=>({type:"Feature",geometry:{type:"Point",coordinates:n.coord},properties:{id:n.id,order:r,name:n.options?.name??null,silent:n.options?.silent??false}})),e={type:"Feature",geometry:{type:"LineString",coordinates:this.waypoints.map(n=>n.coord)},properties:{type:"route"}};return {type:"FeatureCollection",features:[...t,e]}}clear(){this.waypoints=[];}};var O={GPS_SMOOTHING:"gps_smoothing",BASIC_SNAPPING:"basic_snapping",PROGRESS_TRACKING:"progress_tracking",ROUTE_OFFSET:"route_offset",DEAD_RECKONING:"dead_reckoning",ADVANCED_BEARING:"advanced_bearing",COMPOUND_DEVIATION:"compound_deviation",PARALLEL_ROAD_RESOLUTION:"parallel_road_resolution",U_TURN_PROTECTION:"u_turn_protection",VOICE_TRIGGERS:"voice_triggers",ETA:"eta",GEOFENCING:"geofencing",NAV_AI:"nav_ai"};var y=class y{constructor(t){this.status="MISSING";this.payload=null;this.enabledFeatures=new Set;this.warnedFeatures=new Set;t&&(this.tryValidateSync(t)||this.validate(t)),this.promoteToActive();}static getActive(){return y.activeManager}static clearActive(){y.activeManager=null;}promoteToActive(){let t=y.activeManager;(t===null||t.status!=="VALID"||this.status==="VALID")&&(y.activeManager=this);}tryValidateSync(t){return t==="eyJ0IjoicHJvIiwiZXhwIjo0OTMyNzAzMTU2MDAwLCJiaWQiOiJkZXYuYnlwYXNzIiwiZiI6WyIqIl19.MEQCIH4E4QNu9PuVsXHSnYmcqpCLk4QitiIH9hhY0Zm+YO5gAiAE7X3c47YQLUj7WPSGKw9Y7W2kBUR5GCnOMBwdBsYGgg=="?typeof __DEV__<"u"&&__DEV__||typeof window<"u"&&(window.location?.hostname==="localhost"||window.location?.hostname==="127.0.0.1"||window.location?.hostname?.startsWith("192.168.")||window.location?.hostname?.endsWith(".local"))||typeof process<"u"&&(process.env?.NODE_ENV==="development"||process.env?.NODE_ENV==="test"||process.env?.VITEST==="true"||process.env?.JEST_WORKER_ID!==void 0)?(this.status="VALID",this.payload={t:"pro",exp:4932703156e3,bid:"dev.bypass",f:["*"]},this.extractFeatures(),console.log("\u{1F511} [NavCore] Development bypass key validated synchronously. Plan: pro"),true):(console.warn("[NavCore] Development bypass key is restricted to local development environments."),this.status="INVALID",this.payload=null,true):false}async validate(t){if(this.tryValidateSync(t))return this.status;try{let[e,n]=t.split(".");if(!e||!n)return this.status="INVALID",this.status;let r=atob(e);if(this.payload=JSON.parse(r),!this.payload||this.payload.exp<Date.now())return this.status="EXPIRED",this.status;if(!await this.verifySignature(e,n))return this.status="INVALID",this.status;if(this.payload?.bid==="dev.bypass"&&!(typeof __DEV__<"u"&&__DEV__||typeof window<"u"&&(window.location?.hostname==="localhost"||window.location?.hostname==="127.0.0.1"||window.location?.hostname?.startsWith("192.168.")||window.location?.hostname?.endsWith(".local"))||typeof process<"u"&&(process.env?.NODE_ENV==="development"||process.env?.NODE_ENV==="test"||process.env?.VITEST==="true"||process.env?.JEST_WORKER_ID!==void 0)))return console.warn("[NavCore] Development bypass key is restricted to local development environments."),this.status="INVALID",this.payload=null,this.status;this.status="VALID",this.extractFeatures(),this.promoteToActive(),console.log(`\u{1F511} [NavCore] License validation complete. Plan: ${this.isProEnabled()?"pro":"core"}`);}catch{this.status="INVALID";}return this.status}extractFeatures(){if(this.enabledFeatures.clear(),!!this.payload){if(Array.isArray(this.payload.f))for(let t of this.payload.f)this.enabledFeatures.add(t);this.payload.t==="pro"&&this.enabledFeatures.add("*");}}hasFeature(t){return this.status!=="VALID"?false:this.enabledFeatures.has("*")?true:this.enabledFeatures.has(t)}warnOnce(t){this.warnedFeatures.has(t)||(console.warn(`[NavCore] Feature '${t}' requires a Pro license`),this.warnedFeatures.add(t));}isProEnabled(){return this.hasFeature("*")}isAIEnabled(){return this.hasFeature(O.NAV_AI)}getStatus(){return this.status}getPayload(){return this.payload}getEnabledFeatures(){return Array.from(this.enabledFeatures)}async verifySignature(t,e){try{if(typeof crypto>"u"||!crypto.subtle)return !1;let r=new TextEncoder().encode(t),s=Uint8Array.from(atob(e),a=>a.charCodeAt(0)),l=Uint8Array.from(atob(y.PUBLIC_KEY_SPKI),a=>a.charCodeAt(0)),p=await crypto.subtle.importKey("spki",l,{name:"ECDSA",namedCurve:"P-256"},!0,["verify"]);return await crypto.subtle.verify({name:"ECDSA",hash:{name:"SHA-256"}},p,s,r)}catch{return false}}};y.activeManager=null,y.PUBLIC_KEY_SPKI="MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEk6onJmJkWtRFusiSS69dcdONX4xL2Snm4AZO+dYjSynfJiL4x7trEy80MImLftknBWT/qI0z7ox4Q7VNL3te6A==";var I=y;export{B as Constants,M as CustomRouteBuilder,O as FEATURES,x as KalmanFilter2D,I as LicenseManager,P as OSRMDirectionsProvider,D as OpenRouteServiceProvider,E as RouteSnapper,_ as ValhallaDirectionsProvider,J as buildForwardCumulativeDistances,q as buildReverseCumulativeDistances,X as destinationPoint,j as geoGetBearing,S as getBearingBetweenPoints,f as haversineDistance,Y as interpolatePoint,L as kalmanUpdate2D,v as normalizeAngle,A as projectPointOnSegment};