@agent-play/sdk 3.4.1 → 3.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -17,6 +17,22 @@ var MINIMUM_STREET_LAYOUT_BOUNDS = {
17
17
  maxX: 19,
18
18
  maxY: 2
19
19
  };
20
+ var COLUMN_STREET_ROW_HEIGHT = 3;
21
+ var PARKING_STREET_ROW_HEIGHT = 4;
22
+ var PARKING_COLUMN_GAP_ROWS = 2.5;
23
+ var parkingZoneMinYFromColumnBase = (columnMinY) => {
24
+ const columnMaxY = columnMinY + COLUMN_STREET_ROW_HEIGHT - 1;
25
+ return Math.ceil(columnMaxY + 1 + PARKING_COLUMN_GAP_ROWS);
26
+ };
27
+ var parkingZoneMaxYFromColumnBase = (columnMinY) => {
28
+ return parkingZoneMinYFromColumnBase(columnMinY) + PARKING_STREET_ROW_HEIGHT - 1;
29
+ };
30
+ var DEFAULT_LAYOUT_BOUNDS_WITH_PARKING = {
31
+ minX: 0,
32
+ minY: 0,
33
+ maxX: 19,
34
+ maxY: parkingZoneMaxYFromColumnBase(0)
35
+ };
20
36
  function expandBoundsToMinimumPlayArea(bounds) {
21
37
  return {
22
38
  minX: Math.min(bounds.minX, MINIMUM_PLAY_WORLD_BOUNDS.minX),
@@ -264,6 +280,64 @@ function getStreetPoolEntryById(id) {
264
280
  }
265
281
 
266
282
  // src/lib/world-layout-model.ts
283
+ var LEGACY_MCP_PRIMARY_GROUP = "mcp";
284
+ function normalizeLegacyOccupantGroup(value) {
285
+ if (value === LEGACY_MCP_PRIMARY_GROUP) {
286
+ return "arcade";
287
+ }
288
+ if (value === "agent" || value === "space" || value === "arcade" || value === "parking") {
289
+ return value;
290
+ }
291
+ throw new Error(
292
+ `normalizeLegacyWorldLayout: unknown primaryGroup ${value}`
293
+ );
294
+ }
295
+ function migrateLegacyWorldLayoutZone(zone) {
296
+ const rawPrimary = String(zone.primaryGroup);
297
+ const primaryGroup = normalizeLegacyOccupantGroup(rawPrimary);
298
+ const id = zone.id === "zone-mcp-strip" || rawPrimary === LEGACY_MCP_PRIMARY_GROUP ? primaryGroup === "arcade" ? "zone-arcade-strip" : zone.id : zone.id;
299
+ const allowedGroups = [
300
+ ...new Set(
301
+ zone.allowedGroups.map(
302
+ (group) => normalizeLegacyOccupantGroup(String(group))
303
+ )
304
+ )
305
+ ];
306
+ return { ...zone, id, primaryGroup, allowedGroups };
307
+ }
308
+ function threeStreetsFromLayoutOrPool(layout) {
309
+ if (layout.streets.length >= 3) {
310
+ const s0 = layout.streets[0];
311
+ const s1 = layout.streets[1];
312
+ const s2 = layout.streets[2];
313
+ if (s0 !== void 0 && s1 !== void 0 && s2 !== void 0) {
314
+ return [
315
+ { id: s0.id, label: s0.label },
316
+ { id: s1.id, label: s1.label },
317
+ { id: s2.id, label: s2.label }
318
+ ];
319
+ }
320
+ }
321
+ const a = STREET_NAME_POOL[0];
322
+ const b = STREET_NAME_POOL[1];
323
+ const c = STREET_NAME_POOL[2];
324
+ if (a === void 0 || b === void 0 || c === void 0) {
325
+ throw new Error("normalizeLegacyWorldLayout: STREET_NAME_POOL too small");
326
+ }
327
+ return [a, b, c];
328
+ }
329
+ function normalizeLegacyWorldLayout(layout) {
330
+ const migratedZones = layout.zones.map(migrateLegacyWorldLayoutZone);
331
+ if (migratedZones.some((zone) => zone.primaryGroup === "arcade")) {
332
+ return { ...layout, zones: migratedZones };
333
+ }
334
+ const streets = threeStreetsFromLayoutOrPool(layout);
335
+ const rebuilt = createVerticalStripSeedLayout({
336
+ bounds: layout.bounds,
337
+ streets
338
+ });
339
+ return { ...rebuilt, rev: layout.rev };
340
+ }
267
341
  function streetFromPoolEntry(entry) {
268
342
  return { id: entry.id, label: entry.label };
269
343
  }
@@ -382,7 +456,88 @@ function assertValidLayoutBounds(bounds) {
382
456
  );
383
457
  }
384
458
  }
385
- var PRIMARY_GROUP_ORDER = ["agent", "space", "arcade"];
459
+ var PRIMARY_GROUP_ORDER = [
460
+ "agent",
461
+ "space",
462
+ "arcade"
463
+ ];
464
+ function partitionColumnWidths(spanX) {
465
+ if (spanX === 20) {
466
+ return [7, 7, 6];
467
+ }
468
+ const w0 = Math.floor(spanX / 3);
469
+ const w1 = Math.floor((spanX - w0) / 2);
470
+ const w2 = spanX - w0 - w1;
471
+ return [w0, w1, w2];
472
+ }
473
+ function buildColumnZones(input) {
474
+ const { minX, maxX } = input.bounds;
475
+ const spanX = maxX - minX + 1;
476
+ const widths = partitionColumnWidths(spanX);
477
+ const w0 = widths[0];
478
+ const w1 = widths[1];
479
+ const w2 = widths[2];
480
+ if (w0 === void 0 || w1 === void 0 || w2 === void 0) {
481
+ throw new Error("buildColumnZones: width partition failed");
482
+ }
483
+ const x0 = minX;
484
+ const x0Max = x0 + w0 - 1;
485
+ const x1 = x0Max + 1;
486
+ const x1Max = x1 + w1 - 1;
487
+ const x2 = x1Max + 1;
488
+ const x2Max = x2 + w2 - 1;
489
+ const s0 = input.streets[0];
490
+ const s1 = input.streets[1];
491
+ const s2 = input.streets[2];
492
+ if (s0 === void 0 || s1 === void 0 || s2 === void 0) {
493
+ throw new Error("buildColumnZones: expected three streets");
494
+ }
495
+ const { columnMinY, columnMaxY } = input;
496
+ return [
497
+ {
498
+ id: "zone-agent-strip",
499
+ streetId: s0.id,
500
+ streetLabel: s0.label,
501
+ rect: { minX: x0, maxX: x0Max, minY: columnMinY, maxY: columnMaxY },
502
+ primaryGroup: "agent",
503
+ allowedGroups: ["agent"]
504
+ },
505
+ {
506
+ id: "zone-space-strip",
507
+ streetId: s1.id,
508
+ streetLabel: s1.label,
509
+ rect: { minX: x1, maxX: x1Max, minY: columnMinY, maxY: columnMaxY },
510
+ primaryGroup: "space",
511
+ allowedGroups: ["space"]
512
+ },
513
+ {
514
+ id: "zone-arcade-strip",
515
+ streetId: s2.id,
516
+ streetLabel: s2.label,
517
+ rect: { minX: x2, maxX: x2Max, minY: columnMinY, maxY: columnMaxY },
518
+ primaryGroup: "arcade",
519
+ allowedGroups: ["arcade"]
520
+ }
521
+ ];
522
+ }
523
+ function layoutHasParkingZone(layout) {
524
+ return layout.zones.some((z) => z.primaryGroup === "parking");
525
+ }
526
+ function streetsFromLayoutWithParking(layout) {
527
+ const agent = primaryZoneForGroup(layout, "agent");
528
+ const space = primaryZoneForGroup(layout, "space");
529
+ const arcade = primaryZoneForGroup(layout, "arcade");
530
+ const parking = primaryZoneForGroup(layout, "parking");
531
+ if (agent === void 0 || space === void 0 || arcade === void 0 || parking === void 0) {
532
+ throw new Error("streetsFromLayoutWithParking: missing primary zone");
533
+ }
534
+ return [
535
+ { id: agent.streetId, label: agent.streetLabel },
536
+ { id: space.streetId, label: space.streetLabel },
537
+ { id: arcade.streetId, label: arcade.streetLabel },
538
+ { id: parking.streetId, label: parking.streetLabel }
539
+ ];
540
+ }
386
541
  function streetsFromLayoutPrimaryGroups(layout) {
387
542
  const picks = PRIMARY_GROUP_ORDER.map((g) => {
388
543
  const zone = primaryZoneForGroup(layout, g);
@@ -403,6 +558,14 @@ function streetsFromLayoutPrimaryGroups(layout) {
403
558
  }
404
559
  function migrateWorldLayoutBounds(input) {
405
560
  assertValidLayoutBounds(input.bounds);
561
+ if (layoutHasParkingZone(input.layout)) {
562
+ const streets2 = streetsFromLayoutWithParking(input.layout);
563
+ const reseeded2 = createWorldLayoutWithParkingRow({
564
+ bounds: input.bounds,
565
+ streets: streets2
566
+ });
567
+ return { ...reseeded2, rev: input.layout.rev + 1 };
568
+ }
406
569
  const streets = streetsFromLayoutPrimaryGroups(input.layout);
407
570
  const reseeded = createVerticalStripSeedLayout({
408
571
  bounds: input.bounds,
@@ -410,6 +573,72 @@ function migrateWorldLayoutBounds(input) {
410
573
  });
411
574
  return { ...reseeded, rev: input.layout.rev + 1 };
412
575
  }
576
+ function layoutNeedsParkingColumnGapMigration(layout) {
577
+ if (!layoutHasParkingZone(layout)) {
578
+ return false;
579
+ }
580
+ const agent = primaryZoneForGroup(layout, "agent");
581
+ const parking = primaryZoneForGroup(layout, "parking");
582
+ if (agent === void 0 || parking === void 0) {
583
+ return false;
584
+ }
585
+ const expectedParkingMinY = parkingZoneMinYFromColumnBase(agent.rect.minY);
586
+ return parking.rect.minY < expectedParkingMinY;
587
+ }
588
+ function migrateLayoutToParkingColumnGap(layout) {
589
+ const normalized = normalizeLegacyWorldLayout(layout);
590
+ if (!layoutNeedsParkingColumnGapMigration(normalized)) {
591
+ return normalized;
592
+ }
593
+ const streets = streetsFromLayoutWithParking(normalized);
594
+ const { minX, minY, maxX } = normalized.bounds;
595
+ const requiredMaxY = parkingZoneMaxYFromColumnBase(minY);
596
+ const nextBounds = {
597
+ minX,
598
+ minY,
599
+ maxX,
600
+ maxY: Math.max(normalized.bounds.maxY, requiredMaxY)
601
+ };
602
+ const reseeded = createWorldLayoutWithParkingRow({
603
+ bounds: nextBounds,
604
+ streets
605
+ });
606
+ return { ...reseeded, rev: normalized.rev + 1 };
607
+ }
608
+ function migrateLayoutToParkingRow(layout) {
609
+ const normalized = normalizeLegacyWorldLayout(layout);
610
+ if (layoutHasParkingZone(normalized)) {
611
+ return normalized;
612
+ }
613
+ const agent = primaryZoneForGroup(normalized, "agent");
614
+ const space = primaryZoneForGroup(normalized, "space");
615
+ const arcade = primaryZoneForGroup(normalized, "arcade");
616
+ if (agent === void 0 || space === void 0 || arcade === void 0) {
617
+ throw new Error("migrateLayoutToParkingRow: missing column zone");
618
+ }
619
+ const parkingStreet = nextStreetFromPool(
620
+ new Set(normalized.streets.map((s) => s.id))
621
+ );
622
+ if (parkingStreet === void 0) {
623
+ throw new Error("migrateLayoutToParkingRow: no street available in pool");
624
+ }
625
+ const nextBounds = {
626
+ ...normalized.bounds,
627
+ maxY: Math.max(
628
+ normalized.bounds.maxY,
629
+ parkingZoneMaxYFromColumnBase(normalized.bounds.minY)
630
+ )
631
+ };
632
+ return createWorldLayoutWithParkingRow({
633
+ bounds: nextBounds,
634
+ streets: [
635
+ { id: agent.streetId, label: agent.streetLabel },
636
+ { id: space.streetId, label: space.streetLabel },
637
+ { id: arcade.streetId, label: arcade.streetLabel },
638
+ parkingStreet
639
+ ]
640
+ });
641
+ }
413
642
  function applyBoundsFieldUpdateToLayout(input) {
414
643
  assertIntegerBoundsValue(input.value, input.field);
415
644
  const nextBounds = {
@@ -419,61 +648,19 @@ function applyBoundsFieldUpdateToLayout(input) {
419
648
  return migrateWorldLayoutBounds({ layout: input.layout, bounds: nextBounds });
420
649
  }
421
650
  function createVerticalStripSeedLayout(input) {
422
- const { minX, maxX, minY, maxY } = input.bounds;
423
- const spanX = maxX - minX + 1;
424
- if (spanX < 3) {
425
- throw new Error("createVerticalStripSeedLayout: bounds spanX too small");
426
- }
427
- const widths = spanX === 20 ? [7, 7, 6] : (() => {
428
- const w02 = Math.floor(spanX / 3);
429
- const w12 = Math.floor((spanX - w02) / 2);
430
- const w22 = spanX - w02 - w12;
431
- return [w02, w12, w22];
432
- })();
433
- const w0 = widths[0];
434
- const w1 = widths[1];
435
- const w2 = widths[2];
436
- if (w0 === void 0 || w1 === void 0 || w2 === void 0) {
437
- throw new Error("createVerticalStripSeedLayout: width partition failed");
438
- }
439
- const x0 = minX;
440
- const x0Max = x0 + w0 - 1;
441
- const x1 = x0Max + 1;
442
- const x1Max = x1 + w1 - 1;
443
- const x2 = x1Max + 1;
444
- const x2Max = x2 + w2 - 1;
651
+ const { minY, maxY } = input.bounds;
652
+ const zones = buildColumnZones({
653
+ bounds: input.bounds,
654
+ columnMinY: minY,
655
+ columnMaxY: maxY,
656
+ streets: input.streets
657
+ });
445
658
  const s0 = input.streets[0];
446
659
  const s1 = input.streets[1];
447
660
  const s2 = input.streets[2];
448
661
  if (s0 === void 0 || s1 === void 0 || s2 === void 0) {
449
662
  throw new Error("createVerticalStripSeedLayout: expected three streets");
450
663
  }
451
- const zones = [
452
- {
453
- id: "zone-agent-strip",
454
- streetId: s0.id,
455
- streetLabel: s0.label,
456
- rect: { minX: x0, maxX: x0Max, minY, maxY },
457
- primaryGroup: "agent",
458
- allowedGroups: ["agent"]
459
- },
460
- {
461
- id: "zone-space-strip",
462
- streetId: s1.id,
463
- streetLabel: s1.label,
464
- rect: { minX: x1, maxX: x1Max, minY, maxY },
465
- primaryGroup: "space",
466
- allowedGroups: ["space"]
467
- },
468
- {
469
- id: "zone-arcade-strip",
470
- streetId: s2.id,
471
- streetLabel: s2.label,
472
- rect: { minX: x2, maxX: x2Max, minY, maxY },
473
- primaryGroup: "arcade",
474
- allowedGroups: ["arcade"]
475
- }
476
- ];
477
664
  const streets = [
478
665
  streetFromPoolEntry(s0),
479
666
  streetFromPoolEntry(s1),
@@ -486,6 +673,62 @@ function createVerticalStripSeedLayout(input) {
486
673
  streets
487
674
  };
488
675
  }
676
+ function createWorldLayoutWithParkingRow(input) {
677
+ const { minX, maxX, minY, maxY } = input.bounds;
678
+ const spanX = maxX - minX + 1;
679
+ if (spanX < 3) {
680
+ throw new Error("createWorldLayoutWithParkingRow: bounds spanX too small");
681
+ }
682
+ const requiredSpanY = Math.ceil(
683
+ COLUMN_STREET_ROW_HEIGHT + PARKING_COLUMN_GAP_ROWS + PARKING_STREET_ROW_HEIGHT
684
+ );
685
+ const actualSpanY = maxY - minY + 1;
686
+ if (actualSpanY < requiredSpanY) {
687
+ throw new Error(
688
+ `createWorldLayoutWithParkingRow: spanY must be >= ${String(requiredSpanY)}`
689
+ );
690
+ }
691
+ const columnMinY = minY;
692
+ const columnMaxY = minY + COLUMN_STREET_ROW_HEIGHT - 1;
693
+ const parkingMinY = parkingZoneMinYFromColumnBase(columnMinY);
694
+ const parkingMaxY = parkingMinY + PARKING_STREET_ROW_HEIGHT - 1;
695
+ if (parkingMaxY > maxY) {
696
+ throw new Error("createWorldLayoutWithParkingRow: parking band exceeds bounds");
697
+ }
698
+ const s0 = input.streets[0];
699
+ const s1 = input.streets[1];
700
+ const s2 = input.streets[2];
701
+ const s3 = input.streets[3];
702
+ if (s0 === void 0 || s1 === void 0 || s2 === void 0 || s3 === void 0) {
703
+ throw new Error("createWorldLayoutWithParkingRow: expected four streets");
704
+ }
705
+ const columnZones = buildColumnZones({
706
+ bounds: input.bounds,
707
+ columnMinY,
708
+ columnMaxY,
709
+ streets: [s0, s1, s2]
710
+ });
711
+ const parkingZone = {
712
+ id: "zone-parking-strip",
713
+ streetId: s3.id,
714
+ streetLabel: s3.label,
715
+ rect: { minX, maxX, minY: parkingMinY, maxY: parkingMaxY },
716
+ primaryGroup: "parking",
717
+ allowedGroups: ["parking"]
718
+ };
719
+ const streets = [
720
+ streetFromPoolEntry(s0),
721
+ streetFromPoolEntry(s1),
722
+ streetFromPoolEntry(s2),
723
+ streetFromPoolEntry(s3)
724
+ ];
725
+ return {
726
+ rev: 1,
727
+ bounds: input.bounds,
728
+ zones: [...columnZones, parkingZone],
729
+ streets
730
+ };
731
+ }
489
732
 
490
733
  // ../../node_modules/zod/v3/external.js
491
734
  var external_exports = {};
@@ -4621,6 +4864,8 @@ var PurchaseRecordSchema = external_exports.object({
4621
4864
  "shop",
4622
4865
  "supermarket",
4623
4866
  "car_wash",
4867
+ "parking",
4868
+ "house",
4624
4869
  "talk_time",
4625
4870
  "wallet_bundle",
4626
4871
  "apu_credit",
@@ -4631,6 +4876,8 @@ var PurchaseRecordSchema = external_exports.object({
4631
4876
  "shop",
4632
4877
  "supermarket",
4633
4878
  "carwash",
4879
+ "parking",
4880
+ "house",
4634
4881
  "game",
4635
4882
  "apu",
4636
4883
  "talk",
@@ -4661,6 +4908,425 @@ function desaturateColor(hex) {
4661
4908
  return y << 16 | y << 8 | y;
4662
4909
  }
4663
4910
 
4911
+ // src/lib/parking-pricing.ts
4912
+ var PARKING_DURATION_TIERS = [
4913
+ "1h",
4914
+ "12h",
4915
+ "1d",
4916
+ "3d",
4917
+ "7d",
4918
+ "1mo",
4919
+ "3mo",
4920
+ "1y",
4921
+ "forever"
4922
+ ];
4923
+ var HOURS_PER_TIER = {
4924
+ "1h": 1,
4925
+ "12h": 12,
4926
+ "1d": 24,
4927
+ "3d": 72,
4928
+ "7d": 168,
4929
+ "1mo": 24 * 30,
4930
+ "3mo": 24 * 90,
4931
+ "1y": 24 * 365,
4932
+ forever: null
4933
+ };
4934
+ var DEFAULT_PARKING_RATES_USD = {
4935
+ "1h": 0.75,
4936
+ "12h": 3.5,
4937
+ "1d": 5,
4938
+ "3d": 12,
4939
+ "7d": 22,
4940
+ "1mo": 65,
4941
+ "3mo": 165,
4942
+ "1y": 480,
4943
+ forever: 750
4944
+ };
4945
+ var effectiveHourlyRateUsd = (tier) => {
4946
+ const hours = HOURS_PER_TIER[tier];
4947
+ if (hours === null) {
4948
+ return DEFAULT_PARKING_RATES_USD.forever;
4949
+ }
4950
+ return DEFAULT_PARKING_RATES_USD[tier] / hours;
4951
+ };
4952
+ var computeParkingExpiresAt = (input) => {
4953
+ if (input.tier === "forever") {
4954
+ return null;
4955
+ }
4956
+ const hours = HOURS_PER_TIER[input.tier];
4957
+ if (hours === null) {
4958
+ return null;
4959
+ }
4960
+ const purchasedAt = new Date(input.purchasedAtIso);
4961
+ if (Number.isNaN(purchasedAt.getTime())) {
4962
+ throw new Error("computeParkingExpiresAt: invalid purchasedAtIso");
4963
+ }
4964
+ return new Date(purchasedAt.getTime() + hours * 60 * 60 * 1e3).toISOString();
4965
+ };
4966
+ var isParkingOccupantActive = (input) => {
4967
+ if (input.expiresAt === null) {
4968
+ return true;
4969
+ }
4970
+ const expires = new Date(input.expiresAt).getTime();
4971
+ const now = new Date(input.nowIso).getTime();
4972
+ if (Number.isNaN(expires) || Number.isNaN(now)) {
4973
+ return false;
4974
+ }
4975
+ return expires > now;
4976
+ };
4977
+
4978
+ // src/lib/parking-content-model.ts
4979
+ var NonEmpty2 = external_exports.string().trim().min(1);
4980
+ var IsoTimestamp2 = external_exports.string().trim().min(1);
4981
+ var PositivePrice2 = external_exports.number().finite().positive();
4982
+ var HexColor2 = external_exports.string().trim().regex(/^#[0-9a-fA-F]{6}$/, "expected #rrggbb hex color");
4983
+ var ParkingDurationTierSchema = external_exports.enum([
4984
+ "1h",
4985
+ "12h",
4986
+ "1d",
4987
+ "3d",
4988
+ "7d",
4989
+ "1mo",
4990
+ "3mo",
4991
+ "1y",
4992
+ "forever"
4993
+ ]);
4994
+ var ParkingBaySchema = external_exports.union([
4995
+ external_exports.literal(1),
4996
+ external_exports.literal(2),
4997
+ external_exports.literal(3),
4998
+ external_exports.literal(4)
4999
+ ]);
5000
+ var ParkingLayerSchema = external_exports.union([external_exports.literal(1), external_exports.literal(2)]);
5001
+ var ParkingOccupantSchema = external_exports.object({
5002
+ nodeId: NonEmpty2,
5003
+ carPurchaseId: NonEmpty2,
5004
+ displayNick: external_exports.string().trim().min(1).max(24),
5005
+ colorHex: HexColor2,
5006
+ model: NonEmpty2,
5007
+ tier: ParkingDurationTierSchema,
5008
+ purchasedAt: IsoTimestamp2,
5009
+ expiresAt: IsoTimestamp2.nullable()
5010
+ });
5011
+ var ParkingSpotSchema = external_exports.object({
5012
+ id: NonEmpty2,
5013
+ bay: ParkingBaySchema,
5014
+ layer: ParkingLayerSchema,
5015
+ occupant: ParkingOccupantSchema.nullable()
5016
+ });
5017
+ var ParkingStreetContentSchema = external_exports.object({
5018
+ spots: external_exports.array(ParkingSpotSchema).length(8),
5019
+ rates: external_exports.record(ParkingDurationTierSchema, PositivePrice2)
5020
+ });
5021
+ var PARKING_BAY_COUNT = 4;
5022
+ var PARKING_LAYERS_PER_BAY = 2;
5023
+ var PARKING_SPOT_COUNT = PARKING_BAY_COUNT * PARKING_LAYERS_PER_BAY;
5024
+ var spotIdFor = (bay, layer) => `parking-bay-${String(bay)}-layer-${String(layer)}`;
5025
+ var createEmptyParkingStreetContent = () => {
5026
+ const spots = [];
5027
+ for (let bay = 1; bay <= PARKING_BAY_COUNT; bay += 1) {
5028
+ for (let layer = 1; layer <= PARKING_LAYERS_PER_BAY; layer += 1) {
5029
+ spots.push({
5030
+ id: spotIdFor(bay, layer),
5031
+ bay,
5032
+ layer,
5033
+ occupant: null
5034
+ });
5035
+ }
5036
+ }
5037
+ return ParkingStreetContentSchema.parse({
5038
+ spots,
5039
+ rates: { ...DEFAULT_PARKING_RATES_USD }
5040
+ });
5041
+ };
5042
+ var listActiveParkingOccupancies = (content, nowIso) => {
5043
+ const active = [];
5044
+ for (const spot of content.spots) {
5045
+ const occupant = spot.occupant;
5046
+ if (occupant === null) {
5047
+ continue;
5048
+ }
5049
+ if (occupant.expiresAt !== null && new Date(occupant.expiresAt).getTime() <= new Date(nowIso).getTime()) {
5050
+ continue;
5051
+ }
5052
+ active.push({
5053
+ nodeId: occupant.nodeId,
5054
+ tier: occupant.tier,
5055
+ expiresAt: occupant.expiresAt
5056
+ });
5057
+ }
5058
+ return active;
5059
+ };
5060
+ var findParkingSpot = (content, bay, layer) => content.spots.find((s) => s.bay === bay && s.layer === layer);
5061
+ var effectiveParkingStreet = (content, nowIso) => ({
5062
+ spots: content.spots.map((spot) => {
5063
+ const occupant = spot.occupant;
5064
+ if (occupant === null) {
5065
+ return spot;
5066
+ }
5067
+ if (isParkingOccupantActive({
5068
+ expiresAt: occupant.expiresAt,
5069
+ nowIso
5070
+ })) {
5071
+ return spot;
5072
+ }
5073
+ return { ...spot, occupant: null };
5074
+ }),
5075
+ rates: { ...content.rates }
5076
+ });
5077
+
5078
+ // src/lib/house-content-model.ts
5079
+ var NonEmpty3 = external_exports.string().trim().min(1);
5080
+ var IsoTimestamp3 = external_exports.string().trim().min(1);
5081
+ var PositivePrice3 = external_exports.number().finite().positive();
5082
+ var OwnerName = external_exports.string().trim().min(1).max(40);
5083
+ var OwnerSignature = external_exports.string().trim().min(1).max(8);
5084
+ var OwnerDisplayName = external_exports.string().trim().min(1).max(24);
5085
+ var HOUSE_WORLD_X = [3, 8, 13, 18];
5086
+ var HouseIdSchema = external_exports.union([
5087
+ external_exports.literal(1),
5088
+ external_exports.literal(2),
5089
+ external_exports.literal(3),
5090
+ external_exports.literal(4)
5091
+ ]);
5092
+ var ParkingHouseBaySchema = external_exports.union([
5093
+ external_exports.literal(1),
5094
+ external_exports.literal(2),
5095
+ external_exports.literal(3),
5096
+ external_exports.literal(4)
5097
+ ]);
5098
+ var HOUSE_CATALOG = [
5099
+ { houseId: 1, bay: 1, priceUsd: 1299.99, layoutLabel: "Studio layout" },
5100
+ { houseId: 2, bay: 2, priceUsd: 2199.99, layoutLabel: "Split room" },
5101
+ { houseId: 3, bay: 3, priceUsd: 3499.99, layoutLabel: "L-shaped" },
5102
+ { houseId: 4, bay: 4, priceUsd: 5999.99, layoutLabel: "Loft" }
5103
+ ];
5104
+ var HouseSlotSchema = external_exports.object({
5105
+ id: NonEmpty3,
5106
+ houseId: HouseIdSchema,
5107
+ bay: ParkingHouseBaySchema,
5108
+ worldX: external_exports.number().finite(),
5109
+ priceUsd: PositivePrice3,
5110
+ layoutId: HouseIdSchema,
5111
+ layoutLabel: NonEmpty3,
5112
+ ownerNodeId: NonEmpty3.nullable(),
5113
+ ownerDisplayName: OwnerDisplayName.nullable(),
5114
+ ownerName: OwnerName.nullable(),
5115
+ ownerSignature: OwnerSignature.nullable(),
5116
+ purchasedAt: IsoTimestamp3.nullable()
5117
+ });
5118
+ var HouseStreetContentSchema = external_exports.object({
5119
+ houses: external_exports.array(HouseSlotSchema).length(4)
5120
+ });
5121
+ var PARKING_HOUSE_COUNT = 4;
5122
+ var houseIdFor = (houseId) => `house-${String(houseId)}`;
5123
+ var createEmptyHouseStreetContent = () => {
5124
+ const houses = HOUSE_CATALOG.map((entry, index) => {
5125
+ const worldX = HOUSE_WORLD_X[index];
5126
+ if (worldX === void 0) {
5127
+ throw new Error("HOUSE_WORLD_X index mismatch");
5128
+ }
5129
+ return {
5130
+ id: houseIdFor(entry.houseId),
5131
+ houseId: entry.houseId,
5132
+ bay: entry.bay,
5133
+ worldX,
5134
+ priceUsd: entry.priceUsd,
5135
+ layoutId: entry.houseId,
5136
+ layoutLabel: entry.layoutLabel,
5137
+ ownerNodeId: null,
5138
+ ownerDisplayName: null,
5139
+ ownerName: null,
5140
+ ownerSignature: null,
5141
+ purchasedAt: null
5142
+ };
5143
+ });
5144
+ return HouseStreetContentSchema.parse({ houses });
5145
+ };
5146
+ var findHouseSlot = (content, houseId) => content.houses.find((h) => h.houseId === houseId);
5147
+ var isHouseOwned = (house) => house.ownerNodeId !== null;
5148
+ var housePurchaseDetail = (house) => `House ${String(house.houseId)} \xB7 ${house.layoutLabel}`;
5149
+ var formatHouseOwnerDisplayName = (input) => {
5150
+ const name = input.name.trim();
5151
+ const signature = input.signature.trim().toUpperCase();
5152
+ const divider = " \xB7 ";
5153
+ const combined = `${name}${divider}${signature}`;
5154
+ if (combined.length <= 24) {
5155
+ return combined;
5156
+ }
5157
+ const suffix = `${divider}${signature}`;
5158
+ const maxNameLen = 24 - suffix.length;
5159
+ if (maxNameLen < 1) {
5160
+ return signature.slice(0, 24);
5161
+ }
5162
+ return `${name.slice(0, maxNameLen)}${suffix}`;
5163
+ };
5164
+ var buildHouseOwnershipPanelLines = (house) => {
5165
+ if (!isHouseOwned(house)) {
5166
+ return [];
5167
+ }
5168
+ const ownerName = house.ownerName ?? house.ownerDisplayName ?? "Owner";
5169
+ const ownerSignature = house.ownerSignature ?? "\u2014";
5170
+ const purchasedAt = house.purchasedAt !== null ? new Date(house.purchasedAt).toLocaleDateString(void 0, {
5171
+ dateStyle: "medium"
5172
+ }) : "\u2014";
5173
+ return [
5174
+ "PROPERTY RECORD",
5175
+ `Owner: ${ownerName}`,
5176
+ `Signature: ${ownerSignature}`,
5177
+ `Purchased: ${purchasedAt}`,
5178
+ "Security: Node-verified title",
5179
+ "Private residence \xB7 authorized entry only"
5180
+ ];
5181
+ };
5182
+
5183
+ // src/lib/house-layout-model.ts
5184
+ var BASE_BOUNDS = {
5185
+ minX: 0,
5186
+ minY: 0,
5187
+ maxX: 10,
5188
+ maxY: 7
5189
+ };
5190
+ var HOUSE_BLUEPRINTS = [
5191
+ {
5192
+ houseId: 1,
5193
+ label: "Studio layout",
5194
+ bounds: BASE_BOUNDS,
5195
+ floor: { color: 12887412, pattern: "planks" },
5196
+ exteriorPalette: {
5197
+ wall: 16115400,
5198
+ roof: 12986408,
5199
+ door: 5125166,
5200
+ window: 9489145,
5201
+ trim: 16777215
5202
+ },
5203
+ fixtures: [
5204
+ { kind: "bed", variant: "single-left", x: 2, y: 1.2 },
5205
+ { kind: "wardrobe", variant: "single", x: 8.5, y: 1.5 },
5206
+ { kind: "mirror", variant: "wall", x: 5, y: 0.4 },
5207
+ { kind: "window", variant: "double", x: 1.5, y: 0.3 },
5208
+ { kind: "window", variant: "single", x: 8, y: 0.3 }
5209
+ ],
5210
+ spawn: { x: 5, y: 5.5 }
5211
+ },
5212
+ {
5213
+ houseId: 2,
5214
+ label: "Split room",
5215
+ bounds: BASE_BOUNDS,
5216
+ floor: { color: 11583173, pattern: "tiles" },
5217
+ exteriorPalette: {
5218
+ wall: 15527921,
5219
+ roof: 3622735,
5220
+ door: 2503224,
5221
+ window: 16774557,
5222
+ trim: 7901340
5223
+ },
5224
+ fixtures: [
5225
+ { kind: "bed", variant: "single-right", x: 8, y: 5 },
5226
+ { kind: "wardrobe", variant: "double", x: 1.5, y: 1.5 },
5227
+ { kind: "mirror", variant: "standing", x: 9, y: 2.5 },
5228
+ { kind: "window", variant: "single", x: 3, y: 0.3 },
5229
+ { kind: "window", variant: "single", x: 7, y: 0.3 }
5230
+ ],
5231
+ spawn: { x: 5, y: 3 }
5232
+ },
5233
+ {
5234
+ houseId: 3,
5235
+ label: "L-shaped",
5236
+ bounds: BASE_BOUNDS,
5237
+ floor: { color: 14142664, pattern: "carpet" },
5238
+ exteriorPalette: {
5239
+ wall: 15984117,
5240
+ roof: 6953882,
5241
+ door: 4854924,
5242
+ window: 14794471,
5243
+ trim: 13538264
5244
+ },
5245
+ fixtures: [
5246
+ { kind: "bed", variant: "single-left", x: 1.5, y: 5.5 },
5247
+ { kind: "wardrobe", variant: "single", x: 8.5, y: 5 },
5248
+ { kind: "mirror", variant: "wall", x: 5, y: 0.4 },
5249
+ { kind: "window", variant: "tall", x: 9, y: 0.3 },
5250
+ { kind: "window", variant: "double", x: 2, y: 0.3 }
5251
+ ],
5252
+ spawn: { x: 5.5, y: 2.5 }
5253
+ },
5254
+ {
5255
+ houseId: 4,
5256
+ label: "Loft",
5257
+ bounds: BASE_BOUNDS,
5258
+ floor: { color: 6111287, pattern: "planks" },
5259
+ exteriorPalette: {
5260
+ wall: 9268835,
5261
+ roof: 4073251,
5262
+ door: 2171169,
5263
+ window: 16772275,
5264
+ trim: 6111287
5265
+ },
5266
+ fixtures: [
5267
+ { kind: "bed", variant: "bunk", x: 7.5, y: 1 },
5268
+ { kind: "wardrobe", variant: "double", x: 2, y: 4.5 },
5269
+ { kind: "mirror", variant: "standing", x: 5, y: 4 },
5270
+ { kind: "window", variant: "tall", x: 1, y: 0.3 },
5271
+ { kind: "window", variant: "single", x: 6, y: 0.3 }
5272
+ ],
5273
+ spawn: { x: 4, y: 6 }
5274
+ }
5275
+ ];
5276
+ var getHouseBlueprint = (houseId) => {
5277
+ const blueprint = HOUSE_BLUEPRINTS.find((b) => b.houseId === houseId);
5278
+ if (blueprint === void 0) {
5279
+ throw new Error(`getHouseBlueprint: unknown houseId ${String(houseId)}`);
5280
+ }
5281
+ return blueprint;
5282
+ };
5283
+ var layoutHouseFixtures = (blueprint) => blueprint.fixtures.map((fixture) => {
5284
+ const slot = {
5285
+ kind: fixture.kind,
5286
+ variant: fixture.variant,
5287
+ x: fixture.x,
5288
+ y: fixture.y
5289
+ };
5290
+ if (fixture.rotation !== void 0) {
5291
+ return { ...slot, rotation: fixture.rotation };
5292
+ }
5293
+ return slot;
5294
+ });
5295
+ var houseSpawnPosition = (blueprint) => ({
5296
+ x: blueprint.spawn.x,
5297
+ y: blueprint.spawn.y
5298
+ });
5299
+ var clampHousePosition = (blueprint, pos) => {
5300
+ const { minX, minY, maxX, maxY } = blueprint.bounds;
5301
+ return {
5302
+ x: Math.min(maxX, Math.max(minX, pos.x)),
5303
+ y: Math.min(maxY, Math.max(minY, pos.y))
5304
+ };
5305
+ };
5306
+
5307
+ // src/lib/parking-ownership.ts
5308
+ var MAX_TIMED_PARKING_SLOTS_PER_NODE = 2;
5309
+ var MAX_SLOTS_WITH_FOREVER = 1;
5310
+ var canNodeAcquireParkingSpot = (input) => {
5311
+ const mine = input.active.filter((o) => o.nodeId === input.nodeId);
5312
+ const hasForever = mine.some(
5313
+ (o) => o.tier === "forever" || o.expiresAt === null
5314
+ );
5315
+ if (input.tier === "forever") {
5316
+ if (mine.length > 0) {
5317
+ return { ok: false, error: "PARKING_FOREVER_LIMIT" };
5318
+ }
5319
+ return { ok: true };
5320
+ }
5321
+ if (hasForever) {
5322
+ return { ok: false, error: "PARKING_FOREVER_LIMIT" };
5323
+ }
5324
+ if (mine.length >= MAX_TIMED_PARKING_SLOTS_PER_NODE) {
5325
+ return { ok: false, error: "PARKING_OWNERSHIP_LIMIT" };
5326
+ }
5327
+ return { ok: true };
5328
+ };
5329
+
4664
5330
  // src/lib/wallet-apu-transaction.ts
4665
5331
  var APU_TOKEN = "APU";
4666
5332
  var buildApuWalletTransaction = (input) => {
@@ -4904,8 +5570,8 @@ var createEmptyGameStats = (date) => {
4904
5570
  };
4905
5571
 
4906
5572
  // src/lib/scanner-model.ts
4907
- var NonEmpty2 = external_exports.string().trim().min(1);
4908
- var IsoTimestamp2 = external_exports.string().trim().min(1);
5573
+ var NonEmpty4 = external_exports.string().trim().min(1);
5574
+ var IsoTimestamp4 = external_exports.string().trim().min(1);
4909
5575
  var ScannerTxOpSchema = external_exports.enum([
4910
5576
  "purchase",
4911
5577
  "redeemWalletBundle",
@@ -4916,8 +5582,8 @@ var ScannerTxOpSchema = external_exports.enum([
4916
5582
  "walletSeeded"
4917
5583
  ]);
4918
5584
  var ScannerTxRecordSchema = PurchaseRecordSchema.extend({
4919
- hostId: NonEmpty2,
4920
- indexedAt: IsoTimestamp2,
5585
+ hostId: NonEmpty4,
5586
+ indexedAt: IsoTimestamp4,
4921
5587
  op: ScannerTxOpSchema,
4922
5588
  blockRev: external_exports.number().int().nonnegative().optional(),
4923
5589
  merkleRootHex: external_exports.string().optional()
@@ -4926,7 +5592,7 @@ var ScannerBlockRecordSchema = external_exports.object({
4926
5592
  rev: external_exports.number().int().nonnegative(),
4927
5593
  merkleRootHex: external_exports.string(),
4928
5594
  merkleLeafCount: external_exports.number().int().nonnegative(),
4929
- at: IsoTimestamp2,
5595
+ at: IsoTimestamp4,
4930
5596
  occupantCount: external_exports.number().int().nonnegative().optional(),
4931
5597
  leafDeltaCount: external_exports.number().int().nonnegative().optional(),
4932
5598
  label: external_exports.string().optional()
@@ -4941,19 +5607,19 @@ var ScannerMigrationStateSchema = external_exports.object({
4941
5607
  status: ScannerMigrationStatusSchema,
4942
5608
  cursor: external_exports.string(),
4943
5609
  totalIndexed: external_exports.number().int().nonnegative(),
4944
- startedAt: IsoTimestamp2,
4945
- completedAt: IsoTimestamp2.optional(),
5610
+ startedAt: IsoTimestamp4,
5611
+ completedAt: IsoTimestamp4.optional(),
4946
5612
  error: external_exports.string().optional()
4947
5613
  });
4948
5614
  var ScannerWalletSnapshotSchema = external_exports.object({
4949
- playerId: NonEmpty2,
5615
+ playerId: NonEmpty4,
4950
5616
  balanceUsd: external_exports.number().finite().nonnegative(),
4951
5617
  powerUps: external_exports.number().int().nonnegative(),
4952
- updatedAt: IsoTimestamp2
5618
+ updatedAt: IsoTimestamp4
4953
5619
  });
4954
5620
  var ScannerHeadSchema = external_exports.object({
4955
- generatedAt: IsoTimestamp2,
4956
- hostId: NonEmpty2,
5621
+ generatedAt: IsoTimestamp4,
5622
+ hostId: NonEmpty4,
4957
5623
  snapshotRev: external_exports.number().int().nonnegative(),
4958
5624
  merkleRootHex: external_exports.string().nullable(),
4959
5625
  merkleLeafCount: external_exports.number().int().nonnegative().nullable(),
@@ -4968,14 +5634,14 @@ var ScannerNodeWalletSchema = external_exports.object({
4968
5634
  balanceUsd: external_exports.number().finite().nonnegative(),
4969
5635
  powerUps: external_exports.number().int().nonnegative(),
4970
5636
  currency: external_exports.literal("USD"),
4971
- updatedAt: IsoTimestamp2
5637
+ updatedAt: IsoTimestamp4
4972
5638
  });
4973
5639
  var ScannerNodeLedgerKpisSchema = external_exports.object({
4974
5640
  txCount: external_exports.number().int().nonnegative(),
4975
5641
  usdSpent: external_exports.number().finite().nonnegative(),
4976
5642
  apuMinted: external_exports.number().int().nonnegative(),
4977
5643
  apuBurned: external_exports.number().int().nonnegative(),
4978
- lastTxAt: IsoTimestamp2.nullable()
5644
+ lastTxAt: IsoTimestamp4.nullable()
4979
5645
  });
4980
5646
  var ScannerNodeBreakdownSchema = external_exports.object({
4981
5647
  byAmenityKind: external_exports.record(external_exports.string(), external_exports.number().int().nonnegative()),
@@ -4989,15 +5655,15 @@ var ScannerNodeAnalyticsKpisSchema = external_exports.object({
4989
5655
  eventsLast24h: external_exports.number().int().nonnegative(),
4990
5656
  topEvents: external_exports.array(
4991
5657
  external_exports.object({
4992
- event: NonEmpty2,
5658
+ event: NonEmpty4,
4993
5659
  count: external_exports.number().int().nonnegative()
4994
5660
  })
4995
5661
  )
4996
5662
  });
4997
5663
  var ScannerNodeProfileSchema = external_exports.object({
4998
- nodeId: NonEmpty2,
5664
+ nodeId: NonEmpty4,
4999
5665
  kind: ScannerNodeKindSchema,
5000
- generatedAt: IsoTimestamp2,
5666
+ generatedAt: IsoTimestamp4,
5001
5667
  wallet: ScannerNodeWalletSchema.nullable(),
5002
5668
  ledger: ScannerNodeLedgerKpisSchema,
5003
5669
  breakdown: ScannerNodeBreakdownSchema,
@@ -5021,10 +5687,10 @@ var ScannerNodeProfileSchema = external_exports.object({
5021
5687
  }).nullable(),
5022
5688
  analyticsEvents: external_exports.array(
5023
5689
  external_exports.object({
5024
- messageId: NonEmpty2,
5025
- event: NonEmpty2,
5026
- distinctId: NonEmpty2,
5027
- timestamp: IsoTimestamp2,
5690
+ messageId: NonEmpty4,
5691
+ event: NonEmpty4,
5692
+ distinctId: NonEmpty4,
5693
+ timestamp: IsoTimestamp4,
5028
5694
  properties: external_exports.record(
5029
5695
  external_exports.union([external_exports.string(), external_exports.number(), external_exports.boolean(), external_exports.null()])
5030
5696
  )
@@ -5038,8 +5704,8 @@ var ScannerNodeProfileSchema = external_exports.object({
5038
5704
  });
5039
5705
 
5040
5706
  // src/lib/analytics-event-model.ts
5041
- var NonEmpty3 = external_exports.string().trim().min(1);
5042
- var IsoTimestamp3 = external_exports.string().trim().min(1);
5707
+ var NonEmpty5 = external_exports.string().trim().min(1);
5708
+ var IsoTimestamp5 = external_exports.string().trim().min(1);
5043
5709
  var AnalyticsPropertyValueSchema = external_exports.union([
5044
5710
  external_exports.string(),
5045
5711
  external_exports.number(),
@@ -5047,23 +5713,23 @@ var AnalyticsPropertyValueSchema = external_exports.union([
5047
5713
  external_exports.null()
5048
5714
  ]);
5049
5715
  var AnalyticsContextSchema = external_exports.object({
5050
- hostId: NonEmpty3,
5716
+ hostId: NonEmpty5,
5051
5717
  sid: external_exports.string().optional(),
5052
5718
  snapshotRev: external_exports.number().int().nonnegative().optional(),
5053
5719
  library: external_exports.enum(["agent-play-server", "agent-play-client"])
5054
5720
  });
5055
5721
  var AnalyticsEventSchema = external_exports.object({
5056
- messageId: NonEmpty3,
5057
- event: NonEmpty3,
5058
- distinctId: NonEmpty3,
5059
- timestamp: IsoTimestamp3,
5722
+ messageId: NonEmpty5,
5723
+ event: NonEmpty5,
5724
+ distinctId: NonEmpty5,
5725
+ timestamp: IsoTimestamp5,
5060
5726
  properties: external_exports.record(AnalyticsPropertyValueSchema),
5061
5727
  context: AnalyticsContextSchema.optional()
5062
5728
  });
5063
5729
  var AnalyticsTraitsSchema = external_exports.object({
5064
- distinctId: NonEmpty3,
5730
+ distinctId: NonEmpty5,
5065
5731
  traits: external_exports.record(AnalyticsPropertyValueSchema),
5066
- timestamp: IsoTimestamp3
5732
+ timestamp: IsoTimestamp5
5067
5733
  });
5068
5734
  var AnalyticsMigrationStatusSchema = external_exports.enum([
5069
5735
  "pending",
@@ -5075,8 +5741,8 @@ var AnalyticsMigrationStateSchema = external_exports.object({
5075
5741
  status: AnalyticsMigrationStatusSchema,
5076
5742
  cursor: external_exports.string(),
5077
5743
  totalIndexed: external_exports.number().int().nonnegative(),
5078
- startedAt: IsoTimestamp3,
5079
- completedAt: IsoTimestamp3.optional(),
5744
+ startedAt: IsoTimestamp5,
5745
+ completedAt: IsoTimestamp5.optional(),
5080
5746
  error: external_exports.string().optional()
5081
5747
  });
5082
5748
  var ANALYTICS_EVENT_NAMES = {
@@ -5522,6 +6188,12 @@ function mergeSnapshotWithPlayerChainNode(snapshot, node) {
5522
6188
  export {
5523
6189
  MINIMUM_PLAY_WORLD_BOUNDS,
5524
6190
  MINIMUM_STREET_LAYOUT_BOUNDS,
6191
+ COLUMN_STREET_ROW_HEIGHT,
6192
+ PARKING_STREET_ROW_HEIGHT,
6193
+ PARKING_COLUMN_GAP_ROWS,
6194
+ parkingZoneMinYFromColumnBase,
6195
+ parkingZoneMaxYFromColumnBase,
6196
+ DEFAULT_LAYOUT_BOUNDS_WITH_PARKING,
5525
6197
  expandBoundsToMinimumPlayArea,
5526
6198
  clampWorldPosition,
5527
6199
  boundsContain,
@@ -5565,9 +6237,14 @@ export {
5565
6237
  availableCellsForZone,
5566
6238
  isAgentSpawnOccupancyPointAvailableInZone,
5567
6239
  isSpaceAnchorOccupancyPointAvailableInZone,
6240
+ layoutHasParkingZone,
5568
6241
  migrateWorldLayoutBounds,
6242
+ layoutNeedsParkingColumnGapMigration,
6243
+ migrateLayoutToParkingColumnGap,
6244
+ migrateLayoutToParkingRow,
5569
6245
  applyBoundsFieldUpdateToLayout,
5570
6246
  createVerticalStripSeedLayout,
6247
+ createWorldLayoutWithParkingRow,
5571
6248
  SaleStateSchema,
5572
6249
  ShopItemSchema,
5573
6250
  SupermarketItemSchema,
@@ -5579,6 +6256,41 @@ export {
5579
6256
  PurchaseRecordSchema,
5580
6257
  isItemAvailableForPurchase,
5581
6258
  desaturateColor,
6259
+ PARKING_DURATION_TIERS,
6260
+ DEFAULT_PARKING_RATES_USD,
6261
+ effectiveHourlyRateUsd,
6262
+ computeParkingExpiresAt,
6263
+ isParkingOccupantActive,
6264
+ ParkingDurationTierSchema,
6265
+ ParkingSpotSchema,
6266
+ ParkingStreetContentSchema,
6267
+ PARKING_BAY_COUNT,
6268
+ PARKING_LAYERS_PER_BAY,
6269
+ PARKING_SPOT_COUNT,
6270
+ createEmptyParkingStreetContent,
6271
+ listActiveParkingOccupancies,
6272
+ findParkingSpot,
6273
+ effectiveParkingStreet,
6274
+ HOUSE_WORLD_X,
6275
+ HouseIdSchema,
6276
+ HOUSE_CATALOG,
6277
+ HouseSlotSchema,
6278
+ HouseStreetContentSchema,
6279
+ PARKING_HOUSE_COUNT,
6280
+ createEmptyHouseStreetContent,
6281
+ findHouseSlot,
6282
+ isHouseOwned,
6283
+ housePurchaseDetail,
6284
+ formatHouseOwnerDisplayName,
6285
+ buildHouseOwnershipPanelLines,
6286
+ HOUSE_BLUEPRINTS,
6287
+ getHouseBlueprint,
6288
+ layoutHouseFixtures,
6289
+ houseSpawnPosition,
6290
+ clampHousePosition,
6291
+ MAX_TIMED_PARKING_SLOTS_PER_NODE,
6292
+ MAX_SLOTS_WITH_FOREVER,
6293
+ canNodeAcquireParkingSpot,
5582
6294
  APU_TOKEN,
5583
6295
  buildApuWalletTransaction,
5584
6296
  buildAmenityPurchaseApuFields,
@@ -5636,4 +6348,4 @@ export {
5636
6348
  parsePlayerChainNodeRpcBody,
5637
6349
  mergeSnapshotWithPlayerChainNode
5638
6350
  };
5639
- //# sourceMappingURL=chunk-Z2PYRHFU.js.map
6351
+ //# sourceMappingURL=chunk-27BMLID7.js.map