sgerp-frontend-lib 0.1.5 → 0.2.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.
Files changed (35) hide show
  1. package/dist/constants/timezones.d.ts +7 -2
  2. package/dist/constants/timezones.d.ts.map +1 -1
  3. package/dist/constants/timezones.js +17 -2
  4. package/dist/locales/locale_en.d.ts.map +1 -1
  5. package/dist/locales/locale_en.js +159 -0
  6. package/dist/locales/locale_ja.d.ts.map +1 -1
  7. package/dist/locales/locale_ja.js +112 -0
  8. package/dist/sgerp/index.d.ts +2 -2
  9. package/dist/sgerp/index.d.ts.map +1 -1
  10. package/dist/sgerp/index.js +8 -2
  11. package/dist/sgerp/simulation-logic/fetchUtils.d.ts +18 -0
  12. package/dist/sgerp/simulation-logic/fetchUtils.d.ts.map +1 -1
  13. package/dist/sgerp/simulation-logic/fetchUtils.js +194 -0
  14. package/dist/sgerp/simulation-logic/index.d.ts +4 -1
  15. package/dist/sgerp/simulation-logic/index.d.ts.map +1 -1
  16. package/dist/sgerp/simulation-logic/index.js +9 -1
  17. package/dist/sgerp/simulation-logic/vrpStatsCalculator.d.ts +52 -0
  18. package/dist/sgerp/simulation-logic/vrpStatsCalculator.d.ts.map +1 -0
  19. package/dist/sgerp/simulation-logic/vrpStatsCalculator.js +247 -0
  20. package/dist/sgerp/simulation-logic/vrpStatsUtils.d.ts +17 -0
  21. package/dist/sgerp/simulation-logic/vrpStatsUtils.d.ts.map +1 -0
  22. package/dist/sgerp/simulation-logic/vrpStatsUtils.js +48 -0
  23. package/dist/sgerp/utils/timezone.d.ts +15 -0
  24. package/dist/sgerp/utils/timezone.d.ts.map +1 -0
  25. package/dist/sgerp/utils/timezone.js +19 -0
  26. package/dist/sgerp/vrptoolbox-analyzer.d.ts +39 -0
  27. package/dist/sgerp/vrptoolbox-analyzer.d.ts.map +1 -0
  28. package/dist/sgerp/vrptoolbox-analyzer.js +210 -0
  29. package/dist/vrptoolbox/index.d.ts +1 -0
  30. package/dist/vrptoolbox/index.d.ts.map +1 -1
  31. package/dist/vrptoolbox/index.js +16 -0
  32. package/dist/vrptoolbox/vrptoolbox-utils.d.ts +133 -0
  33. package/dist/vrptoolbox/vrptoolbox-utils.d.ts.map +1 -0
  34. package/dist/vrptoolbox/vrptoolbox-utils.js +207 -0
  35. package/package.json +3 -1
@@ -9,6 +9,7 @@ exports.fetchOperationsLocationsByProject = fetchOperationsLocationsByProject;
9
9
  exports.fetchGeofences = fetchGeofences;
10
10
  exports.fetchSimulationGeofence = fetchSimulationGeofence;
11
11
  exports.fetchSimulationData = fetchSimulationData;
12
+ exports.fetchVRPToolboxData = fetchVRPToolboxData;
12
13
  const client_1 = require("../api/client");
13
14
  const referenceUtils_1 = require("./referenceUtils");
14
15
  /**
@@ -226,3 +227,196 @@ async function fetchSimulationData(api, simulationId, simulation = null) {
226
227
  mainGeofence
227
228
  };
228
229
  }
230
+ /**
231
+ * Fetch and convert VRPToolbox job data to SGERP simulation format
232
+ * Based on dashviewer's INITIALIZE_VRPTOOLBOX and createStateFromCommuteOffers logic
233
+ *
234
+ * @param vrpServer - VRPToolbox server URL
235
+ * @param taskId - VRPToolbox job/task ID
236
+ * @returns Simulation data in same format as fetchSimulationData
237
+ */
238
+ async function fetchVRPToolboxData(vrpServer, taskId) {
239
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
240
+ // Fetch VRPToolbox job result with payload
241
+ const url = `${vrpServer}/jobs/${taskId}/result_with_payload`;
242
+ const response = await fetch(url);
243
+ if (!response.ok) {
244
+ throw new Error(`Failed to fetch VRPToolbox data: ${response.statusText}`);
245
+ }
246
+ const data = await response.json();
247
+ const { payload, result } = data;
248
+ console.log('[fetchVRPToolboxData] Raw VRPToolbox data:', {
249
+ payloadNodesCount: (_a = payload.nodes) === null || _a === void 0 ? void 0 : _a.length,
250
+ payloadVehiclesCount: (_b = payload.vehicles) === null || _b === void 0 ? void 0 : _b.length,
251
+ resultVehiclesKeys: Object.keys(result.vehicles || {}),
252
+ resultAssignedBookings: ((_c = result.assigned_bookings) === null || _c === void 0 ? void 0 : _c.length) || 0,
253
+ resultRejectedBookings: ((_d = result.rejected_bookings) === null || _d === void 0 ? void 0 : _d.length) || 0,
254
+ samplePayloadNode: (_e = payload.nodes) === null || _e === void 0 ? void 0 : _e[0],
255
+ sampleResultVehicleNodes: result.vehicles ? Object.values(result.vehicles)[0] : null,
256
+ allPayloadNodeTypes: (_f = payload.nodes) === null || _f === void 0 ? void 0 : _f.map((n) => ({ uid: n.uid, type: n.node_type, booking_uid: n.booking_uid })),
257
+ payloadKeys: Object.keys(payload),
258
+ payloadCalculationParameters: payload.calculation_parameters,
259
+ dataKeys: Object.keys(data)
260
+ });
261
+ // Set default routing engine on vehicles if missing
262
+ const defaultRoutingEngine = (_g = payload.engine_settings) === null || _g === void 0 ? void 0 : _g.routing_engine;
263
+ const vrpVehicles = payload.vehicles.map((vehicle) => (Object.assign(Object.assign({}, vehicle), { routing_engine: vehicle.routing_engine || defaultRoutingEngine })));
264
+ // Build assignedNodesCache from result.vehicles
265
+ const assignedNodesCache = {};
266
+ Object.entries(result.vehicles || {}).forEach(([vehicleAgentId, vehicleNodes]) => {
267
+ vehicleNodes.forEach((node) => {
268
+ assignedNodesCache[node.uid] = Object.assign(Object.assign({}, node), { assigned_vehicle_id: vehicleAgentId, status: 'assigned' });
269
+ });
270
+ });
271
+ // Collect partial route nodes from vehicle.assigned_nodes
272
+ const partialRoutesNodes = [];
273
+ vrpVehicles.forEach((vehicle) => {
274
+ const assignedNodes = vehicle.assigned_nodes || [];
275
+ const completedNodes = vehicle.completed_nodes || [];
276
+ assignedNodes.forEach((vehicleNode) => {
277
+ vehicleNode.id = vehicleNode.uid;
278
+ partialRoutesNodes.push(vehicleNode);
279
+ });
280
+ });
281
+ // Process vehicles to SGERP format
282
+ const vehicles = vrpVehicles.map((vehicle) => (Object.assign(Object.assign({}, vehicle), { id: vehicle.agent_id, simulation_id: taskId, routing_engine_settings: vehicle.routing_engine })));
283
+ // Process nodes to SGERP format
284
+ const nodes = [];
285
+ const included = {};
286
+ payload.nodes.forEach((node) => {
287
+ const processedNode = Object.assign(Object.assign({}, node), { simulation_id: taskId, booking_id: node.booking_uid, id: node.uid });
288
+ if (node.uid in assignedNodesCache) {
289
+ processedNode.scheduled_ts = assignedNodesCache[node.uid].scheduled_ts;
290
+ processedNode.assigned_vehicle_id = assignedNodesCache[node.uid].assigned_vehicle_id;
291
+ processedNode.status = assignedNodesCache[node.uid].status;
292
+ }
293
+ else {
294
+ processedNode.status = 'rejected_by_system';
295
+ processedNode.scheduled_ts = null;
296
+ processedNode.assigned_vehicle_id = null;
297
+ }
298
+ nodes.push(processedNode);
299
+ included[node.uid] = processedNode;
300
+ });
301
+ // Add partial route nodes that weren't in payload.nodes
302
+ partialRoutesNodes.forEach((partialRouteNode) => {
303
+ if (!(partialRouteNode.id in included)) {
304
+ const processedNode = Object.assign(Object.assign({}, partialRouteNode), { simulation_id: taskId });
305
+ if (partialRouteNode.id in assignedNodesCache) {
306
+ processedNode.scheduled_ts = assignedNodesCache[partialRouteNode.id].scheduled_ts;
307
+ processedNode.assigned_vehicle_id = assignedNodesCache[partialRouteNode.id].assigned_vehicle_id;
308
+ processedNode.status = assignedNodesCache[partialRouteNode.id].status;
309
+ }
310
+ else {
311
+ processedNode.scheduled_ts = null;
312
+ processedNode.assigned_vehicle_id = null;
313
+ processedNode.status = 'rejected_by_system';
314
+ }
315
+ nodes.push(processedNode);
316
+ included[partialRouteNode.id] = processedNode;
317
+ }
318
+ });
319
+ // Check if this is CVRP mode (prebook_cvrptw) and find depot/point node
320
+ // CVRP mode detection: check scheduling_mode OR presence of point nodes without pickup nodes
321
+ const schedulingMode = (_h = payload.calculation_parameters) === null || _h === void 0 ? void 0 : _h.scheduling_mode;
322
+ const hasPointNodes = nodes.some((n) => n.node_type === 'point');
323
+ const hasPickupNodes = nodes.some((n) => n.node_type === 'pickup');
324
+ const isCVRP = schedulingMode === 'prebook_cvrptw' || (hasPointNodes && !hasPickupNodes);
325
+ const depotNode = isCVRP ? nodes.find((n) => n.node_type === 'point') : null;
326
+ console.log('[fetchVRPToolboxData] CVRP mode detection:', {
327
+ schedulingMode,
328
+ hasPointNodes,
329
+ hasPickupNodes,
330
+ isCVRP,
331
+ hasDepotNode: !!depotNode,
332
+ depotNodeLocation: depotNode ? { lat: depotNode.lat, lon: depotNode.lon, name: depotNode.location_name } : null
333
+ });
334
+ // Build bookings from nodes (must be done AFTER all nodes are processed)
335
+ const bookingsMap = {};
336
+ const nodeTypeCount = { pickup: 0, dropoff: 0, point: 0, other: 0 };
337
+ nodes.forEach((node) => {
338
+ const nodeType = node.node_type;
339
+ if (nodeType === 'pickup')
340
+ nodeTypeCount.pickup++;
341
+ else if (nodeType === 'dropoff')
342
+ nodeTypeCount.dropoff++;
343
+ else if (nodeType === 'point')
344
+ nodeTypeCount.point++;
345
+ else
346
+ nodeTypeCount.other++;
347
+ if (node.booking_id !== null && node.booking_id !== undefined) {
348
+ if (!(node.booking_id in bookingsMap)) {
349
+ bookingsMap[node.booking_id] = {
350
+ simulation_id: node.simulation_id,
351
+ id: node.booking_id,
352
+ uid: node.booking_id,
353
+ };
354
+ }
355
+ const booking = bookingsMap[node.booking_id];
356
+ // Update booking state from node status
357
+ booking.state = node.status;
358
+ // Set location data based on node type
359
+ booking[`${nodeType}_location_name`] = node.location_name;
360
+ booking[`${nodeType}_location_lat`] = node.lat;
361
+ booking[`${nodeType}_location_lon`] = node.lon;
362
+ booking[`${nodeType}_service_time`] = node.service_time;
363
+ // Set time windows and demand based on node type
364
+ if (nodeType === 'pickup') {
365
+ booking.min_pickup_time = node.open_time_ts;
366
+ booking.demand = node.demand;
367
+ }
368
+ else if (nodeType === 'dropoff') {
369
+ booking.max_dropoff_time = node.close_time_ts;
370
+ // In CVRP mode, set demand from dropoff node (take absolute values since dropoff has negative demand)
371
+ if (isCVRP && node.demand) {
372
+ booking.demand = Object.fromEntries(Object.entries(node.demand).map(([key, value]) => [key, Math.abs(value)]));
373
+ }
374
+ }
375
+ }
376
+ });
377
+ // For CVRP mode: Set all bookings to use depot as pickup location
378
+ if (isCVRP && depotNode) {
379
+ Object.values(bookingsMap).forEach((booking) => {
380
+ booking.pickup_location_lat = depotNode.lat;
381
+ booking.pickup_location_lon = depotNode.lon;
382
+ booking.pickup_location_name = depotNode.location_name || 'Depot';
383
+ booking.pickup_service_time = depotNode.service_time || 0;
384
+ booking.min_pickup_time = depotNode.open_time_ts;
385
+ });
386
+ }
387
+ // Now attach booking_object to each node
388
+ nodes.forEach((node) => {
389
+ if (node.booking_id !== null && node.booking_id !== undefined) {
390
+ node.booking_object = bookingsMap[node.booking_id];
391
+ }
392
+ });
393
+ const bookings = Object.values(bookingsMap);
394
+ console.log('[fetchVRPToolboxData] Result:', {
395
+ vehiclesCount: vehicles.length,
396
+ bookingsCount: bookings.length,
397
+ nodesCount: nodes.length,
398
+ nodeTypeCount,
399
+ sampleBooking: bookings[0],
400
+ sampleBookingKeys: bookings[0] ? Object.keys(bookings[0]) : [],
401
+ sampleBookingId: (_j = bookings[0]) === null || _j === void 0 ? void 0 : _j.id,
402
+ sampleBookingUid: (_k = bookings[0]) === null || _k === void 0 ? void 0 : _k.uid,
403
+ sampleBookingState: (_l = bookings[0]) === null || _l === void 0 ? void 0 : _l.state,
404
+ sampleNode: nodes.find(n => n.booking_id),
405
+ bookingsWithCoordinates: bookings.filter(b => b.pickup_location_lat && b.pickup_location_lon &&
406
+ b.dropoff_location_lat && b.dropoff_location_lon).length,
407
+ bookingsWithPickup: bookings.filter(b => b.pickup_location_lat).length,
408
+ bookingsWithDropoff: bookings.filter(b => b.dropoff_location_lat).length,
409
+ bookingStates: bookings.map(b => b.state).filter((v, i, a) => a.indexOf(v) === i)
410
+ });
411
+ return {
412
+ vehicles,
413
+ bookings,
414
+ nodes,
415
+ drivers: [], // No drivers in VRPToolbox data
416
+ geofences: [], // No geofences in VRPToolbox data
417
+ mainGeofence: null,
418
+ // Also return raw payload and result for analyzer
419
+ rawPayload: payload,
420
+ rawResult: result
421
+ };
422
+ }
@@ -2,7 +2,7 @@
2
2
  * Simulation page logic utilities
3
3
  * Inspired by dashviewer's SimulationPage/logic structure
4
4
  */
5
- export { fetchVehicles, fetchBookings, fetchNodes, fetchDrivers, fetchDriversByProject, fetchOperationsLocationsByProject, fetchSimulationData } from './fetchUtils';
5
+ export { fetchVehicles, fetchBookings, fetchNodes, fetchDrivers, fetchDriversByProject, fetchOperationsLocationsByProject, fetchSimulationData, fetchVRPToolboxData } from './fetchUtils';
6
6
  export { createIndexMaps, attachReferences } from './referenceUtils';
7
7
  export { calculateBoundingBoxCenter } from './mapUtils';
8
8
  export { vehicleComplexRearrange, buildVehicleRouteMap } from './manualEditUtils';
@@ -13,4 +13,7 @@ export { processUnassignResponse } from './optimisticUpdateUtils';
13
13
  export type { UnassignResponse, ProcessUnassignResult } from './optimisticUpdateUtils';
14
14
  export { LIVE_UPDATE_INTERVALS, PROCESSOR_LIVE_UPDATE_PARAMS, getVehicleLiveUpdateConfig, getBookingLiveUpdateConfig, getNodeLiveUpdateConfig, getProcessorLiveUpdateConfig, triggerAllSimulationUpdates } from './liveUpdates';
15
15
  export type { SimulationLiveUpdatesConfig, SimulationLiveUpdateTriggers } from './liveUpdates';
16
+ export { processVRPStatistics, calculateFleetStats } from './vrpStatsCalculator';
17
+ export type { VRPVehicleStats, FleetStats, ProcessedNode } from './vrpStatsCalculator';
18
+ export { formatSeconds, getDistanceFromLatLonInKm, toDisplayDate } from './vrpStatsUtils';
16
19
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../sgerplib/sgerp/simulation-logic/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,aAAa,EACb,aAAa,EACb,UAAU,EACV,YAAY,EACZ,qBAAqB,EACrB,iCAAiC,EACjC,mBAAmB,EACpB,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,eAAe,EACf,gBAAgB,EACjB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,0BAA0B,EAC3B,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,uBAAuB,EACvB,oBAAoB,EACrB,MAAM,mBAAmB,CAAC;AAE3B,YAAY,EACV,8BAA8B,EAC9B,kBAAkB,EAClB,eAAe,EACf,eAAe,EAChB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,mBAAmB,EACnB,uBAAuB,EACxB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,qBAAqB,EACrB,eAAe,EACf,uBAAuB,EACxB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,uBAAuB,EACxB,MAAM,yBAAyB,CAAC;AAEjC,YAAY,EACV,gBAAgB,EAChB,qBAAqB,EACtB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,qBAAqB,EACrB,4BAA4B,EAC5B,0BAA0B,EAC1B,0BAA0B,EAC1B,uBAAuB,EACvB,4BAA4B,EAC5B,2BAA2B,EAC5B,MAAM,eAAe,CAAC;AAEvB,YAAY,EACV,2BAA2B,EAC3B,4BAA4B,EAC7B,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../sgerplib/sgerp/simulation-logic/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,aAAa,EACb,aAAa,EACb,UAAU,EACV,YAAY,EACZ,qBAAqB,EACrB,iCAAiC,EACjC,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,eAAe,EACf,gBAAgB,EACjB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,0BAA0B,EAC3B,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,uBAAuB,EACvB,oBAAoB,EACrB,MAAM,mBAAmB,CAAC;AAE3B,YAAY,EACV,8BAA8B,EAC9B,kBAAkB,EAClB,eAAe,EACf,eAAe,EAChB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,mBAAmB,EACnB,uBAAuB,EACxB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,qBAAqB,EACrB,eAAe,EACf,uBAAuB,EACxB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,uBAAuB,EACxB,MAAM,yBAAyB,CAAC;AAEjC,YAAY,EACV,gBAAgB,EAChB,qBAAqB,EACtB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,qBAAqB,EACrB,4BAA4B,EAC5B,0BAA0B,EAC1B,0BAA0B,EAC1B,uBAAuB,EACvB,4BAA4B,EAC5B,2BAA2B,EAC5B,MAAM,eAAe,CAAC;AAEvB,YAAY,EACV,2BAA2B,EAC3B,4BAA4B,EAC7B,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACpB,MAAM,sBAAsB,CAAC;AAE9B,YAAY,EACV,eAAe,EACf,UAAU,EACV,aAAa,EACd,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,aAAa,EACb,yBAAyB,EACzB,aAAa,EACd,MAAM,iBAAiB,CAAC"}
@@ -4,7 +4,7 @@
4
4
  * Inspired by dashviewer's SimulationPage/logic structure
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.triggerAllSimulationUpdates = exports.getProcessorLiveUpdateConfig = exports.getNodeLiveUpdateConfig = exports.getBookingLiveUpdateConfig = exports.getVehicleLiveUpdateConfig = exports.PROCESSOR_LIVE_UPDATE_PARAMS = exports.LIVE_UPDATE_INTERVALS = exports.processUnassignResponse = exports.recalculateVehicleRoute = exports.hasRouteChanged = exports.calculateVehicleRoute = exports.shiftWaypointTimestamps = exports.shiftNodeTimestamps = exports.buildVehicleRouteMap = exports.vehicleComplexRearrange = exports.calculateBoundingBoxCenter = exports.attachReferences = exports.createIndexMaps = exports.fetchSimulationData = exports.fetchOperationsLocationsByProject = exports.fetchDriversByProject = exports.fetchDrivers = exports.fetchNodes = exports.fetchBookings = exports.fetchVehicles = void 0;
7
+ exports.toDisplayDate = exports.getDistanceFromLatLonInKm = exports.formatSeconds = exports.calculateFleetStats = exports.processVRPStatistics = exports.triggerAllSimulationUpdates = exports.getProcessorLiveUpdateConfig = exports.getNodeLiveUpdateConfig = exports.getBookingLiveUpdateConfig = exports.getVehicleLiveUpdateConfig = exports.PROCESSOR_LIVE_UPDATE_PARAMS = exports.LIVE_UPDATE_INTERVALS = exports.processUnassignResponse = exports.recalculateVehicleRoute = exports.hasRouteChanged = exports.calculateVehicleRoute = exports.shiftWaypointTimestamps = exports.shiftNodeTimestamps = exports.buildVehicleRouteMap = exports.vehicleComplexRearrange = exports.calculateBoundingBoxCenter = exports.attachReferences = exports.createIndexMaps = exports.fetchVRPToolboxData = exports.fetchSimulationData = exports.fetchOperationsLocationsByProject = exports.fetchDriversByProject = exports.fetchDrivers = exports.fetchNodes = exports.fetchBookings = exports.fetchVehicles = void 0;
8
8
  var fetchUtils_1 = require("./fetchUtils");
9
9
  Object.defineProperty(exports, "fetchVehicles", { enumerable: true, get: function () { return fetchUtils_1.fetchVehicles; } });
10
10
  Object.defineProperty(exports, "fetchBookings", { enumerable: true, get: function () { return fetchUtils_1.fetchBookings; } });
@@ -13,6 +13,7 @@ Object.defineProperty(exports, "fetchDrivers", { enumerable: true, get: function
13
13
  Object.defineProperty(exports, "fetchDriversByProject", { enumerable: true, get: function () { return fetchUtils_1.fetchDriversByProject; } });
14
14
  Object.defineProperty(exports, "fetchOperationsLocationsByProject", { enumerable: true, get: function () { return fetchUtils_1.fetchOperationsLocationsByProject; } });
15
15
  Object.defineProperty(exports, "fetchSimulationData", { enumerable: true, get: function () { return fetchUtils_1.fetchSimulationData; } });
16
+ Object.defineProperty(exports, "fetchVRPToolboxData", { enumerable: true, get: function () { return fetchUtils_1.fetchVRPToolboxData; } });
16
17
  var referenceUtils_1 = require("./referenceUtils");
17
18
  Object.defineProperty(exports, "createIndexMaps", { enumerable: true, get: function () { return referenceUtils_1.createIndexMaps; } });
18
19
  Object.defineProperty(exports, "attachReferences", { enumerable: true, get: function () { return referenceUtils_1.attachReferences; } });
@@ -38,3 +39,10 @@ Object.defineProperty(exports, "getBookingLiveUpdateConfig", { enumerable: true,
38
39
  Object.defineProperty(exports, "getNodeLiveUpdateConfig", { enumerable: true, get: function () { return liveUpdates_1.getNodeLiveUpdateConfig; } });
39
40
  Object.defineProperty(exports, "getProcessorLiveUpdateConfig", { enumerable: true, get: function () { return liveUpdates_1.getProcessorLiveUpdateConfig; } });
40
41
  Object.defineProperty(exports, "triggerAllSimulationUpdates", { enumerable: true, get: function () { return liveUpdates_1.triggerAllSimulationUpdates; } });
42
+ var vrpStatsCalculator_1 = require("./vrpStatsCalculator");
43
+ Object.defineProperty(exports, "processVRPStatistics", { enumerable: true, get: function () { return vrpStatsCalculator_1.processVRPStatistics; } });
44
+ Object.defineProperty(exports, "calculateFleetStats", { enumerable: true, get: function () { return vrpStatsCalculator_1.calculateFleetStats; } });
45
+ var vrpStatsUtils_1 = require("./vrpStatsUtils");
46
+ Object.defineProperty(exports, "formatSeconds", { enumerable: true, get: function () { return vrpStatsUtils_1.formatSeconds; } });
47
+ Object.defineProperty(exports, "getDistanceFromLatLonInKm", { enumerable: true, get: function () { return vrpStatsUtils_1.getDistanceFromLatLonInKm; } });
48
+ Object.defineProperty(exports, "toDisplayDate", { enumerable: true, get: function () { return vrpStatsUtils_1.toDisplayDate; } });
@@ -0,0 +1,52 @@
1
+ /**
2
+ * VRPToolbox Statistics Calculator
3
+ * Processes VRP payload and result to calculate fleet statistics, timeline data, and utilization
4
+ */
5
+ export interface ProcessedNode {
6
+ uid?: string;
7
+ lat: number;
8
+ lon: number;
9
+ scheduled_ts: string;
10
+ location_name?: string;
11
+ node_type: string;
12
+ service_time: number;
13
+ travel_time_from_prev: number;
14
+ nodeBreakDuration: number;
15
+ adjustedSlack: number;
16
+ booking_uid?: string;
17
+ slack?: number;
18
+ demand?: Record<string, number>;
19
+ open_time_ts?: string;
20
+ close_time_ts?: string;
21
+ scheduled_cumulative_dist?: number;
22
+ }
23
+ export interface VRPVehicleStats {
24
+ vehicleId: string;
25
+ vehicleName: string;
26
+ timelineWaypoints: ProcessedNode[];
27
+ utilizationData: Array<{
28
+ time: string;
29
+ utilization: number;
30
+ }>;
31
+ color: string;
32
+ totalDistance: string;
33
+ totalTime: string;
34
+ totalSlack: string;
35
+ totalBreakTime: string;
36
+ totalDrivingTime: string;
37
+ }
38
+ export interface FleetStats {
39
+ totalSlack: string;
40
+ totalDistance: string;
41
+ totalDrivingTime: string;
42
+ totalBreakTime: string;
43
+ }
44
+ /**
45
+ * Calculate fleet-wide statistics from processed vehicles
46
+ */
47
+ export declare function calculateFleetStats(vehicles: VRPVehicleStats[]): FleetStats;
48
+ /**
49
+ * Process VRP result and payload to generate vehicle statistics
50
+ */
51
+ export declare function processVRPStatistics(result: any, payload: any): Promise<VRPVehicleStats[]>;
52
+ //# sourceMappingURL=vrpStatsCalculator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vrpStatsCalculator.d.ts","sourceRoot":"","sources":["../../../sgerplib/sgerp/simulation-logic/vrpStatsCalculator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,WAAW,aAAa;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,yBAAyB,CAAC,EAAE,MAAM,CAAC;CACpC;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,aAAa,EAAE,CAAC;IACnC,eAAe,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9D,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;CACxB;AAaD;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,eAAe,EAAE,GAAG,UAAU,CAsB3E;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,GAAG,EACX,OAAO,EAAE,GAAG,GACX,OAAO,CAAC,eAAe,EAAE,CAAC,CAsR5B"}
@@ -0,0 +1,247 @@
1
+ "use strict";
2
+ /**
3
+ * VRPToolbox Statistics Calculator
4
+ * Processes VRP payload and result to calculate fleet statistics, timeline data, and utilization
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.calculateFleetStats = calculateFleetStats;
8
+ exports.processVRPStatistics = processVRPStatistics;
9
+ const vrpStatsUtils_1 = require("./vrpStatsUtils");
10
+ const VEHICLE_COLORS = [
11
+ 'red',
12
+ 'blue',
13
+ 'green',
14
+ 'orange',
15
+ 'purple',
16
+ 'brown',
17
+ 'magenta',
18
+ 'teal',
19
+ ];
20
+ /**
21
+ * Calculate fleet-wide statistics from processed vehicles
22
+ */
23
+ function calculateFleetStats(vehicles) {
24
+ let totalSlack = 0;
25
+ let totalDistance = 0;
26
+ let totalDrivingTime = 0;
27
+ let totalBreakTime = 0;
28
+ vehicles.forEach((vehicle) => {
29
+ totalDistance += parseFloat(vehicle.totalDistance || '0');
30
+ vehicle.timelineWaypoints.forEach((wp) => {
31
+ totalSlack += wp.adjustedSlack || 0;
32
+ totalDrivingTime += wp.travel_time_from_prev || 0;
33
+ totalBreakTime += wp.nodeBreakDuration || 0;
34
+ });
35
+ });
36
+ return {
37
+ totalSlack: (0, vrpStatsUtils_1.formatSeconds)(totalSlack),
38
+ totalDistance: totalDistance.toFixed(2),
39
+ totalDrivingTime: (0, vrpStatsUtils_1.formatSeconds)(totalDrivingTime),
40
+ totalBreakTime: (0, vrpStatsUtils_1.formatSeconds)(totalBreakTime),
41
+ };
42
+ }
43
+ /**
44
+ * Process VRP result and payload to generate vehicle statistics
45
+ */
46
+ async function processVRPStatistics(result, payload) {
47
+ if (!result || !result.vehicles) {
48
+ console.warn('No vehicles in result', result);
49
+ return [];
50
+ }
51
+ const inputVehicles = (payload === null || payload === void 0 ? void 0 : payload.vehicles) || [];
52
+ const vehicleList = Array.isArray(result.vehicles)
53
+ ? result.vehicles
54
+ .filter((v) => v.nodes && v.nodes.length > 0) // Only vehicles with nodes
55
+ .map((v) => ({
56
+ agent_id: v.agent_id,
57
+ nodes: v.nodes,
58
+ }))
59
+ : Object.entries(result.vehicles)
60
+ .filter(([id, nodes]) => nodes && nodes.length > 0) // Only vehicles with nodes
61
+ .map(([id, nodes]) => ({
62
+ agent_id: id,
63
+ nodes: nodes,
64
+ }));
65
+ const vehicles = await Promise.all(vehicleList.map(async (vehicleData, index) => {
66
+ var _a, _b, _c, _d;
67
+ const inputVehicle = inputVehicles.find((v) => v.agent_id === vehicleData.agent_id);
68
+ let vehicleBreakDuration = 0;
69
+ if (inputVehicle &&
70
+ typeof inputVehicle.dynamic_break_duration === 'number') {
71
+ vehicleBreakDuration = inputVehicle.dynamic_break_duration;
72
+ }
73
+ let sortedNodes = JSON.parse(JSON.stringify(vehicleData.nodes));
74
+ sortedNodes.sort((a, b) => new Date(a.scheduled_ts).getTime() - new Date(b.scheduled_ts).getTime());
75
+ // Add start/end nodes if vehicle has start/end times
76
+ if (inputVehicle) {
77
+ if (inputVehicle.start_time) {
78
+ const startNode = ((payload === null || payload === void 0 ? void 0 : payload.nodes) || []).find((n) => { var _a; return n.uid === ((_a = inputVehicle.partial_route) === null || _a === void 0 ? void 0 : _a[0]); }) || vehicleData.nodes[0];
79
+ if (startNode) {
80
+ sortedNodes.unshift({
81
+ lat: startNode.lat,
82
+ lon: startNode.lon,
83
+ scheduled_ts: inputVehicle.start_time,
84
+ location_name: 'Start',
85
+ node_type: 'vehicle_start',
86
+ service_time: 0,
87
+ });
88
+ }
89
+ }
90
+ if (inputVehicle.end_time) {
91
+ const lastRouteUid = (_a = inputVehicle.partial_route) === null || _a === void 0 ? void 0 : _a[((_b = inputVehicle.partial_route) === null || _b === void 0 ? void 0 : _b.length) - 1];
92
+ const endNode = ((payload === null || payload === void 0 ? void 0 : payload.nodes) || []).find((n) => n.uid === lastRouteUid) ||
93
+ vehicleData.nodes[vehicleData.nodes.length - 1];
94
+ if (endNode) {
95
+ sortedNodes.push({
96
+ lat: endNode.lat,
97
+ lon: endNode.lon,
98
+ scheduled_ts: inputVehicle.end_time,
99
+ location_name: 'End',
100
+ node_type: 'vehicle_end',
101
+ service_time: 0,
102
+ });
103
+ }
104
+ }
105
+ }
106
+ // Process nodes with travel times, breaks, and slack
107
+ const processedNodes = sortedNodes.map((node, idx, array) => {
108
+ const prevNode = array[idx - 1];
109
+ let prevNodeDepartureTime;
110
+ if (prevNode) {
111
+ let prevNodeActualBreakDuration = 0;
112
+ let prevNodeEffectiveSlack = 0;
113
+ if (typeof prevNode.dynamic_break_time === 'number') {
114
+ prevNodeActualBreakDuration = prevNode.dynamic_break_time;
115
+ prevNodeEffectiveSlack = prevNode.slack || 0;
116
+ }
117
+ else {
118
+ const prevNodeBreakCount = prevNode.dynamic_break || 0;
119
+ prevNodeActualBreakDuration =
120
+ prevNodeBreakCount * vehicleBreakDuration;
121
+ prevNodeEffectiveSlack = Math.max(0, (prevNode.slack || 0) - prevNodeActualBreakDuration);
122
+ }
123
+ const prevScheduled = new Date(prevNode.scheduled_ts);
124
+ const departureMs = prevScheduled.getTime() +
125
+ ((prevNode.service_time || 0) +
126
+ prevNodeEffectiveSlack +
127
+ prevNodeActualBreakDuration) *
128
+ 1000;
129
+ prevNodeDepartureTime = new Date(departureMs);
130
+ }
131
+ let travel_time_from_prev = 0;
132
+ if (prevNode && node.node_type !== 'vehicle_end') {
133
+ const nodeScheduled = new Date(node.scheduled_ts);
134
+ if (prevNodeDepartureTime) {
135
+ travel_time_from_prev =
136
+ (nodeScheduled.getTime() - prevNodeDepartureTime.getTime()) /
137
+ 1000;
138
+ }
139
+ }
140
+ let nodeBreakDuration = 0;
141
+ let adjustedSlack = 0;
142
+ if (typeof node.dynamic_break_time === 'number') {
143
+ nodeBreakDuration = node.dynamic_break_time;
144
+ adjustedSlack = node.slack || 0;
145
+ }
146
+ else {
147
+ const nodeBreakCount = node.dynamic_break || 0;
148
+ nodeBreakDuration = nodeBreakCount * vehicleBreakDuration;
149
+ adjustedSlack = Math.max(0, (node.slack || 0) - nodeBreakDuration);
150
+ }
151
+ return Object.assign(Object.assign({}, node), { travel_time_from_prev,
152
+ nodeBreakDuration,
153
+ adjustedSlack, service_time: node.service_time || 0 });
154
+ });
155
+ // Calculate total distance (try multiple methods)
156
+ let totalDistance = 0;
157
+ const lastNode = processedNodes[processedNodes.length - 1];
158
+ // Method 1: Use scheduled_cumulative_dist if available
159
+ if (lastNode &&
160
+ typeof lastNode.scheduled_cumulative_dist === 'number') {
161
+ totalDistance = lastNode.scheduled_cumulative_dist / 1000;
162
+ }
163
+ // Method 2: Fallback to Euclidean distance
164
+ else if (processedNodes.length > 1) {
165
+ for (let i = 1; i < processedNodes.length; i++) {
166
+ const prev = processedNodes[i - 1];
167
+ const curr = processedNodes[i];
168
+ totalDistance += (0, vrpStatsUtils_1.getDistanceFromLatLonInKm)(prev.lat, prev.lon, curr.lat, curr.lon);
169
+ }
170
+ }
171
+ // Calculate total time
172
+ let totalTime = 0;
173
+ if (processedNodes.length > 0 && lastNode) {
174
+ const startTime = new Date(processedNodes[0].scheduled_ts);
175
+ const endTime = new Date(lastNode.scheduled_ts);
176
+ totalTime = (endTime.getTime() - startTime.getTime()) / 1000;
177
+ }
178
+ // Calculate utilization over time
179
+ const utilizationData = [];
180
+ const vehicleCapacity = (inputVehicle === null || inputVehicle === void 0 ? void 0 : inputVehicle.capacity) || (inputVehicle === null || inputVehicle === void 0 ? void 0 : inputVehicle.limits) || {};
181
+ const totalCapacity = Object.values(vehicleCapacity).reduce((sum, val) => sum + val, 0);
182
+ const currentLoad = {};
183
+ // Initialize load for prebook_cvrptw mode
184
+ if (((_d = (_c = payload.engine_settings) === null || _c === void 0 ? void 0 : _c.calculation_parameters) === null || _d === void 0 ? void 0 : _d.scheduling_mode) ===
185
+ 'prebook_cvrptw') {
186
+ const inputNodes = payload.nodes || [];
187
+ const allDemands = inputNodes
188
+ .filter((n) => n.node_type === 'dropoff' &&
189
+ n.demand &&
190
+ vehicleData.nodes.some((vn) => vn.booking_uid && vn.booking_uid === n.booking_uid))
191
+ .flatMap((n) => Object.entries(n.demand));
192
+ for (const [key, value] of allDemands) {
193
+ currentLoad[key] = (currentLoad[key] || 0) + Math.abs(value);
194
+ }
195
+ }
196
+ else {
197
+ Object.keys(vehicleCapacity).forEach((key) => (currentLoad[key] = 0));
198
+ }
199
+ // Track utilization at each node
200
+ processedNodes.forEach((node) => {
201
+ const originalNode = (payload.nodes || []).find((n) => n.uid === node.uid || n.id === node.uid);
202
+ if (originalNode === null || originalNode === void 0 ? void 0 : originalNode.demand) {
203
+ if (node.node_type === 'dropoff') {
204
+ for (const [key, value] of Object.entries(originalNode.demand)) {
205
+ currentLoad[key] =
206
+ (currentLoad[key] || 0) - Math.abs(value);
207
+ }
208
+ }
209
+ else if (node.node_type === 'pickup') {
210
+ for (const [key, value] of Object.entries(originalNode.demand)) {
211
+ currentLoad[key] =
212
+ (currentLoad[key] || 0) + Math.abs(value);
213
+ }
214
+ }
215
+ }
216
+ let utilizationAfter = 0;
217
+ if (totalCapacity > 0) {
218
+ const totalLoad = Object.values(currentLoad).reduce((sum, val) => sum + val, 0);
219
+ utilizationAfter = (totalLoad / totalCapacity) * 100;
220
+ }
221
+ utilizationData.push({
222
+ time: node.scheduled_ts,
223
+ utilization: Math.max(0, Math.min(100, utilizationAfter)),
224
+ });
225
+ });
226
+ // Calculate vehicle-specific stats
227
+ const vehicleStats = processedNodes.reduce((acc, node) => {
228
+ acc.slack += node.adjustedSlack || 0;
229
+ acc.breakTime += node.nodeBreakDuration || 0;
230
+ acc.drivingTime += node.travel_time_from_prev || 0;
231
+ return acc;
232
+ }, { slack: 0, breakTime: 0, drivingTime: 0 });
233
+ return {
234
+ vehicleId: vehicleData.agent_id,
235
+ vehicleName: (inputVehicle === null || inputVehicle === void 0 ? void 0 : inputVehicle.service_number) || vehicleData.agent_id,
236
+ timelineWaypoints: processedNodes,
237
+ utilizationData: utilizationData,
238
+ color: VEHICLE_COLORS[index % VEHICLE_COLORS.length],
239
+ totalDistance: totalDistance.toFixed(2),
240
+ totalTime: (0, vrpStatsUtils_1.formatSeconds)(totalTime),
241
+ totalSlack: (0, vrpStatsUtils_1.formatSeconds)(vehicleStats.slack),
242
+ totalBreakTime: (0, vrpStatsUtils_1.formatSeconds)(vehicleStats.breakTime),
243
+ totalDrivingTime: (0, vrpStatsUtils_1.formatSeconds)(vehicleStats.drivingTime),
244
+ };
245
+ }));
246
+ return vehicles;
247
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * VRPToolbox Statistics Utilities
3
+ * Helper functions for calculating and formatting VRP statistics
4
+ */
5
+ /**
6
+ * Format seconds into HH:MM:SS format
7
+ */
8
+ export declare function formatSeconds(seconds: number): string;
9
+ /**
10
+ * Calculate distance between two lat/lon coordinates in kilometers (Haversine formula)
11
+ */
12
+ export declare function getDistanceFromLatLonInKm(lat1: number, lon1: number, lat2: number, lon2: number): number;
13
+ /**
14
+ * Convert timestamp to display Date (handles timezone conversions)
15
+ */
16
+ export declare function toDisplayDate(ts: string): Date;
17
+ //# sourceMappingURL=vrpStatsUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vrpStatsUtils.d.ts","sourceRoot":"","sources":["../../../sgerplib/sgerp/simulation-logic/vrpStatsUtils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAUrD;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,GACX,MAAM,CAaR;AAMD;;GAEG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAc9C"}
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ /**
3
+ * VRPToolbox Statistics Utilities
4
+ * Helper functions for calculating and formatting VRP statistics
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.formatSeconds = formatSeconds;
8
+ exports.getDistanceFromLatLonInKm = getDistanceFromLatLonInKm;
9
+ exports.toDisplayDate = toDisplayDate;
10
+ /**
11
+ * Format seconds into HH:MM:SS format
12
+ */
13
+ function formatSeconds(seconds) {
14
+ const hours = Math.floor(seconds / 3600);
15
+ const minutes = Math.floor((seconds % 3600) / 60);
16
+ const remainingSeconds = Math.floor(seconds % 60);
17
+ const formattedHours = String(hours).padStart(2, '0');
18
+ const formattedMinutes = String(minutes).padStart(2, '0');
19
+ const formattedSeconds = String(remainingSeconds).padStart(2, '0');
20
+ return `${formattedHours}:${formattedMinutes}:${formattedSeconds}`;
21
+ }
22
+ /**
23
+ * Calculate distance between two lat/lon coordinates in kilometers (Haversine formula)
24
+ */
25
+ function getDistanceFromLatLonInKm(lat1, lon1, lat2, lon2) {
26
+ const R = 6371; // Earth's radius in km
27
+ const dLat = deg2rad(lat2 - lat1);
28
+ const dLon = deg2rad(lon2 - lon1);
29
+ const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
30
+ Math.cos(deg2rad(lat1)) *
31
+ Math.cos(deg2rad(lat2)) *
32
+ Math.sin(dLon / 2) *
33
+ Math.sin(dLon / 2);
34
+ const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
35
+ const d = R * c;
36
+ return d;
37
+ }
38
+ function deg2rad(deg) {
39
+ return deg * (Math.PI / 180);
40
+ }
41
+ /**
42
+ * Convert timestamp to display Date (handles timezone conversions)
43
+ */
44
+ function toDisplayDate(ts) {
45
+ // Parse as UTC and return as local Date object
46
+ const date = new Date(ts);
47
+ return new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds(), date.getUTCMilliseconds()));
48
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Timezone utility functions
3
+ */
4
+ /**
5
+ * Get the effective timezone based on the current mode
6
+ * In VRPToolbox mode, uses the VRP timezone selector
7
+ * Otherwise, uses the project timezone (or falls back to UTC)
8
+ *
9
+ * @param mode - The current effective mode ('vrptoolbox' or other)
10
+ * @param vrpTimezone - The timezone selected in VRPToolbox mode
11
+ * @param projectTimezone - The project's configured timezone
12
+ * @returns The effective timezone string (e.g., 'UTC', 'Asia/Singapore')
13
+ */
14
+ export declare function getEffectiveTimezone(mode: string, vrpTimezone: string, projectTimezone?: string): string;
15
+ //# sourceMappingURL=timezone.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timezone.d.ts","sourceRoot":"","sources":["../../../sgerplib/sgerp/utils/timezone.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,eAAe,CAAC,EAAE,MAAM,GACvB,MAAM,CAER"}