@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.
package/dist/pro.d.mts CHANGED
@@ -1,5 +1,4 @@
1
- import { C as Coordinate, i as NavInstruction, g as NavCoreState } from './NavCore-Bjl5fTea.mjs';
2
- export { d as LifecycleContext, e as LifecycleEvent, j as NavLifecycleState, k as NavigationFSM, O as OffRouteContext, l as OffRouteEvent, m as OffRouteFSM, n as OffRouteState, R as RejoinTarget, T as TempRoute, r as resolveNextInstruction } from './NavCore-Bjl5fTea.mjs';
1
+ import { C as Coordinate, i as NavInstruction, g as NavCoreState } from './NavCore.d-BuXR5DO7.mjs';
3
2
 
4
3
  /**
5
4
  * ParallelRoadResolver
@@ -64,6 +63,7 @@ interface ParallelRoadResolverOptions {
64
63
  declare class ParallelRoadResolver {
65
64
  private readonly options;
66
65
  constructor(options?: ParallelRoadResolverOptions);
66
+ private warned;
67
67
  /**
68
68
  * Score and sort snap candidates — lowest score wins.
69
69
  *
@@ -104,18 +104,26 @@ interface DRPrediction {
104
104
  }
105
105
  /**
106
106
  * Given a snapped anchor on the route, extrapolate forward using speed and bearing.
107
+ * Note: This function is a pure utility; license enforcement is in DeadReckoningEngine.predict().
107
108
  */
108
109
  declare function computeDeadReckoningOnRoute(anchor: DRAnchor | null, speed: number, bearing: number, now: number, maxAgeMs?: number): DRPrediction;
109
110
  /**
110
111
  * Stateful dead reckoning engine.
112
+ *
113
+ * FEATURE: DEAD_RECKONING (Pro license required)
114
+ * predict() is a no-op and returns isActive=false when no valid Pro license is present.
111
115
  */
112
116
  declare class DeadReckoningEngine {
113
117
  private anchor;
114
118
  private readonly maxAgeMs;
119
+ private warned;
115
120
  constructor(maxAgeMs?: number);
116
121
  /** Set the anchor point (called when GPS is available and snapping succeeds) */
117
122
  setAnchor(coord: Coordinate, idx: number, timestamp: number): void;
118
- /** Predict position given current speed and bearing */
123
+ /**
124
+ * Predict position given current speed and bearing.
125
+ * Requires a valid Pro license — returns isActive=false without one.
126
+ */
119
127
  predict(speed: number, bearing: number, now: number): DRPrediction;
120
128
  /** Clear the anchor (GPS restored) */
121
129
  clearAnchor(): void;
@@ -125,6 +133,9 @@ declare class DeadReckoningEngine {
125
133
  /**
126
134
  * Module 4b: DeviationDetector
127
135
  * Compound deviation detection using distance, bearing, and movement signals.
136
+ *
137
+ * FEATURE: COMPOUND_DEVIATION (Pro license required)
138
+ * evaluate() returns a neutral "no-deviation" signal without a valid Pro license.
128
139
  */
129
140
 
130
141
  interface DeviationSignals {
@@ -145,8 +156,10 @@ interface ClosestSegment {
145
156
  projection: Coordinate;
146
157
  }
147
158
  declare class DeviationDetector {
159
+ private warned;
148
160
  /**
149
161
  * Evaluate deviation signals for the current GPS position.
162
+ * Requires a valid Pro license — returns a neutral signal without one.
150
163
  */
151
164
  evaluate(gps: Coordinate, gpsBearing: number | null, speedMps: number, closest: ClosestSegment, route: Coordinate[], corridor: number, prevDistToNextSegment: number | null): DeviationSignals;
152
165
  }
@@ -163,42 +176,6 @@ declare class DeviationDetector {
163
176
  */
164
177
  declare function calculateDynamicCorridor(speedMps: number, gpsAccuracy?: number | null, baseMeters?: number, maxMeters?: number, speedFactor?: number, accuracyFactor?: number): number;
165
178
 
166
- /**
167
- * Module 5: BearingEngine
168
- * Speed-adaptive IIR bearing smoothing.
169
- */
170
-
171
- /**
172
- * Calculate speed-adaptive smoothing factor.
173
- * Higher speed → less smoothing (alpha closer to 1).
174
- * Lower speed → more smoothing (alpha closer to base value).
175
- */
176
- declare function getSpeedAdaptiveAlpha(speedMps: number, baseAlpha?: number): number;
177
- /**
178
- * Compute bearing from the route geometry at the current segment.
179
- */
180
- declare function calculateRobustBearing(route: Coordinate[], currentIdx: number, lookAhead?: number): number;
181
- /**
182
- * Blend two bearings using the shortest angular path.
183
- */
184
- declare function blendBearing(current: number, target: number, alpha: number): number;
185
- /**
186
- * Full bearing smoothing pipeline: route bearing → IIR blend → output.
187
- */
188
- declare function applyBearingSmoothing(currentBearing: number, route: Coordinate[], routeIdx: number, speedMps: number, gpsBearing: number | null, baseAlpha?: number): number;
189
-
190
- /**
191
- * Module 6: ProgressTracker
192
- * Monotonic route progress tracking with anti-jitter.
193
- */
194
-
195
- /**
196
- * Validate a progress update: ensures monotonic forward progress with jitter tolerance.
197
- *
198
- * @returns The new progress index (may be the same as current if update is rejected)
199
- */
200
- declare function validateProgressUpdate(currentIdx: number, candidateIdx: number, route: Coordinate[], distToRoute: number, maxSnapDistance: number): number;
201
-
202
179
  /**
203
180
  * InstructionEditor — Fluent builder for NavInstruction arrays.
204
181
  *
@@ -275,30 +252,6 @@ declare class InstructionEditor {
275
252
  get size(): number;
276
253
  }
277
254
 
278
- /**
279
- * Module 8: RouteOffsetPredictor
280
- * Linear distance-based position predictor for smooth rendering between GPS fixes.
281
- */
282
-
283
- /**
284
- * Advance the predictor's offset by speed * dt.
285
- */
286
- declare function advancePredictor(currentOffset: number, speedMps: number, dtSec: number): number;
287
- /**
288
- * Correct the predictor when a new GPS fix arrives.
289
- * Blend towards the actual measured offset using betaCorrection.
290
- */
291
- declare function applyGpsCorrection(predictedOffset: number, measuredOffset: number, betaCorrection?: number): number;
292
- /**
293
- * Given a linear offset (metres from route start), find the [lng, lat] on the route.
294
- *
295
- * @param offset Linear distance from route start in metres
296
- * @param cumulativeDistances Forward cumulative distance array
297
- * @param route Route coordinates
298
- * @returns Interpolated coordinate on the route
299
- */
300
- declare function pointAtOffset(offset: number, cumulativeDistances: Float64Array, route: Coordinate[]): Coordinate;
301
-
302
255
  /**
303
256
  * VoiceTriggerEngine
304
257
  *
@@ -449,14 +402,15 @@ declare class ETAEngine {
449
402
  *
450
403
  * @example
451
404
  * ```typescript
452
- * const geo = new GeofencingEngine();
453
- * geo.addCircle('school-zone', [2.347, 48.859], 50);
454
- * geo.addPolygon('exam-area', [[2.34, 48.85], [2.36, 48.85], [2.36, 48.87], [2.34, 48.87]]);
405
+ * const geo = new GeofencingEngine({ dwellThresholdMs: 5000 });
406
+ * geo.addCircle('school-zone', 'School Zone', [2.347, 48.859], 50, { speedLimit: 30 });
407
+ * geo.addPolygon('exam-area', 'Exam District', [[2.34, 48.85], [2.36, 48.85], [2.36, 48.87], [2.34, 48.87]]);
455
408
  *
456
409
  * engine.on('update', ({ snappedCoord }) => {
457
410
  * const events = geo.update(snappedCoord);
458
411
  * for (const evt of events) {
459
- * console.log(`${evt.type}: ${evt.id}`);
412
+ * // evt.name is the human-readable zone name
413
+ * console.log(`${evt.type}: ${evt.name} (${evt.id})`);
460
414
  * }
461
415
  * });
462
416
  * ```
@@ -467,6 +421,8 @@ type GeofenceEventType = 'enter' | 'exit' | 'dwell';
467
421
  interface GeofenceEvent {
468
422
  /** Geofence ID that triggered the event */
469
423
  id: string;
424
+ /** Human-readable name of the geofence */
425
+ name: string;
470
426
  type: GeofenceEventType;
471
427
  /** Coordinate that triggered the event */
472
428
  coord: Coordinate;
@@ -475,12 +431,25 @@ interface GeofenceEvent {
475
431
  /** Custom metadata passed at creation */
476
432
  meta?: unknown;
477
433
  }
434
+ interface ZoneDefinition {
435
+ id: string;
436
+ name: string;
437
+ type: 'circle' | 'polygon';
438
+ center?: Coordinate;
439
+ radiusMeters?: number;
440
+ coords?: Coordinate[];
441
+ meta?: unknown;
442
+ }
478
443
  interface GeofencingOptions {
479
444
  /**
480
445
  * Milliseconds a vehicle must remain inside a geofence before a 'dwell' event fires.
481
446
  * Default: 10000ms (10 seconds).
482
447
  */
483
448
  dwellThresholdMs?: number;
449
+ /** Initial zones to register on creation */
450
+ zones?: ZoneDefinition[];
451
+ /** Callback for all geofence events */
452
+ onEvent?: (event: GeofenceEvent) => void;
484
453
  }
485
454
  declare class GeofencingEngine {
486
455
  private fences;
@@ -488,12 +457,12 @@ declare class GeofencingEngine {
488
457
  private readonly options;
489
458
  constructor(options?: GeofencingOptions);
490
459
  /** Add a circular geofence. Returns the ID. */
491
- addCircle(id: string, center: Coordinate, radiusM: number, meta?: unknown): string;
460
+ addCircle(id: string, name: string, center: Coordinate, radiusM: number, meta?: unknown): string;
492
461
  /**
493
462
  * Add a polygon geofence. Coords are [lng, lat] pairs.
494
463
  * The polygon is auto-closed (first == last not required).
495
464
  */
496
- addPolygon(id: string, coords: Coordinate[], meta?: unknown): string;
465
+ addPolygon(id: string, name: string, coords: Coordinate[], meta?: unknown): string;
497
466
  /** Remove a geofence by ID */
498
467
  remove(id: string): void;
499
468
  /** Remove all geofences */
@@ -516,4 +485,4 @@ declare class GeofencingEngine {
516
485
  private pointInPolygon;
517
486
  }
518
487
 
519
- export { DeadReckoningEngine, DeviationDetector, ETAEngine, type ETAOptions, type ETAResult, type GeofenceEvent, type GeofenceEventType, type GeofenceType, GeofencingEngine, type GeofencingOptions, InstructionEditor, type InstructionType, NavInstruction, ParallelRoadResolver, type ParallelRoadResolverOptions, type ResolvedCandidate, type RichInstruction, type SnapCandidate, type VoiceCue, type VoicePriority, VoiceTriggerEngine, type VoiceTriggerOptions, advancePredictor, applyBearingSmoothing, applyGpsCorrection, blendBearing, calculateDynamicCorridor, calculateRobustBearing, computeDeadReckoningOnRoute, getSpeedAdaptiveAlpha, pointAtOffset, validateProgressUpdate };
488
+ export { DeadReckoningEngine, DeviationDetector, ETAEngine, type ETAOptions, type ETAResult, type GeofenceEvent, type GeofenceEventType, type GeofenceType, GeofencingEngine, type GeofencingOptions, InstructionEditor, type InstructionType, ParallelRoadResolver, type ParallelRoadResolverOptions, type ResolvedCandidate, type RichInstruction, type SnapCandidate, type VoiceCue, type VoicePriority, VoiceTriggerEngine, type VoiceTriggerOptions, type ZoneDefinition, calculateDynamicCorridor, computeDeadReckoningOnRoute };
package/dist/pro.d.ts CHANGED
@@ -1,5 +1,4 @@
1
- import { C as Coordinate, i as NavInstruction, g as NavCoreState } from './NavCore-Bjl5fTea.js';
2
- export { d as LifecycleContext, e as LifecycleEvent, j as NavLifecycleState, k as NavigationFSM, O as OffRouteContext, l as OffRouteEvent, m as OffRouteFSM, n as OffRouteState, R as RejoinTarget, T as TempRoute, r as resolveNextInstruction } from './NavCore-Bjl5fTea.js';
1
+ import { C as Coordinate, i as NavInstruction, g as NavCoreState } from './NavCore.d-BuXR5DO7.js';
3
2
 
4
3
  /**
5
4
  * ParallelRoadResolver
@@ -64,6 +63,7 @@ interface ParallelRoadResolverOptions {
64
63
  declare class ParallelRoadResolver {
65
64
  private readonly options;
66
65
  constructor(options?: ParallelRoadResolverOptions);
66
+ private warned;
67
67
  /**
68
68
  * Score and sort snap candidates — lowest score wins.
69
69
  *
@@ -104,18 +104,26 @@ interface DRPrediction {
104
104
  }
105
105
  /**
106
106
  * Given a snapped anchor on the route, extrapolate forward using speed and bearing.
107
+ * Note: This function is a pure utility; license enforcement is in DeadReckoningEngine.predict().
107
108
  */
108
109
  declare function computeDeadReckoningOnRoute(anchor: DRAnchor | null, speed: number, bearing: number, now: number, maxAgeMs?: number): DRPrediction;
109
110
  /**
110
111
  * Stateful dead reckoning engine.
112
+ *
113
+ * FEATURE: DEAD_RECKONING (Pro license required)
114
+ * predict() is a no-op and returns isActive=false when no valid Pro license is present.
111
115
  */
112
116
  declare class DeadReckoningEngine {
113
117
  private anchor;
114
118
  private readonly maxAgeMs;
119
+ private warned;
115
120
  constructor(maxAgeMs?: number);
116
121
  /** Set the anchor point (called when GPS is available and snapping succeeds) */
117
122
  setAnchor(coord: Coordinate, idx: number, timestamp: number): void;
118
- /** Predict position given current speed and bearing */
123
+ /**
124
+ * Predict position given current speed and bearing.
125
+ * Requires a valid Pro license — returns isActive=false without one.
126
+ */
119
127
  predict(speed: number, bearing: number, now: number): DRPrediction;
120
128
  /** Clear the anchor (GPS restored) */
121
129
  clearAnchor(): void;
@@ -125,6 +133,9 @@ declare class DeadReckoningEngine {
125
133
  /**
126
134
  * Module 4b: DeviationDetector
127
135
  * Compound deviation detection using distance, bearing, and movement signals.
136
+ *
137
+ * FEATURE: COMPOUND_DEVIATION (Pro license required)
138
+ * evaluate() returns a neutral "no-deviation" signal without a valid Pro license.
128
139
  */
129
140
 
130
141
  interface DeviationSignals {
@@ -145,8 +156,10 @@ interface ClosestSegment {
145
156
  projection: Coordinate;
146
157
  }
147
158
  declare class DeviationDetector {
159
+ private warned;
148
160
  /**
149
161
  * Evaluate deviation signals for the current GPS position.
162
+ * Requires a valid Pro license — returns a neutral signal without one.
150
163
  */
151
164
  evaluate(gps: Coordinate, gpsBearing: number | null, speedMps: number, closest: ClosestSegment, route: Coordinate[], corridor: number, prevDistToNextSegment: number | null): DeviationSignals;
152
165
  }
@@ -163,42 +176,6 @@ declare class DeviationDetector {
163
176
  */
164
177
  declare function calculateDynamicCorridor(speedMps: number, gpsAccuracy?: number | null, baseMeters?: number, maxMeters?: number, speedFactor?: number, accuracyFactor?: number): number;
165
178
 
166
- /**
167
- * Module 5: BearingEngine
168
- * Speed-adaptive IIR bearing smoothing.
169
- */
170
-
171
- /**
172
- * Calculate speed-adaptive smoothing factor.
173
- * Higher speed → less smoothing (alpha closer to 1).
174
- * Lower speed → more smoothing (alpha closer to base value).
175
- */
176
- declare function getSpeedAdaptiveAlpha(speedMps: number, baseAlpha?: number): number;
177
- /**
178
- * Compute bearing from the route geometry at the current segment.
179
- */
180
- declare function calculateRobustBearing(route: Coordinate[], currentIdx: number, lookAhead?: number): number;
181
- /**
182
- * Blend two bearings using the shortest angular path.
183
- */
184
- declare function blendBearing(current: number, target: number, alpha: number): number;
185
- /**
186
- * Full bearing smoothing pipeline: route bearing → IIR blend → output.
187
- */
188
- declare function applyBearingSmoothing(currentBearing: number, route: Coordinate[], routeIdx: number, speedMps: number, gpsBearing: number | null, baseAlpha?: number): number;
189
-
190
- /**
191
- * Module 6: ProgressTracker
192
- * Monotonic route progress tracking with anti-jitter.
193
- */
194
-
195
- /**
196
- * Validate a progress update: ensures monotonic forward progress with jitter tolerance.
197
- *
198
- * @returns The new progress index (may be the same as current if update is rejected)
199
- */
200
- declare function validateProgressUpdate(currentIdx: number, candidateIdx: number, route: Coordinate[], distToRoute: number, maxSnapDistance: number): number;
201
-
202
179
  /**
203
180
  * InstructionEditor — Fluent builder for NavInstruction arrays.
204
181
  *
@@ -275,30 +252,6 @@ declare class InstructionEditor {
275
252
  get size(): number;
276
253
  }
277
254
 
278
- /**
279
- * Module 8: RouteOffsetPredictor
280
- * Linear distance-based position predictor for smooth rendering between GPS fixes.
281
- */
282
-
283
- /**
284
- * Advance the predictor's offset by speed * dt.
285
- */
286
- declare function advancePredictor(currentOffset: number, speedMps: number, dtSec: number): number;
287
- /**
288
- * Correct the predictor when a new GPS fix arrives.
289
- * Blend towards the actual measured offset using betaCorrection.
290
- */
291
- declare function applyGpsCorrection(predictedOffset: number, measuredOffset: number, betaCorrection?: number): number;
292
- /**
293
- * Given a linear offset (metres from route start), find the [lng, lat] on the route.
294
- *
295
- * @param offset Linear distance from route start in metres
296
- * @param cumulativeDistances Forward cumulative distance array
297
- * @param route Route coordinates
298
- * @returns Interpolated coordinate on the route
299
- */
300
- declare function pointAtOffset(offset: number, cumulativeDistances: Float64Array, route: Coordinate[]): Coordinate;
301
-
302
255
  /**
303
256
  * VoiceTriggerEngine
304
257
  *
@@ -449,14 +402,15 @@ declare class ETAEngine {
449
402
  *
450
403
  * @example
451
404
  * ```typescript
452
- * const geo = new GeofencingEngine();
453
- * geo.addCircle('school-zone', [2.347, 48.859], 50);
454
- * geo.addPolygon('exam-area', [[2.34, 48.85], [2.36, 48.85], [2.36, 48.87], [2.34, 48.87]]);
405
+ * const geo = new GeofencingEngine({ dwellThresholdMs: 5000 });
406
+ * geo.addCircle('school-zone', 'School Zone', [2.347, 48.859], 50, { speedLimit: 30 });
407
+ * geo.addPolygon('exam-area', 'Exam District', [[2.34, 48.85], [2.36, 48.85], [2.36, 48.87], [2.34, 48.87]]);
455
408
  *
456
409
  * engine.on('update', ({ snappedCoord }) => {
457
410
  * const events = geo.update(snappedCoord);
458
411
  * for (const evt of events) {
459
- * console.log(`${evt.type}: ${evt.id}`);
412
+ * // evt.name is the human-readable zone name
413
+ * console.log(`${evt.type}: ${evt.name} (${evt.id})`);
460
414
  * }
461
415
  * });
462
416
  * ```
@@ -467,6 +421,8 @@ type GeofenceEventType = 'enter' | 'exit' | 'dwell';
467
421
  interface GeofenceEvent {
468
422
  /** Geofence ID that triggered the event */
469
423
  id: string;
424
+ /** Human-readable name of the geofence */
425
+ name: string;
470
426
  type: GeofenceEventType;
471
427
  /** Coordinate that triggered the event */
472
428
  coord: Coordinate;
@@ -475,12 +431,25 @@ interface GeofenceEvent {
475
431
  /** Custom metadata passed at creation */
476
432
  meta?: unknown;
477
433
  }
434
+ interface ZoneDefinition {
435
+ id: string;
436
+ name: string;
437
+ type: 'circle' | 'polygon';
438
+ center?: Coordinate;
439
+ radiusMeters?: number;
440
+ coords?: Coordinate[];
441
+ meta?: unknown;
442
+ }
478
443
  interface GeofencingOptions {
479
444
  /**
480
445
  * Milliseconds a vehicle must remain inside a geofence before a 'dwell' event fires.
481
446
  * Default: 10000ms (10 seconds).
482
447
  */
483
448
  dwellThresholdMs?: number;
449
+ /** Initial zones to register on creation */
450
+ zones?: ZoneDefinition[];
451
+ /** Callback for all geofence events */
452
+ onEvent?: (event: GeofenceEvent) => void;
484
453
  }
485
454
  declare class GeofencingEngine {
486
455
  private fences;
@@ -488,12 +457,12 @@ declare class GeofencingEngine {
488
457
  private readonly options;
489
458
  constructor(options?: GeofencingOptions);
490
459
  /** Add a circular geofence. Returns the ID. */
491
- addCircle(id: string, center: Coordinate, radiusM: number, meta?: unknown): string;
460
+ addCircle(id: string, name: string, center: Coordinate, radiusM: number, meta?: unknown): string;
492
461
  /**
493
462
  * Add a polygon geofence. Coords are [lng, lat] pairs.
494
463
  * The polygon is auto-closed (first == last not required).
495
464
  */
496
- addPolygon(id: string, coords: Coordinate[], meta?: unknown): string;
465
+ addPolygon(id: string, name: string, coords: Coordinate[], meta?: unknown): string;
497
466
  /** Remove a geofence by ID */
498
467
  remove(id: string): void;
499
468
  /** Remove all geofences */
@@ -516,4 +485,4 @@ declare class GeofencingEngine {
516
485
  private pointInPolygon;
517
486
  }
518
487
 
519
- export { DeadReckoningEngine, DeviationDetector, ETAEngine, type ETAOptions, type ETAResult, type GeofenceEvent, type GeofenceEventType, type GeofenceType, GeofencingEngine, type GeofencingOptions, InstructionEditor, type InstructionType, NavInstruction, ParallelRoadResolver, type ParallelRoadResolverOptions, type ResolvedCandidate, type RichInstruction, type SnapCandidate, type VoiceCue, type VoicePriority, VoiceTriggerEngine, type VoiceTriggerOptions, advancePredictor, applyBearingSmoothing, applyGpsCorrection, blendBearing, calculateDynamicCorridor, calculateRobustBearing, computeDeadReckoningOnRoute, getSpeedAdaptiveAlpha, pointAtOffset, validateProgressUpdate };
488
+ export { DeadReckoningEngine, DeviationDetector, ETAEngine, type ETAOptions, type ETAResult, type GeofenceEvent, type GeofenceEventType, type GeofenceType, GeofencingEngine, type GeofencingOptions, InstructionEditor, type InstructionType, ParallelRoadResolver, type ParallelRoadResolverOptions, type ResolvedCandidate, type RichInstruction, type SnapCandidate, type VoiceCue, type VoicePriority, VoiceTriggerEngine, type VoiceTriggerOptions, type ZoneDefinition, calculateDynamicCorridor, computeDeadReckoningOnRoute };
package/dist/pro.js CHANGED
@@ -1 +1 @@
1
- 'use strict';function h(o,e,t,n){let i=(t-o)*(Math.PI/180),r=(n-e)*(Math.PI/180),s=Math.sin(i/2)*Math.sin(i/2)+Math.cos(o*(Math.PI/180))*Math.cos(t*(Math.PI/180))*Math.sin(r/2)*Math.sin(r/2);return 6371e3*(2*Math.atan2(Math.sqrt(s),Math.sqrt(1-s)))}function P(o,e,t,n){let i=n/6371e3,r=t*(Math.PI/180),s=o*(Math.PI/180),c=e*(Math.PI/180),a=Math.asin(Math.sin(s)*Math.cos(i)+Math.cos(s)*Math.sin(i)*Math.cos(r));return [((c+Math.atan2(Math.sin(r)*Math.sin(i)*Math.cos(s),Math.cos(i)-Math.sin(s)*Math.sin(a)))*180/Math.PI+540)%360-180,a*180/Math.PI]}function w(o,e,t,n,i=5e3){if(!o||e<.5)return {predictedCoord:o?.coord??[0,0],isActive:false,ageMs:0};let r=n-o.ts;if(r>i||r<0)return {predictedCoord:o.coord,isActive:false,ageMs:r};let s=e*(r/1e3);return {predictedCoord:P(o.coord[1],o.coord[0],t,s),isActive:true,ageMs:r}}var M=class{constructor(e=5e3){this.anchor=null;this.maxAgeMs=e;}setAnchor(e,t,n){this.anchor={coord:e,idx:t,ts:n};}predict(e,t,n){return w(this.anchor,e,t,n,this.maxAgeMs)}clearAnchor(){this.anchor=null;}getAnchor(){return this.anchor}};function p(o){let e=o%360;return e>180?e-360:e<-180?e+360:e}function l(o,e){let t=o[1]*(Math.PI/180),n=o[0]*(Math.PI/180),i=e[1]*(Math.PI/180),r=e[0]*(Math.PI/180),s=Math.sin(r-n)*Math.cos(i),c=Math.cos(t)*Math.sin(i)-Math.sin(t)*Math.cos(i)*Math.cos(r-n);return (Math.atan2(s,c)*180/Math.PI+360)%360}function G(o,e,t){let n=(i,r,s)=>i+(r-i)*s;return [n(o[0],e[0],t),n(o[1],e[1],t)]}var T=class{evaluate(e,t,n,i,r,s,c){let a=i.distance>s,u=false;if(t!==null&&i.segmentIndex<r.length-1){let m=l(r[i.segmentIndex],r[i.segmentIndex+1]);u=Math.abs(p(t-m))>90;}let d=false;if(c!==null&&n>1.5){let m=r[Math.min(i.segmentIndex+2,r.length-1)];d=h(e[1],e[0],m[1],m[0])>c+5;}let R=a&&(u||d);return {distanceToRoute:i.distance,outsideCorridor:a,bearingMismatch:u,movingAway:d,confirmed:R}}};function B(o,e=null,t=25,n=60,i=1.2,r=.5){let s=t+o*i;return e!==null&&e>0&&(s+=e*r),Math.min(s,n)}function U(o,e=.3){return o<1.5?e*.5:o>20?Math.min(.9,e*2):e}function L(o,e,t=3){let n=Math.min(e+t,o.length-1);return e>=o.length-1||e===n?e>0?l(o[e-1],o[e]):0:l(o[e],o[n])}function E(o,e,t){let n=p(e-o);return (o+t*n+360)%360}function J(o,e,t,n,i,r=.3){let s=U(n,r),c=L(e,t);if(i!==null&&n>1.5){let a=E(o,i,s*.3);return E(a,c,s)}return E(o,c,s)}function q(o,e,t,n,i){return e<o||e>o+30||n>i?o:e}var z=20,W=60,$=3;function X(o,e,t,n,i,r,s,c=0){if(!e||e.length===0||t>=e.length)return {nextIdx:t,instruction:null,wasTriggered:false};let a=t;for(;a<e.length;){let g=e[a],b=o>g.geometryIndex+30,I=g.cumulativeOffset!==void 0&&s>g.cumulativeOffset+15;if(!b&&!I)break;a++;}if(a>=e.length)return {nextIdx:a,instruction:null,wasTriggered:false};let u=e[a],d=u.cumulativeOffset!==void 0?Math.max(0,u.cumulativeOffset-s):h(i[1],i[0],u.location[1],u.location[0]),R=Math.min(W,Math.max(z,c*$)),m=o<=u.geometryIndex+2,V=d<=R&&m,D=false;if(V){let g=true,b=u.bearingAfter??(u.geometryIndex<n.length-1?l(n[u.geometryIndex],n[u.geometryIndex+1]):null),I=u.bearingBefore??(u.geometryIndex>0?l(n[u.geometryIndex-1],n[u.geometryIndex]):null);I!==null&&b!==null&&r!==null&&Math.abs(p(b-I))>30&&Math.abs(p(r-b))>55&&(g=false),g&&(D=true);}return {nextIdx:a,instruction:u,wasTriggered:D}}var Y=0;function x(){return `instr_${Date.now()}_${++Y}`}var _=class{constructor(){this.instructions=[];}addTurn(e,t,n,i){return this.instructions.push({id:x(),type:"turn",location:e,text:t,instruction:t,geometryIndex:n,silent:i?.silent,meta:i?.meta}),this}addExamPoint(e,t,n,i){return this.instructions.push({id:x(),type:"exam_point",location:e,text:t,instruction:t,geometryIndex:n,severity:i?.severity??"info",silent:i?.silent,meta:i?.meta}),this}addCheckpoint(e,t,n){return this.instructions.push({id:x(),type:"checkpoint",location:e,text:"",instruction:"",geometryIndex:t,silent:true,meta:n}),this}addDepart(e,t="Start navigation"){let n={id:x(),type:"depart",location:e,text:t,instruction:t,geometryIndex:0};return this.instructions.unshift(n),this}addArrive(e,t="You have arrived"){return this.instructions.push({id:x(),type:"arrive",location:e,text:t,instruction:t,geometryIndex:Number.MAX_SAFE_INTEGER}),this}update(e,t){let n=this.instructions.findIndex(i=>i.id===e);if(n===-1)throw new Error(`[InstructionEditor] Instruction ${e} not found`);return this.instructions[n]={...this.instructions[n],...t},this}remove(e){let t=this.instructions.findIndex(n=>n.id===e);if(t===-1)throw new Error(`[InstructionEditor] Instruction ${e} not found`);return this.instructions.splice(t,1),this}reorder(e,t){let n=this.instructions.findIndex(r=>r.id===e);if(n===-1)throw new Error(`[InstructionEditor] Instruction ${e} not found`);let[i]=this.instructions.splice(n,1);return this.instructions.splice(Math.max(0,t),0,i),this}sort(){return this.instructions.sort((e,t)=>e.geometryIndex-t.geometryIndex),this}clear(){return this.instructions=[],this}attachToCumulative(e){if(e.length<2)return this;let t=[0];for(let n=1;n<e.length;n++){let i=e[n-1],r=e[n];t.push(t[n-1]+h(i[1],i[0],r[1],r[0]));}for(let n of this.instructions){let i=Math.min(n.geometryIndex,e.length-1);n.cumulativeOffset=t[i]??0,i>0&&i<e.length-1&&(n.bearingBefore=l(e[i-1],e[i]),n.bearingAfter=l(e[i],e[i+1]));}return this}toArray(){return this.instructions.map(({id:e,type:t,severity:n,meta:i,...r})=>r)}toRichArray(){return [...this.instructions]}get size(){return this.instructions.length}};function K(o,e,t){return o+e*t}function Q(o,e,t=.15){let n=e-o;return o+t*n}function Z(o,e,t){if(t.length===0)return [0,0];if(o<=0)return t[0];let n=e[e.length-1]??0;if(o>=n)return t[t.length-1];let i=0,r=e.length-1;for(;i<r-1;){let d=i+r>>1;e[d]<=o?i=d:r=d;}let s=e[i],a=e[r]-s;if(a===0)return t[i];let u=(o-s)/a;return G(t[i],t[r],u)}var O=class{constructor(){this._state="IDLE";this._context={resumeIndex:null};}get state(){return this._state}get context(){return {...this._context}}dispatch(e){switch(this._state){case "IDLE":e.type==="ROUTE_LOADED"&&(this._state="OVERVIEW"),e.type==="USER_START_NAVIGATION"&&(this._state="APPROACHING_ROUTE");break;case "OVERVIEW":e.type==="USER_START_NAVIGATION"&&(this._state="APPROACHING_ROUTE");break;case "APPROACHING_ROUTE":e.type==="ROUTE_JOINED"&&(this._state="ON_ROUTE",this._context.resumeIndex=e.data.index),e.type==="NAVIGATION_FINISHED"&&(this._state="IDLE");break;case "ON_ROUTE":e.type==="NAVIGATION_FINISHED"&&(this._state="IDLE"),e.type==="ROUTE_JOINED"&&(this._context.resumeIndex=e.data.index);break}return (e.type==="RESET"||e.type==="CANCEL_NAVIGATION")&&(this._state="IDLE",this._context={resumeIndex:null}),{state:this._state,context:{...this._context}}}reset(){this._state="IDLE",this._context={resumeIndex:null};}};var f={deviationSegmentIdx:null,deviationStartMs:null,tempRoute:null,rejoinTarget:null,lastRerouteMs:null,rejoinedAtMs:null,rejoinDwellFrames:0,failureReason:null},k=2e3,ee=3,C=class{constructor(){this._state="ON_ROUTE";this._context={...f};}get state(){return this._state}get context(){return {...this._context}}dispatch(e,t){let n=t??Date.now();switch(this._state){case "ON_ROUTE":e.type==="DEVIATION_SUSPECTED"&&(this._state="DEVIATING",this._context.deviationSegmentIdx=e.deviationSegmentIdx,this._context.deviationStartMs=n);break;case "DEVIATING":e.type==="DEVIATION_CONFIRMED"&&(this._context.deviationStartMs!==null?n-this._context.deviationStartMs:0)>=k&&(this._state="OFF_ROUTE",this._context.deviationSegmentIdx=e.deviationSegmentIdx),(e.type==="RESUME"||e.type==="RESET")&&(this._state="ON_ROUTE",e.type==="RESET"?this._context={...f}:(this._context.deviationSegmentIdx=null,this._context.deviationStartMs=null));break;case "OFF_ROUTE":e.type==="REROUTE_STARTED"&&(this._state="REROUTING",this._context.lastRerouteMs=n),e.type==="RESET"&&(this._state="ON_ROUTE",this._context={...f});break;case "REROUTING":e.type==="REROUTE_SUCCESS"&&(this._state="REJOINING",this._context.tempRoute=e.tempRoute,this._context.rejoinTarget=e.rejoinTarget),e.type==="REROUTE_FAILED"&&(this._state="FAILED",this._context.failureReason=e.reason);break;case "REJOINING":e.type==="REJOIN_DETECTED"&&this._context.rejoinDwellFrames++,(e.type==="REJOIN_CONFIRMED"||this._context.rejoinDwellFrames>=ee)&&(this._state="REJOINED",this._context.rejoinedAtMs=n,this._context.rejoinDwellFrames=0),e.type==="RESET"&&(this._state="ON_ROUTE",this._context={...f});break;case "REJOINED":e.type==="RESUME"&&(this._state="ON_ROUTE",this._context.tempRoute=null,this._context.rejoinTarget=null,this._context.rejoinedAtMs=null,this._context.deviationSegmentIdx=null,this._context.deviationStartMs=null),e.type==="RESET"&&(this._state="ON_ROUTE",this._context={...f});break;case "FAILED":e.type==="RESET"&&(this._state="ON_ROUTE",this._context={...f});break}return {state:this._state,context:{...this._context}}}reset(){this._state="ON_ROUTE",this._context={...f};}isDeviationConfirmed(e=Date.now()){return this._context.deviationStartMs?e-this._context.deviationStartMs>=k:false}};var te={bearingPenalty:80,bearingMismatchThresholdDeg:60,inertiaPenalty:40,inertiaSegmentDist:3},S=class{constructor(e){this.options={...te,...e};}resolve(e,t=null,n=null){return e.map(i=>this.score(i,t,n)).sort((i,r)=>i.score-r.score)}resolveBest(e,t=null,n=null){return e.length===0?null:this.resolve(e,t,n)[0]??null}score(e,t,n){let i=e.distanceMetres,r=null,s=false;if(t!==null){let c=l(e.segA,e.segB),a=Math.abs(p(t-c));r=a,a>this.options.bearingMismatchThresholdDeg&&(i+=this.options.bearingPenalty);}return n!==null&&Math.abs(e.segmentIndex-n)>=this.options.inertiaSegmentDist&&(i+=this.options.inertiaPenalty,s=true),{...e,score:i,bearingDeltaDeg:r,inertiaPenaltyApplied:s}}isLikelyUTurn(e,t,n){let i=l(t,n);return Math.abs(p(e-i))>this.options.bearingMismatchThresholdDeg}};var ne={earlyTriggerMeters:120,lateTriggerMeters:20,reannounceMeters:300},A=class{constructor(e){this.instructions=[];this.triggeredIds=new Set;this.reannouncedIds=new Set;this.options={...ne,...e};}setInstructions(e){this.instructions=[...e],this.triggeredIds.clear(),this.reannouncedIds.clear();}update(e){let{distanceToNextInstruction:t,nextInstructionIndex:n}=e;if(n===null||t===null||n>=this.instructions.length)return null;let i=this.instructions[n],r=this.instrId(n),s=t;if(this.triggeredIds.has(r))return this.options.reannounceMeters>0&&!this.reannouncedIds.has(r)&&s<=this.options.reannounceMeters&&s>this.options.earlyTriggerMeters?(this.reannouncedIds.add(r),this.makeCue(i,s,"low")):null;if(s>this.options.earlyTriggerMeters)return null;if(s<-this.options.lateTriggerMeters)return this.triggeredIds.add(r),null;this.triggeredIds.add(r);let c=s<30?"urgent":s<60?"high":"normal";return this.makeCue(i,s,c)}onInstruction(e,t){let n=t.distanceToNextInstruction??0;return this.makeCue(e,n,"high")}reset(){this.triggeredIds.clear(),this.reannouncedIds.clear();}instrId(e){let t=this.instructions[e];return `${e}_${t?.geometryIndex??0}`}makeCue(e,t,n){return {instruction:e,text:e.text??e.instruction??"",distanceMetres:Math.max(0,t),priority:n,triggerId:`${e.geometryIndex}_${t.toFixed(0)}`}}};var ie={speedWindowSize:6,minimumSpeedMs:.5,fallbackSpeedMs:8.33},v=class{constructor(e){this.speedSamples=[];this.options={...ie,...e},this.lastReliableSpeed=this.options.fallbackSpeedMs;}update(e){let t=e.distanceToDestination??0,n=e.currentSpeed??0;this.speedSamples.push(n),this.speedSamples.length>this.options.speedWindowSize&&this.speedSamples.shift();let i=this.rollingAverage();i>=this.options.minimumSpeedMs&&(this.lastReliableSpeed=i);let r=i>=this.options.minimumSpeedMs?i:this.lastReliableSpeed,s=this.speedSamples.length>=Math.ceil(this.options.speedWindowSize/2)&&r>0&&t>0,c=r>0?t/r:0;return {etaSeconds:Math.round(c),etaMs:Date.now()+c*1e3,distanceRemainingM:t,averageSpeedMs:i,isReliable:s}}reset(){this.speedSamples=[],this.lastReliableSpeed=this.options.fallbackSpeedMs;}rollingAverage(){return this.speedSamples.length===0?0:this.speedSamples.reduce((t,n)=>t+n,0)/this.speedSamples.length}};var re={dwellThresholdMs:1e4},N=class{constructor(e){this.fences=new Map;this.states=new Map;this.options={...re,...e};}addCircle(e,t,n,i){return this.fences.set(e,{kind:"circle",id:e,center:t,radiusM:n,meta:i}),this.states.set(e,{inside:false,enteredAtMs:null}),e}addPolygon(e,t,n){if(t.length<3)throw new Error("[Geofencing] Polygon requires at least 3 coordinates");return this.fences.set(e,{kind:"polygon",id:e,coords:t,meta:n}),this.states.set(e,{inside:false,enteredAtMs:null}),e}remove(e){this.fences.delete(e),this.states.delete(e);}clear(){this.fences.clear(),this.states.clear();}listIds(){return Array.from(this.fences.keys())}update(e){if(!e)return [];let t=[],n=Date.now();for(let[i,r]of this.fences){let s=this.states.get(i),c=this.contains(r,e);if(!s.inside&&c)s.inside=true,s.enteredAtMs=n,t.push({id:i,type:"enter",coord:e,meta:r.meta});else if(s.inside&&!c){s.inside=false;let a=s.enteredAtMs?n-s.enteredAtMs:0;s.enteredAtMs=null,t.push({id:i,type:"exit",coord:e,dwellMs:a,meta:r.meta});}else if(s.inside&&s.enteredAtMs!==null){let a=n-s.enteredAtMs;a>=this.options.dwellThresholdMs&&(t.push({id:i,type:"dwell",coord:e,dwellMs:a,meta:r.meta}),s.enteredAtMs=n);}}return t}isInside(e,t){let n=this.fences.get(e);return n?this.contains(n,t):false}contains(e,t){return e.kind==="circle"?h(t[1],t[0],e.center[1],e.center[0])<=e.radiusM:this.pointInPolygon(t,e.coords)}pointInPolygon(e,t){let[n,i]=e,r=false,s=t.length;for(let c=0,a=s-1;c<s;a=c++){let[u,d]=t[c],[R,m]=t[a];d>i!=m>i&&n<(R-u)*(i-d)/(m-d)+u&&(r=!r);}return r}};exports.DeadReckoningEngine=M;exports.DeviationDetector=T;exports.ETAEngine=v;exports.GeofencingEngine=N;exports.InstructionEditor=_;exports.NavigationFSM=O;exports.OffRouteFSM=C;exports.ParallelRoadResolver=S;exports.VoiceTriggerEngine=A;exports.advancePredictor=K;exports.applyBearingSmoothing=J;exports.applyGpsCorrection=Q;exports.blendBearing=E;exports.calculateDynamicCorridor=B;exports.calculateRobustBearing=L;exports.computeDeadReckoningOnRoute=w;exports.getSpeedAdaptiveAlpha=U;exports.pointAtOffset=Z;exports.resolveNextInstruction=X;exports.validateProgressUpdate=q;
1
+ 'use strict';function f(c,e,t,i){let n=(t-c)*(Math.PI/180),r=(i-e)*(Math.PI/180),o=Math.sin(n/2)*Math.sin(n/2)+Math.cos(c*(Math.PI/180))*Math.cos(t*(Math.PI/180))*Math.sin(r/2)*Math.sin(r/2);return 6371e3*(2*Math.atan2(Math.sqrt(o),Math.sqrt(1-o)))}function x(c,e,t,i){let n=i/6371e3,r=t*(Math.PI/180),o=c*(Math.PI/180),s=e*(Math.PI/180),a=Math.asin(Math.sin(o)*Math.cos(n)+Math.cos(o)*Math.sin(n)*Math.cos(r));return [((s+Math.atan2(Math.sin(r)*Math.sin(n)*Math.cos(o),Math.cos(n)-Math.sin(o)*Math.sin(a)))*180/Math.PI+540)%360-180,a*180/Math.PI]}var l={DEAD_RECKONING:"dead_reckoning",COMPOUND_DEVIATION:"compound_deviation",VOICE_TRIGGERS:"voice_triggers",ETA:"eta",GEOFENCING:"geofencing",NAV_AI:"nav_ai"};var h=class h{constructor(e){this.status="MISSING";this.payload=null;this.enabledFeatures=new Set;this.warnedFeatures=new Set;e&&(this.tryValidateSync(e)||this.validate(e)),this.promoteToActive();}static getActive(){return h.activeManager}static clearActive(){h.activeManager=null;}promoteToActive(){let e=h.activeManager;(e===null||e.status!=="VALID"||this.status==="VALID")&&(h.activeManager=this);}tryValidateSync(e){return e==="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(e){if(this.tryValidateSync(e))return this.status;try{let[t,i]=e.split(".");if(!t||!i)return this.status="INVALID",this.status;let n=atob(t);if(this.payload=JSON.parse(n),!this.payload||this.payload.exp<Date.now())return this.status="EXPIRED",this.status;if(!await this.verifySignature(t,i))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 e of this.payload.f)this.enabledFeatures.add(e);this.payload.t==="pro"&&this.enabledFeatures.add("*");}}hasFeature(e){return this.status!=="VALID"?false:this.enabledFeatures.has("*")?true:this.enabledFeatures.has(e)}warnOnce(e){this.warnedFeatures.has(e)||(console.warn(`[NavCore] Feature '${e}' requires a Pro license`),this.warnedFeatures.add(e));}isProEnabled(){return this.hasFeature("*")}isAIEnabled(){return this.hasFeature(l.NAV_AI)}getStatus(){return this.status}getPayload(){return this.payload}getEnabledFeatures(){return Array.from(this.enabledFeatures)}async verifySignature(e,t){try{if(typeof crypto>"u"||!crypto.subtle)return !1;let n=new TextEncoder().encode(e),r=Uint8Array.from(atob(t),a=>a.charCodeAt(0)),o=Uint8Array.from(atob(h.PUBLIC_KEY_SPKI),a=>a.charCodeAt(0)),s=await crypto.subtle.importKey("spki",o,{name:"ECDSA",namedCurve:"P-256"},!0,["verify"]);return await crypto.subtle.verify({name:"ECDSA",hash:{name:"SHA-256"}},s,r,n)}catch{return false}}};h.activeManager=null,h.PUBLIC_KEY_SPKI="MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEk6onJmJkWtRFusiSS69dcdONX4xL2Snm4AZO+dYjSynfJiL4x7trEy80MImLftknBWT/qI0z7ox4Q7VNL3te6A==";var d=h;function D(c,e,t,i,n=5e3){if(!c||e<.5)return {predictedCoord:c?.coord??[0,0],isActive:false,ageMs:0};let r=i-c.ts;if(r>n||r<0)return {predictedCoord:c.coord,isActive:false,ageMs:r};let o=e*(r/1e3);return {predictedCoord:x(c.coord[1],c.coord[0],t,o),isActive:true,ageMs:r}}var M=class{constructor(e=5e3){this.anchor=null;this.warned=false;this.maxAgeMs=e;}setAnchor(e,t,i){this.anchor={coord:e,idx:t,ts:i};}predict(e,t,i){let n=d.getActive();return !n||!n.hasFeature(l.DEAD_RECKONING)?(this.warned||(n?n.warnOnce(l.DEAD_RECKONING):console.warn(`[NavCore] Feature '${l.DEAD_RECKONING}' requires a Pro license`),this.warned=true),{predictedCoord:this.anchor?.coord??[0,0],isActive:false,ageMs:0}):(this.warned=false,D(this.anchor,e,t,i,this.maxAgeMs))}clearAnchor(){this.anchor=null;}getAnchor(){return this.anchor}};function b(c){let e=c%360;return e>180?e-360:e<-180?e+360:e}function m(c,e){let t=c[1]*(Math.PI/180),i=c[0]*(Math.PI/180),n=e[1]*(Math.PI/180),r=e[0]*(Math.PI/180),o=Math.sin(r-i)*Math.cos(n),s=Math.cos(t)*Math.sin(n)-Math.sin(t)*Math.cos(n)*Math.cos(r-i);return (Math.atan2(o,s)*180/Math.PI+360)%360}var E=class{constructor(){this.warned=false;}evaluate(e,t,i,n,r,o,s){let a=d.getActive();if(!a||!a.hasFeature(l.COMPOUND_DEVIATION))return this.warned||(a?a.warnOnce(l.COMPOUND_DEVIATION):console.warn(`[NavCore] Feature '${l.COMPOUND_DEVIATION}' requires a Pro license`),this.warned=true),{distanceToRoute:n.distance,outsideCorridor:false,bearingMismatch:false,movingAway:false,confirmed:false};this.warned=false;let u=n.distance>o,p=false;if(t!==null&&n.segmentIndex<r.length-1){let v=m(r[n.segmentIndex],r[n.segmentIndex+1]);p=Math.abs(b(t-v))>90;}let g=false;if(s!==null&&i>1.5){let v=r[Math.min(n.segmentIndex+2,r.length-1)];g=f(e[1],e[0],v[1],v[0])>s+5;}let I=u&&(p||g);return {distanceToRoute:n.distance,outsideCorridor:u,bearingMismatch:p,movingAway:g,confirmed:I}}};function N(c,e=null,t=25,i=60,n=1.2,r=.5){let o=t+c*n;return e!==null&&e>0&&(o+=e*r),Math.min(o,i)}var _={bearingPenalty:80,bearingMismatchThresholdDeg:60,inertiaPenalty:40,inertiaSegmentDist:3},C=class{constructor(e){this.warned=false;this.options={..._,...e};}resolve(e,t=null,i=null){let n=d.getActive();return (!n||!n.isProEnabled())&&(this.warned||(console.warn("[NavCore] ParallelRoadResolver and U-turn protection require a Pro license. Falling back to core distance snapping."),this.warned=true)),e.map(r=>this.score(r,t,i)).sort((r,o)=>r.score-o.score)}resolveBest(e,t=null,i=null){return e.length===0?null:this.resolve(e,t,i)[0]??null}score(e,t,i){let n=e.distanceMetres,r=null,o=false,s=d.getActive(),a=s&&s.isProEnabled();if(t!==null&&a){let u=m(e.segA,e.segB),p=Math.abs(b(t-u));r=p,p>this.options.bearingMismatchThresholdDeg&&(n+=this.options.bearingPenalty);}return i!==null&&a&&Math.abs(e.segmentIndex-i)>=this.options.inertiaSegmentDist&&(n+=this.options.inertiaPenalty,o=true),{...e,score:n,bearingDeltaDeg:r,inertiaPenaltyApplied:o}}isLikelyUTurn(e,t,i){let n=m(t,i);return Math.abs(b(e-n))>this.options.bearingMismatchThresholdDeg}};var O={earlyTriggerMeters:120,lateTriggerMeters:20,reannounceMeters:300},A=class{constructor(e){this.instructions=[];this.triggeredIds=new Set;this.reannouncedIds=new Set;this.options={...O,...e};}setInstructions(e){this.instructions=[...e],this.triggeredIds.clear(),this.reannouncedIds.clear();}update(e){let t=d.getActive();if(!t||!t.hasFeature(l.VOICE_TRIGGERS))return t?t.warnOnce(l.VOICE_TRIGGERS):console.warn(`[NavCore] Feature '${l.VOICE_TRIGGERS}' requires a Pro license`),null;let{distanceToNextInstruction:i,nextInstructionIndex:n}=e;if(n===null||i===null||n>=this.instructions.length)return null;let r=this.instructions[n],o=this.instrId(n),s=i;if(this.triggeredIds.has(o))return this.options.reannounceMeters>0&&!this.reannouncedIds.has(o)&&s<=this.options.reannounceMeters&&s>this.options.earlyTriggerMeters?(this.reannouncedIds.add(o),this.makeCue(r,s,"low")):null;if(s>this.options.earlyTriggerMeters)return null;if(s<-this.options.lateTriggerMeters)return this.triggeredIds.add(o),null;this.triggeredIds.add(o);let a=s<30?"urgent":s<60?"high":"normal";return this.makeCue(r,s,a)}onInstruction(e,t){let i=d.getActive();if(!i||!i.hasFeature(l.VOICE_TRIGGERS))return i?i.warnOnce(l.VOICE_TRIGGERS):console.warn(`[NavCore] Feature '${l.VOICE_TRIGGERS}' requires a Pro license`),{instruction:e,text:"",distanceMetres:0,priority:"normal",triggerId:"bypass"};let n=t.distanceToNextInstruction??0;return this.makeCue(e,n,"high")}reset(){this.triggeredIds.clear(),this.reannouncedIds.clear();}instrId(e){let t=this.instructions[e];return `${e}_${t?.geometryIndex??0}`}makeCue(e,t,i){return {instruction:e,text:e.text??e.instruction??"",distanceMetres:Math.max(0,t),priority:i,triggerId:`${e.geometryIndex}_${t.toFixed(0)}`}}};var G={speedWindowSize:6,minimumSpeedMs:.5,fallbackSpeedMs:8.33},R=class{constructor(e){this.speedSamples=[];this.options={...G,...e},this.lastReliableSpeed=this.options.fallbackSpeedMs;}update(e){let t=d.getActive();if(!t||!t.hasFeature(l.ETA))return t?t.warnOnce(l.ETA):console.warn(`[NavCore] Feature '${l.ETA}' requires a Pro license`),{etaSeconds:0,etaMs:0,distanceRemainingM:0,averageSpeedMs:0,isReliable:false};let i=e.distanceToDestination??0,n=e.currentSpeed??0;this.speedSamples.push(n),this.speedSamples.length>this.options.speedWindowSize&&this.speedSamples.shift();let r=this.rollingAverage();r>=this.options.minimumSpeedMs&&(this.lastReliableSpeed=r);let o=r>=this.options.minimumSpeedMs?r:this.lastReliableSpeed,s=this.speedSamples.length>=Math.ceil(this.options.speedWindowSize/2)&&o>0&&i>0,a=o>0?i/o:0;return {etaSeconds:Math.round(a),etaMs:Date.now()+a*1e3,distanceRemainingM:i,averageSpeedMs:r,isReliable:s}}reset(){this.speedSamples=[],this.lastReliableSpeed=this.options.fallbackSpeedMs;}rollingAverage(){return this.speedSamples.length===0?0:this.speedSamples.reduce((t,i)=>t+i,0)/this.speedSamples.length}};var F={dwellThresholdMs:1e4},S=class{constructor(e){this.fences=new Map;this.states=new Map;if(this.options={...F,...e},this.options.zones)for(let t of this.options.zones)t.type==="circle"&&t.center&&t.radiusMeters?this.addCircle(t.id,t.name,t.center,t.radiusMeters,t.meta):t.type==="polygon"&&t.coords&&this.addPolygon(t.id,t.name,t.coords,t.meta);}addCircle(e,t,i,n,r){return this.fences.set(e,{kind:"circle",id:e,name:t,center:i,radiusM:n,meta:r}),this.states.set(e,{inside:false,enteredAtMs:null}),e}addPolygon(e,t,i,n){if(i.length<3)throw new Error("[Geofencing] Polygon requires at least 3 coordinates");return this.fences.set(e,{kind:"polygon",id:e,name:t,coords:i,meta:n}),this.states.set(e,{inside:false,enteredAtMs:null}),e}remove(e){this.fences.delete(e),this.states.delete(e);}clear(){this.fences.clear(),this.states.clear();}listIds(){return Array.from(this.fences.keys())}update(e){let t=d.getActive();if(!t||!t.hasFeature(l.GEOFENCING))return t?t.warnOnce(l.GEOFENCING):console.warn(`[NavCore] Feature '${l.GEOFENCING}' requires a Pro license`),[];if(!e)return [];let i=[],n=Date.now();for(let[r,o]of this.fences){let s=this.states.get(r),a=this.contains(o,e);if(!s.inside&&a){s.inside=true,s.enteredAtMs=n;let u={id:r,name:o.name,type:"enter",coord:e,meta:o.meta};i.push(u),this.options.onEvent?.(u);}else if(s.inside&&!a){s.inside=false;let u=s.enteredAtMs?n-s.enteredAtMs:0;s.enteredAtMs=null;let p={id:r,name:o.name,type:"exit",coord:e,dwellMs:u,meta:o.meta};i.push(p),this.options.onEvent?.(p);}else if(s.inside&&s.enteredAtMs!==null){let u=n-s.enteredAtMs;if(u>=this.options.dwellThresholdMs){let p={id:r,name:o.name,type:"dwell",coord:e,dwellMs:u,meta:o.meta};i.push(p),this.options.onEvent?.(p),s.enteredAtMs=n;}}}return i}isInside(e,t){let i=this.fences.get(e);return i?this.contains(i,t):false}contains(e,t){return e.kind==="circle"?f(t[1],t[0],e.center[1],e.center[0])<=e.radiusM:this.pointInPolygon(t,e.coords)}pointInPolygon(e,t){let[i,n]=e,r=false,o=t.length;for(let s=0,a=o-1;s<o;a=s++){let[u,p]=t[s],[g,I]=t[a];p>n!=I>n&&i<(g-u)*(n-p)/(I-p)+u&&(r=!r);}return r}};var V=0;function y(){return `instr_${Date.now()}_${++V}`}var w=class{constructor(){this.instructions=[];}addTurn(e,t,i,n){return this.instructions.push({id:y(),type:"turn",location:e,text:t,instruction:t,geometryIndex:i,silent:n?.silent,meta:n?.meta}),this}addExamPoint(e,t,i,n){return this.instructions.push({id:y(),type:"exam_point",location:e,text:t,instruction:t,geometryIndex:i,severity:n?.severity??"info",silent:n?.silent,meta:n?.meta}),this}addCheckpoint(e,t,i){return this.instructions.push({id:y(),type:"checkpoint",location:e,text:"",instruction:"",geometryIndex:t,silent:true,meta:i}),this}addDepart(e,t="Start navigation"){let i={id:y(),type:"depart",location:e,text:t,instruction:t,geometryIndex:0};return this.instructions.unshift(i),this}addArrive(e,t="You have arrived"){return this.instructions.push({id:y(),type:"arrive",location:e,text:t,instruction:t,geometryIndex:Number.MAX_SAFE_INTEGER}),this}update(e,t){let i=this.instructions.findIndex(n=>n.id===e);if(i===-1)throw new Error(`[InstructionEditor] Instruction ${e} not found`);return this.instructions[i]={...this.instructions[i],...t},this}remove(e){let t=this.instructions.findIndex(i=>i.id===e);if(t===-1)throw new Error(`[InstructionEditor] Instruction ${e} not found`);return this.instructions.splice(t,1),this}reorder(e,t){let i=this.instructions.findIndex(r=>r.id===e);if(i===-1)throw new Error(`[InstructionEditor] Instruction ${e} not found`);let[n]=this.instructions.splice(i,1);return this.instructions.splice(Math.max(0,t),0,n),this}sort(){return this.instructions.sort((e,t)=>e.geometryIndex-t.geometryIndex),this}clear(){return this.instructions=[],this}attachToCumulative(e){let t=d.getActive();if(!t||!t.isProEnabled())return console.warn("[NavCore] InstructionEditor requires a Pro license. Fluent editing is disabled."),this;if(e.length<2)return this;let i=[0];for(let n=1;n<e.length;n++){let r=e[n-1],o=e[n];i.push(i[n-1]+f(r[1],r[0],o[1],o[0]));}for(let n of this.instructions){let r=Math.min(n.geometryIndex,e.length-1);n.cumulativeOffset=i[r]??0,r>0&&r<e.length-1&&(n.bearingBefore=m(e[r-1],e[r]),n.bearingAfter=m(e[r],e[r+1]));}return this}toArray(){let e=d.getActive();return !e||!e.isProEnabled()?(console.warn("[NavCore] InstructionEditor.toArray() requires a Pro license. Returning empty instruction set."),[]):this.instructions.map(({id:t,type:i,severity:n,meta:r,...o})=>o)}toRichArray(){return [...this.instructions]}get size(){return this.instructions.length}};exports.DeadReckoningEngine=M;exports.DeviationDetector=E;exports.ETAEngine=R;exports.GeofencingEngine=S;exports.InstructionEditor=w;exports.ParallelRoadResolver=C;exports.VoiceTriggerEngine=A;exports.calculateDynamicCorridor=N;exports.computeDeadReckoningOnRoute=D;
package/dist/pro.mjs CHANGED
@@ -1 +1 @@
1
- function h(o,e,t,n){let i=(t-o)*(Math.PI/180),r=(n-e)*(Math.PI/180),s=Math.sin(i/2)*Math.sin(i/2)+Math.cos(o*(Math.PI/180))*Math.cos(t*(Math.PI/180))*Math.sin(r/2)*Math.sin(r/2);return 6371e3*(2*Math.atan2(Math.sqrt(s),Math.sqrt(1-s)))}function P(o,e,t,n){let i=n/6371e3,r=t*(Math.PI/180),s=o*(Math.PI/180),c=e*(Math.PI/180),a=Math.asin(Math.sin(s)*Math.cos(i)+Math.cos(s)*Math.sin(i)*Math.cos(r));return [((c+Math.atan2(Math.sin(r)*Math.sin(i)*Math.cos(s),Math.cos(i)-Math.sin(s)*Math.sin(a)))*180/Math.PI+540)%360-180,a*180/Math.PI]}function w(o,e,t,n,i=5e3){if(!o||e<.5)return {predictedCoord:o?.coord??[0,0],isActive:false,ageMs:0};let r=n-o.ts;if(r>i||r<0)return {predictedCoord:o.coord,isActive:false,ageMs:r};let s=e*(r/1e3);return {predictedCoord:P(o.coord[1],o.coord[0],t,s),isActive:true,ageMs:r}}var M=class{constructor(e=5e3){this.anchor=null;this.maxAgeMs=e;}setAnchor(e,t,n){this.anchor={coord:e,idx:t,ts:n};}predict(e,t,n){return w(this.anchor,e,t,n,this.maxAgeMs)}clearAnchor(){this.anchor=null;}getAnchor(){return this.anchor}};function p(o){let e=o%360;return e>180?e-360:e<-180?e+360:e}function l(o,e){let t=o[1]*(Math.PI/180),n=o[0]*(Math.PI/180),i=e[1]*(Math.PI/180),r=e[0]*(Math.PI/180),s=Math.sin(r-n)*Math.cos(i),c=Math.cos(t)*Math.sin(i)-Math.sin(t)*Math.cos(i)*Math.cos(r-n);return (Math.atan2(s,c)*180/Math.PI+360)%360}function G(o,e,t){let n=(i,r,s)=>i+(r-i)*s;return [n(o[0],e[0],t),n(o[1],e[1],t)]}var T=class{evaluate(e,t,n,i,r,s,c){let a=i.distance>s,u=false;if(t!==null&&i.segmentIndex<r.length-1){let m=l(r[i.segmentIndex],r[i.segmentIndex+1]);u=Math.abs(p(t-m))>90;}let d=false;if(c!==null&&n>1.5){let m=r[Math.min(i.segmentIndex+2,r.length-1)];d=h(e[1],e[0],m[1],m[0])>c+5;}let R=a&&(u||d);return {distanceToRoute:i.distance,outsideCorridor:a,bearingMismatch:u,movingAway:d,confirmed:R}}};function B(o,e=null,t=25,n=60,i=1.2,r=.5){let s=t+o*i;return e!==null&&e>0&&(s+=e*r),Math.min(s,n)}function U(o,e=.3){return o<1.5?e*.5:o>20?Math.min(.9,e*2):e}function L(o,e,t=3){let n=Math.min(e+t,o.length-1);return e>=o.length-1||e===n?e>0?l(o[e-1],o[e]):0:l(o[e],o[n])}function E(o,e,t){let n=p(e-o);return (o+t*n+360)%360}function J(o,e,t,n,i,r=.3){let s=U(n,r),c=L(e,t);if(i!==null&&n>1.5){let a=E(o,i,s*.3);return E(a,c,s)}return E(o,c,s)}function q(o,e,t,n,i){return e<o||e>o+30||n>i?o:e}var z=20,W=60,$=3;function X(o,e,t,n,i,r,s,c=0){if(!e||e.length===0||t>=e.length)return {nextIdx:t,instruction:null,wasTriggered:false};let a=t;for(;a<e.length;){let g=e[a],b=o>g.geometryIndex+30,I=g.cumulativeOffset!==void 0&&s>g.cumulativeOffset+15;if(!b&&!I)break;a++;}if(a>=e.length)return {nextIdx:a,instruction:null,wasTriggered:false};let u=e[a],d=u.cumulativeOffset!==void 0?Math.max(0,u.cumulativeOffset-s):h(i[1],i[0],u.location[1],u.location[0]),R=Math.min(W,Math.max(z,c*$)),m=o<=u.geometryIndex+2,V=d<=R&&m,D=false;if(V){let g=true,b=u.bearingAfter??(u.geometryIndex<n.length-1?l(n[u.geometryIndex],n[u.geometryIndex+1]):null),I=u.bearingBefore??(u.geometryIndex>0?l(n[u.geometryIndex-1],n[u.geometryIndex]):null);I!==null&&b!==null&&r!==null&&Math.abs(p(b-I))>30&&Math.abs(p(r-b))>55&&(g=false),g&&(D=true);}return {nextIdx:a,instruction:u,wasTriggered:D}}var Y=0;function x(){return `instr_${Date.now()}_${++Y}`}var _=class{constructor(){this.instructions=[];}addTurn(e,t,n,i){return this.instructions.push({id:x(),type:"turn",location:e,text:t,instruction:t,geometryIndex:n,silent:i?.silent,meta:i?.meta}),this}addExamPoint(e,t,n,i){return this.instructions.push({id:x(),type:"exam_point",location:e,text:t,instruction:t,geometryIndex:n,severity:i?.severity??"info",silent:i?.silent,meta:i?.meta}),this}addCheckpoint(e,t,n){return this.instructions.push({id:x(),type:"checkpoint",location:e,text:"",instruction:"",geometryIndex:t,silent:true,meta:n}),this}addDepart(e,t="Start navigation"){let n={id:x(),type:"depart",location:e,text:t,instruction:t,geometryIndex:0};return this.instructions.unshift(n),this}addArrive(e,t="You have arrived"){return this.instructions.push({id:x(),type:"arrive",location:e,text:t,instruction:t,geometryIndex:Number.MAX_SAFE_INTEGER}),this}update(e,t){let n=this.instructions.findIndex(i=>i.id===e);if(n===-1)throw new Error(`[InstructionEditor] Instruction ${e} not found`);return this.instructions[n]={...this.instructions[n],...t},this}remove(e){let t=this.instructions.findIndex(n=>n.id===e);if(t===-1)throw new Error(`[InstructionEditor] Instruction ${e} not found`);return this.instructions.splice(t,1),this}reorder(e,t){let n=this.instructions.findIndex(r=>r.id===e);if(n===-1)throw new Error(`[InstructionEditor] Instruction ${e} not found`);let[i]=this.instructions.splice(n,1);return this.instructions.splice(Math.max(0,t),0,i),this}sort(){return this.instructions.sort((e,t)=>e.geometryIndex-t.geometryIndex),this}clear(){return this.instructions=[],this}attachToCumulative(e){if(e.length<2)return this;let t=[0];for(let n=1;n<e.length;n++){let i=e[n-1],r=e[n];t.push(t[n-1]+h(i[1],i[0],r[1],r[0]));}for(let n of this.instructions){let i=Math.min(n.geometryIndex,e.length-1);n.cumulativeOffset=t[i]??0,i>0&&i<e.length-1&&(n.bearingBefore=l(e[i-1],e[i]),n.bearingAfter=l(e[i],e[i+1]));}return this}toArray(){return this.instructions.map(({id:e,type:t,severity:n,meta:i,...r})=>r)}toRichArray(){return [...this.instructions]}get size(){return this.instructions.length}};function K(o,e,t){return o+e*t}function Q(o,e,t=.15){let n=e-o;return o+t*n}function Z(o,e,t){if(t.length===0)return [0,0];if(o<=0)return t[0];let n=e[e.length-1]??0;if(o>=n)return t[t.length-1];let i=0,r=e.length-1;for(;i<r-1;){let d=i+r>>1;e[d]<=o?i=d:r=d;}let s=e[i],a=e[r]-s;if(a===0)return t[i];let u=(o-s)/a;return G(t[i],t[r],u)}var O=class{constructor(){this._state="IDLE";this._context={resumeIndex:null};}get state(){return this._state}get context(){return {...this._context}}dispatch(e){switch(this._state){case "IDLE":e.type==="ROUTE_LOADED"&&(this._state="OVERVIEW"),e.type==="USER_START_NAVIGATION"&&(this._state="APPROACHING_ROUTE");break;case "OVERVIEW":e.type==="USER_START_NAVIGATION"&&(this._state="APPROACHING_ROUTE");break;case "APPROACHING_ROUTE":e.type==="ROUTE_JOINED"&&(this._state="ON_ROUTE",this._context.resumeIndex=e.data.index),e.type==="NAVIGATION_FINISHED"&&(this._state="IDLE");break;case "ON_ROUTE":e.type==="NAVIGATION_FINISHED"&&(this._state="IDLE"),e.type==="ROUTE_JOINED"&&(this._context.resumeIndex=e.data.index);break}return (e.type==="RESET"||e.type==="CANCEL_NAVIGATION")&&(this._state="IDLE",this._context={resumeIndex:null}),{state:this._state,context:{...this._context}}}reset(){this._state="IDLE",this._context={resumeIndex:null};}};var f={deviationSegmentIdx:null,deviationStartMs:null,tempRoute:null,rejoinTarget:null,lastRerouteMs:null,rejoinedAtMs:null,rejoinDwellFrames:0,failureReason:null},k=2e3,ee=3,C=class{constructor(){this._state="ON_ROUTE";this._context={...f};}get state(){return this._state}get context(){return {...this._context}}dispatch(e,t){let n=t??Date.now();switch(this._state){case "ON_ROUTE":e.type==="DEVIATION_SUSPECTED"&&(this._state="DEVIATING",this._context.deviationSegmentIdx=e.deviationSegmentIdx,this._context.deviationStartMs=n);break;case "DEVIATING":e.type==="DEVIATION_CONFIRMED"&&(this._context.deviationStartMs!==null?n-this._context.deviationStartMs:0)>=k&&(this._state="OFF_ROUTE",this._context.deviationSegmentIdx=e.deviationSegmentIdx),(e.type==="RESUME"||e.type==="RESET")&&(this._state="ON_ROUTE",e.type==="RESET"?this._context={...f}:(this._context.deviationSegmentIdx=null,this._context.deviationStartMs=null));break;case "OFF_ROUTE":e.type==="REROUTE_STARTED"&&(this._state="REROUTING",this._context.lastRerouteMs=n),e.type==="RESET"&&(this._state="ON_ROUTE",this._context={...f});break;case "REROUTING":e.type==="REROUTE_SUCCESS"&&(this._state="REJOINING",this._context.tempRoute=e.tempRoute,this._context.rejoinTarget=e.rejoinTarget),e.type==="REROUTE_FAILED"&&(this._state="FAILED",this._context.failureReason=e.reason);break;case "REJOINING":e.type==="REJOIN_DETECTED"&&this._context.rejoinDwellFrames++,(e.type==="REJOIN_CONFIRMED"||this._context.rejoinDwellFrames>=ee)&&(this._state="REJOINED",this._context.rejoinedAtMs=n,this._context.rejoinDwellFrames=0),e.type==="RESET"&&(this._state="ON_ROUTE",this._context={...f});break;case "REJOINED":e.type==="RESUME"&&(this._state="ON_ROUTE",this._context.tempRoute=null,this._context.rejoinTarget=null,this._context.rejoinedAtMs=null,this._context.deviationSegmentIdx=null,this._context.deviationStartMs=null),e.type==="RESET"&&(this._state="ON_ROUTE",this._context={...f});break;case "FAILED":e.type==="RESET"&&(this._state="ON_ROUTE",this._context={...f});break}return {state:this._state,context:{...this._context}}}reset(){this._state="ON_ROUTE",this._context={...f};}isDeviationConfirmed(e=Date.now()){return this._context.deviationStartMs?e-this._context.deviationStartMs>=k:false}};var te={bearingPenalty:80,bearingMismatchThresholdDeg:60,inertiaPenalty:40,inertiaSegmentDist:3},S=class{constructor(e){this.options={...te,...e};}resolve(e,t=null,n=null){return e.map(i=>this.score(i,t,n)).sort((i,r)=>i.score-r.score)}resolveBest(e,t=null,n=null){return e.length===0?null:this.resolve(e,t,n)[0]??null}score(e,t,n){let i=e.distanceMetres,r=null,s=false;if(t!==null){let c=l(e.segA,e.segB),a=Math.abs(p(t-c));r=a,a>this.options.bearingMismatchThresholdDeg&&(i+=this.options.bearingPenalty);}return n!==null&&Math.abs(e.segmentIndex-n)>=this.options.inertiaSegmentDist&&(i+=this.options.inertiaPenalty,s=true),{...e,score:i,bearingDeltaDeg:r,inertiaPenaltyApplied:s}}isLikelyUTurn(e,t,n){let i=l(t,n);return Math.abs(p(e-i))>this.options.bearingMismatchThresholdDeg}};var ne={earlyTriggerMeters:120,lateTriggerMeters:20,reannounceMeters:300},A=class{constructor(e){this.instructions=[];this.triggeredIds=new Set;this.reannouncedIds=new Set;this.options={...ne,...e};}setInstructions(e){this.instructions=[...e],this.triggeredIds.clear(),this.reannouncedIds.clear();}update(e){let{distanceToNextInstruction:t,nextInstructionIndex:n}=e;if(n===null||t===null||n>=this.instructions.length)return null;let i=this.instructions[n],r=this.instrId(n),s=t;if(this.triggeredIds.has(r))return this.options.reannounceMeters>0&&!this.reannouncedIds.has(r)&&s<=this.options.reannounceMeters&&s>this.options.earlyTriggerMeters?(this.reannouncedIds.add(r),this.makeCue(i,s,"low")):null;if(s>this.options.earlyTriggerMeters)return null;if(s<-this.options.lateTriggerMeters)return this.triggeredIds.add(r),null;this.triggeredIds.add(r);let c=s<30?"urgent":s<60?"high":"normal";return this.makeCue(i,s,c)}onInstruction(e,t){let n=t.distanceToNextInstruction??0;return this.makeCue(e,n,"high")}reset(){this.triggeredIds.clear(),this.reannouncedIds.clear();}instrId(e){let t=this.instructions[e];return `${e}_${t?.geometryIndex??0}`}makeCue(e,t,n){return {instruction:e,text:e.text??e.instruction??"",distanceMetres:Math.max(0,t),priority:n,triggerId:`${e.geometryIndex}_${t.toFixed(0)}`}}};var ie={speedWindowSize:6,minimumSpeedMs:.5,fallbackSpeedMs:8.33},v=class{constructor(e){this.speedSamples=[];this.options={...ie,...e},this.lastReliableSpeed=this.options.fallbackSpeedMs;}update(e){let t=e.distanceToDestination??0,n=e.currentSpeed??0;this.speedSamples.push(n),this.speedSamples.length>this.options.speedWindowSize&&this.speedSamples.shift();let i=this.rollingAverage();i>=this.options.minimumSpeedMs&&(this.lastReliableSpeed=i);let r=i>=this.options.minimumSpeedMs?i:this.lastReliableSpeed,s=this.speedSamples.length>=Math.ceil(this.options.speedWindowSize/2)&&r>0&&t>0,c=r>0?t/r:0;return {etaSeconds:Math.round(c),etaMs:Date.now()+c*1e3,distanceRemainingM:t,averageSpeedMs:i,isReliable:s}}reset(){this.speedSamples=[],this.lastReliableSpeed=this.options.fallbackSpeedMs;}rollingAverage(){return this.speedSamples.length===0?0:this.speedSamples.reduce((t,n)=>t+n,0)/this.speedSamples.length}};var re={dwellThresholdMs:1e4},N=class{constructor(e){this.fences=new Map;this.states=new Map;this.options={...re,...e};}addCircle(e,t,n,i){return this.fences.set(e,{kind:"circle",id:e,center:t,radiusM:n,meta:i}),this.states.set(e,{inside:false,enteredAtMs:null}),e}addPolygon(e,t,n){if(t.length<3)throw new Error("[Geofencing] Polygon requires at least 3 coordinates");return this.fences.set(e,{kind:"polygon",id:e,coords:t,meta:n}),this.states.set(e,{inside:false,enteredAtMs:null}),e}remove(e){this.fences.delete(e),this.states.delete(e);}clear(){this.fences.clear(),this.states.clear();}listIds(){return Array.from(this.fences.keys())}update(e){if(!e)return [];let t=[],n=Date.now();for(let[i,r]of this.fences){let s=this.states.get(i),c=this.contains(r,e);if(!s.inside&&c)s.inside=true,s.enteredAtMs=n,t.push({id:i,type:"enter",coord:e,meta:r.meta});else if(s.inside&&!c){s.inside=false;let a=s.enteredAtMs?n-s.enteredAtMs:0;s.enteredAtMs=null,t.push({id:i,type:"exit",coord:e,dwellMs:a,meta:r.meta});}else if(s.inside&&s.enteredAtMs!==null){let a=n-s.enteredAtMs;a>=this.options.dwellThresholdMs&&(t.push({id:i,type:"dwell",coord:e,dwellMs:a,meta:r.meta}),s.enteredAtMs=n);}}return t}isInside(e,t){let n=this.fences.get(e);return n?this.contains(n,t):false}contains(e,t){return e.kind==="circle"?h(t[1],t[0],e.center[1],e.center[0])<=e.radiusM:this.pointInPolygon(t,e.coords)}pointInPolygon(e,t){let[n,i]=e,r=false,s=t.length;for(let c=0,a=s-1;c<s;a=c++){let[u,d]=t[c],[R,m]=t[a];d>i!=m>i&&n<(R-u)*(i-d)/(m-d)+u&&(r=!r);}return r}};export{M as DeadReckoningEngine,T as DeviationDetector,v as ETAEngine,N as GeofencingEngine,_ as InstructionEditor,O as NavigationFSM,C as OffRouteFSM,S as ParallelRoadResolver,A as VoiceTriggerEngine,K as advancePredictor,J as applyBearingSmoothing,Q as applyGpsCorrection,E as blendBearing,B as calculateDynamicCorridor,L as calculateRobustBearing,w as computeDeadReckoningOnRoute,U as getSpeedAdaptiveAlpha,Z as pointAtOffset,X as resolveNextInstruction,q as validateProgressUpdate};
1
+ function f(c,e,t,i){let n=(t-c)*(Math.PI/180),r=(i-e)*(Math.PI/180),o=Math.sin(n/2)*Math.sin(n/2)+Math.cos(c*(Math.PI/180))*Math.cos(t*(Math.PI/180))*Math.sin(r/2)*Math.sin(r/2);return 6371e3*(2*Math.atan2(Math.sqrt(o),Math.sqrt(1-o)))}function x(c,e,t,i){let n=i/6371e3,r=t*(Math.PI/180),o=c*(Math.PI/180),s=e*(Math.PI/180),a=Math.asin(Math.sin(o)*Math.cos(n)+Math.cos(o)*Math.sin(n)*Math.cos(r));return [((s+Math.atan2(Math.sin(r)*Math.sin(n)*Math.cos(o),Math.cos(n)-Math.sin(o)*Math.sin(a)))*180/Math.PI+540)%360-180,a*180/Math.PI]}var l={DEAD_RECKONING:"dead_reckoning",COMPOUND_DEVIATION:"compound_deviation",VOICE_TRIGGERS:"voice_triggers",ETA:"eta",GEOFENCING:"geofencing",NAV_AI:"nav_ai"};var h=class h{constructor(e){this.status="MISSING";this.payload=null;this.enabledFeatures=new Set;this.warnedFeatures=new Set;e&&(this.tryValidateSync(e)||this.validate(e)),this.promoteToActive();}static getActive(){return h.activeManager}static clearActive(){h.activeManager=null;}promoteToActive(){let e=h.activeManager;(e===null||e.status!=="VALID"||this.status==="VALID")&&(h.activeManager=this);}tryValidateSync(e){return e==="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(e){if(this.tryValidateSync(e))return this.status;try{let[t,i]=e.split(".");if(!t||!i)return this.status="INVALID",this.status;let n=atob(t);if(this.payload=JSON.parse(n),!this.payload||this.payload.exp<Date.now())return this.status="EXPIRED",this.status;if(!await this.verifySignature(t,i))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 e of this.payload.f)this.enabledFeatures.add(e);this.payload.t==="pro"&&this.enabledFeatures.add("*");}}hasFeature(e){return this.status!=="VALID"?false:this.enabledFeatures.has("*")?true:this.enabledFeatures.has(e)}warnOnce(e){this.warnedFeatures.has(e)||(console.warn(`[NavCore] Feature '${e}' requires a Pro license`),this.warnedFeatures.add(e));}isProEnabled(){return this.hasFeature("*")}isAIEnabled(){return this.hasFeature(l.NAV_AI)}getStatus(){return this.status}getPayload(){return this.payload}getEnabledFeatures(){return Array.from(this.enabledFeatures)}async verifySignature(e,t){try{if(typeof crypto>"u"||!crypto.subtle)return !1;let n=new TextEncoder().encode(e),r=Uint8Array.from(atob(t),a=>a.charCodeAt(0)),o=Uint8Array.from(atob(h.PUBLIC_KEY_SPKI),a=>a.charCodeAt(0)),s=await crypto.subtle.importKey("spki",o,{name:"ECDSA",namedCurve:"P-256"},!0,["verify"]);return await crypto.subtle.verify({name:"ECDSA",hash:{name:"SHA-256"}},s,r,n)}catch{return false}}};h.activeManager=null,h.PUBLIC_KEY_SPKI="MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEk6onJmJkWtRFusiSS69dcdONX4xL2Snm4AZO+dYjSynfJiL4x7trEy80MImLftknBWT/qI0z7ox4Q7VNL3te6A==";var d=h;function D(c,e,t,i,n=5e3){if(!c||e<.5)return {predictedCoord:c?.coord??[0,0],isActive:false,ageMs:0};let r=i-c.ts;if(r>n||r<0)return {predictedCoord:c.coord,isActive:false,ageMs:r};let o=e*(r/1e3);return {predictedCoord:x(c.coord[1],c.coord[0],t,o),isActive:true,ageMs:r}}var M=class{constructor(e=5e3){this.anchor=null;this.warned=false;this.maxAgeMs=e;}setAnchor(e,t,i){this.anchor={coord:e,idx:t,ts:i};}predict(e,t,i){let n=d.getActive();return !n||!n.hasFeature(l.DEAD_RECKONING)?(this.warned||(n?n.warnOnce(l.DEAD_RECKONING):console.warn(`[NavCore] Feature '${l.DEAD_RECKONING}' requires a Pro license`),this.warned=true),{predictedCoord:this.anchor?.coord??[0,0],isActive:false,ageMs:0}):(this.warned=false,D(this.anchor,e,t,i,this.maxAgeMs))}clearAnchor(){this.anchor=null;}getAnchor(){return this.anchor}};function b(c){let e=c%360;return e>180?e-360:e<-180?e+360:e}function m(c,e){let t=c[1]*(Math.PI/180),i=c[0]*(Math.PI/180),n=e[1]*(Math.PI/180),r=e[0]*(Math.PI/180),o=Math.sin(r-i)*Math.cos(n),s=Math.cos(t)*Math.sin(n)-Math.sin(t)*Math.cos(n)*Math.cos(r-i);return (Math.atan2(o,s)*180/Math.PI+360)%360}var E=class{constructor(){this.warned=false;}evaluate(e,t,i,n,r,o,s){let a=d.getActive();if(!a||!a.hasFeature(l.COMPOUND_DEVIATION))return this.warned||(a?a.warnOnce(l.COMPOUND_DEVIATION):console.warn(`[NavCore] Feature '${l.COMPOUND_DEVIATION}' requires a Pro license`),this.warned=true),{distanceToRoute:n.distance,outsideCorridor:false,bearingMismatch:false,movingAway:false,confirmed:false};this.warned=false;let u=n.distance>o,p=false;if(t!==null&&n.segmentIndex<r.length-1){let v=m(r[n.segmentIndex],r[n.segmentIndex+1]);p=Math.abs(b(t-v))>90;}let g=false;if(s!==null&&i>1.5){let v=r[Math.min(n.segmentIndex+2,r.length-1)];g=f(e[1],e[0],v[1],v[0])>s+5;}let I=u&&(p||g);return {distanceToRoute:n.distance,outsideCorridor:u,bearingMismatch:p,movingAway:g,confirmed:I}}};function N(c,e=null,t=25,i=60,n=1.2,r=.5){let o=t+c*n;return e!==null&&e>0&&(o+=e*r),Math.min(o,i)}var _={bearingPenalty:80,bearingMismatchThresholdDeg:60,inertiaPenalty:40,inertiaSegmentDist:3},C=class{constructor(e){this.warned=false;this.options={..._,...e};}resolve(e,t=null,i=null){let n=d.getActive();return (!n||!n.isProEnabled())&&(this.warned||(console.warn("[NavCore] ParallelRoadResolver and U-turn protection require a Pro license. Falling back to core distance snapping."),this.warned=true)),e.map(r=>this.score(r,t,i)).sort((r,o)=>r.score-o.score)}resolveBest(e,t=null,i=null){return e.length===0?null:this.resolve(e,t,i)[0]??null}score(e,t,i){let n=e.distanceMetres,r=null,o=false,s=d.getActive(),a=s&&s.isProEnabled();if(t!==null&&a){let u=m(e.segA,e.segB),p=Math.abs(b(t-u));r=p,p>this.options.bearingMismatchThresholdDeg&&(n+=this.options.bearingPenalty);}return i!==null&&a&&Math.abs(e.segmentIndex-i)>=this.options.inertiaSegmentDist&&(n+=this.options.inertiaPenalty,o=true),{...e,score:n,bearingDeltaDeg:r,inertiaPenaltyApplied:o}}isLikelyUTurn(e,t,i){let n=m(t,i);return Math.abs(b(e-n))>this.options.bearingMismatchThresholdDeg}};var O={earlyTriggerMeters:120,lateTriggerMeters:20,reannounceMeters:300},A=class{constructor(e){this.instructions=[];this.triggeredIds=new Set;this.reannouncedIds=new Set;this.options={...O,...e};}setInstructions(e){this.instructions=[...e],this.triggeredIds.clear(),this.reannouncedIds.clear();}update(e){let t=d.getActive();if(!t||!t.hasFeature(l.VOICE_TRIGGERS))return t?t.warnOnce(l.VOICE_TRIGGERS):console.warn(`[NavCore] Feature '${l.VOICE_TRIGGERS}' requires a Pro license`),null;let{distanceToNextInstruction:i,nextInstructionIndex:n}=e;if(n===null||i===null||n>=this.instructions.length)return null;let r=this.instructions[n],o=this.instrId(n),s=i;if(this.triggeredIds.has(o))return this.options.reannounceMeters>0&&!this.reannouncedIds.has(o)&&s<=this.options.reannounceMeters&&s>this.options.earlyTriggerMeters?(this.reannouncedIds.add(o),this.makeCue(r,s,"low")):null;if(s>this.options.earlyTriggerMeters)return null;if(s<-this.options.lateTriggerMeters)return this.triggeredIds.add(o),null;this.triggeredIds.add(o);let a=s<30?"urgent":s<60?"high":"normal";return this.makeCue(r,s,a)}onInstruction(e,t){let i=d.getActive();if(!i||!i.hasFeature(l.VOICE_TRIGGERS))return i?i.warnOnce(l.VOICE_TRIGGERS):console.warn(`[NavCore] Feature '${l.VOICE_TRIGGERS}' requires a Pro license`),{instruction:e,text:"",distanceMetres:0,priority:"normal",triggerId:"bypass"};let n=t.distanceToNextInstruction??0;return this.makeCue(e,n,"high")}reset(){this.triggeredIds.clear(),this.reannouncedIds.clear();}instrId(e){let t=this.instructions[e];return `${e}_${t?.geometryIndex??0}`}makeCue(e,t,i){return {instruction:e,text:e.text??e.instruction??"",distanceMetres:Math.max(0,t),priority:i,triggerId:`${e.geometryIndex}_${t.toFixed(0)}`}}};var G={speedWindowSize:6,minimumSpeedMs:.5,fallbackSpeedMs:8.33},R=class{constructor(e){this.speedSamples=[];this.options={...G,...e},this.lastReliableSpeed=this.options.fallbackSpeedMs;}update(e){let t=d.getActive();if(!t||!t.hasFeature(l.ETA))return t?t.warnOnce(l.ETA):console.warn(`[NavCore] Feature '${l.ETA}' requires a Pro license`),{etaSeconds:0,etaMs:0,distanceRemainingM:0,averageSpeedMs:0,isReliable:false};let i=e.distanceToDestination??0,n=e.currentSpeed??0;this.speedSamples.push(n),this.speedSamples.length>this.options.speedWindowSize&&this.speedSamples.shift();let r=this.rollingAverage();r>=this.options.minimumSpeedMs&&(this.lastReliableSpeed=r);let o=r>=this.options.minimumSpeedMs?r:this.lastReliableSpeed,s=this.speedSamples.length>=Math.ceil(this.options.speedWindowSize/2)&&o>0&&i>0,a=o>0?i/o:0;return {etaSeconds:Math.round(a),etaMs:Date.now()+a*1e3,distanceRemainingM:i,averageSpeedMs:r,isReliable:s}}reset(){this.speedSamples=[],this.lastReliableSpeed=this.options.fallbackSpeedMs;}rollingAverage(){return this.speedSamples.length===0?0:this.speedSamples.reduce((t,i)=>t+i,0)/this.speedSamples.length}};var F={dwellThresholdMs:1e4},S=class{constructor(e){this.fences=new Map;this.states=new Map;if(this.options={...F,...e},this.options.zones)for(let t of this.options.zones)t.type==="circle"&&t.center&&t.radiusMeters?this.addCircle(t.id,t.name,t.center,t.radiusMeters,t.meta):t.type==="polygon"&&t.coords&&this.addPolygon(t.id,t.name,t.coords,t.meta);}addCircle(e,t,i,n,r){return this.fences.set(e,{kind:"circle",id:e,name:t,center:i,radiusM:n,meta:r}),this.states.set(e,{inside:false,enteredAtMs:null}),e}addPolygon(e,t,i,n){if(i.length<3)throw new Error("[Geofencing] Polygon requires at least 3 coordinates");return this.fences.set(e,{kind:"polygon",id:e,name:t,coords:i,meta:n}),this.states.set(e,{inside:false,enteredAtMs:null}),e}remove(e){this.fences.delete(e),this.states.delete(e);}clear(){this.fences.clear(),this.states.clear();}listIds(){return Array.from(this.fences.keys())}update(e){let t=d.getActive();if(!t||!t.hasFeature(l.GEOFENCING))return t?t.warnOnce(l.GEOFENCING):console.warn(`[NavCore] Feature '${l.GEOFENCING}' requires a Pro license`),[];if(!e)return [];let i=[],n=Date.now();for(let[r,o]of this.fences){let s=this.states.get(r),a=this.contains(o,e);if(!s.inside&&a){s.inside=true,s.enteredAtMs=n;let u={id:r,name:o.name,type:"enter",coord:e,meta:o.meta};i.push(u),this.options.onEvent?.(u);}else if(s.inside&&!a){s.inside=false;let u=s.enteredAtMs?n-s.enteredAtMs:0;s.enteredAtMs=null;let p={id:r,name:o.name,type:"exit",coord:e,dwellMs:u,meta:o.meta};i.push(p),this.options.onEvent?.(p);}else if(s.inside&&s.enteredAtMs!==null){let u=n-s.enteredAtMs;if(u>=this.options.dwellThresholdMs){let p={id:r,name:o.name,type:"dwell",coord:e,dwellMs:u,meta:o.meta};i.push(p),this.options.onEvent?.(p),s.enteredAtMs=n;}}}return i}isInside(e,t){let i=this.fences.get(e);return i?this.contains(i,t):false}contains(e,t){return e.kind==="circle"?f(t[1],t[0],e.center[1],e.center[0])<=e.radiusM:this.pointInPolygon(t,e.coords)}pointInPolygon(e,t){let[i,n]=e,r=false,o=t.length;for(let s=0,a=o-1;s<o;a=s++){let[u,p]=t[s],[g,I]=t[a];p>n!=I>n&&i<(g-u)*(n-p)/(I-p)+u&&(r=!r);}return r}};var V=0;function y(){return `instr_${Date.now()}_${++V}`}var w=class{constructor(){this.instructions=[];}addTurn(e,t,i,n){return this.instructions.push({id:y(),type:"turn",location:e,text:t,instruction:t,geometryIndex:i,silent:n?.silent,meta:n?.meta}),this}addExamPoint(e,t,i,n){return this.instructions.push({id:y(),type:"exam_point",location:e,text:t,instruction:t,geometryIndex:i,severity:n?.severity??"info",silent:n?.silent,meta:n?.meta}),this}addCheckpoint(e,t,i){return this.instructions.push({id:y(),type:"checkpoint",location:e,text:"",instruction:"",geometryIndex:t,silent:true,meta:i}),this}addDepart(e,t="Start navigation"){let i={id:y(),type:"depart",location:e,text:t,instruction:t,geometryIndex:0};return this.instructions.unshift(i),this}addArrive(e,t="You have arrived"){return this.instructions.push({id:y(),type:"arrive",location:e,text:t,instruction:t,geometryIndex:Number.MAX_SAFE_INTEGER}),this}update(e,t){let i=this.instructions.findIndex(n=>n.id===e);if(i===-1)throw new Error(`[InstructionEditor] Instruction ${e} not found`);return this.instructions[i]={...this.instructions[i],...t},this}remove(e){let t=this.instructions.findIndex(i=>i.id===e);if(t===-1)throw new Error(`[InstructionEditor] Instruction ${e} not found`);return this.instructions.splice(t,1),this}reorder(e,t){let i=this.instructions.findIndex(r=>r.id===e);if(i===-1)throw new Error(`[InstructionEditor] Instruction ${e} not found`);let[n]=this.instructions.splice(i,1);return this.instructions.splice(Math.max(0,t),0,n),this}sort(){return this.instructions.sort((e,t)=>e.geometryIndex-t.geometryIndex),this}clear(){return this.instructions=[],this}attachToCumulative(e){let t=d.getActive();if(!t||!t.isProEnabled())return console.warn("[NavCore] InstructionEditor requires a Pro license. Fluent editing is disabled."),this;if(e.length<2)return this;let i=[0];for(let n=1;n<e.length;n++){let r=e[n-1],o=e[n];i.push(i[n-1]+f(r[1],r[0],o[1],o[0]));}for(let n of this.instructions){let r=Math.min(n.geometryIndex,e.length-1);n.cumulativeOffset=i[r]??0,r>0&&r<e.length-1&&(n.bearingBefore=m(e[r-1],e[r]),n.bearingAfter=m(e[r],e[r+1]));}return this}toArray(){let e=d.getActive();return !e||!e.isProEnabled()?(console.warn("[NavCore] InstructionEditor.toArray() requires a Pro license. Returning empty instruction set."),[]):this.instructions.map(({id:t,type:i,severity:n,meta:r,...o})=>o)}toRichArray(){return [...this.instructions]}get size(){return this.instructions.length}};export{M as DeadReckoningEngine,E as DeviationDetector,R as ETAEngine,S as GeofencingEngine,w as InstructionEditor,C as ParallelRoadResolver,A as VoiceTriggerEngine,N as calculateDynamicCorridor,D as computeDeadReckoningOnRoute};