@expofp/floorplan 0.0.0-experimental.2632d13 → 0.0.0-experimental.6f27bb7

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.
Files changed (28) hide show
  1. package/dist/browser/{GpsLoader-DwNSQv4V.js → GpsLoader-BrvSPc8H.js} +3 -3
  2. package/dist/browser/{KioskStore-DgP9k2lT.js → KioskStore-BJ4bqapB.js} +3 -3
  3. package/dist/browser/{LayerStore-DCwl80sb.js → LayerStore-C4GTDPHD.js} +1 -1
  4. package/dist/browser/{MaplibreAdapter-B-c-uOJf.js → MaplibreAdapter-LT3aYdKq.js} +55 -56
  5. package/dist/browser/{RouteStore-CuslHjhJ.js → RouteStore-BdR5neK3.js} +1548 -740
  6. package/dist/browser/{SetKioskMode-CVD7sZLr.js → SetKioskMode-DAr5HygV.js} +2 -2
  7. package/dist/browser/{ShowKiosk-DuOS8tTO.js → ShowKiosk-D69MzGn1.js} +2 -2
  8. package/dist/browser/{ViewerMenuPanel-Xj-8aVzf.js → ViewerMenuPanel-YKHGRQD6.js} +2 -2
  9. package/dist/browser/bundle.json +22 -25
  10. package/dist/browser/{components-D8dv3ezN.js → components-CKKQ_xN7.js} +714 -714
  11. package/dist/browser/{create-live-plan-Ff4MkKcG.js → create-live-plan-RDVxhQNb.js} +385 -724
  12. package/dist/browser/{floorplan.loader-fOvLfGGf.js → floorplan.loader-BpPAaf2G.js} +3 -3
  13. package/dist/browser/{floorplan.ready-Bvj8hVzH.js → floorplan.ready-ewj3L_Nf.js} +48 -48
  14. package/dist/browser/index.js +5 -5
  15. package/dist/browser/{venue-public-CH7uq9Xn.js → init-ui-J0bwWoYp.js} +5 -15
  16. package/dist/browser/{integrateKiosk-DhdxcN-Y.js → integrateKiosk-C3Y0PTW1.js} +1 -1
  17. package/dist/browser/{journey-plan-cw-9rqLk.js → journey-plan-CXmXiYcU.js} +14 -14
  18. package/dist/browser/{kiosk-mode-Bqv2L5PO.js → kiosk-mode-DaPbSm7O.js} +1 -1
  19. package/dist/browser/{kioskUrlParam-dw9tDQ6e.js → kioskUrlParam-BvyzbPxz.js} +1 -1
  20. package/dist/browser/{logDeviceInfo-D2Anqc6y.js → logDeviceInfo-BVFtT7aX.js} +3 -3
  21. package/dist/browser/{debounce-B4PlcNh4.js → venue-selection-BaGA9szA.js} +6 -16
  22. package/dist/browser/{viewport-juWifKNy.js → viewport-DVZ47XEo.js} +1 -1
  23. package/dist/esm/store/RouteStore.d.ts +10 -0
  24. package/dist/esm/store/RouteStore.js +39 -15
  25. package/dist/esm/store/VenueStore.d.ts +7 -0
  26. package/dist/esm/store/VenueStore.js +9 -0
  27. package/package.json +10 -10
  28. package/dist/browser/venues-Yq0wU18A.js +0 -447
@@ -18,6 +18,7 @@ import store, { layersStore, uiState } from '.';
18
18
  import { BoothBase } from './BoothStore';
19
19
  import { LayersMode } from './LayerStore';
20
20
  import { revealLayer } from './reveal-layer.js';
21
+ import { venueLevelForFix } from './VenueStore.js';
21
22
  /** A coordinate as the SDK may deliver it — `1.5`, or `"1,5"` from a comma locale. */
22
23
  function replaceCommasWithDot(value) {
23
24
  if (typeof value === 'string') {
@@ -107,9 +108,14 @@ export default class RouteStore {
107
108
  return;
108
109
  if (destinationReady) {
109
110
  void destinationReady.then(() => {
110
- if (selectRouteRequest === this.selectRouteRequest) {
111
- this.rootStore.moveToList(list, true);
112
- }
111
+ if (selectRouteRequest !== this.selectRouteRequest)
112
+ return;
113
+ // A route the engine has already drawn framed itself as it did (`onRouteUpdate`), and
114
+ // this focus, held back for the destination's level, would land after that fit and
115
+ // pull the camera onto the listed booths — from the blue dot, the destination alone.
116
+ if (this.routedRoute === route && this.routeLines.length)
117
+ return;
118
+ this.rootStore.moveToList(list, true);
113
119
  });
114
120
  }
115
121
  else {
@@ -172,6 +178,23 @@ export default class RouteStore {
172
178
  ?.filter((name, i, self) => self.indexOf(name) === i);
173
179
  return routeSteps(layers ?? [], this.campusLayersBox.get(), (name) => Boolean(store.layerStore.findLayer(name))).map((name, i) => ({ id: i + 1, layer: store.layerStore.findLayer(name) }));
174
180
  }
181
+ /**
182
+ * The floor a plan point stands on — a position fix, or a coordinate route endpoint. Floors
183
+ * belong to venues, so on a venue-model plan the outline the point lies in decides: outdoors it
184
+ * stands on none, whatever floor it reports; inside a venue it keeps the reported floor only when
185
+ * that floor is one of the venue's own levels, and otherwise takes the venue's
186
+ * (`venueLevelForFix`). Another hall's floor would scope the point to that hall — read as off a
187
+ * route right under it, and start a route "from here" at that hall's nearest walkway. Off a
188
+ * venue model the reported floor stands as is.
189
+ */
190
+ pointLayer(point, z) {
191
+ const reported = this.rootStore.layerStore.findLayer(z);
192
+ const venueStore = this.rootStore.venueStore;
193
+ if (!venueStore?.hasVenueModel)
194
+ return reported;
195
+ const venue = venueStore.venueAt(point);
196
+ return venue ? venueLevelForFix(venue, reported?.name).layer : null;
197
+ }
175
198
  /**
176
199
  * Used only by the SDK `getBooth(RouteWaypoint)` path for coord-form
177
200
  * waypoints (`floorplan.ready.tsx`). Internal callers prefer
@@ -181,7 +204,6 @@ export default class RouteStore {
181
204
  getNearestBooth(position) {
182
205
  if (!position)
183
206
  return null;
184
- const layerExists = this.rootStore.layerStore.findLayer(position.z);
185
207
  const gpsConfig = getFpGeo()?.properties.config;
186
208
  const isGpsFix = Boolean(position.lat && position.lng);
187
209
  const localPoint = gpsConfig && isGpsFix ? convertGpsToLocal(position, gpsConfig) : position;
@@ -190,15 +212,17 @@ export default class RouteStore {
190
212
  if (!localPoint || !isValidPointCoords(localPoint.x) || !isValidPointCoords(localPoint.y)) {
191
213
  return null;
192
214
  }
215
+ const layer = this.pointLayer(localPoint, position.z);
216
+ // Off a venue model an empty `z` can still match a layer by name, and such a floorless fix keeps
217
+ // every visible booth in play, as before; on one, the floor `pointLayer` decided is the answer.
218
+ const floorless = !this.rootStore.venueStore?.hasVenueModel && typeof position.z !== 'number' && !position.z;
193
219
  return (this.rootStore.boothStore.booths
194
220
  .filter((b) => {
195
- if (layersStore.mode === LayersMode.Default || !layerExists) {
221
+ if (this.rootStore.layerStore.mode === LayersMode.Default || !layer) {
196
222
  return b.visible && b.rect;
197
223
  }
198
224
  else {
199
- return (b.rect &&
200
- ((typeof position.z !== 'number' && !position.z && b.visible) ||
201
- layerExists.name === b.layer?.name));
225
+ return b.rect && ((floorless && b.visible) || layer.name === b.layer?.name);
202
226
  }
203
227
  })
204
228
  .sort((b1, b2) => pointDistance(localPoint, b1.rect.center) - pointDistance(localPoint, b2.rect.center))[0] || null);
@@ -292,13 +316,13 @@ export default class RouteStore {
292
316
  this.currentPosition = null;
293
317
  return;
294
318
  }
295
- // Floors belong to venues: a fix outside every venue outline stands on none, whatever floor it
296
- // reports and whichever floor the route is on. A floor it is not on would scope it to that
297
- // hall — read as off a route that is right under it, and start a route from inside the hall.
298
- const venueStore = this.rootStore.venueStore;
299
- const outdoors = !!venueStore?.hasVenueModel && !venueStore.venueAt(position);
300
- const layer = outdoors ? null : store.layerStore.findLayer(point.z);
301
- const newPosition = new CurrentPosition(position.x, position.y, outdoors ? undefined : layer?.name || this.currentRouteLayer?.name, calculateRelativeBearing(position), point.lat, point.lng);
319
+ const layer = this.pointLayer(position, point.z);
320
+ // Off a venue model, a fix without a floor takes the route's; on one, `pointLayer` has
321
+ // already decided — no floor outdoors, the venue's own inside an outline.
322
+ const routeLayerFallback = this.rootStore.venueStore?.hasVenueModel
323
+ ? undefined
324
+ : this.currentRouteLayer?.name;
325
+ const newPosition = new CurrentPosition(position.x, position.y, layer?.name || routeLayerFallback, calculateRelativeBearing(position), point.lat, point.lng);
302
326
  let isPositionAndRouteOnTheSameLayer = !this.routeLines?.length;
303
327
  if (layer && this.routeLines?.length) {
304
328
  isPositionAndRouteOnTheSameLayer = !!this.routeLines.find((line) => line.p0.layer === layer.name || line.p1.layer === layer.name);
@@ -94,6 +94,13 @@ export declare class Venue {
94
94
  /** Full floor detail currently visible (R6); unevaluated counts as visible. */
95
95
  get detailVisible(): boolean;
96
96
  }
97
+ /**
98
+ * The level of `venue` that a position fix inside it stands on: the reported floor when it is one
99
+ * of the venue's own levels, otherwise the level the venue shows. The outline a fix lies in names
100
+ * its venue beyond doubt; the floor it reports can be wrong — a positioning system may carry an
101
+ * indoor floor over onto later GPS fixes, or number the floors its own way.
102
+ */
103
+ export declare function venueLevelForFix(venue: Pick<Venue, 'levels' | 'activeLevel'>, reportedLayerName: string | undefined): VenueLevel;
97
104
  /**
98
105
  * Owns the venue model of a multi-venue plan: the venue list, viewport focus,
99
106
  * and each venue's active level. Levels stay owned by LayerStore; a venue
@@ -89,6 +89,15 @@ export class Venue {
89
89
  return this._presentationState.get()?.detailVisible ?? true;
90
90
  }
91
91
  }
92
+ /**
93
+ * The level of `venue` that a position fix inside it stands on: the reported floor when it is one
94
+ * of the venue's own levels, otherwise the level the venue shows. The outline a fix lies in names
95
+ * its venue beyond doubt; the floor it reports can be wrong — a positioning system may carry an
96
+ * indoor floor over onto later GPS fixes, or number the floors its own way.
97
+ */
98
+ export function venueLevelForFix(venue, reportedLayerName) {
99
+ return venue.levels.find((level) => level.layer.name === reportedLayerName) ?? venue.activeLevel;
100
+ }
92
101
  /**
93
102
  * Owns the venue model of a multi-venue plan: the venue list, viewport focus,
94
103
  * and each venue's active level. Levels stay owned by LayerStore; a venue
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@expofp/floorplan",
3
- "version": "0.0.0-experimental.2632d13",
3
+ "version": "0.0.0-experimental.6f27bb7",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/expofp/efp-app.git",
@@ -69,15 +69,15 @@
69
69
  "tslib": "^2.3.0",
70
70
  "uuid": "^9.0.1",
71
71
  "zod": "4.4.3",
72
- "@expofp/config": "0.0.0-experimental.2632d13",
73
- "@expofp/debug": "0.0.0-experimental.2632d13",
74
- "@expofp/geometry": "0.0.0-experimental.2632d13",
75
- "@expofp/renderer": "0.0.0-experimental.2632d13",
76
- "@expofp/resolve": "0.0.0-experimental.2632d13",
77
- "@expofp/schema": "0.0.0-experimental.2632d13",
78
- "@expofp/ui": "0.0.0-experimental.2632d13",
79
- "@expofp/utils": "0.0.0-experimental.2632d13",
80
- "@expofp/wayfinding": "0.0.0-experimental.2632d13"
72
+ "@expofp/config": "0.0.0-experimental.6f27bb7",
73
+ "@expofp/debug": "0.0.0-experimental.6f27bb7",
74
+ "@expofp/geometry": "0.0.0-experimental.6f27bb7",
75
+ "@expofp/renderer": "0.0.0-experimental.6f27bb7",
76
+ "@expofp/resolve": "0.0.0-experimental.6f27bb7",
77
+ "@expofp/schema": "0.0.0-experimental.6f27bb7",
78
+ "@expofp/ui": "0.0.0-experimental.6f27bb7",
79
+ "@expofp/utils": "0.0.0-experimental.6f27bb7",
80
+ "@expofp/wayfinding": "0.0.0-experimental.6f27bb7"
81
81
  },
82
82
  "devDependencies": {
83
83
  "@babel/plugin-proposal-decorators": "^8.0.2",
@@ -1,447 +0,0 @@
1
- (function() {
2
- try {
3
- var e = typeof window < "u" ? window : typeof global < "u" ? global : typeof globalThis < "u" ? globalThis : typeof self < "u" ? self : {};
4
- e.SENTRY_RELEASE = { id: "3.45.6" };
5
- var t = new e.Error().stack;
6
- t && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[t] = "5f4c3e09-f59c-417b-b628-a47d62512eb3", e._sentryDebugIdIdentifier = "sentry-dbid-5f4c3e09-f59c-417b-b628-a47d62512eb3");
7
- } catch {}
8
- })();
9
- import { _n as e, gn as t, mn as n, un as r } from "./LayerStore-DCwl80sb.js";
10
- //#region src/data/venues.ts
11
- var i = /^[a-z0-9_-]+$/, a = ["scene", "marker"], o = 11, s = 10;
12
- function c(e, t) {
13
- return e * s >= t * o;
14
- }
15
- function l(e) {
16
- return e === 60 ? 66 : Math.ceil(e * o / s);
17
- }
18
- var u = /* @__PURE__ */ new Set([
19
- "id",
20
- "name",
21
- "order",
22
- "levels",
23
- "contour",
24
- "markerPoint",
25
- "detailMinSizePx",
26
- "markerMaxSizePx",
27
- "layers",
28
- "entrances",
29
- "campusViewbox"
30
- ]), d = /* @__PURE__ */ new Set([
31
- "layer",
32
- "ordinal",
33
- "name",
34
- "initial"
35
- ]), f = /* @__PURE__ */ new Set([
36
- "layer",
37
- "point",
38
- "name"
39
- ]), p = /* @__PURE__ */ new Set([
40
- "layer",
41
- "render",
42
- "replacesDefault",
43
- "suppressesLabel",
44
- "minSizePx",
45
- "maxSizePx"
46
- ]), m = (e, t) => e < t ? -1 : +(e > t), h = (e) => typeof e == "object" && !!e && !Array.isArray(e), g = (e) => typeof e == "number" && Number.isFinite(e), _ = (e) => typeof e == "string" && e.length > 0, v = (e) => h(e) && g(e.x) && g(e.y), y = (e) => h(e) && g(e.x) && g(e.y) && g(e.width) && g(e.height) && e.width > 0 && e.height > 0;
47
- function b(e) {
48
- try {
49
- let t = JSON.stringify(e);
50
- return t === void 0 ? String(e) : t;
51
- } catch {
52
- return String(e);
53
- }
54
- }
55
- function x(e) {
56
- for (let t of e) try {
57
- console.warn("parseVenues:", `${t.code} (${t.effect}) ${t.path || "(root)"}: ${t.message}; ${t.consequence}`);
58
- } catch {}
59
- }
60
- function S(e, t, n, r = null) {
61
- return x(t), {
62
- venues: e,
63
- diagnostics: t,
64
- quarantinedLayerNames: n,
65
- campusViewbox: r
66
- };
67
- }
68
- function C(e, t, n, r) {
69
- let i = (e, t, n) => (t.x - e.x) * (n.y - e.y) - (t.y - e.y) * (n.x - e.x), a = i(n, r, e), o = i(n, r, t), s = i(e, t, n), c = i(e, t, r);
70
- if ((a > 0 && o < 0 || a < 0 && o > 0) && (s > 0 && c < 0 || s < 0 && c > 0)) return !0;
71
- let l = (e, t, n) => Math.min(e.x, t.x) <= n.x && n.x <= Math.max(e.x, t.x) && Math.min(e.y, t.y) <= n.y && n.y <= Math.max(e.y, t.y);
72
- return a === 0 && l(n, r, e) || o === 0 && l(n, r, t) || s === 0 && l(e, t, n) || c === 0 && l(e, t, r);
73
- }
74
- function w(e) {
75
- if (!Array.isArray(e)) return { issue: "is not an array" };
76
- if (e.length < 3) return { issue: `has ${e.length} point(s); a ring needs at least 3` };
77
- if (!e.every(v)) return { issue: "contains a non-finite or malformed point" };
78
- let t = e.map((e) => ({
79
- x: e.x,
80
- y: e.y
81
- })), n = t[0], i = t[t.length - 1];
82
- if (n.x === i.x && n.y === i.y && t.pop(), t.length < 3) return { issue: `has ${t.length} point(s); a ring needs at least 3` };
83
- let { width: a, height: o } = r.fromPoints(t).size;
84
- if (a === 0 || o === 0) return { issue: "is degenerate (zero width or height)" };
85
- for (let e = 0; e < t.length; e++) {
86
- let n = t[e], r = t[(e + 1) % t.length];
87
- for (let i = e + 1; i < t.length; i++) if (!(i === e || (i + 1) % t.length === e || (e + 1) % t.length === i) && C(n, r, t[i], t[(i + 1) % t.length])) return { issue: "is self-intersecting; v1 accepts one simple ring only (no holes, no multi-part)" };
88
- }
89
- let s = 0;
90
- for (let e = 0; e < t.length; e++) {
91
- let n = t[e], r = t[(e + 1) % t.length];
92
- s += n.x * r.y - r.x * n.y;
93
- }
94
- return s === 0 ? { issue: "is degenerate (zero area)" } : { ring: t };
95
- }
96
- function T(e, r) {
97
- let i = [];
98
- for (let t of e) {
99
- var a;
100
- if (!t.surviving) continue;
101
- let e = r.get(t.value.layer), o = (a = e == null ? void 0 : e.rect) == null ? e == null ? void 0 : e.viewbox : a;
102
- !o || o.area <= 0 || i.push(...n(o).map((e) => ({
103
- x: e.x,
104
- y: e.y
105
- })));
106
- }
107
- return t(i);
108
- }
109
- function E(e, t, n = []) {
110
- try {
111
- return D(e, t, n);
112
- } catch {
113
- return S([], [{
114
- code: "venues-payload-invalid",
115
- path: "venues",
116
- message: "could not be parsed",
117
- consequence: "plan loads as single-venue",
118
- effect: "dropped"
119
- }], []);
120
- }
121
- }
122
- function D(t, n, o) {
123
- let s = [], x = (e) => (t, n, r, i) => s.push({
124
- code: t,
125
- path: n,
126
- message: r,
127
- consequence: i,
128
- effect: e
129
- }), C = x("dropped"), E = x("fallback"), D = x("clamped"), O = x("advisory"), k = (e, t, n) => {
130
- for (let r of Object.keys(t)) n.has(r) || O("unknown-key", `${e}.${r}`, "is not a contract field", "ignored by the SDK");
131
- }, A = (e) => {
132
- let t = s.length;
133
- try {
134
- return e();
135
- } finally {
136
- s.length = t;
137
- }
138
- }, j = /* @__PURE__ */ new Set();
139
- for (let e of o) for (let t of e) j.add(t.layer);
140
- if (t == null) return S([], s, []);
141
- if (!h(t)) return C("venues-payload-invalid", "", "payload is not an object", "nothing to parse"), S([], s, []);
142
- let M = t.venues;
143
- if (M === void 0) return S([], s, []);
144
- if (t.venuesVersion !== void 0 && t.venuesVersion !== 1) return C("venues-version-unsupported", "venuesVersion", `payload version ${b(t.venuesVersion)} is unsupported; SDK supports version 1`, "whole venues array ignored; plan loads as single-venue"), S([], s, []);
145
- if (!Array.isArray(M)) return C("venues-payload-invalid", "venues", "is not an array", "plan loads as single-venue"), S([], s, []);
146
- let N = /* @__PURE__ */ new Map(), P = /* @__PURE__ */ new Map(), F = /* @__PURE__ */ new Map();
147
- M.forEach((e, t) => {
148
- if (!h(e) || !_(e.name)) return;
149
- let n = `venues[${t}]`, r = e.name.toLowerCase(), i = P.get(r);
150
- i ? F.set(n, i) : P.set(r, n);
151
- });
152
- let I = M.map((e, t) => {
153
- var r, o;
154
- let s = `venues[${t}]`;
155
- if (!h(e)) return C("venue-identity-invalid", s, "is not an object", "venue dropped"), {
156
- at: s,
157
- label: s,
158
- claimable: !1,
159
- order: t,
160
- levels: [],
161
- aux: [],
162
- entrances: [],
163
- expectedSceneLayers: [],
164
- referencedLayers: []
165
- };
166
- k(s, e, u);
167
- let m = !0, y = e.id;
168
- _(y) ? (i.test(y) || (C("venue-identity-invalid", `${s}.id`, `"${y}" must match ${i} (lowercase alphanumerics, hyphen, underscore)`, "id is used as a MapLibre feature id, a style-image id and a ?camera[venue]= deep-link value"), m = !1), N.has(y) ? (C("venue-id-duplicate", `${s}.id`, `"${y}" duplicates ${N.get(y)}`, "this venue dropped"), m = !1) : N.set(y, s)) : (C("venue-identity-invalid", `${s}.id`, "is missing or not a non-empty string", "venue dropped"), m = !1);
169
- let x = _(y) ? `"${y}"` : s, S = e.name;
170
- _(S) ? F.has(s) && O("venue-name-duplicate", `${s}.name`, `"${S}" duplicates the name of ${F.get(s)} (case-insensitive)`, "nothing dropped — two identical rows in the venue switch, ambiguous search results") : (C("venue-identity-invalid", `${s}.name`, "is missing or not a non-empty string", "venue dropped"), m = !1);
171
- let T = t;
172
- Number.isInteger(e.order) ? T = e.order : E("venue-order-invalid", `${s}.order`, e.order === void 0 ? "is missing" : "is not an integer", "falls back to array position; order is contractually required (§9)");
173
- let A = [], M = (e, t = !1) => {
174
- _(e) && !e.startsWith("WF") && t && !A.includes(e) && A.push(e);
175
- }, P = [];
176
- if (!Array.isArray(e.levels) || e.levels.length === 0) C("venue-levels-missing", `${s}.levels`, "is missing or empty", "venue dropped"), m = !1;
177
- else {
178
- e.levels.forEach((e, t) => {
179
- let r = `${s}.levels[${t}]`;
180
- if (!h(e)) {
181
- C("level-entry-invalid", r, "is not an object", "level dropped");
182
- return;
183
- }
184
- k(r, e, d), M(e.layer, n.has(e.layer));
185
- let i = !0;
186
- _(e.layer) ? (n.has(e.layer) || (C("level-layer-unknown", `${r}.layer`, `"${e.layer}" does not exist in the plan`, `level dropped; venue ${x} loses this floor (check for a rename or typo)`), i = !1), e.layer.startsWith("WF") && (C("level-layer-wayfinding", `${r}.layer`, `"${e.layer}" is a wayfinding layer`, "WF* layers are excluded before the venue model sees them — level dropped"), i = !1)) : (C("level-layer-invalid", `${r}.layer`, "is missing or not a non-empty string", "level dropped"), i = !1), Number.isInteger(e.ordinal) || (C("level-ordinal-invalid", `${r}.ordinal`, "is missing or not an integer", "level dropped; ordinal is required (0 = ground, -1 = basement)"), i = !1), e.name !== void 0 && !_(e.name) && E("level-field-invalid", `${r}.name`, "is not a non-empty string", "falls back to the layer's description"), e.initial !== void 0 && typeof e.initial != "boolean" && E("level-field-invalid", `${r}.initial`, "is not a boolean", "ignored"), P.push({
187
- value: {
188
- layer: _(e.layer) ? e.layer : "",
189
- ordinal: Number.isInteger(e.ordinal) ? e.ordinal : 0,
190
- name: _(e.name) ? e.name : void 0,
191
- initial: typeof e.initial == "boolean" ? e.initial : void 0
192
- },
193
- at: r,
194
- ok: i,
195
- surviving: !1
196
- });
197
- });
198
- let t = /* @__PURE__ */ new Map();
199
- for (let e of P) {
200
- if (!e.ok) continue;
201
- let n = e.value.ordinal, r = t.get(n);
202
- r ? (C("level-ordinal-duplicate", `${e.at}.ordinal`, `${n} duplicates ${r}`, "level dropped; ordinals are unique within a venue"), e.ok = !1) : t.set(n, e.at);
203
- }
204
- }
205
- let I;
206
- if (e.contour !== void 0) {
207
- let t = w(e.contour);
208
- t.issue ? E("contour-invalid", `${s}.contour`, t.issue, "falls back to the scene layer's geometry, then to the hull of level rects") : I = t.ring;
209
- }
210
- let L;
211
- e.markerPoint !== void 0 && (v(e.markerPoint) ? L = {
212
- x: e.markerPoint.x,
213
- y: e.markerPoint.y
214
- } : E("venue-marker-point-invalid", `${s}.markerPoint`, "is not a finite {x, y} point", "falls back to the contour centroid"));
215
- let R;
216
- e.detailMinSizePx !== void 0 && (!g(e.detailMinSizePx) || e.detailMinSizePx <= 0 ? E("detail-min-size-invalid", `${s}.detailMinSizePx`, "is not a positive finite number", "default 240 used") : R = e.detailMinSizePx);
217
- let z;
218
- if (e.markerMaxSizePx !== void 0) {
219
- let t = R === void 0 ? 240 : Math.max(66, R);
220
- !g(e.markerMaxSizePx) || e.markerMaxSizePx <= 0 ? E("marker-max-size-invalid", `${s}.markerMaxSizePx`, "is not a positive finite number", "default 60 used") : e.markerMaxSizePx >= t ? E("marker-max-size-inverted", `${s}.markerMaxSizePx`, `${e.markerMaxSizePx} is at or above the venue's resolved detailMinSizePx of ${t}`, "default 60 used, then the detail-edge clamp applies") : z = e.markerMaxSizePx;
221
- }
222
- let B = (r = z) == null ? 60 : r;
223
- if (R !== void 0 && !c(R, B)) {
224
- let e = l(B);
225
- D("detail-min-size-clamped", `${s}.detailMinSizePx`, `${R} is below the ${e}px marker/scene sticky enter edge`, `clamped to ${e}`), R = e;
226
- }
227
- let V = (o = R) == null ? 240 : o, H = [], U = [];
228
- e.layers !== void 0 && (Array.isArray(e.layers) ? e.layers.forEach((e, t) => {
229
- let r = `${s}.layers[${t}]`;
230
- if (!h(e)) {
231
- C("aux-entry-invalid", r, "is not an object", "entry dropped");
232
- return;
233
- }
234
- k(r, e, p), _(e.layer) && e.render === "scene" && (e.replacesDefault === void 0 || e.replacesDefault === !0) && U.push(e.layer);
235
- let i = _(e.layer) && (n.has(e.layer) || j.has(e.layer));
236
- M(e.layer, i);
237
- let o = !0;
238
- _(e.layer) ? (i || (C("aux-layer-unknown", `${r}.layer`, `"${e.layer}" does not exist in the plan`, "entry dropped; venue falls back to the procedural appearance"), o = !1), e.layer.startsWith("WF") && (C("aux-layer-wayfinding", `${r}.layer`, `"${e.layer}" is a wayfinding layer`, "WF* layers are excluded before the venue model sees them — entry dropped"), o = !1)) : (C("aux-layer-invalid", `${r}.layer`, "is missing or not a non-empty string", "entry dropped"), o = !1);
239
- let c = a.includes(e.render);
240
- c || (C("aux-entry-invalid", `${r}.render`, `is ${b(e.render)}, expected "scene" or "marker"`, "entry dropped"), o = !1), e.replacesDefault !== void 0 && typeof e.replacesDefault != "boolean" && (C("aux-entry-invalid", `${r}.replacesDefault`, "is not a boolean", "entry dropped"), o = !1), e.suppressesLabel !== void 0 && typeof e.suppressesLabel != "boolean" && (C("aux-entry-invalid", `${r}.suppressesLabel`, "is not a boolean", "entry dropped"), o = !1), e.minSizePx !== void 0 && (!g(e.minSizePx) || e.minSizePx < 0) && (C("aux-entry-invalid", `${r}.minSizePx`, "is not a non-negative finite number", "entry dropped"), o = !1), e.maxSizePx !== void 0 && e.maxSizePx !== "detail" && (!g(e.maxSizePx) || e.maxSizePx < 0) && (C("aux-entry-invalid", `${r}.maxSizePx`, "is not a non-negative finite number or the literal \"detail\"", "entry dropped"), o = !1), g(e.minSizePx) && g(e.maxSizePx) && e.minSizePx >= 0 && e.maxSizePx >= 0 && e.minSizePx > e.maxSizePx && (C("aux-range-inverted", r, `minSizePx ${e.minSizePx} exceeds maxSizePx ${e.maxSizePx}`, "entry dropped"), o = !1);
241
- let l = c ? e.render : "scene", u = g(e.minSizePx) && e.minSizePx >= 0 ? e.minSizePx : l === "marker" ? 0 : B, d = e.maxSizePx !== void 0 && (e.maxSizePx === "detail" || g(e.maxSizePx)) ? e.maxSizePx : l === "scene" ? "detail" : B;
242
- c && (d === "detail" ? u >= V : u > d) && (C("aux-range-never-visible", r, `resolved range ${u}..${d} can never render`, "entry dropped; the procedural fallback for this render mode is restored"), o = !1), c && l === "scene" && g(e.maxSizePx) && O("aux-max-size-numeric", `${r}.maxSizePx`, `is the hard edge ${e.maxSizePx} rather than "detail"`, "a static edge cannot follow the ±10% detail hysteresis — expect flicker and brief overlap with the floor plan"), H.push({
243
- value: {
244
- layer: _(e.layer) ? e.layer : "",
245
- render: l,
246
- replacesDefault: typeof e.replacesDefault == "boolean" ? e.replacesDefault : void 0,
247
- suppressesLabel: typeof e.suppressesLabel == "boolean" ? e.suppressesLabel : void 0,
248
- minSizePx: g(e.minSizePx) ? e.minSizePx : void 0,
249
- maxSizePx: e.maxSizePx === "detail" || g(e.maxSizePx) ? e.maxSizePx : void 0
250
- },
251
- at: r,
252
- ok: o,
253
- surviving: !1
254
- });
255
- }) : E("aux-layers-invalid", `${s}.layers`, "is not an array", "ignored; procedural appearance used"));
256
- let W = new Set((Array.isArray(e.levels) ? e.levels : []).filter(h).map((e) => e.layer).filter(_)), G = [];
257
- return e.entrances !== void 0 && (Array.isArray(e.entrances) ? e.entrances.forEach((e, t) => {
258
- let n = `${s}.entrances[${t}]`;
259
- if (!h(e)) {
260
- C("entrance-entry-invalid", n, "is not an object", "entrance dropped");
261
- return;
262
- }
263
- k(n, e, f);
264
- let r = !0;
265
- _(e.layer) ? W.has(e.layer) || (C("entrance-layer-foreign", `${n}.layer`, `"${e.layer}" is not a level of venue ${x}`, "entrance dropped; an entrance stands on one of its own venue’s levels"), r = !1) : (C("entrance-layer-invalid", `${n}.layer`, "is missing or not a non-empty string", "entrance dropped"), r = !1), v(e.point) || (C("entrance-entry-invalid", `${n}.point`, "is missing or not a finite {x, y} point", "entrance dropped; an entrance is a point before it is anything else"), r = !1), e.name !== void 0 && !_(e.name) && E("entrance-field-invalid", `${n}.name`, "is not a non-empty string", "falls back to the venue’s own name"), !(!r || !_(e.layer) || !v(e.point)) && G.push({
266
- value: {
267
- layer: e.layer,
268
- point: {
269
- x: e.point.x,
270
- y: e.point.y
271
- },
272
- name: _(e.name) ? e.name : void 0
273
- },
274
- at: n
275
- });
276
- }) : E("entrances-invalid", `${s}.entrances`, "is not an array", "ignored; the venue keeps marker-point targeting")), {
277
- at: s,
278
- id: _(y) ? y : void 0,
279
- name: _(S) ? S : void 0,
280
- label: x,
281
- claimable: m,
282
- order: T,
283
- levels: P,
284
- aux: H,
285
- entrances: G,
286
- expectedSceneLayers: U,
287
- contour: I,
288
- markerPoint: L,
289
- detailMinSizePx: R,
290
- markerMaxSizePx: z,
291
- referencedLayers: A,
292
- campusViewbox: e.campusViewbox
293
- };
294
- }), L = /* @__PURE__ */ new Set(), R = [...I].sort((e, t) => {
295
- var n, r;
296
- return e.order - t.order || m((n = e.id) == null ? "" : n, (r = t.id) == null ? "" : r);
297
- }), z = null, B;
298
- for (let e of R) {
299
- if (e.campusViewbox === void 0) continue;
300
- let t = `${e.at}.campusViewbox`;
301
- if (B) {
302
- C("campus-viewbox-duplicate", t, `${B.at} already carries the campus viewbox`, "this venue's value is ignored; the first carrier by order wins");
303
- continue;
304
- }
305
- B = e;
306
- let n = e.campusViewbox;
307
- y(n) ? z = new r(n.x, n.y, n.width, n.height) : E("campus-viewbox-invalid", t, "is not an {x, y, width, height} of finite numbers with a positive width and height", "the campus is framed by the union of the venue footprints");
308
- }
309
- let V = () => {
310
- let e = /* @__PURE__ */ new Map();
311
- for (let e of I) {
312
- e.parsed = void 0;
313
- for (let t of e.levels) t.surviving = !1;
314
- for (let t of e.aux) t.surviving = !1;
315
- }
316
- for (let t of R) if (!(!t.claimable || !t.id || !t.name || L.has(t))) for (let n of t.levels) {
317
- if (!n.ok) continue;
318
- let r = n.value.layer, i = e.get(r);
319
- if (i) {
320
- C("level-layer-claimed", `${n.at}.layer`, `"${r}" is already used by ${i.label} (${i.role})`, "level dropped; a layer belongs to at most one venue and one role");
321
- continue;
322
- }
323
- e.set(r, {
324
- label: t.label,
325
- role: "level"
326
- }), n.surviving = !0;
327
- }
328
- for (let t of R) {
329
- if (!t.claimable || !t.id || !t.name || L.has(t) || !t.levels.some((e) => e.surviving)) continue;
330
- let n = 0;
331
- for (let r of t.aux) {
332
- if (!r.ok) continue;
333
- let i = r.value, a = e.get(i.layer);
334
- if (a) {
335
- C("aux-layer-claimed", `${r.at}.layer`, `"${i.layer}" is already used by ${a.label} (${a.role})`, "entry dropped; a layer is a level, an aux layer, or neither — never two");
336
- continue;
337
- }
338
- if (i.render === "marker" && n > 0) {
339
- C("aux-marker-duplicate", `${r.at}.render`, "is a second marker layer for this venue", "at most one per venue; extras dropped, the first wins");
340
- continue;
341
- }
342
- e.set(i.layer, {
343
- label: t.label,
344
- role: "aux"
345
- }), r.surviving = !0, i.render === "marker" && n++;
346
- }
347
- }
348
- return e;
349
- }, H = (e) => {
350
- var t;
351
- if (e.contour) return e.contour;
352
- let r = I.indexOf(e), i = e.aux.filter((e) => e.ok && e.value.render === "scene" && e.value.replacesDefault !== !1), a = new Map(i.filter((e) => e.surviving).map((e) => [e.value.layer, e])), s = [];
353
- for (let e of (t = o[r]) == null ? [] : t) {
354
- let t = a.get(e.layer);
355
- if (!(t != null && t.surviving)) continue;
356
- let n = (n) => E("footprint-source-unusable", `${t.at}.layer`, `scene layer "${e.layer}" ${n}`, "the next valid replacing scene is tried, then the level-rect hull"), { extraction: r } = e;
357
- if (!r.ring) {
358
- n(r.unusableElementKinds.length > 0 ? `draws no usable <path>; only paths are footprint sources, and it draws ${r.unusableElementKinds.map((e) => `<${e}>`).join(", ")}` : "could not supply a valid contour");
359
- continue;
360
- }
361
- let i = w(r.ring);
362
- if (!i.ring) {
363
- var c;
364
- n((c = i.issue) == null ? "could not supply a valid contour" : c);
365
- continue;
366
- }
367
- s.push({
368
- candidate: t,
369
- layer: e.layer,
370
- ring: i.ring,
371
- boundsFallback: r.boundsFallback
372
- });
373
- }
374
- s.length > 1 && O("footprint-source-ambiguous", `${e.at}.layers`, `multiple replacing scene layers provide contours: ${s.map(({ layer: e }) => `"${e}"`).join(", ")}`, `the first in plan-layer order, "${s[0].layer}", wins`);
375
- let l = s[0];
376
- if (l) return l.boundsFallback && E("footprint-bounding-box", `${l.candidate.at}.layer`, `scene layer "${l.layer}" uses its bounding box for the venue contour`, "camera, tap target, and size bounds may extend beyond the artwork"), l.ring;
377
- let u = T(e.levels, n);
378
- return u.length >= 3 && e.expectedSceneLayers.length > 0 && E("footprint-source-fallthrough", `${e.at}.contour`, "replacing scene contour unavailable; using the level-rect hull", "bounds, camera target, tap target, and the size axis changed source"), u;
379
- };
380
- for (;;) {
381
- let e = A(() => (V(), R.find((e) => e.claimable && !L.has(e) && e.levels.some((e) => e.surviving) && H(e).length < 3)));
382
- if (!e) break;
383
- H(e), C("footprint-underivable", `${e.at}.contour`, "no valid polygon can be derived", `venue ${e.label} dropped entirely`), L.add(e);
384
- }
385
- let U = V();
386
- for (let t of I) {
387
- var W, G;
388
- if (!t.claimable || !t.id || !t.name || L.has(t)) continue;
389
- let n = t.levels.filter((e) => e.surviving);
390
- if (n.length === 0) {
391
- C("venue-levels-all-dropped", `${t.at}.levels`, "no level survives validation", `venue ${t.label} dropped entirely`);
392
- continue;
393
- }
394
- let i = H(t), a = t.levels.filter((e) => e.value.initial === !0), o = n.filter((e) => e.value.initial === !0);
395
- a.some((e) => !e.surviving) && E("level-initial-dropped", `${a.find((e) => !e.surviving).at}.initial`, "initial level was dropped", "the lowest surviving ordinal is initial"), t.levels.filter((e) => e.value.ordinal === 0).length > 0 && !n.some((e) => e.value.ordinal === 0) && O("level-ground-dropped", `${t.at}.levels`, "the ordinal 0 (ground) level was dropped", "cross-venue routing into this venue is likely broken (§13); the venue also boots on an upper floor"), o.length > 1 && O("level-initial-duplicate", `${t.at}.levels`, `${o.length} levels are marked initial`, "at most one per venue; the SDK takes the first");
396
- let s = (W = o[0]) == null ? n.reduce((e, t) => t.value.ordinal < e.value.ordinal ? t : e) : W, c = new Set(n.map((e) => e.value.layer)), l = [];
397
- for (let e of t.entrances) {
398
- if (!c.has(e.value.layer)) {
399
- C("entrance-level-dropped", `${e.at}.layer`, `level "${e.value.layer}" did not survive validation`, "entrance dropped; the venue falls back to its remaining doors, then to marker-point targeting");
400
- continue;
401
- }
402
- l.push({ ...e.value });
403
- }
404
- let u = i.map((e) => ({
405
- x: e.x,
406
- y: e.y
407
- }));
408
- t.parsed = {
409
- id: t.id,
410
- name: t.name,
411
- order: t.order,
412
- levels: n.map((e) => ({
413
- layer: e.value.layer,
414
- ordinal: e.value.ordinal,
415
- name: e.value.name,
416
- initial: e === s
417
- })),
418
- contour: u,
419
- markerPoint: (G = t.markerPoint) == null ? e(u) : G,
420
- bounds: r.fromPoints(u),
421
- detailMinSizePx: t.detailMinSizePx,
422
- markerMaxSizePx: t.markerMaxSizePx,
423
- entrances: l,
424
- auxLayers: t.aux.filter((e) => e.surviving).map(({ value: e }) => {
425
- var t, n;
426
- let r = (t = e.replacesDefault) == null || t;
427
- return {
428
- layer: e.layer,
429
- render: e.render,
430
- replacesDefault: r,
431
- suppressesLabel: (n = e.suppressesLabel) == null ? e.render === "scene" && r : n,
432
- minSizePx: e.minSizePx,
433
- maxSizePx: e.maxSizePx
434
- };
435
- })
436
- };
437
- }
438
- let K = [];
439
- for (let e of I) if (!e.parsed) for (let t of e.referencedLayers) K.includes(t) || K.push(t);
440
- let q = [];
441
- for (let e of I) e.parsed && q.push(e.parsed);
442
- if (M.length > 0 && q.length === 0) return C("venues-all-dropped", "venues", "no venue survived validation", "plan loads as single-venue"), S([], s, []);
443
- let J = K.filter((e) => !U.has(e));
444
- return J.length > 0 && C("plan-layers-quarantined", "venues", `quarantined unclaimed layer${J.length === 1 ? "" : "s"}: ${J.map((e) => `"${e}"`).join(", ")}`, "hidden from venue and ordinary layer rendering"), S(q, s, J, z);
445
- }
446
- //#endregion
447
- export { l as n, E as r, m as t };