@7365admin1/core 3.83.0 → 3.84.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -77,6 +77,7 @@ __export(src_exports, {
77
77
  ConsoleAuditAction: () => ConsoleAuditAction,
78
78
  ConsoleAuditTarget: () => ConsoleAuditTarget,
79
79
  DEFAULT_RING_SECONDS: () => DEFAULT_RING_SECONDS,
80
+ DEFAULT_SCALE_M_PER_PX: () => DEFAULT_SCALE_M_PER_PX,
80
81
  DEFAULT_SITE_TIMEZONE: () => DEFAULT_SITE_TIMEZONE,
81
82
  DEVICE_STATUS: () => DEVICE_STATUS,
82
83
  DOBStatus: () => DOBStatus,
@@ -296,6 +297,8 @@ __export(src_exports, {
296
297
  VerificationType: () => VerificationType,
297
298
  VisitorSort: () => VisitorSort,
298
299
  VisitorStatus: () => VisitorStatus,
300
+ WALL_HEIGHT_M: () => WALL_HEIGHT_M,
301
+ WALL_THICKNESS_M: () => WALL_THICKNESS_M,
299
302
  addressSchema: () => addressSchema,
300
303
  allowedFieldsSite: () => allowedFieldsSite,
301
304
  allowedNatures: () => allowedNatures,
@@ -307,6 +310,8 @@ __export(src_exports, {
307
310
  attendanceSchema: () => attendanceSchema,
308
311
  attendanceSettingsSchema: () => attendanceSettingsSchema,
309
312
  buildSelfServiceEmailContext: () => buildSelfServiceEmailContext,
313
+ buildingMapFromRobotMaps: () => buildingMapFromRobotMaps,
314
+ buildingSolids: () => buildingSolids,
310
315
  building_level_namespace_collection: () => building_level_namespace_collection,
311
316
  building_units_namespace_collection: () => building_units_namespace_collection,
312
317
  buildings_namespace_collection: () => buildings_namespace_collection,
@@ -413,6 +418,9 @@ __export(src_exports, {
413
418
  isTermsCurrent: () => isTermsCurrent,
414
419
  isTrackingStale: () => isTrackingStale,
415
420
  isValidTimezone: () => isValidTimezone,
421
+ levelPixelToMetres: () => levelPixelToMetres,
422
+ levelScale: () => levelScale,
423
+ levelSolids: () => levelSolids,
416
424
  listStaffUserIds: () => listStaffUserIds,
417
425
  liveStatusFor: () => liveStatusFor,
418
426
  manpowerDesignationsSchema: () => manpowerDesignationsSchema,
@@ -511,6 +519,7 @@ __export(src_exports, {
511
519
  robotTier: () => robotTier,
512
520
  robotTypesVisibleTo: () => robotTypesVisibleTo,
513
521
  rtspUrl: () => rtspUrl,
522
+ scaleFromMeasurement: () => scaleFromMeasurement,
514
523
  schema: () => schema,
515
524
  schemaAppSlugNotification: () => schemaAppSlugNotification,
516
525
  schemaApprovedBy: () => schemaApprovedBy,
@@ -928,8 +937,10 @@ __export(src_exports, {
928
937
  vehicleSchema: () => vehicleSchema,
929
938
  vehicleViewOf: () => vehicleViewOf,
930
939
  vehicles_namespace_collection: () => vehicles_namespace_collection,
940
+ vertexDistancePx: () => vertexDistancePx,
931
941
  visitors_namespace_collection: () => visitors_namespace_collection,
932
942
  wallConfig: () => wallConfig,
943
+ wallsFromOccupancyGrid: () => wallsFromOccupancyGrid,
933
944
  withLiveLink: () => withLiveLink,
934
945
  workOrderSchema: () => workOrderSchema,
935
946
  work_orders2_namespace_collection: () => work_orders2_namespace_collection,
@@ -60127,6 +60138,179 @@ function createLiftSimulator(options) {
60127
60138
  };
60128
60139
  }
60129
60140
 
60141
+ // src/utils/building-map.util.ts
60142
+ var WALL_HEIGHT_M = 2.5;
60143
+ var WALL_THICKNESS_M = 0.1;
60144
+ var DEFAULT_SCALE_M_PER_PX = 0.05;
60145
+ function scaleFromMeasurement(pixelDistance, realDistanceM) {
60146
+ if (!Number.isFinite(pixelDistance) || pixelDistance <= 0) {
60147
+ throw new Error("A measurement needs a positive pixel distance.");
60148
+ }
60149
+ if (!Number.isFinite(realDistanceM) || realDistanceM <= 0) {
60150
+ throw new Error("A measurement needs a positive real distance in metres.");
60151
+ }
60152
+ return realDistanceM / pixelDistance;
60153
+ }
60154
+ function vertexDistancePx(a, b) {
60155
+ return Math.hypot(b.x - a.x, b.y - a.y);
60156
+ }
60157
+ function levelScale(level) {
60158
+ const measurement = level.measurements?.find((m) => {
60159
+ const a = level.vertices[m.start];
60160
+ const b = level.vertices[m.end];
60161
+ return a && b && m.distanceM > 0 && vertexDistancePx(a, b) > 0;
60162
+ });
60163
+ if (measurement) {
60164
+ return scaleFromMeasurement(
60165
+ vertexDistancePx(level.vertices[measurement.start], level.vertices[measurement.end]),
60166
+ measurement.distanceM
60167
+ );
60168
+ }
60169
+ return level.scaleMPerPx > 0 ? level.scaleMPerPx : DEFAULT_SCALE_M_PER_PX;
60170
+ }
60171
+ function levelPixelToMetres(level, px, py, imageHeightPx) {
60172
+ const scale = levelScale(level);
60173
+ return {
60174
+ x: level.originXM + px * scale,
60175
+ y: level.originYM + (imageHeightPx - py) * scale
60176
+ };
60177
+ }
60178
+ function levelSolids(level, imageHeightPx) {
60179
+ const toM = (v) => levelPixelToMetres(level, v.x, v.y, imageHeightPx);
60180
+ const walls = [];
60181
+ for (const wall of level.walls ?? []) {
60182
+ const a = level.vertices[wall.start];
60183
+ const b = level.vertices[wall.end];
60184
+ if (!a || !b)
60185
+ continue;
60186
+ const pa = toM(a);
60187
+ const pb = toM(b);
60188
+ const lengthM = Math.hypot(pb.x - pa.x, pb.y - pa.y);
60189
+ if (lengthM <= 0)
60190
+ continue;
60191
+ const heightM = wall.heightM ?? WALL_HEIGHT_M;
60192
+ walls.push({
60193
+ centre: {
60194
+ x: (pa.x + pb.x) / 2,
60195
+ y: (pa.y + pb.y) / 2,
60196
+ // Boxes are centred, so a wall standing ON the floor sits at half its
60197
+ // own height above the level's elevation.
60198
+ z: level.elevationM + heightM / 2
60199
+ },
60200
+ lengthM,
60201
+ thicknessM: wall.thicknessM ?? WALL_THICKNESS_M,
60202
+ heightM,
60203
+ yaw: Math.atan2(pb.y - pa.y, pb.x - pa.x)
60204
+ });
60205
+ }
60206
+ const floors = [];
60207
+ for (const floor of level.floors ?? []) {
60208
+ const points = (floor.vertices ?? []).map((i) => level.vertices[i]).filter(Boolean).map(toM);
60209
+ if (points.length < 3)
60210
+ continue;
60211
+ floors.push({ points, elevationM: level.elevationM, hole: floor.hole === true });
60212
+ }
60213
+ return { level: level.name, elevationM: level.elevationM, walls, floors };
60214
+ }
60215
+ function buildingSolids(map, imageHeightFor) {
60216
+ return (map.levels ?? []).map((level) => levelSolids(level, imageHeightFor(level)));
60217
+ }
60218
+ function wallsFromOccupancyGrid(grid, options) {
60219
+ const threshold = options?.threshold ?? 100;
60220
+ const minRun = Math.max(2, options?.minRunPx ?? 6);
60221
+ const { data, width, height } = grid;
60222
+ if (!width || !height || !data || data.length < width * height) {
60223
+ return { vertices: [], walls: [] };
60224
+ }
60225
+ const occupied = (x, y) => Number(data[y * width + x]) <= threshold;
60226
+ const consumed = new Uint8Array(width * height);
60227
+ const vertices = [];
60228
+ const walls = [];
60229
+ const index = /* @__PURE__ */ new Map();
60230
+ const vertexAt = (x, y) => {
60231
+ const key = `${x}:${y}`;
60232
+ const found = index.get(key);
60233
+ if (found !== void 0)
60234
+ return found;
60235
+ vertices.push({ x, y, z: 0 });
60236
+ index.set(key, vertices.length - 1);
60237
+ return vertices.length - 1;
60238
+ };
60239
+ const addRun = (x1, y1, x2, y2) => {
60240
+ walls.push({ start: vertexAt(x1, y1), end: vertexAt(x2, y2) });
60241
+ };
60242
+ for (let y = 0; y < height; y++) {
60243
+ let run = 0;
60244
+ for (let x = 0; x <= width; x++) {
60245
+ const on = x < width && occupied(x, y);
60246
+ if (on) {
60247
+ run++;
60248
+ continue;
60249
+ }
60250
+ if (run >= minRun) {
60251
+ const startX = x - run;
60252
+ addRun(startX, y, x - 1, y);
60253
+ for (let i = startX; i < x; i++)
60254
+ consumed[y * width + i] = 1;
60255
+ }
60256
+ run = 0;
60257
+ }
60258
+ }
60259
+ for (let x = 0; x < width; x++) {
60260
+ let run = 0;
60261
+ for (let y = 0; y <= height; y++) {
60262
+ const on = y < height && occupied(x, y) && !consumed[y * width + x];
60263
+ if (on) {
60264
+ run++;
60265
+ continue;
60266
+ }
60267
+ if (run >= minRun) {
60268
+ addRun(x, y - run, x, y - 1);
60269
+ }
60270
+ run = 0;
60271
+ }
60272
+ }
60273
+ return { vertices, walls };
60274
+ }
60275
+ function buildingMapFromRobotMaps(name, maps, floorHeightM = 3) {
60276
+ const levels = [...maps ?? []].sort((a, b) => a.floorNo - b.floorNo).map((map) => {
60277
+ const vertices = [];
60278
+ if (map.baseX || map.baseY) {
60279
+ vertices.push({
60280
+ x: map.baseX ?? 0,
60281
+ y: map.baseY ?? 0,
60282
+ z: 0,
60283
+ name: `L${map.floorNo}_charger`,
60284
+ isCharger: true,
60285
+ theta: map.baseTheta ?? 0
60286
+ });
60287
+ }
60288
+ for (const area of map.areaList ?? []) {
60289
+ vertices.push({
60290
+ x: area.x,
60291
+ y: area.y,
60292
+ z: 0,
60293
+ name: area.areaName,
60294
+ isCleaningZone: true
60295
+ });
60296
+ }
60297
+ return {
60298
+ name: map.mapName?.trim() || `L${map.floorNo}`,
60299
+ elevationM: (map.floorNo - 1) * floorHeightM,
60300
+ drawing: { fileKey: map.backgroundFileKey },
60301
+ scaleMPerPx: map.resolution && map.resolution > 0 ? map.resolution : DEFAULT_SCALE_M_PER_PX,
60302
+ originXM: map.originX ?? 0,
60303
+ originYM: map.originY ?? 0,
60304
+ vertices,
60305
+ walls: [],
60306
+ floors: [],
60307
+ doors: [],
60308
+ measurements: []
60309
+ };
60310
+ });
60311
+ return { name, levels, lifts: [] };
60312
+ }
60313
+
60130
60314
  // src/services/robot-fleet.service.ts
60131
60315
  var import_node_server_utils157 = require("@7365admin1/node-server-utils");
60132
60316
 
@@ -93944,6 +94128,7 @@ function usePersonalEmergencyChainController() {
93944
94128
  ConsoleAuditAction,
93945
94129
  ConsoleAuditTarget,
93946
94130
  DEFAULT_RING_SECONDS,
94131
+ DEFAULT_SCALE_M_PER_PX,
93947
94132
  DEFAULT_SITE_TIMEZONE,
93948
94133
  DEVICE_STATUS,
93949
94134
  DOBStatus,
@@ -94163,6 +94348,8 @@ function usePersonalEmergencyChainController() {
94163
94348
  VerificationType,
94164
94349
  VisitorSort,
94165
94350
  VisitorStatus,
94351
+ WALL_HEIGHT_M,
94352
+ WALL_THICKNESS_M,
94166
94353
  addressSchema,
94167
94354
  allowedFieldsSite,
94168
94355
  allowedNatures,
@@ -94174,6 +94361,8 @@ function usePersonalEmergencyChainController() {
94174
94361
  attendanceSchema,
94175
94362
  attendanceSettingsSchema,
94176
94363
  buildSelfServiceEmailContext,
94364
+ buildingMapFromRobotMaps,
94365
+ buildingSolids,
94177
94366
  building_level_namespace_collection,
94178
94367
  building_units_namespace_collection,
94179
94368
  buildings_namespace_collection,
@@ -94280,6 +94469,9 @@ function usePersonalEmergencyChainController() {
94280
94469
  isTermsCurrent,
94281
94470
  isTrackingStale,
94282
94471
  isValidTimezone,
94472
+ levelPixelToMetres,
94473
+ levelScale,
94474
+ levelSolids,
94283
94475
  listStaffUserIds,
94284
94476
  liveStatusFor,
94285
94477
  manpowerDesignationsSchema,
@@ -94378,6 +94570,7 @@ function usePersonalEmergencyChainController() {
94378
94570
  robotTier,
94379
94571
  robotTypesVisibleTo,
94380
94572
  rtspUrl,
94573
+ scaleFromMeasurement,
94381
94574
  schema,
94382
94575
  schemaAppSlugNotification,
94383
94576
  schemaApprovedBy,
@@ -94795,8 +94988,10 @@ function usePersonalEmergencyChainController() {
94795
94988
  vehicleSchema,
94796
94989
  vehicleViewOf,
94797
94990
  vehicles_namespace_collection,
94991
+ vertexDistancePx,
94798
94992
  visitors_namespace_collection,
94799
94993
  wallConfig,
94994
+ wallsFromOccupancyGrid,
94800
94995
  withLiveLink,
94801
94996
  workOrderSchema,
94802
94997
  work_orders2_namespace_collection,