mudlet-map-editor 0.4.0 → 0.6.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-lib/index.js CHANGED
@@ -76,7 +76,8 @@ var T = C(), E = {
76
76
  activeSwatchSetId: T.activeSwatchSetId,
77
77
  activeSwatchId: T.activeSwatchId,
78
78
  swatchPaletteOpen: !1,
79
- sessionId: null
79
+ sessionId: null,
80
+ spreadShrink: null
80
81
  }, D = new class {
81
82
  state = E;
82
83
  listeners = /* @__PURE__ */ new Set();
@@ -1136,7 +1137,7 @@ var se = [
1136
1137
  {
1137
1138
  id: "select",
1138
1139
  label: "Select",
1139
- hint: "Click a room to select. Drag to move (snaps to grid). Arrow keys nudge.",
1140
+ hint: "Click to select · Shift+click/drag to add · Ctrl+click/drag to toggle · drag to move (snaps to grid) · arrow keys nudge · MMB or Space to pan.",
1140
1141
  key: "1"
1141
1142
  },
1142
1143
  {
@@ -1198,6 +1199,10 @@ var se = [
1198
1199
  keys: ["F"],
1199
1200
  desc: "Fit area to view"
1200
1201
  },
1202
+ {
1203
+ keys: [`${g}+F`],
1204
+ desc: "Open / close search (rooms, labels)"
1205
+ },
1201
1206
  {
1202
1207
  keys: [`${g}+A`],
1203
1208
  desc: "Select all rooms on current level"
@@ -1290,20 +1295,20 @@ function le({ onClose: e }) {
1290
1295
  }
1291
1296
  //#endregion
1292
1297
  //#region src/components/Toolbar.tsx
1293
- function ue({ title: e = "Mudlet Map Editor", onHelpClick: t, onLoadFromUrl: a, onSave: o }) {
1294
- let s = O((e) => e.activeTool), c = O((e) => e.map), l = c != null, p = O((e) => e.loaded), m = O((e) => e.currentAreaId), h = O((e) => e.currentZ), _ = O((e) => e.snapToGrid), v = O((e) => e.status), y = O((e) => e.pending), b = O((e) => e.undo.length), x = O((e) => e.redo.length), C = O((e) => e.savedUndoLength), w = O((e) => e.swatchPaletteOpen), T = O((e) => e.activeSwatchId), E = O((e) => e.activeSwatchSetId), k = O((e) => e.swatchSets), A = O((e) => e.pluginSwatchSets), j = [...k, ...A].find((e) => e.id === E)?.swatches.find((e) => e.id === T) ?? null, M = b !== C, N = O((e) => e.structureVersion), P = n(() => c ? Object.entries(c.areaNames).map(([e, t]) => ({
1298
+ function ue({ title: e = "Mudlet Map Editor", onHelpClick: t, onLoadFromUrl: a, onSave: o, onSearchClick: s }) {
1299
+ let c = O((e) => e.activeTool), l = O((e) => e.map), p = l != null, m = O((e) => e.loaded), h = O((e) => e.currentAreaId), _ = O((e) => e.currentZ), v = O((e) => e.snapToGrid), y = O((e) => e.status), b = O((e) => e.pending), x = O((e) => e.undo.length), C = O((e) => e.redo.length), w = O((e) => e.savedUndoLength), T = O((e) => e.swatchPaletteOpen), E = O((e) => e.activeSwatchId), k = O((e) => e.activeSwatchSetId), A = O((e) => e.swatchSets), j = O((e) => e.pluginSwatchSets), M = [...A, ...j].find((e) => e.id === k)?.swatches.find((e) => e.id === E) ?? null, N = x !== w, P = O((e) => e.structureVersion), F = n(() => l ? Object.entries(l.areaNames).map(([e, t]) => ({
1295
1300
  id: Number(e),
1296
1301
  name: t
1297
- })).sort((e, t) => e.name.localeCompare(t.name)) : [], [c, N]), F = n(() => {
1298
- if (!c || m == null) return [0];
1299
- let e = c.areas[m];
1302
+ })).sort((e, t) => e.name.localeCompare(t.name)) : [], [l, P]), I = n(() => {
1303
+ if (!l || h == null) return [0];
1304
+ let e = l.areas[h];
1300
1305
  return e?.zLevels?.length ? [...e.zLevels].sort((e, t) => e - t) : [0];
1301
1306
  }, [
1302
- c,
1303
- m,
1304
- N
1305
- ]), I = r(null), [L, R] = i(""), ee = () => {
1306
- let e = parseInt(L, 10);
1307
+ l,
1308
+ h,
1309
+ P
1310
+ ]), L = r(null), [R, ee] = i(""), z = () => {
1311
+ let e = parseInt(R, 10);
1307
1312
  if (Number.isNaN(e)) return;
1308
1313
  let t = D.getState();
1309
1314
  if (!t.map) return;
@@ -1324,8 +1329,8 @@ function ue({ title: e = "Mudlet Map Editor", onHelpClick: t, onLoadFromUrl: a,
1324
1329
  ids: [e]
1325
1330
  },
1326
1331
  pending: null
1327
- }), D.bumpStructure(), R("");
1328
- }, z = () => {
1332
+ }), D.bumpStructure(), ee("");
1333
+ }, B = () => {
1329
1334
  let e = W();
1330
1335
  D.setState({
1331
1336
  map: e,
@@ -1341,7 +1346,7 @@ function ue({ title: e = "Mudlet Map Editor", onHelpClick: t, onLoadFromUrl: a,
1341
1346
  status: "New map created · 0 rooms · 1 area",
1342
1347
  sessionId: null
1343
1348
  }), D.bumpStructure();
1344
- }, B = ae;
1349
+ }, V = ae;
1345
1350
  return /* @__PURE__ */ f("div", {
1346
1351
  className: "toolbar",
1347
1352
  children: [/* @__PURE__ */ f("div", {
@@ -1356,7 +1361,7 @@ function ue({ title: e = "Mudlet Map Editor", onHelpClick: t, onLoadFromUrl: a,
1356
1361
  /* @__PURE__ */ d("button", {
1357
1362
  type: "button",
1358
1363
  title: "New Map",
1359
- onClick: z,
1364
+ onClick: B,
1360
1365
  children: /* @__PURE__ */ f("svg", {
1361
1366
  width: "16",
1362
1367
  height: "16",
@@ -1418,13 +1423,13 @@ function ue({ title: e = "Mudlet Map Editor", onHelpClick: t, onLoadFromUrl: a,
1418
1423
  })
1419
1424
  ]
1420
1425
  }), /* @__PURE__ */ d("input", {
1421
- ref: I,
1426
+ ref: L,
1422
1427
  type: "file",
1423
1428
  accept: ".dat",
1424
1429
  style: { display: "none" },
1425
1430
  onChange: (e) => {
1426
1431
  let t = e.target.files?.[0];
1427
- t && B(t), e.target.value = "";
1432
+ t && V(t), e.target.value = "";
1428
1433
  }
1429
1434
  })]
1430
1435
  }),
@@ -1488,10 +1493,10 @@ function ue({ title: e = "Mudlet Map Editor", onHelpClick: t, onLoadFromUrl: a,
1488
1493
  D.setState({ status: `Save failed: ${e.message}` }), console.error(e);
1489
1494
  }
1490
1495
  },
1491
- disabled: !l,
1496
+ disabled: !p,
1492
1497
  style: {
1493
1498
  position: "relative",
1494
- ...M ? { color: "#ffd080" } : {}
1499
+ ...N ? { color: "#ffd080" } : {}
1495
1500
  },
1496
1501
  children: [/* @__PURE__ */ f("svg", {
1497
1502
  width: "16",
@@ -1526,7 +1531,7 @@ function ue({ title: e = "Mudlet Map Editor", onHelpClick: t, onLoadFromUrl: a,
1526
1531
  fill: "none"
1527
1532
  })
1528
1533
  ]
1529
- }), M && /* @__PURE__ */ d("span", {
1534
+ }), N && /* @__PURE__ */ d("span", {
1530
1535
  style: {
1531
1536
  position: "absolute",
1532
1537
  top: 6,
@@ -1538,12 +1543,12 @@ function ue({ title: e = "Mudlet Map Editor", onHelpClick: t, onLoadFromUrl: a,
1538
1543
  children: "*"
1539
1544
  })]
1540
1545
  }),
1541
- l && /* @__PURE__ */ f(u, { children: [
1546
+ p && /* @__PURE__ */ f(u, { children: [
1542
1547
  /* @__PURE__ */ d("div", { className: "toolbar-sep" }),
1543
1548
  /* @__PURE__ */ d(oe, {
1544
1549
  label: "Area",
1545
- value: m,
1546
- options: P.map((e) => ({
1550
+ value: h,
1551
+ options: F.map((e) => ({
1547
1552
  value: e.id,
1548
1553
  label: `${e.name} (#${e.id})`
1549
1554
  })),
@@ -1560,8 +1565,8 @@ function ue({ title: e = "Mudlet Map Editor", onHelpClick: t, onLoadFromUrl: a,
1560
1565
  }),
1561
1566
  /* @__PURE__ */ d(oe, {
1562
1567
  label: "Level",
1563
- value: h,
1564
- options: F.map((e) => ({
1568
+ value: _,
1569
+ options: I.map((e) => ({
1565
1570
  value: e,
1566
1571
  label: String(e)
1567
1572
  })),
@@ -1589,17 +1594,17 @@ function ue({ title: e = "Mudlet Map Editor", onHelpClick: t, onLoadFromUrl: a,
1589
1594
  type: "number",
1590
1595
  min: 1,
1591
1596
  placeholder: "ID",
1592
- value: L,
1593
- onChange: (e) => R(e.target.value),
1597
+ value: R,
1598
+ onChange: (e) => ee(e.target.value),
1594
1599
  onKeyDown: (e) => {
1595
- e.key === "Enter" && ee();
1600
+ e.key === "Enter" && z();
1596
1601
  }
1597
1602
  }),
1598
1603
  /* @__PURE__ */ d("button", {
1599
1604
  type: "button",
1600
1605
  className: "toolbar-goto-btn",
1601
- onClick: ee,
1602
- disabled: L === "",
1606
+ onClick: z,
1607
+ disabled: R === "",
1603
1608
  children: "Go"
1604
1609
  })
1605
1610
  ]
@@ -1613,20 +1618,30 @@ function ue({ title: e = "Mudlet Map Editor", onHelpClick: t, onLoadFromUrl: a,
1613
1618
  className: "tool-key",
1614
1619
  children: "F"
1615
1620
  }), /* @__PURE__ */ d("span", { children: "Fit" })]
1621
+ }),
1622
+ /* @__PURE__ */ f("button", {
1623
+ type: "button",
1624
+ className: "tool-btn",
1625
+ title: "Search rooms and labels (Ctrl+F)",
1626
+ onClick: s,
1627
+ children: [/* @__PURE__ */ d("span", {
1628
+ className: "tool-key",
1629
+ children: "^F"
1630
+ }), /* @__PURE__ */ d("span", { children: "Search" })]
1616
1631
  })
1617
1632
  ] }),
1618
1633
  /* @__PURE__ */ f("span", {
1619
1634
  className: "status",
1620
- children: [p && /* @__PURE__ */ f("span", {
1635
+ children: [m && /* @__PURE__ */ f("span", {
1621
1636
  className: "status-file",
1622
1637
  children: [
1623
1638
  "[",
1624
- p.fileName,
1639
+ m.fileName,
1625
1640
  "]"
1626
1641
  ]
1627
1642
  }), /* @__PURE__ */ d("span", {
1628
1643
  className: "status-action",
1629
- children: v
1644
+ children: y
1630
1645
  })]
1631
1646
  }),
1632
1647
  /* @__PURE__ */ d("button", {
@@ -1637,14 +1652,14 @@ function ue({ title: e = "Mudlet Map Editor", onHelpClick: t, onLoadFromUrl: a,
1637
1652
  children: "?"
1638
1653
  })
1639
1654
  ]
1640
- }), l && /* @__PURE__ */ f("div", {
1655
+ }), p && /* @__PURE__ */ f("div", {
1641
1656
  className: "toolbar-row toolbar-row-tools",
1642
1657
  children: [
1643
1658
  /* @__PURE__ */ d("div", {
1644
1659
  className: "tool-group",
1645
1660
  children: se.map((e) => /* @__PURE__ */ f("button", {
1646
1661
  type: "button",
1647
- className: `tool-btn${s === e.id ? " active" : ""}`,
1662
+ className: `tool-btn${c === e.id ? " active" : ""}`,
1648
1663
  title: `${e.label} (${e.key}) — ${e.hint}`,
1649
1664
  onClick: () => {
1650
1665
  D.setState({
@@ -1662,24 +1677,24 @@ function ue({ title: e = "Mudlet Map Editor", onHelpClick: t, onLoadFromUrl: a,
1662
1677
  /* @__PURE__ */ d("button", {
1663
1678
  type: "button",
1664
1679
  title: "Undo (Ctrl+Z)",
1665
- disabled: b === 0,
1680
+ disabled: x === 0,
1666
1681
  onClick: () => window.dispatchEvent(new CustomEvent("editor:undo")),
1667
1682
  children: "↶ Undo"
1668
1683
  }),
1669
1684
  /* @__PURE__ */ d("button", {
1670
1685
  type: "button",
1671
1686
  title: "Redo (Ctrl+Shift+Z)",
1672
- disabled: x === 0,
1687
+ disabled: C === 0,
1673
1688
  onClick: () => window.dispatchEvent(new CustomEvent("editor:redo")),
1674
1689
  children: "↷ Redo"
1675
1690
  }),
1676
1691
  /* @__PURE__ */ d("div", { className: "toolbar-sep" }),
1677
1692
  /* @__PURE__ */ f("button", {
1678
1693
  type: "button",
1679
- className: `tool-btn toolbar-snap-btn${_ ? " active" : ""}`,
1694
+ className: `tool-btn toolbar-snap-btn${v ? " active" : ""}`,
1680
1695
  title: "Snap to grid (G)",
1681
1696
  onClick: () => {
1682
- S({ snapToGrid: !_ }), D.setState({ snapToGrid: !_ });
1697
+ S({ snapToGrid: !v }), D.setState({ snapToGrid: !v });
1683
1698
  },
1684
1699
  children: [/* @__PURE__ */ d("span", {
1685
1700
  className: "tool-key",
@@ -1688,54 +1703,54 @@ function ue({ title: e = "Mudlet Map Editor", onHelpClick: t, onLoadFromUrl: a,
1688
1703
  }),
1689
1704
  /* @__PURE__ */ d("button", {
1690
1705
  type: "button",
1691
- className: `tool-btn${w ? " active" : ""}`,
1706
+ className: `tool-btn${T ? " active" : ""}`,
1692
1707
  title: "Room swatches palette",
1693
- onClick: () => D.setState({ swatchPaletteOpen: !w }),
1694
- children: j ? /* @__PURE__ */ f(u, { children: [/* @__PURE__ */ d("span", {
1708
+ onClick: () => D.setState({ swatchPaletteOpen: !T }),
1709
+ children: M ? /* @__PURE__ */ f(u, { children: [/* @__PURE__ */ d("span", {
1695
1710
  className: "tool-key",
1696
1711
  children: "8↴"
1697
- }), /* @__PURE__ */ d("span", { children: j.name })] }) : /* @__PURE__ */ f(u, { children: [/* @__PURE__ */ d("span", {
1712
+ }), /* @__PURE__ */ d("span", { children: M.name })] }) : /* @__PURE__ */ f(u, { children: [/* @__PURE__ */ d("span", {
1698
1713
  className: "tool-key",
1699
1714
  children: "8↴"
1700
1715
  }), /* @__PURE__ */ d("span", { children: "Swatches" })] })
1701
1716
  }),
1702
- !y && s === "paint" && /* @__PURE__ */ d("span", {
1717
+ !b && c === "paint" && /* @__PURE__ */ d("span", {
1703
1718
  className: "toolbar-pending-hint",
1704
- children: j ? `Painting "${j.name}" (env ${j.environment}${j.symbol ? `, symbol "${j.symbol}"` : ""}) · click or drag rooms` : "No swatch selected — open Swatches palette and pick one"
1719
+ children: M ? `Painting "${M.name}" (env ${M.environment}${M.symbol ? `, symbol "${M.symbol}"` : ""}) · click or drag rooms` : "No swatch selected — open Swatches palette and pick one"
1705
1720
  }),
1706
- y?.kind === "marquee" && /* @__PURE__ */ d("span", {
1721
+ b?.kind === "marquee" && /* @__PURE__ */ d("span", {
1707
1722
  className: "toolbar-pending-hint",
1708
1723
  children: "Hold Ctrl to toggle selection"
1709
1724
  }),
1710
- y?.kind === "connect" && /* @__PURE__ */ d("span", {
1725
+ b?.kind === "connect" && /* @__PURE__ */ d("span", {
1711
1726
  className: "toolbar-pending-hint",
1712
1727
  children: "Pick target · Shift = one-way · Esc cancels"
1713
1728
  }),
1714
- y?.kind === "customLine" && /* @__PURE__ */ d("span", {
1729
+ b?.kind === "customLine" && /* @__PURE__ */ d("span", {
1715
1730
  className: "toolbar-pending-hint",
1716
1731
  children: "Click to add waypoints · right-click or Enter to finish · Esc cancels"
1717
1732
  }),
1718
- !y && s === "select" && /* @__PURE__ */ d("span", {
1733
+ !b && c === "select" && /* @__PURE__ */ d("span", {
1719
1734
  className: "toolbar-pending-hint",
1720
- children: "Hold Space to pan"
1735
+ children: "Click to select · Shift+click/drag to add · Ctrl+click/drag to toggle · drag selected rooms to move · MMB or Space to pan"
1721
1736
  }),
1722
- !y && s === "unlink" && /* @__PURE__ */ d("span", {
1737
+ !b && c === "unlink" && /* @__PURE__ */ d("span", {
1723
1738
  className: "toolbar-pending-hint",
1724
1739
  children: "Click a room to remove all its exits · click an exit or custom line to remove just that one"
1725
1740
  }),
1726
- !y && s === "addRoom" && /* @__PURE__ */ d("span", {
1741
+ !b && c === "addRoom" && /* @__PURE__ */ d("span", {
1727
1742
  className: "toolbar-pending-hint",
1728
1743
  children: `Click an empty grid cell to place a room · ${g}+click to place without selecting`
1729
1744
  }),
1730
- !y && s === "addLabel" && /* @__PURE__ */ d("span", {
1745
+ !b && c === "addLabel" && /* @__PURE__ */ d("span", {
1731
1746
  className: "toolbar-pending-hint",
1732
1747
  children: "Click to place a label · select to move/edit · Delete to remove"
1733
1748
  }),
1734
- y?.kind === "paint" && /* @__PURE__ */ d("span", {
1749
+ b?.kind === "paint" && /* @__PURE__ */ d("span", {
1735
1750
  className: "toolbar-pending-hint",
1736
1751
  children: "Drag to paint multiple rooms · release to commit"
1737
1752
  }),
1738
- y?.kind === "pickSwatch" && /* @__PURE__ */ d("span", {
1753
+ b?.kind === "pickSwatch" && /* @__PURE__ */ d("span", {
1739
1754
  className: "toolbar-pending-hint",
1740
1755
  style: { color: "#ffd080" },
1741
1756
  children: "Click a room to copy its symbol & environment · Esc to cancel"
@@ -2684,7 +2699,7 @@ function Y(e, t) {
2684
2699
  redo: []
2685
2700
  })), r;
2686
2701
  }
2687
- function De(e, t) {
2702
+ function X(e, t) {
2688
2703
  if (e.length === 0) return !1;
2689
2704
  if (e.length === 1) return Y(e[0], t);
2690
2705
  let n = D.getState();
@@ -2700,7 +2715,7 @@ function De(e, t) {
2700
2715
  redo: []
2701
2716
  })), r;
2702
2717
  }
2703
- function Oe(e) {
2718
+ function De(e) {
2704
2719
  let t = D.getState();
2705
2720
  if (!t.map || t.undo.length === 0) return {
2706
2721
  changed: !1,
@@ -2715,7 +2730,7 @@ function Oe(e) {
2715
2730
  structural: r
2716
2731
  };
2717
2732
  }
2718
- function ke(e) {
2733
+ function Oe(e) {
2719
2734
  let t = D.getState();
2720
2735
  if (!t.map || t.redo.length === 0) return {
2721
2736
  changed: !1,
@@ -2730,7 +2745,7 @@ function ke(e) {
2730
2745
  structural: r
2731
2746
  };
2732
2747
  }
2733
- function Ae(e, t, n, r) {
2748
+ function ke(e, t, n, r) {
2734
2749
  if (n === 0 && r === 0) return [];
2735
2750
  let i = e.rooms[t];
2736
2751
  if (!i) return [];
@@ -2765,14 +2780,14 @@ function Ae(e, t, n, r) {
2765
2780
  }
2766
2781
  return a;
2767
2782
  }
2768
- function je(e, t) {
2783
+ function Ae(e, t) {
2769
2784
  return Ce(e, t).map((t) => ({
2770
2785
  roomId: t.roomId,
2771
2786
  dir: t.dir,
2772
2787
  was: J(e.rooms[t.roomId], t.dir)
2773
2788
  }));
2774
2789
  }
2775
- function Me(e, t) {
2790
+ function je(e, t) {
2776
2791
  let n = new Set(t), r = new Map(t.map((e) => [e, []]));
2777
2792
  for (let t of Object.keys(e.rooms)) {
2778
2793
  let i = Number(t);
@@ -2791,7 +2806,7 @@ function Me(e, t) {
2791
2806
  }
2792
2807
  //#endregion
2793
2808
  //#region src/components/panelShared.tsx
2794
- function Ne({ id: e, name: t, className: n }) {
2809
+ function Me({ id: e, name: t, className: n }) {
2795
2810
  return /* @__PURE__ */ f("button", {
2796
2811
  type: "button",
2797
2812
  className: n ?? "exit-target",
@@ -2836,11 +2851,11 @@ function Ne({ id: e, name: t, className: n }) {
2836
2851
  children: [
2837
2852
  "#",
2838
2853
  e,
2839
- t ? ` · ${t}` : ""
2854
+ t && String(e) !== t ? ` · ${t}` : ""
2840
2855
  ]
2841
2856
  });
2842
2857
  }
2843
- function X({ label: e, children: t, as: n = "label" }) {
2858
+ function Z({ label: e, children: t, as: n = "label" }) {
2844
2859
  return /* @__PURE__ */ f(n, {
2845
2860
  className: "field",
2846
2861
  children: [/* @__PURE__ */ d("span", {
@@ -2849,7 +2864,7 @@ function X({ label: e, children: t, as: n = "label" }) {
2849
2864
  }), t]
2850
2865
  });
2851
2866
  }
2852
- function Pe({ checked: e, onChange: t, description: n }) {
2867
+ function Ne({ checked: e, onChange: t, description: n }) {
2853
2868
  return /* @__PURE__ */ f("label", {
2854
2869
  className: "field checkbox-field",
2855
2870
  children: [/* @__PURE__ */ d("input", {
@@ -2859,7 +2874,7 @@ function Pe({ checked: e, onChange: t, description: n }) {
2859
2874
  }), /* @__PURE__ */ d("span", { children: n })]
2860
2875
  });
2861
2876
  }
2862
- function Fe({ activeTool: e }) {
2877
+ function Pe({ activeTool: e }) {
2863
2878
  return /* @__PURE__ */ d("p", {
2864
2879
  className: "hint-tool",
2865
2880
  children: {
@@ -2874,7 +2889,7 @@ function Fe({ activeTool: e }) {
2874
2889
  }[e] ?? ""
2875
2890
  });
2876
2891
  }
2877
- function Ie({ data: e, onCommit: t }) {
2892
+ function Fe({ data: e, onCommit: t }) {
2878
2893
  let [n, r] = i(""), [a, o] = i(""), s = () => {
2879
2894
  let e = n.trim();
2880
2895
  e && (t(e, null, a), r(""), o(""));
@@ -2941,14 +2956,14 @@ function Ie({ data: e, onCommit: t }) {
2941
2956
  ]
2942
2957
  });
2943
2958
  }
2944
- function Le(e) {
2959
+ function Ie(e) {
2945
2960
  return "#" + [
2946
2961
  e.r,
2947
2962
  e.g,
2948
2963
  e.b
2949
2964
  ].map((e) => e.toString(16).padStart(2, "0")).join("");
2950
2965
  }
2951
- function Re(e) {
2966
+ function Le(e) {
2952
2967
  return {
2953
2968
  spec: 1,
2954
2969
  alpha: 255,
@@ -2960,7 +2975,7 @@ function Re(e) {
2960
2975
  }
2961
2976
  //#endregion
2962
2977
  //#region src/components/AreaManagerModal.tsx
2963
- function ze({ sceneRef: e }) {
2978
+ function Re({ sceneRef: e }) {
2964
2979
  let t = O((e) => e.map), [n, r] = i(""), [a, o] = i(null), [s, c] = i(""), [l, u] = i(null), [p, m] = i(null);
2965
2980
  if (!t) return /* @__PURE__ */ d("div", {
2966
2981
  className: "modal-empty",
@@ -3032,7 +3047,7 @@ function ze({ sceneRef: e }) {
3032
3047
  }, y = () => {
3033
3048
  if (!l || l.moveTarget === "") return;
3034
3049
  let t = Number(l.moveTarget);
3035
- De([{
3050
+ X([{
3036
3051
  kind: "moveRoomsToArea",
3037
3052
  roomIds: [...l.rooms],
3038
3053
  fromAreaId: l.id,
@@ -3131,7 +3146,7 @@ function ze({ sceneRef: e }) {
3131
3146
  }),
3132
3147
  p === n && /* @__PURE__ */ d("div", {
3133
3148
  className: "area-ud-section",
3134
- children: /* @__PURE__ */ d(Ie, {
3149
+ children: /* @__PURE__ */ d(Fe, {
3135
3150
  data: t.areas[n]?.userData ?? {},
3136
3151
  onCommit: (t, r, i) => {
3137
3152
  Y({
@@ -3203,14 +3218,14 @@ function ze({ sceneRef: e }) {
3203
3218
  }
3204
3219
  //#endregion
3205
3220
  //#region src/components/EnvManagerModal.tsx
3206
- function Be(e) {
3221
+ function ze(e) {
3207
3222
  return "#" + [
3208
3223
  e.r,
3209
3224
  e.g,
3210
3225
  e.b
3211
3226
  ].map((e) => e.toString(16).padStart(2, "0")).join("");
3212
3227
  }
3213
- function Ve(e) {
3228
+ function Be(e) {
3214
3229
  return {
3215
3230
  spec: 1,
3216
3231
  alpha: 255,
@@ -3220,7 +3235,7 @@ function Ve(e) {
3220
3235
  pad: 0
3221
3236
  };
3222
3237
  }
3223
- function He({ sceneRef: e }) {
3238
+ function Ve({ sceneRef: e }) {
3224
3239
  let t = O((e) => e.map), n = O((e) => e.dataVersion), [r, a] = i(""), [o, s] = i(null), [c, l] = i(!1), [u, p] = i(""), [m, h] = i("#888888");
3225
3240
  if (!t) return /* @__PURE__ */ d("div", {
3226
3241
  className: "modal-empty",
@@ -3241,7 +3256,7 @@ function He({ sceneRef: e }) {
3241
3256
  }, S = () => {
3242
3257
  s(null), p(String(x())), l(!0);
3243
3258
  }, C = (n, r) => {
3244
- let i = Ve(r);
3259
+ let i = Be(r);
3245
3260
  Y({
3246
3261
  kind: "setCustomEnvColor",
3247
3262
  envId: n,
@@ -3262,7 +3277,7 @@ function He({ sceneRef: e }) {
3262
3277
  D.setState({ status: "Env IDs 1–256 are reserved. Use 257 or higher." });
3263
3278
  return;
3264
3279
  }
3265
- let r = Ve(m);
3280
+ let r = Be(m);
3266
3281
  Y({
3267
3282
  kind: "setCustomEnvColor",
3268
3283
  envId: n,
@@ -3367,7 +3382,7 @@ function He({ sceneRef: e }) {
3367
3382
  }),
3368
3383
  /* @__PURE__ */ d("input", {
3369
3384
  type: "color",
3370
- value: Be(t.mCustomEnvColors[y.envId]),
3385
+ value: ze(t.mCustomEnvColors[y.envId]),
3371
3386
  onChange: (e) => C(y.envId, e.target.value),
3372
3387
  style: {
3373
3388
  width: "100%",
@@ -3392,7 +3407,7 @@ function He({ sceneRef: e }) {
3392
3407
  }
3393
3408
  //#endregion
3394
3409
  //#region src/components/panels/HistoryPanel.tsx
3395
- function Ue(e) {
3410
+ function He(e) {
3396
3411
  switch (e.kind) {
3397
3412
  case "moveRoom": return `Move room #${e.id}`;
3398
3413
  case "addRoom": return `Add room #${e.id}`;
@@ -3434,10 +3449,10 @@ function Ue(e) {
3434
3449
  case "setLabelNoScaling": return `${e.to ? "Disable" : "Enable"} zoom scaling on label #${e.id}`;
3435
3450
  case "setLabelShowOnTop": return `Set label #${e.id} ${e.to ? "foreground" : "background"}`;
3436
3451
  case "resizeLabel": return `Resize label #${e.id}`;
3437
- case "batch": return Ue(e.cmds[0]);
3452
+ case "batch": return He(e.cmds[0]);
3438
3453
  }
3439
3454
  }
3440
- function We({ cmd: e, className: t, onClick: n, title: r }) {
3455
+ function Ue({ cmd: e, className: t, onClick: n, title: r }) {
3441
3456
  return /* @__PURE__ */ f("button", {
3442
3457
  type: "button",
3443
3458
  className: t,
@@ -3445,23 +3460,23 @@ function We({ cmd: e, className: t, onClick: n, title: r }) {
3445
3460
  title: r,
3446
3461
  children: [/* @__PURE__ */ d("span", {
3447
3462
  className: "history-label",
3448
- children: Ue(e)
3463
+ children: He(e)
3449
3464
  }), e.kind === "batch" && e.cmds.slice(1).map((e, t) => /* @__PURE__ */ d("span", {
3450
3465
  className: "history-sub",
3451
- children: Ue(e)
3466
+ children: He(e)
3452
3467
  }, t))]
3453
3468
  });
3454
3469
  }
3455
- function Ge({ sceneRef: e }) {
3470
+ function We({ sceneRef: e }) {
3456
3471
  let t = O((e) => e.undo), n = O((e) => e.redo), r = (t, n) => {
3457
3472
  let r = e.current, i = !1;
3458
3473
  for (let e = 0; e < t; e++) {
3459
- let e = Oe(r);
3474
+ let e = De(r);
3460
3475
  if (!e.changed) break;
3461
3476
  e.structural && (i = !0);
3462
3477
  }
3463
3478
  for (let e = 0; e < n; e++) {
3464
- let e = ke(r);
3479
+ let e = Oe(r);
3465
3480
  if (!e.changed) break;
3466
3481
  e.structural && (i = !0);
3467
3482
  }
@@ -3472,7 +3487,7 @@ function Ge({ sceneRef: e }) {
3472
3487
  children: /* @__PURE__ */ f("div", {
3473
3488
  className: "history-list",
3474
3489
  children: [
3475
- n.map((e, t) => /* @__PURE__ */ d(We, {
3490
+ n.map((e, t) => /* @__PURE__ */ d(Ue, {
3476
3491
  cmd: e,
3477
3492
  className: "history-item history-undone",
3478
3493
  onClick: () => r(0, n.length - t),
@@ -3488,7 +3503,7 @@ function Ge({ sceneRef: e }) {
3488
3503
  children: "Current state"
3489
3504
  })]
3490
3505
  }),
3491
- i.map((e, t) => /* @__PURE__ */ d(We, {
3506
+ i.map((e, t) => /* @__PURE__ */ d(Ue, {
3492
3507
  cmd: e,
3493
3508
  className: "history-item history-done",
3494
3509
  onClick: () => r(t + 1, 0),
@@ -3505,7 +3520,7 @@ function Ge({ sceneRef: e }) {
3505
3520
  }
3506
3521
  //#endregion
3507
3522
  //#region src/components/panels/MapPanel.tsx
3508
- function Ke(e, t) {
3523
+ function Ge(e, t) {
3509
3524
  let n = [], r = e.current?.reader;
3510
3525
  if (r) for (let e of r.getAreas()) {
3511
3526
  let t = e.getAreaId(), r = e.getAreaName();
@@ -3547,7 +3562,7 @@ function Ke(e, t) {
3547
3562
  }
3548
3563
  return n;
3549
3564
  }
3550
- function qe(e) {
3565
+ function Ke(e) {
3551
3566
  let t = D.getState(), n = e.areaId !== t.currentAreaId, r = e.z !== t.currentZ, i = e.x, a = -e.y;
3552
3567
  n || r ? (D.setState({
3553
3568
  selection: {
@@ -3575,7 +3590,7 @@ function qe(e) {
3575
3590
  sidebarTab: "selection"
3576
3591
  });
3577
3592
  }
3578
- function Je(e) {
3593
+ function qe(e) {
3579
3594
  let t = D.getState(), n = t.map?.rooms[e.roomId];
3580
3595
  if (!n) return;
3581
3596
  let r = n.area !== t.currentAreaId, i = n.z !== t.currentZ;
@@ -3603,7 +3618,7 @@ function Je(e) {
3603
3618
  sidebarTab: "selection"
3604
3619
  });
3605
3620
  }
3606
- function Ye({ sceneRef: e }) {
3621
+ function Je({ sceneRef: e }) {
3607
3622
  let t = O((e) => e.map);
3608
3623
  if (O((e) => e.structureVersion), O((e) => e.dataVersion), !t) return /* @__PURE__ */ f("div", {
3609
3624
  className: "panel-content",
@@ -3612,7 +3627,7 @@ function Ye({ sceneRef: e }) {
3612
3627
  children: "Drag a .dat file in or load from toolbar."
3613
3628
  })]
3614
3629
  });
3615
- let n = Object.keys(t.rooms).length, r = Object.keys(t.areas).length, i = Object.keys(t.mCustomEnvColors).length, a = Ke(e, t);
3630
+ let n = Object.keys(t.rooms).length, r = Object.keys(t.areas).length, i = Object.keys(t.mCustomEnvColors).length, a = Ge(e, t);
3616
3631
  return /* @__PURE__ */ f("div", {
3617
3632
  className: "panel-content",
3618
3633
  children: [
@@ -3663,7 +3678,7 @@ function Ye({ sceneRef: e }) {
3663
3678
  ]
3664
3679
  }),
3665
3680
  /* @__PURE__ */ d("h4", { children: "User Data" }),
3666
- /* @__PURE__ */ d(Ie, {
3681
+ /* @__PURE__ */ d(Fe, {
3667
3682
  data: t.mUserData ?? {},
3668
3683
  onCommit: (t, n, r) => {
3669
3684
  Y({
@@ -3702,7 +3717,7 @@ function Ye({ sceneRef: e }) {
3702
3717
  /* @__PURE__ */ d("button", {
3703
3718
  type: "button",
3704
3719
  className: "warning-go-btn",
3705
- onClick: () => qe(e),
3720
+ onClick: () => Ke(e),
3706
3721
  children: "Go"
3707
3722
  })
3708
3723
  ]
@@ -3729,7 +3744,7 @@ function Ye({ sceneRef: e }) {
3729
3744
  /* @__PURE__ */ d("button", {
3730
3745
  type: "button",
3731
3746
  className: "warning-go-btn",
3732
- onClick: () => Je(e),
3747
+ onClick: () => qe(e),
3733
3748
  children: "Go"
3734
3749
  })
3735
3750
  ]
@@ -3741,7 +3756,7 @@ function Ye({ sceneRef: e }) {
3741
3756
  }
3742
3757
  //#endregion
3743
3758
  //#region src/components/panels/ExitPanel.tsx
3744
- function Xe({ selection: e, map: t, sceneRef: n }) {
3759
+ function Ye({ selection: e, map: t, sceneRef: n }) {
3745
3760
  let r = t.rooms[e.fromId], i = t.rooms[e.toId], a = {
3746
3761
  north: "south",
3747
3762
  south: "north",
@@ -3783,7 +3798,7 @@ function Xe({ selection: e, map: t, sceneRef: n }) {
3783
3798
  /* @__PURE__ */ f("div", {
3784
3799
  className: "exit-flow",
3785
3800
  children: [
3786
- /* @__PURE__ */ d(Ne, {
3801
+ /* @__PURE__ */ d(Me, {
3787
3802
  id: e.fromId,
3788
3803
  name: r?.name
3789
3804
  }),
@@ -3818,7 +3833,7 @@ function Xe({ selection: e, map: t, sceneRef: n }) {
3818
3833
  })
3819
3834
  ]
3820
3835
  }),
3821
- /* @__PURE__ */ d(Ne, {
3836
+ /* @__PURE__ */ d(Me, {
3822
3837
  id: e.toId,
3823
3838
  name: i?.name
3824
3839
  })
@@ -3834,10 +3849,10 @@ function Xe({ selection: e, map: t, sceneRef: n }) {
3834
3849
  }
3835
3850
  //#endregion
3836
3851
  //#region src/editor/coords.ts
3837
- function Ze(e, t) {
3852
+ function Xe(e, t) {
3838
3853
  return Math.round(e / t) * t;
3839
3854
  }
3840
- function Qe(e, t, n, r) {
3855
+ function Ze(e, t, n, r) {
3841
3856
  let i = t.getBoundingClientRect(), a = e.backend.viewport.clientToMapPoint(n, r, {
3842
3857
  left: i.left,
3843
3858
  top: i.top
@@ -3851,7 +3866,7 @@ function Qe(e, t, n, r) {
3851
3866
  }
3852
3867
  //#endregion
3853
3868
  //#region src/editor/hitTest.ts
3854
- function $e(e, t, n, r, i) {
3869
+ function Qe(e, t, n, r, i) {
3855
3870
  let a = i.getArea(e);
3856
3871
  if (!a) return null;
3857
3872
  let o = a.getPlane(t);
@@ -3866,7 +3881,7 @@ function $e(e, t, n, r, i) {
3866
3881
  }
3867
3882
  return c;
3868
3883
  }
3869
- function et(e, t, n, r, i) {
3884
+ function $e(e, t, n, r, i) {
3870
3885
  let a = i.getArea(e);
3871
3886
  if (!a) return [];
3872
3887
  let o = a.getPlane(t);
@@ -3881,7 +3896,7 @@ function et(e, t, n, r, i) {
3881
3896
  }
3882
3897
  return c;
3883
3898
  }
3884
- function tt(e, t, n, r, i, a, o, s) {
3899
+ function et(e, t, n, r, i, a, o, s) {
3885
3900
  let c = [], l = e.backend.culling?.findRoomAtMapPoint?.(i, a);
3886
3901
  if (l) {
3887
3902
  let e = t.rooms[l.id];
@@ -3890,19 +3905,19 @@ function tt(e, t, n, r, i, a, o, s) {
3890
3905
  id: Number(i)
3891
3906
  });
3892
3907
  }
3893
- let u = et(n, r, i, a, s);
3908
+ let u = $e(n, r, i, a, s);
3894
3909
  for (let e = u.length - 1; e >= 0; e--) c.push({
3895
3910
  kind: "label",
3896
3911
  id: u[e].id,
3897
3912
  areaId: u[e].areaId
3898
3913
  });
3899
- let d = lt(e, i, a, o);
3914
+ let d = ct(e, i, a, o);
3900
3915
  d && c.push({
3901
3916
  kind: "customLine",
3902
3917
  roomId: d.roomId,
3903
3918
  exitName: d.exitName
3904
3919
  });
3905
- let f = ct(e, i, a, o);
3920
+ let f = st(e, i, a, o);
3906
3921
  return f && c.push({
3907
3922
  kind: "exit",
3908
3923
  fromId: f.fromId,
@@ -3910,7 +3925,7 @@ function tt(e, t, n, r, i, a, o, s) {
3910
3925
  dir: f.dir
3911
3926
  }), c;
3912
3927
  }
3913
- function nt(e, t, n, r) {
3928
+ function tt(e, t, n, r) {
3914
3929
  let i = .05, a = e.x - i, o = e.y - i, s = e.w + i * 2, c = e.h + i * 2, l = Math.max(.15, r), u = [
3915
3930
  [
3916
3931
  a,
@@ -3962,7 +3977,7 @@ function nt(e, t, n, r) {
3962
3977
  }
3963
3978
  return d?.handle ?? null;
3964
3979
  }
3965
- function rt(e, t, n, r, i) {
3980
+ function nt(e, t, n, r, i) {
3966
3981
  let a = e.areas[t];
3967
3982
  if (!a) return null;
3968
3983
  for (let t of a.rooms) {
@@ -3971,22 +3986,22 @@ function rt(e, t, n, r, i) {
3971
3986
  }
3972
3987
  return null;
3973
3988
  }
3974
- function it(e, t, n, r, i, a) {
3989
+ function rt(e, t, n, r, i, a) {
3975
3990
  let o = i - n, s = a - r, c = o * o + s * s;
3976
3991
  if (c < 1e-9) return Math.hypot(e - n, t - r);
3977
3992
  let l = ((e - n) * o + (t - r) * s) / c;
3978
3993
  return l = Math.max(0, Math.min(1, l)), Math.hypot(e - (n + l * o), t - (r + l * s));
3979
3994
  }
3980
- function at(e, t, n) {
3995
+ function it(e, t, n) {
3981
3996
  if (e.length < 4) return Infinity;
3982
3997
  let r = Infinity;
3983
3998
  for (let i = 0; i + 3 < e.length; i += 2) {
3984
- let a = it(t, n, e[i], e[i + 1], e[i + 2], e[i + 3]);
3999
+ let a = rt(t, n, e[i], e[i + 1], e[i + 2], e[i + 3]);
3985
4000
  a < r && (r = a);
3986
4001
  }
3987
4002
  return r;
3988
4003
  }
3989
- var ot = [
4004
+ var at = [
3990
4005
  [
3991
4006
  0,
3992
4007
  -1,
@@ -4028,18 +4043,18 @@ var ot = [
4028
4043
  "northwest"
4029
4044
  ]
4030
4045
  ];
4031
- function st(e, t, n) {
4046
+ function ot(e, t, n) {
4032
4047
  let r = e.x - t.x, i = e.y - t.y;
4033
4048
  if (r === 0 && i === 0) return "east";
4034
4049
  let a = (Math.atan2(i, r) * 180 / Math.PI + 360) % 360;
4035
4050
  return a < 22.5 || a >= 337.5 ? "east" : a < 67.5 ? "southeast" : a < 112.5 ? "south" : a < 157.5 ? "southwest" : a < 202.5 ? "west" : a < 247.5 ? "northwest" : a < 292.5 ? "north" : "northeast";
4036
4051
  }
4037
- function ct(e, t, n, r) {
4052
+ function st(e, t, n, r) {
4038
4053
  let i = r * .35, a = e.getDrawnExits(), o = null;
4039
4054
  for (let e of a) {
4040
4055
  let r = Infinity, a = !0;
4041
4056
  for (let i of e.data.lines) {
4042
- let e = at(i.points, t, n);
4057
+ let e = it(i.points, t, n);
4043
4058
  if (e < r) {
4044
4059
  r = e;
4045
4060
  let o = Math.hypot(t - i.points[0], n - i.points[1]), s = i.points.length - 2;
@@ -4047,7 +4062,7 @@ function ct(e, t, n, r) {
4047
4062
  }
4048
4063
  }
4049
4064
  for (let i of e.data.arrows) {
4050
- let o = at(i.points, t, n);
4065
+ let o = it(i.points, t, n);
4051
4066
  if (o < r) {
4052
4067
  r = o;
4053
4068
  let s = Math.hypot(t - i.points[0], n - i.points[1]), c = i.points.length - 2, l = Math.hypot(t - i.points[c], n - i.points[c + 1]);
@@ -4081,10 +4096,10 @@ function ct(e, t, n, r) {
4081
4096
  dir: o.bDir
4082
4097
  } : null : null;
4083
4098
  }
4084
- function lt(e, t, n, r) {
4099
+ function ct(e, t, n, r) {
4085
4100
  let i = r * .5, a = null;
4086
4101
  for (let r of e.getDrawnSpecialExits()) {
4087
- let e = at(r.points, t, n);
4102
+ let e = it(r.points, t, n);
4088
4103
  e < i && (a === null || e < a.dist) && (a = {
4089
4104
  roomId: r.roomId,
4090
4105
  exitName: r.exitName,
@@ -4096,13 +4111,13 @@ function lt(e, t, n, r) {
4096
4111
  exitName: a.exitName
4097
4112
  } : null;
4098
4113
  }
4099
- function ut(e, t, n, r, i, a) {
4114
+ function lt(e, t, n, r, i, a) {
4100
4115
  let o = a * .5;
4101
4116
  for (let a of e.getDrawnSpecialExits()) {
4102
4117
  if (a.roomId !== t || a.exitName !== n) continue;
4103
4118
  let e = null;
4104
4119
  for (let t = 0; t + 3 < a.points.length; t += 2) {
4105
- let n = it(r, i, a.points[t], a.points[t + 1], a.points[t + 2], a.points[t + 3]);
4120
+ let n = rt(r, i, a.points[t], a.points[t + 1], a.points[t + 2], a.points[t + 3]);
4106
4121
  n < o && (e === null || n < e.dist) && (e = {
4107
4122
  segIdx: t / 2,
4108
4123
  dist: n
@@ -4112,7 +4127,7 @@ function ut(e, t, n, r, i, a) {
4112
4127
  }
4113
4128
  return null;
4114
4129
  }
4115
- function dt(e, t, n, r, i, a) {
4130
+ function ut(e, t, n, r, i, a) {
4116
4131
  let o = a * .45;
4117
4132
  for (let a of e.getDrawnSpecialExits()) {
4118
4133
  if (a.roomId !== t || a.exitName !== n) continue;
@@ -4130,21 +4145,21 @@ function dt(e, t, n, r, i, a) {
4130
4145
  }
4131
4146
  //#endregion
4132
4147
  //#region src/editor/tools.ts
4133
- var ft = null;
4134
- function pt(e) {
4135
- ft = e;
4148
+ var dt = null;
4149
+ function ft(e) {
4150
+ dt = e;
4136
4151
  }
4137
- function Z(e, t) {
4138
- return Qe(e.renderer, e.container, t.clientX, t.clientY);
4152
+ function Q(e, t) {
4153
+ return Ze(e.renderer, e.container, t.clientX, t.clientY);
4139
4154
  }
4140
- function mt(e, t) {
4141
- let n = Z(e, t), r = D.getState();
4155
+ function pt(e, t) {
4156
+ let n = Q(e, t), r = D.getState();
4142
4157
  return r.snapToGrid ? {
4143
- x: Ze(n.x, r.gridStep),
4144
- y: Ze(n.y, r.gridStep)
4158
+ x: Xe(n.x, r.gridStep),
4159
+ y: Xe(n.y, r.gridStep)
4145
4160
  } : n;
4146
4161
  }
4147
- function ht() {
4162
+ function mt() {
4148
4163
  let e = D.getState();
4149
4164
  return !e.map || e.currentAreaId == null ? null : {
4150
4165
  map: e.map,
@@ -4153,8 +4168,8 @@ function ht() {
4153
4168
  state: e
4154
4169
  };
4155
4170
  }
4156
- function Q(e, t) {
4157
- if (!ht()) return null;
4171
+ function $(e, t) {
4172
+ if (!mt()) return null;
4158
4173
  let n = e.container.getBoundingClientRect(), r = e.renderer.backend.viewport.clientToMapPoint(t.clientX, t.clientY, {
4159
4174
  left: n.left,
4160
4175
  top: n.top
@@ -4163,14 +4178,14 @@ function Q(e, t) {
4163
4178
  let i = e.renderer.backend.culling?.findRoomAtMapPoint?.(r.x, r.y);
4164
4179
  return i ? e.scene.getRenderRoom(i.id) ?? null : null;
4165
4180
  }
4166
- var gt = .15, _t = {
4181
+ var ht = .15, gt = {
4167
4182
  id: "select",
4168
4183
  cursor: "default",
4169
4184
  onPointerDown(e, t) {
4170
4185
  if (e.button !== 0) return !1;
4171
4186
  let n = D.getState();
4172
4187
  if (n.contextMenu && D.setState({ contextMenu: null }), n.pending?.kind === "pickExit") {
4173
- let r = Q(t, e);
4188
+ let r = $(t, e);
4174
4189
  if (r && n.map) {
4175
4190
  let { fromId: e, dir: i } = n.pending, a = n.map.rooms[e];
4176
4191
  if (a) {
@@ -4195,8 +4210,8 @@ var gt = .15, _t = {
4195
4210
  return !0;
4196
4211
  }
4197
4212
  if (n.pending?.kind === "pickSpecialExit") {
4198
- let r = Q(t, e), i = n.pending.fromId;
4199
- return r && ft && ft(r.id), D.setState({
4213
+ let r = $(t, e), i = n.pending.fromId;
4214
+ return r && dt && dt(r.id), D.setState({
4200
4215
  pending: null,
4201
4216
  selection: {
4202
4217
  kind: "room",
@@ -4205,7 +4220,7 @@ var gt = .15, _t = {
4205
4220
  }), !0;
4206
4221
  }
4207
4222
  if (n.pending?.kind === "pickSwatch") {
4208
- let r = Q(t, e);
4223
+ let r = $(t, e);
4209
4224
  if (r && n.map) {
4210
4225
  let e = n.map.rooms[r.id];
4211
4226
  e && window.dispatchEvent(new CustomEvent("editor:swatchRoomPicked", { detail: {
@@ -4215,9 +4230,9 @@ var gt = .15, _t = {
4215
4230
  }
4216
4231
  return D.setState({ pending: null }), !0;
4217
4232
  }
4218
- let r = Z(t, e), i = ht();
4233
+ let r = Q(t, e), i = mt();
4219
4234
  if (e.altKey) {
4220
- let e = i ? tt(t.renderer, i.map, i.areaId, i.z, r.x, r.y, t.settings.roomSize, t.scene.reader) : [];
4235
+ let e = i ? et(t.renderer, i.map, i.areaId, i.z, r.x, r.y, t.settings.roomSize, t.scene.reader) : [];
4221
4236
  if (e.length > 0) {
4222
4237
  let t = Math.round(r.x), i = Math.round(r.y), a = n.hitCycle, o = a && a.x === t && a.y === i ? (a.index + 1) % e.length : 0, s = e[o];
4223
4238
  D.setState({
@@ -4226,15 +4241,15 @@ var gt = .15, _t = {
4226
4241
  y: i,
4227
4242
  index: o
4228
4243
  },
4229
- selection: Lt(s),
4244
+ selection: It(s),
4230
4245
  sidebarTab: "selection",
4231
- status: `Selected ${Rt(s)} (${o + 1}/${e.length})`
4246
+ status: `Selected ${Lt(s)} (${o + 1}/${e.length})`
4232
4247
  });
4233
4248
  }
4234
4249
  return !0;
4235
4250
  }
4236
4251
  if (D.setState({ hitCycle: null }), n.selection?.kind === "customLine" && i) {
4237
- let i = dt(t.renderer, n.selection.roomId, n.selection.exitName, r.x, r.y, t.settings.roomSize);
4252
+ let i = ut(t.renderer, n.selection.roomId, n.selection.exitName, r.x, r.y, t.settings.roomSize);
4238
4253
  if (i !== null) {
4239
4254
  let r = n.map?.rooms[n.selection.roomId], a = r?.customLines?.[n.selection.exitName] ? [...r.customLines[n.selection.exitName]] : [];
4240
4255
  return D.setState({
@@ -4269,7 +4284,7 @@ var gt = .15, _t = {
4269
4284
  }), c = t.renderer.backend.viewport.clientToMapPoint(8, 0, {
4270
4285
  left: o.left,
4271
4286
  top: o.top
4272
- }), l = s && c ? Math.abs(c.x - s.x) : .25, u = nt(n, r.x, r.y, l);
4287
+ }), l = s && c ? Math.abs(c.x - s.x) : .25, u = tt(n, r.x, r.y, l);
4273
4288
  if (u) return D.setState({ pending: {
4274
4289
  kind: "labelResize",
4275
4290
  labelId: i.id,
@@ -4280,7 +4295,7 @@ var gt = .15, _t = {
4280
4295
  } }), t.container.setPointerCapture(e.pointerId), !0;
4281
4296
  }
4282
4297
  }
4283
- let a = $e(i.areaId, i.z, r.x, r.y, t.scene.reader);
4298
+ let a = Qe(i.areaId, i.z, r.x, r.y, t.scene.reader);
4284
4299
  if (a) {
4285
4300
  let n = t.scene.reader.getLabelSnapshot(a.areaId, a.id), i = n ? n.pos[0] : 0, o = n ? -n.pos[1] : 0;
4286
4301
  return D.setState({
@@ -4301,7 +4316,7 @@ var gt = .15, _t = {
4301
4316
  }), t.container.setPointerCapture(e.pointerId), !0;
4302
4317
  }
4303
4318
  }
4304
- let a = Q(t, e);
4319
+ let a = $(t, e);
4305
4320
  if (a && n.selection?.kind === "room") {
4306
4321
  let e = a, r = n.selection.ids.find((n) => {
4307
4322
  let r = t.scene.getRenderRoom(n);
@@ -4312,6 +4327,13 @@ var gt = .15, _t = {
4312
4327
  if (a) {
4313
4328
  let i = n.map?.rooms[a.id];
4314
4329
  if (!i) return !0;
4330
+ if (e.shiftKey) {
4331
+ let e = n.selection?.kind === "room" ? n.selection.ids : [];
4332
+ return e.includes(a.id) || D.setState({ selection: {
4333
+ kind: "room",
4334
+ ids: [...e, a.id]
4335
+ } }), !0;
4336
+ }
4315
4337
  if (e.ctrlKey || e.metaKey) {
4316
4338
  let e = n.selection?.kind === "room" ? n.selection.ids : [], t = e.indexOf(a.id) >= 0 ? e.filter((e) => e !== a.id) : [...e, a.id];
4317
4339
  return D.setState({ selection: t.length === 0 ? null : {
@@ -4365,13 +4387,13 @@ var gt = .15, _t = {
4365
4387
  }), t.container.setPointerCapture(e.pointerId), !0;
4366
4388
  }
4367
4389
  if (i) {
4368
- let e = lt(t.renderer, r.x, r.y, t.settings.roomSize);
4390
+ let e = ct(t.renderer, r.x, r.y, t.settings.roomSize);
4369
4391
  if (e) return D.setState({ selection: {
4370
4392
  kind: "customLine",
4371
4393
  roomId: e.roomId,
4372
4394
  exitName: e.exitName
4373
4395
  } }), !0;
4374
- let n = ct(t.renderer, r.x, r.y, t.settings.roomSize);
4396
+ let n = st(t.renderer, r.x, r.y, t.settings.roomSize);
4375
4397
  if (n) return D.setState({ selection: {
4376
4398
  kind: "exit",
4377
4399
  fromId: n.fromId,
@@ -4379,7 +4401,7 @@ var gt = .15, _t = {
4379
4401
  dir: n.dir
4380
4402
  } }), !0;
4381
4403
  }
4382
- let o = Z(t, e);
4404
+ let o = Q(t, e);
4383
4405
  return D.setState({ pending: {
4384
4406
  kind: "marquee",
4385
4407
  startX: o.x,
@@ -4387,25 +4409,30 @@ var gt = .15, _t = {
4387
4409
  currentX: o.x,
4388
4410
  currentY: o.y,
4389
4411
  ctrlHeld: e.ctrlKey || e.metaKey,
4412
+ shiftHeld: e.shiftKey,
4390
4413
  preExistingIds: n.selection?.kind === "room" ? n.selection.ids : []
4391
4414
  } }), t.container.setPointerCapture(e.pointerId), !0;
4392
4415
  },
4393
4416
  onPointerMove(e, t) {
4394
4417
  let n = D.getState();
4395
4418
  if (n.pending?.kind === "customLinePoint") {
4396
- let r = mt(t, e);
4419
+ let r = pt(t, e);
4397
4420
  return t.scene.reader.setCustomLinePoint(n.pending.roomId, n.pending.exitName, n.pending.pointIndex, r.x, r.y), t.refresh(), D.bumpData(), !0;
4398
4421
  }
4399
4422
  if (n.pending?.kind === "marquee") {
4400
- let r = Z(t, e), i = {
4423
+ let r = Q(t, e), i = {
4401
4424
  ...n.pending,
4402
4425
  currentX: r.x,
4403
4426
  currentY: r.y
4404
- }, a = vt(Math.min(i.startX, r.x), Math.max(i.startX, r.x), Math.min(i.startY, r.y), Math.max(i.startY, r.y)), o;
4427
+ }, a = _t(Math.min(i.startX, r.x), Math.max(i.startX, r.x), Math.min(i.startY, r.y), Math.max(i.startY, r.y)), o;
4405
4428
  if (i.ctrlHeld) {
4406
4429
  let e = new Set(i.preExistingIds);
4407
4430
  for (let t of a) e.has(t) ? e.delete(t) : e.add(t);
4408
4431
  o = [...e];
4432
+ } else if (i.shiftHeld) {
4433
+ let e = new Set(i.preExistingIds);
4434
+ for (let t of a) e.add(t);
4435
+ o = [...e];
4409
4436
  } else o = a;
4410
4437
  return D.setState({
4411
4438
  pending: i,
@@ -4416,28 +4443,28 @@ var gt = .15, _t = {
4416
4443
  }), !0;
4417
4444
  }
4418
4445
  if (n.pending?.kind === "labelDrag") {
4419
- let r = Z(t, e), i = {
4446
+ let r = Q(t, e), i = {
4420
4447
  x: r.x - n.pending.offsetX,
4421
4448
  y: r.y - n.pending.offsetY
4422
4449
  }, a = n.snapToGrid ? {
4423
- x: Ze(i.x, n.gridStep),
4424
- y: Ze(i.y, n.gridStep)
4450
+ x: Xe(i.x, n.gridStep),
4451
+ y: Xe(i.y, n.gridStep)
4425
4452
  } : i, o = t.scene.reader.getLabelSnapshot(n.pending.areaId, n.pending.labelId), s = o ? a.x - o.pos[0] : 1, c = o ? a.y - -o.pos[1] : 1;
4426
4453
  return (s !== 0 || c !== 0) && (t.scene.reader.moveLabel(n.pending.areaId, n.pending.labelId, a.x, a.y), t.refresh(), D.bumpData()), !0;
4427
4454
  }
4428
4455
  if (n.pending?.kind === "labelResize") {
4429
- let r = Z(t, e), i = n.pending, a = n.labelAspectRatioLocked && i.originSize[1] > 0 ? i.originSize[0] / i.originSize[1] : void 0, o = jt(i.handle, i.originPos[0], -i.originPos[1], i.originSize[0], i.originSize[1], r.x, r.y, a), s = t.scene.reader.getLabelSnapshot(i.areaId, i.labelId);
4456
+ let r = Q(t, e), i = n.pending, a = n.labelAspectRatioLocked && i.originSize[1] > 0 ? i.originSize[0] / i.originSize[1] : void 0, o = At(i.handle, i.originPos[0], -i.originPos[1], i.originSize[0], i.originSize[1], r.x, r.y, a), s = t.scene.reader.getLabelSnapshot(i.areaId, i.labelId);
4430
4457
  return (!s || o.x !== s.pos[0] || o.y !== -s.pos[1] || o.w !== s.size[0] || o.h !== s.size[1]) && (t.scene.reader.moveLabel(i.areaId, i.labelId, o.x, o.y), t.scene.reader.setLabelSize(i.areaId, i.labelId, o.w, o.h), t.scene.refresh()), !0;
4431
4458
  }
4432
- if (n.pending?.kind !== "drag") return zt(t, e), !1;
4459
+ if (n.pending?.kind !== "drag") return Rt(t, e), !1;
4433
4460
  let r = t.scene.getRenderRoom(n.pending.roomId);
4434
4461
  if (!r) return !0;
4435
- let i = Z(t, e), a = {
4462
+ let i = Q(t, e), a = {
4436
4463
  x: i.x - n.pending.offsetX,
4437
4464
  y: i.y - n.pending.offsetY
4438
4465
  }, o = n.snapToGrid ? {
4439
- x: Ze(a.x, n.gridStep),
4440
- y: Ze(a.y, n.gridStep)
4466
+ x: Xe(a.x, n.gridStep),
4467
+ y: Xe(a.y, n.gridStep)
4441
4468
  } : a, s = o.x - r.x, c = o.y - r.y;
4442
4469
  if (s !== 0 || c !== 0) {
4443
4470
  if (t.scene.reader.moveRoom(n.pending.roomId, o.x, o.y, r.z), n.pending.multiOrigins) for (let { id: e } of n.pending.multiOrigins) {
@@ -4495,7 +4522,7 @@ var gt = .15, _t = {
4495
4522
  t.container.releasePointerCapture(e.pointerId);
4496
4523
  } catch {}
4497
4524
  let r = n.pending, i = Math.abs(r.currentX - r.startX), a = Math.abs(r.currentY - r.startY);
4498
- return i <= gt && a <= gt && !r.ctrlHeld && D.setState({ selection: null }), D.setState({ pending: null }), !0;
4525
+ return i <= ht && a <= ht && !r.ctrlHeld && !r.shiftHeld && D.setState({ selection: null }), D.setState({ pending: null }), !0;
4499
4526
  }
4500
4527
  if (n.pending?.kind === "labelDrag" && n.map) {
4501
4528
  let e = n.pending, r = t.scene.reader.getLabelSnapshot(e.areaId, e.labelId);
@@ -4597,9 +4624,17 @@ var gt = .15, _t = {
4597
4624
  onContextMenu(e, t) {
4598
4625
  let n = D.getState();
4599
4626
  if (!n.map) return !1;
4600
- let r = Z(t, e), i = ht();
4627
+ if (n.spreadShrink) {
4628
+ let r = $(t, e);
4629
+ if (r) return D.setState({ spreadShrink: {
4630
+ ...n.spreadShrink,
4631
+ centerMode: "anchor",
4632
+ anchorRoomId: r.id
4633
+ } }), !0;
4634
+ }
4635
+ let r = Q(t, e), i = mt();
4601
4636
  if (i) {
4602
- let n = tt(t.renderer, i.map, i.areaId, i.z, r.x, r.y, t.settings.roomSize, t.scene.reader).filter((e) => e.kind !== "exit" && e.kind !== "customLine");
4637
+ let n = et(t.renderer, i.map, i.areaId, i.z, r.x, r.y, t.settings.roomSize, t.scene.reader).filter((e) => e.kind !== "exit" && e.kind !== "customLine");
4603
4638
  if (n.length > 1) return D.setState({ contextMenu: {
4604
4639
  kind: "disambiguate",
4605
4640
  hits: n,
@@ -4607,7 +4642,7 @@ var gt = .15, _t = {
4607
4642
  screenY: e.clientY
4608
4643
  } }), !0;
4609
4644
  }
4610
- let a = Q(t, e);
4645
+ let a = $(t, e);
4611
4646
  if (a) return D.setState({ contextMenu: {
4612
4647
  kind: "room",
4613
4648
  roomId: a.id,
@@ -4615,7 +4650,7 @@ var gt = .15, _t = {
4615
4650
  screenY: e.clientY
4616
4651
  } }), !0;
4617
4652
  if (i) {
4618
- let n = $e(i.areaId, i.z, r.x, r.y, t.scene.reader);
4653
+ let n = Qe(i.areaId, i.z, r.x, r.y, t.scene.reader);
4619
4654
  if (n) return D.setState({
4620
4655
  selection: {
4621
4656
  kind: "label",
@@ -4635,7 +4670,7 @@ var gt = .15, _t = {
4635
4670
  if (n.selection?.kind !== "customLine") return !1;
4636
4671
  let o = n.selection, s = n.map.rooms[o.roomId], c = s?.customLines?.[o.exitName];
4637
4672
  if (!s || !c) return !1;
4638
- let l = dt(t.renderer, o.roomId, o.exitName, r.x, r.y, t.settings.roomSize);
4673
+ let l = ut(t.renderer, o.roomId, o.exitName, r.x, r.y, t.settings.roomSize);
4639
4674
  if (l !== null) return D.setState({
4640
4675
  selection: {
4641
4676
  kind: "customLine",
@@ -4652,10 +4687,10 @@ var gt = .15, _t = {
4652
4687
  screenY: e.clientY
4653
4688
  }
4654
4689
  }), !0;
4655
- let u = ut(t.renderer, o.roomId, o.exitName, r.x, r.y, t.settings.roomSize);
4690
+ let u = lt(t.renderer, o.roomId, o.exitName, r.x, r.y, t.settings.roomSize);
4656
4691
  if (u !== null) {
4657
- let n = mt(t, e);
4658
- return yt(t, o.roomId, o.exitName, u.insertIndex, n.x, n.y), !0;
4692
+ let n = pt(t, e);
4693
+ return vt(t, o.roomId, o.exitName, u.insertIndex, n.x, n.y), !0;
4659
4694
  }
4660
4695
  return !1;
4661
4696
  },
@@ -4682,7 +4717,7 @@ var gt = .15, _t = {
4682
4717
  D.setState({ pending: null });
4683
4718
  }
4684
4719
  };
4685
- function vt(e, t, n, r) {
4720
+ function _t(e, t, n, r) {
4686
4721
  let i = D.getState();
4687
4722
  if (!i.map || i.currentAreaId == null) return [];
4688
4723
  let a = [];
@@ -4693,7 +4728,7 @@ function vt(e, t, n, r) {
4693
4728
  }
4694
4729
  return a;
4695
4730
  }
4696
- function yt(e, t, n, r, i, a) {
4731
+ function vt(e, t, n, r, i, a) {
4697
4732
  let o = D.getState();
4698
4733
  if (!o.map) return;
4699
4734
  let s = o.map.rooms[t], c = s?.customLines?.[n];
@@ -4733,17 +4768,17 @@ function yt(e, t, n, r, i, a) {
4733
4768
  status: `Added waypoint to '${n}' on room ${t}`
4734
4769
  });
4735
4770
  }
4736
- var bt = {
4771
+ var yt = {
4737
4772
  id: "connect",
4738
4773
  cursor: "crosshair",
4739
4774
  onPointerDown(e, t) {
4740
4775
  if (e.button !== 0) return !1;
4741
- let n = Q(t, e);
4776
+ let n = $(t, e);
4742
4777
  if (!n) return D.getState().pending?.kind === "connect" && D.setState({
4743
4778
  pending: null,
4744
4779
  status: "Connect cancelled."
4745
4780
  }), !0;
4746
- let r = Z(t, e), i = st(r, {
4781
+ let r = Q(t, e), i = ot(r, {
4747
4782
  x: n.x,
4748
4783
  y: n.y
4749
4784
  }, t.settings.roomSize);
@@ -4768,10 +4803,10 @@ var bt = {
4768
4803
  return !0;
4769
4804
  },
4770
4805
  onPointerMove(e, t) {
4771
- let n = D.getState(), r = Z(t, e), i = Q(t, e), a = i ? i.id : null;
4806
+ let n = D.getState(), r = Q(t, e), i = $(t, e), a = i ? i.id : null;
4772
4807
  if (n.pending?.kind === "connect") {
4773
4808
  let e = null;
4774
- return i && i.id !== n.pending.sourceId && (e = st(r, {
4809
+ return i && i.id !== n.pending.sourceId && (e = ot(r, {
4775
4810
  x: i.x,
4776
4811
  y: i.y
4777
4812
  }, t.settings.roomSize)), D.setState({ pending: {
@@ -4781,7 +4816,7 @@ var bt = {
4781
4816
  targetDir: e
4782
4817
  } }), !0;
4783
4818
  }
4784
- return zt(t, e), !1;
4819
+ return Rt(t, e), !1;
4785
4820
  },
4786
4821
  onPointerUp(e, t) {
4787
4822
  let n = D.getState();
@@ -4790,13 +4825,13 @@ var bt = {
4790
4825
  try {
4791
4826
  t.container.releasePointerCapture(e.pointerId);
4792
4827
  } catch {}
4793
- return r.hoverTargetId != null && r.hoverTargetId !== r.sourceId ? xt(t, r.sourceId, r.hoverTargetId, r.sourceDir, r.targetDir, e.shiftKey) : D.setState({ status: "Connect cancelled." }), D.setState({ pending: null }), !0;
4828
+ return r.hoverTargetId != null && r.hoverTargetId !== r.sourceId ? bt(t, r.sourceId, r.hoverTargetId, r.sourceDir, r.targetDir, e.shiftKey) : D.setState({ status: "Connect cancelled." }), D.setState({ pending: null }), !0;
4794
4829
  },
4795
4830
  onCancel() {
4796
4831
  D.setState({ pending: null });
4797
4832
  }
4798
4833
  };
4799
- function xt(e, t, n, r, i, a) {
4834
+ function bt(e, t, n, r, i, a) {
4800
4835
  let o = e.scene.getRenderRoom(t), s = e.scene.getRenderRoom(n);
4801
4836
  if (!o || !s) return;
4802
4837
  let c = r ?? Se(o.x, o.y, s.x, s.y);
@@ -4819,16 +4854,16 @@ function xt(e, t, n, r, i, a) {
4819
4854
  let g = h ? `Connected ${t}.${c} ↔ ${n}.${f}` : `Connected ${t}.${c} → ${n}`;
4820
4855
  D.setState({ status: g });
4821
4856
  }
4822
- var St = {
4857
+ var xt = {
4823
4858
  id: "unlink",
4824
4859
  cursor: "crosshair",
4825
4860
  onPointerDown(e, t) {
4826
4861
  if (e.button !== 0) return !1;
4827
- let n = ht();
4862
+ let n = mt();
4828
4863
  if (!n) return !1;
4829
- let r = Z(t, e), i = Q(t, e), a = t.settings.roomSize / 2;
4864
+ let r = Q(t, e), i = $(t, e), a = t.settings.roomSize / 2;
4830
4865
  if (!(i && Math.abs(r.x - i.x) <= a && Math.abs(r.y - i.y) <= a)) {
4831
- let e = lt(t.renderer, r.x, r.y, t.settings.roomSize);
4866
+ let e = ct(t.renderer, r.x, r.y, t.settings.roomSize);
4832
4867
  if (e) {
4833
4868
  let r = n.map.rooms[e.roomId], i = r?.customLines?.[e.exitName] ?? [], a = r?.customLinesColor?.[e.exitName] ?? {
4834
4869
  spec: 1,
@@ -4851,7 +4886,7 @@ var St = {
4851
4886
  let c = D.getState();
4852
4887
  return c.selection?.kind === "customLine" && c.selection.roomId === e.roomId && c.selection.exitName === e.exitName && D.setState({ selection: null }), D.setState({ status: `Removed custom line '${e.exitName}' from room ${e.roomId}` }), !0;
4853
4888
  }
4854
- let i = ct(t.renderer, r.x, r.y, t.settings.roomSize);
4889
+ let i = st(t.renderer, r.x, r.y, t.settings.roomSize);
4855
4890
  if (i) {
4856
4891
  if (!n.map.rooms[i.fromId]) return !0;
4857
4892
  let e = me[i.dir], r = n.map.rooms[i.toId], a = r && we(e) && J(r, e) === i.fromId ? {
@@ -4900,17 +4935,17 @@ var St = {
4900
4935
  }, t.scene), t.refresh(), D.bumpData(), D.setState({ status: `Removed all exits from room ${i.id}` }), !0);
4901
4936
  },
4902
4937
  onPointerMove(e, t) {
4903
- zt(t, e);
4938
+ Rt(t, e);
4904
4939
  }
4905
- }, Ct = {
4940
+ }, St = {
4906
4941
  id: "addRoom",
4907
4942
  cursor: "crosshair",
4908
4943
  onPointerDown(e, t) {
4909
4944
  if (e.button !== 0) return !1;
4910
- let n = ht();
4945
+ let n = mt();
4911
4946
  if (!n) return !1;
4912
- let { x: r, y: i } = mt(t, e), a = r, o = -i;
4913
- if (rt(n.map, n.areaId, a, o, n.z)) return D.setState({ status: "Cell is already occupied." }), !0;
4947
+ let { x: r, y: i } = pt(t, e), a = r, o = -i;
4948
+ if (nt(n.map, n.areaId, a, o, n.z)) return D.setState({ status: "Cell is already occupied." }), !0;
4914
4949
  let s = be(n.map);
4915
4950
  return Y({
4916
4951
  kind: "addRoom",
@@ -4927,17 +4962,17 @@ var St = {
4927
4962
  }), !0;
4928
4963
  },
4929
4964
  onPointerMove(e, t) {
4930
- let n = mt(t, e);
4931
- D.setState({ snapCursor: n }), zt(t, e);
4965
+ let n = pt(t, e);
4966
+ D.setState({ snapCursor: n }), Rt(t, e);
4932
4967
  }
4933
- }, wt = {
4968
+ }, Ct = {
4934
4969
  id: "delete",
4935
4970
  cursor: "not-allowed",
4936
4971
  onPointerDown(e, t) {
4937
4972
  if (e.button !== 0) return !1;
4938
- let n = ht();
4973
+ let n = mt();
4939
4974
  if (!n) return !1;
4940
- let r = Z(t, e), i = $e(n.areaId, n.z, r.x, r.y, t.scene.reader);
4975
+ let r = Q(t, e), i = Qe(n.areaId, n.z, r.x, r.y, t.scene.reader);
4941
4976
  if (i) {
4942
4977
  let e = t.scene.reader.getLabelSnapshot(i.areaId, i.id);
4943
4978
  if (e) {
@@ -4951,9 +4986,9 @@ var St = {
4951
4986
  }
4952
4987
  return !0;
4953
4988
  }
4954
- let a = Q(t, e), o = t.settings.roomSize / 2;
4989
+ let a = $(t, e), o = t.settings.roomSize / 2;
4955
4990
  if (!(a && Math.abs(r.x - a.x) <= o && Math.abs(r.y - a.y) <= o)) {
4956
- let e = lt(t.renderer, r.x, r.y, t.settings.roomSize);
4991
+ let e = ct(t.renderer, r.x, r.y, t.settings.roomSize);
4957
4992
  if (e) {
4958
4993
  let r = n.map.rooms[e.roomId], i = r?.customLines?.[e.exitName] ?? [], a = r?.customLinesColor?.[e.exitName] ?? {
4959
4994
  spec: 1,
@@ -4976,7 +5011,7 @@ var St = {
4976
5011
  let c = D.getState();
4977
5012
  return c.selection?.kind === "customLine" && c.selection.roomId === e.roomId && c.selection.exitName === e.exitName && D.setState({ selection: null }), D.setState({ status: `Removed custom line '${e.exitName}' from room ${e.roomId}` }), !0;
4978
5013
  }
4979
- let i = ct(t.renderer, r.x, r.y, t.settings.roomSize);
5014
+ let i = st(t.renderer, r.x, r.y, t.settings.roomSize);
4980
5015
  if (i) {
4981
5016
  if (!n.map.rooms[i.fromId]) return !0;
4982
5017
  let e = me[i.dir], r = n.map.rooms[i.toId], a = r && we(e) && J(r, e) === i.fromId ? {
@@ -4998,7 +5033,7 @@ var St = {
4998
5033
  if (!a) return D.setState({ status: "No exit, custom line, or room under cursor." }), !0;
4999
5034
  let s = n.map.rooms[a.id];
5000
5035
  if (!s) return !0;
5001
- let c = { ...s }, l = je(n.map, a.id);
5036
+ let c = { ...s }, l = Ae(n.map, a.id);
5002
5037
  Y({
5003
5038
  kind: "deleteRoom",
5004
5039
  id: a.id,
@@ -5010,37 +5045,37 @@ var St = {
5010
5045
  return u.selection?.kind === "room" && u.selection.ids.includes(a.id) && D.setState({ selection: null }), D.setState({ status: `Deleted room ${a.id}` }), !0;
5011
5046
  },
5012
5047
  onPointerMove(e, t) {
5013
- zt(t, e);
5048
+ Rt(t, e);
5014
5049
  }
5015
- }, Tt = !1, Et = {
5050
+ }, wt = !1, Tt = {
5016
5051
  id: "pan",
5017
5052
  cursor: "grab",
5018
5053
  onPointerDown(e, t) {
5019
- return e.button !== 0 || e.pointerType !== "mouse" ? !1 : (t.renderer.backend.viewport.startDrag(e.clientX, e.clientY), Tt = !0, !0);
5054
+ return e.button !== 0 || e.pointerType !== "mouse" ? !1 : (t.renderer.backend.viewport.startDrag(e.clientX, e.clientY), wt = !0, !0);
5020
5055
  },
5021
5056
  onPointerMove(e, t) {
5022
5057
  if (e.pointerType === "mouse") {
5023
- if (!Tt) {
5058
+ if (!wt) {
5024
5059
  if (e.buttons === 0) return;
5025
- t.renderer.backend.viewport.startDrag(e.clientX, e.clientY), Tt = !0;
5060
+ t.renderer.backend.viewport.startDrag(e.clientX, e.clientY), wt = !0;
5026
5061
  }
5027
5062
  return t.renderer.backend.viewport.updateDrag(e.clientX, e.clientY), t.refresh(), !0;
5028
5063
  }
5029
5064
  },
5030
5065
  onPointerUp(e, t) {
5031
- return Tt ? (t.renderer.backend.viewport.endDrag(), Tt = !1, !0) : !1;
5066
+ return wt ? (t.renderer.backend.viewport.endDrag(), wt = !1, !0) : !1;
5032
5067
  },
5033
5068
  onCancel(e) {
5034
- Tt &&= (e.renderer.backend.viewport.endDrag(), !1);
5069
+ wt &&= (e.renderer.backend.viewport.endDrag(), !1);
5035
5070
  }
5036
- }, Dt = {
5071
+ }, Et = {
5037
5072
  id: "customLine",
5038
5073
  cursor: "crosshair",
5039
5074
  onPointerDown(e, t) {
5040
5075
  let n = D.getState();
5041
5076
  if (!n.pending || n.pending.kind !== "customLine" || e.button !== 0) return !1;
5042
- let r = mt(t, e), i = [...n.pending.points, [r.x, r.y]];
5043
- return Ot(n.pending, i, t), D.setState({ pending: {
5077
+ let r = pt(t, e), i = [...n.pending.points, [r.x, r.y]];
5078
+ return Dt(n.pending, i, t), D.setState({ pending: {
5044
5079
  ...n.pending,
5045
5080
  points: i,
5046
5081
  cursor: r
@@ -5048,31 +5083,31 @@ var St = {
5048
5083
  },
5049
5084
  onContextMenu(e, t) {
5050
5085
  let n = D.getState();
5051
- return n.pending?.kind === "customLine" ? (At(n.pending, t), !0) : !1;
5086
+ return n.pending?.kind === "customLine" ? (kt(n.pending, t), !0) : !1;
5052
5087
  },
5053
5088
  onPointerMove(e, t) {
5054
- let n = D.getState(), r = mt(t, e);
5089
+ let n = D.getState(), r = pt(t, e);
5055
5090
  return n.pending?.kind === "customLine" ? (D.setState({ pending: {
5056
5091
  ...n.pending,
5057
5092
  cursor: r
5058
- } }), !0) : (zt(t, e), !1);
5093
+ } }), !0) : (Rt(t, e), !1);
5059
5094
  },
5060
5095
  onPointerUp() {
5061
5096
  return !1;
5062
5097
  },
5063
5098
  onCancel(e) {
5064
5099
  let t = D.getState();
5065
- t.pending?.kind === "customLine" && e && kt(t.pending, e.scene), D.setState({
5100
+ t.pending?.kind === "customLine" && e && Ot(t.pending, e.scene), D.setState({
5066
5101
  pending: null,
5067
5102
  status: "Custom line cancelled."
5068
5103
  }), D.bumpData();
5069
5104
  }
5070
5105
  };
5071
- function Ot(e, t, n) {
5106
+ function Dt(e, t, n) {
5072
5107
  let r = t.slice(1).map(([e, t]) => [e, -t]);
5073
5108
  n.scene.reader.setCustomLine(e.roomId, e.exitName, r, e.color, e.style, e.arrow), n.refresh();
5074
5109
  }
5075
- function kt(e, t) {
5110
+ function Ot(e, t) {
5076
5111
  if (e.previousSnapshot) {
5077
5112
  let n = e.previousSnapshot;
5078
5113
  t.reader.setCustomLine(e.roomId, e.exitName, n.points, n.color, n.style, n.arrow);
@@ -5086,10 +5121,10 @@ function kt(e, t) {
5086
5121
  }
5087
5122
  t.refresh();
5088
5123
  }
5089
- function At(e, t) {
5124
+ function kt(e, t) {
5090
5125
  if (!D.getState().map) return;
5091
5126
  if (e.points.length < 2) {
5092
- t && kt(e, t.scene), D.setState({
5127
+ t && Ot(e, t.scene), D.setState({
5093
5128
  pending: null,
5094
5129
  activeTool: "select",
5095
5130
  status: "Need at least 1 waypoint — cancelled."
@@ -5128,7 +5163,7 @@ function At(e, t) {
5128
5163
  status: `Custom line '${e.exitName}' saved on room ${e.roomId}`
5129
5164
  });
5130
5165
  }
5131
- function jt(e, t, n, r, i, a, o, s) {
5166
+ function At(e, t, n, r, i, a, o, s) {
5132
5167
  let c = t, l = t + r, u = n, d = n + i;
5133
5168
  switch (e) {
5134
5169
  case "nw":
@@ -5189,19 +5224,19 @@ function jt(e, t, n, r, i, a, o, s) {
5189
5224
  h
5190
5225
  };
5191
5226
  }
5192
- function Mt(e) {
5227
+ function jt(e) {
5193
5228
  let t = 0;
5194
5229
  for (let n of Object.values(e.labels ?? {})) for (let e of n) e.id > t && (t = e.id);
5195
5230
  return t + 1;
5196
5231
  }
5197
- var Nt = {
5232
+ var Mt = {
5198
5233
  id: "addLabel",
5199
5234
  cursor: "crosshair",
5200
5235
  onPointerDown(e, t) {
5201
5236
  if (e.button !== 0) return !1;
5202
- let n = ht();
5237
+ let n = mt();
5203
5238
  if (!n) return !1;
5204
- let r = mt(t, e);
5239
+ let r = pt(t, e);
5205
5240
  return D.setState({ pending: {
5206
5241
  kind: "labelRect",
5207
5242
  areaId: n.areaId,
@@ -5215,15 +5250,15 @@ var Nt = {
5215
5250
  onPointerMove(e, t) {
5216
5251
  let n = D.getState();
5217
5252
  if (n.pending?.kind === "labelRect") {
5218
- let r = Z(t, e);
5253
+ let r = Q(t, e);
5219
5254
  return D.setState({ pending: {
5220
5255
  ...n.pending,
5221
5256
  currentX: r.x,
5222
5257
  currentY: r.y
5223
5258
  } }), !0;
5224
5259
  }
5225
- let r = mt(t, e);
5226
- D.setState({ snapCursor: r }), zt(t, e);
5260
+ let r = pt(t, e);
5261
+ D.setState({ snapCursor: r }), Rt(t, e);
5227
5262
  },
5228
5263
  onPointerUp(e, t) {
5229
5264
  let n = D.getState();
@@ -5231,9 +5266,9 @@ var Nt = {
5231
5266
  try {
5232
5267
  t.container.releasePointerCapture(e.pointerId);
5233
5268
  } catch {}
5234
- let r = n.pending, i = ht();
5269
+ let r = n.pending, i = mt();
5235
5270
  if (!i) return D.setState({ pending: null }), !0;
5236
- let a = Math.abs(r.currentX - r.startX), o = Math.abs(r.currentY - r.startY), s = a < .5 ? 4 : a, c = o < .5 ? 1 : o, l = a < .5 ? r.startX : Math.min(r.startX, r.currentX), u = o < .5 ? r.startY : Math.min(r.startY, r.currentY), d = Mt(i.map), f = {
5271
+ let a = Math.abs(r.currentX - r.startX), o = Math.abs(r.currentY - r.startY), s = a < .5 ? 4 : a, c = o < .5 ? 1 : o, l = a < .5 ? r.startX : Math.min(r.startX, r.currentX), u = o < .5 ? r.startY : Math.min(r.startY, r.currentY), d = jt(i.map), f = {
5237
5272
  id: d,
5238
5273
  pos: [
5239
5274
  l,
@@ -5281,13 +5316,13 @@ var Nt = {
5281
5316
  D.setState({ pending: null });
5282
5317
  }
5283
5318
  };
5284
- function Pt(e) {
5319
+ function Nt(e) {
5285
5320
  return !e.activeSwatchSetId || !e.activeSwatchId ? null : [...e.swatchSets, ...e.pluginSwatchSets].find((t) => t.id === e.activeSwatchSetId)?.swatches.find((t) => t.id === e.activeSwatchId) ?? null;
5286
5321
  }
5287
- function Ft(e, t, n) {
5322
+ function Pt(e, t, n) {
5288
5323
  let r = D.getState();
5289
5324
  if (r.pending?.kind !== "paint") return;
5290
- let i = Q(e, t);
5325
+ let i = $(e, t);
5291
5326
  if (!i || r.pending.painted.some((e) => e.id === i.id)) return;
5292
5327
  let a = r.map?.rooms[i.id];
5293
5328
  if (!a) return;
@@ -5303,31 +5338,31 @@ function Ft(e, t, n) {
5303
5338
  painted: c
5304
5339
  } });
5305
5340
  }
5306
- var It = {
5307
- select: _t,
5308
- connect: bt,
5309
- unlink: St,
5310
- addRoom: Ct,
5311
- delete: wt,
5312
- pan: Et,
5313
- customLine: Dt,
5314
- addLabel: Nt,
5341
+ var Ft = {
5342
+ select: gt,
5343
+ connect: yt,
5344
+ unlink: xt,
5345
+ addRoom: St,
5346
+ delete: Ct,
5347
+ pan: Tt,
5348
+ customLine: Et,
5349
+ addLabel: Mt,
5315
5350
  paint: {
5316
5351
  id: "paint",
5317
5352
  cursor: "cell",
5318
5353
  onPointerDown(e, t) {
5319
5354
  if (e.button !== 0) return !1;
5320
- let n = Pt(D.getState());
5355
+ let n = Nt(D.getState());
5321
5356
  return n ? (D.setState({ pending: {
5322
5357
  kind: "paint",
5323
5358
  painted: []
5324
- } }), t.container.setPointerCapture(e.pointerId), Ft(t, e, n), !0) : (D.setState({ status: "No swatch selected — open the Swatches palette first." }), !0);
5359
+ } }), t.container.setPointerCapture(e.pointerId), Pt(t, e, n), !0) : (D.setState({ status: "No swatch selected — open the Swatches palette first." }), !0);
5325
5360
  },
5326
5361
  onPointerMove(e, t) {
5327
5362
  let n = D.getState();
5328
- if (n.pending?.kind !== "paint") return zt(t, e), !1;
5329
- let r = Pt(n);
5330
- return r && Ft(t, e, r), !0;
5363
+ if (n.pending?.kind !== "paint") return Rt(t, e), !1;
5364
+ let r = Nt(n);
5365
+ return r && Pt(t, e, r), !0;
5331
5366
  },
5332
5367
  onPointerUp(e, t) {
5333
5368
  let n = D.getState();
@@ -5335,7 +5370,7 @@ var It = {
5335
5370
  try {
5336
5371
  t.container.releasePointerCapture(e.pointerId);
5337
5372
  } catch {}
5338
- let r = n.pending.painted, i = Pt(n);
5373
+ let r = n.pending.painted, i = Nt(n);
5339
5374
  if (r.length > 0 && i) {
5340
5375
  let e = [];
5341
5376
  for (let { id: t, prevSymbol: n, prevEnv: a } of r) n !== i.symbol && e.push({
@@ -5374,7 +5409,7 @@ var It = {
5374
5409
  }
5375
5410
  }
5376
5411
  };
5377
- function Lt(e) {
5412
+ function It(e) {
5378
5413
  switch (e.kind) {
5379
5414
  case "room": return {
5380
5415
  kind: "room",
@@ -5398,7 +5433,7 @@ function Lt(e) {
5398
5433
  };
5399
5434
  }
5400
5435
  }
5401
- function Rt(e) {
5436
+ function Lt(e) {
5402
5437
  switch (e.kind) {
5403
5438
  case "room": return `room ${e.id}`;
5404
5439
  case "label": return `label ${e.id}`;
@@ -5406,12 +5441,12 @@ function Rt(e) {
5406
5441
  case "exit": return `exit ${e.dir} (${e.fromId}→${e.toId})`;
5407
5442
  }
5408
5443
  }
5409
- function zt(e, t) {
5410
- let n = ht();
5444
+ function Rt(e, t) {
5445
+ let n = mt();
5411
5446
  if (!n) return;
5412
- let r = Z(e, t), i = Q(e, t), a = null;
5447
+ let r = Q(e, t), i = $(e, t), a = null;
5413
5448
  if (i) {
5414
- let t = st(r, {
5449
+ let t = ot(r, {
5415
5450
  x: i.x,
5416
5451
  y: i.y
5417
5452
  }, e.settings.roomSize);
@@ -5421,21 +5456,21 @@ function zt(e, t) {
5421
5456
  handleDir: t
5422
5457
  };
5423
5458
  } else {
5424
- let t = $e(n.areaId, n.z, r.x, r.y, e.scene.reader);
5459
+ let t = Qe(n.areaId, n.z, r.x, r.y, e.scene.reader);
5425
5460
  if (t) a = {
5426
5461
  kind: "label",
5427
5462
  id: t.id,
5428
5463
  areaId: t.areaId
5429
5464
  };
5430
5465
  else {
5431
- let t = lt(e.renderer, r.x, r.y, e.settings.roomSize);
5466
+ let t = ct(e.renderer, r.x, r.y, e.settings.roomSize);
5432
5467
  if (t) a = {
5433
5468
  kind: "customLine",
5434
5469
  roomId: t.roomId,
5435
5470
  exitName: t.exitName
5436
5471
  };
5437
5472
  else {
5438
- let t = ct(e.renderer, r.x, r.y, e.settings.roomSize);
5473
+ let t = st(e.renderer, r.x, r.y, e.settings.roomSize);
5439
5474
  t && (a = {
5440
5475
  kind: "exit",
5441
5476
  ...t
@@ -5444,18 +5479,18 @@ function zt(e, t) {
5444
5479
  }
5445
5480
  }
5446
5481
  let o = D.getState().hover;
5447
- Bt(o, a) || D.setState({ hover: a });
5482
+ zt(o, a) || D.setState({ hover: a });
5448
5483
  }
5449
- function Bt(e, t) {
5484
+ function zt(e, t) {
5450
5485
  return e === t ? !0 : !e || !t || e.kind !== t.kind ? !1 : e.kind === "room" && t.kind === "room" ? e.id === t.id && e.handleDir === t.handleDir : e.kind === "exit" && t.kind === "exit" ? e.fromId === t.fromId && e.toId === t.toId && e.dir === t.dir : e.kind === "customLine" && t.kind === "customLine" ? e.roomId === t.roomId && e.exitName === t.exitName : e.kind === "label" && t.kind === "label" ? e.id === t.id && e.areaId === t.areaId : !1;
5451
5486
  }
5452
5487
  //#endregion
5453
5488
  //#region src/components/panels/CustomLinePanel.tsx
5454
- function Vt({ pending: e, sceneRef: t }) {
5489
+ function Bt({ pending: e, sceneRef: t }) {
5455
5490
  let n = (t) => D.setState({ pending: {
5456
5491
  ...e,
5457
5492
  ...t
5458
- } }), r = Le(e.color), i = (r) => {
5493
+ } }), r = Ie(e.color), i = (r) => {
5459
5494
  n(r);
5460
5495
  let i = t.current;
5461
5496
  if (!i) return;
@@ -5479,7 +5514,7 @@ function Vt({ pending: e, sceneRef: t }) {
5479
5514
  "Click to add waypoints · right-click or Enter to finish · Esc cancels."
5480
5515
  ]
5481
5516
  }),
5482
- /* @__PURE__ */ d(X, {
5517
+ /* @__PURE__ */ d(Z, {
5483
5518
  label: "Exit Name",
5484
5519
  children: /* @__PURE__ */ d("span", {
5485
5520
  className: "readonly",
@@ -5510,7 +5545,7 @@ function Vt({ pending: e, sceneRef: t }) {
5510
5545
  }), /* @__PURE__ */ d("input", {
5511
5546
  type: "color",
5512
5547
  value: r,
5513
- onChange: (e) => i({ color: Re(e.target.value) })
5548
+ onChange: (e) => i({ color: Le(e.target.value) })
5514
5549
  })]
5515
5550
  }),
5516
5551
  /* @__PURE__ */ f("div", {
@@ -5571,14 +5606,14 @@ function Vt({ pending: e, sceneRef: t }) {
5571
5606
  },
5572
5607
  children: [/* @__PURE__ */ d("button", {
5573
5608
  type: "button",
5574
- onClick: () => At(e),
5609
+ onClick: () => kt(e),
5575
5610
  disabled: e.points.length < 2,
5576
5611
  style: { flex: 1 },
5577
5612
  children: "Finish"
5578
5613
  }), /* @__PURE__ */ d("button", {
5579
5614
  type: "button",
5580
5615
  onClick: () => {
5581
- t.current && kt(e, t.current), D.setState({
5616
+ t.current && Ot(e, t.current), D.setState({
5582
5617
  pending: null,
5583
5618
  activeTool: "select",
5584
5619
  status: "Custom line cancelled."
@@ -5592,8 +5627,8 @@ function Vt({ pending: e, sceneRef: t }) {
5592
5627
  })
5593
5628
  });
5594
5629
  }
5595
- function Ht({ selection: e, map: t, sceneRef: n }) {
5596
- let r = t.rooms[e.roomId], a = r?.customLines?.[e.exitName], o = r?.customLinesColor?.[e.exitName], s = r?.customLinesStyle?.[e.exitName] ?? 1, c = r?.customLinesArrow?.[e.exitName] ?? !1, l = r?.mSpecialExits?.[e.exitName], p = J(r, he[e.exitName] ?? e.exitName), m = l ?? (p != null && p > 0 ? p : void 0), h = m == null ? null : t.rooms[m], [g, _] = i(o ? Le(o) : "#ffffff"), [v, y] = i(s), [b, x] = i(c), [S, C] = i(null);
5630
+ function Vt({ selection: e, map: t, sceneRef: n }) {
5631
+ let r = t.rooms[e.roomId], a = r?.customLines?.[e.exitName], o = r?.customLinesColor?.[e.exitName], s = r?.customLinesStyle?.[e.exitName] ?? 1, c = r?.customLinesArrow?.[e.exitName] ?? !1, l = r?.mSpecialExits?.[e.exitName], p = J(r, he[e.exitName] ?? e.exitName), m = l ?? (p != null && p > 0 ? p : void 0), h = m == null ? null : t.rooms[m], [g, _] = i(o ? Ie(o) : "#ffffff"), [v, y] = i(s), [b, x] = i(c), [S, C] = i(null);
5597
5632
  if (!r || !a) return /* @__PURE__ */ d("h3", { children: "Custom line not found" });
5598
5633
  let w = (e) => ({
5599
5634
  points: a,
@@ -5703,7 +5738,7 @@ function Ht({ selection: e, map: t, sceneRef: n }) {
5703
5738
  children: [/* @__PURE__ */ d("span", {
5704
5739
  className: "label",
5705
5740
  children: h == null ? "Room" : "From"
5706
- }), /* @__PURE__ */ d(Ne, {
5741
+ }), /* @__PURE__ */ d(Me, {
5707
5742
  id: e.roomId,
5708
5743
  name: r.name
5709
5744
  })]
@@ -5713,7 +5748,7 @@ function Ht({ selection: e, map: t, sceneRef: n }) {
5713
5748
  children: [/* @__PURE__ */ d("span", {
5714
5749
  className: "label",
5715
5750
  children: "To"
5716
- }), /* @__PURE__ */ d(Ne, {
5751
+ }), /* @__PURE__ */ d(Me, {
5717
5752
  id: m,
5718
5753
  name: h.name
5719
5754
  })]
@@ -5751,7 +5786,7 @@ function Ht({ selection: e, map: t, sceneRef: n }) {
5751
5786
  type: "color",
5752
5787
  value: g,
5753
5788
  onChange: (e) => _(e.target.value),
5754
- onBlur: (e) => E({ color: Re(e.target.value) })
5789
+ onBlur: (e) => E({ color: Le(e.target.value) })
5755
5790
  })]
5756
5791
  }),
5757
5792
  /* @__PURE__ */ f("div", {
@@ -5856,7 +5891,7 @@ function Ht({ selection: e, map: t, sceneRef: n }) {
5856
5891
  width: "100%"
5857
5892
  },
5858
5893
  onClick: () => {
5859
- let t = D.getState().gridStep, r = a.map(([e, n]) => [Ze(e, t), -Ze(-n, t)]);
5894
+ let t = D.getState().gridStep, r = a.map(([e, n]) => [Xe(e, t), -Xe(-n, t)]);
5860
5895
  if (!r.some((e, t) => e[0] !== a[t][0] || e[1] !== a[t][1])) {
5861
5896
  D.setState({ status: `Custom line '${e.exitName}' already on grid.` });
5862
5897
  return;
@@ -5894,28 +5929,28 @@ function Ht({ selection: e, map: t, sceneRef: n }) {
5894
5929
  }
5895
5930
  //#endregion
5896
5931
  //#region src/editor/labelPixmap.ts
5897
- var Ut = 64;
5898
- function Wt(e) {
5932
+ var Ht = 64;
5933
+ function Ut(e) {
5899
5934
  return `rgba(${e.r},${e.g},${e.b},${(e.alpha / 255).toFixed(3)})`;
5900
5935
  }
5901
- function Gt(e) {
5936
+ function Wt(e) {
5902
5937
  let t = document.createElement("canvas"), n = t.getContext("2d");
5903
5938
  if (!n) return "";
5904
- let r = Math.max(1, Math.round(e.size[0] * Ut)), i = Math.max(1, Math.round(e.size[1] * Ut)), a = window.devicePixelRatio || 1;
5905
- if (t.width = r * a, t.height = i * a, n.scale(a, a), n.fillStyle = Wt(e.bgColor), n.fillRect(0, 0, r, i), !e.text) return t.toDataURL("image/png");
5939
+ let r = Math.max(1, Math.round(e.size[0] * Ht)), i = Math.max(1, Math.round(e.size[1] * Ht)), a = window.devicePixelRatio || 1;
5940
+ if (t.width = r * a, t.height = i * a, n.scale(a, a), n.fillStyle = Ut(e.bgColor), n.fillRect(0, 0, r, i), !e.text) return t.toDataURL("image/png");
5906
5941
  let { font: o } = e;
5907
5942
  n.font = [
5908
5943
  o.italic ? "italic" : "",
5909
5944
  o.bold ? "bold" : "",
5910
5945
  `${o.size}px`,
5911
5946
  `"${o.family}", sans-serif`
5912
- ].filter(Boolean).join(" "), n.fillStyle = Wt(e.fgColor), n.textBaseline = "middle", n.textAlign = "center";
5947
+ ].filter(Boolean).join(" "), n.fillStyle = Ut(e.fgColor), n.textBaseline = "middle", n.textAlign = "center";
5913
5948
  let s = e.text.split("\n"), c = o.size * 1.25, l = (i - s.length * c) / 2 + c / 2, u = r / 2;
5914
5949
  for (let t = 0; t < s.length; t++) {
5915
5950
  let i = l + t * c;
5916
- if (e.outlineColor && e.outlineColor.alpha > 0 && (n.strokeStyle = Wt(e.outlineColor), n.lineWidth = Math.max(1, o.size / 12), n.lineJoin = "round", n.strokeText(s[t], u, i, r)), n.fillText(s[t], u, i, r), o.underline || o.strikeout) {
5951
+ if (e.outlineColor && e.outlineColor.alpha > 0 && (n.strokeStyle = Ut(e.outlineColor), n.lineWidth = Math.max(1, o.size / 12), n.lineJoin = "round", n.strokeText(s[t], u, i, r)), n.fillText(s[t], u, i, r), o.underline || o.strikeout) {
5917
5952
  let r = n.measureText(s[t]).width, a = u - r / 2, c = u + r / 2;
5918
- if (n.strokeStyle = Wt(e.fgColor), n.lineWidth = Math.max(1, o.size / 14), o.underline) {
5953
+ if (n.strokeStyle = Ut(e.fgColor), n.lineWidth = Math.max(1, o.size / 14), o.underline) {
5919
5954
  let e = i + o.size * .6;
5920
5955
  n.beginPath(), n.moveTo(a, e), n.lineTo(c, e), n.stroke();
5921
5956
  }
@@ -5924,13 +5959,13 @@ function Gt(e) {
5924
5959
  }
5925
5960
  return t.toDataURL("image/png");
5926
5961
  }
5927
- function Kt(e) {
5962
+ function Gt(e) {
5928
5963
  let t = e.includes(",") ? e.split(",")[1] : e;
5929
5964
  return t ? re.from(t, "base64") : re.alloc(0);
5930
5965
  }
5931
5966
  //#endregion
5932
5967
  //#region src/components/FontPicker.tsx
5933
- function qt({ value: e, options: n, onChange: a }) {
5968
+ function Kt({ value: e, options: n, onChange: a }) {
5934
5969
  let [o, s] = i(!1), [c, p] = i(""), [m, h] = i(-1), [g, _] = i({}), v = r(null), y = r(null), b = r(null), x = c.trim() ? n.filter((e) => e.toLowerCase().includes(c.toLowerCase())) : n;
5935
5970
  t(() => {
5936
5971
  let t = x.findIndex((t) => t === e);
@@ -6033,7 +6068,7 @@ function qt({ value: e, options: n, onChange: a }) {
6033
6068
  }
6034
6069
  //#endregion
6035
6070
  //#region src/components/panels/LabelPanel.tsx
6036
- var Jt = [
6071
+ var qt = [
6037
6072
  "Arial",
6038
6073
  "Arial Black",
6039
6074
  "Comic Sans MS",
@@ -6046,9 +6081,9 @@ var Jt = [
6046
6081
  "Times New Roman",
6047
6082
  "Trebuchet MS",
6048
6083
  "Verdana"
6049
- ], Yt = (e, t) => e.r === t.r && e.g === t.g && e.b === t.b && e.alpha === t.alpha, Xt = (e, t) => e === void 0 && t === void 0 ? !0 : e === void 0 || t === void 0 ? !1 : Yt(e, t), Zt = 64;
6050
- function Qt({ selection: e, sceneRef: n }) {
6051
- let a = O((e) => e.dataVersion), o = O((e) => e.labelAspectRatioLocked), s = n.current?.reader.getLabelSnapshot(e.areaId, e.id), [c, l] = i(s?.text ?? ""), [p, m] = i(String(s?.size[0] ?? 4)), [h, g] = i(String(s?.size[1] ?? 1)), [_, v] = i(s?.bgColor.alpha ?? 255), [y, b] = i(s?.outlineColor?.alpha ?? 0), [x, S] = i(Jt);
6084
+ ], Jt = (e, t) => e.r === t.r && e.g === t.g && e.b === t.b && e.alpha === t.alpha, Yt = (e, t) => e === void 0 && t === void 0 ? !0 : e === void 0 || t === void 0 ? !1 : Jt(e, t), Xt = 64;
6085
+ function Zt({ selection: e, sceneRef: n }) {
6086
+ let a = O((e) => e.dataVersion), o = O((e) => e.labelAspectRatioLocked), s = n.current?.reader.getLabelSnapshot(e.areaId, e.id), [c, l] = i(s?.text ?? ""), [p, m] = i(String(s?.size[0] ?? 4)), [h, g] = i(String(s?.size[1] ?? 1)), [_, v] = i(s?.bgColor.alpha ?? 255), [y, b] = i(s?.outlineColor?.alpha ?? 0), [x, S] = i(qt);
6052
6087
  t(() => {
6053
6088
  "queryLocalFonts" in window && window.queryLocalFonts?.().then((e) => {
6054
6089
  let t = [...new Set(e.map((e) => e.family))].sort();
@@ -6077,7 +6112,7 @@ function Qt({ selection: e, sceneRef: n }) {
6077
6112
  })
6078
6113
  });
6079
6114
  let N = (t) => {
6080
- let n = Gt(t);
6115
+ let n = Wt(t);
6081
6116
  return n === t.pixMap ? [] : [{
6082
6117
  kind: "setLabelPixmap",
6083
6118
  areaId: e.areaId,
@@ -6094,7 +6129,7 @@ function Qt({ selection: e, sceneRef: n }) {
6094
6129
  ...r,
6095
6130
  text: E.current
6096
6131
  };
6097
- De([{
6132
+ X([{
6098
6133
  kind: "setLabelText",
6099
6134
  areaId: e.areaId,
6100
6135
  id: e.id,
@@ -6112,7 +6147,7 @@ function Qt({ selection: e, sceneRef: n }) {
6112
6147
  ...r,
6113
6148
  size: [i, a]
6114
6149
  };
6115
- De([{
6150
+ X([{
6116
6151
  kind: "setLabelSize",
6117
6152
  areaId: e.areaId,
6118
6153
  id: e.id,
@@ -6129,7 +6164,7 @@ function Qt({ selection: e, sceneRef: n }) {
6129
6164
  fg: s.fgColor,
6130
6165
  bg: s.bgColor
6131
6166
  };
6132
- if (j.current = null, !i || Yt(a.fg, t) && Yt(a.bg, r)) return;
6167
+ if (j.current = null, !i || Jt(a.fg, t) && Jt(a.bg, r)) return;
6133
6168
  let o = i.reader.getLabelSnapshot(e.areaId, e.id);
6134
6169
  if (!o) return;
6135
6170
  let c = {
@@ -6137,7 +6172,7 @@ function Qt({ selection: e, sceneRef: n }) {
6137
6172
  fgColor: t,
6138
6173
  bgColor: r
6139
6174
  };
6140
- De([{
6175
+ X([{
6141
6176
  kind: "setLabelColors",
6142
6177
  areaId: e.areaId,
6143
6178
  id: e.id,
@@ -6177,7 +6212,7 @@ function Qt({ selection: e, sceneRef: n }) {
6177
6212
  ...i.font,
6178
6213
  ...t
6179
6214
  };
6180
- De([{
6215
+ X([{
6181
6216
  kind: "setLabelFont",
6182
6217
  areaId: e.areaId,
6183
6218
  id: e.id,
@@ -6191,14 +6226,14 @@ function Qt({ selection: e, sceneRef: n }) {
6191
6226
  M.current ||= { color: s.outlineColor };
6192
6227
  }, V = (t) => {
6193
6228
  let r = n.current, i = M.current ?? { color: s.outlineColor };
6194
- if (M.current = null, !r || Xt(i.color, t)) return;
6229
+ if (M.current = null, !r || Yt(i.color, t)) return;
6195
6230
  let a = r.reader.getLabelSnapshot(e.areaId, e.id);
6196
6231
  if (!a) return;
6197
6232
  let o = {
6198
6233
  ...a,
6199
6234
  outlineColor: t
6200
6235
  };
6201
- De([{
6236
+ X([{
6202
6237
  kind: "setLabelOutlineColor",
6203
6238
  areaId: e.areaId,
6204
6239
  id: e.id,
@@ -6212,7 +6247,7 @@ function Qt({ selection: e, sceneRef: n }) {
6212
6247
  if (!r || !r.text) return;
6213
6248
  let i = document.createElement("canvas").getContext("2d");
6214
6249
  if (!i) return;
6215
- let a = Math.max(1, Math.round(r.size[0] * Zt)), o = Math.max(1, Math.round(r.size[1] * Zt)), s = a - 16, c = o - 16;
6250
+ let a = Math.max(1, Math.round(r.size[0] * Xt)), o = Math.max(1, Math.round(r.size[1] * Xt)), s = a - 16, c = o - 16;
6216
6251
  if (s <= 0 || c <= 0) return;
6217
6252
  let l = r.text.split("\n"), { font: u } = r, d = Math.floor(c / (l.length * 1.25)), f = 1, p = d, m = 1;
6218
6253
  for (; f <= p;) {
@@ -6230,7 +6265,7 @@ function Qt({ selection: e, sceneRef: n }) {
6230
6265
  if (!t) return;
6231
6266
  let r = t.reader.getLabelSnapshot(e.areaId, e.id);
6232
6267
  if (!r) return;
6233
- let i = Gt(r);
6268
+ let i = Wt(r);
6234
6269
  i !== r.pixMap && (Y({
6235
6270
  kind: "setLabelPixmap",
6236
6271
  areaId: e.areaId,
@@ -6251,8 +6286,8 @@ function Qt({ selection: e, sceneRef: n }) {
6251
6286
  if (!i) return;
6252
6287
  let a = i.reader.getLabelSnapshot(e.areaId, e.id);
6253
6288
  if (!a) return;
6254
- let o = Math.max(.1, Math.round(r.naturalWidth / Zt * 100) / 100), s = Math.max(.1, Math.round(r.naturalHeight / Zt * 100) / 100);
6255
- De([
6289
+ let o = Math.max(.1, Math.round(r.naturalWidth / Xt * 100) / 100), s = Math.max(.1, Math.round(r.naturalHeight / Xt * 100) / 100);
6290
+ X([
6256
6291
  {
6257
6292
  kind: "setLabelImageSrc",
6258
6293
  areaId: e.areaId,
@@ -6283,8 +6318,8 @@ function Qt({ selection: e, sceneRef: n }) {
6283
6318
  if (!t) return;
6284
6319
  let r = t.reader.getLabelSnapshot(e.areaId, e.id);
6285
6320
  if (!r || !r.imageSrc) return;
6286
- let i = Gt(r);
6287
- De([{
6321
+ let i = Wt(r);
6322
+ X([{
6288
6323
  kind: "setLabelImageSrc",
6289
6324
  areaId: e.areaId,
6290
6325
  id: e.id,
@@ -6297,14 +6332,14 @@ function Qt({ selection: e, sceneRef: n }) {
6297
6332
  from: r.pixMap,
6298
6333
  to: i
6299
6334
  }], t), t.refresh(), D.setState({ labelAspectRatioLocked: !1 }), D.bumpData();
6300
- }, H = !!s.imageSrc, U = Le(s.fgColor), W = Le(s.bgColor), G = s.outlineColor ?? {
6335
+ }, H = !!s.imageSrc, U = Ie(s.fgColor), W = Ie(s.bgColor), G = s.outlineColor ?? {
6301
6336
  spec: 1,
6302
6337
  r: 0,
6303
6338
  g: 0,
6304
6339
  b: 0,
6305
6340
  alpha: 0,
6306
6341
  pad: 0
6307
- }, ae = Le(G), oe = (e) => ({
6342
+ }, ae = Ie(G), oe = (e) => ({
6308
6343
  flex: 1,
6309
6344
  padding: "4px 0",
6310
6345
  fontSize: 12,
@@ -6358,7 +6393,7 @@ function Qt({ selection: e, sceneRef: n }) {
6358
6393
  /* @__PURE__ */ f("div", {
6359
6394
  className: "field-row",
6360
6395
  children: [
6361
- /* @__PURE__ */ d(X, {
6396
+ /* @__PURE__ */ d(Z, {
6362
6397
  label: "Width",
6363
6398
  children: /* @__PURE__ */ d("input", {
6364
6399
  type: "number",
@@ -6376,7 +6411,7 @@ function Qt({ selection: e, sceneRef: n }) {
6376
6411
  style: { width: 70 }
6377
6412
  })
6378
6413
  }),
6379
- /* @__PURE__ */ d(X, {
6414
+ /* @__PURE__ */ d(Z, {
6380
6415
  label: "Height",
6381
6416
  children: /* @__PURE__ */ d("input", {
6382
6417
  type: "number",
@@ -6405,17 +6440,17 @@ function Qt({ selection: e, sceneRef: n }) {
6405
6440
  })
6406
6441
  ]
6407
6442
  }),
6408
- /* @__PURE__ */ d(Pe, {
6443
+ /* @__PURE__ */ d(Ne, {
6409
6444
  checked: s.showOnTop,
6410
6445
  onChange: ee,
6411
6446
  description: "Show on top (foreground)"
6412
6447
  }),
6413
- /* @__PURE__ */ d(Pe, {
6448
+ /* @__PURE__ */ d(Ne, {
6414
6449
  checked: !s.noScaling,
6415
6450
  onChange: (e) => R(!e),
6416
6451
  description: "Scale with zoom"
6417
6452
  }),
6418
- H && /* @__PURE__ */ d(X, {
6453
+ H && /* @__PURE__ */ d(Z, {
6419
6454
  label: "Image",
6420
6455
  children: /* @__PURE__ */ f("div", {
6421
6456
  style: {
@@ -6440,7 +6475,7 @@ function Qt({ selection: e, sceneRef: n }) {
6440
6475
  })
6441
6476
  }),
6442
6477
  !H && /* @__PURE__ */ f(u, { children: [
6443
- /* @__PURE__ */ d(X, {
6478
+ /* @__PURE__ */ d(Z, {
6444
6479
  label: "Text",
6445
6480
  children: /* @__PURE__ */ d("textarea", {
6446
6481
  value: c,
@@ -6460,16 +6495,16 @@ function Qt({ selection: e, sceneRef: n }) {
6460
6495
  display: "flex",
6461
6496
  gap: 8
6462
6497
  },
6463
- children: [/* @__PURE__ */ d(X, {
6498
+ children: [/* @__PURE__ */ d(Z, {
6464
6499
  label: "Text color",
6465
6500
  as: "div",
6466
6501
  children: /* @__PURE__ */ d("input", {
6467
6502
  type: "color",
6468
6503
  defaultValue: U,
6469
6504
  onMouseDown: I,
6470
- onBlur: (e) => L(Re(e.target.value), s.bgColor)
6505
+ onBlur: (e) => L(Le(e.target.value), s.bgColor)
6471
6506
  }, `fg-${e.id}-${U}`)
6472
- }), /* @__PURE__ */ d(X, {
6507
+ }), /* @__PURE__ */ d(Z, {
6473
6508
  label: "BG color",
6474
6509
  as: "div",
6475
6510
  children: /* @__PURE__ */ d("input", {
@@ -6477,13 +6512,13 @@ function Qt({ selection: e, sceneRef: n }) {
6477
6512
  defaultValue: W,
6478
6513
  onMouseDown: I,
6479
6514
  onBlur: (e) => L(s.fgColor, {
6480
- ...Re(e.target.value),
6515
+ ...Le(e.target.value),
6481
6516
  alpha: s.bgColor.alpha
6482
6517
  })
6483
6518
  }, `bg-${e.id}-${W}`)
6484
6519
  })]
6485
6520
  }),
6486
- /* @__PURE__ */ d(X, {
6521
+ /* @__PURE__ */ d(Z, {
6487
6522
  label: "BG alpha",
6488
6523
  children: /* @__PURE__ */ f("div", {
6489
6524
  style: {
@@ -6520,16 +6555,16 @@ function Qt({ selection: e, sceneRef: n }) {
6520
6555
  })]
6521
6556
  })
6522
6557
  }),
6523
- /* @__PURE__ */ d(X, {
6558
+ /* @__PURE__ */ d(Z, {
6524
6559
  label: "Font",
6525
6560
  as: "div",
6526
- children: /* @__PURE__ */ d(qt, {
6561
+ children: /* @__PURE__ */ d(Kt, {
6527
6562
  value: s.font.family,
6528
6563
  options: x,
6529
6564
  onChange: (e) => z({ family: e })
6530
6565
  })
6531
6566
  }),
6532
- /* @__PURE__ */ d(X, {
6567
+ /* @__PURE__ */ d(Z, {
6533
6568
  label: "Size",
6534
6569
  children: /* @__PURE__ */ f("div", {
6535
6570
  style: {
@@ -6612,7 +6647,7 @@ function Qt({ selection: e, sceneRef: n }) {
6612
6647
  ]
6613
6648
  })
6614
6649
  }),
6615
- /* @__PURE__ */ d(X, {
6650
+ /* @__PURE__ */ d(Z, {
6616
6651
  label: "Outline color",
6617
6652
  as: "div",
6618
6653
  children: /* @__PURE__ */ d("input", {
@@ -6621,11 +6656,11 @@ function Qt({ selection: e, sceneRef: n }) {
6621
6656
  onMouseDown: B,
6622
6657
  onBlur: (e) => V({
6623
6658
  ...G,
6624
- ...Re(e.target.value)
6659
+ ...Le(e.target.value)
6625
6660
  })
6626
6661
  }, `outline-${e.id}-${ae}`)
6627
6662
  }),
6628
- /* @__PURE__ */ d(X, {
6663
+ /* @__PURE__ */ d(Z, {
6629
6664
  label: "Outline alpha",
6630
6665
  children: /* @__PURE__ */ f("div", {
6631
6666
  style: {
@@ -6668,7 +6703,7 @@ function Qt({ selection: e, sceneRef: n }) {
6668
6703
  })]
6669
6704
  })
6670
6705
  }),
6671
- /* @__PURE__ */ d(X, {
6706
+ /* @__PURE__ */ d(Z, {
6672
6707
  label: "Pixmap",
6673
6708
  children: /* @__PURE__ */ f("div", {
6674
6709
  style: {
@@ -6701,7 +6736,7 @@ function Qt({ selection: e, sceneRef: n }) {
6701
6736
  }
6702
6737
  //#endregion
6703
6738
  //#region src/components/EnvPicker.tsx
6704
- function $t({ map: e, sceneRef: n, currentEnvId: a, onSelect: o, onClose: s }) {
6739
+ function Qt({ map: e, sceneRef: n, currentEnvId: a, onSelect: o, onClose: s }) {
6705
6740
  let c = r(null), [l, u] = i("");
6706
6741
  t(() => {
6707
6742
  let e = (e) => {
@@ -6776,7 +6811,7 @@ function $t({ map: e, sceneRef: n, currentEnvId: a, onSelect: o, onClose: s }) {
6776
6811
  }
6777
6812
  //#endregion
6778
6813
  //#region src/components/icons.tsx
6779
- function en() {
6814
+ function $t() {
6780
6815
  return /* @__PURE__ */ f("svg", {
6781
6816
  width: "10",
6782
6817
  height: "12",
@@ -6799,7 +6834,7 @@ function en() {
6799
6834
  })]
6800
6835
  });
6801
6836
  }
6802
- function tn({ locked: e }) {
6837
+ function en({ locked: e }) {
6803
6838
  return /* @__PURE__ */ f("svg", {
6804
6839
  width: "10",
6805
6840
  height: "12",
@@ -6836,7 +6871,7 @@ function tn({ locked: e }) {
6836
6871
  ]
6837
6872
  });
6838
6873
  }
6839
- function nn() {
6874
+ function tn() {
6840
6875
  return /* @__PURE__ */ f("svg", {
6841
6876
  width: "12",
6842
6877
  height: "8",
@@ -6869,7 +6904,7 @@ function nn() {
6869
6904
  ]
6870
6905
  });
6871
6906
  }
6872
- function rn() {
6907
+ function nn() {
6873
6908
  return /* @__PURE__ */ f("svg", {
6874
6909
  width: "11",
6875
6910
  height: "11",
@@ -6890,7 +6925,7 @@ function rn() {
6890
6925
  })]
6891
6926
  });
6892
6927
  }
6893
- function an() {
6928
+ function rn() {
6894
6929
  return /* @__PURE__ */ f("svg", {
6895
6930
  width: "10",
6896
6931
  height: "10",
@@ -6946,7 +6981,7 @@ function an() {
6946
6981
  }
6947
6982
  //#endregion
6948
6983
  //#region src/components/RoomPanel.tsx
6949
- var on = [
6984
+ var an = [
6950
6985
  "north",
6951
6986
  "northeast",
6952
6987
  "east",
@@ -6959,7 +6994,7 @@ var on = [
6959
6994
  "down",
6960
6995
  "in",
6961
6996
  "out"
6962
- ], sn = [
6997
+ ], on = [
6963
6998
  [
6964
6999
  "northwest",
6965
7000
  "north",
@@ -6975,7 +7010,7 @@ var on = [
6975
7010
  "south",
6976
7011
  "southeast"
6977
7012
  ]
6978
- ], cn = [[
7013
+ ], sn = [[
6979
7014
  "up",
6980
7015
  null,
6981
7016
  "down"
@@ -6983,7 +7018,7 @@ var on = [
6983
7018
  "in",
6984
7019
  null,
6985
7020
  "out"
6986
- ]], ln = {
7021
+ ]], cn = {
6987
7022
  north: "N",
6988
7023
  northeast: "NE",
6989
7024
  east: "E",
@@ -6996,20 +7031,20 @@ var on = [
6996
7031
  down: "Dn",
6997
7032
  in: "In",
6998
7033
  out: "Out"
6999
- }, un = [
7034
+ }, ln = [
7000
7035
  "No door (click to set)",
7001
7036
  "Open door",
7002
7037
  "Closed door",
7003
7038
  "Locked door"
7004
- ], dn = [
7039
+ ], un = [
7005
7040
  "",
7006
7041
  "door-open",
7007
7042
  "door-closed",
7008
7043
  "door-locked"
7009
7044
  ];
7010
- function fn({ selection: n, room: a, map: o, sceneRef: s, pluginSections: c = [] }) {
7045
+ function dn({ selection: n, room: a, map: o, sceneRef: s, pluginSections: c = [] }) {
7011
7046
  let l = n.ids[0], p = O((e) => e.pending), [m, h] = i(a.name ?? ""), [g, _] = i(String(a.weight ?? 1)), [v, y] = i(a.symbol ?? ""), [b, x] = i(a.userData?.["system.fallback_symbol_color"] ?? null), [S, C] = i(!1), [w, T] = i(""), [E, k] = i(""), [A, j] = i({}), [M, N] = i(null), [P, F] = i("#ffffff"), [I, L] = i(1), [R, ee] = i(!1), [z, B] = i(!1), V = r(k);
7012
- V.current = k, t(() => (pt((e) => V.current(String(e))), () => pt(null)), []);
7047
+ V.current = k, t(() => (ft((e) => V.current(String(e))), () => ft(null)), []);
7013
7048
  let te = r(m);
7014
7049
  te.current = m;
7015
7050
  let ne = r(g);
@@ -7137,7 +7172,7 @@ function fn({ selection: n, room: a, map: o, sceneRef: s, pluginSections: c = []
7137
7172
  roomId: l,
7138
7173
  dir: e,
7139
7174
  stub: !0
7140
- }, s.current) : De([{
7175
+ }, s.current) : X([{
7141
7176
  kind: "removeExit",
7142
7177
  fromId: l,
7143
7178
  dir: e,
@@ -7218,7 +7253,7 @@ function fn({ selection: n, room: a, map: o, sceneRef: s, pluginSections: c = []
7218
7253
  },
7219
7254
  style: a.customLinesStyle?.[i] ?? 1,
7220
7255
  arrow: a.customLinesArrow?.[i] ?? !1
7221
- } : null, u = Re(P), d = null, f = _e[i];
7256
+ } : null, u = Le(P), d = null, f = _e[i];
7222
7257
  if (z && f) {
7223
7258
  let e = a?.[f];
7224
7259
  if (e !== void 0 && e !== -1) {
@@ -7373,7 +7408,7 @@ function fn({ selection: n, room: a, map: o, sceneRef: s, pluginSections: c = []
7373
7408
  className: "cc-header",
7374
7409
  children: [/* @__PURE__ */ d("span", {
7375
7410
  className: "cc-label",
7376
- children: ln[e]
7411
+ children: cn[e]
7377
7412
  }), /* @__PURE__ */ f("span", {
7378
7413
  className: "cc-header-btn-slot",
7379
7414
  children: [
@@ -7413,7 +7448,7 @@ function fn({ selection: n, room: a, map: o, sceneRef: s, pluginSections: c = []
7413
7448
  /* @__PURE__ */ f("div", {
7414
7449
  className: "cc-middle",
7415
7450
  children: [
7416
- r && /* @__PURE__ */ d(Ne, {
7451
+ r && /* @__PURE__ */ d(Me, {
7417
7452
  id: n,
7418
7453
  className: "cc-target"
7419
7454
  }),
@@ -7451,7 +7486,7 @@ function fn({ selection: n, room: a, map: o, sceneRef: s, pluginSections: c = []
7451
7486
  fromId: l,
7452
7487
  dir: t
7453
7488
  } }),
7454
- children: /* @__PURE__ */ d(an, {})
7489
+ children: /* @__PURE__ */ d(rn, {})
7455
7490
  })]
7456
7491
  })
7457
7492
  ]
@@ -7461,11 +7496,11 @@ function fn({ selection: n, room: a, map: o, sceneRef: s, pluginSections: c = []
7461
7496
  children: [
7462
7497
  /* @__PURE__ */ d("button", {
7463
7498
  type: "button",
7464
- className: `cc-door-btn ${dn[u]}${c ? "" : " cc-dim"}`,
7465
- title: c ? un[u] : void 0,
7499
+ className: `cc-door-btn ${un[u]}${c ? "" : " cc-dim"}`,
7500
+ title: c ? ln[u] : void 0,
7466
7501
  disabled: !c,
7467
7502
  onClick: c ? () => G(t, u, (u + 1) % 4) : void 0,
7468
- children: /* @__PURE__ */ d(en, {})
7503
+ children: /* @__PURE__ */ d($t, {})
7469
7504
  }),
7470
7505
  /* @__PURE__ */ d("button", {
7471
7506
  type: "button",
@@ -7473,11 +7508,11 @@ function fn({ selection: n, room: a, map: o, sceneRef: s, pluginSections: c = []
7473
7508
  title: c ? h ? "Locked — click to unlock" : "Unlocked — click to lock" : void 0,
7474
7509
  disabled: !c,
7475
7510
  onClick: c ? () => oe(t, h) : void 0,
7476
- children: /* @__PURE__ */ d(tn, { locked: h })
7511
+ children: /* @__PURE__ */ d(en, { locked: h })
7477
7512
  }),
7478
7513
  /* @__PURE__ */ f("span", {
7479
7514
  className: `cc-weight-wrap${c ? "" : " cc-dim"}`,
7480
- children: [/* @__PURE__ */ d(nn, {}), /* @__PURE__ */ d("input", {
7515
+ children: [/* @__PURE__ */ d(tn, {}), /* @__PURE__ */ d("input", {
7481
7516
  type: "number",
7482
7517
  className: "cc-weight",
7483
7518
  min: 1,
@@ -7519,11 +7554,11 @@ function fn({ selection: n, room: a, map: o, sceneRef: s, pluginSections: c = []
7519
7554
  let e = s.current;
7520
7555
  e && (e.renderer.backend.viewport.panToMapPoint(a.x, -a.y), e.refresh());
7521
7556
  },
7522
- children: /* @__PURE__ */ d(rn, {})
7557
+ children: /* @__PURE__ */ d(nn, {})
7523
7558
  })]
7524
7559
  })]
7525
7560
  }),
7526
- /* @__PURE__ */ d(X, {
7561
+ /* @__PURE__ */ d(Z, {
7527
7562
  label: "Name",
7528
7563
  children: /* @__PURE__ */ d("input", {
7529
7564
  value: m,
@@ -7555,7 +7590,7 @@ function fn({ selection: n, room: a, map: o, sceneRef: s, pluginSections: c = []
7555
7590
  className: "env-id-label",
7556
7591
  children: ["#", a.environment]
7557
7592
  }),
7558
- S && /* @__PURE__ */ d($t, {
7593
+ S && /* @__PURE__ */ d(Qt, {
7559
7594
  map: o,
7560
7595
  sceneRef: s,
7561
7596
  currentEnvId: a.environment,
@@ -7564,7 +7599,7 @@ function fn({ selection: n, room: a, map: o, sceneRef: s, pluginSections: c = []
7564
7599
  })
7565
7600
  ]
7566
7601
  })]
7567
- }), /* @__PURE__ */ d(X, {
7602
+ }), /* @__PURE__ */ d(Z, {
7568
7603
  label: "Symbol",
7569
7604
  children: /* @__PURE__ */ f("div", {
7570
7605
  className: "symbol-row",
@@ -7602,7 +7637,7 @@ function fn({ selection: n, room: a, map: o, sceneRef: s, pluginSections: c = []
7602
7637
  /* @__PURE__ */ d("h4", { children: "Exits" }),
7603
7638
  /* @__PURE__ */ d("div", {
7604
7639
  className: "compass-rose",
7605
- children: sn.flat().map((e, t) => e === null ? /* @__PURE__ */ f("div", {
7640
+ children: on.flat().map((e, t) => e === null ? /* @__PURE__ */ f("div", {
7606
7641
  className: "compass-cell compass-center",
7607
7642
  children: [/* @__PURE__ */ d("button", {
7608
7643
  type: "button",
@@ -7615,7 +7650,7 @@ function fn({ selection: n, room: a, map: o, sceneRef: s, pluginSections: c = []
7615
7650
  lock: !a.isLocked
7616
7651
  }, s.current), s.current?.refresh(), D.bumpData();
7617
7652
  },
7618
- children: /* @__PURE__ */ d(tn, { locked: a.isLocked })
7653
+ children: /* @__PURE__ */ d(en, { locked: a.isLocked })
7619
7654
  }), /* @__PURE__ */ d("input", {
7620
7655
  type: "number",
7621
7656
  className: "cc-room-weight",
@@ -7630,9 +7665,9 @@ function fn({ selection: n, room: a, map: o, sceneRef: s, pluginSections: c = []
7630
7665
  }),
7631
7666
  /* @__PURE__ */ d("div", {
7632
7667
  className: "compass-extra",
7633
- children: cn.flat().map((e, t) => e === null ? /* @__PURE__ */ d("div", { className: "compass-vert-spacer" }, t) : xe(e))
7668
+ children: sn.flat().map((e, t) => e === null ? /* @__PURE__ */ d("div", { className: "compass-vert-spacer" }, t) : xe(e))
7634
7669
  }),
7635
- M !== null && on.includes(M) && be(M),
7670
+ M !== null && an.includes(M) && be(M),
7636
7671
  /* @__PURE__ */ d("h4", { children: "Special Exits" }),
7637
7672
  /* @__PURE__ */ f("div", {
7638
7673
  className: "special-exits-list",
@@ -7669,7 +7704,7 @@ function fn({ selection: n, room: a, map: o, sceneRef: s, pluginSections: c = []
7669
7704
  }),
7670
7705
  /* @__PURE__ */ d("div", {
7671
7706
  className: "cc-middle",
7672
- children: /* @__PURE__ */ d(Ne, {
7707
+ children: /* @__PURE__ */ d(Me, {
7673
7708
  id: n,
7674
7709
  className: "cc-target"
7675
7710
  })
@@ -7679,14 +7714,14 @@ function fn({ selection: n, room: a, map: o, sceneRef: s, pluginSections: c = []
7679
7714
  children: [
7680
7715
  /* @__PURE__ */ d("button", {
7681
7716
  type: "button",
7682
- className: `cc-door-btn ${dn[r]}`,
7683
- title: un[r],
7717
+ className: `cc-door-btn ${un[r]}`,
7718
+ title: ln[r],
7684
7719
  onClick: () => de(t, r, (r + 1) % 4),
7685
- children: /* @__PURE__ */ d(en, {})
7720
+ children: /* @__PURE__ */ d($t, {})
7686
7721
  }),
7687
7722
  /* @__PURE__ */ f("span", {
7688
7723
  className: "cc-weight-wrap",
7689
- children: [/* @__PURE__ */ d(nn, {}), /* @__PURE__ */ d("input", {
7724
+ children: [/* @__PURE__ */ d(tn, {}), /* @__PURE__ */ d("input", {
7690
7725
  type: "number",
7691
7726
  className: "cc-weight",
7692
7727
  min: 1,
@@ -7736,7 +7771,7 @@ function fn({ selection: n, room: a, map: o, sceneRef: s, pluginSections: c = []
7736
7771
  fromId: l
7737
7772
  } });
7738
7773
  },
7739
- children: /* @__PURE__ */ d(an, {})
7774
+ children: /* @__PURE__ */ d(rn, {})
7740
7775
  })]
7741
7776
  }),
7742
7777
  /* @__PURE__ */ d("button", {
@@ -7793,7 +7828,7 @@ function fn({ selection: n, room: a, map: o, sceneRef: s, pluginSections: c = []
7793
7828
  sceneRef: s
7794
7829
  }) }, t.id)),
7795
7830
  /* @__PURE__ */ d("h4", { children: "User Data" }),
7796
- /* @__PURE__ */ d(Ie, {
7831
+ /* @__PURE__ */ d(Fe, {
7797
7832
  data: a.userData,
7798
7833
  onCommit: (e, t, n) => {
7799
7834
  Y({
@@ -7810,7 +7845,7 @@ function fn({ selection: n, room: a, map: o, sceneRef: s, pluginSections: c = []
7810
7845
  }
7811
7846
  //#endregion
7812
7847
  //#region src/components/SidePanel.tsx
7813
- var pn = [
7848
+ var fn = [
7814
7849
  {
7815
7850
  id: "selection",
7816
7851
  label: "Sel"
@@ -7832,11 +7867,11 @@ var pn = [
7832
7867
  label: "Map"
7833
7868
  }
7834
7869
  ];
7835
- function mn({ sceneRef: e, extraTabs: t = [], pluginRoomSections: n = [] }) {
7870
+ function pn({ sceneRef: e, extraTabs: t = [], pluginRoomSections: n = [] }) {
7836
7871
  let r = O((e) => e.selection), i = O((e) => e.map), a = O((e) => e.activeTool), o = O((e) => e.pending), s = O((e) => e.sidebarTab), c = O((e) => e.panelCollapsed), l = O((e) => e.undo.length);
7837
7872
  O((e) => e.dataVersion);
7838
7873
  let u = i ? Object.keys(i.mCustomEnvColors).length : 0, p = i ? Object.keys(i.areaNames).length : 0;
7839
- if (a === "customLine" && o?.kind === "customLine") return /* @__PURE__ */ d(Vt, {
7874
+ if (a === "customLine" && o?.kind === "customLine") return /* @__PURE__ */ d(Bt, {
7840
7875
  pending: o,
7841
7876
  sceneRef: e
7842
7877
  });
@@ -7850,7 +7885,7 @@ function mn({ sceneRef: e, extraTabs: t = [], pluginRoomSections: n = [] }) {
7850
7885
  children: "◀"
7851
7886
  }), /* @__PURE__ */ d("div", {
7852
7887
  className: "side-panel-tabs side-panel-tabs--vert",
7853
- children: [...pn, ...t].map((e) => /* @__PURE__ */ d("button", {
7888
+ children: [...fn, ...t].map((e) => /* @__PURE__ */ d("button", {
7854
7889
  type: "button",
7855
7890
  className: `side-panel-tab${s === e.id ? " active" : ""}`,
7856
7891
  onClick: () => D.setState({
@@ -7920,19 +7955,19 @@ function mn({ sceneRef: e, extraTabs: t = [], pluginRoomSections: n = [] }) {
7920
7955
  });
7921
7956
  if (s === "areas") return /* @__PURE__ */ f("div", {
7922
7957
  className: "side-panel",
7923
- children: [m, /* @__PURE__ */ d(ze, { sceneRef: e })]
7958
+ children: [m, /* @__PURE__ */ d(Re, { sceneRef: e })]
7924
7959
  });
7925
7960
  if (s === "envs") return /* @__PURE__ */ f("div", {
7926
7961
  className: "side-panel",
7927
- children: [m, /* @__PURE__ */ d(He, { sceneRef: e })]
7962
+ children: [m, /* @__PURE__ */ d(Ve, { sceneRef: e })]
7928
7963
  });
7929
7964
  if (s === "history") return /* @__PURE__ */ f("div", {
7930
7965
  className: "side-panel",
7931
- children: [m, /* @__PURE__ */ d(Ge, { sceneRef: e })]
7966
+ children: [m, /* @__PURE__ */ d(We, { sceneRef: e })]
7932
7967
  });
7933
7968
  if (s === "map") return /* @__PURE__ */ f("div", {
7934
7969
  className: "side-panel",
7935
- children: [m, /* @__PURE__ */ d(Ye, { sceneRef: e })]
7970
+ children: [m, /* @__PURE__ */ d(Je, { sceneRef: e })]
7936
7971
  });
7937
7972
  let h = t.find((e) => e.id === s);
7938
7973
  if (h) return /* @__PURE__ */ f("div", {
@@ -7944,7 +7979,7 @@ function mn({ sceneRef: e, extraTabs: t = [], pluginRoomSections: n = [] }) {
7944
7979
  });
7945
7980
  if (r?.kind === "label") return /* @__PURE__ */ f("div", {
7946
7981
  className: "side-panel",
7947
- children: [m, /* @__PURE__ */ d(Qt, {
7982
+ children: [m, /* @__PURE__ */ d(Zt, {
7948
7983
  selection: r,
7949
7984
  sceneRef: e
7950
7985
  })]
@@ -7953,7 +7988,7 @@ function mn({ sceneRef: e, extraTabs: t = [], pluginRoomSections: n = [] }) {
7953
7988
  className: "side-panel",
7954
7989
  children: [m, /* @__PURE__ */ d("div", {
7955
7990
  className: "panel-content",
7956
- children: /* @__PURE__ */ d(Xe, {
7991
+ children: /* @__PURE__ */ d(Ye, {
7957
7992
  selection: r,
7958
7993
  map: i,
7959
7994
  sceneRef: e
@@ -7964,7 +7999,7 @@ function mn({ sceneRef: e, extraTabs: t = [], pluginRoomSections: n = [] }) {
7964
7999
  className: "side-panel",
7965
8000
  children: [m, /* @__PURE__ */ d("div", {
7966
8001
  className: "panel-content",
7967
- children: /* @__PURE__ */ d(Ht, {
8002
+ children: /* @__PURE__ */ d(Vt, {
7968
8003
  selection: r,
7969
8004
  map: i,
7970
8005
  sceneRef: e
@@ -7977,7 +8012,7 @@ function mn({ sceneRef: e, extraTabs: t = [], pluginRoomSections: n = [] }) {
7977
8012
  className: "panel-content",
7978
8013
  children: [/* @__PURE__ */ f("h3", { children: [r.ids.length, " rooms selected"] }), /* @__PURE__ */ d("p", {
7979
8014
  className: "hint",
7980
- children: "Drag to move all. Delete to remove all. Ctrl+click to toggle rooms. Ctrl+A selects all."
8015
+ children: "Drag to move all. Delete to remove all. Shift+click/drag to add more. Ctrl+click/drag to toggle. Ctrl+A selects all."
7981
8016
  })]
7982
8017
  })]
7983
8018
  });
@@ -7992,12 +8027,12 @@ function mn({ sceneRef: e, extraTabs: t = [], pluginRoomSections: n = [] }) {
7992
8027
  className: "hint",
7993
8028
  children: "Select a room with the Select tool to edit its properties."
7994
8029
  }),
7995
- /* @__PURE__ */ d(Fe, { activeTool: a })
8030
+ /* @__PURE__ */ d(Pe, { activeTool: a })
7996
8031
  ]
7997
8032
  })]
7998
8033
  }) : /* @__PURE__ */ f("div", {
7999
8034
  className: "side-panel",
8000
- children: [m, /* @__PURE__ */ d(fn, {
8035
+ children: [m, /* @__PURE__ */ d(dn, {
8001
8036
  selection: r,
8002
8037
  room: g,
8003
8038
  map: i,
@@ -8008,7 +8043,7 @@ function mn({ sceneRef: e, extraTabs: t = [], pluginRoomSections: n = [] }) {
8008
8043
  }
8009
8044
  //#endregion
8010
8045
  //#region src/components/ContextMenu.tsx
8011
- function hn({ sceneRef: e }) {
8046
+ function mn({ sceneRef: e }) {
8012
8047
  let n = O((e) => e.contextMenu), a = r(null), [o, s] = i(null), [c, l] = i(null);
8013
8048
  if (t(() => {
8014
8049
  if (!n) {
@@ -8024,12 +8059,12 @@ function hn({ sceneRef: e }) {
8024
8059
  window.removeEventListener("keydown", t), window.removeEventListener("mousedown", r, !0);
8025
8060
  };
8026
8061
  }, [n]), !n) return null;
8027
- let u = () => D.setState({ contextMenu: null }), p = () => {
8062
+ let p = () => D.setState({ contextMenu: null }), m = () => {
8028
8063
  if (n.kind !== "customLinePoint") return;
8029
8064
  let t = D.getState();
8030
- if (!t.map) return u();
8065
+ if (!t.map) return p();
8031
8066
  let r = t.map.rooms[n.roomId], i = r?.customLines?.[n.exitName];
8032
- if (!r || !i || n.pointIndex < 0 || n.pointIndex >= i.length) return u();
8067
+ if (!r || !i || n.pointIndex < 0 || n.pointIndex >= i.length) return p();
8033
8068
  let a = r.customLinesColor?.[n.exitName] ?? {
8034
8069
  spec: 1,
8035
8070
  alpha: 255,
@@ -8066,7 +8101,7 @@ function hn({ sceneRef: e }) {
8066
8101
  if (n.kind === "disambiguate") {
8067
8102
  let t = D.getState(), r = (e) => {
8068
8103
  e.kind === "room" ? D.setState({
8069
- selection: Lt(e),
8104
+ selection: It(e),
8070
8105
  contextMenu: {
8071
8106
  kind: "room",
8072
8107
  roomId: e.id,
@@ -8075,7 +8110,7 @@ function hn({ sceneRef: e }) {
8075
8110
  },
8076
8111
  sidebarTab: "selection"
8077
8112
  }) : e.kind === "label" ? D.setState({
8078
- selection: Lt(e),
8113
+ selection: It(e),
8079
8114
  contextMenu: {
8080
8115
  kind: "label",
8081
8116
  areaId: e.areaId,
@@ -8085,21 +8120,21 @@ function hn({ sceneRef: e }) {
8085
8120
  },
8086
8121
  sidebarTab: "selection"
8087
8122
  }) : D.setState({
8088
- selection: Lt(e),
8123
+ selection: It(e),
8089
8124
  contextMenu: null,
8090
8125
  sidebarTab: "selection",
8091
- status: `Selected ${Rt(e)}`
8126
+ status: `Selected ${Lt(e)}`
8092
8127
  });
8093
8128
  }, i = (n) => {
8094
8129
  if (n.kind === "room") {
8095
8130
  let e = t.map?.rooms[n.id]?.name;
8096
- return e ? `Room ${n.id}: ${e}` : `Room ${n.id}`;
8131
+ return e && String(n.id) !== e ? `Room ${n.id}: ${e}` : `Room ${n.id}`;
8097
8132
  }
8098
8133
  if (n.kind === "label") {
8099
8134
  let t = (e.current?.reader.getLabelSnapshot(n.areaId, n.id))?.text?.trim();
8100
8135
  return t ? `Label: "${t.length > 24 ? t.slice(0, 24) + "…" : t}"` : `Label ${n.id}`;
8101
8136
  }
8102
- return Rt(n);
8137
+ return Lt(n);
8103
8138
  };
8104
8139
  return /* @__PURE__ */ f("div", {
8105
8140
  ref: a,
@@ -8131,7 +8166,7 @@ function hn({ sceneRef: e }) {
8131
8166
  children: /* @__PURE__ */ d("button", {
8132
8167
  type: "button",
8133
8168
  className: "context-menu-item danger",
8134
- onClick: p,
8169
+ onClick: m,
8135
8170
  children: "Delete waypoint"
8136
8171
  })
8137
8172
  });
@@ -8254,7 +8289,7 @@ function hn({ sceneRef: e }) {
8254
8289
  type: "button",
8255
8290
  className: "context-menu-item danger",
8256
8291
  onClick: () => {
8257
- if (!t) return u();
8292
+ if (!t) return p();
8258
8293
  Y({
8259
8294
  kind: "deleteLabel",
8260
8295
  areaId: n.areaId,
@@ -8272,19 +8307,19 @@ function hn({ sceneRef: e }) {
8272
8307
  });
8273
8308
  }
8274
8309
  if (n.kind !== "room") return null;
8275
- let m = D.getState(), h = m.map?.rooms[n.roomId], g = m.map?.areaNames ?? {}, _ = m.selection, v = _?.kind === "room" && _.ids.length > 1 && _.ids.includes(n.roomId) ? _.ids : null, y = () => {
8276
- h && s({
8277
- areaId: h.area,
8278
- x: String(h.x),
8279
- y: String(h.y),
8280
- z: String(h.z)
8310
+ let h = D.getState(), g = h.map?.rooms[n.roomId], _ = h.map?.areaNames ?? {}, v = h.selection, y = v?.kind === "room" && v.ids.length > 1 && v.ids.includes(n.roomId) ? v.ids : null, b = () => {
8311
+ g && s({
8312
+ areaId: g.area,
8313
+ x: String(g.x),
8314
+ y: String(g.y),
8315
+ z: String(g.z)
8281
8316
  });
8282
- }, b = () => {
8317
+ }, x = () => {
8283
8318
  let t = D.getState();
8284
- if (!t.map) return u();
8319
+ if (!t.map) return p();
8285
8320
  let r = t.map.rooms[n.roomId];
8286
- if (!r) return u();
8287
- let i = { ...r }, a = je(t.map, n.roomId);
8321
+ if (!r) return p();
8322
+ let i = { ...r }, a = Ae(t.map, n.roomId);
8288
8323
  Y({
8289
8324
  kind: "deleteRoom",
8290
8325
  id: n.roomId,
@@ -8297,21 +8332,21 @@ function hn({ sceneRef: e }) {
8297
8332
  status: `Deleted room ${n.roomId}`,
8298
8333
  contextMenu: null
8299
8334
  });
8300
- }, x = () => {
8301
- if (!o || !h || !m.map) return;
8335
+ }, S = () => {
8336
+ if (!o || !g || !h.map) return;
8302
8337
  let t = parseInt(o.x, 10), r = parseInt(o.y, 10), i = parseInt(o.z, 10);
8303
8338
  if (isNaN(t) || isNaN(r) || isNaN(i)) return;
8304
8339
  let a = [];
8305
- if (v) {
8306
- let e = t - h.x, n = r - h.y, s = i - h.z;
8307
- o.areaId !== h.area && a.push({
8340
+ if (y) {
8341
+ let e = t - g.x, n = r - g.y, s = i - g.z;
8342
+ o.areaId !== g.area && a.push({
8308
8343
  kind: "moveRoomsToArea",
8309
- roomIds: v,
8310
- fromAreaId: h.area,
8344
+ roomIds: y,
8345
+ fromAreaId: g.area,
8311
8346
  toAreaId: o.areaId
8312
8347
  });
8313
- for (let t of v) {
8314
- let r = m.map.rooms[t];
8348
+ for (let t of y) {
8349
+ let r = h.map.rooms[t];
8315
8350
  if (!r) continue;
8316
8351
  let i = r.x + e, o = r.y + n, c = r.z + s;
8317
8352
  (i !== r.x || o !== r.y || c !== r.z) && a.push({
@@ -8327,33 +8362,33 @@ function hn({ sceneRef: e }) {
8327
8362
  y: o,
8328
8363
  z: c
8329
8364
  }
8330
- }), a.push(...Ae(m.map, t, e, n));
8365
+ }), a.push(...ke(h.map, t, e, n));
8331
8366
  }
8332
8367
  } else {
8333
- o.areaId !== h.area && a.push({
8368
+ o.areaId !== g.area && a.push({
8334
8369
  kind: "moveRoomsToArea",
8335
8370
  roomIds: [n.roomId],
8336
- fromAreaId: h.area,
8371
+ fromAreaId: g.area,
8337
8372
  toAreaId: o.areaId
8338
8373
  });
8339
- let e = t - h.x, s = r - h.y;
8340
- (t !== h.x || r !== h.y || i !== h.z) && a.push({
8374
+ let e = t - g.x, s = r - g.y;
8375
+ (t !== g.x || r !== g.y || i !== g.z) && a.push({
8341
8376
  kind: "moveRoom",
8342
8377
  id: n.roomId,
8343
8378
  from: {
8344
- x: h.x,
8345
- y: h.y,
8346
- z: h.z
8379
+ x: g.x,
8380
+ y: g.y,
8381
+ z: g.z
8347
8382
  },
8348
8383
  to: {
8349
8384
  x: t,
8350
8385
  y: r,
8351
8386
  z: i
8352
8387
  }
8353
- }), a.push(...Ae(m.map, n.roomId, e, s));
8388
+ }), a.push(...ke(h.map, n.roomId, e, s));
8354
8389
  }
8355
- a.length > 0 && (De(a, e.current), e.current?.refresh(), D.bumpStructure(), D.setState({ status: v ? `Moved ${v.length} rooms to area ${o.areaId} (${t}, ${r}, ${i})` : `Moved room ${n.roomId} to area ${o.areaId} (${t}, ${r}, ${i})` }));
8356
- let s = o.areaId !== (m.currentAreaId ?? h.area), c = i !== m.currentZ;
8390
+ a.length > 0 && (X(a, e.current), e.current?.refresh(), D.bumpStructure(), D.setState({ status: y ? `Moved ${y.length} rooms to area ${o.areaId} (${t}, ${r}, ${i})` : `Moved room ${n.roomId} to area ${o.areaId} (${t}, ${r}, ${i})` }));
8391
+ let s = o.areaId !== (h.currentAreaId ?? g.area), c = i !== h.currentZ;
8357
8392
  D.setState({
8358
8393
  contextMenu: null,
8359
8394
  currentAreaId: o.areaId,
@@ -8363,7 +8398,7 @@ function hn({ sceneRef: e }) {
8363
8398
  mapY: -r
8364
8399
  } : null
8365
8400
  });
8366
- }, S = Object.entries(g).map(([e, t]) => ({
8401
+ }, C = Object.entries(_).map(([e, t]) => ({
8367
8402
  id: Number(e),
8368
8403
  name: t
8369
8404
  })).sort((e, t) => e.name.localeCompare(t.name));
@@ -8378,7 +8413,7 @@ function hn({ sceneRef: e }) {
8378
8413
  children: [
8379
8414
  /* @__PURE__ */ d("div", {
8380
8415
  className: "context-menu-title",
8381
- children: v ? `Move ${v.length} rooms to` : `Move room ${n.roomId} to`
8416
+ children: y ? `Move ${y.length} rooms to` : `Move room ${n.roomId} to`
8382
8417
  }),
8383
8418
  /* @__PURE__ */ f("div", {
8384
8419
  className: "context-menu-field",
@@ -8388,7 +8423,7 @@ function hn({ sceneRef: e }) {
8388
8423
  ...t,
8389
8424
  areaId: Number(e.target.value)
8390
8425
  }),
8391
- children: S.map(({ id: e, name: t }) => /* @__PURE__ */ d("option", {
8426
+ children: C.map(({ id: e, name: t }) => /* @__PURE__ */ d("option", {
8392
8427
  value: e,
8393
8428
  children: t
8394
8429
  }, e))
@@ -8442,7 +8477,7 @@ function hn({ sceneRef: e }) {
8442
8477
  }), /* @__PURE__ */ d("button", {
8443
8478
  type: "button",
8444
8479
  className: "context-menu-btn primary",
8445
- onClick: x,
8480
+ onClick: S,
8446
8481
  children: "Move"
8447
8482
  })]
8448
8483
  })
@@ -8456,34 +8491,61 @@ function hn({ sceneRef: e }) {
8456
8491
  },
8457
8492
  onContextMenu: (e) => e.preventDefault(),
8458
8493
  children: [
8459
- /* @__PURE__ */ f("div", {
8494
+ /* @__PURE__ */ d("div", {
8460
8495
  className: "context-menu-title",
8461
- children: ["Room ", n.roomId]
8496
+ children: y ? `${y.length} rooms` : `Room ${n.roomId}`
8462
8497
  }),
8463
8498
  /* @__PURE__ */ d("button", {
8464
8499
  type: "button",
8465
8500
  className: "context-menu-item",
8466
- onClick: y,
8501
+ onClick: b,
8467
8502
  children: "Move to…"
8468
8503
  }),
8504
+ y && /* @__PURE__ */ f(u, { children: [/* @__PURE__ */ d("button", {
8505
+ type: "button",
8506
+ className: "context-menu-item",
8507
+ onClick: () => D.setState({
8508
+ spreadShrink: {
8509
+ mode: "spread",
8510
+ factor: 2,
8511
+ centerMode: "centroid",
8512
+ anchorRoomId: null
8513
+ },
8514
+ contextMenu: null
8515
+ }),
8516
+ children: "Spread…"
8517
+ }), /* @__PURE__ */ d("button", {
8518
+ type: "button",
8519
+ className: "context-menu-item",
8520
+ onClick: () => D.setState({
8521
+ spreadShrink: {
8522
+ mode: "shrink",
8523
+ factor: .5,
8524
+ centerMode: "centroid",
8525
+ anchorRoomId: null
8526
+ },
8527
+ contextMenu: null
8528
+ }),
8529
+ children: "Shrink…"
8530
+ })] }),
8469
8531
  /* @__PURE__ */ d("button", {
8470
8532
  type: "button",
8471
8533
  className: "context-menu-item danger",
8472
- onClick: b,
8473
- children: "Delete room"
8534
+ onClick: x,
8535
+ children: y ? `Delete ${y.length} rooms` : "Delete room"
8474
8536
  })
8475
8537
  ]
8476
8538
  });
8477
8539
  }
8478
8540
  //#endregion
8479
8541
  //#region src/editor/session.ts
8480
- var gn = "mudlet-map-editor", $ = "sessions", _n = 2;
8542
+ var hn = "mudlet-map-editor", gn = "sessions", _n = 2;
8481
8543
  function vn() {
8482
8544
  return new Promise((e, t) => {
8483
- let n = indexedDB.open(gn, _n);
8545
+ let n = indexedDB.open(hn, _n);
8484
8546
  n.onupgradeneeded = (e) => {
8485
8547
  let t = n.result;
8486
- e.oldVersion < 2 && t.objectStoreNames.contains($) && t.deleteObjectStore($), t.createObjectStore($, { keyPath: "id" });
8548
+ e.oldVersion < 2 && t.objectStoreNames.contains(gn) && t.deleteObjectStore(gn), t.createObjectStore(gn, { keyPath: "id" });
8487
8549
  }, n.onsuccess = () => e(n.result), n.onerror = () => t(n.error);
8488
8550
  });
8489
8551
  }
@@ -8505,8 +8567,8 @@ async function bn(e, t, n, r, i, a) {
8505
8567
  roomCount: Object.keys(t.rooms).length
8506
8568
  }, u = await vn();
8507
8569
  return new Promise((e, t) => {
8508
- let n = u.transaction($, "readwrite");
8509
- n.objectStore($).put(l), n.oncomplete = () => {
8570
+ let n = u.transaction(gn, "readwrite");
8571
+ n.objectStore(gn).put(l), n.oncomplete = () => {
8510
8572
  u.close(), e(c);
8511
8573
  }, n.onerror = () => {
8512
8574
  u.close(), t(n.error);
@@ -8516,7 +8578,7 @@ async function bn(e, t, n, r, i, a) {
8516
8578
  async function xn() {
8517
8579
  let e = await vn();
8518
8580
  return new Promise((t, n) => {
8519
- let r = e.transaction($, "readonly").objectStore($).getAll();
8581
+ let r = e.transaction(gn, "readonly").objectStore(gn).getAll();
8520
8582
  r.onsuccess = () => {
8521
8583
  e.close(), t(r.result.sort((e, t) => t.savedAt - e.savedAt));
8522
8584
  }, r.onerror = () => {
@@ -8527,8 +8589,8 @@ async function xn() {
8527
8589
  async function Sn() {
8528
8590
  let e = await vn();
8529
8591
  return new Promise((t, n) => {
8530
- let r = e.transaction($, "readwrite");
8531
- r.objectStore($).clear(), r.oncomplete = () => {
8592
+ let r = e.transaction(gn, "readwrite");
8593
+ r.objectStore(gn).clear(), r.oncomplete = () => {
8532
8594
  e.close(), t();
8533
8595
  }, r.onerror = () => {
8534
8596
  e.close(), n(r.error);
@@ -8538,8 +8600,8 @@ async function Sn() {
8538
8600
  async function Cn(e) {
8539
8601
  let t = await vn();
8540
8602
  return new Promise((n, r) => {
8541
- let i = t.transaction($, "readwrite");
8542
- i.objectStore($).delete(e), i.oncomplete = () => {
8603
+ let i = t.transaction(gn, "readwrite");
8604
+ i.objectStore(gn).delete(e), i.oncomplete = () => {
8543
8605
  t.close(), n();
8544
8606
  }, i.onerror = () => {
8545
8607
  t.close(), r(i.error);
@@ -9009,7 +9071,7 @@ function An({ sceneRef: e }) {
9009
9071
  className: "swatch-env-id",
9010
9072
  children: N === -1 ? "−" : N
9011
9073
  })
9012
- }), F && c && /* @__PURE__ */ d($t, {
9074
+ }), F && c && /* @__PURE__ */ d(Qt, {
9013
9075
  map: c,
9014
9076
  sceneRef: e,
9015
9077
  currentEnvId: N,
@@ -9050,15 +9112,415 @@ function An({ sceneRef: e }) {
9050
9112
  });
9051
9113
  }
9052
9114
  //#endregion
9115
+ //#region src/components/SearchPanel.tsx
9116
+ function jn(e, t = 40) {
9117
+ return e.length > t ? e.slice(0, t) + "…" : e;
9118
+ }
9119
+ function Mn({ onClose: e }) {
9120
+ let a = O((e) => e.map), [o, s] = i(""), [c, l] = i("rooms"), [p, m] = i(0), h = r(null), g = r(null);
9121
+ t(() => {
9122
+ h.current?.focus();
9123
+ }, []);
9124
+ let _ = n(() => {
9125
+ if (!a || o.trim().length === 0) return [];
9126
+ let e = o.trim().toLowerCase();
9127
+ if (c === "rooms") {
9128
+ let t = [];
9129
+ for (let [n, r] of Object.entries(a.rooms)) {
9130
+ if (!r) continue;
9131
+ let i = Number(n), o = null;
9132
+ if (r.name?.toLowerCase().includes(e)) o = "name";
9133
+ else if (n.includes(e)) o = "id";
9134
+ else if (r.userData) {
9135
+ for (let [t, n] of Object.entries(r.userData)) if (t.toLowerCase().includes(e) || String(n).toLowerCase().includes(e)) {
9136
+ o = `${t}: ${jn(String(n))}`;
9137
+ break;
9138
+ }
9139
+ }
9140
+ if (o !== null && (t.push({
9141
+ kind: "room",
9142
+ id: i,
9143
+ name: r.name ?? "",
9144
+ areaId: r.area,
9145
+ areaName: a.areaNames[r.area] ?? `Area ${r.area}`,
9146
+ x: r.x,
9147
+ y: r.y,
9148
+ z: r.z,
9149
+ matchReason: o
9150
+ }), t.length >= 100)) break;
9151
+ }
9152
+ return t;
9153
+ } else {
9154
+ let t = [];
9155
+ for (let [n, r] of Object.entries(a.labels)) {
9156
+ if (!r) continue;
9157
+ let i = Number(n);
9158
+ for (let n of r) if (!(!n || !n.text?.toLowerCase().includes(e)) && (t.push({
9159
+ kind: "label",
9160
+ id: n.id,
9161
+ text: n.text,
9162
+ areaId: i,
9163
+ areaName: a.areaNames[i] ?? `Area ${i}`,
9164
+ x: n.pos[0],
9165
+ y: n.pos[1],
9166
+ z: n.pos[2]
9167
+ }), t.length >= 100)) break;
9168
+ if (t.length >= 100) break;
9169
+ }
9170
+ return t;
9171
+ }
9172
+ }, [
9173
+ a,
9174
+ o,
9175
+ c
9176
+ ]);
9177
+ t(() => {
9178
+ m(0);
9179
+ }, [_]);
9180
+ let v = (e) => {
9181
+ let t = D.getState(), n = t.currentAreaId === e.areaId && t.currentZ === e.z;
9182
+ e.kind === "room" ? n ? D.setState({
9183
+ selection: {
9184
+ kind: "room",
9185
+ ids: [e.id]
9186
+ },
9187
+ panRequest: {
9188
+ mapX: e.x,
9189
+ mapY: -e.y
9190
+ }
9191
+ }) : (D.setState({
9192
+ currentAreaId: e.areaId,
9193
+ currentZ: e.z,
9194
+ navigateTo: {
9195
+ mapX: e.x,
9196
+ mapY: -e.y
9197
+ },
9198
+ selection: {
9199
+ kind: "room",
9200
+ ids: [e.id]
9201
+ },
9202
+ pending: null
9203
+ }), D.bumpStructure()) : n ? D.setState({
9204
+ selection: {
9205
+ kind: "label",
9206
+ id: e.id,
9207
+ areaId: e.areaId
9208
+ },
9209
+ panRequest: {
9210
+ mapX: e.x,
9211
+ mapY: -e.y
9212
+ }
9213
+ }) : (D.setState({
9214
+ currentAreaId: e.areaId,
9215
+ currentZ: e.z,
9216
+ navigateTo: {
9217
+ mapX: e.x,
9218
+ mapY: -e.y
9219
+ },
9220
+ selection: {
9221
+ kind: "label",
9222
+ id: e.id,
9223
+ areaId: e.areaId
9224
+ },
9225
+ pending: null
9226
+ }), D.bumpStructure());
9227
+ }, y = (t) => {
9228
+ if (t.key === "Escape") {
9229
+ e();
9230
+ return;
9231
+ }
9232
+ if (t.key === "Tab") {
9233
+ t.preventDefault(), b(c === "rooms" ? "labels" : "rooms");
9234
+ return;
9235
+ }
9236
+ t.key === "ArrowDown" ? (t.preventDefault(), m((e) => Math.min(e + 1, _.length - 1))) : t.key === "ArrowUp" ? (t.preventDefault(), m((e) => Math.max(e - 1, 0))) : t.key === "Enter" && _.length > 0 && (t.preventDefault(), v(_[p]));
9237
+ };
9238
+ t(() => {
9239
+ (g.current?.children[p])?.scrollIntoView({ block: "nearest" });
9240
+ }, [p]);
9241
+ let b = (e) => {
9242
+ l(e), s(""), h.current?.focus();
9243
+ };
9244
+ return /* @__PURE__ */ f("div", {
9245
+ className: "search-panel",
9246
+ onKeyDown: y,
9247
+ children: [
9248
+ /* @__PURE__ */ f("div", {
9249
+ className: "search-panel-header",
9250
+ children: [/* @__PURE__ */ f("div", {
9251
+ className: "search-panel-tabs",
9252
+ children: [/* @__PURE__ */ d("button", {
9253
+ type: "button",
9254
+ className: `search-tab${c === "rooms" ? " active" : ""}`,
9255
+ onClick: () => b("rooms"),
9256
+ children: "Rooms"
9257
+ }), /* @__PURE__ */ d("button", {
9258
+ type: "button",
9259
+ className: `search-tab${c === "labels" ? " active" : ""}`,
9260
+ onClick: () => b("labels"),
9261
+ children: "Labels"
9262
+ })]
9263
+ }), /* @__PURE__ */ d("button", {
9264
+ type: "button",
9265
+ className: "modal-close",
9266
+ onClick: e,
9267
+ title: "Close (Esc)",
9268
+ children: "✕"
9269
+ })]
9270
+ }),
9271
+ /* @__PURE__ */ f("div", {
9272
+ className: "search-panel-input-wrap",
9273
+ children: [
9274
+ /* @__PURE__ */ f("svg", {
9275
+ className: "search-panel-icon",
9276
+ width: "14",
9277
+ height: "14",
9278
+ viewBox: "0 0 16 16",
9279
+ fill: "none",
9280
+ "aria-hidden": "true",
9281
+ children: [/* @__PURE__ */ d("circle", {
9282
+ cx: "6.5",
9283
+ cy: "6.5",
9284
+ r: "4.5",
9285
+ stroke: "currentColor",
9286
+ strokeWidth: "1.4"
9287
+ }), /* @__PURE__ */ d("path", {
9288
+ d: "M10.5 10.5L14 14",
9289
+ stroke: "currentColor",
9290
+ strokeWidth: "1.4",
9291
+ strokeLinecap: "round"
9292
+ })]
9293
+ }),
9294
+ /* @__PURE__ */ d("input", {
9295
+ ref: h,
9296
+ className: "search-panel-input",
9297
+ type: "text",
9298
+ placeholder: c === "rooms" ? "name, ID, or user data… (Tab to switch)" : "label text… (Tab to switch)",
9299
+ value: o,
9300
+ onChange: (e) => s(e.target.value)
9301
+ }),
9302
+ o && /* @__PURE__ */ d("button", {
9303
+ type: "button",
9304
+ className: "search-panel-clear",
9305
+ onClick: () => {
9306
+ s(""), h.current?.focus();
9307
+ },
9308
+ title: "Clear",
9309
+ children: "✕"
9310
+ })
9311
+ ]
9312
+ }),
9313
+ o.trim().length > 0 && /* @__PURE__ */ f("ul", {
9314
+ className: "search-panel-results",
9315
+ ref: g,
9316
+ children: [_.length === 0 ? /* @__PURE__ */ d("li", {
9317
+ className: "search-panel-empty",
9318
+ children: "No matches"
9319
+ }) : _.map((e, t) => /* @__PURE__ */ d("li", {
9320
+ className: `search-panel-result${t === p ? " selected" : ""}`,
9321
+ onClick: () => v(e),
9322
+ onMouseEnter: () => m(t),
9323
+ children: e.kind === "room" ? /* @__PURE__ */ f(u, { children: [/* @__PURE__ */ f("div", {
9324
+ className: "search-result-row",
9325
+ children: [/* @__PURE__ */ d("span", {
9326
+ className: "search-result-name",
9327
+ children: e.name || /* @__PURE__ */ d("em", { children: "unnamed" })
9328
+ }), /* @__PURE__ */ f("span", {
9329
+ className: "search-result-meta",
9330
+ children: [
9331
+ "#",
9332
+ e.id,
9333
+ " · ",
9334
+ e.areaName,
9335
+ e.z === 0 ? "" : ` · z${e.z}`
9336
+ ]
9337
+ })]
9338
+ }), /* @__PURE__ */ d("div", {
9339
+ className: "search-result-reason",
9340
+ children: e.matchReason
9341
+ })] }) : /* @__PURE__ */ f(u, { children: [/* @__PURE__ */ d("span", {
9342
+ className: "search-result-name",
9343
+ children: e.text || /* @__PURE__ */ d("em", { children: "empty label" })
9344
+ }), /* @__PURE__ */ f("span", {
9345
+ className: "search-result-meta",
9346
+ children: [e.areaName, e.z === 0 ? "" : ` · z${e.z}`]
9347
+ })] })
9348
+ }, e.kind === "room" ? `room-${e.id}` : `label-${e.areaId}-${e.id}`)), _.length === 100 && /* @__PURE__ */ d("li", {
9349
+ className: "search-panel-more",
9350
+ children: "Showing first 100 results — refine your query"
9351
+ })]
9352
+ })
9353
+ ]
9354
+ });
9355
+ }
9356
+ //#endregion
9357
+ //#region src/components/SpreadShrinkPopup.tsx
9358
+ function Nn({ sceneRef: e }) {
9359
+ let n = O((e) => e.spreadShrink), i = O((e) => e.selection), a = r(null);
9360
+ if (t(() => {
9361
+ if (!n) return;
9362
+ let e = () => D.setState({ spreadShrink: null }), t = (t) => {
9363
+ t.key === "Escape" && e();
9364
+ }, r = (t) => {
9365
+ t.button === 0 && a.current && !a.current.contains(t.target) && e();
9366
+ };
9367
+ return window.addEventListener("keydown", t), window.addEventListener("mousedown", r, !0), () => {
9368
+ window.removeEventListener("keydown", t), window.removeEventListener("mousedown", r, !0);
9369
+ };
9370
+ }, [n]), !n || !i || i.kind !== "room") return null;
9371
+ let { mode: o, factor: s, centerMode: c, anchorRoomId: l } = n, p = (e) => {
9372
+ D.setState({ spreadShrink: {
9373
+ ...n,
9374
+ mode: e,
9375
+ factor: e === "spread" ? 2 : .5
9376
+ } });
9377
+ }, m = (e) => {
9378
+ D.setState({ spreadShrink: {
9379
+ ...n,
9380
+ centerMode: e,
9381
+ anchorRoomId: null
9382
+ } });
9383
+ }, h = (e) => {
9384
+ let t = parseFloat(e);
9385
+ !isNaN(t) && t > 0 && D.setState({ spreadShrink: {
9386
+ ...n,
9387
+ factor: t
9388
+ } });
9389
+ };
9390
+ return /* @__PURE__ */ f("div", {
9391
+ ref: a,
9392
+ className: "spread-shrink-popup",
9393
+ onContextMenu: (e) => e.preventDefault(),
9394
+ children: [
9395
+ /* @__PURE__ */ f("div", {
9396
+ className: "spread-shrink-title",
9397
+ children: [
9398
+ o === "spread" ? "Spread" : "Shrink",
9399
+ " ",
9400
+ i.ids.length,
9401
+ " rooms"
9402
+ ]
9403
+ }),
9404
+ /* @__PURE__ */ f("div", {
9405
+ className: "spread-shrink-mode",
9406
+ children: [/* @__PURE__ */ d("button", {
9407
+ type: "button",
9408
+ className: `spread-shrink-tab${o === "spread" ? " active" : ""}`,
9409
+ onClick: () => p("spread"),
9410
+ children: "Spread"
9411
+ }), /* @__PURE__ */ d("button", {
9412
+ type: "button",
9413
+ className: `spread-shrink-tab${o === "shrink" ? " active" : ""}`,
9414
+ onClick: () => p("shrink"),
9415
+ children: "Shrink"
9416
+ })]
9417
+ }),
9418
+ /* @__PURE__ */ f("div", {
9419
+ className: "spread-shrink-mode",
9420
+ children: [/* @__PURE__ */ d("button", {
9421
+ type: "button",
9422
+ className: `spread-shrink-tab${c === "centroid" ? " active" : ""}`,
9423
+ onClick: () => m("centroid"),
9424
+ children: "Centroid"
9425
+ }), /* @__PURE__ */ d("button", {
9426
+ type: "button",
9427
+ className: `spread-shrink-tab${c === "anchor" ? " active" : ""}`,
9428
+ onClick: () => m("anchor"),
9429
+ children: "Anchor"
9430
+ })]
9431
+ }),
9432
+ c === "anchor" && /* @__PURE__ */ d("div", {
9433
+ className: "spread-shrink-anchor",
9434
+ children: l === null ? /* @__PURE__ */ d("span", {
9435
+ className: "spread-shrink-anchor-hint",
9436
+ children: "Right-click a room to set anchor"
9437
+ }) : /* @__PURE__ */ f(u, { children: [/* @__PURE__ */ f("span", { children: ["Anchor: room ", l] }), /* @__PURE__ */ d("button", {
9438
+ type: "button",
9439
+ className: "spread-shrink-anchor-clear",
9440
+ onClick: () => m("anchor"),
9441
+ children: "×"
9442
+ })] })
9443
+ }),
9444
+ /* @__PURE__ */ f("div", {
9445
+ className: "spread-shrink-field",
9446
+ children: [/* @__PURE__ */ d("label", { children: "Scale factor" }), /* @__PURE__ */ d("input", {
9447
+ type: "number",
9448
+ min: "0.01",
9449
+ max: "10",
9450
+ step: "0.1",
9451
+ value: s,
9452
+ onChange: (e) => h(e.target.value)
9453
+ })]
9454
+ }),
9455
+ /* @__PURE__ */ f("div", {
9456
+ className: "spread-shrink-actions",
9457
+ children: [/* @__PURE__ */ d("button", {
9458
+ type: "button",
9459
+ className: "context-menu-btn",
9460
+ onClick: () => D.setState({ spreadShrink: null }),
9461
+ children: "Cancel"
9462
+ }), /* @__PURE__ */ d("button", {
9463
+ type: "button",
9464
+ className: "context-menu-btn primary",
9465
+ onClick: () => {
9466
+ let t = D.getState(), n = t.selection, r = e.current;
9467
+ if (!n || n.kind !== "room" || !r || !t.map) return;
9468
+ let i = [];
9469
+ for (let e of n.ids) {
9470
+ let n = r.getRenderRoom(e);
9471
+ !n || n.z !== t.currentZ || n.area !== t.currentAreaId || i.push({
9472
+ id: e,
9473
+ rx: n.x,
9474
+ ry: n.y
9475
+ });
9476
+ }
9477
+ if (i.length < 2) {
9478
+ D.setState({ spreadShrink: null });
9479
+ return;
9480
+ }
9481
+ let a = t.spreadShrink, c, l;
9482
+ if (a.centerMode === "anchor" && a.anchorRoomId !== null) {
9483
+ let e = r.getRenderRoom(a.anchorRoomId);
9484
+ c = e ? e.x : i.reduce((e, t) => e + t.rx, 0) / i.length, l = e ? e.y : i.reduce((e, t) => e + t.ry, 0) / i.length;
9485
+ } else c = i.reduce((e, t) => e + t.rx, 0) / i.length, l = i.reduce((e, t) => e + t.ry, 0) / i.length;
9486
+ let u = t.snapToGrid ? (e) => Math.round(e / t.gridStep) * t.gridStep : Math.round, d = [];
9487
+ for (let { id: e, rx: n, ry: r } of i) {
9488
+ let i = u(c + (n - c) * s), a = u(l + (r - l) * s), o = t.map.rooms[e];
9489
+ if (!o) continue;
9490
+ let f = i, p = -a;
9491
+ f === o.x && p === o.y || (d.push({
9492
+ kind: "moveRoom",
9493
+ id: e,
9494
+ from: {
9495
+ x: o.x,
9496
+ y: o.y,
9497
+ z: o.z
9498
+ },
9499
+ to: {
9500
+ x: f,
9501
+ y: p,
9502
+ z: o.z
9503
+ }
9504
+ }), d.push(...ke(t.map, e, f - o.x, p - o.y)));
9505
+ }
9506
+ d.length > 0 && (X(d, r), r.refresh(), D.bumpStructure(), D.setState({ status: `${o === "spread" ? "Spread" : "Shrunk"} ${i.length} rooms (×${s.toFixed(2)})` })), D.setState({ spreadShrink: null });
9507
+ },
9508
+ children: "Apply"
9509
+ })]
9510
+ })
9511
+ ]
9512
+ });
9513
+ }
9514
+ //#endregion
9053
9515
  //#region src/editor/reader/EditorMapReader.ts
9054
- var jn = {
9516
+ var Pn = {
9055
9517
  1: "solid line",
9056
9518
  2: "dash line",
9057
9519
  3: "dot line",
9058
9520
  4: "dash dot line",
9059
9521
  5: "dash dot dot line"
9060
9522
  };
9061
- function Mn(e, t) {
9523
+ function Fn(e, t) {
9062
9524
  let n = {
9063
9525
  id: e,
9064
9526
  __raw: t
@@ -9147,7 +9609,7 @@ function Mn(e, t) {
9147
9609
  g: 255,
9148
9610
  b: 255
9149
9611
  },
9150
- style: jn[t.customLinesStyle?.[r]] ?? "solid line",
9612
+ style: Pn[t.customLinesStyle?.[r]] ?? "solid line",
9151
9613
  arrow: t.customLinesArrow?.[r] ?? !1
9152
9614
  }
9153
9615
  };
@@ -9158,7 +9620,7 @@ function Mn(e, t) {
9158
9620
  configurable: !0
9159
9621
  }), n;
9160
9622
  }
9161
- function Nn(e) {
9623
+ function In(e) {
9162
9624
  let t = {
9163
9625
  north: "south",
9164
9626
  south: "north",
@@ -9224,7 +9686,7 @@ function Nn(e) {
9224
9686
  }
9225
9687
  return r;
9226
9688
  }
9227
- function Pn(e) {
9689
+ function Ln(e) {
9228
9690
  if (!e || e.length === 0) return "";
9229
9691
  if (typeof e == "string") return e.includes(",") ? e.split(",")[1] : e;
9230
9692
  try {
@@ -9233,10 +9695,10 @@ function Pn(e) {
9233
9695
  return "";
9234
9696
  }
9235
9697
  }
9236
- function Fn(e) {
9237
- e.pixMapBase64 === void 0 && (e.pixMapBase64 = Pn(e.pixMap));
9698
+ function Rn(e) {
9699
+ e.pixMapBase64 === void 0 && (e.pixMapBase64 = Ln(e.pixMap));
9238
9700
  }
9239
- function In(e, t) {
9701
+ function zn(e, t) {
9240
9702
  let n = e.id;
9241
9703
  if (!e.font) {
9242
9704
  let r = t[`system.labelFont_${n}`];
@@ -9266,7 +9728,7 @@ function In(e, t) {
9266
9728
  });
9267
9729
  }
9268
9730
  }
9269
- function Ln(e, t) {
9731
+ function Bn(e, t) {
9270
9732
  let n = e.id, r = e.font;
9271
9733
  if (r?.family) {
9272
9734
  let e = r.bold ? 75 : 50;
@@ -9277,7 +9739,7 @@ function Ln(e, t) {
9277
9739
  t[`system.labelOutlineColor_${n}`] = `${r}|${i}|${a}|${o}`;
9278
9740
  } else t[`system.labelOutlineColor_${n}`] = "0|0|0|0";
9279
9741
  }
9280
- function Rn(e) {
9742
+ function Vn(e) {
9281
9743
  return {
9282
9744
  id: e.id,
9283
9745
  pos: [...e.pos],
@@ -9293,7 +9755,7 @@ function Rn(e) {
9293
9755
  imageSrc: e.imageSrc
9294
9756
  };
9295
9757
  }
9296
- var zn = class {
9758
+ var Hn = class {
9297
9759
  constructor(e, t) {
9298
9760
  this.rooms = e, this.labels = t;
9299
9761
  }
@@ -9323,7 +9785,7 @@ var zn = class {
9323
9785
  setLabels(e) {
9324
9786
  this.labels = e;
9325
9787
  }
9326
- }, Bn = class {
9788
+ }, Un = class {
9327
9789
  planes = {};
9328
9790
  exits = /* @__PURE__ */ new Map();
9329
9791
  version = 0;
@@ -9391,19 +9853,19 @@ var zn = class {
9391
9853
  let t = {};
9392
9854
  for (let [n, r] of Object.entries(e)) {
9393
9855
  let e = Number(n);
9394
- t[e] = new zn(r, this.labels.filter((t) => t.Z === e));
9856
+ t[e] = new Hn(r, this.labels.filter((t) => t.Z === e));
9395
9857
  }
9396
9858
  this.planes = t;
9397
9859
  }
9398
9860
  rebuildExits() {
9399
- this.exits = Nn(this.rooms);
9861
+ this.exits = In(this.rooms);
9400
9862
  }
9401
9863
  };
9402
- function Vn(e) {
9864
+ function Wn(e) {
9403
9865
  let t = e[0] / 255, n = e[1] / 255, r = e[2] / 255;
9404
9866
  return (Math.max(t, n, r) + Math.min(t, n, r)) / 2;
9405
9867
  }
9406
- var Hn = {
9868
+ var Gn = {
9407
9869
  rgb: [
9408
9870
  114,
9409
9871
  1,
@@ -9416,7 +9878,7 @@ var Hn = {
9416
9878
  225
9417
9879
  ],
9418
9880
  symbolColorValue: "rgb(225,225,225)"
9419
- }, Un = class {
9881
+ }, Kn = class {
9420
9882
  rooms = {};
9421
9883
  areas = {};
9422
9884
  colors = {};
@@ -9426,7 +9888,7 @@ var Hn = {
9426
9888
  for (let e of t) this.colors[e.envId] = {
9427
9889
  rgb: e.colors,
9428
9890
  rgbValue: `rgb(${e.colors.join(",")})`,
9429
- symbolColor: Vn(e.colors) > .41 ? [
9891
+ symbolColor: Wn(e.colors) > .41 ? [
9430
9892
  25,
9431
9893
  25,
9432
9894
  25
@@ -9435,19 +9897,19 @@ var Hn = {
9435
9897
  255,
9436
9898
  255
9437
9899
  ],
9438
- symbolColorValue: Vn(e.colors) > .41 ? "rgb(25,25,25)" : "rgb(225,255,255)"
9900
+ symbolColorValue: Wn(e.colors) > .41 ? "rgb(25,25,25)" : "rgb(225,255,255)"
9439
9901
  };
9440
9902
  for (let [t, n] of Object.entries(e.areas)) {
9441
9903
  let r = Number(t), i = [];
9442
9904
  for (let t of n.rooms) {
9443
9905
  let n = e.rooms[t];
9444
9906
  if (!n) continue;
9445
- let r = Mn(t, n);
9907
+ let r = Fn(t, n);
9446
9908
  this.rooms[t] = r, i.push(r);
9447
9909
  }
9448
9910
  let a = e.labels?.[r] ?? [], o = e.areas[r]?.userData ?? {};
9449
- for (let e of a) Fn(e), In(e, o);
9450
- this.areas[r] = new Bn(r, e.areaNames[r] ?? `Area ${r}`, i, a.map((e) => this.toRendererLabel(e, r)));
9911
+ for (let e of a) Rn(e), zn(e, o);
9912
+ this.areas[r] = new Un(r, e.areaNames[r] ?? `Area ${r}`, i, a.map((e) => this.toRendererLabel(e, r)));
9451
9913
  }
9452
9914
  }
9453
9915
  toRendererLabel(e, t) {
@@ -9504,10 +9966,10 @@ var Hn = {
9504
9966
  return !1;
9505
9967
  }
9506
9968
  getColorValue(e) {
9507
- return this.colors[e]?.rgbValue ?? Hn.rgbValue;
9969
+ return this.colors[e]?.rgbValue ?? Gn.rgbValue;
9508
9970
  }
9509
9971
  getSymbolColor(e, t) {
9510
- let n = this.colors[e] ?? Hn, r = Math.min(Math.max(t ?? 1, 0), 1), i = n.symbolColor.join(",");
9972
+ let n = this.colors[e] ?? Gn, r = Math.min(Math.max(t ?? 1, 0), 1), i = n.symbolColor.join(",");
9511
9973
  return r === 1 ? `rgba(${i})` : `rgba(${i}, ${r})`;
9512
9974
  }
9513
9975
  moveRoom(e, t, n, r) {
@@ -9541,7 +10003,7 @@ var Hn = {
9541
10003
  this.raw.rooms[e] = t;
9542
10004
  let n = this.raw.areas[t.area];
9543
10005
  n && !n.rooms.includes(e) && n.rooms.push(e);
9544
- let r = Mn(e, t);
10006
+ let r = Fn(e, t);
9545
10007
  this.rooms[e] = r, this.areas[t.area]?.addRoomLive(r);
9546
10008
  }
9547
10009
  setSpecialExit(e, t, n) {
@@ -9637,7 +10099,7 @@ var Hn = {
9637
10099
  isZone: !1,
9638
10100
  zoneAreaRef: -1,
9639
10101
  userData: {}
9640
- }, this.raw.areaNames[e] = t, this.areas[e] = new Bn(e, t, [], []);
10102
+ }, this.raw.areaNames[e] = t, this.areas[e] = new Un(e, t, [], []);
9641
10103
  }
9642
10104
  removeArea(e) {
9643
10105
  delete this.raw.areas[e], delete this.raw.areaNames[e], delete this.areas[e];
@@ -9669,7 +10131,7 @@ var Hn = {
9669
10131
  for (let e of n) this.colors[e.envId] = {
9670
10132
  rgb: e.colors,
9671
10133
  rgbValue: `rgb(${e.colors.join(",")})`,
9672
- symbolColor: Vn(e.colors) > .41 ? [
10134
+ symbolColor: Wn(e.colors) > .41 ? [
9673
10135
  25,
9674
10136
  25,
9675
10137
  25
@@ -9678,17 +10140,17 @@ var Hn = {
9678
10140
  255,
9679
10141
  255
9680
10142
  ],
9681
- symbolColorValue: Vn(e.colors) > .41 ? "rgb(25,25,25)" : "rgb(225,255,255)"
10143
+ symbolColorValue: Wn(e.colors) > .41 ? "rgb(25,25,25)" : "rgb(225,255,255)"
9682
10144
  };
9683
10145
  t === null && delete this.colors[e];
9684
10146
  }
9685
10147
  getLabelSnapshot(e, t) {
9686
10148
  let n = this.raw.labels[e]?.find((e) => e.id === t);
9687
- return n ? Rn(n) : null;
10149
+ return n ? Vn(n) : null;
9688
10150
  }
9689
10151
  addLabel(e, t) {
9690
10152
  this.raw.labels[e] || (this.raw.labels[e] = []);
9691
- let n = t.pixMap || Gt(t), r = {
10153
+ let n = t.pixMap || Wt(t), r = {
9692
10154
  id: t.id,
9693
10155
  labelId: t.id,
9694
10156
  areaId: e,
@@ -9697,7 +10159,7 @@ var Hn = {
9697
10159
  text: t.text,
9698
10160
  fgColor: { ...t.fgColor },
9699
10161
  bgColor: { ...t.bgColor },
9700
- pixMap: Kt(n),
10162
+ pixMap: Gt(n),
9701
10163
  pixMapBase64: n.includes(",") ? n.split(",")[1] : n,
9702
10164
  noScaling: t.noScaling,
9703
10165
  showOnTop: t.showOnTop,
@@ -9706,7 +10168,7 @@ var Hn = {
9706
10168
  };
9707
10169
  this.raw.labels[e].push(r);
9708
10170
  let i = this.raw.areas[e]?.userData;
9709
- i && Ln(r, i), this.syncRendererLabels(e);
10171
+ i && Bn(r, i), this.syncRendererLabels(e);
9710
10172
  }
9711
10173
  removeLabel(e, t) {
9712
10174
  if (!this.raw.labels[e]) return;
@@ -9728,7 +10190,7 @@ var Hn = {
9728
10190
  }
9729
10191
  setLabelPixmap(e, t, n) {
9730
10192
  let r = this.raw.labels[e]?.find((e) => e.id === t);
9731
- r && (r.pixMap = Kt(n), r.pixMapBase64 = n.includes(",") ? n.split(",")[1] : n, this.syncRendererLabels(e));
10193
+ r && (r.pixMap = Gt(n), r.pixMapBase64 = n.includes(",") ? n.split(",")[1] : n, this.syncRendererLabels(e));
9732
10194
  }
9733
10195
  setLabelImageSrc(e, t, n) {
9734
10196
  let r = this.raw.labels[e]?.find((e) => e.id === t);
@@ -9739,14 +10201,14 @@ var Hn = {
9739
10201
  if (!r) return;
9740
10202
  r.font = { ...n };
9741
10203
  let i = this.raw.areas[e]?.userData;
9742
- i && Ln(r, i), this.syncRendererLabels(e);
10204
+ i && Bn(r, i), this.syncRendererLabels(e);
9743
10205
  }
9744
10206
  setLabelOutlineColor(e, t, n) {
9745
10207
  let r = this.raw.labels[e]?.find((e) => e.id === t);
9746
10208
  if (!r) return;
9747
10209
  r.outlineColor = n ? { ...n } : void 0;
9748
10210
  let i = this.raw.areas[e]?.userData;
9749
- i && Ln(r, i), this.syncRendererLabels(e);
10211
+ i && Bn(r, i), this.syncRendererLabels(e);
9750
10212
  }
9751
10213
  setLabelNoScaling(e, t, n) {
9752
10214
  let r = this.raw.labels[e]?.find((e) => e.id === t);
@@ -9777,10 +10239,10 @@ var Hn = {
9777
10239
  restoreAreaWithRooms(e, t, n, r) {
9778
10240
  let i = [];
9779
10241
  for (let { id: e, room: t } of n) {
9780
- let n = Mn(e, t);
10242
+ let n = Fn(e, t);
9781
10243
  this.rooms[e] = n, i.push(n);
9782
10244
  }
9783
- this.areas[e] = new Bn(e, t, i, []);
10245
+ this.areas[e] = new Un(e, t, i, []);
9784
10246
  for (let e of r) {
9785
10247
  let t = this.areas[e];
9786
10248
  t && (t.rebuildExits(), t.markDirty());
@@ -9819,7 +10281,7 @@ var Hn = {
9819
10281
  }
9820
10282
  for (let e of this.getAreas()) n.has(e.getAreaId()) || e.rebuildExits();
9821
10283
  }
9822
- }, Wn = class {
10284
+ }, qn = class {
9823
10285
  rects = /* @__PURE__ */ new Map();
9824
10286
  layer;
9825
10287
  unsubscribe;
@@ -9863,7 +10325,7 @@ var Hn = {
9863
10325
  }
9864
10326
  this.layer.batchDraw();
9865
10327
  }
9866
- }, Gn = "#ffcc00", Kn = .9, qn = .3, Jn = .2, Yn = class {
10328
+ }, Jn = "#ffcc00", Yn = .9, Xn = .3, Zn = .2, Qn = class {
9867
10329
  roomRect;
9868
10330
  linkGroup;
9869
10331
  layer;
@@ -9874,7 +10336,7 @@ var Hn = {
9874
10336
  }
9875
10337
  attach(e) {
9876
10338
  this.layer = e, this.roomRect = new h.Rect({
9877
- stroke: Gn,
10339
+ stroke: Jn,
9878
10340
  strokeWidth: .06,
9879
10341
  listening: !1,
9880
10342
  visible: !1,
@@ -9922,23 +10384,23 @@ var Hn = {
9922
10384
  }
9923
10385
  for (let t of e.data.lines) this.linkGroup.add(new h.Line({
9924
10386
  points: [...t.points],
9925
- stroke: Gn,
10387
+ stroke: Jn,
9926
10388
  strokeWidth: r,
9927
10389
  dash: t.dash ? [...t.dash] : void 0,
9928
10390
  listening: !1,
9929
10391
  lineCap: "round",
9930
- opacity: Kn
10392
+ opacity: Yn
9931
10393
  }));
9932
10394
  for (let t of e.data.arrows) this.linkGroup.add(new h.Arrow({
9933
10395
  points: [...t.points],
9934
- stroke: Gn,
9935
- fill: Gn,
10396
+ stroke: Jn,
10397
+ fill: Jn,
9936
10398
  strokeWidth: r,
9937
10399
  dash: t.dash ? [...t.dash] : void 0,
9938
10400
  pointerLength: t.pointerLength,
9939
10401
  pointerWidth: t.pointerWidth,
9940
10402
  listening: !1,
9941
- opacity: Kn
10403
+ opacity: Yn
9942
10404
  }));
9943
10405
  this.linkGroup.visible(!0);
9944
10406
  } else if (t.kind === "customLine") {
@@ -9949,33 +10411,33 @@ var Hn = {
9949
10411
  }
9950
10412
  let i = e.hasArrow && e.points.length >= 4 ? new h.Arrow({
9951
10413
  points: [...e.points],
9952
- stroke: Gn,
9953
- fill: Gn,
10414
+ stroke: Jn,
10415
+ fill: Jn,
9954
10416
  strokeWidth: r,
9955
10417
  dash: e.dash ? [...e.dash] : void 0,
9956
- pointerLength: qn,
9957
- pointerWidth: Jn,
10418
+ pointerLength: Xn,
10419
+ pointerWidth: Zn,
9958
10420
  listening: !1,
9959
10421
  lineCap: "round",
9960
10422
  lineJoin: "round",
9961
- opacity: Kn
10423
+ opacity: Yn
9962
10424
  }) : new h.Line({
9963
10425
  points: [...e.points],
9964
- stroke: Gn,
10426
+ stroke: Jn,
9965
10427
  strokeWidth: r,
9966
10428
  dash: e.dash ? [...e.dash] : void 0,
9967
10429
  listening: !1,
9968
10430
  lineCap: "round",
9969
10431
  lineJoin: "round",
9970
- opacity: Kn
10432
+ opacity: Yn
9971
10433
  });
9972
10434
  this.linkGroup.add(i), this.linkGroup.visible(!0);
9973
10435
  }
9974
10436
  this.layer.batchDraw();
9975
10437
  }
9976
- }, Xn = .6;
9977
- function Zn(e) {
9978
- for (let [t, n, r] of ot) if (r === e) return {
10438
+ }, $n = .6;
10439
+ function er(e) {
10440
+ for (let [t, n, r] of at) if (r === e) return {
9979
10441
  ox: t,
9980
10442
  oy: n
9981
10443
  };
@@ -9984,7 +10446,7 @@ function Zn(e) {
9984
10446
  oy: 0
9985
10447
  };
9986
10448
  }
9987
- var Qn = class {
10449
+ var tr = class {
9988
10450
  line;
9989
10451
  dirLabel;
9990
10452
  layer;
@@ -10031,14 +10493,14 @@ var Qn = class {
10031
10493
  }
10032
10494
  let r = n.getRenderRoom(t.sourceId);
10033
10495
  if (!r) return;
10034
- let i = t.hoverTargetId == null ? null : n.getRenderRoom(t.hoverTargetId), a = (n.settings.roomSize ?? Xn) / 2, o = r.x, s = r.y;
10496
+ let i = t.hoverTargetId == null ? null : n.getRenderRoom(t.hoverTargetId), a = (n.settings.roomSize ?? $n) / 2, o = r.x, s = r.y;
10035
10497
  if (t.sourceDir) {
10036
- let { ox: e, oy: n } = Zn(t.sourceDir);
10498
+ let { ox: e, oy: n } = er(t.sourceDir);
10037
10499
  o = r.x + e * a, s = r.y + n * a;
10038
10500
  }
10039
10501
  let c, l;
10040
10502
  if (i && t.targetDir) {
10041
- let { ox: e, oy: n } = Zn(t.targetDir);
10503
+ let { ox: e, oy: n } = er(t.targetDir);
10042
10504
  c = i.x + e * a, l = i.y + n * a;
10043
10505
  } else i ? (c = i.x, l = i.y) : (c = t.cursorMap?.x ?? r.x, l = t.cursorMap?.y ?? r.y);
10044
10506
  let u = !0, d = "";
@@ -10059,7 +10521,7 @@ var Qn = class {
10059
10521
  l
10060
10522
  ]), this.line.stroke(f), this.line.fill(f), this.line.visible(!0), d ? (this.dirLabel.text(d), this.dirLabel.fill(f), this.dirLabel.x((o + c) / 2 + .2), this.dirLabel.y((s + l) / 2 + .2), this.dirLabel.visible(!0)) : this.dirLabel.visible(!1), this.layer.batchDraw();
10061
10523
  }
10062
- }, $n = class {
10524
+ }, nr = class {
10063
10525
  rect;
10064
10526
  layer;
10065
10527
  unsubscribe;
@@ -10095,7 +10557,7 @@ var Qn = class {
10095
10557
  }
10096
10558
  this.rect.x(t.x), this.rect.y(t.y), this.rect.visible(!0), this.layer.batchDraw();
10097
10559
  }
10098
- }, er = class {
10560
+ }, rr = class {
10099
10561
  source;
10100
10562
  target;
10101
10563
  layer;
@@ -10119,7 +10581,7 @@ var Qn = class {
10119
10581
  listening: !1,
10120
10582
  visible: !1
10121
10583
  }), t = /* @__PURE__ */ new Map();
10122
- for (let [, , n] of ot) {
10584
+ for (let [, , n] of at) {
10123
10585
  let r = new h.Circle({
10124
10586
  radius: this.roomSize * .12,
10125
10587
  fill: "rgba(143, 184, 255, 0.85)",
@@ -10136,7 +10598,7 @@ var Qn = class {
10136
10598
  }
10137
10599
  placeHandles(e, t, n, r) {
10138
10600
  let i = this.roomSize / 2, a = r === "drag-source" || r === "drag-target" ? "#7fff9f" : "#ffd27f", o = r === "drag-source" || r === "drag-target" ? "#ffffff" : "#cfe1ff";
10139
- for (let [r, s, c] of ot) {
10601
+ for (let [r, s, c] of at) {
10140
10602
  let l = e.handles.get(c);
10141
10603
  l.x(t.x + r * i), l.y(t.y + s * i), l.fill(c === n ? a : "rgba(143, 184, 255, 0.85)"), l.stroke(c === n ? o : "#cfe1ff");
10142
10604
  }
@@ -10173,7 +10635,7 @@ var Qn = class {
10173
10635
  }
10174
10636
  this.layer.batchDraw();
10175
10637
  }
10176
- }, tr = "rgba(255, 220, 60, 0.9)", nr = .55, rr = class {
10638
+ }, ir = "rgba(255, 220, 60, 0.9)", ar = .55, or = class {
10177
10639
  group;
10178
10640
  layer;
10179
10641
  unsubscribe;
@@ -10246,14 +10708,14 @@ var Qn = class {
10246
10708
  if (o) {
10247
10709
  let t = this.resolveTargetRoom(e, o.roomId, o.exitName);
10248
10710
  if (t) {
10249
- let { x: e, y: n } = t, r = nr, i = new h.Line({
10711
+ let { x: e, y: n } = t, r = ar, i = new h.Line({
10250
10712
  points: [
10251
10713
  e - r,
10252
10714
  n,
10253
10715
  e + r,
10254
10716
  n
10255
10717
  ],
10256
- stroke: tr,
10718
+ stroke: ir,
10257
10719
  strokeWidth: a,
10258
10720
  listening: !1,
10259
10721
  lineCap: "round"
@@ -10264,7 +10726,7 @@ var Qn = class {
10264
10726
  e,
10265
10727
  n + r
10266
10728
  ],
10267
- stroke: tr,
10729
+ stroke: ir,
10268
10730
  strokeWidth: a,
10269
10731
  listening: !1,
10270
10732
  lineCap: "round"
@@ -10294,11 +10756,11 @@ var Qn = class {
10294
10756
  y: c.y
10295
10757
  };
10296
10758
  }
10297
- }, ir = "#00e5ff", ar = {
10298
- shadowColor: ir,
10759
+ }, sr = "#00e5ff", cr = {
10760
+ shadowColor: sr,
10299
10761
  shadowBlur: 4,
10300
10762
  shadowOpacity: .8
10301
- }, or = .3, sr = .2, cr = class {
10763
+ }, lr = .3, ur = .2, dr = class {
10302
10764
  group;
10303
10765
  layer;
10304
10766
  unsubscribe;
@@ -10336,22 +10798,22 @@ var Qn = class {
10336
10798
  }
10337
10799
  for (let t of e.data.lines) this.group.add(new h.Line({
10338
10800
  points: [...t.points],
10339
- stroke: ir,
10801
+ stroke: sr,
10340
10802
  strokeWidth: .08,
10341
10803
  dash: t.dash ? [...t.dash] : void 0,
10342
10804
  listening: !1,
10343
- ...ar
10805
+ ...cr
10344
10806
  }));
10345
10807
  for (let t of e.data.arrows) this.group.add(new h.Arrow({
10346
10808
  points: [...t.points],
10347
- stroke: ir,
10348
- fill: ir,
10809
+ stroke: sr,
10810
+ fill: sr,
10349
10811
  strokeWidth: .08,
10350
10812
  dash: t.dash ? [...t.dash] : void 0,
10351
10813
  pointerLength: t.pointerLength,
10352
10814
  pointerWidth: t.pointerWidth,
10353
10815
  listening: !1,
10354
- ...ar
10816
+ ...cr
10355
10817
  }));
10356
10818
  this.group.visible(!0), this.layer.batchDraw();
10357
10819
  return;
@@ -10364,28 +10826,28 @@ var Qn = class {
10364
10826
  }
10365
10827
  let r = e.hasArrow && e.points.length >= 4 ? new h.Arrow({
10366
10828
  points: [...e.points],
10367
- stroke: ir,
10368
- fill: ir,
10829
+ stroke: sr,
10830
+ fill: sr,
10369
10831
  strokeWidth: .08,
10370
10832
  dash: e.dash ? [...e.dash] : void 0,
10371
- pointerLength: or,
10372
- pointerWidth: sr,
10833
+ pointerLength: lr,
10834
+ pointerWidth: ur,
10373
10835
  listening: !1,
10374
- ...ar
10836
+ ...cr
10375
10837
  }) : new h.Line({
10376
10838
  points: [...e.points],
10377
- stroke: ir,
10839
+ stroke: sr,
10378
10840
  strokeWidth: .08,
10379
10841
  dash: e.dash ? [...e.dash] : void 0,
10380
10842
  listening: !1,
10381
- ...ar
10843
+ ...cr
10382
10844
  });
10383
10845
  this.group.add(r), this.group.add(new h.Circle({
10384
10846
  x: e.points[0],
10385
10847
  y: e.points[1],
10386
10848
  radius: .1,
10387
10849
  fill: "#1a2030",
10388
- stroke: ir,
10850
+ stroke: sr,
10389
10851
  strokeWidth: .04,
10390
10852
  listening: !1
10391
10853
  }));
@@ -10396,8 +10858,8 @@ var Qn = class {
10396
10858
  x: e.points[t],
10397
10859
  y: e.points[t + 1],
10398
10860
  radius: r ? .14 : .1,
10399
- fill: r ? "#ffffff" : ir,
10400
- stroke: r ? ir : "#ffffff",
10861
+ fill: r ? "#ffffff" : sr,
10862
+ stroke: r ? sr : "#ffffff",
10401
10863
  strokeWidth: r ? .06 : .04,
10402
10864
  listening: !1
10403
10865
  }));
@@ -10410,13 +10872,13 @@ var Qn = class {
10410
10872
  };
10411
10873
  //#endregion
10412
10874
  //#region src/editor/effects/GridOverlayEffect.ts
10413
- function lr(e, t) {
10875
+ function fr(e, t) {
10414
10876
  let n = e.match(/rgba?\(\s*(\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\s*\)/);
10415
10877
  if (!n) return e;
10416
10878
  let r = n[4] === void 0 ? 1 : parseFloat(n[4]);
10417
10879
  return `rgba(${n[1]}, ${n[2]}, ${n[3]}, ${Math.min(1, r * t)})`;
10418
10880
  }
10419
- var ur = class {
10881
+ var pr = class {
10420
10882
  gridShape;
10421
10883
  axisShape;
10422
10884
  labelShape;
@@ -10448,7 +10910,7 @@ var ur = class {
10448
10910
  }), this.axisShape = new h.Shape({
10449
10911
  listening: !1,
10450
10912
  visible: !1,
10451
- stroke: lr(this.gridColor, 2),
10913
+ stroke: fr(this.gridColor, 2),
10452
10914
  strokeWidth: this.gridLineWidth * 2,
10453
10915
  sceneFunc: (e, t) => {
10454
10916
  let { minX: n, maxX: r, minY: i, maxY: a } = this.bounds;
@@ -10462,7 +10924,7 @@ var ur = class {
10462
10924
  text: "(0,0)",
10463
10925
  fontSize: this.gridSize,
10464
10926
  fontFamily: "monospace",
10465
- fill: lr(this.gridColor, 2)
10927
+ fill: fr(this.gridColor, 2)
10466
10928
  }), e.add(this.gridShape), e.add(this.axisShape), e.add(this.labelShape), this.unsubscribe = D.subscribe(() => this.syncVisibility());
10467
10929
  }
10468
10930
  updateViewport(e, t, n) {
@@ -10476,7 +10938,7 @@ var ur = class {
10476
10938
  let e = this.getIsEmpty();
10477
10939
  e && (this.bounds = this.getViewportBounds()), this.gridShape.visible() !== e && (this.gridShape.visible(e), this.axisShape.visible(e), this.labelShape.visible(e), this.layer.batchDraw());
10478
10940
  }
10479
- }, dr = class {
10941
+ }, mr = class {
10480
10942
  rect;
10481
10943
  layer;
10482
10944
  unsubscribe;
@@ -10510,7 +10972,7 @@ var ur = class {
10510
10972
  };
10511
10973
  //#endregion
10512
10974
  //#region src/editor/effects/LabelHaloEffect.ts
10513
- function fr(e, t, n, r) {
10975
+ function hr(e, t, n, r) {
10514
10976
  return [
10515
10977
  {
10516
10978
  id: "nw",
@@ -10554,7 +11016,7 @@ function fr(e, t, n, r) {
10554
11016
  }
10555
11017
  ];
10556
11018
  }
10557
- var pr = class {
11019
+ var gr = class {
10558
11020
  selRect;
10559
11021
  hoverRect;
10560
11022
  previewRect;
@@ -10644,7 +11106,7 @@ var pr = class {
10644
11106
  for (let e of this.handles) e.visible(!1);
10645
11107
  return;
10646
11108
  }
10647
- let t = .05, n = e.x - t, r = e.y - t, i = e.w + t * 2, a = e.h + t * 2, o = this.handleSize, s = fr(n, r, i, a);
11109
+ let t = .05, n = e.x - t, r = e.y - t, i = e.w + t * 2, a = e.h + t * 2, o = this.handleSize, s = hr(n, r, i, a);
10648
11110
  for (let e = 0; e < this.handles.length; e++) {
10649
11111
  let t = this.handles[e], n = s[e];
10650
11112
  t.x(n.x - o / 2), t.y(n.y - o / 2), t.width(o), t.height(o), t.visible(!0);
@@ -10663,13 +11125,170 @@ var pr = class {
10663
11125
  } else this.previewRect.visible(!1);
10664
11126
  this.layer.batchDraw();
10665
11127
  }
11128
+ }, _r = class {
11129
+ hLine;
11130
+ vLine;
11131
+ dot;
11132
+ layer;
11133
+ unsubscribe;
11134
+ constructor(e) {
11135
+ this.sceneRef = e;
11136
+ }
11137
+ attach(e) {
11138
+ this.layer = e;
11139
+ let t = {
11140
+ stroke: "rgba(0, 229, 255, 0.7)",
11141
+ strokeWidth: .05,
11142
+ listening: !1,
11143
+ visible: !1
11144
+ };
11145
+ this.hLine = new h.Line({
11146
+ ...t,
11147
+ points: [
11148
+ 0,
11149
+ 0,
11150
+ 0,
11151
+ 0
11152
+ ]
11153
+ }), this.vLine = new h.Line({
11154
+ ...t,
11155
+ points: [
11156
+ 0,
11157
+ 0,
11158
+ 0,
11159
+ 0
11160
+ ]
11161
+ }), this.dot = new h.Circle({
11162
+ radius: .07,
11163
+ fill: "rgba(0, 229, 255, 0.6)",
11164
+ listening: !1,
11165
+ visible: !1
11166
+ }), e.add(this.hLine), e.add(this.vLine), e.add(this.dot), this.unsubscribe = D.subscribe((e) => this.sync(e)), this.sync(D.getState());
11167
+ }
11168
+ updateViewport(e, t, n) {
11169
+ let r = Math.max(.02, 1.5 / t);
11170
+ this.hLine?.strokeWidth(r), this.vLine?.strokeWidth(r), this.layer?.batchDraw();
11171
+ }
11172
+ syncPositions() {
11173
+ this.sync(D.getState());
11174
+ }
11175
+ destroy() {
11176
+ this.unsubscribe?.(), this.hLine?.destroy(), this.vLine?.destroy(), this.dot?.destroy();
11177
+ }
11178
+ sync(e) {
11179
+ if (!this.layer) return;
11180
+ let t = e.selection, n = this.sceneRef.current, r = () => {
11181
+ this.hLine?.visible(!1), this.vLine?.visible(!1), this.dot?.visible(!1), this.layer.batchDraw();
11182
+ };
11183
+ if (!t || t.kind !== "room" || t.ids.length < 2 || !n) return r();
11184
+ let { spreadShrink: i } = e, a, o;
11185
+ if (i?.centerMode === "anchor" && i.anchorRoomId !== null) {
11186
+ let e = n.getRenderRoom(i.anchorRoomId);
11187
+ if (!e) return r();
11188
+ a = e.x, o = e.y;
11189
+ } else {
11190
+ let i = [];
11191
+ for (let r of t.ids) {
11192
+ let t = n.getRenderRoom(r);
11193
+ !t || t.z !== e.currentZ || t.area !== e.currentAreaId || i.push({
11194
+ x: t.x,
11195
+ y: t.y
11196
+ });
11197
+ }
11198
+ if (i.length < 2) return r();
11199
+ a = i.reduce((e, t) => e + t.x, 0) / i.length, o = i.reduce((e, t) => e + t.y, 0) / i.length;
11200
+ }
11201
+ let s = .3;
11202
+ this.hLine.points([
11203
+ a - s,
11204
+ o,
11205
+ a + s,
11206
+ o
11207
+ ]), this.hLine.visible(!0), this.vLine.points([
11208
+ a,
11209
+ o - s,
11210
+ a,
11211
+ o + s
11212
+ ]), this.vLine.visible(!0), this.dot.x(a), this.dot.y(o), this.dot.visible(!0), this.layer.batchDraw();
11213
+ }
11214
+ };
11215
+ //#endregion
11216
+ //#region src/editor/effects/GhostRoomsEffect.ts
11217
+ function vr(e, t) {
11218
+ let n = e.match(/\d+/g);
11219
+ return !n || n.length < 3 ? `rgba(128, 128, 128, ${t})` : `rgba(${n[0]}, ${n[1]}, ${n[2]}, ${t})`;
11220
+ }
11221
+ var yr = class {
11222
+ rects = /* @__PURE__ */ new Map();
11223
+ layer;
11224
+ unsubscribe;
11225
+ strokeWidth = .06;
11226
+ dash = [.2, .15];
11227
+ constructor(e, t) {
11228
+ this.roomSize = e, this.sceneRef = t;
11229
+ }
11230
+ attach(e) {
11231
+ this.layer = e, this.unsubscribe = D.subscribe((e) => this.sync(e)), this.sync(D.getState());
11232
+ }
11233
+ updateViewport(e, t, n) {
11234
+ this.strokeWidth = Math.max(.03, 2 / t), this.dash = [Math.max(.1, 6 / t), Math.max(.08, 5 / t)], this.rects.forEach((e) => {
11235
+ e.strokeWidth(this.strokeWidth), e.dash([...this.dash]);
11236
+ }), this.layer?.batchDraw();
11237
+ }
11238
+ syncPositions() {
11239
+ this.sync(D.getState());
11240
+ }
11241
+ destroy() {
11242
+ this.unsubscribe?.(), this.rects.forEach((e) => e.destroy()), this.rects.clear();
11243
+ }
11244
+ computePositions(e) {
11245
+ let t = /* @__PURE__ */ new Map(), { selection: n, spreadShrink: r, currentAreaId: i, currentZ: a } = e, o = this.sceneRef.current;
11246
+ if (!r || !n || n.kind !== "room" || !o) return t;
11247
+ let s = [];
11248
+ for (let e of n.ids) {
11249
+ let t = o.getRenderRoom(e);
11250
+ !t || t.z !== a || t.area !== i || s.push({
11251
+ id: e,
11252
+ x: t.x,
11253
+ y: t.y
11254
+ });
11255
+ }
11256
+ if (s.length < 2) return t;
11257
+ let c, l;
11258
+ if (r.centerMode === "anchor" && r.anchorRoomId !== null) {
11259
+ let e = o.getRenderRoom(r.anchorRoomId);
11260
+ c = e ? e.x : s.reduce((e, t) => e + t.x, 0) / s.length, l = e ? e.y : s.reduce((e, t) => e + t.y, 0) / s.length;
11261
+ } else c = s.reduce((e, t) => e + t.x, 0) / s.length, l = s.reduce((e, t) => e + t.y, 0) / s.length;
11262
+ let { factor: u } = r, d = e.snapToGrid ? (t) => Math.round(t / e.gridStep) * e.gridStep : (e) => e;
11263
+ for (let { id: e, x: n, y: r } of s) t.set(e, {
11264
+ x: d(c + (n - c) * u),
11265
+ y: d(l + (r - l) * u)
11266
+ });
11267
+ return t;
11268
+ }
11269
+ sync(e) {
11270
+ if (!this.layer) return;
11271
+ let t = this.sceneRef.current, n = this.computePositions(e);
11272
+ for (let [e, t] of this.rects) n.has(e) || (t.destroy(), this.rects.delete(e));
11273
+ let r = .05, i = this.roomSize + r * 2;
11274
+ for (let [e, a] of n) {
11275
+ let n = t?.getRenderRoom(e), o = t?.reader.getColorValue(n?.env ?? 1) ?? "rgb(128,128,128)", s = vr(o, .2), c = vr(o, .65), l = this.rects.get(e);
11276
+ l || (l = new h.Rect({
11277
+ strokeWidth: this.strokeWidth,
11278
+ dash: [...this.dash],
11279
+ cornerRadius: .04,
11280
+ listening: !1
11281
+ }), this.layer.add(l), this.rects.set(e, l)), l.fill(s), l.stroke(c), l.x(a.x - this.roomSize / 2 - r), l.y(a.y - this.roomSize / 2 - r), l.width(i), l.height(i);
11282
+ }
11283
+ this.layer.batchDraw();
11284
+ }
10666
11285
  };
10667
11286
  //#endregion
10668
11287
  //#region src/editor/pointerController.ts
10669
- function mr(e) {
11288
+ function br(e) {
10670
11289
  let { container: t } = e, n = null, r = null, i = D.getState().spaceHeld, a = D.subscribe((r) => {
10671
11290
  if (!i && r.spaceHeld && n !== null) {
10672
- It[r.activeTool].onCancel?.(e);
11291
+ Ft[r.activeTool].onCancel?.(e);
10673
11292
  try {
10674
11293
  t.releasePointerCapture(n);
10675
11294
  } catch {}
@@ -10687,7 +11306,7 @@ function mr(e) {
10687
11306
  e.renderer.backend.viewport.startDrag(i.clientX - n.left, i.clientY - n.top), r = i.pointerId, t.setPointerCapture(i.pointerId), o(i);
10688
11307
  return;
10689
11308
  }
10690
- let a = D.getState().pending?.kind, l = It[a === "pickSwatch" || a === "pickExit" || a === "pickSpecialExit" ? "select" : s()];
11309
+ let a = D.getState().pending?.kind, l = Ft[a === "pickSwatch" || a === "pickExit" || a === "pickSpecialExit" ? "select" : s()];
10691
11310
  !l.onPointerDown || !c(i) || l.onPointerDown(i, e) && (n = i.pointerId, o(i));
10692
11311
  }, u = (i) => {
10693
11312
  if (r === i.pointerId) {
@@ -10695,7 +11314,7 @@ function mr(e) {
10695
11314
  e.renderer.backend.viewport.updateDrag(i.clientX - n.left, i.clientY - n.top), e.refresh(), o(i);
10696
11315
  return;
10697
11316
  }
10698
- (It[s()].onPointerMove?.(i, e) || n === i.pointerId) && o(i);
11317
+ (Ft[s()].onPointerMove?.(i, e) || n === i.pointerId) && o(i);
10699
11318
  }, d = (i) => {
10700
11319
  if (r === i.pointerId) {
10701
11320
  e.renderer.backend.viewport.endDrag();
@@ -10705,14 +11324,14 @@ function mr(e) {
10705
11324
  r = null, o(i);
10706
11325
  return;
10707
11326
  }
10708
- let a = It[s()].onPointerUp?.(i, e), c = n === i.pointerId;
11327
+ let a = Ft[s()].onPointerUp?.(i, e), c = n === i.pointerId;
10709
11328
  c && (n = null), (a || c) && o(i);
10710
11329
  }, f = (t) => {
10711
11330
  if (r === t.pointerId) {
10712
11331
  e.renderer.backend.viewport.endDrag(), r = null;
10713
11332
  return;
10714
11333
  }
10715
- It[s()].onCancel?.(e), n === t.pointerId && (n = null, o(t));
11334
+ Ft[s()].onCancel?.(e), n === t.pointerId && (n = null, o(t));
10716
11335
  }, p = () => {
10717
11336
  D.getState().hover && D.setState({ hover: null });
10718
11337
  }, m = (e) => {
@@ -10724,7 +11343,7 @@ function mr(e) {
10724
11343
  }, h = (e) => {
10725
11344
  e.button !== 1 && (e.button === 0 || e.button === 2) && s() !== "pan" && o(e);
10726
11345
  }, g = (t) => {
10727
- t.preventDefault(), It[s()].onContextMenu?.(t, e);
11346
+ t.preventDefault(), Ft[s()].onContextMenu?.(t, e);
10728
11347
  }, _ = { capture: !0 };
10729
11348
  return t.addEventListener("pointerdown", l, _), t.addEventListener("pointermove", u, _), t.addEventListener("pointerup", d, _), t.addEventListener("pointercancel", f, _), t.addEventListener("pointerleave", p), t.addEventListener("mousedown", m, _), t.addEventListener("mouseup", h, _), t.addEventListener("contextmenu", g), () => {
10730
11349
  a(), t.removeEventListener("pointerdown", l, _), t.removeEventListener("pointermove", u, _), t.removeEventListener("pointerup", d, _), t.removeEventListener("pointercancel", f, _), t.removeEventListener("pointerleave", p), t.removeEventListener("mousedown", m, _), t.removeEventListener("mouseup", h, _), t.removeEventListener("contextmenu", g);
@@ -10732,17 +11351,17 @@ function mr(e) {
10732
11351
  }
10733
11352
  //#endregion
10734
11353
  //#region src/editor/scene.ts
10735
- function hr(e, t) {
11354
+ function xr(e, t) {
10736
11355
  let n = m();
10737
11356
  n.gridEnabled = !0, n.highlightCurrentRoom = !1, n.areaName = !1, n.labelRenderMode = "image", t.dataset.editorCursor = "true";
10738
- let r = new Un(e), i = new p(r, n, t), a = { current: null }, o = new dr(), s = new Wn(n.roomSize, a), c = new Yn(n.roomSize, a), l = new Qn(a), u = new $n(n.roomSize), d = new er(n.roomSize, a), f = new rr(a), h = new cr(a, n.roomSize), g = new pr(a), _ = new ur(n.gridColor, n.gridLineWidth, n.gridSize, () => {
11357
+ let r = new Kn(e), i = new p(r, n, t), a = { current: null }, o = new mr(), s = new qn(n.roomSize, a), c = new Qn(n.roomSize, a), l = new tr(a), u = new nr(n.roomSize), d = new rr(n.roomSize, a), f = new or(a), h = new dr(a, n.roomSize), g = new gr(a), _ = new _r(a), v = new yr(n.roomSize, a), y = new pr(n.gridColor, n.gridLineWidth, n.gridSize, () => {
10739
11358
  let e = D.getState();
10740
11359
  if (e.currentAreaId == null) return !1;
10741
11360
  let t = r.getArea(e.currentAreaId);
10742
11361
  return t ? t.getRooms().every((t) => t.z !== e.currentZ) : !1;
10743
11362
  }, () => i.backend.viewport.getViewportBounds());
10744
- i.addLiveEffect("editor.marquee", o), i.addLiveEffect("editor.selection", s), i.addLiveEffect("editor.hover", c), i.addLiveEffect("editor.rubberband", l), i.addLiveEffect("editor.snap", u), i.addLiveEffect("editor.connectHandles", d), i.addLiveEffect("editor.customLinePreview", f), i.addLiveEffect("editor.selectedLink", h), i.addLiveEffect("editor.labelHalo", g), i.addLiveEffect("editor.gridOverlay", _);
10745
- let v = {
11363
+ i.addLiveEffect("editor.marquee", o), i.addLiveEffect("editor.selection", s), i.addLiveEffect("editor.hover", c), i.addLiveEffect("editor.rubberband", l), i.addLiveEffect("editor.snap", u), i.addLiveEffect("editor.connectHandles", d), i.addLiveEffect("editor.customLinePreview", f), i.addLiveEffect("editor.selectedLink", h), i.addLiveEffect("editor.labelHalo", g), i.addLiveEffect("editor.selectionCenter", _), i.addLiveEffect("editor.ghostRooms", v), i.addLiveEffect("editor.gridOverlay", y);
11364
+ let b = {
10746
11365
  renderer: i,
10747
11366
  reader: r,
10748
11367
  settings: n,
@@ -10752,36 +11371,36 @@ function hr(e, t) {
10752
11371
  setArea(e, t, n) {
10753
11372
  i.drawArea(e, t);
10754
11373
  let a = r.getArea(e);
10755
- !a || a.getRooms().every((e) => e.z !== t) ? i.backend.viewport.panToMapPoint(0, 0) : i.fitArea(n), _.syncVisibility();
11374
+ !a || a.getRooms().every((e) => e.z !== t) ? i.backend.viewport.panToMapPoint(0, 0) : i.fitArea(n), y.syncVisibility();
10756
11375
  },
10757
11376
  setAreaAt(e, t, n, r) {
10758
- i.drawArea(e, t), i.backend.viewport.panToMapPoint(n, r), _.syncVisibility();
11377
+ i.drawArea(e, t), i.backend.viewport.panToMapPoint(n, r), y.syncVisibility();
10759
11378
  },
10760
11379
  refresh() {
10761
- i.refresh(), s.syncPositions(), g.syncPositions();
11380
+ i.refresh(), s.syncPositions(), g.syncPositions(), _.syncPositions(), v.syncPositions();
10762
11381
  },
10763
11382
  destroy() {
10764
- delete t.dataset.editorCursor, y(), i.removeLiveEffect("editor.selection"), i.removeLiveEffect("editor.hover"), i.removeLiveEffect("editor.rubberband"), i.removeLiveEffect("editor.snap"), i.removeLiveEffect("editor.connectHandles"), o.destroy(), i.removeLiveEffect("editor.marquee"), s.destroy(), c.destroy(), l.destroy(), u.destroy(), d.destroy(), f.destroy(), i.removeLiveEffect("editor.customLinePreview"), h.destroy(), i.removeLiveEffect("editor.selectedLink"), g.destroy(), i.removeLiveEffect("editor.labelHalo"), _.destroy(), i.removeLiveEffect("editor.gridOverlay"), i.destroy();
11383
+ delete t.dataset.editorCursor, x(), i.removeLiveEffect("editor.selection"), i.removeLiveEffect("editor.hover"), i.removeLiveEffect("editor.rubberband"), i.removeLiveEffect("editor.snap"), i.removeLiveEffect("editor.connectHandles"), o.destroy(), i.removeLiveEffect("editor.marquee"), s.destroy(), c.destroy(), l.destroy(), u.destroy(), d.destroy(), f.destroy(), i.removeLiveEffect("editor.customLinePreview"), h.destroy(), i.removeLiveEffect("editor.selectedLink"), g.destroy(), i.removeLiveEffect("editor.labelHalo"), _.destroy(), i.removeLiveEffect("editor.selectionCenter"), v.destroy(), i.removeLiveEffect("editor.ghostRooms"), y.destroy(), i.removeLiveEffect("editor.gridOverlay"), i.destroy();
10765
11384
  }
10766
11385
  };
10767
- a.current = v;
10768
- let y = mr({
11386
+ a.current = b;
11387
+ let x = br({
10769
11388
  renderer: i,
10770
11389
  container: t,
10771
11390
  settings: n,
10772
11391
  refresh: () => i.refresh(),
10773
- scene: v
11392
+ scene: b
10774
11393
  });
10775
- return v;
11394
+ return b;
10776
11395
  }
10777
11396
  //#endregion
10778
11397
  //#region src/App.tsx
10779
- var gr = {
11398
+ var Sr = {
10780
11399
  top: 104,
10781
11400
  right: 464,
10782
11401
  bottom: 24,
10783
11402
  left: 24
10784
- }, _r = {
11403
+ }, Cr = {
10785
11404
  1: "select",
10786
11405
  2: "connect",
10787
11406
  3: "unlink",
@@ -10790,7 +11409,7 @@ var gr = {
10790
11409
  6: "delete",
10791
11410
  7: "pan",
10792
11411
  8: "paint"
10793
- }, vr = {
11412
+ }, wr = {
10794
11413
  ArrowLeft: {
10795
11414
  dx: -1,
10796
11415
  dy: 0
@@ -10808,43 +11427,43 @@ var gr = {
10808
11427
  dy: -1
10809
11428
  }
10810
11429
  };
10811
- function yr({ plugins: a = [], title: o = "Mudlet Map Editor" }) {
10812
- let s = r(null), c = r(null), l = O((e) => e.map), u = O((e) => e.swatchPaletteOpen), p = l != null, m = O((e) => e.currentAreaId), h = O((e) => e.currentZ), g = O((e) => e.activeTool), _ = O((e) => e.pending), v = O((e) => e.hover), y = O((e) => e.spaceHeld), b = O((e) => e.panelCollapsed), x = O((e) => e.dataVersion), C = O((e) => e.panRequest), [w, T] = i(!1), [E, k] = i(!1), [A, j] = i(() => new URLSearchParams(window.location.search).get("map")), M = n(() => a.flatMap((e) => e.swatchSets?.() ?? []), [a]), N = n(() => a.flatMap((e) => e.sidebarTabs?.() ?? []), [a]), P = n(() => a.flatMap((e) => e.roomPanelSections?.() ?? []), [a]);
11430
+ function Tr({ plugins: a = [], title: o = "Mudlet Map Editor" }) {
11431
+ let s = r(null), c = r(null), l = O((e) => e.map), p = O((e) => e.swatchPaletteOpen), m = l != null, h = O((e) => e.currentAreaId), g = O((e) => e.currentZ), _ = O((e) => e.activeTool), v = O((e) => e.pending), y = O((e) => e.hover), b = O((e) => e.spaceHeld), x = O((e) => e.panelCollapsed), C = O((e) => e.dataVersion), w = O((e) => e.panRequest), [T, E] = i(!1), [k, A] = i(!1), [j, M] = i(!1), [N, P] = i(() => new URLSearchParams(window.location.search).get("map")), F = n(() => a.flatMap((e) => e.swatchSets?.() ?? []), [a]), I = n(() => a.flatMap((e) => e.sidebarTabs?.() ?? []), [a]), L = n(() => a.flatMap((e) => e.roomPanelSections?.() ?? []), [a]);
10813
11432
  t(() => {
10814
- D.setState({ pluginSwatchSets: M });
10815
- }, [M]), t(() => {
11433
+ D.setState({ pluginSwatchSets: F });
11434
+ }, [F]), t(() => {
10816
11435
  a.length !== 0 && (async () => {
10817
11436
  for (let e of a) await e.onAppReady?.();
10818
11437
  })();
10819
11438
  }, []);
10820
- let F = r(l);
11439
+ let R = r(l);
10821
11440
  t(() => {
10822
- let e = F.current;
10823
- if (F.current = l, l && l !== e) for (let e of a) e.onMapOpened?.(l);
11441
+ let e = R.current;
11442
+ if (R.current = l, l && l !== e) for (let e of a) e.onMapOpened?.(l);
10824
11443
  else if (e && !l) for (let e of a) e.onMapClosed?.();
10825
11444
  }, [l]), t(() => {
10826
11445
  if (!l || !s.current) return;
10827
- let e = hr(l, s.current);
11446
+ let e = xr(l, s.current);
10828
11447
  c.current = e;
10829
11448
  let { currentAreaId: t, currentZ: n } = D.getState();
10830
- return t != null && e.setArea(t, n, gr), () => {
11449
+ return t != null && e.setArea(t, n, Sr), () => {
10831
11450
  e.destroy(), c.current = null;
10832
11451
  };
10833
11452
  }, [l]), t(() => {
10834
11453
  let e = c.current;
10835
- if (!e || !p || m == null) return;
11454
+ if (!e || !m || h == null) return;
10836
11455
  let t = D.getState().navigateTo;
10837
- t ? (D.setState({ navigateTo: null }), e.setAreaAt(m, h, t.mapX, t.mapY)) : e.setArea(m, h, gr);
11456
+ t ? (D.setState({ navigateTo: null }), e.setAreaAt(h, g, t.mapX, t.mapY)) : e.setArea(h, g, Sr);
10838
11457
  }, [
10839
- m,
10840
11458
  h,
10841
- p
11459
+ g,
11460
+ m
10842
11461
  ]), t(() => {
10843
- !C || !c.current || (D.setState({ panRequest: null }), c.current.renderer.backend.viewport.panToMapPoint(C.mapX, C.mapY), c.current.refresh());
10844
- }, [C]), t(() => {
11462
+ !w || !c.current || (D.setState({ panRequest: null }), c.current.renderer.backend.viewport.panToMapPoint(w.mapX, w.mapY), c.current.refresh());
11463
+ }, [w]), t(() => {
10845
11464
  let e = s.current;
10846
11465
  if (!e) return;
10847
- if (y) {
11466
+ if (b) {
10848
11467
  let t = () => {
10849
11468
  e.style.cursor = "grabbing";
10850
11469
  }, n = () => {
@@ -10854,12 +11473,12 @@ function yr({ plugins: a = [], title: o = "Mudlet Map Editor" }) {
10854
11473
  e.removeEventListener("pointerdown", t), e.removeEventListener("pointerup", n), e.removeEventListener("pointercancel", n);
10855
11474
  };
10856
11475
  }
10857
- if (_?.kind === "pickExit" || _?.kind === "pickSpecialExit" || _?.kind === "pickSwatch") {
11476
+ if (v?.kind === "pickExit" || v?.kind === "pickSpecialExit" || v?.kind === "pickSwatch") {
10858
11477
  e.style.cursor = "crosshair";
10859
11478
  return;
10860
11479
  }
10861
11480
  let t = {
10862
- select: v ? "pointer" : "default",
11481
+ select: y ? "pointer" : "default",
10863
11482
  connect: "crosshair",
10864
11483
  unlink: "crosshair",
10865
11484
  addRoom: "crosshair",
@@ -10869,12 +11488,12 @@ function yr({ plugins: a = [], title: o = "Mudlet Map Editor" }) {
10869
11488
  addLabel: "crosshair",
10870
11489
  paint: "cell"
10871
11490
  };
10872
- e.style.cursor = t[g];
11491
+ e.style.cursor = t[_];
10873
11492
  }, [
10874
- g,
10875
- v,
11493
+ _,
10876
11494
  y,
10877
- _
11495
+ b,
11496
+ v
10878
11497
  ]), t(() => {
10879
11498
  let { map: e, loaded: t, undo: n, currentAreaId: r, currentZ: i, sessionId: a } = D.getState();
10880
11499
  if (!e || !t) return;
@@ -10884,7 +11503,7 @@ function yr({ plugins: a = [], title: o = "Mudlet Map Editor" }) {
10884
11503
  }).catch(console.error);
10885
11504
  }, 1500);
10886
11505
  return () => clearTimeout(o);
10887
- }, [x]), t(() => {
11506
+ }, [C]), t(() => {
10888
11507
  let e = (e) => {
10889
11508
  let t = e?.tagName;
10890
11509
  return t === "INPUT" || t === "TEXTAREA" || t === "SELECT";
@@ -10898,22 +11517,26 @@ function yr({ plugins: a = [], title: o = "Mudlet Map Editor" }) {
10898
11517
  t.preventDefault(), D.getState().spaceHeld || D.setState({ spaceHeld: !0 });
10899
11518
  return;
10900
11519
  }
11520
+ if ((t.ctrlKey || t.metaKey) && t.key.toLowerCase() === "f") {
11521
+ t.preventDefault(), M((e) => !e);
11522
+ return;
11523
+ }
10901
11524
  if ((t.ctrlKey || t.metaKey) && !t.shiftKey && t.key.toLowerCase() === "z") {
10902
- t.preventDefault(), L();
11525
+ t.preventDefault(), z();
10903
11526
  return;
10904
11527
  }
10905
11528
  if ((t.ctrlKey || t.metaKey) && (t.shiftKey && t.key.toLowerCase() === "z" || t.key.toLowerCase() === "y")) {
10906
- t.preventDefault(), R();
11529
+ t.preventDefault(), B();
10907
11530
  return;
10908
11531
  }
10909
11532
  if (t.key === "Enter") {
10910
11533
  let e = D.getState();
10911
- e.pending?.kind === "customLine" && At(e.pending);
11534
+ e.pending?.kind === "customLine" && kt(e.pending);
10912
11535
  return;
10913
11536
  }
10914
11537
  if (t.key === "Escape") {
10915
11538
  let e = D.getState();
10916
- e.pending ? (e.pending.kind === "customLine" && c.current && kt(e.pending, c.current), D.setState({
11539
+ e.pending ? (e.pending.kind === "customLine" && c.current && Ot(e.pending, c.current), D.setState({
10917
11540
  pending: null,
10918
11541
  activeTool: e.pending.kind === "customLine" ? "select" : e.activeTool,
10919
11542
  status: "Cancelled."
@@ -10921,7 +11544,7 @@ function yr({ plugins: a = [], title: o = "Mudlet Map Editor" }) {
10921
11544
  return;
10922
11545
  }
10923
11546
  if (t.key === "Delete" || t.key === "Backspace") {
10924
- I();
11547
+ ee();
10925
11548
  return;
10926
11549
  }
10927
11550
  if (t.key === "g" || t.key === "G") {
@@ -10929,13 +11552,13 @@ function yr({ plugins: a = [], title: o = "Mudlet Map Editor" }) {
10929
11552
  return;
10930
11553
  }
10931
11554
  if (t.key === "f" || t.key === "F") {
10932
- c.current?.renderer.fitArea(gr);
11555
+ c.current?.renderer.fitArea(Sr);
10933
11556
  return;
10934
11557
  }
10935
- if (_r[t.key]) {
11558
+ if (Cr[t.key]) {
10936
11559
  let e = D.getState();
10937
- e.pending?.kind === "customLine" && c.current && (kt(e.pending, c.current), D.bumpData()), D.setState({
10938
- activeTool: _r[t.key],
11560
+ e.pending?.kind === "customLine" && c.current && (Ot(e.pending, c.current), D.bumpData()), D.setState({
11561
+ activeTool: Cr[t.key],
10939
11562
  pending: null
10940
11563
  });
10941
11564
  return;
@@ -10951,14 +11574,14 @@ function yr({ plugins: a = [], title: o = "Mudlet Map Editor" }) {
10951
11574
  } });
10952
11575
  return;
10953
11576
  }
10954
- if (vr[t.key]) {
11577
+ if (wr[t.key]) {
10955
11578
  let e = D.getState();
10956
11579
  if (e.activeTool !== "select" || !e.selection || !e.map) return;
10957
11580
  if (e.selection.kind === "label") {
10958
11581
  let { id: n, areaId: r } = e.selection, i = c.current?.reader.getLabelSnapshot(r, n);
10959
11582
  if (!i) return;
10960
11583
  t.preventDefault();
10961
- let a = (t.shiftKey ? 5 : 1) * e.gridStep, o = vr[t.key], s = o.dx * a, l = o.dy * a, u = [...i.pos], d = [
11584
+ let a = (t.shiftKey ? 5 : 1) * e.gridStep, o = wr[t.key], s = o.dx * a, l = o.dy * a, u = [...i.pos], d = [
10962
11585
  i.pos[0] + s,
10963
11586
  i.pos[1] + l,
10964
11587
  i.pos[2]
@@ -10975,42 +11598,49 @@ function yr({ plugins: a = [], title: o = "Mudlet Map Editor" }) {
10975
11598
  })), c.current?.refresh(), D.bumpData(), D.setState({ status: `Moved label ${n}` });
10976
11599
  return;
10977
11600
  }
10978
- if (e.selection.kind !== "room" || e.selection.ids.length !== 1) return;
10979
- let n = e.selection.ids[0], r = e.map.rooms[n];
10980
- if (!r) return;
11601
+ if (e.selection.kind !== "room") return;
10981
11602
  t.preventDefault();
10982
- let i = (t.shiftKey ? 5 : 1) * e.gridStep, a = vr[t.key], o = a.dx * i, s = a.dy * i, l = {
10983
- x: r.x,
10984
- y: r.y,
10985
- z: r.z
10986
- }, u = Ae(e.map, n, o, s);
10987
- c.current?.reader.moveRoom(n, r.x + o, -(r.y + s), r.z);
10988
- let d = {
10989
- x: r.x,
10990
- y: r.y,
10991
- z: r.z
10992
- };
10993
- for (let e of u) e.kind === "setCustomLine" && c.current?.reader.setCustomLine(e.roomId, e.exitName, e.data.points, e.data.color, e.data.style, e.data.arrow);
10994
- let f = {
10995
- kind: "moveRoom",
10996
- id: n,
10997
- from: l,
10998
- to: d
10999
- }, p = u.length > 0 ? {
11603
+ let n = (t.shiftKey ? 5 : 1) * e.gridStep, r = wr[t.key], i = r.dx * n, a = r.dy * n, o = [];
11604
+ for (let t of e.selection.ids) {
11605
+ let n = e.map.rooms[t];
11606
+ if (!n) continue;
11607
+ let r = {
11608
+ x: n.x,
11609
+ y: n.y,
11610
+ z: n.z
11611
+ }, s = ke(e.map, t, i, a);
11612
+ c.current?.reader.moveRoom(t, n.x + i, -(n.y + a), n.z);
11613
+ let l = {
11614
+ x: n.x,
11615
+ y: n.y,
11616
+ z: n.z
11617
+ };
11618
+ for (let e of s) e.kind === "setCustomLine" && c.current?.reader.setCustomLine(e.roomId, e.exitName, e.data.points, e.data.color, e.data.style, e.data.arrow);
11619
+ o.push({
11620
+ kind: "moveRoom",
11621
+ id: t,
11622
+ from: r,
11623
+ to: l
11624
+ }, ...s);
11625
+ }
11626
+ if (o.length === 0) return;
11627
+ let s = o.length === 1 ? o[0] : {
11000
11628
  kind: "batch",
11001
- cmds: [f, ...u]
11002
- } : f;
11629
+ cmds: o
11630
+ };
11003
11631
  D.setState((e) => ({
11004
- undo: [...e.undo, p],
11632
+ undo: [...e.undo, s],
11005
11633
  redo: []
11006
- })), c.current?.refresh(), D.bumpData(), D.setState({ status: `Moved room ${n} → (${r.x}, ${r.y}, ${r.z})` });
11634
+ })), c.current?.refresh(), D.bumpData();
11635
+ let { ids: l } = e.selection;
11636
+ D.setState({ status: l.length === 1 ? `Moved room ${l[0]} → (${e.map.rooms[l[0]]?.x}, ${e.map.rooms[l[0]]?.y}, ${e.map.rooms[l[0]]?.z})` : `Moved ${l.length} rooms` });
11007
11637
  }
11008
11638
  }
11009
11639
  };
11010
11640
  window.addEventListener("keydown", r), window.addEventListener("keyup", t), window.addEventListener("blur", n);
11011
- let i = () => c.current?.renderer.fitArea(gr);
11012
- return window.addEventListener("editor:undo", L), window.addEventListener("editor:redo", R), window.addEventListener("editor:fit", i), () => {
11013
- window.removeEventListener("keydown", r), window.removeEventListener("keyup", t), window.removeEventListener("blur", n), window.removeEventListener("editor:undo", L), window.removeEventListener("editor:redo", R), window.removeEventListener("editor:fit", i);
11641
+ let i = () => c.current?.renderer.fitArea(Sr);
11642
+ return window.addEventListener("editor:undo", z), window.addEventListener("editor:redo", B), window.addEventListener("editor:fit", i), () => {
11643
+ window.removeEventListener("keydown", r), window.removeEventListener("keyup", t), window.removeEventListener("blur", n), window.removeEventListener("editor:undo", z), window.removeEventListener("editor:redo", B), window.removeEventListener("editor:fit", i);
11014
11644
  };
11015
11645
  }, []), t(() => {
11016
11646
  let e = (e) => {
@@ -11024,7 +11654,7 @@ function yr({ plugins: a = [], title: o = "Mudlet Map Editor" }) {
11024
11654
  window.removeEventListener("dragover", e), window.removeEventListener("drop", t);
11025
11655
  };
11026
11656
  }, []);
11027
- let I = () => {
11657
+ let ee = () => {
11028
11658
  let e = D.getState();
11029
11659
  if (!e.map) return;
11030
11660
  let t = e.selection;
@@ -11032,7 +11662,7 @@ function yr({ plugins: a = [], title: o = "Mudlet Map Editor" }) {
11032
11662
  if (t.kind === "room") {
11033
11663
  if (e.currentAreaId == null) return;
11034
11664
  if (t.ids.length > 1) {
11035
- let n = Me(e.map, t.ids), r = [];
11665
+ let n = je(e.map, t.ids), r = [];
11036
11666
  for (let i of t.ids) {
11037
11667
  let t = e.map.rooms[i];
11038
11668
  t && r.push({
@@ -11055,7 +11685,7 @@ function yr({ plugins: a = [], title: o = "Mudlet Map Editor" }) {
11055
11685
  }
11056
11686
  let n = t.ids[0], r = e.map.rooms[n];
11057
11687
  if (!r) return;
11058
- let i = { ...r }, a = je(e.map, n);
11688
+ let i = { ...r }, a = Ae(e.map, n);
11059
11689
  Y({
11060
11690
  kind: "deleteRoom",
11061
11691
  id: n,
@@ -11169,15 +11799,15 @@ function yr({ plugins: a = [], title: o = "Mudlet Map Editor" }) {
11169
11799
  return;
11170
11800
  }
11171
11801
  }
11172
- }, L = () => {
11173
- let { changed: e, structural: t } = Oe(c.current);
11802
+ }, z = () => {
11803
+ let { changed: e, structural: t } = De(c.current);
11174
11804
  e && (c.current?.refresh(), t ? D.bumpStructure() : D.bumpData(), D.setState({ status: "Undone" }));
11175
- }, R = () => {
11176
- let { changed: e, structural: t } = ke(c.current);
11805
+ }, B = () => {
11806
+ let { changed: e, structural: t } = Oe(c.current);
11177
11807
  e && (c.current?.refresh(), t ? D.bumpStructure() : D.bumpData(), D.setState({ status: "Redone" }));
11178
11808
  };
11179
11809
  return /* @__PURE__ */ f("div", {
11180
- className: `app${b ? " panel-collapsed" : ""}`,
11810
+ className: `app${x ? " panel-collapsed" : ""}`,
11181
11811
  children: [
11182
11812
  /* @__PURE__ */ f("div", {
11183
11813
  className: "map-viewport",
@@ -11186,30 +11816,40 @@ function yr({ plugins: a = [], title: o = "Mudlet Map Editor" }) {
11186
11816
  ref: s,
11187
11817
  className: "map-container"
11188
11818
  }),
11189
- !p && /* @__PURE__ */ d(kn, {}),
11819
+ !m && /* @__PURE__ */ d(kn, {}),
11190
11820
  /* @__PURE__ */ d(ue, {
11191
11821
  title: o,
11192
- onHelpClick: () => T(!0),
11193
- onLoadFromUrl: () => k(!0),
11822
+ onHelpClick: () => E(!0),
11823
+ onLoadFromUrl: () => A(!0),
11194
11824
  onSave: (e) => {
11195
11825
  for (let t of a) t.onMapSave?.(e);
11196
- }
11826
+ },
11827
+ onSearchClick: () => M((e) => !e)
11197
11828
  }),
11198
- /* @__PURE__ */ d(mn, {
11829
+ /* @__PURE__ */ d(pn, {
11199
11830
  sceneRef: c,
11200
- extraTabs: N,
11201
- pluginRoomSections: P
11831
+ extraTabs: I,
11832
+ pluginRoomSections: L
11202
11833
  })
11203
11834
  ]
11204
11835
  }),
11205
- /* @__PURE__ */ d(hn, { sceneRef: c }),
11206
- u && /* @__PURE__ */ d(An, { sceneRef: c }),
11836
+ /* @__PURE__ */ d(mn, { sceneRef: c }),
11837
+ p && /* @__PURE__ */ d(An, { sceneRef: c }),
11207
11838
  a.map((t, n) => /* @__PURE__ */ d(e, { children: t.renderOverlay?.() }, n)),
11208
- w && /* @__PURE__ */ d(le, { onClose: () => T(!1) }),
11209
- (E || A) && /* @__PURE__ */ d(de, {
11210
- initialUrl: A ?? void 0,
11839
+ j && m && /* @__PURE__ */ f(u, { children: [/* @__PURE__ */ d("div", {
11840
+ style: {
11841
+ position: "fixed",
11842
+ inset: 0,
11843
+ zIndex: 399
11844
+ },
11845
+ onMouseDown: () => M(!1)
11846
+ }), /* @__PURE__ */ d(Mn, { onClose: () => M(!1) })] }),
11847
+ /* @__PURE__ */ d(Nn, { sceneRef: c }),
11848
+ T && /* @__PURE__ */ d(le, { onClose: () => E(!1) }),
11849
+ (k || N) && /* @__PURE__ */ d(de, {
11850
+ initialUrl: N ?? void 0,
11211
11851
  onClose: () => {
11212
- k(!1), j(null);
11852
+ A(!1), P(null);
11213
11853
  }
11214
11854
  })
11215
11855
  ]
@@ -11217,9 +11857,9 @@ function yr({ plugins: a = [], title: o = "Mudlet Map Editor" }) {
11217
11857
  }
11218
11858
  //#endregion
11219
11859
  //#region src/editor/mapBytes.ts
11220
- function br() {
11860
+ function Er() {
11221
11861
  let { map: e } = D.getState();
11222
11862
  return e ? H(e) : null;
11223
11863
  }
11224
11864
  //#endregion
11225
- export { yr as App, br as getMapBytes, G as loadUrlIntoStore, Y as pushCommand, D as store, O as useEditorState };
11865
+ export { Tr as App, Er as getMapBytes, G as loadUrlIntoStore, Y as pushCommand, D as store, O as useEditorState };