@mappedin/blue-dot 6.0.1-beta.56 → 6.0.1-beta.58

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1560 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
8
+ var __esm = (fn, res) => function __init() {
9
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
10
+ };
11
+ var __commonJS = (cb, mod) => function __require() {
12
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
13
+ };
14
+ var __copyProps = (to, from, except, desc) => {
15
+ if (from && typeof from === "object" || typeof from === "function") {
16
+ for (let key of __getOwnPropNames(from))
17
+ if (!__hasOwnProp.call(to, key) && key !== except)
18
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
19
+ }
20
+ return to;
21
+ };
22
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
23
+ // If the importer is in node compatibility mode or this is not an ESM
24
+ // file that has been converted to a CommonJS file using a Babel-
25
+ // compatible transform (i.e. "__esModule" has not been set), then set
26
+ // "default" to the CommonJS "module.exports" for node compatibility.
27
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
28
+ mod
29
+ ));
30
+
31
+ // <define:process>
32
+ var define_process_default;
33
+ var init_define_process = __esm({
34
+ "<define:process>"() {
35
+ define_process_default = { env: { npm_package_version: "6.0.1-beta.58" } };
36
+ }
37
+ });
38
+
39
+ // ../../node_modules/.pnpm/simplify-js@1.2.4/node_modules/simplify-js/simplify.js
40
+ var require_simplify = __commonJS({
41
+ "../../node_modules/.pnpm/simplify-js@1.2.4/node_modules/simplify-js/simplify.js"(exports, module) {
42
+ init_define_process();
43
+ (function() {
44
+ "use strict";
45
+ function getSqDist(p1, p2) {
46
+ var dx = p1.x - p2.x, dy = p1.y - p2.y;
47
+ return dx * dx + dy * dy;
48
+ }
49
+ __name(getSqDist, "getSqDist");
50
+ function getSqSegDist(p, p1, p2) {
51
+ var x = p1.x, y = p1.y, dx = p2.x - x, dy = p2.y - y;
52
+ if (dx !== 0 || dy !== 0) {
53
+ var t = ((p.x - x) * dx + (p.y - y) * dy) / (dx * dx + dy * dy);
54
+ if (t > 1) {
55
+ x = p2.x;
56
+ y = p2.y;
57
+ } else if (t > 0) {
58
+ x += dx * t;
59
+ y += dy * t;
60
+ }
61
+ }
62
+ dx = p.x - x;
63
+ dy = p.y - y;
64
+ return dx * dx + dy * dy;
65
+ }
66
+ __name(getSqSegDist, "getSqSegDist");
67
+ function simplifyRadialDist(points, sqTolerance) {
68
+ var prevPoint = points[0], newPoints = [prevPoint], point;
69
+ for (var i = 1, len = points.length; i < len; i++) {
70
+ point = points[i];
71
+ if (getSqDist(point, prevPoint) > sqTolerance) {
72
+ newPoints.push(point);
73
+ prevPoint = point;
74
+ }
75
+ }
76
+ if (prevPoint !== point) newPoints.push(point);
77
+ return newPoints;
78
+ }
79
+ __name(simplifyRadialDist, "simplifyRadialDist");
80
+ function simplifyDPStep(points, first, last, sqTolerance, simplified) {
81
+ var maxSqDist = sqTolerance, index;
82
+ for (var i = first + 1; i < last; i++) {
83
+ var sqDist = getSqSegDist(points[i], points[first], points[last]);
84
+ if (sqDist > maxSqDist) {
85
+ index = i;
86
+ maxSqDist = sqDist;
87
+ }
88
+ }
89
+ if (maxSqDist > sqTolerance) {
90
+ if (index - first > 1) simplifyDPStep(points, first, index, sqTolerance, simplified);
91
+ simplified.push(points[index]);
92
+ if (last - index > 1) simplifyDPStep(points, index, last, sqTolerance, simplified);
93
+ }
94
+ }
95
+ __name(simplifyDPStep, "simplifyDPStep");
96
+ function simplifyDouglasPeucker(points, sqTolerance) {
97
+ var last = points.length - 1;
98
+ var simplified = [points[0]];
99
+ simplifyDPStep(points, 0, last, sqTolerance, simplified);
100
+ simplified.push(points[last]);
101
+ return simplified;
102
+ }
103
+ __name(simplifyDouglasPeucker, "simplifyDouglasPeucker");
104
+ function simplify2(points, tolerance, highestQuality) {
105
+ if (points.length <= 2) return points;
106
+ var sqTolerance = tolerance !== void 0 ? tolerance * tolerance : 1;
107
+ points = highestQuality ? points : simplifyRadialDist(points, sqTolerance);
108
+ points = simplifyDouglasPeucker(points, sqTolerance);
109
+ return points;
110
+ }
111
+ __name(simplify2, "simplify");
112
+ if (typeof define === "function" && define.amd) define(function() {
113
+ return simplify2;
114
+ });
115
+ else if (typeof module !== "undefined") {
116
+ module.exports = simplify2;
117
+ module.exports.default = simplify2;
118
+ } else if (typeof self !== "undefined") self.simplify = simplify2;
119
+ else window.simplify = simplify2;
120
+ })();
121
+ }
122
+ });
123
+
124
+ // src/blue-dot.ts
125
+ init_define_process();
126
+ import { ANIMATION_TWEENS, Coordinate as Coordinate2 } from "@mappedin/mappedin-js";
127
+
128
+ // ../packages/common/Mappedin.Logger.ts
129
+ init_define_process();
130
+ var MI_ERROR_LABEL = "[MappedinJS]";
131
+ function createLogger(name = "", { prefix = MI_ERROR_LABEL } = {}) {
132
+ const label = `${prefix}${name ? `-${name}` : ""}`;
133
+ const rnDebug = /* @__PURE__ */ __name((type, args) => {
134
+ if (typeof window !== "undefined" && window.rnDebug) {
135
+ const processed = args.map((arg) => {
136
+ if (arg instanceof Error && arg.stack) {
137
+ return `${arg.message}
138
+ ${arg.stack}`;
139
+ }
140
+ return arg;
141
+ });
142
+ window.rnDebug(`${name} ${type}: ${processed.join(" ")}`);
143
+ }
144
+ }, "rnDebug");
145
+ return {
146
+ logState: define_process_default.env.NODE_ENV === "test" ? 3 /* SILENT */ : 0 /* LOG */,
147
+ log(...args) {
148
+ if (this.logState <= 0 /* LOG */) {
149
+ console.log(label, ...args);
150
+ rnDebug("log", args);
151
+ }
152
+ },
153
+ warn(...args) {
154
+ if (this.logState <= 1 /* WARN */) {
155
+ console.warn(label, ...args);
156
+ rnDebug("warn", args);
157
+ }
158
+ },
159
+ error(...args) {
160
+ if (this.logState <= 2 /* ERROR */) {
161
+ console.error(label, ...args);
162
+ rnDebug("error", args);
163
+ }
164
+ },
165
+ // It's a bit tricky to prepend [MappedinJs] to assert and time because of how the output is structured in the console, so it is left out for simplicity
166
+ assert(...args) {
167
+ console.assert(...args);
168
+ },
169
+ time(label2) {
170
+ console.time(label2);
171
+ },
172
+ timeEnd(label2) {
173
+ console.timeEnd(label2);
174
+ },
175
+ setLevel(level) {
176
+ if (0 /* LOG */ <= level && level <= 3 /* SILENT */) {
177
+ this.logState = level;
178
+ }
179
+ }
180
+ };
181
+ }
182
+ __name(createLogger, "createLogger");
183
+ var Logger = createLogger();
184
+ var Mappedin_Logger_default = Logger;
185
+
186
+ // ../packages/common/pubsub.ts
187
+ init_define_process();
188
+ var PubSub = class {
189
+ static {
190
+ __name(this, "PubSub");
191
+ }
192
+ /**
193
+ * @private
194
+ * @internal
195
+ */
196
+ _subscribers = {};
197
+ /**
198
+ * @private
199
+ * @internal
200
+ */
201
+ _destroyed = false;
202
+ /**
203
+ * @private
204
+ * @internal
205
+ */
206
+ publish(eventName, data) {
207
+ if (!this._subscribers || !this._subscribers[eventName] || this._destroyed) {
208
+ return;
209
+ }
210
+ this._subscribers[eventName].forEach(function(fn) {
211
+ if (typeof fn !== "function") {
212
+ return;
213
+ }
214
+ fn(data);
215
+ });
216
+ }
217
+ /**
218
+ * Subscribe a function to an event.
219
+ *
220
+ * @param eventName An event name which, when fired, will call the provided
221
+ * function.
222
+ * @param fn A callback that gets called when the corresponding event is fired. The
223
+ * callback will get passed an argument with a type that's one of event payloads.
224
+ * @example
225
+ * // Subscribe to the 'click' event
226
+ * const handler = (event) => {
227
+ * const { coordinate } = event;
228
+ * const { latitude, longitude } = coordinate;
229
+ * console.log(`Map was clicked at ${latitude}, ${longitude}`);
230
+ * };
231
+ * map.on('click', handler);
232
+ */
233
+ on(eventName, fn) {
234
+ if (!this._subscribers || this._destroyed) {
235
+ this._subscribers = {};
236
+ }
237
+ this._subscribers[eventName] = this._subscribers[eventName] || [];
238
+ this._subscribers[eventName].push(fn);
239
+ }
240
+ /**
241
+ * Unsubscribe a function previously subscribed with {@link on}
242
+ *
243
+ * @param eventName An event name to which the provided function was previously
244
+ * subscribed.
245
+ * @param fn A function that was previously passed to {@link on}. The function must
246
+ * have the same reference as the function that was subscribed.
247
+ * @example
248
+ * // Unsubscribe from the 'click' event
249
+ * const handler = (event) => {
250
+ * console.log('Map was clicked', event);
251
+ * };
252
+ * map.off('click', handler);
253
+ */
254
+ off(eventName, fn) {
255
+ if (!this._subscribers || this._subscribers[eventName] == null || this._destroyed) {
256
+ return;
257
+ }
258
+ const itemIdx = this._subscribers[eventName].indexOf(fn);
259
+ if (itemIdx !== -1) {
260
+ this._subscribers[eventName].splice(itemIdx, 1);
261
+ }
262
+ }
263
+ /**
264
+ * @private
265
+ * @internal
266
+ */
267
+ destroy() {
268
+ this._destroyed = true;
269
+ this._subscribers = {};
270
+ }
271
+ };
272
+
273
+ // ../packages/common/utils.ts
274
+ init_define_process();
275
+
276
+ // ../../node_modules/.pnpm/jwt-decode@4.0.0/node_modules/jwt-decode/build/esm/index.js
277
+ init_define_process();
278
+ var InvalidTokenError = class extends Error {
279
+ static {
280
+ __name(this, "InvalidTokenError");
281
+ }
282
+ };
283
+ InvalidTokenError.prototype.name = "InvalidTokenError";
284
+
285
+ // ../packages/common/constants.ts
286
+ init_define_process();
287
+ var EARTH_RADIUS_M = 63710088e-1;
288
+
289
+ // ../packages/common/math-utils.ts
290
+ init_define_process();
291
+
292
+ // ../packages/common/array-utils.ts
293
+ init_define_process();
294
+
295
+ // ../packages/common/utils.ts
296
+ function toRadians(degrees) {
297
+ return degrees * (Math.PI / 180);
298
+ }
299
+ __name(toRadians, "toRadians");
300
+ function toDegrees(radians) {
301
+ return radians * (180 / Math.PI);
302
+ }
303
+ __name(toDegrees, "toDegrees");
304
+ function euclideanModulo(value, modulus) {
305
+ return (value % modulus + modulus) % modulus;
306
+ }
307
+ __name(euclideanModulo, "euclideanModulo");
308
+ function haversineDistance([lon1, lat1], [lon2, lat2]) {
309
+ const dLat = toRadians(lat2 - lat1);
310
+ const dLon = toRadians(lon2 - lon1);
311
+ const startLat = toRadians(lat1);
312
+ const destLat = toRadians(lat2);
313
+ const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(startLat) * Math.cos(destLat);
314
+ const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
315
+ return EARTH_RADIUS_M * c;
316
+ }
317
+ __name(haversineDistance, "haversineDistance");
318
+ function getForwardBearing([lon1, lat1], [lon2, lat2]) {
319
+ const startLat = toRadians(lat1);
320
+ const startLon = toRadians(lon1);
321
+ const destLat = toRadians(lat2);
322
+ const destLon = toRadians(lon2);
323
+ const dLon = destLon - startLon;
324
+ const y = Math.sin(dLon) * Math.cos(destLat);
325
+ const x = Math.cos(startLat) * Math.sin(destLat) - Math.sin(startLat) * Math.cos(destLat) * Math.cos(dLon);
326
+ return toDegrees((Math.atan2(y, x) + Math.PI * 2) % (Math.PI * 2));
327
+ }
328
+ __name(getForwardBearing, "getForwardBearing");
329
+ function shortestTweenRotation(startRotation, targetRotation) {
330
+ const startRotationMod2Pi = euclideanModulo(startRotation, Math.PI * 2);
331
+ const targetRotationMod2Pi = euclideanModulo(targetRotation, Math.PI * 2);
332
+ const delta = targetRotationMod2Pi - startRotationMod2Pi;
333
+ const endRotation = targetRotationMod2Pi + (delta > Math.PI ? -Math.PI * 2 : delta < -Math.PI ? Math.PI * 2 : 0);
334
+ return { start: startRotationMod2Pi, end: endRotation };
335
+ }
336
+ __name(shortestTweenRotation, "shortestTweenRotation");
337
+
338
+ // src/blue-dot.ts
339
+ var import_simplify_js = __toESM(require_simplify());
340
+ import z2 from "zod";
341
+
342
+ // src/constants.ts
343
+ init_define_process();
344
+ var POSITION_ANIMATION_DURATION = 1e3;
345
+ var SCALE_ANIMATION_DURATION = 150;
346
+ var ROTATION_ANIMATION_DURATION = 150;
347
+ var MIN_BLUEDOT_RADIUS = 0.35;
348
+ var BLUEDOT_RADIUS = 10;
349
+ var BASE_COLOR = "#2266ff";
350
+ var INACTIVE_COLOR = "#808080";
351
+ var HEADING_CONE_OPACITY = 0.7;
352
+ var ACCURACY_RING_OPACITY = 0.3;
353
+ var DEFAULT_BLUEDOT_OPTIONS = {
354
+ radius: BLUEDOT_RADIUS,
355
+ color: BASE_COLOR,
356
+ inactiveColor: INACTIVE_COLOR,
357
+ heading: {
358
+ color: BASE_COLOR,
359
+ opacity: HEADING_CONE_OPACITY,
360
+ displayWhenInactive: false
361
+ },
362
+ accuracyRing: {
363
+ color: BASE_COLOR,
364
+ opacity: ACCURACY_RING_OPACITY
365
+ },
366
+ timeout: 3e4,
367
+ watchDevicePosition: true,
368
+ debug: false,
369
+ accuracyThreshold: 50,
370
+ initialState: "hidden",
371
+ preventOutOfBounds: true
372
+ };
373
+
374
+ // src/model-manager.ts
375
+ init_define_process();
376
+ import { Coordinate } from "@mappedin/mappedin-js";
377
+
378
+ // src/models/accuracy-ring.gltf
379
+ var accuracy_ring_default = '{"asset":{"version":"2.0"},"scenes":[{"nodes":[0]}],"scene":0,"nodes":[{"mesh":0}],"bufferViews":[{"buffer":0,"byteOffset":0,"byteLength":2352,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":2352,"byteLength":2352,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":4704,"byteLength":1568,"target":34962,"byteStride":8},{"buffer":0,"byteOffset":6272,"byteLength":768,"target":34963}],"buffers":[{"byteLength":7040,"uri":"data:application/octet-stream;base64,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AAAAAAAAgCUAAIA/AAAAAAAAgCUAAIA/AAAAAAAAgCUAAIA/AAAAAAAAgCUAAIA/AAAAAAAAgCUAAIA/AAAAAAAAgCUAAIA/AAAAAAAAgCUAAIA/AAAAAAAAgCUAAIA/AAAAAAAAgCUAAIA/AAAAAAAAgCUAAIA/AAAAAAAAgCUAAIA/AAAAAAAAgCUAAIA/AAAAAAAAgCUAAIA/AAAAAAAAgCUAAIA/AAAAAAAAgCUAAIA/AAAAAAAAgCUAAIA/AAAAAAAAgCUAAIA/AAAAAAAAgCUAAIA/AAAAAAAAgCUAAIA/AAAAAAAAgCUAAIA/AAAAAAAAgCUAAIA/AAAAAAAAgCUAAIA/AAAAAAAAgCUAAIA/AAAAAAAAgCUAAIA/AAAAAAAAgCUAAIA/AAAAAAAAgCUAAIA/AAAAAAAAgCUAAIA/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgD8AAAA9AACAPwAAgD0AAIA/AADAPQAAgD8AAAA+AACAPwAAID4AAIA/AABAPgAAgD8AAGA+AACAPwAAgD4AAIA/AACQPgAAgD8AAKA+AACAPwAAsD4AAIA/AADAPgAAgD8AANA+AACAPwAA4D4AAIA/AADwPgAAgD8AAAA/AACAPwAACD8AAIA/AAAQPwAAgD8AABg/AACAPwAAID8AAIA/AAAoPwAAgD8AADA/AACAPwAAOD8AAIA/AABAPwAAgD8AAEg/AACAPwAAUD8AAIA/AABYPwAAgD8AAGA/AACAPwAAaD8AAIA/AABwPwAAgD8AAHg/AACAPwAAgD8AAIA/AAAAAAAAAAAAAAA9AAAAAAAAgD0AAAAAAADAPQAAAAAAAAA+AAAAAAAAID4AAAAAAABAPgAAAAAAAGA+AAAAAAAAgD4AAAAAAACQPgAAAAAAAKA+AAAAAAAAsD4AAAAAAADAPgAAAAAAANA+AAAAAAAA4D4AAAAAAADwPgAAAAAAAAA/AAAAAAAACD8AAAAAAAAQPwAAAAAAABg/AAAAAAAAID8AAAAAAAAoPwAAAAAAADA/AAAAAAAAOD8AAAAAAABAPwAAAAAAAEg/AAAAAAAAUD8AAAAAAABYPwAAAAAAAGA/AAAAAAAAaD8AAAAAAABwPwAAAAAAAHg/AAAAAAAAgD8AAAAAAAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAgD8AAAA/X4p9P7j4GD+vQXY/xfswP5ltaj/tHEc/eoJaP3qCWj/tHEc/mW1qP8X7MD+vQXY/uPgYP1+KfT8AAAA/AACAP5AOzj5fin0/dQiePq9Bdj9MjGM+mW1qPxr2FT56glo/O5OsPe0cRz8M5Rs9xfswPzBoHTy4+Bg/AAAAAAAAAD8waB08kA7OPgzlGz11CJ4+O5OsPUyMYz4a9hU+GvYVPkyMYz47k6w9dQiePgzlGz2QDs4+MGgdPAAAAD8AAAAAuPgYPzBoHTzF+zA/DOUbPe0cRz87k6w9eoJaPxr2FT6ZbWo/TIxjPq9Bdj91CJ4+X4p9P5AOzj4AAIA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAIA/AAAAP1+KfT+QDs4+r0F2P3UInj6ZbWo/TIxjPnqCWj8a9hU+7RxHPzuTrD3F+zA/DOUbPbj4GD8waB08AAAAPwAAAACQDs4+MGgdPHUInj4M5Rs9TIxjPjuTrD0a9hU+GvYVPjuTrD1MjGM+DOUbPXUInj4waB08kA7OPgAAAAAAAAA/MGgdPLj4GD8M5Rs9xfswPzuTrD3tHEc/GvYVPnqCWj9MjGM+mW1qP3UInj6vQXY/kA7OPl+KfT8AAAA/AACAP7j4GD9fin0/xfswP69Bdj/tHEc/mW1qP3qCWj96glo/mW1qP+0cRz+vQXY/xfswP1+KfT+4+Bg/AACAPwAAAD8AACEAAQAhACIAAQABACIAAgAiACMAAgACACMAAwAjACQAAwADACQABAAkACUABAAEACUABQAlACYABQAFACYABgAmACcABgAGACcABwAnACgABwAHACgACAAoACkACAAIACkACQApACoACQAJACoACgAqACsACgAKACsACwArACwACwALACwADAAsAC0ADAAMAC0ADQAtAC4ADQANAC4ADgAuAC8ADgAOAC8ADwAvADAADwAPADAAEAAwADEAEAAQADEAEQAxADIAEQARADIAEgAyADMAEgASADMAEwAzADQAEwATADQAFAA0ADUAFAAUADUAFQA1ADYAFQAVADYAFgA2ADcAFgAWADcAFwA3ADgAFwAXADgAGAA4ADkAGAAYADkAGQA5ADoAGQAZADoAGgA6ADsAGgAaADsAGwA7ADwAGwAbADwAHAA8AD0AHAAcAD0AHQA9AD4AHQAdAD4AHgA+AD8AHgAeAD8AHwA/AEAAHwAfAEAAIABAAEEAIABiAGMAQgBjAGQAQwBkAGUARABlAGYARQBmAGcARgBnAGgARwBoAGkASABpAGoASQBqAGsASgBrAGwASwBsAG0ATABtAG4ATQBuAG8ATgBvAHAATwBwAHEAUABxAHIAUQByAHMAUgBzAHQAUwB0AHUAVAB1AHYAVQB2AHcAVgB3AHgAVwB4AHkAWAB5AHoAWQB6AHsAWgB7AHwAWwB8AH0AXAB9AH4AXQB+AH8AXgB/AIAAXwCAAIEAYACBAIIAYQCkAKMAgwClAKQAhACmAKUAhQCnAKYAhgCoAKcAhwCpAKgAiACqAKkAiQCrAKoAigCsAKsAiwCtAKwAjACuAK0AjQCvAK4AjgCwAK8AjwCxALAAkACyALEAkQCzALIAkgC0ALMAkwC1ALQAlAC2ALUAlQC3ALYAlgC4ALcAlwC5ALgAmAC6ALkAmQC7ALoAmgC8ALsAmwC9ALwAnAC+AL0AnQC/AL4AngDAAL8AnwDBAMAAoADCAMEAoQDDAMIAogA="}],"accessors":[{"bufferView":0,"componentType":5126,"count":196,"max":[1,1,0.02500000037252903],"min":[-1,-1,-0.02500000037252903],"type":"VEC3"},{"bufferView":1,"componentType":5126,"count":196,"max":[1,1,1],"min":[-1,-1,-1],"type":"VEC3"},{"bufferView":2,"componentType":5126,"count":196,"max":[1,1],"min":[0,0],"type":"VEC2"},{"bufferView":3,"componentType":5123,"count":384,"max":[195],"min":[0],"type":"SCALAR"}],"materials":[{"pbrMetallicRoughness":{"baseColorFactor":[0.015996293361446288,0.13286832154414627,1,1],"metallicFactor":0,"roughnessFactor":1},"alphaMode":"BLEND","name":"AccuracyRing"}],"meshes":[{"primitives":[{"mode":4,"attributes":{"POSITION":0,"NORMAL":1,"TEXCOORD_0":2},"indices":3,"material":0}]}]}';
380
+
381
+ // src/models/blue-dot.gltf
382
+ var blue_dot_default = '{"asset":{"version":"2.0"},"scenes":[{"nodes":[2]}],"scene":0,"nodes":[{"mesh":0},{"mesh":1},{"children":[0,1]}],"bufferViews":[{"buffer":0,"byteOffset":0,"byteLength":2352,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":2352,"byteLength":2352,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":4704,"byteLength":1568,"target":34962,"byteStride":8},{"buffer":0,"byteOffset":6272,"byteLength":768,"target":34963},{"buffer":0,"byteOffset":7040,"byteLength":2352,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":9392,"byteLength":2352,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":11744,"byteLength":1568,"target":34962,"byteStride":8},{"buffer":0,"byteOffset":13312,"byteLength":768,"target":34963}],"buffers":[{"byteLength":14080,"uri":"data:application/octet-stream;base64,AAAAADMzs74pXI89O9eLPbnBr74pXI89XCcJPimPpb4pXI89yx1HPtb/lL4pXI89VG19PlRtfb4pXI891v+UPssdR74pXI89KY+lPlwnCb4pXI89ucGvPjvXi70pXI89MzOzPmH6e6MpXI89ucGvPjvXiz0pXI89KY+lPlwnCT4pXI891v+UPssdRz4pXI89VG19PlRtfT4pXI89yx1HPtb/lD4pXI89XCcJPimPpT4pXI89O9eLPbnBrz4pXI89RatFJDMzsz4pXI89O9eLvbnBrz4pXI89XCcJvimPpT4pXI89yx1Hvtb/lD4pXI89VG19vlRtfT4pXI891v+UvssdRz4pXI89KY+lvlwnCT4pXI89ucGvvjvXiz0pXI89MzOzvvkrpiQpXI89ucGvvjvXi70pXI89KY+lvlwnCb4pXI891v+UvssdR74pXI89VG19vlRtfb4pXI89yx1Hvtb/lL4pXI89XCcJvimPpb4pXI89O9eLvbnBr74pXI89RavFpDMzs74pXI89AAAAADMzs74E1yOvO9eLPbnBr74E1yOvXCcJPimPpb4F1yOvyx1HPtb/lL4G1yOvVG19PlRtfb4G1yOv1v+UPssdR74H1yOvKY+lPlwnCb4I1yOvucGvPjvXi70J1yOvMzOzPq2sBqQK1yOvucGvPjvXiz0L1yOvKY+lPlwnCT4M1yOv1v+UPssdRz4N1yOvVG19PlRtfT4O1yOvyx1HPtb/lD4O1yOvXCcJPimPpT4P1yOvO9eLPbnBrz4Q1yOvRatFJDMzsz4Q1yOvO9eLvbnBrz4Q1yOvXCcJvimPpT4P1yOvyx1Hvtb/lD4O1yOvVG19vlRtfT4O1yOv1v+UvssdRz4N1yOvKY+lvlwnCT4M1yOvucGvvjvXiz0L1yOvMzOzvu9UgiQK1yOvucGvvjvXi70J1yOvKY+lvlwnCb4I1yOv1v+UvssdR74H1yOvVG19vlRtfb4G1yOvyx1Hvtb/lL4G1yOvXCcJvimPpb4F1yOvO9eLvbnBr74E1yOvRavFpDMzs74E1yOvAAAAAClcDyMpXI89AAAAAClcDyMpXI89AAAAAClcDyMpXI89AAAAAClcDyMpXI89AAAAAClcDyMpXI89AAAAAClcDyMpXI89AAAAAClcDyMpXI89AAAAAClcDyMpXI89AAAAAClcDyMpXI89AAAAAClcDyMpXI89AAAAAClcDyMpXI89AAAAAClcDyMpXI89AAAAAClcDyMpXI89AAAAAClcDyMpXI89AAAAAClcDyMpXI89AAAAAClcDyMpXI89AAAAAClcDyMpXI89AAAAAClcDyMpXI89AAAAAClcDyMpXI89AAAAAClcDyMpXI89AAAAAClcDyMpXI89AAAAAClcDyMpXI89AAAAAClcDyMpXI89AAAAAClcDyMpXI89AAAAAClcDyMpXI89AAAAAClcDyMpXI89AAAAAClcDyMpXI89AAAAAClcDyMpXI89AAAAAClcDyMpXI89AAAAAClcDyMpXI89AAAAAClcDyMpXI89AAAAAClcDyMpXI89AAAAADMzs74pXI89O9eLPbnBr74pXI89XCcJPimPpb4pXI89yx1HPtb/lL4pXI89VG19PlRtfb4pXI891v+UPssdR74pXI89KY+lPlwnCb4pXI89ucGvPjvXi70pXI89MzOzPmH6e6MpXI89ucGvPjvXiz0pXI89KY+lPlwnCT4pXI891v+UPssdRz4pXI89VG19PlRtfT4pXI89yx1HPtb/lD4pXI89XCcJPimPpT4pXI89O9eLPbnBrz4pXI89RatFJDMzsz4pXI89O9eLvbnBrz4pXI89XCcJvimPpT4pXI89yx1Hvtb/lD4pXI89VG19vlRtfT4pXI891v+UvssdRz4pXI89KY+lvlwnCT4pXI89ucGvvjvXiz0pXI89MzOzvvkrpiQpXI89ucGvvjvXi70pXI89KY+lvlwnCb4pXI891v+UvssdR74pXI89VG19vlRtfb4pXI89yx1Hvtb/lL4pXI89XCcJvimPpb4pXI89O9eLvbnBr74pXI89RavFpDMzs74pXI89AAAAAClcD6MK1yOvAAAAAClcD6MK1yOvAAAAAClcD6MK1yOvAAAAAClcD6MK1yOvAAAAAClcD6MK1yOvAAAAAClcD6MK1yOvAAAAAClcD6MK1yOvAAAAAClcD6MK1yOvAAAAAClcD6MK1yOvAAAAAClcD6MK1yOvAAAAAClcD6MK1yOvAAAAAClcD6MK1yOvAAAAAClcD6MK1yOvAAAAAClcD6MK1yOvAAAAAClcD6MK1yOvAAAAAClcD6MK1yOvAAAAAClcD6MK1yOvAAAAAClcD6MK1yOvAAAAAClcD6MK1yOv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AAAAAAAAgCUAAIA/AAAAAAAAgCUAAIA/AAAAAAAAgCUAAIA/AAAAAAAAgCUAAIA/AAAAAAAAgCUAAIA/AAAAAAAAgCUAAIA/AAAAAAAAgCUAAIA/AAAAAAAAgCUAAIA/AAAAAAAAgCUAAIA/AAAAAAAAgCUAAIA/AAAAAAAAgCUAAIA/AAAAAAAAgCUAAIA/AAAAAAAAgCUAAIA/AAAAAAAAgCUAAIA/AAAAAAAAgCUAAIA/AAAAAAAAgCUAAIA/AAAAAAAAgCUAAIA/AAAAAAAAgCUAAIA/AAAAAAAAgCUAAIA/AAAAAAAAgCUAAIA/AAAAAAAAgCUAAIA/AAAAAAAAgCUAAIA/AAAAAAAAgCUAAIA/AAAAAAAAgCUAAIA/AAAAAAAAgCUAAIA/AAAAAAAAgCUAAIA/AAAAAAAAgCUAAIA/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgKUAAIC/AAAAAAAAgD8AAAA9AACAPwAAgD0AAIA/AADAPQAAgD8AAAA+AACAPwAAID4AAIA/AABAPgAAgD8AAGA+AACAPwAAgD4AAIA/AACQPgAAgD8AAKA+AACAPwAAsD4AAIA/AADAPgAAgD8AANA+AACAPwAA4D4AAIA/AADwPgAAgD8AAAA/AACAPwAACD8AAIA/AAAQPwAAgD8AABg/AACAPwAAID8AAIA/AAAoPwAAgD8AADA/AACAPwAAOD8AAIA/AABAPwAAgD8AAEg/AACAPwAAUD8AAIA/AABYPwAAgD8AAGA/AACAPwAAaD8AAIA/AABwPwAAgD8AAHg/AACAPwAAgD8AAIA/AAAAAAAAAAAAAAA9AAAAAAAAgD0AAAAAAADAPQAAAAAAAAA+AAAAAAAAID4AAAAAAABAPgAAAAAAAGA+AAAAAAAAgD4AAAAAAACQPgAAAAAAAKA+AAAAAAAAsD4AAAAAAADAPgAAAAAAANA+AAAAAAAA4D4AAAAAAADwPgAAAAAAAAA/AAAAAAAACD8AAAAAAAAQPwAAAAAAABg/AAAAAAAAID8AAAAAAAAoPwAAAAAAADA/AAAAAAAAOD8AAAAAAABAPwAAAAAAAEg/AAAAAAAAUD8AAAAAAABYPwAAAAAAAGA/AAAAAAAAaD8AAAAAAABwPwAAAAAAAHg/AAAAAAAAgD8AAAAAAAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAgD8AAAA/X4p9P7j4GD+vQXY/xfswP5ltaj/tHEc/eoJaP3qCWj/tHEc/mW1qP8X7MD+vQXY/uPgYP1+KfT8AAAA/AACAP5AOzj5fin0/dQiePq9Bdj9MjGM+mW1qPxr2FT56glo/O5OsPe0cRz8M5Rs9xfswPzBoHTy4+Bg/AAAAAAAAAD8waB08kA7OPgzlGz11CJ4+O5OsPUyMYz4a9hU+GvYVPkyMYz47k6w9dQiePgzlGz2QDs4+MGgdPAAAAD8AAAAAuPgYPzBoHTzF+zA/DOUbPe0cRz87k6w9eoJaPxr2FT6ZbWo/TIxjPq9Bdj91CJ4+X4p9P5AOzj4AAIA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAIA/AAAAP1+KfT+QDs4+r0F2P3UInj6ZbWo/TIxjPnqCWj8a9hU+7RxHPzuTrD3F+zA/DOUbPbj4GD8waB08AAAAPwAAAACQDs4+MGgdPHUInj4M5Rs9TIxjPjuTrD0a9hU+GvYVPjuTrD1MjGM+DOUbPXUInj4waB08kA7OPgAAAAAAAAA/MGgdPLj4GD8M5Rs9xfswPzuTrD3tHEc/GvYVPnqCWj9MjGM+mW1qP3UInj6vQXY/kA7OPl+KfT8AAAA/AACAP7j4GD9fin0/xfswP69Bdj/tHEc/mW1qP3qCWj96glo/mW1qP+0cRz+vQXY/xfswP1+KfT+4+Bg/AACAPwAAAD8AACEAAQAhACIAAQABACIAAgAiACMAAgACACMAAwAjACQAAwADACQABAAkACUABAAEACUABQAlACYABQAFACYABgAmACcABgAGACcABwAnACgABwAHACgACAAoACkACAAIACkACQApACoACQAJACoACgAqACsACgAKACsACwArACwACwALACwADAAsAC0ADAAMAC0ADQAtAC4ADQANAC4ADgAuAC8ADgAOAC8ADwAvADAADwAPADAAEAAwADEAEAAQADEAEQAxADIAEQARADIAEgAyADMAEgASADMAEwAzADQAEwATADQAFAA0ADUAFAAUADUAFQA1ADYAFQAVADYAFgA2ADcAFgAWADcAFwA3ADgAFwAXADgAGAA4ADkAGAAYADkAGQA5ADoAGQAZADoAGgA6ADsAGgAaADsAGwA7ADwAGwAbADwAHAA8AD0AHAAcAD0AHQA9AD4AHQAdAD4AHgA+AD8AHgAeAD8AHwA/AEAAHwAfAEAAIABAAEEAIABiAGMAQgBjAGQAQwBkAGUARABlAGYARQBmAGcARgBnAGgARwBoAGkASABpAGoASQBqAGsASgBrAGwASwBsAG0ATABtAG4ATQBuAG8ATgBvAHAATwBwAHEAUABxAHIAUQByAHMAUgBzAHQAUwB0AHUAVAB1AHYAVQB2AHcAVgB3AHgAVwB4AHkAWAB5AHoAWQB6AHsAWgB7AHwAWwB8AH0AXAB9AH4AXQB+AH8AXgB/AIAAXwCAAIEAYACBAIIAYQCkAKMAgwClAKQAhACmAKUAhQCnAKYAhgCoAKcAhwCpAKgAiACqAKkAiQCrAKoAigCsAKsAiwCtAKwAjACuAK0AjQCvAK4AjgCwAK8AjwCxALAAkACyALEAkQCzALIAkgC0ALMAkwC1ALQAlAC2ALUAlQC3ALYAlgC4ALcAlwC5ALgAmAC6ALkAmQC7ALoAmgC8ALsAmwC9ALwAnAC+AL0AnQC/AL4AngDAAL8AnwDBAMAAoADCAMEAoQDDAMIAogAAAAAAKVyPvpqZmT3Fvl89+pqMvpqZmT0scts9h3KEvpqZmT0ISx8+I2ZuvpqZmT3dvUo+3b1KvpqZmT0jZm4+CEsfvpqZmT2HcoQ+LHLbvZqZmT36mow+xb5fvZqZmT0pXI8+LeWTo5qZmT36mow+xb5fPZqZmT2HcoQ+LHLbPZqZmT0jZm4+CEsfPpqZmT3dvUo+3b1KPpqZmT0ISx8+I2ZuPpqZmT0scts9h3KEPpqZmT3Fvl89+pqMPpqZmT2eIh4kKVyPPpqZmT3Fvl+9+pqMPpqZmT0sctu9h3KEPpqZmT0ISx++I2ZuPpqZmT3dvUq+3b1KPpqZmT0jZm6+CEsfPpqZmT2HcoS+LHLbPZqZmT36moy+xb5fPZqZmT0pXI++pVJyJJqZmT36moy+xb5fvZqZmT2HcoS+LHLbvZqZmT0jZm6+CEsfvpqZmT3dvUq+3b1KvpqZmT0ISx++I2ZuvpqZmT0sctu9h3KEvpqZmT3Fvl+9+pqMvpqZmT2eIp6kKVyPvpqZmT0AAAAAKVyPvrgehT3Fvl89+pqMvrgehT0scts9h3KEvrgehT0ISx8+I2ZuvrgehT3dvUo+3b1KvrgehT0jZm4+CEsfvrgehT2HcoQ+LHLbvbgehT36mow+xb5fvbgehT0pXI8+D2Coo7gehT36mow+xb5fPbgehT2HcoQ+LHLbPbgehT0jZm4+CEsfPrgehT3dvUo+3b1KPrgehT0ISx8+I2ZuPrgehT0scts9h3KEPrgehT3Fvl89+pqMPrgehT2eIh4kKVyPPrgehT3Fvl+9+pqMPrgehT0sctu9h3KEPrgehT0ISx++I2ZuPrgehT3dvUq+3b1KPrgehT0jZm6+CEsfPrgehT2HcoS+LHLbPbgehT36moy+xb5fPbgehT0pXI++NRVoJLgehT36moy+xb5fvbgehT2HcoS+LHLbvbgehT0jZm6+CEsfvrgehT3dvUq+3b1KvrgehT0ISx++I2ZuvrgehT0sctu9h3KEvrgehT3Fvl+9+pqMvrgehT2eIp6kKVyPvrgehT0AAAAACtejIZqZmT0AAAAACtejIZqZmT0AAAAACtejIZqZmT0AAAAACtejIZqZmT0AAAAACtejIZqZmT0AAAAACtejIZqZmT0AAAAACtejIZqZmT0AAAAACtejIZqZmT0AAAAACtejIZqZmT0AAAAACtejIZqZmT0AAAAACtejIZqZmT0AAAAACtejIZqZmT0AAAAACtejIZqZmT0AAAAACtejIZqZmT0AAAAACtejIZqZmT0AAAAACtejIZqZmT0AAAAACtejIZqZmT0AAAAACtejIZqZmT0AAAAACtejIZqZmT0AAAAACtejIZqZmT0AAAAACtejIZqZmT0AAAAACtejIZqZmT0AAAAACtejIZqZmT0AAAAACtejIZqZmT0AAAAACtejIZqZmT0AAAAACtejIZqZmT0AAAAACtejIZqZmT0AAAAACtejIZqZmT0AAAAACtejIZqZmT0AAAAACtejIZqZmT0AAAAACtejIZqZmT0AAAAACtejIZqZmT0AAAAAKVyPvpqZmT3Fvl89+pqMvpqZmT0scts9h3KEvpqZmT0ISx8+I2ZuvpqZmT3dvUo+3b1KvpqZmT0jZm4+CEsfvpqZmT2HcoQ+LHLbvZqZmT36mow+xb5fvZqZmT0pXI8+LeWTo5qZmT36mow+xb5fPZqZmT2HcoQ+LHLbPZqZmT0jZm4+CEsfPpqZmT3dvUo+3b1KPpqZmT0ISx8+I2ZuPpqZmT0scts9h3KEPpqZmT3Fvl89+pqMPpqZmT2eIh4kKVyPPpqZmT3Fvl+9+pqMPpqZmT0sctu9h3KEPpqZmT0ISx++I2ZuPpqZmT3dvUq+3b1KPpqZmT0jZm6+CEsfPpqZmT2HcoS+LHLbPZqZmT36moy+xb5fPZqZmT0pXI++pVJyJJqZmT36moy+xb5fvZqZmT2HcoS+LHLbvZqZmT0jZm6+CEsfvpqZmT3dvUq+3b1KvpqZmT0ISx++I2ZuvpqZmT0sctu9h3KEvpqZmT3Fvl+9+pqMvpqZmT2eIp6kKVyPvpqZmT0AAAAACtejobgehT0AAAAACtejobgehT0AAAAACtejobgehT0AAAAACtejobgehT0AAAAACtejobgehT0AAAAACtejobgehT0AAAAACtejobgehT0AAAAACtejobgehT0AAAAACtejobgehT0AAAAACtejobgehT0AAAAACtejobgehT0AAAAACtejobgehT0AAAAACtejobgehT0AAAAACtejobgehT0AAAAACtejobgehT0AAAAACtejobgehT0AAAAACtejobgehT0AAAAACtejobgehT0AAAAACtejobgehT0AAAAACtejobgehT0AAAAACtejobgehT0AAAAACtejobgehT0AAAAACtejobgehT0AAAAACtejobgehT0AAAAACtejobgehT0AAAAACtejobgehT0AAAAACtejobgehT0AAAAACtejobgehT0AAAAACtejobgehT0AAAAACtejobgehT0AAAAACtejobgehT0AAAAACtejobgehT0AAAAA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AACAJQAAgD8AAAAAAACAJQAAgD8AAAAAAACAJQAAgD8AAAAAAACAJQAAgD8AAAAAAACAJQAAgD8AAAAAAACAJQAAgD8AAAAAAACAJQAAgD8AAAAAAACAJQAAgD8AAAAAAACAJQAAgD8AAAAAAACAJQAAgD8AAAAAAACAJQAAgD8AAAAAAACAJQAAgD8AAAAAAACAJQAAgD8AAAAAAACAJQAAgD8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAAAACApQAAgL8AAAAA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MQAQABAAMQARADEAMgARABEAMgASADIAMwASABIAMwATADMANAATABMANAAUADQANQAUABQANQAVADUANgAVABUANgAWADYANwAWABYANwAXADcAOAAXABcAOAAYADgAOQAYABgAOQAZADkAOgAZABkAOgAaADoAOwAaABoAOwAbADsAPAAbABsAPAAcADwAPQAcABwAPQAdAD0APgAdAB0APgAeAD4APwAeAB4APwAfAD8AQAAfAB8AQAAgAEAAQQAgAGIAYwBCAGMAZABDAGQAZQBEAGUAZgBFAGYAZwBGAGcAaABHAGgAaQBIAGkAagBJAGoAawBKAGsAbABLAGwAbQBMAG0AbgBNAG4AbwBOAG8AcABPAHAAcQBQAHEAcgBRAHIAcwBSAHMAdABTAHQAdQBUAHUAdgBVAHYAdwBWAHcAeABXAHgAeQBYAHkAegBZAHoAewBaAHsAfABbAHwAfQBcAH0AfgBdAH4AfwBeAH8AgABfAIAAgQBgAIEAggBhAKQAowCDAKUApACEAKYApQCFAKcApgCGAKgApwCHAKkAqACIAKoAqQCJAKsAqgCKAKwAqwCLAK0ArACMAK4ArQCNAK8ArgCOALAArwCPALEAsACQALIAsQCRALMAsgCSALQAswCTALUAtACUALYAtQCVALcAtgCWALgAtwCXALkAuACYALoAuQCZALsAugCaALwAuwCbAL0AvACcAL4AvQCdAL8AvgCeAMAAvwCfAMEAwACgAMIAwQChAMMAwgCiAA=="}],"accessors":[{"bufferView":0,"componentType":5126,"count":196,"max":[0.3499999940395355,0.3499999940395355,0.07000000029802322],"min":[-0.3499999940395355,-0.3499999940395355,-1.4901169187453434e-10],"type":"VEC3"},{"bufferView":1,"componentType":5126,"count":196,"max":[1,1,1],"min":[-1,-1,-1],"type":"VEC3"},{"bufferView":2,"componentType":5126,"count":196,"max":[1,1],"min":[0,0],"type":"VEC2"},{"bufferView":3,"componentType":5123,"count":384,"max":[195],"min":[0],"type":"SCALAR"},{"bufferView":4,"componentType":5126,"count":196,"max":[0.2800000011920929,0.2800000011920929,0.07500000298023224],"min":[-0.2800000011920929,-0.2800000011920929,0.06499999761581421],"type":"VEC3"},{"bufferView":5,"componentType":5126,"count":196,"max":[1,1,1],"min":[-1,-1,-1],"type":"VEC3"},{"bufferView":6,"componentType":5126,"count":196,"max":[1,1],"min":[0,0],"type":"VEC2"},{"bufferView":7,"componentType":5123,"count":384,"max":[195],"min":[0],"type":"SCALAR"}],"materials":[{"pbrMetallicRoughness":{"baseColorFactor":[0.913098651791473,0.913098651791473,0.913098651791473,1],"metallicFactor":0,"roughnessFactor":1},"alphaMode":"BLEND","name":"Border"},{"pbrMetallicRoughness":{"baseColorFactor":[0.015996293361446288,0.13286832154414627,1,1],"metallicFactor":0,"roughnessFactor":1},"alphaMode":"BLEND","name":"Inner"}],"meshes":[{"primitives":[{"mode":4,"attributes":{"POSITION":0,"NORMAL":1,"TEXCOORD_0":2},"indices":3,"material":0}]},{"primitives":[{"mode":4,"attributes":{"POSITION":4,"NORMAL":5,"TEXCOORD_0":6},"indices":7,"material":1}]}]}';
383
+
384
+ // src/models/heading-cone.gltf
385
+ var heading_cone_default = '{"asset":{"version":"2.0"},"scenes":[{"nodes":[0]}],"scene":0,"nodes":[{"mesh":0}],"bufferViews":[{"buffer":0,"byteOffset":0,"byteLength":2880,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":2880,"byteLength":1920,"target":34962,"byteStride":8},{"buffer":0,"byteOffset":4800,"byteLength":2880,"target":34962,"byteStride":12}],"buffers":[{"byteLength":7680,"uri":"data:application/octet-stream;base64,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AACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAgAAAAIAAAIC/AAAAgAAAAIAAAIC/AAAAgAAAAIAAAIC/AAAAgAAAAIAAAIC/AAAAgAAAAIAAAIC/AAAAgAAAAIAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAgAAAAIAAAIC/AAAAgAAAAIAAAIC/AAAAgAAAAIAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/ARlkP3Bx6L4AAAAAARlkP3Bx6L4AAAAAARlkP3Bx6L4AAAAAARlkP3Bx6L4AAAAAARlkP3Bx6L4AAAAAARlkP3Bx6L4AAAAA8wQ1P/MENb8AAAAA8wQ1P/MENb8AAAAA8wQ1P/MENb8AAAAA8wQ1P/MENb8AAAAA8wQ1P/MENb8AAAAA8wQ1P/MENb8AAAAAcHHoPgEZZL8AAAAAcHHoPgEZZL8AAAAAcHHoPgEZZL8AAAAAcHHoPgEZZL8AAAAAcHHoPgEZZL8AAAAAcHHoPgEZZL8AAAAAXzAgPiTZfL8AAAAAXzAgPiTZfL8AAAAAXzAgPiTZfL8AAAAAXzAgPiTZfL8AAAAAXzAgPiTZfL8AAAAAXzAgPiTZfL8AAAAAXzAgviTZfL8AAAAAXzAgviTZfL8AAAAAXzAgviTZfL8AAAAAXzAgviTZfL8AAACAXzAgviTZfL8AAACAXzAgviTZfL8AAACAcHHovgEZZL8AAAAAcHHovgEZZL8AAAAAcHHovgEZZL8AAAAAcHHovgEZZL8AAACAcHHovgEZZL8AAACAcHHovgEZZL8AAACA8wQ1v/MENb8AAAAA8wQ1v/MENb8AAAAA8wQ1v/MENb8AAAAA8wQ1v/MENb8AAACA8wQ1v/MENb8AAACA8wQ1v/MENb8AAACAARlkv3Bx6L4AAAAAARlkv3Bx6L4AAAAAARlkv3Bx6L4AAAAAARlkv3Bx6L4AAACAARlkv3Bx6L4AAACAARlkv3Bx6L4AAACAJNl8v18wIL4AAAAAJNl8v18wIL4AAAAAJNl8v18wIL4AAAAAJNl8v18wIL4AAACAJNl8v18wIL4AAACAJNl8v18wIL4AAACAX8V8P5kgIr4AAAAAX8V8P5kgIr4AAAAAX8V8P5kgIr4AAAAAX8V8P5kgIr4AAAAAX8V8P5kgIr4AAAAAX8V8P5kgIr4AAAAA8ps6Ppi2ez8AAAAA8ps6Ppi2ez8AAAAA8ps6Ppi2ez8AAAAA8ps6Ppi2ez8AAAAA8ps6Ppi2ez8AAAAA8ps6Ppi2ez8AAAAAu6gFPlTPfT8AAAAAu6gFPlTPfT8AAAAAu6gFPlTPfT8AAAAAu6gFPlTPfT8AAAAAu6gFPlTPfT8AAAAAu6gFPlTPfT8AAAAAx66gPfo1fz8AAAAAx66gPfo1fz8AAAAAx66gPfo1fz8AAAAAx66gPfo1fz8AAAAAx66gPfo1fz8AAAAAx66gPfo1fz8AAAAAaHLWPIvpfz8AAAAAaHLWPIvpfz8AAAAAaHLWPIvpfz8AAAAAaHLWPIvpfz8AAAAAaHLWPIvpfz8AAAAAaHLWPIvpfz8AAAAAaHLWvIvpfz8AAAAAaHLWvIvpfz8AAAAAaHLWvIvpfz8AAAAAaHLWvIvpfz8AAAAAaHLWvIvpfz8AAAAAaHLWvIvpfz8AAAAAx66gvfo1fz8AAAAAx66gvfo1fz8AAAAAx66gvfo1fz8AAAAAx66gvfo1fz8AAAAAx66gvfo1fz8AAAAAx66gvfo1fz8AAAAAu6gFvlTPfT8AAAAAu6gFvlTPfT8AAAAAu6gFvlTPfT8AAAAAu6gFvlTPfT8AAAAAu6gFvlTPfT8AAAAAu6gFvlTPfT8AAAAA8ps6vpi2ez8AAAAA8ps6vpi2ez8AAAAA8ps6vpi2ez8AAAAA8ps6vpi2ez8AAAAA8ps6vpi2ez8AAAAA8ps6vpi2ez8AAAAAZwxvvjvteD8AAAAAZwxvvjvteD8AAAAAZwxvvjvteD8AAAAAZwxvvjvteD8AAAAAZwxvvjvteD8AAAAAZwxvvjvteD8AAAAA6kZ3v++DhL4AAAAA6kZ3v++DhL4AAAAA6kZ3v++DhL4AAAAA6kZ3v++DhL4AAACA6kZ3v++DhL4AAACA6kZ3v++DhL4AAACAJNl8P18wIL4AAAAAJNl8P18wIL4AAAAAJNl8P18wIL4AAAAAJNl8P18wIL4AAAAAJNl8P18wIL4AAAAAJNl8P18wIL4AAAAA"}],"accessors":[{"bufferView":0,"componentType":5126,"count":240,"max":[0.572234570980072,1.4460784196853638,0.10000000149011612],"min":[-0.7123466730117798,0,0],"type":"VEC3"},{"bufferView":1,"componentType":5126,"count":240,"max":[0,1],"min":[0,0],"type":"VEC2"},{"bufferView":2,"componentType":5126,"count":240,"max":[0.9876883029937744,0.9996573328971863,1],"min":[-0.9876883029937744,-0.9876883029937744,-1],"type":"VEC3"}],"materials":[{"pbrMetallicRoughness":{"baseColorFactor":[0.015996293361446288,0.13286832154414627,1,1],"metallicFactor":0,"roughnessFactor":1,"baseColorTexture":{"index":0,"texCoord":0}},"alphaMode":"BLEND","name":"HeadingCone"}],"textures":[{"sampler":0,"source":0}],"samplers":[{"magFilter":9729,"minFilter":9729,"wrapS":33071,"wrapT":33071}],"images":[{"mimeType":"image/png","uri":"data:image/png;base64,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"}],"meshes":[{"primitives":[{"mode":4,"attributes":{"POSITION":0,"TEXCOORD_0":1,"NORMAL":2},"material":0}]}]}';
386
+
387
+ // src/utils.ts
388
+ init_define_process();
389
+ function deepMergeState(existing, update) {
390
+ if (update == null) {
391
+ return existing;
392
+ }
393
+ const result = { ...existing };
394
+ for (const key in update) {
395
+ const value = update[key];
396
+ if (value !== void 0 && key !== "accuracyRing" && key !== "heading") {
397
+ result[key] = value;
398
+ }
399
+ }
400
+ if (update.accuracyRing != null) {
401
+ result.accuracyRing = { ...existing.accuracyRing };
402
+ for (const key in update.accuracyRing) {
403
+ const value = update.accuracyRing[key];
404
+ if (value !== void 0) {
405
+ result.accuracyRing[key] = value;
406
+ }
407
+ }
408
+ }
409
+ if (update.heading != null) {
410
+ result.heading = { ...existing.heading };
411
+ for (const key in update.heading) {
412
+ const value = update.heading[key];
413
+ if (value !== void 0) {
414
+ result.heading[key] = value;
415
+ }
416
+ }
417
+ }
418
+ return result;
419
+ }
420
+ __name(deepMergeState, "deepMergeState");
421
+ function getPointLineIntersection([startLongitude, startLatitude], [endLongitude, endLatitude], [positionLongitude, positionLatitude]) {
422
+ const dx = endLongitude - startLongitude;
423
+ const dy = endLatitude - startLatitude;
424
+ const segmentLengthSquared = dx ** 2 + dy ** 2;
425
+ if (segmentLengthSquared === 0) {
426
+ return;
427
+ }
428
+ const proportion = ((positionLongitude - startLongitude) * dx + (positionLatitude - startLatitude) * dy) / segmentLengthSquared;
429
+ let intersection;
430
+ if (proportion <= 0) {
431
+ intersection = [startLongitude, startLatitude];
432
+ } else if (proportion >= 1) {
433
+ intersection = [endLongitude, endLatitude];
434
+ } else {
435
+ intersection = [startLongitude + proportion * dx, startLatitude + proportion * dy];
436
+ }
437
+ const distance = haversineDistance([positionLongitude, positionLatitude], intersection);
438
+ return {
439
+ proportion: Math.max(0, Math.min(1, proportion)),
440
+ intersection,
441
+ distance
442
+ };
443
+ }
444
+ __name(getPointLineIntersection, "getPointLineIntersection");
445
+ function findBlueDotOnPath(pathCoordinates, position) {
446
+ if (pathCoordinates == null || pathCoordinates.length < 2) {
447
+ return;
448
+ }
449
+ let minDistance = Number.MAX_SAFE_INTEGER;
450
+ let nearestIntersection;
451
+ let nearestSegmentIndex = 0;
452
+ let nearestProportion = 0;
453
+ for (let i = 0; i < pathCoordinates.length - 1; i++) {
454
+ const start = pathCoordinates[i];
455
+ const end = pathCoordinates[i + 1];
456
+ const pointOnLine = getPointLineIntersection(start, end, position);
457
+ if (pointOnLine == null) continue;
458
+ if (pointOnLine.distance < minDistance) {
459
+ minDistance = pointOnLine.distance;
460
+ nearestIntersection = pointOnLine.intersection;
461
+ nearestSegmentIndex = i;
462
+ nearestProportion = pointOnLine.proportion;
463
+ }
464
+ }
465
+ if (!nearestIntersection) {
466
+ return;
467
+ }
468
+ return {
469
+ intersection: nearestIntersection,
470
+ distance: minDistance,
471
+ segmentIndex: nearestSegmentIndex,
472
+ proportion: nearestProportion
473
+ };
474
+ }
475
+ __name(findBlueDotOnPath, "findBlueDotOnPath");
476
+ function getPositionWithOverrides(update, overrides) {
477
+ if (overrides == null) {
478
+ return update;
479
+ }
480
+ const position = {
481
+ latitude: update?.latitude,
482
+ longitude: update?.longitude,
483
+ accuracy: update?.accuracy,
484
+ floor: update?.floor,
485
+ heading: update?.heading,
486
+ timestamp: update?.timestamp
487
+ };
488
+ if ("latitude" in overrides) {
489
+ position.latitude = overrides?.latitude == null || overrides.latitude === "device" ? update?.latitude : overrides.latitude;
490
+ }
491
+ if ("longitude" in overrides) {
492
+ position.longitude = overrides.longitude == null || overrides.longitude === "device" ? update?.longitude : overrides.longitude;
493
+ }
494
+ if ("accuracy" in overrides) {
495
+ position.accuracy = overrides.accuracy === "device" ? update?.accuracy : overrides.accuracy;
496
+ }
497
+ if ("floor" in overrides) {
498
+ position.floor = overrides.floor === "device" ? update?.floor : overrides.floor;
499
+ }
500
+ if ("heading" in overrides) {
501
+ position.heading = overrides.heading === "device" ? update?.heading : overrides.heading;
502
+ }
503
+ if ("timestamp" in overrides) {
504
+ position.timestamp = overrides.timestamp;
505
+ }
506
+ return position;
507
+ }
508
+ __name(getPositionWithOverrides, "getPositionWithOverrides");
509
+ function isWithinPanBounds({ longitude: positionLongitude, latitude: positionLatitude }, { radius, center }) {
510
+ const distance = haversineDistance([positionLongitude, positionLatitude], [center.longitude, center.latitude]);
511
+ return distance <= radius;
512
+ }
513
+ __name(isWithinPanBounds, "isWithinPanBounds");
514
+ function computeBlueDotScale(radius, metersPerPixel) {
515
+ const scale = radius / (MIN_BLUEDOT_RADIUS / metersPerPixel);
516
+ return Math.max(scale, 1);
517
+ }
518
+ __name(computeBlueDotScale, "computeBlueDotScale");
519
+ function easeOutCubic(t) {
520
+ return 1 - Math.pow(1 - t, 3);
521
+ }
522
+ __name(easeOutCubic, "easeOutCubic");
523
+ function shouldShowHeadingCone(state, heading, displayWhenInactive) {
524
+ return heading != null && (state === "active" || state === "inactive" && displayWhenInactive);
525
+ }
526
+ __name(shouldShowHeadingCone, "shouldShowHeadingCone");
527
+ function shouldShowAccuracyRing(state, accuracy) {
528
+ return state === "active" && accuracy != null;
529
+ }
530
+ __name(shouldShowAccuracyRing, "shouldShowAccuracyRing");
531
+
532
+ // src/model-manager.ts
533
+ var BlueDotModelManager = class {
534
+ static {
535
+ __name(this, "BlueDotModelManager");
536
+ }
537
+ #mapView;
538
+ #blueDot;
539
+ #scale = 1;
540
+ #cachedZoomLevel;
541
+ // animations
542
+ #scaleAnimation;
543
+ #rotationAnimation;
544
+ // models
545
+ dot;
546
+ accuracyRing;
547
+ headingCone;
548
+ constructor(mapView, BlueDot2) {
549
+ this.#mapView = mapView;
550
+ this.#blueDot = BlueDot2;
551
+ this.#mapView.on("camera-change", this.#updateScale);
552
+ }
553
+ add(position) {
554
+ this.remove();
555
+ this.#updateScale({ zoomLevel: this.#mapView.Camera.zoomLevel });
556
+ const coordinate = new Coordinate({
557
+ latitude: position.latitude,
558
+ longitude: position.longitude
559
+ });
560
+ this.accuracyRing = this.#mapView.Models.add(coordinate, accuracy_ring_default, {
561
+ visible: false,
562
+ scale: position.accuracy ?? 0,
563
+ rotation: [0, 0, 0],
564
+ color: this.options.accuracyRing.color,
565
+ opacity: this.options.accuracyRing.opacity,
566
+ visibleThroughGeometry: true
567
+ });
568
+ this.headingCone = this.#mapView.Models.add(coordinate, heading_cone_default, {
569
+ visible: false,
570
+ scale: this.#scale,
571
+ rotation: [0, 0, 0],
572
+ color: this.#blueDot.status === "inactive" ? this.options.inactiveColor : this.options.heading.color,
573
+ opacity: this.options.heading.opacity,
574
+ visibleThroughGeometry: true
575
+ });
576
+ this.dot = this.#mapView.Models.add(coordinate, blue_dot_default, {
577
+ visible: false,
578
+ scale: this.#scale,
579
+ rotation: [0, 0, 0],
580
+ interactive: true,
581
+ visibleThroughGeometry: true,
582
+ material: {
583
+ Inner: {
584
+ color: this.#blueDot.status === "inactive" ? this.options.inactiveColor : this.options.color
585
+ }
586
+ }
587
+ });
588
+ }
589
+ get options() {
590
+ return this.#blueDot.getState();
591
+ }
592
+ getPosition() {
593
+ if (this.dot == null) {
594
+ return void 0;
595
+ }
596
+ return this.#mapView.getState(this.dot).position;
597
+ }
598
+ setPosition(value) {
599
+ if (this.dot == null) {
600
+ return;
601
+ }
602
+ if (this.dot) {
603
+ this.#mapView.updateState(this.dot, { visible: true, position: value });
604
+ }
605
+ if (this.accuracyRing) {
606
+ this.#mapView.updateState(this.accuracyRing, { position: value });
607
+ }
608
+ if (this.headingCone) {
609
+ this.#mapView.updateState(this.headingCone, { position: value });
610
+ }
611
+ }
612
+ #accuracy;
613
+ setAccuracy(value) {
614
+ if (this.accuracyRing == null) {
615
+ return;
616
+ }
617
+ this.#accuracy = value;
618
+ const accuracyRingState = this.#mapView.getState(this.accuracyRing);
619
+ if (accuracyRingState == null) {
620
+ return;
621
+ }
622
+ if (value != null) {
623
+ this.#mapView.updateState(this.accuracyRing, {
624
+ visible: shouldShowAccuracyRing(this.#blueDot.status, this.#accuracy)
625
+ });
626
+ if (this.#scaleAnimation) {
627
+ this.#scaleAnimation.stop();
628
+ }
629
+ this.#mapView.tween({ scale: accuracyRingState.scale[0] }).to({ scale: value / 2 }, SCALE_ANIMATION_DURATION).onUpdate(({ scale }) => {
630
+ if (this.accuracyRing == null) {
631
+ return;
632
+ }
633
+ this.#mapView.updateState(this.accuracyRing, {
634
+ scale: [scale, scale, 1]
635
+ });
636
+ }).start();
637
+ } else {
638
+ this.#mapView.updateState(this.accuracyRing, {
639
+ visible: false
640
+ });
641
+ }
642
+ }
643
+ #heading;
644
+ setHeading(value) {
645
+ if (this.headingCone == null) {
646
+ return;
647
+ }
648
+ this.#heading = value;
649
+ const headingConeState = this.#mapView.getState(this.headingCone);
650
+ if (headingConeState == null) {
651
+ return;
652
+ }
653
+ if (value != null) {
654
+ this.#mapView.updateState(this.headingCone, {
655
+ visible: shouldShowHeadingCone(this.#blueDot.status, this.#heading, this.options.heading.displayWhenInactive)
656
+ });
657
+ if (this.#rotationAnimation) {
658
+ this.#rotationAnimation.stop();
659
+ }
660
+ const currentZRad = headingConeState.rotation[2] != null ? toRadians(headingConeState.rotation[2]) : 0;
661
+ const targetZRad = -toRadians(value);
662
+ const { start, end } = shortestTweenRotation(currentZRad, targetZRad);
663
+ this.#rotationAnimation = this.#mapView.tween({ rotation: toDegrees(start) }).to({ rotation: toDegrees(end) }, ROTATION_ANIMATION_DURATION).onUpdate(({ rotation }) => {
664
+ if (this.headingCone == null) {
665
+ return;
666
+ }
667
+ this.#mapView.updateState(this.headingCone, {
668
+ // updateState expects degrees; preserve base X/Y and apply absolute Z in degrees
669
+ rotation: [0, 0, rotation]
670
+ });
671
+ }).start();
672
+ } else {
673
+ this.#mapView.updateState(this.headingCone, {
674
+ visible: false
675
+ });
676
+ }
677
+ }
678
+ setAltitude(value) {
679
+ if (this.dot == null) {
680
+ return;
681
+ }
682
+ const update = {
683
+ verticalOffset: value
684
+ };
685
+ this.#mapView.updateState(this.dot, update);
686
+ if (this.accuracyRing) {
687
+ this.#mapView.updateState(this.accuracyRing, update);
688
+ }
689
+ if (this.headingCone) {
690
+ this.#mapView.updateState(this.headingCone, update);
691
+ }
692
+ }
693
+ /**
694
+ * Updates appearance of the BlueDot models based on a given status.
695
+ */
696
+ updateAppearance() {
697
+ switch (this.#blueDot.status) {
698
+ case "hidden":
699
+ case "disabled":
700
+ if (this.dot) {
701
+ this.#mapView.updateState(this.dot, {
702
+ visible: false
703
+ });
704
+ }
705
+ if (this.accuracyRing) {
706
+ this.#mapView.updateState(this.accuracyRing, {
707
+ visible: false
708
+ });
709
+ }
710
+ if (this.headingCone) {
711
+ this.#mapView.updateState(this.headingCone, {
712
+ visible: false
713
+ });
714
+ }
715
+ break;
716
+ case "active":
717
+ case "inactive":
718
+ if (this.dot) {
719
+ this.#mapView.updateState(this.dot, {
720
+ visible: true,
721
+ material: {
722
+ Inner: {
723
+ color: this.#blueDot.status === "active" ? this.options.color : this.options.inactiveColor
724
+ }
725
+ }
726
+ });
727
+ }
728
+ if (this.accuracyRing) {
729
+ this.#mapView.updateState(this.accuracyRing, {
730
+ visible: shouldShowAccuracyRing(this.#blueDot.status, this.#accuracy)
731
+ // Is there a use case where we ever want an inactive color accuracy ring?
732
+ // color: state === 'active' ? this.#options.accuracyRing.color : this.#options.inactiveColor,
733
+ });
734
+ }
735
+ if (this.headingCone) {
736
+ this.#mapView.updateState(this.headingCone, {
737
+ visible: shouldShowHeadingCone(
738
+ this.#blueDot.status,
739
+ this.#heading,
740
+ this.options.heading.displayWhenInactive
741
+ ),
742
+ color: this.#blueDot.status === "active" ? this.options.heading.color : this.options.inactiveColor
743
+ });
744
+ }
745
+ break;
746
+ }
747
+ }
748
+ remove() {
749
+ if (this.dot) {
750
+ this.#mapView.Models.remove(this.dot);
751
+ this.dot = void 0;
752
+ }
753
+ if (this.accuracyRing) {
754
+ this.#mapView.Models.remove(this.accuracyRing);
755
+ this.accuracyRing = void 0;
756
+ }
757
+ if (this.headingCone) {
758
+ this.#mapView.Models.remove(this.headingCone);
759
+ this.headingCone = void 0;
760
+ }
761
+ }
762
+ destroy() {
763
+ this.remove();
764
+ this.#mapView.off("camera-change", this.#updateScale);
765
+ }
766
+ #updateScale = /* @__PURE__ */ __name(({ zoomLevel }) => {
767
+ const currentZoomLevel = Math.round(zoomLevel * 1e5);
768
+ if (currentZoomLevel !== this.#cachedZoomLevel) {
769
+ this.#cachedZoomLevel = currentZoomLevel;
770
+ const metersPerPixel = this.#mapView.getMetersPerPixel();
771
+ this.#scale = computeBlueDotScale(this.options.radius, metersPerPixel);
772
+ if (this.dot) {
773
+ this.#mapView.updateState(this.dot, {
774
+ scale: [this.#scale, this.#scale, this.#scale]
775
+ });
776
+ }
777
+ if (this.headingCone) {
778
+ this.#mapView.updateState(this.headingCone, {
779
+ scale: [this.#scale, this.#scale, 1]
780
+ });
781
+ }
782
+ }
783
+ }, "#updateScale");
784
+ };
785
+
786
+ // src/schemas.ts
787
+ init_define_process();
788
+ import z from "zod";
789
+ var geolocationPositionSchema = z.object({
790
+ coords: z.object({
791
+ latitude: z.number(),
792
+ longitude: z.number(),
793
+ accuracy: z.number(),
794
+ altitude: z.number().optional().nullable(),
795
+ altitudeAccuracy: z.number().optional().nullable(),
796
+ heading: z.number().optional().nullable(),
797
+ speed: z.number().optional().nullable(),
798
+ floorLevel: z.number().optional().nullable()
799
+ }),
800
+ timestamp: z.number()
801
+ });
802
+ var positionSchema = z.object({
803
+ latitude: z.number(),
804
+ longitude: z.number(),
805
+ floor: z.any().optional(),
806
+ accuracy: z.number().optional(),
807
+ heading: z.number().optional().nullable(),
808
+ // heading can be nullable due to the Geolocation API
809
+ timestamp: z.number().optional()
810
+ });
811
+
812
+ // src/state-machine.ts
813
+ init_define_process();
814
+ var stateMachine = {
815
+ hidden: {
816
+ actions: {
817
+ enable: "hidden",
818
+ error: "hidden",
819
+ "position-update": "active",
820
+ initialize: "inactive",
821
+ disable: "disabled",
822
+ timeout: "hidden"
823
+ }
824
+ },
825
+ active: {
826
+ actions: {
827
+ enable: "active",
828
+ disable: "disabled",
829
+ "position-update": "active",
830
+ error: "inactive",
831
+ timeout: "inactive"
832
+ }
833
+ },
834
+ inactive: {
835
+ actions: {
836
+ enable: "inactive",
837
+ disable: "disabled",
838
+ "position-update": "active",
839
+ error: "inactive",
840
+ timeout: "inactive"
841
+ }
842
+ },
843
+ disabled: {
844
+ actions: {
845
+ enable: "hidden",
846
+ disable: "disabled"
847
+ }
848
+ }
849
+ };
850
+
851
+ // src/blue-dot.ts
852
+ var BlueDot = class {
853
+ static {
854
+ __name(this, "BlueDot");
855
+ }
856
+ #pubsub = new PubSub();
857
+ #mapView;
858
+ #mapData;
859
+ #watcherId;
860
+ /**
861
+ * The latest position received from the device's geolocation API.
862
+ */
863
+ #currentGeolocation;
864
+ /** The latest position manually set by the user. */
865
+ #overridePosition;
866
+ /** The latest actual position of the Blue Dot. */
867
+ #lastPosition;
868
+ #timer;
869
+ #positionAnimation;
870
+ #options = DEFAULT_BLUEDOT_OPTIONS;
871
+ #cachedCoordinate;
872
+ #status = "disabled";
873
+ #following = false;
874
+ #blueDotModel;
875
+ #currentFloor;
876
+ #lastFloorAltitude;
877
+ #floorTransitionStartTime;
878
+ #floorTransitionStartAltitude;
879
+ #floorTransitionDuration = 1e3;
880
+ /**
881
+ * Create a new {@link BlueDot} instance.
882
+ */
883
+ constructor(mapView) {
884
+ this.#mapView = mapView;
885
+ this.#mapData = mapView.getMapData();
886
+ this.#mapView.on("pre-render", this.#syncVerticalOffset);
887
+ this.#mapView.on("click", this.#handleClick);
888
+ this.#mapView.on("hover", this.#handleHover);
889
+ this.#blueDotModel = new BlueDotModelManager(mapView, this);
890
+ }
891
+ /**
892
+ * Get the Model for the BlueDot core element.
893
+ */
894
+ get dotModel() {
895
+ return this.#blueDotModel.dot;
896
+ }
897
+ /**
898
+ * Get the Model for the accuracy ring.
899
+ */
900
+ get accuracyRingModel() {
901
+ return this.#blueDotModel.accuracyRing;
902
+ }
903
+ /**
904
+ * Get the Model for the heading cone.
905
+ */
906
+ get headingConeModel() {
907
+ return this.#blueDotModel.headingCone;
908
+ }
909
+ /**
910
+ * Whether the BlueDot is currently enabled.
911
+ */
912
+ get isEnabled() {
913
+ return this.#status !== "disabled";
914
+ }
915
+ /**
916
+ * The current state of the BlueDot. Can be 'hidden', 'active', 'inactive', or 'disabled'.
917
+ * Listen for state changes using the 'status-change' event.
918
+ *
919
+ * @example
920
+ * mapView.BlueDot.on('status-change', ({ status }) => {
921
+ * if (status === 'active') {
922
+ * // BlueDot is visible and tracking
923
+ * }
924
+ * });
925
+ */
926
+ get status() {
927
+ return this.#status;
928
+ }
929
+ /**
930
+ * Whether the BlueDot is currently following the user (camera follow mode).
931
+ */
932
+ get isFollowing() {
933
+ return this.#following;
934
+ }
935
+ /**
936
+ * The direction the user is facing in degrees from north clockwise.
937
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/GeolocationCoordinates/heading
938
+ */
939
+ get heading() {
940
+ return this.#lastPosition?.heading;
941
+ }
942
+ /**
943
+ * The accuracy of the current position in metres.
944
+ */
945
+ get accuracy() {
946
+ return this.#lastPosition?.accuracy;
947
+ }
948
+ /**
949
+ * The coordinate of the current position.
950
+ */
951
+ get coordinate() {
952
+ if (this.#lastPosition == null) {
953
+ return void 0;
954
+ }
955
+ if (this.#cachedCoordinate == null || this.floor?.id !== this.#cachedCoordinate.floorId || this.#lastPosition.latitude !== this.#cachedCoordinate.latitude || this.#lastPosition.longitude !== this.#cachedCoordinate.longitude) {
956
+ this.#cachedCoordinate = new Coordinate2({
957
+ latitude: this.#lastPosition.latitude,
958
+ longitude: this.#lastPosition.longitude,
959
+ floorId: this.floor?.id
960
+ });
961
+ }
962
+ return this.#cachedCoordinate;
963
+ }
964
+ getState = /* @__PURE__ */ __name(() => {
965
+ return { ...this.#options };
966
+ }, "getState");
967
+ /**
968
+ * The floor the Blue Dot is currently on. If undefined, the Blue Dot will appear on every floor.
969
+ */
970
+ get floor() {
971
+ return this.#lastPosition?.floor;
972
+ }
973
+ /**
974
+ * Enable the Blue Dot. It will be hidden until a position is received either from the browser or by calling {@link BlueDot.update}.
975
+ * @param options - The options to setup the Blue Dot (see {@link BlueDotOptions}).
976
+ *
977
+ * @example Enable with default options
978
+ * mapView.BlueDot.enable();
979
+ *
980
+ * @example Enable with custom color and accuracy ring
981
+ * mapView.BlueDot.enable({ color: '#00ff00', accuracyRing: { color: '#00ff00', opacity: 0.2 } });
982
+ *
983
+ * @see See the [BlueDot Guide](https://developer.mappedin.com/web-sdk/blue-dot) for more information.
984
+ */
985
+ enable = /* @__PURE__ */ __name((options) => {
986
+ this.#options = deepMergeState(this.#options, options);
987
+ this.#transitionAction("enable");
988
+ if (this.#options.initialState === "inactive") {
989
+ this.#transitionAction("initialize");
990
+ }
991
+ this.watchDevicePosition(this.#options.watchDevicePosition);
992
+ }, "enable");
993
+ /**
994
+ * Disable the Blue Dot. It will be hidden and no longer update.
995
+ */
996
+ disable = /* @__PURE__ */ __name(() => {
997
+ this.#blueDotModel.remove();
998
+ if (this.#timer) {
999
+ clearTimeout(this.#timer);
1000
+ this.#timer = void 0;
1001
+ }
1002
+ if (this.#following) {
1003
+ this.#cancelFollow();
1004
+ }
1005
+ this.watchDevicePosition(false);
1006
+ this.#lastPosition = void 0;
1007
+ this.#overridePosition = void 0;
1008
+ this.#currentFloor = void 0;
1009
+ this.#transitionAction("disable");
1010
+ this.#mapView.off("user-interaction-start", this.#cancelFollow);
1011
+ this.#mapView.off("navigation-active-path-change", this.#pathChangeHandler);
1012
+ }, "disable");
1013
+ /**
1014
+ * Subscribe to a BlueDot event.
1015
+ * @param eventName The name of the event to listen for.
1016
+ * @param fn The function to call when the event is emitted.
1017
+ */
1018
+ on = /* @__PURE__ */ __name((eventName, fn) => {
1019
+ this.#pubsub.on(eventName, fn);
1020
+ }, "on");
1021
+ /**
1022
+ * Unsubscribe from a BlueDot event.
1023
+ * @param eventName The name of the event to unsubscribe from.
1024
+ * @param fn The function to unsubscribe from the event.
1025
+ */
1026
+ off = /* @__PURE__ */ __name((eventName, fn) => {
1027
+ this.#pubsub.off(eventName, fn);
1028
+ }, "off");
1029
+ /**
1030
+ * Update the BlueDot state after it has been enabled.
1031
+ * This allows overriding previously set values like colors, and other options.
1032
+ * @param options - The options to update
1033
+ *
1034
+ * @example Update color and accuracy ring
1035
+ * mapView.BlueDot.updateState({
1036
+ * color: '#ff0000',
1037
+ * accuracyRing: { color: '#ff0000', opacity: 0.5 }
1038
+ * });
1039
+ */
1040
+ updateState = /* @__PURE__ */ __name((options) => {
1041
+ const oldWatchDevicePosition = this.#options.watchDevicePosition;
1042
+ this.#options = deepMergeState(this.#options, options);
1043
+ this.#blueDotModel.updateAppearance();
1044
+ if (options.watchDevicePosition != null && options.watchDevicePosition !== oldWatchDevicePosition) {
1045
+ this.watchDevicePosition(options.watchDevicePosition);
1046
+ }
1047
+ if (options.timeout != null && this.#status === "active") {
1048
+ this.#resetActiveTimer();
1049
+ }
1050
+ }, "updateState");
1051
+ #resetActiveTimer = /* @__PURE__ */ __name(() => {
1052
+ if (this.#timer) {
1053
+ clearTimeout(this.#timer);
1054
+ }
1055
+ if (typeof this.#options.timeout === "number" && this.#options.timeout < Infinity) {
1056
+ this.#timer = setTimeout(() => {
1057
+ if (this.#options.debug) {
1058
+ Mappedin_Logger_default.log(`BlueDot: Position timed out after ${this.#options.timeout}ms`);
1059
+ }
1060
+ this.#transitionAction("timeout");
1061
+ }, this.#options.timeout);
1062
+ }
1063
+ }, "#resetActiveTimer");
1064
+ /**
1065
+ * Enable or disable the devices's geolocation listener to automatically position the Blue Dot.
1066
+ * If enabled, the device will request permission to access the user's precise location.
1067
+ * @param watch - Whether to enable or disable the listener.
1068
+ */
1069
+ watchDevicePosition = /* @__PURE__ */ __name((watch) => {
1070
+ if (this.#watcherId) {
1071
+ navigator.geolocation.clearWatch(this.#watcherId);
1072
+ this.#watcherId = void 0;
1073
+ }
1074
+ if (this.#currentGeolocation) {
1075
+ this.#currentGeolocation = void 0;
1076
+ }
1077
+ if (watch) {
1078
+ if (this.#status === "disabled") {
1079
+ Mappedin_Logger_default.warn("BlueDot must be enabled before watching browser position.");
1080
+ return;
1081
+ }
1082
+ this.#watcherId = navigator.geolocation.watchPosition(this.onPositionUpdate, this.onPositionError, {
1083
+ enableHighAccuracy: true
1084
+ });
1085
+ }
1086
+ }, "watchDevicePosition");
1087
+ #setPosition = /* @__PURE__ */ __name((update, options) => {
1088
+ let parsed;
1089
+ try {
1090
+ parsed = positionSchema.parse(getPositionWithOverrides(update, this.#overridePosition));
1091
+ } catch (error) {
1092
+ this.#transitionAction("error");
1093
+ Mappedin_Logger_default.error("BlueDot: Position parse failed", error instanceof z2.ZodError ? error.message : String(error));
1094
+ return;
1095
+ }
1096
+ if (this.#options.debug) {
1097
+ Mappedin_Logger_default.log("BlueDot: Parsed position", parsed);
1098
+ }
1099
+ if (this.#options.preventOutOfBounds) {
1100
+ const { radius, center } = this.#mapView.Camera.bounds;
1101
+ if (radius != null && isFinite(radius) && center != null) {
1102
+ const within = isWithinPanBounds(
1103
+ { longitude: parsed.longitude, latitude: parsed.latitude },
1104
+ { radius, center }
1105
+ );
1106
+ if (!within) {
1107
+ Mappedin_Logger_default.warn(
1108
+ `BlueDot: Position [${parsed.longitude}, ${parsed.latitude}] is outside map bounds. Position update will be discarded.`
1109
+ );
1110
+ return;
1111
+ }
1112
+ }
1113
+ }
1114
+ if (!this.#isAccurateEnough(parsed.accuracy)) {
1115
+ Mappedin_Logger_default.log(
1116
+ `BlueDot: Dropping position update with accuracy ${parsed.accuracy}m (exceeds threshold ${this.#options.accuracyThreshold}m)`
1117
+ );
1118
+ return;
1119
+ }
1120
+ if (!options?.silent) {
1121
+ this.#transitionAction("position-update");
1122
+ } else {
1123
+ this.#blueDotModel.updateAppearance();
1124
+ }
1125
+ if (!this.#shouldUpdateGeometry()) {
1126
+ Mappedin_Logger_default.warn(
1127
+ `BlueDot: Cannot update position because BlueDot state is '${this.#status}'. BlueDot must be enabled first.`
1128
+ );
1129
+ return;
1130
+ }
1131
+ this.#applyPosition(parsed, options);
1132
+ }, "#setPosition");
1133
+ #applyPosition = /* @__PURE__ */ __name((position, options) => {
1134
+ this.#lastPosition = position;
1135
+ if (!options?.silent) {
1136
+ this.#resetActiveTimer();
1137
+ this.#getAnalyticsIfEnabled().updateState({
1138
+ userPosition: {
1139
+ bluedotTimestamp: Date.now(),
1140
+ latitude: position.latitude,
1141
+ longitude: position.longitude,
1142
+ floorLevel: position.floor?.elevation,
1143
+ accuracy: position.accuracy
1144
+ }
1145
+ });
1146
+ }
1147
+ let startPosition;
1148
+ let startWorldAltitude = 0;
1149
+ if (!this.dotModel) {
1150
+ startPosition = [position.longitude, position.latitude, 0];
1151
+ startWorldAltitude = position.floor ? this.#mapView.getState(position.floor)?.altitude ?? 0 : 0;
1152
+ this.#lastFloorAltitude = startWorldAltitude;
1153
+ this.#currentFloor = position.floor;
1154
+ this.#blueDotModel.add(position);
1155
+ } else {
1156
+ const coordinate = this.#blueDotModel.getPosition();
1157
+ startPosition = [coordinate?.longitude ?? 0, coordinate?.latitude ?? 0, coordinate?.verticalOffset ?? 0];
1158
+ }
1159
+ if (this.#positionAnimation) {
1160
+ this.#positionAnimation.stop();
1161
+ this.#positionAnimation = void 0;
1162
+ }
1163
+ const isFloorChange = this.#currentFloor?.id !== position.floor?.id;
1164
+ if (isFloorChange) {
1165
+ this.#floorTransitionStartTime = Date.now();
1166
+ this.#floorTransitionStartAltitude = this.#lastFloorAltitude ?? 0;
1167
+ this.#currentFloor = position.floor;
1168
+ }
1169
+ const to = [position.longitude, position.latitude];
1170
+ const setGeometryPosition = /* @__PURE__ */ __name((newPos) => {
1171
+ const currentAltitude = this.#lastFloorAltitude ?? 0;
1172
+ this.#blueDotModel.setPosition(
1173
+ new Coordinate2({
1174
+ latitude: newPos[1],
1175
+ longitude: newPos[0]
1176
+ })
1177
+ );
1178
+ this.#blueDotModel.setAltitude(currentAltitude);
1179
+ }, "setGeometryPosition");
1180
+ if (options?.animate === false) {
1181
+ setGeometryPosition(to);
1182
+ this.#updateAccuracyRing();
1183
+ this.#updateHeadingCone();
1184
+ } else {
1185
+ const startLatLng = [startPosition[0], startPosition[1]];
1186
+ this.#positionAnimation = this.#mapView.tween({ position: startLatLng }).to({ position: to }, POSITION_ANIMATION_DURATION).easing(ANIMATION_TWEENS["ease-out"]).onUpdate(({ position: position2 }) => {
1187
+ setGeometryPosition(position2);
1188
+ }).onStart(() => {
1189
+ this.#updateAccuracyRing();
1190
+ this.#updateHeadingCone();
1191
+ }).start();
1192
+ }
1193
+ if (!options?.silent) {
1194
+ this.#pubsub.publish("position-update", {
1195
+ floor: this.floor,
1196
+ heading: this.heading,
1197
+ accuracy: this.accuracy,
1198
+ coordinate: this.coordinate
1199
+ });
1200
+ }
1201
+ }, "#applyPosition");
1202
+ #updateAccuracyRing = /* @__PURE__ */ __name(() => {
1203
+ if (this.#status === "active") {
1204
+ this.#blueDotModel.setAccuracy(this.accuracy);
1205
+ } else {
1206
+ this.#blueDotModel.setAccuracy(void 0);
1207
+ }
1208
+ }, "#updateAccuracyRing");
1209
+ #updateHeadingCone = /* @__PURE__ */ __name(() => {
1210
+ const shouldShow = shouldShowHeadingCone(this.#status, this.heading, this.#options.heading.displayWhenInactive);
1211
+ if (this.heading != null && shouldShow) {
1212
+ this.#blueDotModel.setHeading(this.heading);
1213
+ } else {
1214
+ this.#blueDotModel.setHeading(void 0);
1215
+ }
1216
+ }, "#updateHeadingCone");
1217
+ #shouldUpdateGeometry = /* @__PURE__ */ __name(() => {
1218
+ return this.#status !== "hidden" && this.#status !== "disabled";
1219
+ }, "#shouldUpdateGeometry");
1220
+ /**
1221
+ * Manually override some position properties of the Blue Dot.
1222
+ * Accepts a full GeolocationPosition object or a partial {@link BlueDotPositionUpdate} object.
1223
+ * @example Manually set the accuracy and heading
1224
+ * ```ts
1225
+ * api.BlueDot.update({ accuracy: 10, heading: 90 });
1226
+ * ```
1227
+ * @example Reset accuracy and heading to device values
1228
+ * ```ts
1229
+ * api.BlueDot.update({ accuracy: 'device', heading: 'device' });
1230
+ * ```
1231
+ */
1232
+ update = /* @__PURE__ */ __name((position, options) => {
1233
+ if (position == null) {
1234
+ this.#overridePosition = void 0;
1235
+ } else if ("coords" in position) {
1236
+ this.#overridePosition = Object.assign({}, this.#overridePosition, {
1237
+ latitude: position.coords.latitude,
1238
+ longitude: position.coords.longitude,
1239
+ accuracy: position.coords.accuracy,
1240
+ heading: position.coords.heading,
1241
+ floor: this.#getFloorByFloorLevel(position.coords.floorLevel),
1242
+ timestamp: position.timestamp
1243
+ });
1244
+ } else {
1245
+ this.#overridePosition = Object.assign({}, this.#overridePosition, position);
1246
+ if ("floorOrFloorId" in position) {
1247
+ this.#overridePosition.floor = typeof position.floorOrFloorId === "string" && position.floorOrFloorId !== "device" ? this.#getFloorByFloorId(position.floorOrFloorId) : position.floorOrFloorId;
1248
+ }
1249
+ }
1250
+ const hasPosition = this.#overridePosition?.latitude != null && this.#overridePosition?.longitude != null;
1251
+ if (hasPosition || this.#currentGeolocation != null) {
1252
+ this.#setPosition(this.#currentGeolocation, options);
1253
+ }
1254
+ }, "update");
1255
+ #getFloorByFloorId = /* @__PURE__ */ __name((floorId) => {
1256
+ return this.#mapData.getById("floor", floorId);
1257
+ }, "#getFloorByFloorId");
1258
+ #getFloorByFloorLevel = /* @__PURE__ */ __name((floorLevel) => {
1259
+ if (floorLevel == null) {
1260
+ return void 0;
1261
+ }
1262
+ return this.#mapView.currentFloorStack.floors.sort((a, b) => a.elevation - b.elevation).find((f) => f.elevation === floorLevel);
1263
+ }, "#getFloorByFloorLevel");
1264
+ #simplifiedDirections;
1265
+ #positionProcessor;
1266
+ #getSimplifiedDirections = /* @__PURE__ */ __name(() => {
1267
+ if (this.#simplifiedDirections == null && this.#mapView.Navigation.activeDirections != null) {
1268
+ const coordinates = Array.isArray(this.#mapView.Navigation.activeDirections) ? this.#mapView.Navigation.activeDirections.flatMap((d) => d.coordinates) : this.#mapView.Navigation.activeDirections.coordinates;
1269
+ const coordinatesOnMap = coordinates.filter((c) => c.floorId === this.#mapView.currentFloor.id);
1270
+ this.#simplifiedDirections = (0, import_simplify_js.default)(
1271
+ coordinatesOnMap.map((c) => ({ x: c.longitude, y: c.latitude })),
1272
+ 1e-5
1273
+ ).map((p) => [p.x, p.y]);
1274
+ }
1275
+ return this.#simplifiedDirections;
1276
+ }, "#getSimplifiedDirections");
1277
+ #cancelFollow = /* @__PURE__ */ __name(() => {
1278
+ if (this.#mapView.Camera.isAnimating) {
1279
+ this.#mapView.Camera.cancelAnimation();
1280
+ }
1281
+ if (this.#followHandler) {
1282
+ this.off("position-update", this.#followHandler);
1283
+ this.#followHandler = void 0;
1284
+ }
1285
+ this.#following = false;
1286
+ this.#simplifiedDirections = void 0;
1287
+ this.#mapView.off("user-interaction-start", this.#cancelFollow);
1288
+ this.#mapView.off("navigation-active-path-change", this.#pathChangeHandler);
1289
+ this.#pubsub.publish("follow-change", { following: false });
1290
+ }, "#cancelFollow");
1291
+ #pathChangeHandler = /* @__PURE__ */ __name(() => {
1292
+ this.#simplifiedDirections = void 0;
1293
+ }, "#pathChangeHandler");
1294
+ #followHandler;
1295
+ /**
1296
+ * Set the camera to follow the BlueDot in various modes. User interaction will cancel following automatically.
1297
+ * @param mode The follow mode ('position-only', 'position-and-heading', 'position-and-path-direction', or false to disable).
1298
+ * @param cameraOptions Optional camera options (zoom, pitch, etc.).
1299
+ *
1300
+ * @example
1301
+ * mapView.BlueDot.follow('position-and-heading', { zoomLevel: 21, pitch: 45 });
1302
+ */
1303
+ follow = /* @__PURE__ */ __name((mode, cameraOptions) => {
1304
+ if (mode === false) {
1305
+ this.#cancelFollow();
1306
+ return;
1307
+ }
1308
+ if (mode !== "position-only" && cameraOptions?.bearing != null) {
1309
+ Mappedin_Logger_default.warn(
1310
+ `BlueDot: Camera bearing option will be ignored in follow mode '${mode}'. To control the bearing manually, use mode 'position-only'.`
1311
+ );
1312
+ }
1313
+ const cameraTargetWithDefaults = {
1314
+ zoomLevel: cameraOptions?.zoomLevel ?? 21,
1315
+ bearing: mode === "position-only" ? cameraOptions?.bearing : void 0,
1316
+ pitch: cameraOptions?.pitch ?? 45
1317
+ };
1318
+ const cameraOptionsWithDefaults = {
1319
+ duration: cameraOptions?.duration ?? POSITION_ANIMATION_DURATION,
1320
+ easing: cameraOptions?.easing ?? "ease-in-out"
1321
+ };
1322
+ if (this.#following) {
1323
+ if (this.#followHandler) {
1324
+ this.off("position-update", this.#followHandler);
1325
+ }
1326
+ } else {
1327
+ this.#following = true;
1328
+ this.#mapView.on("user-interaction-start", this.#cancelFollow);
1329
+ this.#mapView.on("navigation-active-path-change", this.#pathChangeHandler);
1330
+ }
1331
+ this.#followHandler = (event) => {
1332
+ const { coordinate, heading, floor } = event;
1333
+ cameraTargetWithDefaults.center = coordinate;
1334
+ if (floor != null && floor.id !== this.#mapView.currentFloor.id) {
1335
+ this.#mapView.setFloor(floor.id);
1336
+ this.#simplifiedDirections = void 0;
1337
+ }
1338
+ if (mode === "position-and-heading") {
1339
+ cameraTargetWithDefaults.bearing = heading ?? void 0;
1340
+ } else if (mode === "position-and-path-direction") {
1341
+ const directions = this.#getSimplifiedDirections();
1342
+ if (directions != null) {
1343
+ const intersection = findBlueDotOnPath(directions, [coordinate.longitude, coordinate.latitude]);
1344
+ if (intersection != null) {
1345
+ const segment = directions[intersection.segmentIndex];
1346
+ const endSegment = directions[intersection.segmentIndex + 1];
1347
+ cameraTargetWithDefaults.bearing = getForwardBearing(segment, endSegment);
1348
+ }
1349
+ }
1350
+ }
1351
+ this.#mapView.Camera.animateTo(cameraTargetWithDefaults, cameraOptionsWithDefaults);
1352
+ };
1353
+ this.on("position-update", this.#followHandler);
1354
+ this.#pubsub.publish("follow-change", { following: true, mode });
1355
+ }, "follow");
1356
+ /**
1357
+ * Set a position processor callback that allows intercepting and modifying device/geolocation position updates before they are applied.
1358
+ *
1359
+ * **Note**: This processor only applies to automatic position updates from device geolocation.
1360
+ * Manual position updates via `update()` method bypass the processor and are applied directly.
1361
+ *
1362
+ * @param processor - A callback function that receives current state and incoming update. Return undefined to discard the update, or return a modified update object.
1363
+ *
1364
+ * @example Discard inaccurate positions
1365
+ * ```ts
1366
+ * blueDot.setPositionProcessor((current, incoming) => {
1367
+ * if (incoming.accuracy && incoming.accuracy > 50) {
1368
+ * return undefined; // Discard update
1369
+ * }
1370
+ * return incoming; // Accept update
1371
+ * });
1372
+ * ```
1373
+ *
1374
+ * @example Modify incoming positions
1375
+ * ```ts
1376
+ * blueDot.setPositionProcessor((current, incoming) => {
1377
+ * // Apply custom smoothing or validation logic
1378
+ * return {
1379
+ * ...incoming,
1380
+ * accuracy: Math.min(incoming.accuracy || 100, 10) // Cap accuracy
1381
+ * };
1382
+ * });
1383
+ * ```
1384
+ */
1385
+ setPositionProcessor(processor) {
1386
+ this.#positionProcessor = processor;
1387
+ }
1388
+ /**
1389
+ * Checks if the current accuracy is acceptable for updating the BlueDot position.
1390
+ * @param accuracy The accuracy value to check
1391
+ * @returns true if the accuracy is acceptable, false if it should be dropped
1392
+ */
1393
+ #isAccurateEnough = /* @__PURE__ */ __name((accuracy) => {
1394
+ if (accuracy == null) {
1395
+ return this.#status !== "disabled";
1396
+ }
1397
+ return accuracy <= this.#options.accuracyThreshold;
1398
+ }, "#isAccurateEnough");
1399
+ /**
1400
+ * Process incoming position update through the position processor callback if set.
1401
+ * @param incoming The incoming position update
1402
+ * @returns The processed position update or undefined if discarded
1403
+ */
1404
+ #processIncomingPosition = /* @__PURE__ */ __name((incoming) => {
1405
+ const currentState = {
1406
+ latitude: this.#lastPosition?.latitude,
1407
+ longitude: this.#lastPosition?.longitude,
1408
+ accuracy: this.#lastPosition?.accuracy,
1409
+ heading: this.#lastPosition?.heading,
1410
+ floor: this.#lastPosition?.floor,
1411
+ timestamp: this.#lastPosition?.timestamp
1412
+ };
1413
+ try {
1414
+ return this.#positionProcessor(currentState, incoming);
1415
+ } catch (error) {
1416
+ Mappedin_Logger_default.error(
1417
+ "BlueDot: Position processor callback threw an error",
1418
+ error instanceof Error ? error.message : String(error)
1419
+ );
1420
+ return incoming;
1421
+ }
1422
+ }, "#processIncomingPosition");
1423
+ destroy = /* @__PURE__ */ __name(() => {
1424
+ this.disable();
1425
+ this.#blueDotModel.destroy();
1426
+ this.#mapView.off("pre-render", this.#syncVerticalOffset);
1427
+ this.#mapView.off("click", this.#handleClick);
1428
+ this.#mapView.off("hover", this.#handleHover);
1429
+ this.#pubsub.destroy();
1430
+ }, "destroy");
1431
+ #transitionAction = /* @__PURE__ */ __name((action) => {
1432
+ const nextStatus = stateMachine[this.#status].actions[action];
1433
+ if (nextStatus == null) {
1434
+ Mappedin_Logger_default.warn(`BlueDot: Invalid state transition from ${this.#status} to ${nextStatus} using ${action}`);
1435
+ return;
1436
+ }
1437
+ if (nextStatus === this.#status) {
1438
+ return;
1439
+ }
1440
+ if (this.#options.debug) {
1441
+ Mappedin_Logger_default.log(`BlueDot: Transitioning from ${this.#status} to ${nextStatus} using ${action}`);
1442
+ }
1443
+ this.#status = nextStatus;
1444
+ this.#blueDotModel.updateAppearance();
1445
+ this.#pubsub.publish("status-change", {
1446
+ status: nextStatus,
1447
+ action
1448
+ });
1449
+ }, "#transitionAction");
1450
+ /**
1451
+ * Synchronizes BlueDot vertical offset with current floor altitude on every frame.
1452
+ * Handles smooth floor transitions and real-time altitude tracking.
1453
+ */
1454
+ #syncVerticalOffset = /* @__PURE__ */ __name(() => {
1455
+ if (!this.dotModel || !this.#lastPosition || this.#status === "hidden" || this.#status === "disabled") {
1456
+ return;
1457
+ }
1458
+ const targetFloorAltitude = this.#lastPosition.floor ? this.#mapView.getState(this.#lastPosition.floor)?.altitude ?? 0 : this.#mapView.getState(this.#mapView.currentFloor)?.altitude ?? 0;
1459
+ let currentAltitude = targetFloorAltitude;
1460
+ if (this.#floorTransitionStartTime != null && this.#floorTransitionStartAltitude != null) {
1461
+ const elapsed = Date.now() - this.#floorTransitionStartTime;
1462
+ const progress = Math.min(elapsed / this.#floorTransitionDuration, 1);
1463
+ if (progress < 1) {
1464
+ const easeProgress = easeOutCubic(progress);
1465
+ currentAltitude = this.#floorTransitionStartAltitude + (targetFloorAltitude - this.#floorTransitionStartAltitude) * easeProgress;
1466
+ } else {
1467
+ this.#floorTransitionStartTime = void 0;
1468
+ this.#floorTransitionStartAltitude = void 0;
1469
+ }
1470
+ }
1471
+ if (this.#lastFloorAltitude !== currentAltitude) {
1472
+ this.#lastFloorAltitude = currentAltitude;
1473
+ this.#blueDotModel.setAltitude(currentAltitude);
1474
+ }
1475
+ }, "#syncVerticalOffset");
1476
+ onPositionUpdate = /* @__PURE__ */ __name((position) => {
1477
+ if (this.isEnabled === false) {
1478
+ return;
1479
+ }
1480
+ try {
1481
+ geolocationPositionSchema.parse(position);
1482
+ } catch (error) {
1483
+ this.#transitionAction("error");
1484
+ Mappedin_Logger_default.error(
1485
+ "BlueDot: Browser sent invalid position",
1486
+ error instanceof z2.ZodError ? error.message : String(error)
1487
+ );
1488
+ return;
1489
+ }
1490
+ this.#currentGeolocation = {
1491
+ latitude: position.coords?.latitude,
1492
+ longitude: position.coords?.longitude,
1493
+ accuracy: position.coords?.accuracy,
1494
+ heading: position.coords?.heading,
1495
+ floor: this.#getFloorByFloorLevel(position.coords?.floorLevel),
1496
+ timestamp: position.timestamp
1497
+ // TODO: can we use these in the future ?
1498
+ // altitude: position.coords?.altitude,
1499
+ // altitudeAccuracy: position.coords?.altitudeAccuracy,
1500
+ // speed: position.coords?.speed,
1501
+ };
1502
+ let finalPosition = this.#currentGeolocation;
1503
+ if (this.#positionProcessor) {
1504
+ const processedPosition = this.#processIncomingPosition(this.#currentGeolocation);
1505
+ if (processedPosition === void 0) {
1506
+ if (this.#options.debug) {
1507
+ Mappedin_Logger_default.log("BlueDot: Position update discarded by position processor");
1508
+ }
1509
+ return;
1510
+ }
1511
+ finalPosition = processedPosition;
1512
+ }
1513
+ this.#setPosition(finalPosition);
1514
+ }, "onPositionUpdate");
1515
+ onPositionError = /* @__PURE__ */ __name((error) => {
1516
+ this.#transitionAction("error");
1517
+ switch (error.code) {
1518
+ case error.PERMISSION_DENIED:
1519
+ Mappedin_Logger_default.error("Geolocation permission denied by the user.", error);
1520
+ this.#getAnalyticsIfEnabled().sendWatchPositionDenied();
1521
+ break;
1522
+ case error.POSITION_UNAVAILABLE:
1523
+ Mappedin_Logger_default.error("Geolocation position unavailable.", error);
1524
+ break;
1525
+ case error.TIMEOUT:
1526
+ Mappedin_Logger_default.error("Geolocation request timed out.", error);
1527
+ break;
1528
+ default:
1529
+ Mappedin_Logger_default.error("An unknown geolocation error occurred.", error);
1530
+ break;
1531
+ }
1532
+ this.#pubsub.publish("error", error);
1533
+ }, "onPositionError");
1534
+ #getAnalyticsIfEnabled = /* @__PURE__ */ __name(() => {
1535
+ return !this.#options.preventOutOfBounds ? { sendWatchPositionDenied: /* @__PURE__ */ __name(() => {
1536
+ }, "sendWatchPositionDenied"), updateState: /* @__PURE__ */ __name(() => {
1537
+ }, "updateState") } : this.#mapData.internal.Analytics;
1538
+ }, "#getAnalyticsIfEnabled");
1539
+ #handleClickOrHover = /* @__PURE__ */ __name((type) => (event) => {
1540
+ if (event.models == null || event.models.length === 0 || this.dotModel == null) {
1541
+ return;
1542
+ }
1543
+ const dotModel = event.models.find((m) => m.id === this.dotModel?.id);
1544
+ if (dotModel == null) {
1545
+ return;
1546
+ }
1547
+ this.#pubsub.publish(type, {
1548
+ coordinate: event.coordinate
1549
+ });
1550
+ }, "#handleClickOrHover");
1551
+ #handleClick = this.#handleClickOrHover("click");
1552
+ #handleHover = this.#handleClickOrHover("hover");
1553
+ };
1554
+
1555
+ export {
1556
+ __name,
1557
+ init_define_process,
1558
+ BlueDot
1559
+ };
1560
+ //# sourceMappingURL=chunk-TPJ6NPMJ.js.map