floor-editor-ts 1.3.0 → 1.3.1

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.
@@ -6392,6 +6392,11 @@ function updateBackgroundImage(updates) {
6392
6392
  if (f.backgroundImage) Object.assign(f.backgroundImage, updates);
6393
6393
  });
6394
6394
  }
6395
+ var cameraThumbnailOpacity = writable(.65);
6396
+ function updateCameraThumbnailOpacity(opacity) {
6397
+ const clamped = Math.min(1, Math.max(.05, opacity));
6398
+ cameraThumbnailOpacity.set(clamped);
6399
+ }
6395
6400
  function addColumn(position, shape = "round") {
6396
6401
  const id = uid$1();
6397
6402
  mutate((f) => {
@@ -6989,17 +6994,20 @@ var DEFAULT_CONFIG = {
6989
6994
  showCameraLabels: true,
6990
6995
  cameraHeatmapMatrix: [],
6991
6996
  siteCameras: [],
6992
- cameraThumbnail: ""
6997
+ cameraThumbnail: "",
6998
+ cameraThumbnailOpacity: .65
6993
6999
  };
6994
7000
  function normalizeConfig(value) {
6995
7001
  if (!value || typeof value !== "object") return { ...DEFAULT_CONFIG };
6996
7002
  const siteCameras = Array.isArray(value.siteCameras) ? value.siteCameras.filter((c) => !!c && typeof c === "object" && typeof c.serial === "string" && typeof c.name === "string") : DEFAULT_CONFIG.siteCameras;
6997
7003
  const image = typeof value.cameraThumbnail === "string" ? value.cameraThumbnail ? value.cameraThumbnail : DEFAULT_CONFIG.cameraThumbnail : DEFAULT_CONFIG.cameraThumbnail;
7004
+ const opacity = typeof value.cameraThumbnailOpacity === "number" && value.cameraThumbnailOpacity >= 0 && value.cameraThumbnailOpacity <= 1 ? value.cameraThumbnailOpacity : DEFAULT_CONFIG.cameraThumbnailOpacity;
6998
7005
  return {
6999
7006
  ...DEFAULT_CONFIG,
7000
7007
  ...value,
7001
7008
  siteCameras,
7002
- cameraThumbnail: image
7009
+ cameraThumbnail: image,
7010
+ cameraThumbnailOpacity: opacity
7003
7011
  };
7004
7012
  }
7005
7013
  function normalizeFloorData(data) {
@@ -58101,9 +58109,9 @@ var root_17$2 = /* @__PURE__ */ from_html(`<div class="text-[10px] text-gray-400
58101
58109
  var root_18$2 = /* @__PURE__ */ from_html(`<button> </button>`);
58102
58110
  var root_20$2 = /* @__PURE__ */ from_html(`<button draggable="true"><span role="button" tabindex="0"> </span> <div class="w-8 h-8 rounded-lg flex items-center justify-center"><div class="w-4 h-4 rounded-sm"></div></div> <span class="text-[10px] font-medium text-gray-600 leading-tight text-center"> </span></button>`);
58103
58111
  var root_19$2 = /* @__PURE__ */ from_html(`<div class="mt-1"><h4 class="text-[10px] font-semibold text-gray-400 uppercase mb-1.5">Recent</h4> <div class="grid grid-cols-2 gap-2"></div></div> <hr class="border-gray-100"/>`, 1);
58104
- var root_22$2 = /* @__PURE__ */ from_html(`<span class="text-xs font-medium text-gray-600"> <mark class="bg-yellow-200 text-gray-800 rounded-sm px-0.5"> </mark> </span>`);
58112
+ var root_22$1 = /* @__PURE__ */ from_html(`<span class="text-xs font-medium text-gray-600"> <mark class="bg-yellow-200 text-gray-800 rounded-sm px-0.5"> </mark> </span>`);
58105
58113
  var root_23$2 = /* @__PURE__ */ from_html(`<span class="text-xs font-medium text-gray-600"> </span>`);
58106
- var root_21$1 = /* @__PURE__ */ from_html(`<button draggable="true"><span role="button" tabindex="0"> </span> <div class="w-10 h-10 rounded-lg flex items-center justify-center"><div class="w-5 h-5 rounded-sm"></div></div> <!> <span class="text-[10px] text-gray-400"> </span></button>`);
58114
+ var root_21$2 = /* @__PURE__ */ from_html(`<button draggable="true"><span role="button" tabindex="0"> </span> <div class="w-10 h-10 rounded-lg flex items-center justify-center"><div class="w-5 h-5 rounded-sm"></div></div> <!> <span class="text-[10px] text-gray-400"> </span></button>`);
58107
58115
  var root_15$2 = /* @__PURE__ */ from_html(`<div class="space-y-2"><div class="relative"><input type="text" placeholder="Search furniture..." class="w-full px-3 py-2 pr-8 border border-gray-200 rounded-lg text-sm focus:ring-2 focus:ring-blue-200 focus:border-blue-400 outline-none"/> <!></div> <!> <div class="flex flex-wrap gap-1 max-h-24 overflow-y-auto"><button>All</button> <button> </button> <!></div> <!> <div class="grid grid-cols-2 gap-2 mt-2"></div></div>`);
58108
58116
  var root_24$2 = /* @__PURE__ */ from_html(`<div class="fixed z-50 pointer-events-none"><div class="bg-white rounded-xl shadow-2xl border border-gray-200 overflow-hidden" style="width: 220px;"><div class="w-full h-[120px] bg-gray-50 flex items-center justify-center p-3"><div class="w-16 h-16 rounded-xl flex items-center justify-center"><div class="w-10 h-10 rounded-md"></div></div></div> <div class="p-3 space-y-1.5"><div class="flex items-center gap-2"><span class="text-sm font-semibold text-gray-800"> </span> <span class="px-1.5 py-0.5 rounded-full text-[9px] font-semibold text-white"> </span></div> <div class="text-xs text-gray-500"> </div></div></div></div>`);
58109
58117
  var root_25$1 = /* @__PURE__ */ from_html(`<div class="fixed inset-0 bg-black/50 z-50 flex items-center justify-center"><div class="bg-white rounded-xl shadow-2xl w-80 p-5"><h3 class="text-sm font-bold text-gray-800 mb-1">Import RoomPlan</h3> <p class="text-xs text-gray-400 mb-4"> </p> <div class="space-y-3"><label class="flex items-start gap-2.5 cursor-pointer"><input type="checkbox" class="accent-blue-500 mt-0.5"/> <div><div class="text-sm font-medium text-gray-700">Straighten walls</div> <div class="text-xs text-gray-400">Snap near-horizontal/vertical walls to axis</div></div></label> <label class="flex items-start gap-2.5 cursor-pointer"><input type="checkbox" class="accent-blue-500 mt-0.5"/> <div><div class="text-sm font-medium text-gray-700">Enforce orthogonal <span class="text-xs text-blue-400 font-mono"> </span></div> <div class="text-xs text-gray-400">Force all walls to 90°/180° angles</div></div></label> <label class="block"><div class="text-xs text-gray-500 mb-1">Corner merge distance (cm)</div> <input type="number" min="0" max="50" step="5" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label></div> <div class="flex gap-2 mt-5"><button class="flex-1 px-3 py-2 border border-gray-200 rounded-lg text-sm text-gray-600 hover:bg-gray-50 transition-colors">Cancel</button> <button class="flex-1 px-3 py-2 bg-blue-500 text-white rounded-lg text-sm font-medium hover:bg-blue-600 transition-colors">Import</button></div></div></div>`);
@@ -58761,7 +58769,7 @@ function BuildPanel($$anchor, $$props) {
58761
58769
  var div_29 = sibling(node_6, 2);
58762
58770
  each(div_29, 21, () => get(filtered), index$1, ($$anchor, item) => {
58763
58771
  const s = /* @__PURE__ */ user_derived(() => get(search).toLowerCase());
58764
- var button_23 = root_21$1();
58772
+ var button_23 = root_21$2();
58765
58773
  var span_10 = child(button_23);
58766
58774
  var text_22 = child(span_10, true);
58767
58775
  reset(span_10);
@@ -58771,7 +58779,7 @@ function BuildPanel($$anchor, $$props) {
58771
58779
  var node_7 = sibling(div_30, 2);
58772
58780
  var consequent_12 = ($$anchor) => {
58773
58781
  const idx = /* @__PURE__ */ user_derived(() => get(item).name.toLowerCase().indexOf(get(s)));
58774
- var span_11 = root_22$2();
58782
+ var span_11 = root_22$1();
58775
58783
  var text_23 = child(span_11, true);
58776
58784
  var mark = sibling(text_23);
58777
58785
  var text_24 = child(mark, true);
@@ -59354,17 +59362,18 @@ var root_12$1 = /* @__PURE__ */ from_html(`<label class="block"><span class="tex
59354
59362
  var root_15$1 = /* @__PURE__ */ from_html(`<label class="block"><span class="text-xs text-gray-500">Camera Name</span> <input type="text" placeholder="Display name" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label> <label class="block"><span class="text-xs text-gray-500">Camera Serial</span> <input type="text" placeholder="Device serial" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label>`, 1);
59355
59363
  var root_16 = /* @__PURE__ */ from_html(`<button></button>`);
59356
59364
  var root_10$1 = /* @__PURE__ */ from_html(`<h3 class="text-sm font-semibold text-gray-700 mb-3 flex items-center gap-2"><span class="w-6 h-6 bg-purple-100 rounded flex items-center justify-center text-xs"> </span> <button> </button></h3> <div class="space-y-3"><!> <div><div class="flex items-center gap-1 mb-2"><span class="text-xs text-gray-500">Color</span> <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="text-gray-400"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect><circle cx="9" cy="9" r="2"></circle><path d="m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21"></path></svg></div> <div class="grid grid-cols-5 gap-1.5 mb-2"></div> <div class="flex items-center gap-2"><span class="text-xs text-gray-500">Custom:</span> <input type="color" class="w-8 h-6 rounded border border-gray-200 cursor-pointer"/></div></div> <label class="block"><span class="text-xs text-gray-500"> </span> <input type="number" min="1" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label> <label class="block"><span class="text-xs text-gray-500"> </span> <input type="number" min="1" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label> <label class="block"><span class="text-xs text-gray-500"> </span> <input type="number" min="1" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label> <label class="block"><span class="text-xs text-gray-500">Material</span> <select class="w-full px-2 py-1 border border-gray-200 rounded text-sm"><option>Wood</option><option>Metal</option><option>Fabric</option><option>Leather</option><option>Glass</option><option>Plastic</option><option>Stone</option><option>Ceramic</option></select></label> <label class="block"><span class="text-xs text-gray-500">Rotation (degrees)</span> <input type="number" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label> <div class="flex gap-1"><button class="flex-1 px-2 py-1.5 border border-gray-200 rounded text-sm hover:bg-gray-50 transition-colors" title="Rotate 90° left">↺ 90°</button> <button class="flex-1 px-2 py-1.5 border border-gray-200 rounded text-sm hover:bg-gray-50 transition-colors" title="Rotate 90° right">↻ 90°</button></div> <div class="flex gap-1"><button class="flex-1 px-2 py-1.5 border border-gray-200 rounded text-sm hover:bg-gray-50 transition-colors" title="Flip horizontally">↔ Flip H</button> <button class="flex-1 px-2 py-1.5 border border-gray-200 rounded text-sm hover:bg-gray-50 transition-colors" title="Flip vertically">↕ Flip V</button></div> <button class="w-full px-2 py-1.5 border border-gray-300 rounded text-sm text-gray-600 hover:bg-gray-50 transition-colors">Reset to defaults</button></div>`, 1);
59357
- var root_18$1 = /* @__PURE__ */ from_html(`<option> </option>`);
59358
- var root_19$1 = /* @__PURE__ */ from_html(`<button></button>`);
59359
- var root_22$1 = /* @__PURE__ */ from_html(`<button><div class="w-full h-12 rounded-md mb-1 overflow-hidden"></div> <div class="text-center leading-3 text-[10px] text-gray-600 truncate"> </div></button>`);
59360
- var root_20$1 = /* @__PURE__ */ from_html(`<div><span class="text-xs font-medium text-gray-600 mb-1.5 block"> </span> <div class="grid grid-cols-3 gap-1.5"></div></div>`);
59361
- var root_17$1 = /* @__PURE__ */ from_html(`<h3 class="text-sm font-semibold text-gray-700 mb-3 flex items-center gap-2"><span class="w-6 h-6 bg-green-100 rounded flex items-center justify-center text-xs">⬜</span> Room Properties</h3> <div class="space-y-3"><label class="block"><span class="text-xs text-gray-500">Room Type</span> <select class="w-full px-2 py-1 border border-gray-200 rounded text-sm"></select></label> <label class="block"><span class="text-xs text-gray-500">Room Name</span> <input type="text" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label> <label class="block"><span class="text-xs text-gray-500">Category</span> <select class="w-full px-2 py-1 border border-gray-200 rounded text-sm"><option>🏠 Indoor</option><option>🌳 Outdoor</option><option>🚗 Garage</option><option>🔧 Utility</option></select></label> <div><span class="text-xs text-gray-500">Area</span> <p class="text-sm text-gray-700"> </p></div> <div><span class="text-xs text-gray-500 mb-1.5 block">Room Color</span> <div class="grid grid-cols-5 gap-1.5 mb-2"></div> <div class="flex items-center gap-2"><span class="text-xs text-gray-500">Custom:</span> <input type="color" class="w-8 h-6 rounded border border-gray-200 cursor-pointer"/></div></div> <div><div class="flex items-center gap-1 mb-2"><span class="text-xs text-gray-500">Floor Material</span> <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="text-gray-400"><path d="M3 3h18v18H3z"></path><path d="M8 8h8v8H8z"></path></svg></div> <div class="space-y-3"></div></div></div>`, 1);
59362
- var root_23$1 = /* @__PURE__ */ from_html(`<h3 class="text-sm font-semibold text-gray-700 mb-3 flex items-center gap-2"><span class="w-6 h-6 bg-gray-200 rounded flex items-center justify-center text-xs">🪜</span> Stair Properties</h3> <div class="space-y-3"><label class="block"><span class="text-xs text-gray-500">Type</span> <select class="w-full px-2 py-1 border border-gray-200 rounded text-sm"><option>Straight</option><option>L-Shaped</option><option>U-Shaped</option><option>Spiral</option></select></label> <label class="block"><span class="text-xs text-gray-500"> </span> <input type="number" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label> <label class="block"><span class="text-xs text-gray-500"> </span> <input type="number" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label> <label class="block"><span class="text-xs text-gray-500">Risers</span> <input type="number" min="3" max="30" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label> <label class="block"><span class="text-xs text-gray-500">Direction</span> <div class="flex gap-2"><button>Up ↑</button> <button>Down ↓</button></div></label> <label class="block"><span class="text-xs text-gray-500">Rotation (degrees)</span> <input type="number" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label></div>`, 1);
59363
- var root_25 = /* @__PURE__ */ from_html(`<button></button>`);
59364
- var root_26 = /* @__PURE__ */ from_html(`<label class="block"><span class="text-xs text-gray-500">Rotation (degrees)</span> <input type="number" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label>`);
59365
- var root_24$1 = /* @__PURE__ */ from_html(`<h3 class="text-sm font-semibold text-gray-700 mb-3 flex items-center gap-2"><span class="w-6 h-6 bg-gray-200 rounded flex items-center justify-center text-xs">🏛️</span> Column Properties</h3> <div class="space-y-3"><label class="block"><span class="text-xs text-gray-500">Shape</span> <div class="flex gap-2"><button>⭕ Round</button> <button>⬜ Square</button></div></label> <label class="block"><span class="text-xs text-gray-500"> </span> <input type="number" min="10" max="200" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label> <label class="block"><span class="text-xs text-gray-500"> </span> <input type="number" min="50" max="1000" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label> <div><span class="text-xs text-gray-500 mb-1.5 block">Color</span> <div class="grid grid-cols-5 gap-1.5 mb-2"></div> <div class="flex items-center gap-2"><span class="text-xs text-gray-500">Custom:</span> <input type="color" class="w-8 h-6 rounded border border-gray-200 cursor-pointer"/></div></div> <!></div>`, 1);
59366
- var root_27 = /* @__PURE__ */ from_html(`<div class="space-y-3"><h3 class="text-sm font-semibold text-gray-700 mb-3 flex items-center gap-2"><span class="w-6 h-6 bg-emerald-100 rounded flex items-center justify-center text-xs">🏷️</span> Text Annotation</h3> <label class="block"><span class="text-xs text-gray-500">Text</span> <input type="text" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label> <label class="block"><span class="text-xs text-gray-500">Font Size</span> <input type="number" min="8" max="72" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label> <label class="block"><span class="text-xs text-gray-500">Color</span> <div class="flex items-center gap-2"><input type="color" class="w-8 h-6 rounded border border-gray-200 cursor-pointer"/> <span class="text-xs text-gray-400"> </span></div></label> <label class="block"><span class="text-xs text-gray-500">Rotation (°)</span> <input type="number" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label> <label class="block"><span class="text-xs text-gray-500">X</span> <input type="number" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label> <label class="block"><span class="text-xs text-gray-500">Y</span> <input type="number" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label></div>`);
59367
- var root_28 = /* @__PURE__ */ from_html(`<div class="mt-4 pt-3 border-t border-gray-200"><h3 class="text-sm font-semibold text-gray-700 mb-3 flex items-center gap-2"><span class="w-6 h-6 bg-blue-100 rounded flex items-center justify-center text-xs">🖼️</span> Background Image</h3> <div class="space-y-3"><label class="block"><span class="text-xs text-gray-500">Opacity</span> <input type="range" min="0.05" max="1" step="0.05" class="w-full"/></label> <label class="block"><span class="text-xs text-gray-500">Scale</span> <input type="range" min="0.1" max="5" step="0.05" class="w-full"/></label> <label class="block"><span class="text-xs text-gray-500">Rotation</span> <input type="number" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label> <div class="flex gap-2"><button> </button> <button class="flex-1 px-2 py-1.5 border rounded text-sm border-gray-200 hover:bg-gray-50">📏 Set Scale</button></div> <button class="w-full px-2 py-1.5 border border-red-300 rounded text-sm text-red-600 hover:bg-red-50">Remove Image</button></div></div>`);
59365
+ var root_18$1 = /* @__PURE__ */ from_html(`<label class="block pb-3 border-b border-gray-200"><span class="text-xs text-gray-500"> </span> <input type="range" min="0.05" max="1" step="0.05" class="w-full"/></label>`);
59366
+ var root_19$1 = /* @__PURE__ */ from_html(`<option> </option>`);
59367
+ var root_20$1 = /* @__PURE__ */ from_html(`<button></button>`);
59368
+ var root_23$1 = /* @__PURE__ */ from_html(`<button><div class="w-full h-12 rounded-md mb-1 overflow-hidden"></div> <div class="text-center leading-3 text-[10px] text-gray-600 truncate"> </div></button>`);
59369
+ var root_21$1 = /* @__PURE__ */ from_html(`<div><span class="text-xs font-medium text-gray-600 mb-1.5 block"> </span> <div class="grid grid-cols-3 gap-1.5"></div></div>`);
59370
+ var root_17$1 = /* @__PURE__ */ from_html(`<h3 class="text-sm font-semibold text-gray-700 mb-3 flex items-center gap-2"><span class="w-6 h-6 bg-green-100 rounded flex items-center justify-center text-xs">⬜</span> Room Properties</h3> <div class="space-y-3"><!> <label class="block"><span class="text-xs text-gray-500">Room Type</span> <select class="w-full px-2 py-1 border border-gray-200 rounded text-sm"></select></label> <label class="block"><span class="text-xs text-gray-500">Room Name</span> <input type="text" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label> <label class="block"><span class="text-xs text-gray-500">Category</span> <select class="w-full px-2 py-1 border border-gray-200 rounded text-sm"><option>🏠 Indoor</option><option>🌳 Outdoor</option><option>🚗 Garage</option><option>🔧 Utility</option></select></label> <div><span class="text-xs text-gray-500">Area</span> <p class="text-sm text-gray-700"> </p></div> <div><span class="text-xs text-gray-500 mb-1.5 block">Room Color</span> <div class="grid grid-cols-5 gap-1.5 mb-2"></div> <div class="flex items-center gap-2"><span class="text-xs text-gray-500">Custom:</span> <input type="color" class="w-8 h-6 rounded border border-gray-200 cursor-pointer"/></div></div> <div><div class="flex items-center gap-1 mb-2"><span class="text-xs text-gray-500">Floor Material</span> <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="text-gray-400"><path d="M3 3h18v18H3z"></path><path d="M8 8h8v8H8z"></path></svg></div> <div class="space-y-3"></div></div></div>`, 1);
59371
+ var root_24$1 = /* @__PURE__ */ from_html(`<h3 class="text-sm font-semibold text-gray-700 mb-3 flex items-center gap-2"><span class="w-6 h-6 bg-gray-200 rounded flex items-center justify-center text-xs">🪜</span> Stair Properties</h3> <div class="space-y-3"><label class="block"><span class="text-xs text-gray-500">Type</span> <select class="w-full px-2 py-1 border border-gray-200 rounded text-sm"><option>Straight</option><option>L-Shaped</option><option>U-Shaped</option><option>Spiral</option></select></label> <label class="block"><span class="text-xs text-gray-500"> </span> <input type="number" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label> <label class="block"><span class="text-xs text-gray-500"> </span> <input type="number" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label> <label class="block"><span class="text-xs text-gray-500">Risers</span> <input type="number" min="3" max="30" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label> <label class="block"><span class="text-xs text-gray-500">Direction</span> <div class="flex gap-2"><button>Up ↑</button> <button>Down ↓</button></div></label> <label class="block"><span class="text-xs text-gray-500">Rotation (degrees)</span> <input type="number" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label></div>`, 1);
59372
+ var root_26 = /* @__PURE__ */ from_html(`<button></button>`);
59373
+ var root_27 = /* @__PURE__ */ from_html(`<label class="block"><span class="text-xs text-gray-500">Rotation (degrees)</span> <input type="number" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label>`);
59374
+ var root_25 = /* @__PURE__ */ from_html(`<h3 class="text-sm font-semibold text-gray-700 mb-3 flex items-center gap-2"><span class="w-6 h-6 bg-gray-200 rounded flex items-center justify-center text-xs">🏛️</span> Column Properties</h3> <div class="space-y-3"><label class="block"><span class="text-xs text-gray-500">Shape</span> <div class="flex gap-2"><button>⭕ Round</button> <button>⬜ Square</button></div></label> <label class="block"><span class="text-xs text-gray-500"> </span> <input type="number" min="10" max="200" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label> <label class="block"><span class="text-xs text-gray-500"> </span> <input type="number" min="50" max="1000" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label> <div><span class="text-xs text-gray-500 mb-1.5 block">Color</span> <div class="grid grid-cols-5 gap-1.5 mb-2"></div> <div class="flex items-center gap-2"><span class="text-xs text-gray-500">Custom:</span> <input type="color" class="w-8 h-6 rounded border border-gray-200 cursor-pointer"/></div></div> <!></div>`, 1);
59375
+ var root_28 = /* @__PURE__ */ from_html(`<div class="space-y-3"><h3 class="text-sm font-semibold text-gray-700 mb-3 flex items-center gap-2"><span class="w-6 h-6 bg-emerald-100 rounded flex items-center justify-center text-xs">🏷️</span> Text Annotation</h3> <label class="block"><span class="text-xs text-gray-500">Text</span> <input type="text" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label> <label class="block"><span class="text-xs text-gray-500">Font Size</span> <input type="number" min="8" max="72" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label> <label class="block"><span class="text-xs text-gray-500">Color</span> <div class="flex items-center gap-2"><input type="color" class="w-8 h-6 rounded border border-gray-200 cursor-pointer"/> <span class="text-xs text-gray-400"> </span></div></label> <label class="block"><span class="text-xs text-gray-500">Rotation (°)</span> <input type="number" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label> <label class="block"><span class="text-xs text-gray-500">X</span> <input type="number" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label> <label class="block"><span class="text-xs text-gray-500">Y</span> <input type="number" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label></div>`);
59376
+ var root_29 = /* @__PURE__ */ from_html(`<div class="mt-4 pt-3 border-t border-gray-200"><h3 class="text-sm font-semibold text-gray-700 mb-3 flex items-center gap-2"><span class="w-6 h-6 bg-blue-100 rounded flex items-center justify-center text-xs">🖼️</span> Background Image</h3> <div class="space-y-3"><label class="block"><span class="text-xs text-gray-500">Opacity</span> <input type="range" min="0.05" max="1" step="0.05" class="w-full"/></label> <label class="block"><span class="text-xs text-gray-500">Scale</span> <input type="range" min="0.1" max="5" step="0.05" class="w-full"/></label> <label class="block"><span class="text-xs text-gray-500">Rotation</span> <input type="number" class="w-full px-2 py-1 border border-gray-200 rounded text-sm"/></label> <div class="flex gap-2"><button> </button> <button class="flex-1 px-2 py-1.5 border rounded text-sm border-gray-200 hover:bg-gray-50">📏 Set Scale</button></div> <button class="w-full px-2 py-1.5 border border-red-300 rounded text-sm text-red-600 hover:bg-red-50">Remove Image</button></div></div>`);
59368
59377
  var root$3 = /* @__PURE__ */ from_html(`<div data-properties-panel="" style="top: 48px; bottom: 36px;"><!> <!></div>`);
59369
59378
  function PropertiesPanel($$anchor, $$props) {
59370
59379
  push($$props, true);
@@ -59402,7 +59411,7 @@ function PropertiesPanel($$anchor, $$props) {
59402
59411
  function unitLabel() {
59403
59412
  return get(settings).units === "imperial" ? "in" : "cm";
59404
59413
  }
59405
- let is3D = prop($$props, "is3D", 3, false), siteCameras = prop($$props, "siteCameras", 19, () => []);
59414
+ let is3D = prop($$props, "is3D", 3, false), siteCameras = prop($$props, "siteCameras", 19, () => []), cameraThumbnail = prop($$props, "cameraThumbnail", 3, "");
59406
59415
  let wallSideTab = /* @__PURE__ */ state("interior");
59407
59416
  let selectedWall = /* @__PURE__ */ user_derived(() => {
59408
59417
  var _$$get$walls$find, _$$get;
@@ -59436,17 +59445,25 @@ function PropertiesPanel($$anchor, $$props) {
59436
59445
  var _$$get8;
59437
59446
  return !!((_$$get8 = get(floor)) === null || _$$get8 === void 0 ? void 0 : _$$get8.backgroundImage);
59438
59447
  });
59448
+ let hasCameraThumbnailOverlay = /* @__PURE__ */ user_derived(() => {
59449
+ var _cameraThumbnail, _$$get9;
59450
+ return !!((_cameraThumbnail = cameraThumbnail()) === null || _cameraThumbnail === void 0 ? void 0 : _cameraThumbnail.trim()) && !((_$$get9 = get(floor)) === null || _$$get9 === void 0 ? void 0 : _$$get9.backgroundImage);
59451
+ });
59452
+ let thumbOpacity = /* @__PURE__ */ state(.65);
59453
+ cameraThumbnailOpacity.subscribe((v) => {
59454
+ set(thumbOpacity, v, true);
59455
+ });
59439
59456
  let selectedRoom = /* @__PURE__ */ user_derived(() => {
59440
- var _ref, _$$get$rooms$find, _$$get9;
59441
- return (_ref = (_$$get$rooms$find = (_$$get9 = get(floor)) === null || _$$get9 === void 0 || (_$$get9 = _$$get9.rooms) === null || _$$get9 === void 0 ? void 0 : _$$get9.find((r) => r.id === get(selRoomId))) !== null && _$$get$rooms$find !== void 0 ? _$$get$rooms$find : get(detectedRooms).find((r) => r.id === get(selRoomId))) !== null && _ref !== void 0 ? _ref : null;
59457
+ var _ref, _$$get$rooms$find, _$$get10;
59458
+ return (_ref = (_$$get$rooms$find = (_$$get10 = get(floor)) === null || _$$get10 === void 0 || (_$$get10 = _$$get10.rooms) === null || _$$get10 === void 0 ? void 0 : _$$get10.find((r) => r.id === get(selRoomId))) !== null && _$$get$rooms$find !== void 0 ? _$$get$rooms$find : get(detectedRooms).find((r) => r.id === get(selRoomId))) !== null && _ref !== void 0 ? _ref : null;
59442
59459
  });
59443
59460
  let selectedDoorWall = /* @__PURE__ */ user_derived(() => {
59444
- var _ref2, _$$get10;
59445
- return (_ref2 = get(selectedDoor) && ((_$$get10 = get(floor)) === null || _$$get10 === void 0 || (_$$get10 = _$$get10.walls) === null || _$$get10 === void 0 ? void 0 : _$$get10.find((w) => w.id === get(selectedDoor).wallId))) !== null && _ref2 !== void 0 ? _ref2 : null;
59461
+ var _ref2, _$$get11;
59462
+ return (_ref2 = get(selectedDoor) && ((_$$get11 = get(floor)) === null || _$$get11 === void 0 || (_$$get11 = _$$get11.walls) === null || _$$get11 === void 0 ? void 0 : _$$get11.find((w) => w.id === get(selectedDoor).wallId))) !== null && _ref2 !== void 0 ? _ref2 : null;
59446
59463
  });
59447
59464
  let selectedWindowWall = /* @__PURE__ */ user_derived(() => {
59448
- var _ref3, _$$get11;
59449
- return (_ref3 = get(selectedWindow) && ((_$$get11 = get(floor)) === null || _$$get11 === void 0 || (_$$get11 = _$$get11.walls) === null || _$$get11 === void 0 ? void 0 : _$$get11.find((w) => w.id === get(selectedWindow).wallId))) !== null && _ref3 !== void 0 ? _ref3 : null;
59465
+ var _ref3, _$$get12;
59466
+ return (_ref3 = get(selectedWindow) && ((_$$get12 = get(floor)) === null || _$$get12 === void 0 || (_$$get12 = _$$get12.walls) === null || _$$get12 === void 0 ? void 0 : _$$get12.find((w) => w.id === get(selectedWindow).wallId))) !== null && _ref3 !== void 0 ? _ref3 : null;
59450
59467
  });
59451
59468
  function calcWallLength(wall) {
59452
59469
  if (wall.curvePoint) {
@@ -59543,9 +59560,9 @@ function PropertiesPanel($$anchor, $$props) {
59543
59560
  }
59544
59561
  const useSiteCameraSelect = /* @__PURE__ */ user_derived(() => siteCameras().length > 0);
59545
59562
  const usedCameraSerials = /* @__PURE__ */ user_derived(() => {
59546
- var _$$get12;
59563
+ var _$$get13;
59547
59564
  const used = /* @__PURE__ */ new Set();
59548
- if (!((_$$get12 = get(floor)) === null || _$$get12 === void 0 ? void 0 : _$$get12.furniture) || !get(selectedFurniture)) return used;
59565
+ if (!((_$$get13 = get(floor)) === null || _$$get13 === void 0 ? void 0 : _$$get13.furniture) || !get(selectedFurniture)) return used;
59549
59566
  for (const item of get(floor).furniture) {
59550
59567
  if (item.catalogId !== "camera" || item.id === get(selectedFurniture).id) continue;
59551
59568
  if (item.serial) used.add(item.serial);
@@ -60132,7 +60149,7 @@ function PropertiesPanel($$anchor, $$props) {
60132
60149
  reset(label_11);
60133
60150
  reset(div_11);
60134
60151
  template_effect(($0, $1, $2, $3, $4, $5, $6, $7) => {
60135
- var _$$get13, _$$get14, _$$get15, _$$get16;
60152
+ var _$$get14, _$$get15, _$$get16, _$$get17;
60136
60153
  set_text(text_6, `Width (${$0 !== null && $0 !== void 0 ? $0 : ""})`);
60137
60154
  set_value(input_5, $1);
60138
60155
  set_text(text_7, `Distance from A (${$2 !== null && $2 !== void 0 ? $2 : ""})`);
@@ -60145,10 +60162,10 @@ function PropertiesPanel($$anchor, $$props) {
60145
60162
  var _select$__value;
60146
60163
  select.value = (_select$__value = select.__value = get(selectedDoor).type) !== null && _select$__value !== void 0 ? _select$__value : "", select_option(select, get(selectedDoor).type);
60147
60164
  }
60148
- set_class(button_9, 1, `flex-1 px-2 py-1.5 border rounded text-sm transition-colors ${((_$$get13 = get(selectedDoor)) === null || _$$get13 === void 0 ? void 0 : _$$get13.swingDirection) === "left" ? "bg-blue-100 border-blue-400 text-blue-700" : "border-gray-200 hover:bg-gray-50"}`);
60149
- set_class(button_10, 1, `flex-1 px-2 py-1.5 border rounded text-sm transition-colors ${((_$$get14 = get(selectedDoor)) === null || _$$get14 === void 0 ? void 0 : _$$get14.swingDirection) === "right" ? "bg-blue-100 border-blue-400 text-blue-700" : "border-gray-200 hover:bg-gray-50"}`);
60150
- set_class(button_11, 1, `flex-1 px-2 py-1.5 border rounded text-sm transition-colors ${!((_$$get15 = get(selectedDoor)) === null || _$$get15 === void 0 ? void 0 : _$$get15.flipSide) ? "bg-blue-100 border-blue-400 text-blue-700" : "border-gray-200 hover:bg-gray-50"}`);
60151
- set_class(button_12, 1, `flex-1 px-2 py-1.5 border rounded text-sm transition-colors ${((_$$get16 = get(selectedDoor)) === null || _$$get16 === void 0 ? void 0 : _$$get16.flipSide) ? "bg-blue-100 border-blue-400 text-blue-700" : "border-gray-200 hover:bg-gray-50"}`);
60165
+ set_class(button_9, 1, `flex-1 px-2 py-1.5 border rounded text-sm transition-colors ${((_$$get14 = get(selectedDoor)) === null || _$$get14 === void 0 ? void 0 : _$$get14.swingDirection) === "left" ? "bg-blue-100 border-blue-400 text-blue-700" : "border-gray-200 hover:bg-gray-50"}`);
60166
+ set_class(button_10, 1, `flex-1 px-2 py-1.5 border rounded text-sm transition-colors ${((_$$get15 = get(selectedDoor)) === null || _$$get15 === void 0 ? void 0 : _$$get15.swingDirection) === "right" ? "bg-blue-100 border-blue-400 text-blue-700" : "border-gray-200 hover:bg-gray-50"}`);
60167
+ set_class(button_11, 1, `flex-1 px-2 py-1.5 border rounded text-sm transition-colors ${!((_$$get16 = get(selectedDoor)) === null || _$$get16 === void 0 ? void 0 : _$$get16.flipSide) ? "bg-blue-100 border-blue-400 text-blue-700" : "border-gray-200 hover:bg-gray-50"}`);
60168
+ set_class(button_12, 1, `flex-1 px-2 py-1.5 border rounded text-sm transition-colors ${((_$$get17 = get(selectedDoor)) === null || _$$get17 === void 0 ? void 0 : _$$get17.flipSide) ? "bg-blue-100 border-blue-400 text-blue-700" : "border-gray-200 hover:bg-gray-50"}`);
60152
60169
  }, [
60153
60170
  () => unitLabel(),
60154
60171
  () => displayValue(get(selectedDoor).width),
@@ -60540,19 +60557,38 @@ function PropertiesPanel($$anchor, $$props) {
60540
60557
  delegated("click", button_19, resetFurnitureDefaults);
60541
60558
  append($$anchor, fragment_3);
60542
60559
  };
60543
- var consequent_9 = ($$anchor) => {
60560
+ var consequent_10 = ($$anchor) => {
60544
60561
  var fragment_7 = root_17$1();
60545
60562
  var div_21 = sibling(first_child(fragment_7), 2);
60546
- var label_26 = child(div_21);
60547
- var select_4 = sibling(child(label_26), 2);
60563
+ var node_8 = child(div_21);
60564
+ var consequent_8 = ($$anchor) => {
60565
+ var label_26 = root_18$1();
60566
+ var span_19 = child(label_26);
60567
+ var text_23 = child(span_19);
60568
+ reset(span_19);
60569
+ var input_21 = sibling(span_19, 2);
60570
+ remove_input_defaults(input_21);
60571
+ reset(label_26);
60572
+ template_effect(($0) => {
60573
+ set_text(text_23, `Camera Thumbnail Opacity (${$0 !== null && $0 !== void 0 ? $0 : ""}%)`);
60574
+ set_value(input_21, get(thumbOpacity));
60575
+ }, [() => Math.round(get(thumbOpacity) * 100)]);
60576
+ delegated("input", input_21, (e) => updateCameraThumbnailOpacity(Number(e.target.value)));
60577
+ append($$anchor, label_26);
60578
+ };
60579
+ if_block(node_8, ($$render) => {
60580
+ if (get(hasCameraThumbnailOverlay)) $$render(consequent_8);
60581
+ });
60582
+ var label_27 = sibling(node_8, 2);
60583
+ var select_4 = sibling(child(label_27), 2);
60548
60584
  each(select_4, 21, () => roomTypes, index$1, ($$anchor, rt) => {
60549
- var option_21 = root_18$1();
60550
- var text_23 = child(option_21);
60585
+ var option_21 = root_19$1();
60586
+ var text_24 = child(option_21);
60551
60587
  reset(option_21);
60552
60588
  var option_21_value = {};
60553
60589
  template_effect(() => {
60554
60590
  var _$$get$icon, _$$get$label;
60555
- set_text(text_23, `${(_$$get$icon = get(rt).icon) !== null && _$$get$icon !== void 0 ? _$$get$icon : ""} ${(_$$get$label = get(rt).label) !== null && _$$get$label !== void 0 ? _$$get$label : ""}`);
60591
+ set_text(text_24, `${(_$$get$icon = get(rt).icon) !== null && _$$get$icon !== void 0 ? _$$get$icon : ""} ${(_$$get$label = get(rt).label) !== null && _$$get$label !== void 0 ? _$$get$label : ""}`);
60556
60592
  if (option_21_value !== (option_21_value = get(rt).id)) {
60557
60593
  var _option_21$__value;
60558
60594
  option_21.value = (_option_21$__value = option_21.__value = get(rt).id) !== null && _option_21$__value !== void 0 ? _option_21$__value : "";
@@ -60563,13 +60599,13 @@ function PropertiesPanel($$anchor, $$props) {
60563
60599
  reset(select_4);
60564
60600
  var select_4_value;
60565
60601
  init_select(select_4);
60566
- reset(label_26);
60567
- var label_27 = sibling(label_26, 2);
60568
- var input_21 = sibling(child(label_27), 2);
60569
- remove_input_defaults(input_21);
60570
60602
  reset(label_27);
60571
60603
  var label_28 = sibling(label_27, 2);
60572
- var select_5 = sibling(child(label_28), 2);
60604
+ var input_22 = sibling(child(label_28), 2);
60605
+ remove_input_defaults(input_22);
60606
+ reset(label_28);
60607
+ var label_29 = sibling(label_28, 2);
60608
+ var select_5 = sibling(child(label_29), 2);
60573
60609
  var option_22 = child(select_5);
60574
60610
  option_22.value = option_22.__value = "indoor";
60575
60611
  var option_23 = sibling(option_22);
@@ -60581,16 +60617,16 @@ function PropertiesPanel($$anchor, $$props) {
60581
60617
  reset(select_5);
60582
60618
  var select_5_value;
60583
60619
  init_select(select_5);
60584
- reset(label_28);
60585
- var div_22 = sibling(label_28, 2);
60620
+ reset(label_29);
60621
+ var div_22 = sibling(label_29, 2);
60586
60622
  var p_1 = sibling(child(div_22), 2);
60587
- var text_24 = child(p_1, true);
60623
+ var text_25 = child(p_1, true);
60588
60624
  reset(p_1);
60589
60625
  reset(div_22);
60590
60626
  var div_23 = sibling(div_22, 2);
60591
60627
  var div_24 = sibling(child(div_23), 2);
60592
60628
  each(div_24, 21, () => roomColorPresets, index$1, ($$anchor, preset) => {
60593
- var button_20 = root_19$1();
60629
+ var button_20 = root_20$1();
60594
60630
  template_effect(() => {
60595
60631
  var _$$get$color5;
60596
60632
  set_class(button_20, 1, `w-7 h-7 rounded-md border-2 hover:border-gray-300 transition-colors ${get(selectedRoom).color === get(preset).color ? "border-blue-500 ring-1 ring-blue-200" : "border-gray-200"}`);
@@ -60602,50 +60638,50 @@ function PropertiesPanel($$anchor, $$props) {
60602
60638
  });
60603
60639
  reset(div_24);
60604
60640
  var div_25 = sibling(div_24, 2);
60605
- var input_22 = sibling(child(div_25), 2);
60606
- remove_input_defaults(input_22);
60641
+ var input_23 = sibling(child(div_25), 2);
60642
+ remove_input_defaults(input_23);
60607
60643
  reset(div_25);
60608
60644
  reset(div_23);
60609
60645
  var div_26 = sibling(div_23, 2);
60610
60646
  var div_27 = sibling(child(div_26), 2);
60611
60647
  each(div_27, 21, () => textureGroups, index$1, ($$anchor, group) => {
60612
- var div_28 = root_20$1();
60613
- var span_19 = child(div_28);
60614
- var text_25 = child(span_19, true);
60615
- reset(span_19);
60616
- var div_29 = sibling(span_19, 2);
60648
+ var div_28 = root_21$1();
60649
+ var span_20 = child(div_28);
60650
+ var text_26 = child(span_20, true);
60651
+ reset(span_20);
60652
+ var div_29 = sibling(span_20, 2);
60617
60653
  each(div_29, 21, () => get(group).ids, index$1, ($$anchor, matId) => {
60618
60654
  const mat = /* @__PURE__ */ user_derived(() => floorMaterials.find((m) => m.id === get(matId)));
60619
60655
  var fragment_8 = comment();
60620
- var node_8 = first_child(fragment_8);
60621
- var consequent_8 = ($$anchor) => {
60656
+ var node_9 = first_child(fragment_8);
60657
+ var consequent_9 = ($$anchor) => {
60622
60658
  const texPath = /* @__PURE__ */ user_derived(() => {
60623
60659
  var _floorTexPaths$$$get$;
60624
60660
  return (_floorTexPaths$$$get$ = floorTexPaths[get(mat).id]) !== null && _floorTexPaths$$$get$ !== void 0 ? _floorTexPaths$$$get$ : "";
60625
60661
  });
60626
- var button_21 = root_22$1();
60662
+ var button_21 = root_23$1();
60627
60663
  var div_30 = child(button_21);
60628
60664
  var div_31 = sibling(div_30, 2);
60629
- var text_26 = child(div_31, true);
60665
+ var text_27 = child(div_31, true);
60630
60666
  reset(div_31);
60631
60667
  reset(button_21);
60632
60668
  template_effect(() => {
60633
60669
  set_class(button_21, 1, `p-1 rounded-lg border-2 hover:border-gray-300 transition-all text-xs ${get(selectedRoom).floorTexture === get(mat).id ? "border-blue-500 ring-2 ring-blue-200 shadow-sm" : "border-gray-200"}`);
60634
60670
  set_attribute(button_21, "title", get(mat).name);
60635
60671
  set_style(div_30, get(texPath) ? `background-image: url(${get(texPath)}); background-size: cover; background-position: center;` : `background-color: ${get(mat).color}`);
60636
- set_text(text_26, get(mat).name);
60672
+ set_text(text_27, get(mat).name);
60637
60673
  });
60638
60674
  delegated("click", button_21, () => onRoomFloor(get(mat).id));
60639
60675
  append($$anchor, button_21);
60640
60676
  };
60641
- if_block(node_8, ($$render) => {
60642
- if (get(mat)) $$render(consequent_8);
60677
+ if_block(node_9, ($$render) => {
60678
+ if (get(mat)) $$render(consequent_9);
60643
60679
  });
60644
60680
  append($$anchor, fragment_8);
60645
60681
  });
60646
60682
  reset(div_29);
60647
60683
  reset(div_28);
60648
- template_effect(() => set_text(text_25, get(group).label));
60684
+ template_effect(() => set_text(text_26, get(group).label));
60649
60685
  append($$anchor, div_28);
60650
60686
  });
60651
60687
  reset(div_27);
@@ -60657,16 +60693,16 @@ function PropertiesPanel($$anchor, $$props) {
60657
60693
  var _select_4$__value;
60658
60694
  select_4.value = (_select_4$__value = select_4.__value = get(selectedRoomType)) !== null && _select_4$__value !== void 0 ? _select_4$__value : "", select_option(select_4, get(selectedRoomType));
60659
60695
  }
60660
- set_value(input_21, get(selectedRoom).name);
60696
+ set_value(input_22, get(selectedRoom).name);
60661
60697
  if (select_5_value !== (select_5_value = (_$$get$roomType = get(selectedRoom).roomType) !== null && _$$get$roomType !== void 0 ? _$$get$roomType : "indoor")) {
60662
60698
  var _select_5$__value, _$$get$roomType2, _$$get$roomType3;
60663
60699
  select_5.value = (_select_5$__value = select_5.__value = (_$$get$roomType2 = get(selectedRoom).roomType) !== null && _$$get$roomType2 !== void 0 ? _$$get$roomType2 : "indoor") !== null && _select_5$__value !== void 0 ? _select_5$__value : "", select_option(select_5, (_$$get$roomType3 = get(selectedRoom).roomType) !== null && _$$get$roomType3 !== void 0 ? _$$get$roomType3 : "indoor");
60664
60700
  }
60665
- set_text(text_24, $0);
60666
- set_value(input_22, (_$$get$color6 = get(selectedRoom).color) !== null && _$$get$color6 !== void 0 ? _$$get$color6 : "#ffffff");
60701
+ set_text(text_25, $0);
60702
+ set_value(input_23, (_$$get$color6 = get(selectedRoom).color) !== null && _$$get$color6 !== void 0 ? _$$get$color6 : "#ffffff");
60667
60703
  }, [() => formatArea(get(selectedRoom).area, get(settings).units)]);
60668
60704
  delegated("change", select_4, onRoomType);
60669
- delegated("input", input_21, onRoomName);
60705
+ delegated("input", input_22, onRoomName);
60670
60706
  delegated("change", select_5, (e) => {
60671
60707
  if (get(selectedRoom)) {
60672
60708
  const v = e.target.value;
@@ -60674,14 +60710,14 @@ function PropertiesPanel($$anchor, $$props) {
60674
60710
  updateDetectedRoom(get(selectedRoom).id, { roomType: v });
60675
60711
  }
60676
60712
  });
60677
- delegated("input", input_22, (e) => onRoomColor(e.target.value));
60713
+ delegated("input", input_23, (e) => onRoomColor(e.target.value));
60678
60714
  append($$anchor, fragment_7);
60679
60715
  };
60680
- var consequent_10 = ($$anchor) => {
60681
- var fragment_9 = root_23$1();
60716
+ var consequent_11 = ($$anchor) => {
60717
+ var fragment_9 = root_24$1();
60682
60718
  var div_32 = sibling(first_child(fragment_9), 2);
60683
- var label_29 = child(div_32);
60684
- var select_6 = sibling(child(label_29), 2);
60719
+ var label_30 = child(div_32);
60720
+ var select_6 = sibling(child(label_30), 2);
60685
60721
  var option_26 = child(select_6);
60686
60722
  option_26.value = option_26.__value = "straight";
60687
60723
  var option_27 = sibling(option_26);
@@ -60693,13 +60729,6 @@ function PropertiesPanel($$anchor, $$props) {
60693
60729
  reset(select_6);
60694
60730
  var select_6_value;
60695
60731
  init_select(select_6);
60696
- reset(label_29);
60697
- var label_30 = sibling(label_29, 2);
60698
- var span_20 = child(label_30);
60699
- var text_27 = child(span_20);
60700
- reset(span_20);
60701
- var input_23 = sibling(span_20, 2);
60702
- remove_input_defaults(input_23);
60703
60732
  reset(label_30);
60704
60733
  var label_31 = sibling(label_30, 2);
60705
60734
  var span_21 = child(label_31);
@@ -60709,33 +60738,40 @@ function PropertiesPanel($$anchor, $$props) {
60709
60738
  remove_input_defaults(input_24);
60710
60739
  reset(label_31);
60711
60740
  var label_32 = sibling(label_31, 2);
60712
- var input_25 = sibling(child(label_32), 2);
60741
+ var span_22 = child(label_32);
60742
+ var text_29 = child(span_22);
60743
+ reset(span_22);
60744
+ var input_25 = sibling(span_22, 2);
60713
60745
  remove_input_defaults(input_25);
60714
60746
  reset(label_32);
60715
60747
  var label_33 = sibling(label_32, 2);
60716
- var div_33 = sibling(child(label_33), 2);
60748
+ var input_26 = sibling(child(label_33), 2);
60749
+ remove_input_defaults(input_26);
60750
+ reset(label_33);
60751
+ var label_34 = sibling(label_33, 2);
60752
+ var div_33 = sibling(child(label_34), 2);
60717
60753
  var button_22 = child(div_33);
60718
60754
  var button_23 = sibling(button_22, 2);
60719
60755
  reset(div_33);
60720
- reset(label_33);
60721
- var label_34 = sibling(label_33, 2);
60722
- var input_26 = sibling(child(label_34), 2);
60723
- remove_input_defaults(input_26);
60724
60756
  reset(label_34);
60757
+ var label_35 = sibling(label_34, 2);
60758
+ var input_27 = sibling(child(label_35), 2);
60759
+ remove_input_defaults(input_27);
60760
+ reset(label_35);
60725
60761
  reset(div_32);
60726
60762
  template_effect(($0, $1, $2, $3) => {
60727
60763
  if (select_6_value !== (select_6_value = get(selectedStair).stairType || "straight")) {
60728
60764
  var _select_6$__value;
60729
60765
  select_6.value = (_select_6$__value = select_6.__value = get(selectedStair).stairType || "straight") !== null && _select_6$__value !== void 0 ? _select_6$__value : "", select_option(select_6, get(selectedStair).stairType || "straight");
60730
60766
  }
60731
- set_text(text_27, `Width (${$0 !== null && $0 !== void 0 ? $0 : ""})`);
60732
- set_value(input_23, $1);
60733
- set_text(text_28, `Depth (${$2 !== null && $2 !== void 0 ? $2 : ""})`);
60734
- set_value(input_24, $3);
60735
- set_value(input_25, get(selectedStair).riserCount);
60767
+ set_text(text_28, `Width (${$0 !== null && $0 !== void 0 ? $0 : ""})`);
60768
+ set_value(input_24, $1);
60769
+ set_text(text_29, `Depth (${$2 !== null && $2 !== void 0 ? $2 : ""})`);
60770
+ set_value(input_25, $3);
60771
+ set_value(input_26, get(selectedStair).riserCount);
60736
60772
  set_class(button_22, 1, `flex-1 px-2 py-1.5 border rounded text-sm transition-colors ${get(selectedStair).direction === "up" ? "bg-blue-100 border-blue-400 text-blue-700" : "border-gray-200 hover:bg-gray-50"}`);
60737
60773
  set_class(button_23, 1, `flex-1 px-2 py-1.5 border rounded text-sm transition-colors ${get(selectedStair).direction === "down" ? "bg-blue-100 border-blue-400 text-blue-700" : "border-gray-200 hover:bg-gray-50"}`);
60738
- set_value(input_26, get(selectedStair).rotation);
60774
+ set_value(input_27, get(selectedStair).rotation);
60739
60775
  }, [
60740
60776
  () => unitLabel(),
60741
60777
  () => displayValue(get(selectedStair).width),
@@ -60743,29 +60779,22 @@ function PropertiesPanel($$anchor, $$props) {
60743
60779
  () => displayValue(get(selectedStair).depth)
60744
60780
  ]);
60745
60781
  delegated("change", select_6, (e) => updateStair(get(selectedStair).id, { stairType: e.target.value }));
60746
- delegated("input", input_23, (e) => updateStair(get(selectedStair).id, { width: inputToCm(Number(e.target.value)) }));
60747
- delegated("input", input_24, (e) => updateStair(get(selectedStair).id, { depth: inputToCm(Number(e.target.value)) }));
60748
- delegated("input", input_25, (e) => updateStair(get(selectedStair).id, { riserCount: Number(e.target.value) }));
60782
+ delegated("input", input_24, (e) => updateStair(get(selectedStair).id, { width: inputToCm(Number(e.target.value)) }));
60783
+ delegated("input", input_25, (e) => updateStair(get(selectedStair).id, { depth: inputToCm(Number(e.target.value)) }));
60784
+ delegated("input", input_26, (e) => updateStair(get(selectedStair).id, { riserCount: Number(e.target.value) }));
60749
60785
  delegated("click", button_22, () => updateStair(get(selectedStair).id, { direction: "up" }));
60750
60786
  delegated("click", button_23, () => updateStair(get(selectedStair).id, { direction: "down" }));
60751
- delegated("input", input_26, (e) => updateStair(get(selectedStair).id, { rotation: Number(e.target.value) }));
60787
+ delegated("input", input_27, (e) => updateStair(get(selectedStair).id, { rotation: Number(e.target.value) }));
60752
60788
  append($$anchor, fragment_9);
60753
60789
  };
60754
- var consequent_12 = ($$anchor) => {
60755
- var fragment_10 = root_24$1();
60790
+ var consequent_13 = ($$anchor) => {
60791
+ var fragment_10 = root_25();
60756
60792
  var div_34 = sibling(first_child(fragment_10), 2);
60757
- var label_35 = child(div_34);
60758
- var div_35 = sibling(child(label_35), 2);
60793
+ var label_36 = child(div_34);
60794
+ var div_35 = sibling(child(label_36), 2);
60759
60795
  var button_24 = child(div_35);
60760
60796
  var button_25 = sibling(button_24, 2);
60761
60797
  reset(div_35);
60762
- reset(label_35);
60763
- var label_36 = sibling(label_35, 2);
60764
- var span_22 = child(label_36);
60765
- var text_29 = child(span_22);
60766
- reset(span_22);
60767
- var input_27 = sibling(span_22, 2);
60768
- remove_input_defaults(input_27);
60769
60798
  reset(label_36);
60770
60799
  var label_37 = sibling(label_36, 2);
60771
60800
  var span_23 = child(label_37);
@@ -60774,10 +60803,17 @@ function PropertiesPanel($$anchor, $$props) {
60774
60803
  var input_28 = sibling(span_23, 2);
60775
60804
  remove_input_defaults(input_28);
60776
60805
  reset(label_37);
60777
- var div_36 = sibling(label_37, 2);
60806
+ var label_38 = sibling(label_37, 2);
60807
+ var span_24 = child(label_38);
60808
+ var text_31 = child(span_24);
60809
+ reset(span_24);
60810
+ var input_29 = sibling(span_24, 2);
60811
+ remove_input_defaults(input_29);
60812
+ reset(label_38);
60813
+ var div_36 = sibling(label_38, 2);
60778
60814
  var div_37 = sibling(child(div_36), 2);
60779
60815
  each(div_37, 21, () => columnColorPresets, index$1, ($$anchor, preset) => {
60780
- var button_26 = root_25();
60816
+ var button_26 = root_26();
60781
60817
  template_effect(() => {
60782
60818
  var _$$get$color7;
60783
60819
  set_class(button_26, 1, `w-7 h-7 rounded-md border-2 hover:border-gray-300 transition-colors ${get(selectedColumn).color === get(preset).color ? "border-blue-500 ring-1 ring-blue-200" : "border-gray-200"}`);
@@ -60789,32 +60825,32 @@ function PropertiesPanel($$anchor, $$props) {
60789
60825
  });
60790
60826
  reset(div_37);
60791
60827
  var div_38 = sibling(div_37, 2);
60792
- var input_29 = sibling(child(div_38), 2);
60793
- remove_input_defaults(input_29);
60828
+ var input_30 = sibling(child(div_38), 2);
60829
+ remove_input_defaults(input_30);
60794
60830
  reset(div_38);
60795
60831
  reset(div_36);
60796
- var node_9 = sibling(div_36, 2);
60797
- var consequent_11 = ($$anchor) => {
60798
- var label_38 = root_26();
60799
- var input_30 = sibling(child(label_38), 2);
60800
- remove_input_defaults(input_30);
60801
- reset(label_38);
60802
- template_effect(() => set_value(input_30, get(selectedColumn).rotation));
60803
- delegated("input", input_30, (e) => updateColumn(get(selectedColumn).id, { rotation: Number(e.target.value) }));
60804
- append($$anchor, label_38);
60832
+ var node_10 = sibling(div_36, 2);
60833
+ var consequent_12 = ($$anchor) => {
60834
+ var label_39 = root_27();
60835
+ var input_31 = sibling(child(label_39), 2);
60836
+ remove_input_defaults(input_31);
60837
+ reset(label_39);
60838
+ template_effect(() => set_value(input_31, get(selectedColumn).rotation));
60839
+ delegated("input", input_31, (e) => updateColumn(get(selectedColumn).id, { rotation: Number(e.target.value) }));
60840
+ append($$anchor, label_39);
60805
60841
  };
60806
- if_block(node_9, ($$render) => {
60807
- if (get(selectedColumn).shape === "square") $$render(consequent_11);
60842
+ if_block(node_10, ($$render) => {
60843
+ if (get(selectedColumn).shape === "square") $$render(consequent_12);
60808
60844
  });
60809
60845
  reset(div_34);
60810
60846
  template_effect(($0, $1, $2, $3) => {
60811
60847
  set_class(button_24, 1, `flex-1 px-2 py-1.5 border rounded text-sm transition-colors ${get(selectedColumn).shape === "round" ? "bg-blue-100 border-blue-400 text-blue-700" : "border-gray-200 hover:bg-gray-50"}`);
60812
60848
  set_class(button_25, 1, `flex-1 px-2 py-1.5 border rounded text-sm transition-colors ${get(selectedColumn).shape === "square" ? "bg-blue-100 border-blue-400 text-blue-700" : "border-gray-200 hover:bg-gray-50"}`);
60813
- set_text(text_29, `${get(selectedColumn).shape === "round" ? "Diameter" : "Side Length"} (${$0 !== null && $0 !== void 0 ? $0 : ""})`);
60814
- set_value(input_27, $1);
60815
- set_text(text_30, `Height (${$2 !== null && $2 !== void 0 ? $2 : ""})`);
60816
- set_value(input_28, $3);
60817
- set_value(input_29, get(selectedColumn).color);
60849
+ set_text(text_30, `${get(selectedColumn).shape === "round" ? "Diameter" : "Side Length"} (${$0 !== null && $0 !== void 0 ? $0 : ""})`);
60850
+ set_value(input_28, $1);
60851
+ set_text(text_31, `Height (${$2 !== null && $2 !== void 0 ? $2 : ""})`);
60852
+ set_value(input_29, $3);
60853
+ set_value(input_30, get(selectedColumn).color);
60818
60854
  }, [
60819
60855
  () => unitLabel(),
60820
60856
  () => displayValue(get(selectedColumn).diameter),
@@ -60823,33 +60859,29 @@ function PropertiesPanel($$anchor, $$props) {
60823
60859
  ]);
60824
60860
  delegated("click", button_24, () => updateColumn(get(selectedColumn).id, { shape: "round" }));
60825
60861
  delegated("click", button_25, () => updateColumn(get(selectedColumn).id, { shape: "square" }));
60826
- delegated("input", input_27, (e) => updateColumn(get(selectedColumn).id, { diameter: inputToCm(Number(e.target.value)) }));
60827
- delegated("input", input_28, (e) => updateColumn(get(selectedColumn).id, { height: inputToCm(Number(e.target.value)) }));
60828
- delegated("input", input_29, (e) => updateColumn(get(selectedColumn).id, { color: e.target.value }));
60862
+ delegated("input", input_28, (e) => updateColumn(get(selectedColumn).id, { diameter: inputToCm(Number(e.target.value)) }));
60863
+ delegated("input", input_29, (e) => updateColumn(get(selectedColumn).id, { height: inputToCm(Number(e.target.value)) }));
60864
+ delegated("input", input_30, (e) => updateColumn(get(selectedColumn).id, { color: e.target.value }));
60829
60865
  append($$anchor, fragment_10);
60830
60866
  };
60831
- var consequent_13 = ($$anchor) => {
60832
- var div_39 = root_27();
60833
- var label_39 = sibling(child(div_39), 2);
60834
- var input_31 = sibling(child(label_39), 2);
60835
- remove_input_defaults(input_31);
60836
- reset(label_39);
60837
- var label_40 = sibling(label_39, 2);
60867
+ var consequent_14 = ($$anchor) => {
60868
+ var div_39 = root_28();
60869
+ var label_40 = sibling(child(div_39), 2);
60838
60870
  var input_32 = sibling(child(label_40), 2);
60839
60871
  remove_input_defaults(input_32);
60840
60872
  reset(label_40);
60841
60873
  var label_41 = sibling(label_40, 2);
60842
- var div_40 = sibling(child(label_41), 2);
60843
- var input_33 = child(div_40);
60874
+ var input_33 = sibling(child(label_41), 2);
60844
60875
  remove_input_defaults(input_33);
60845
- var span_24 = sibling(input_33, 2);
60846
- var text_31 = child(span_24, true);
60847
- reset(span_24);
60848
- reset(div_40);
60849
60876
  reset(label_41);
60850
60877
  var label_42 = sibling(label_41, 2);
60851
- var input_34 = sibling(child(label_42), 2);
60878
+ var div_40 = sibling(child(label_42), 2);
60879
+ var input_34 = child(div_40);
60852
60880
  remove_input_defaults(input_34);
60881
+ var span_25 = sibling(input_34, 2);
60882
+ var text_32 = child(span_25, true);
60883
+ reset(span_25);
60884
+ reset(div_40);
60853
60885
  reset(label_42);
60854
60886
  var label_43 = sibling(label_42, 2);
60855
60887
  var input_35 = sibling(child(label_43), 2);
@@ -60859,22 +60891,26 @@ function PropertiesPanel($$anchor, $$props) {
60859
60891
  var input_36 = sibling(child(label_44), 2);
60860
60892
  remove_input_defaults(input_36);
60861
60893
  reset(label_44);
60894
+ var label_45 = sibling(label_44, 2);
60895
+ var input_37 = sibling(child(label_45), 2);
60896
+ remove_input_defaults(input_37);
60897
+ reset(label_45);
60862
60898
  reset(div_39);
60863
60899
  template_effect(($0, $1) => {
60864
- set_value(input_31, get(selectedTextAnnotation).text);
60865
- set_value(input_32, get(selectedTextAnnotation).fontSize);
60866
- set_value(input_33, get(selectedTextAnnotation).color);
60867
- set_text(text_31, get(selectedTextAnnotation).color);
60868
- set_value(input_34, get(selectedTextAnnotation).rotation);
60869
- set_value(input_35, $0);
60870
- set_value(input_36, $1);
60900
+ set_value(input_32, get(selectedTextAnnotation).text);
60901
+ set_value(input_33, get(selectedTextAnnotation).fontSize);
60902
+ set_value(input_34, get(selectedTextAnnotation).color);
60903
+ set_text(text_32, get(selectedTextAnnotation).color);
60904
+ set_value(input_35, get(selectedTextAnnotation).rotation);
60905
+ set_value(input_36, $0);
60906
+ set_value(input_37, $1);
60871
60907
  }, [() => Math.round(get(selectedTextAnnotation).x), () => Math.round(get(selectedTextAnnotation).y)]);
60872
- delegated("input", input_31, (e) => updateTextAnnotation(get(selectedTextAnnotation).id, { text: e.target.value }));
60873
- delegated("input", input_32, (e) => updateTextAnnotation(get(selectedTextAnnotation).id, { fontSize: Number(e.target.value) }));
60874
- delegated("input", input_33, (e) => updateTextAnnotation(get(selectedTextAnnotation).id, { color: e.target.value }));
60875
- delegated("input", input_34, (e) => updateTextAnnotation(get(selectedTextAnnotation).id, { rotation: Number(e.target.value) }));
60876
- delegated("input", input_35, (e) => updateTextAnnotation(get(selectedTextAnnotation).id, { x: Number(e.target.value) }));
60877
- delegated("input", input_36, (e) => updateTextAnnotation(get(selectedTextAnnotation).id, { y: Number(e.target.value) }));
60908
+ delegated("input", input_32, (e) => updateTextAnnotation(get(selectedTextAnnotation).id, { text: e.target.value }));
60909
+ delegated("input", input_33, (e) => updateTextAnnotation(get(selectedTextAnnotation).id, { fontSize: Number(e.target.value) }));
60910
+ delegated("input", input_34, (e) => updateTextAnnotation(get(selectedTextAnnotation).id, { color: e.target.value }));
60911
+ delegated("input", input_35, (e) => updateTextAnnotation(get(selectedTextAnnotation).id, { rotation: Number(e.target.value) }));
60912
+ delegated("input", input_36, (e) => updateTextAnnotation(get(selectedTextAnnotation).id, { x: Number(e.target.value) }));
60913
+ delegated("input", input_37, (e) => updateTextAnnotation(get(selectedTextAnnotation).id, { y: Number(e.target.value) }));
60878
60914
  append($$anchor, div_39);
60879
60915
  };
60880
60916
  if_block(node, ($$render) => {
@@ -60882,20 +60918,16 @@ function PropertiesPanel($$anchor, $$props) {
60882
60918
  else if (get(selectedDoor)) $$render(consequent_2, 1);
60883
60919
  else if (get(selectedWindow)) $$render(consequent_3, 2);
60884
60920
  else if (get(selectedFurniture)) $$render(consequent_7, 3);
60885
- else if (get(selectedRoom)) $$render(consequent_9, 4);
60886
- else if (get(selectedStair)) $$render(consequent_10, 5);
60887
- else if (get(selectedColumn)) $$render(consequent_12, 6);
60888
- else if (get(selectedTextAnnotation)) $$render(consequent_13, 7);
60921
+ else if (get(selectedRoom)) $$render(consequent_10, 4);
60922
+ else if (get(selectedStair)) $$render(consequent_11, 5);
60923
+ else if (get(selectedColumn)) $$render(consequent_13, 6);
60924
+ else if (get(selectedTextAnnotation)) $$render(consequent_14, 7);
60889
60925
  });
60890
- var node_10 = sibling(node, 2);
60891
- var consequent_14 = ($$anchor) => {
60892
- var div_41 = root_28();
60926
+ var node_11 = sibling(node, 2);
60927
+ var consequent_15 = ($$anchor) => {
60928
+ var div_41 = root_29();
60893
60929
  var div_42 = sibling(child(div_41), 2);
60894
- var label_45 = child(div_42);
60895
- var input_37 = sibling(child(label_45), 2);
60896
- remove_input_defaults(input_37);
60897
- reset(label_45);
60898
- var label_46 = sibling(label_45, 2);
60930
+ var label_46 = child(div_42);
60899
60931
  var input_38 = sibling(child(label_46), 2);
60900
60932
  remove_input_defaults(input_38);
60901
60933
  reset(label_46);
@@ -60903,9 +60935,13 @@ function PropertiesPanel($$anchor, $$props) {
60903
60935
  var input_39 = sibling(child(label_47), 2);
60904
60936
  remove_input_defaults(input_39);
60905
60937
  reset(label_47);
60906
- var div_43 = sibling(label_47, 2);
60938
+ var label_48 = sibling(label_47, 2);
60939
+ var input_40 = sibling(child(label_48), 2);
60940
+ remove_input_defaults(input_40);
60941
+ reset(label_48);
60942
+ var div_43 = sibling(label_48, 2);
60907
60943
  var button_27 = child(div_43);
60908
- var text_32 = child(button_27, true);
60944
+ var text_33 = child(button_27, true);
60909
60945
  reset(button_27);
60910
60946
  var button_28 = sibling(button_27, 2);
60911
60947
  reset(div_43);
@@ -60913,15 +60949,15 @@ function PropertiesPanel($$anchor, $$props) {
60913
60949
  reset(div_42);
60914
60950
  reset(div_41);
60915
60951
  template_effect(() => {
60916
- set_value(input_37, get(floor).backgroundImage.opacity);
60917
- set_value(input_38, get(floor).backgroundImage.scale);
60918
- set_value(input_39, get(floor).backgroundImage.rotation);
60952
+ set_value(input_38, get(floor).backgroundImage.opacity);
60953
+ set_value(input_39, get(floor).backgroundImage.scale);
60954
+ set_value(input_40, get(floor).backgroundImage.rotation);
60919
60955
  set_class(button_27, 1, `flex-1 px-2 py-1.5 border rounded text-sm ${get(floor).backgroundImage.locked ? "bg-amber-100 border-amber-400 text-amber-700" : "border-gray-200 hover:bg-gray-50"}`);
60920
- set_text(text_32, get(floor).backgroundImage.locked ? "🔒 Locked" : "🔓 Unlocked");
60956
+ set_text(text_33, get(floor).backgroundImage.locked ? "🔒 Locked" : "🔓 Unlocked");
60921
60957
  });
60922
- delegated("input", input_37, (e) => updateBackgroundImage({ opacity: Number(e.target.value) }));
60923
- delegated("input", input_38, (e) => updateBackgroundImage({ scale: Number(e.target.value) }));
60924
- delegated("input", input_39, (e) => updateBackgroundImage({ rotation: Number(e.target.value) }));
60958
+ delegated("input", input_38, (e) => updateBackgroundImage({ opacity: Number(e.target.value) }));
60959
+ delegated("input", input_39, (e) => updateBackgroundImage({ scale: Number(e.target.value) }));
60960
+ delegated("input", input_40, (e) => updateBackgroundImage({ rotation: Number(e.target.value) }));
60925
60961
  delegated("click", button_27, () => updateBackgroundImage({ locked: !get(floor).backgroundImage.locked }));
60926
60962
  delegated("click", button_28, () => {
60927
60963
  calibrationPoints.set([]);
@@ -60930,9 +60966,9 @@ function PropertiesPanel($$anchor, $$props) {
60930
60966
  delegated("click", button_29, () => setBackgroundImage(void 0));
60931
60967
  append($$anchor, div_41);
60932
60968
  };
60933
- if_block(node_10, ($$render) => {
60934
- var _$$get17;
60935
- if (get(hasBgImage) && ((_$$get17 = get(floor)) === null || _$$get17 === void 0 ? void 0 : _$$get17.backgroundImage)) $$render(consequent_14);
60969
+ if_block(node_11, ($$render) => {
60970
+ var _$$get18;
60971
+ if (get(hasBgImage) && ((_$$get18 = get(floor)) === null || _$$get18 === void 0 ? void 0 : _$$get18.backgroundImage)) $$render(consequent_15);
60936
60972
  });
60937
60973
  reset(div);
60938
60974
  template_effect(() => classes = set_class(div, 1, `${is3D() ? "w-80" : "w-64"} shrink-0 bg-white border-l border-gray-200 flex flex-col overflow-y-auto p-3 fixed right-0 z-40 shadow-lg`, null, classes, { hidden: !get(hasSelection) }));
@@ -64894,6 +64930,7 @@ function FloorPlanCanvas($$anchor, $$props) {
64894
64930
  let isCalibrating = /* @__PURE__ */ state(false);
64895
64931
  let calPoints = /* @__PURE__ */ state(proxy([]));
64896
64932
  let bgImage = /* @__PURE__ */ state(null);
64933
+ let thumbnailOpacity = /* @__PURE__ */ state(.65);
64897
64934
  user_effect(() => {
64898
64935
  var _$$get, _cameraThumbnail$trim, _cameraThumbnail;
64899
64936
  const floorBgUrl = (_$$get = get(currentFloor)) === null || _$$get === void 0 || (_$$get = _$$get.backgroundImage) === null || _$$get === void 0 ? void 0 : _$$get.dataUrl;
@@ -65648,31 +65685,45 @@ function FloorPlanCanvas($$anchor, $$props) {
65648
65685
  function drawColumn$1(col, selected) {
65649
65686
  drawColumn(getCS(), col, selected);
65650
65687
  }
65688
+ function getCameraThumbnailBounds(floor = get(currentFloor)) {
65689
+ if (!floor) return null;
65690
+ return getFloorBounds(floor, { includeWallThickness: true });
65691
+ }
65692
+ function isCameraThumbnailOverlayActive() {
65693
+ var _cameraThumbnail2, _$$get3;
65694
+ return !!(((_cameraThumbnail2 = cameraThumbnail()) === null || _cameraThumbnail2 === void 0 ? void 0 : _cameraThumbnail2.trim()) && get(bgImage) && !((_$$get3 = get(currentFloor)) === null || _$$get3 === void 0 ? void 0 : _$$get3.backgroundImage));
65695
+ }
65651
65696
  function drawBackgroundImage() {
65652
- if (!get(bgImage) || !get(currentFloor)) return;
65697
+ var _$$get4;
65698
+ if (!get(bgImage) || !((_$$get4 = get(currentFloor)) === null || _$$get4 === void 0 ? void 0 : _$$get4.backgroundImage)) return;
65653
65699
  const bg = get(currentFloor).backgroundImage;
65654
65700
  ctx.save();
65655
- if (bg) {
65656
- const s = worldToScreen(bg.position.x, bg.position.y);
65657
- ctx.globalAlpha = bg.opacity;
65658
- ctx.translate(s.x, s.y);
65659
- ctx.rotate(bg.rotation * Math.PI / 180);
65660
- const sw = get(bgImage).width * bg.scale * get(zoom);
65661
- const sh = get(bgImage).height * bg.scale * get(zoom);
65662
- ctx.drawImage(get(bgImage), -sw / 2, -sh / 2, sw, sh);
65663
- } else if (cameraThumbnail()) {
65664
- const bounds = getFloorBounds(get(currentFloor), { includeWallThickness: true });
65665
- if (!bounds) {
65666
- ctx.restore();
65667
- return;
65668
- }
65669
- ctx.globalAlpha = .85;
65670
- const topLeft = worldToScreen(bounds.minX, bounds.minY);
65671
- const bottomRight = worldToScreen(bounds.maxX, bounds.maxY);
65672
- ctx.drawImage(get(bgImage), topLeft.x, topLeft.y, bottomRight.x - topLeft.x, bottomRight.y - topLeft.y);
65673
- }
65701
+ ctx.globalAlpha = bg.opacity;
65702
+ const s = worldToScreen(bg.position.x, bg.position.y);
65703
+ ctx.translate(s.x, s.y);
65704
+ ctx.rotate(bg.rotation * Math.PI / 180);
65705
+ const sw = get(bgImage).width * bg.scale * get(zoom);
65706
+ const sh = get(bgImage).height * bg.scale * get(zoom);
65707
+ ctx.drawImage(get(bgImage), -sw / 2, -sh / 2, sw, sh);
65674
65708
  ctx.restore();
65675
65709
  }
65710
+ function drawCameraThumbnail() {
65711
+ if (!isCameraThumbnailOverlayActive() || !get(bgImage) || !get(currentFloor)) return;
65712
+ const bounds = getCameraThumbnailBounds();
65713
+ if (!bounds) return;
65714
+ ctx.save();
65715
+ ctx.globalAlpha = get(thumbnailOpacity);
65716
+ const topLeft = worldToScreen(bounds.minX, bounds.minY);
65717
+ const bottomRight = worldToScreen(bounds.maxX, bounds.maxY);
65718
+ ctx.drawImage(get(bgImage), topLeft.x, topLeft.y, bottomRight.x - topLeft.x, bottomRight.y - topLeft.y);
65719
+ ctx.restore();
65720
+ }
65721
+ function drawFloorHeatmapLayer() {
65722
+ var _$$props$heatmapMatri, _$$props$heatmapMatri2;
65723
+ const floor = get(currentFloor);
65724
+ if (!floor || !$$props.heatmapEnabled || !((_$$props$heatmapMatri = $$props.heatmapMatrix) === null || _$$props$heatmapMatri === void 0 ? void 0 : _$$props$heatmapMatri.length)) return;
65725
+ drawFloorHeatmap(getCS(), floor, (_$$props$heatmapMatri2 = $$props.heatmapMatrix) !== null && _$$props$heatmapMatri2 !== void 0 ? _$$props$heatmapMatri2 : [], get(detectedRooms));
65726
+ }
65676
65727
  function getFloorWallBounds(floor = get(currentFloor)) {
65677
65728
  var _floor$walls;
65678
65729
  if (!(floor === null || floor === void 0 || (_floor$walls = floor.walls) === null || _floor$walls === void 0 ? void 0 : _floor$walls.length)) return null;
@@ -65743,10 +65794,6 @@ function FloorPlanCanvas($$anchor, $$props) {
65743
65794
  return id === selId || multiIds.has(id);
65744
65795
  }
65745
65796
  drawRooms$1();
65746
- if (floor && $$props.heatmapEnabled && $$props.heatmapMatrix && $$props.heatmapMatrix.length > 0) {
65747
- var _$$props$heatmapMatri;
65748
- drawFloorHeatmap(getCS(), floor, (_$$props$heatmapMatri = $$props.heatmapMatrix) !== null && _$$props$heatmapMatri !== void 0 ? _$$props$heatmapMatri : [], get(detectedRooms));
65749
- }
65750
65797
  if (!$$props.viewOnly) drawSnapPoints$1();
65751
65798
  if (get(layerVis).walls) {
65752
65799
  for (const w of floor.walls) drawWall$1(w, isSelected(w.id));
@@ -66333,6 +66380,7 @@ function FloorPlanCanvas($$anchor, $$props) {
66333
66380
  if (get(layerVis).annotations && floor) drawAnnotations$1(floor);
66334
66381
  if (get(annotating) && get(annotationStart)) drawAnnotationPreview();
66335
66382
  if (floor) drawTextAnnotations$1(floor);
66383
+ drawCameraThumbnail();
66336
66384
  if (get(draggingHandle) === "rotate" && get(currentSelectedId) && get(currentFloor)) {
66337
66385
  const fi = get(currentFloor).furniture.find((f) => f.id === get(currentSelectedId));
66338
66386
  if (fi) {
@@ -66369,6 +66417,7 @@ function FloorPlanCanvas($$anchor, $$props) {
66369
66417
  ctx.setLineDash([]);
66370
66418
  ctx.restore();
66371
66419
  }
66420
+ drawFloorHeatmapLayer();
66372
66421
  drawMinimap$1();
66373
66422
  requestAnimationFrame(draw);
66374
66423
  }
@@ -66494,6 +66543,10 @@ function FloorPlanCanvas($$anchor, $$props) {
66494
66543
  }
66495
66544
  }
66496
66545
  document.addEventListener("paste", handlePaste);
66546
+ const unsubThumbOpacity = cameraThumbnailOpacity.subscribe((v) => {
66547
+ set(thumbnailOpacity, v, true);
66548
+ markDirty();
66549
+ });
66497
66550
  return () => {
66498
66551
  resizeObs.disconnect();
66499
66552
  unsub1();
@@ -66513,6 +66566,7 @@ function FloorPlanCanvas($$anchor, $$props) {
66513
66566
  unsubZoom();
66514
66567
  unsubCamX();
66515
66568
  unsubCamY();
66569
+ unsubThumbOpacity();
66516
66570
  unsub_col();
66517
66571
  unsub_cols();
66518
66572
  unsub_layers();
@@ -66683,7 +66737,7 @@ function FloorPlanCanvas($$anchor, $$props) {
66683
66737
  return findRoomAt(p, get(detectedRooms), get(currentFloor).walls);
66684
66738
  }
66685
66739
  function onMouseDown(e) {
66686
- var _$$get3;
66740
+ var _$$get5;
66687
66741
  if ($$props.viewOnly) return;
66688
66742
  markDirty();
66689
66743
  if (e.button === 1 || e.button === 0 && (get(spaceDown) || $panMode() || e.shiftKey && get(currentTool) === "select")) {
@@ -66764,7 +66818,7 @@ function FloorPlanCanvas($$anchor, $$props) {
66764
66818
  placingStair.set(false);
66765
66819
  return;
66766
66820
  }
66767
- if (tool === "select" && ((_$$get3 = get(currentFloor)) === null || _$$get3 === void 0 ? void 0 : _$$get3.guides)) {
66821
+ if (tool === "select" && ((_$$get5 = get(currentFloor)) === null || _$$get5 === void 0 ? void 0 : _$$get5.guides)) {
66768
66822
  const GUIDE_HIT = 6 / get(zoom);
66769
66823
  for (const g of get(currentFloor).guides) {
66770
66824
  if (g.orientation === "horizontal" && Math.abs(wp.y - g.position) < GUIDE_HIT) {
@@ -66833,9 +66887,9 @@ function FloorPlanCanvas($$anchor, $$props) {
66833
66887
  const dist = Math.hypot(newPts[1].x - newPts[0].x, newPts[1].y - newPts[0].y);
66834
66888
  const realDist = prompt("Enter the real-world distance between these two points (in cm):");
66835
66889
  if (realDist && Number(realDist) > 0) {
66836
- var _$$get4;
66890
+ var _$$get6;
66837
66891
  const pixelsPerCm = dist / Number(realDist);
66838
- if ((_$$get4 = get(currentFloor)) === null || _$$get4 === void 0 ? void 0 : _$$get4.backgroundImage) updateBackgroundImage({ scale: get(currentFloor).backgroundImage.scale * (1 / pixelsPerCm) });
66892
+ if ((_$$get6 = get(currentFloor)) === null || _$$get6 === void 0 ? void 0 : _$$get6.backgroundImage) updateBackgroundImage({ scale: get(currentFloor).backgroundImage.scale * (1 / pixelsPerCm) });
66839
66893
  }
66840
66894
  calibrationMode.set(false);
66841
66895
  return [];
@@ -67205,7 +67259,7 @@ function FloorPlanCanvas($$anchor, $$props) {
67205
67259
  }
67206
67260
  }
67207
67261
  function onMouseMove(e) {
67208
- var _$$get5, _$$get6, _$$get7, _$$get8;
67262
+ var _$$get7, _$$get8, _$$get9, _$$get10;
67209
67263
  if ($$props.viewOnly) return;
67210
67264
  markDirty();
67211
67265
  const rect = canvas.getBoundingClientRect();
@@ -67223,7 +67277,7 @@ function FloorPlanCanvas($$anchor, $$props) {
67223
67277
  } : r));
67224
67278
  return;
67225
67279
  }
67226
- if (get(draggingGuideId) && ((_$$get5 = get(currentFloor)) === null || _$$get5 === void 0 ? void 0 : _$$get5.guides)) {
67280
+ if (get(draggingGuideId) && ((_$$get7 = get(currentFloor)) === null || _$$get7 === void 0 ? void 0 : _$$get7.guides)) {
67227
67281
  const g = get(currentFloor).guides.find((g) => g.id === get(draggingGuideId));
67228
67282
  if (g) {
67229
67283
  const newPos = g.orientation === "horizontal" ? get(mousePos).y : get(mousePos).x;
@@ -67379,7 +67433,7 @@ function FloorPlanCanvas($$anchor, $$props) {
67379
67433
  }
67380
67434
  }
67381
67435
  }
67382
- if (get(draggingTextAnnotationId) && ((_$$get6 = get(currentFloor)) === null || _$$get6 === void 0 ? void 0 : _$$get6.textAnnotations)) {
67436
+ if (get(draggingTextAnnotationId) && ((_$$get8 = get(currentFloor)) === null || _$$get8 === void 0 ? void 0 : _$$get8.textAnnotations)) {
67383
67437
  const basePos = {
67384
67438
  x: get(mousePos).x - textAnnotationDragOffset.x,
67385
67439
  y: get(mousePos).y - textAnnotationDragOffset.y
@@ -67396,7 +67450,7 @@ function FloorPlanCanvas($$anchor, $$props) {
67396
67450
  }, true);
67397
67451
  }
67398
67452
  }
67399
- if (get(draggingColumnId) && ((_$$get7 = get(currentFloor)) === null || _$$get7 === void 0 ? void 0 : _$$get7.columns)) {
67453
+ if (get(draggingColumnId) && ((_$$get9 = get(currentFloor)) === null || _$$get9 === void 0 ? void 0 : _$$get9.columns)) {
67400
67454
  const basePos = {
67401
67455
  x: get(mousePos).x - columnDragOffset.x,
67402
67456
  y: get(mousePos).y - columnDragOffset.y
@@ -67406,7 +67460,7 @@ function FloorPlanCanvas($$anchor, $$props) {
67406
67460
  y: snap(basePos.y)
67407
67461
  });
67408
67462
  }
67409
- if (get(draggingStairId) && ((_$$get8 = get(currentFloor)) === null || _$$get8 === void 0 ? void 0 : _$$get8.stairs)) {
67463
+ if (get(draggingStairId) && ((_$$get10 = get(currentFloor)) === null || _$$get10 === void 0 ? void 0 : _$$get10.stairs)) {
67410
67464
  const basePos = {
67411
67465
  x: get(mousePos).x - stairDragOffset.x,
67412
67466
  y: get(mousePos).y - stairDragOffset.y
@@ -67417,12 +67471,12 @@ function FloorPlanCanvas($$anchor, $$props) {
67417
67471
  });
67418
67472
  }
67419
67473
  if (get(draggingFurnitureId)) {
67420
- var _$$get9;
67474
+ var _$$get11;
67421
67475
  const basePos = {
67422
67476
  x: get(mousePos).x - dragOffset.x,
67423
67477
  y: get(mousePos).y - dragOffset.y
67424
67478
  };
67425
- const fi = (_$$get9 = get(currentFloor)) === null || _$$get9 === void 0 ? void 0 : _$$get9.furniture.find((f) => f.id === get(draggingFurnitureId));
67479
+ const fi = (_$$get11 = get(currentFloor)) === null || _$$get11 === void 0 ? void 0 : _$$get11.furniture.find((f) => f.id === get(draggingFurnitureId));
67426
67480
  if (fi) {
67427
67481
  const wallSnap = snapFurnitureToWall(basePos, fi.catalogId, fi.rotation);
67428
67482
  if (wallSnap) {
@@ -67435,13 +67489,13 @@ function FloorPlanCanvas($$anchor, $$props) {
67435
67489
  wallAngle: wallSnap.wallAngle
67436
67490
  }, true);
67437
67491
  } else {
67438
- var _$$get10;
67492
+ var _$$get12;
67439
67493
  const snapped = {
67440
67494
  x: snap(basePos.x),
67441
67495
  y: snap(basePos.y)
67442
67496
  };
67443
67497
  const GUIDE_SNAP = 10;
67444
- if ((_$$get10 = get(currentFloor)) === null || _$$get10 === void 0 ? void 0 : _$$get10.guides) for (const g of get(currentFloor).guides) {
67498
+ if ((_$$get12 = get(currentFloor)) === null || _$$get12 === void 0 ? void 0 : _$$get12.guides) for (const g of get(currentFloor).guides) {
67445
67499
  if (g.orientation === "horizontal" && Math.abs(snapped.y - g.position) < GUIDE_SNAP) snapped.y = g.position;
67446
67500
  if (g.orientation === "vertical" && Math.abs(snapped.x - g.position) < GUIDE_SNAP) snapped.x = g.position;
67447
67501
  }
@@ -68137,8 +68191,8 @@ function FloorPlanCanvas($$anchor, $$props) {
68137
68191
  }
68138
68192
  }
68139
68193
  let cursorStyle = /* @__PURE__ */ user_derived(() => {
68140
- var _$$get11;
68141
- return get(spaceDown) || get(isPanning) || $panMode() || get(shiftDown) && get(currentTool) === "select" ? "grab" : get(draggingFurnitureId) ? "move" : get(draggingRoomId) ? "move" : get(draggingMultiSelect) ? "move" : get(draggingDoorId) ? "move" : get(draggingWindowId) ? "move" : get(draggingStairId) ? "move" : get(draggingColumnId) ? "move" : get(draggingTextAnnotationId) ? "move" : get(draggingWallParallel) ? "move" : get(draggingCurveHandle) ? "crosshair" : get(draggingWallEndpoint) ? "crosshair" : get(draggingHandle) === "rotate" ? "grabbing" : get(draggingHandle) === "resize-t" || get(draggingHandle) === "resize-b" ? "ns-resize" : get(draggingHandle) === "resize-l" || get(draggingHandle) === "resize-r" ? "ew-resize" : ((_$$get11 = get(draggingHandle)) === null || _$$get11 === void 0 ? void 0 : _$$get11.startsWith("resize")) ? "nwse-resize" : get(currentTool) === "text" ? "text" : get(currentTool) === "select" ? "default" : get(currentTool) === "furniture" ? "copy" : get(currentTool) === "door" || get(currentTool) === "window" ? get(placementPreview) ? "crosshair" : "not-allowed" : "crosshair";
68194
+ var _$$get13;
68195
+ return get(spaceDown) || get(isPanning) || $panMode() || get(shiftDown) && get(currentTool) === "select" ? "grab" : get(draggingFurnitureId) ? "move" : get(draggingRoomId) ? "move" : get(draggingMultiSelect) ? "move" : get(draggingDoorId) ? "move" : get(draggingWindowId) ? "move" : get(draggingStairId) ? "move" : get(draggingColumnId) ? "move" : get(draggingTextAnnotationId) ? "move" : get(draggingWallParallel) ? "move" : get(draggingCurveHandle) ? "crosshair" : get(draggingWallEndpoint) ? "crosshair" : get(draggingHandle) === "rotate" ? "grabbing" : get(draggingHandle) === "resize-t" || get(draggingHandle) === "resize-b" ? "ns-resize" : get(draggingHandle) === "resize-l" || get(draggingHandle) === "resize-r" ? "ew-resize" : ((_$$get13 = get(draggingHandle)) === null || _$$get13 === void 0 ? void 0 : _$$get13.startsWith("resize")) ? "nwse-resize" : get(currentTool) === "text" ? "text" : get(currentTool) === "select" ? "default" : get(currentTool) === "furniture" ? "copy" : get(currentTool) === "door" || get(currentTool) === "window" ? get(placementPreview) ? "crosshair" : "not-allowed" : "crosshair";
68142
68196
  });
68143
68197
  var div = root$1();
68144
68198
  event("keydown", $window, onKeyDown);
@@ -68225,8 +68279,8 @@ function FloorPlanCanvas($$anchor, $$props) {
68225
68279
  }
68226
68280
  set(editingTextAnnotationId, null);
68227
68281
  } else if (e.key === "Escape") {
68228
- var _$$get12;
68229
- if ((_$$get12 = get(currentFloor)) === null || _$$get12 === void 0 ? void 0 : _$$get12.textAnnotations) {
68282
+ var _$$get14;
68283
+ if ((_$$get14 = get(currentFloor)) === null || _$$get14 === void 0 ? void 0 : _$$get14.textAnnotations) {
68230
68284
  const ta = get(currentFloor).textAnnotations.find((t) => t.id === get(editingTextAnnotationId));
68231
68285
  if (ta && ta.text === "Text" && !get(editingTextAnnotationValue).trim()) {
68232
68286
  removeTextAnnotation(get(editingTextAnnotationId));
@@ -68578,8 +68632,8 @@ function FloorPlanCanvas($$anchor, $$props) {
68578
68632
  var text_16 = child(div_8);
68579
68633
  reset(div_8);
68580
68634
  template_effect(() => {
68581
- var _$$get13;
68582
- return set_text(text_16, `Click to place · Scroll or R to rotate (${(_$$get13 = get(currentPlacingRotation)) !== null && _$$get13 !== void 0 ? _$$get13 : ""}°) · Esc
68635
+ var _$$get15;
68636
+ return set_text(text_16, `Click to place · Scroll or R to rotate (${(_$$get15 = get(currentPlacingRotation)) !== null && _$$get15 !== void 0 ? _$$get15 : ""}°) · Esc
68583
68637
  to cancel`);
68584
68638
  });
68585
68639
  append($$anchor, div_8);
@@ -69677,6 +69731,9 @@ function App($$anchor, $$props) {
69677
69731
  let config = /* @__PURE__ */ state(proxy({ ...DEFAULT_CONFIG }));
69678
69732
  (_$$props$stores = $$props.stores) === null || _$$props$stores === void 0 || _$$props$stores.floorData.subscribe((v) => set(floorData, v, true));
69679
69733
  (_$$props$stores2 = $$props.stores) === null || _$$props$stores2 === void 0 || _$$props$stores2.config.subscribe((v) => set(config, normalizeConfig(v), true));
69734
+ user_effect(() => {
69735
+ if (get(config).cameraThumbnailOpacity != null) cameraThumbnailOpacity.set(get(config).cameraThumbnailOpacity);
69736
+ });
69680
69737
  let commandPaletteOpen = /* @__PURE__ */ state(false);
69681
69738
  let printOpen = /* @__PURE__ */ state(false);
69682
69739
  let mode = /* @__PURE__ */ state("2d");
@@ -69882,12 +69939,19 @@ function App($$anchor, $$props) {
69882
69939
  var _$$get$siteCameras, _$$get13;
69883
69940
  return (_$$get$siteCameras = (_$$get13 = get(config)) === null || _$$get13 === void 0 ? void 0 : _$$get13.siteCameras) !== null && _$$get$siteCameras !== void 0 ? _$$get$siteCameras : [];
69884
69941
  });
69942
+ let $2 = /* @__PURE__ */ user_derived(() => {
69943
+ var _$$get$cameraThumbnai, _$$get14;
69944
+ return (_$$get$cameraThumbnai = (_$$get14 = get(config)) === null || _$$get14 === void 0 ? void 0 : _$$get14.cameraThumbnail) !== null && _$$get$cameraThumbnai !== void 0 ? _$$get$cameraThumbnai : "";
69945
+ });
69885
69946
  PropertiesPanel($$anchor, {
69886
69947
  get is3D() {
69887
69948
  return get($0);
69888
69949
  },
69889
69950
  get siteCameras() {
69890
69951
  return get($1);
69952
+ },
69953
+ get cameraThumbnail() {
69954
+ return get($2);
69891
69955
  }
69892
69956
  });
69893
69957
  }