floor-editor-ts 1.4.4 → 1.4.5

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.
@@ -3988,6 +3988,52 @@ function from_html(content, flags) {
3988
3988
  };
3989
3989
  }
3990
3990
  /**
3991
+ * @param {string} content
3992
+ * @param {number} flags
3993
+ * @param {'svg' | 'math'} ns
3994
+ * @returns {() => Node | Node[]}
3995
+ */
3996
+ /* @__NO_SIDE_EFFECTS__ */
3997
+ function from_namespace(content, flags, ns = "svg") {
3998
+ /**
3999
+ * Whether or not the first item is a text/element node. If not, we need to
4000
+ * create an additional comment node to act as `effect.nodes.start`
4001
+ */
4002
+ var has_start = !content.startsWith("<!>");
4003
+ var is_fragment = (flags & 1) !== 0;
4004
+ var wrapped = `<${ns}>${has_start ? content : "<!>" + content}</${ns}>`;
4005
+ /** @type {Element | DocumentFragment} */
4006
+ var node;
4007
+ return () => {
4008
+ if (hydrating) {
4009
+ assign_nodes(hydrate_node, null);
4010
+ return hydrate_node;
4011
+ }
4012
+ if (!node) {
4013
+ var root = /* @__PURE__ */ get_first_child(create_fragment_from_html(wrapped));
4014
+ if (is_fragment) {
4015
+ node = document.createDocumentFragment();
4016
+ while (/* @__PURE__ */ get_first_child(root)) node.appendChild(/* @__PURE__ */ get_first_child(root));
4017
+ } else node = /* @__PURE__ */ get_first_child(root);
4018
+ }
4019
+ var clone = node.cloneNode(true);
4020
+ if (is_fragment) {
4021
+ var start = /* @__PURE__ */ get_first_child(clone);
4022
+ var end = clone.lastChild;
4023
+ assign_nodes(start, end);
4024
+ } else assign_nodes(clone, clone);
4025
+ return clone;
4026
+ };
4027
+ }
4028
+ /**
4029
+ * @param {string} content
4030
+ * @param {number} flags
4031
+ */
4032
+ /* @__NO_SIDE_EFFECTS__ */
4033
+ function from_svg(content, flags) {
4034
+ return /* @__PURE__ */ from_namespace(content, flags, "svg");
4035
+ }
4036
+ /**
3991
4037
  * Don't mark this as side-effect-free, hydration needs to walk all nodes
3992
4038
  * @param {any} value
3993
4039
  */
@@ -6065,6 +6111,15 @@ function resizeRectCorner(points, cornerIndex, to) {
6065
6111
  function isNearPoint(a, b, threshold) {
6066
6112
  return Math.hypot(a.x - b.x, a.y - b.y) <= threshold;
6067
6113
  }
6114
+ /** Screen/world AABB top-right corner for floating toolbar anchor. */
6115
+ function polygonToolbarAnchor(points) {
6116
+ const b = zoneBounds(points);
6117
+ if (!b) return null;
6118
+ return {
6119
+ x: b.maxX,
6120
+ y: b.minY
6121
+ };
6122
+ }
6068
6123
  //#endregion
6069
6124
  //#region src/lib/utils/cameraCoordinates.ts
6070
6125
  var FOV_PROP_KEYS = ["coordinates", "mapCoordinates"];
@@ -11177,6 +11232,23 @@ function drawTextAnnotations(cs, floor, selectedTextAnnotationId, currentSelecte
11177
11232
  ctx.restore();
11178
11233
  }
11179
11234
  }
11235
+ /** Numbered vertex badge (0, 1, 2…) — FOV / zone polygons. */
11236
+ function drawVertexIndexBadge(ctx, x, y, index, color, radius = 9) {
11237
+ ctx.save();
11238
+ ctx.beginPath();
11239
+ ctx.arc(x, y, radius, 0, Math.PI * 2);
11240
+ ctx.fillStyle = color;
11241
+ ctx.fill();
11242
+ ctx.lineWidth = 2;
11243
+ ctx.strokeStyle = "#ffffff";
11244
+ ctx.stroke();
11245
+ ctx.fillStyle = "#ffffff";
11246
+ ctx.font = `700 ${Math.max(9, Math.round(radius * 1.05))}px system-ui, sans-serif`;
11247
+ ctx.textAlign = "center";
11248
+ ctx.textBaseline = "middle";
11249
+ ctx.fillText(String(index), x, y + .5);
11250
+ ctx.restore();
11251
+ }
11180
11252
  function hexToRgba(hex, alpha) {
11181
11253
  const c = hex.trim();
11182
11254
  const short = c.match(/^#([0-9a-f]{3})$/i);
@@ -11237,15 +11309,10 @@ function drawZoneShape(cs, zone, selected) {
11237
11309
  ctx.fillStyle = color;
11238
11310
  ctx.fillText(zone.name, bx + 6, by + 4);
11239
11311
  }
11240
- if (selected) for (const p of pts) {
11241
- const s = wts(cs, p.x, p.y);
11242
- ctx.fillStyle = "#ffffff";
11243
- ctx.strokeStyle = color;
11244
- ctx.lineWidth = 1.5;
11245
- ctx.beginPath();
11246
- ctx.arc(s.x, s.y, 5, 0, Math.PI * 2);
11247
- ctx.fill();
11248
- ctx.stroke();
11312
+ const r = selected ? 9 : 7;
11313
+ for (let i = 0; i < pts.length; i++) {
11314
+ const s = wts(cs, pts[i].x, pts[i].y);
11315
+ drawVertexIndexBadge(ctx, s.x, s.y, i, color, r);
11249
11316
  }
11250
11317
  ctx.restore();
11251
11318
  }
@@ -11262,8 +11329,9 @@ function drawZoneDraft(cs, points, color, closed, cursor) {
11262
11329
  if (cursor) pts.push(cursor);
11263
11330
  ctx.save();
11264
11331
  ctx.strokeStyle = color;
11265
- ctx.fillStyle = hexToRgba(color, .08);
11266
- ctx.lineWidth = 1.5;
11332
+ ctx.fillStyle = hexToRgba(color, .12);
11333
+ ctx.lineWidth = 2;
11334
+ ctx.lineJoin = "round";
11267
11335
  ctx.setLineDash([6 * Math.max(.6, zoom), 4 * Math.max(.6, zoom)]);
11268
11336
  if (pts.length >= 2) {
11269
11337
  ctx.beginPath();
@@ -11273,21 +11341,26 @@ function drawZoneDraft(cs, points, color, closed, cursor) {
11273
11341
  const s = wts(cs, pts[i].x, pts[i].y);
11274
11342
  ctx.lineTo(s.x, s.y);
11275
11343
  }
11276
- if (closed && pts.length >= 3) {
11344
+ if (closed && points.length >= 3) {
11277
11345
  ctx.closePath();
11278
11346
  ctx.fill();
11279
11347
  }
11280
11348
  ctx.stroke();
11281
11349
  }
11282
- for (const p of points) {
11283
- const s = wts(cs, p.x, p.y);
11284
- ctx.setLineDash([]);
11285
- ctx.fillStyle = "#fff";
11286
- ctx.strokeStyle = color;
11350
+ if (!closed && cursor && points.length >= 3) {
11351
+ const a = wts(cs, cursor.x, cursor.y);
11352
+ const b = wts(cs, points[0].x, points[0].y);
11353
+ ctx.globalAlpha = .45;
11287
11354
  ctx.beginPath();
11288
- ctx.arc(s.x, s.y, 4, 0, Math.PI * 2);
11289
- ctx.fill();
11355
+ ctx.moveTo(a.x, a.y);
11356
+ ctx.lineTo(b.x, b.y);
11290
11357
  ctx.stroke();
11358
+ ctx.globalAlpha = 1;
11359
+ }
11360
+ ctx.setLineDash([]);
11361
+ for (let i = 0; i < points.length; i++) {
11362
+ const s = wts(cs, points[i].x, points[i].y);
11363
+ drawVertexIndexBadge(ctx, s.x, s.y, i, color, 9);
11291
11364
  }
11292
11365
  ctx.restore();
11293
11366
  }
@@ -60082,17 +60155,17 @@ var root_3$12 = /* @__PURE__ */ from_html(`<div class="absolute bottom-0 left-0
60082
60155
  var root_4$11 = /* @__PURE__ */ from_html(`<div class="absolute bottom-0 left-0 right-0 h-0.5 bg-slate-700 dark:bg-slate-300 rounded-t"></div>`);
60083
60156
  var root_5$8 = /* @__PURE__ */ from_html(`<div class="absolute bottom-0 left-0 right-0 h-0.5 bg-slate-700 dark:bg-slate-300 rounded-t"></div>`);
60084
60157
  var root_6$6 = /* @__PURE__ */ from_html(`<div class="space-y-4"><label class="block"><span class="text-sm font-medium text-gray-700 dark:text-gray-300">Project Name</span> <input type="text" class="mt-1 w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg text-sm focus:ring-2 focus:ring-slate-500 focus:border-slate-500 outline-none bg-white dark:bg-gray-700 dark:text-gray-100" placeholder="Untitled Project"/></label> <label class="block"><span class="text-sm font-medium text-gray-700 dark:text-gray-300">Description</span> <textarea rows="3" class="mt-1 w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg text-sm focus:ring-2 focus:ring-slate-500 focus:border-slate-500 outline-none resize-none bg-white dark:bg-gray-700 dark:text-gray-100" placeholder="Add a description for this project..."></textarea></label></div>`);
60085
- var root_7$6 = /* @__PURE__ */ from_html(`<div class="flex items-center justify-between mb-5"><span class="text-sm font-medium text-gray-700 dark:text-gray-300">Metrics unit</span> <div class="flex rounded-lg border border-gray-300 dark:border-gray-600 overflow-hidden"><button>m, cm</button> <button>ft, inch</button></div></div> <div class="bg-gray-50 dark:bg-gray-700/50 rounded-xl divide-y divide-gray-200 dark:divide-gray-600"><label class="flex items-center justify-between px-4 py-3.5 cursor-pointer"><span class="text-sm text-gray-700">Dimensions</span> <input type="checkbox" class="w-10 h-5 rounded-full appearance-none cursor-pointer bg-gray-300 checked:bg-slate-700 relative transition-colors
60158
+ var root_7$7 = /* @__PURE__ */ from_html(`<div class="flex items-center justify-between mb-5"><span class="text-sm font-medium text-gray-700 dark:text-gray-300">Metrics unit</span> <div class="flex rounded-lg border border-gray-300 dark:border-gray-600 overflow-hidden"><button>m, cm</button> <button>ft, inch</button></div></div> <div class="bg-gray-50 dark:bg-gray-700/50 rounded-xl divide-y divide-gray-200 dark:divide-gray-600"><label class="flex items-center justify-between px-4 py-3.5 cursor-pointer"><span class="text-sm text-gray-700">Dimensions</span> <input type="checkbox" class="w-10 h-5 rounded-full appearance-none cursor-pointer bg-gray-300 checked:bg-slate-700 relative transition-colors
60086
60159
  before:content-[''] before:absolute before:w-4 before:h-4 before:rounded-full before:bg-white before:top-0.5 before:left-0.5 before:transition-transform checked:before:translate-x-5"/></label> <label class="flex items-center justify-between px-4 py-3.5 cursor-pointer"><span class="text-sm text-gray-700">External Dimensions</span> <input type="checkbox" class="w-10 h-5 rounded-full appearance-none cursor-pointer bg-gray-300 checked:bg-slate-700 relative transition-colors
60087
60160
  before:content-[''] before:absolute before:w-4 before:h-4 before:rounded-full before:bg-white before:top-0.5 before:left-0.5 before:transition-transform checked:before:translate-x-5"/></label> <label class="flex items-center justify-between px-4 py-3.5 cursor-pointer"><span class="text-sm text-gray-700">Internal Dimensions</span> <input type="checkbox" class="w-10 h-5 rounded-full appearance-none cursor-pointer bg-gray-300 checked:bg-slate-700 relative transition-colors
60088
60161
  before:content-[''] before:absolute before:w-4 before:h-4 before:rounded-full before:bg-white before:top-0.5 before:left-0.5 before:transition-transform checked:before:translate-x-5"/></label> <label class="flex items-center justify-between px-4 py-3.5 cursor-pointer"><span class="text-sm text-gray-700">Extension Lines</span> <input type="checkbox" class="w-10 h-5 rounded-full appearance-none cursor-pointer bg-gray-300 checked:bg-slate-700 relative transition-colors
60089
60162
  before:content-[''] before:absolute before:w-4 before:h-4 before:rounded-full before:bg-white before:top-0.5 before:left-0.5 before:transition-transform checked:before:translate-x-5"/></label> <label class="flex items-center justify-between px-4 py-3.5 cursor-pointer"><span class="text-sm text-gray-700">Object Distance</span> <input type="checkbox" class="w-10 h-5 rounded-full appearance-none cursor-pointer bg-gray-300 checked:bg-slate-700 relative transition-colors
60090
60163
  before:content-[''] before:absolute before:w-4 before:h-4 before:rounded-full before:bg-white before:top-0.5 before:left-0.5 before:transition-transform checked:before:translate-x-5"/></label> <div class="flex items-center justify-between px-4 py-3.5"><span class="text-sm text-gray-700">Line Color</span> <div class="flex items-center gap-2"><button style="background-color: #ffffff" aria-label="White line color"></button> <span class="text-gray-300">|</span> <button style="background-color: #1e293b" aria-label="Dark line color"></button></div></div></div>`, 1);
60091
60164
  var root_9$4 = /* @__PURE__ */ from_html(`<button><span class="text-2xl"> </span> <span class="text-xs font-medium text-gray-700 dark:text-gray-300"> </span></button>`);
60092
- var root_8$5 = /* @__PURE__ */ from_html(`<div class="space-y-4"><div><span class="text-sm font-medium text-gray-700 dark:text-gray-300 block mb-3">Theme</span> <div class="flex gap-3"></div></div></div>`);
60165
+ var root_8$4 = /* @__PURE__ */ from_html(`<div class="space-y-4"><div><span class="text-sm font-medium text-gray-700 dark:text-gray-300 block mb-3">Theme</span> <div class="flex gap-3"></div></div></div>`);
60093
60166
  var root_11$5 = /* @__PURE__ */ from_html(`<button class="px-4 py-2 text-sm font-medium text-red-600 dark:text-red-400 border border-red-300 dark:border-red-600 rounded-lg hover:bg-red-50 dark:hover:bg-red-900/20 transition-colors">Remove</button>`);
60094
- var root_12$4 = /* @__PURE__ */ from_html(`<button class="px-4 py-2 text-sm font-medium text-red-600 dark:text-red-400 border border-red-300 dark:border-red-600 rounded-lg hover:bg-red-50 dark:hover:bg-red-900/20 transition-colors">Remove</button>`);
60095
- var root_10$4 = /* @__PURE__ */ from_html(`<div class="space-y-4"><div><span class="text-sm font-medium text-gray-700 dark:text-gray-300 block mb-1">Gemini API Key</span> <p class="text-xs text-gray-500 dark:text-gray-400 mb-3">Required for AI-powered photorealistic rendering. Your key is stored locally in your browser only - never sent to our servers.</p> <div class="flex gap-2"><div class="relative flex-1"><input class="w-full px-3 py-2 pr-10 border border-gray-300 dark:border-gray-600 rounded-lg text-sm font-mono focus:ring-2 focus:ring-slate-500 focus:border-slate-500 outline-none bg-white dark:bg-gray-700 dark:text-gray-100" placeholder="AIza..."/> <button class="absolute right-2 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 text-sm"> </button></div></div> <div class="flex gap-2 mt-3"><button class="px-4 py-2 text-sm font-medium bg-slate-700 text-white rounded-lg hover:bg-slate-600 transition-colors"> </button> <!></div></div> <div class="border-t border-gray-200 dark:border-gray-700 pt-4"><span class="text-sm font-medium text-gray-700 dark:text-gray-300 block mb-2">How to get a Gemini key</span> <ol class="text-xs text-gray-500 dark:text-gray-400 space-y-1 list-decimal list-inside"><li>Go to <a href="https://aistudio.google.com/apikey" target="_blank" rel="noopener" class="text-blue-500 hover:underline">Google AI Studio</a></li> <li>Click "Create API Key"</li> <li>Copy and paste it above</li></ol></div> <div class="border-t border-gray-200 dark:border-gray-700 pt-4"><span class="text-sm font-medium text-gray-700 dark:text-gray-300 block mb-1">OpenAI API Key</span> <p class="text-xs text-gray-500 dark:text-gray-400 mb-3">Optional — enables OpenAI image generation as an alternative to Gemini. Stored locally only.</p> <div class="flex gap-2"><div class="relative flex-1"><input class="w-full px-3 py-2 pr-10 border border-gray-300 dark:border-gray-600 rounded-lg text-sm font-mono focus:ring-2 focus:ring-slate-500 focus:border-slate-500 outline-none bg-white dark:bg-gray-700 dark:text-gray-100" placeholder="sk-..."/> <button class="absolute right-2 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 text-sm"> </button></div></div> <div class="flex gap-2 mt-3"><button class="px-4 py-2 text-sm font-medium bg-slate-700 text-white rounded-lg hover:bg-slate-600 transition-colors"> </button> <!></div> <div class="mt-3"><span class="text-sm font-medium text-gray-700 dark:text-gray-300 block mb-2">How to get an OpenAI key</span> <ol class="text-xs text-gray-500 dark:text-gray-400 space-y-1 list-decimal list-inside"><li>Go to <a href="https://platform.openai.com/api-keys" target="_blank" rel="noopener" class="text-blue-500 hover:underline">OpenAI Platform</a></li> <li>Click "Create new secret key"</li> <li>Copy and paste it above</li></ol></div></div></div>`);
60167
+ var root_12$3 = /* @__PURE__ */ from_html(`<button class="px-4 py-2 text-sm font-medium text-red-600 dark:text-red-400 border border-red-300 dark:border-red-600 rounded-lg hover:bg-red-50 dark:hover:bg-red-900/20 transition-colors">Remove</button>`);
60168
+ var root_10$5 = /* @__PURE__ */ from_html(`<div class="space-y-4"><div><span class="text-sm font-medium text-gray-700 dark:text-gray-300 block mb-1">Gemini API Key</span> <p class="text-xs text-gray-500 dark:text-gray-400 mb-3">Required for AI-powered photorealistic rendering. Your key is stored locally in your browser only - never sent to our servers.</p> <div class="flex gap-2"><div class="relative flex-1"><input class="w-full px-3 py-2 pr-10 border border-gray-300 dark:border-gray-600 rounded-lg text-sm font-mono focus:ring-2 focus:ring-slate-500 focus:border-slate-500 outline-none bg-white dark:bg-gray-700 dark:text-gray-100" placeholder="AIza..."/> <button class="absolute right-2 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 text-sm"> </button></div></div> <div class="flex gap-2 mt-3"><button class="px-4 py-2 text-sm font-medium bg-slate-700 text-white rounded-lg hover:bg-slate-600 transition-colors"> </button> <!></div></div> <div class="border-t border-gray-200 dark:border-gray-700 pt-4"><span class="text-sm font-medium text-gray-700 dark:text-gray-300 block mb-2">How to get a Gemini key</span> <ol class="text-xs text-gray-500 dark:text-gray-400 space-y-1 list-decimal list-inside"><li>Go to <a href="https://aistudio.google.com/apikey" target="_blank" rel="noopener" class="text-blue-500 hover:underline">Google AI Studio</a></li> <li>Click "Create API Key"</li> <li>Copy and paste it above</li></ol></div> <div class="border-t border-gray-200 dark:border-gray-700 pt-4"><span class="text-sm font-medium text-gray-700 dark:text-gray-300 block mb-1">OpenAI API Key</span> <p class="text-xs text-gray-500 dark:text-gray-400 mb-3">Optional — enables OpenAI image generation as an alternative to Gemini. Stored locally only.</p> <div class="flex gap-2"><div class="relative flex-1"><input class="w-full px-3 py-2 pr-10 border border-gray-300 dark:border-gray-600 rounded-lg text-sm font-mono focus:ring-2 focus:ring-slate-500 focus:border-slate-500 outline-none bg-white dark:bg-gray-700 dark:text-gray-100" placeholder="sk-..."/> <button class="absolute right-2 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 text-sm"> </button></div></div> <div class="flex gap-2 mt-3"><button class="px-4 py-2 text-sm font-medium bg-slate-700 text-white rounded-lg hover:bg-slate-600 transition-colors"> </button> <!></div> <div class="mt-3"><span class="text-sm font-medium text-gray-700 dark:text-gray-300 block mb-2">How to get an OpenAI key</span> <ol class="text-xs text-gray-500 dark:text-gray-400 space-y-1 list-decimal list-inside"><li>Go to <a href="https://platform.openai.com/api-keys" target="_blank" rel="noopener" class="text-blue-500 hover:underline">OpenAI Platform</a></li> <li>Click "Create new secret key"</li> <li>Copy and paste it above</li></ol></div></div></div>`);
60096
60169
  var root_1$14 = /* @__PURE__ */ from_html(`<div class="fixed inset-0 bg-black/50 z-50 flex items-center justify-center" role="dialog" tabindex="-1" aria-label="Settings"><div class="bg-white dark:bg-gray-800 rounded-xl shadow-2xl w-[420px] max-h-[80vh] flex flex-col" role="document"><div class="flex items-center justify-between px-5 pt-4 pb-2"><h2 class="text-lg font-bold text-gray-800 dark:text-gray-100">Settings</h2> <button class="text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 text-xl leading-none" aria-label="Close settings">✕</button></div> <div class="flex border-b border-gray-200 dark:border-gray-700 px-5"><button>Project <!></button> <button>Dimensions <!></button> <button>Appearance <!></button> <button>AI <!></button></div> <div class="p-5 overflow-y-auto"><!></div></div></div>`);
60097
60170
  function SettingsDialog($$anchor, $$props) {
60098
60171
  push($$props, true);
@@ -60261,7 +60334,7 @@ function SettingsDialog($$anchor, $$props) {
60261
60334
  append($$anchor, div_9);
60262
60335
  };
60263
60336
  var consequent_5 = ($$anchor) => {
60264
- var fragment_1 = root_7$6();
60337
+ var fragment_1 = root_7$7();
60265
60338
  var div_10 = first_child(fragment_1);
60266
60339
  var div_11 = sibling(child(div_10), 2);
60267
60340
  var button_5 = child(div_11);
@@ -60319,7 +60392,7 @@ function SettingsDialog($$anchor, $$props) {
60319
60392
  append($$anchor, fragment_1);
60320
60393
  };
60321
60394
  var consequent_6 = ($$anchor) => {
60322
- var div_15 = root_8$5();
60395
+ var div_15 = root_8$4();
60323
60396
  var div_16 = child(div_15);
60324
60397
  var div_17 = sibling(child(div_16), 2);
60325
60398
  each(div_17, 20, () => [
@@ -60365,7 +60438,7 @@ function SettingsDialog($$anchor, $$props) {
60365
60438
  append($$anchor, div_15);
60366
60439
  };
60367
60440
  var consequent_9 = ($$anchor) => {
60368
- var div_18 = root_10$4();
60441
+ var div_18 = root_10$5();
60369
60442
  var div_19 = child(div_18);
60370
60443
  var div_20 = sibling(child(div_19), 4);
60371
60444
  var div_21 = child(div_20);
@@ -60407,7 +60480,7 @@ function SettingsDialog($$anchor, $$props) {
60407
60480
  reset(button_14);
60408
60481
  var node_7 = sibling(button_14, 2);
60409
60482
  var consequent_8 = ($$anchor) => {
60410
- var button_15 = root_12$4();
60483
+ var button_15 = root_12$3();
60411
60484
  delegated("click", button_15, clearOpenAIKey);
60412
60485
  append($$anchor, button_15);
60413
60486
  };
@@ -60957,23 +61030,25 @@ delegate(["click", "keydown"]);
60957
61030
  init_client();
60958
61031
  init_index_client();
60959
61032
  init_onboarding_svelte();
60960
- var root_2$10 = /* @__PURE__ */ from_html(`<input type="text" class="bg-white/20 text-white font-semibold px-2 py-0.5 rounded border border-white/30 outline-none text-sm w-40"/>`);
60961
- var root_3$9 = /* @__PURE__ */ from_html(`<button class="font-semibold text-white text-sm hover:bg-white/10 px-2 py-0.5 rounded transition-colors" title="Click to rename"> </button>`);
60962
- var root_4$8 = /* @__PURE__ */ from_html(`<button> </button>`);
60963
- var root_5$5 = /* @__PURE__ */ from_html(`<button aria-label="Snap to Grid"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="7" height="7"></rect><rect x="14" y="3" width="7" height="7"></rect><rect x="14" y="14" width="7" height="7"></rect><rect x="3" y="14" width="7" height="7"></rect></svg></button>`);
60964
- var root_6$5 = /* @__PURE__ */ from_html(`<div class="flex bg-white/15 rounded-full p-0.5 shrink-0"><button title="Select mode (V)" aria-label="Select mode"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 3l7.07 16.97 2.51-7.39 7.39-2.51L3 3z"></path><path d="M13 13l6 6"></path></svg></button> <button title="Pan mode (H)" aria-label="Pan mode"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 11V6a2 2 0 0 0-4 0v1"></path><path d="M14 10V4a2 2 0 0 0-4 0v2"></path><path d="M10 10.5V6a2 2 0 0 0-4 0v8"></path><path d="M18 8a2 2 0 1 1 4 0v6a8 8 0 0 1-8 8h-2c-2.8 0-4.5-.86-5.99-2.34l-3.6-3.6a2 2 0 0 1 2.83-2.82L7 15"></path></svg></button></div>`);
60965
- var root_7$5 = /* @__PURE__ */ from_html(`<button aria-label="Toggle Furniture"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="12" width="20" height="8" rx="1"></rect><path d="M4 12V7a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v5"></path><line x1="12" y1="12" x2="12" y2="20"></line></svg></button>`);
60966
- var root_8$4 = /* @__PURE__ */ from_html(`<div class="flex items-center gap-1 bg-white/15 rounded-full p-0.5 shrink-0"><button class="w-7 h-7 flex items-center justify-center text-white/80 hover:text-white hover:bg-white/10 rounded-full transition-colors text-sm font-bold" title="Zoom Out (−)" aria-label="Zoom Out">−</button> <button class="px-2 py-1 text-xs font-medium text-white/80 hover:text-white hover:bg-white/10 rounded-full transition-colors min-w-[3rem] text-center" title="Reset Zoom (100%)"> </button> <button class="w-7 h-7 flex items-center justify-center text-white/80 hover:text-white hover:bg-white/10 rounded-full transition-colors text-sm font-bold" title="Zoom In (+)" aria-label="Zoom In">+</button></div>`);
60967
- var root_10$3 = /* @__PURE__ */ from_html(`<div class="absolute right-0 top-full mt-1 bg-white rounded-lg shadow-lg border border-gray-200 py-1 w-56 z-50" role="menu"><button type="button" role="menuitemcheckbox" class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center justify-between gap-2"><span>Snap to grid</span> <span> </span></button> <button type="button" role="menuitemcheckbox" class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center justify-between gap-2"><span>Show furniture</span> <span> </span></button> <div class="h-px bg-gray-100 my-1"></div> <button type="button" role="menuitem" class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left">Version history</button> <button type="button" role="menuitem" class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left">Area summary</button> <div class="h-px bg-gray-100 my-1"></div> <button type="button" role="menuitem" class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left">Settings…</button></div>`);
60968
- var root_9$3 = /* @__PURE__ */ from_html(`<div class="relative shrink-0"><button title="Settings &amp; tools" aria-label="Settings &amp; tools"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"></circle><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path></svg></button> <!></div>`);
60969
- var root_11$4 = /* @__PURE__ */ from_html(`<button class="p-1.5 text-white/80 hover:text-white hover:bg-white/10 rounded transition-colors" title="Version History" aria-label="Version History"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><polyline points="12 6 12 12 16 14"></polyline></svg></button> <button class="px-2 py-1.5 text-white/80 hover:text-white hover:bg-white/10 rounded transition-colors" title="Area Summary" aria-label="Area Summary"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2"></rect><path d="M3 9h18"></path><path d="M9 3v18"></path></svg></button> <button class="px-2 py-1.5 text-white/80 hover:text-white hover:bg-white/10 rounded transition-colors" title="Settings" aria-label="Settings"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"></circle><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path></svg></button>`, 1);
60970
- var root_13$2 = /* @__PURE__ */ from_html(`<button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="17 8 12 3 7 8"></polyline><line x1="12" y1="3" x2="12" y2="15"></line></svg> Import JSON</button>`);
60971
- var root_12$3 = /* @__PURE__ */ from_html(`<div class="absolute right-0 top-full mt-1 bg-white rounded-lg shadow-lg border border-gray-200 py-1 w-48 z-50"><button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="6 9 6 2 18 2 18 9"></polyline><path d="M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"></path><rect x="6" y="14" width="12" height="8"></rect></svg> Print Layout</button> <div class="h-px bg-gray-100 my-1"></div> <button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="18" height="18" rx="2"></rect><circle cx="8.5" cy="8.5" r="1.5"></circle><path d="M21 15l-5-5L5 21"></path></svg> Export 2D as PNG</button> <button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 2L2 7l10 5 10-5-10-5z"></path><path d="M2 17l10 5 10-5"></path><path d="M2 12l10 5 10-5"></path></svg> Export 3D as PNG</button> <button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 19V5"></path><path d="M5 12l7-7 7 7"></path></svg> Export as SVG</button> <button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><path d="M14 2v6h6"></path><path d="M8 16h2"></path><path d="M14 16h2"></path></svg> Export as DXF</button> <button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><path d="M14 2v6h6"></path><path d="M9 16h6"></path></svg> Export as DWG</button> <button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><path d="M14 2v6h6"></path><path d="M16 11v6"></path><path d="M8 11v6"></path><path d="M12 11v6"></path></svg> Export as PDF</button> <button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><path d="M14 2v6h6"></path></svg> Download JSON</button> <div class="h-px bg-gray-100 my-1"></div> <!> <button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="12" y1="5" x2="12" y2="19"></line><line x1="5" y1="12" x2="19" y2="12"></line></svg> New Project</button></div>`);
60972
- var root_1$11 = /* @__PURE__ */ from_html(`<div class="h-12 bg-gradient-to-r from-slate-800 to-slate-700 flex items-center px-4 gap-3 shrink-0 shadow-sm overflow-hidden"><button type="button"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="3" width="18" height="18" rx="2.5"></rect><path d="M9 3v18"></path></svg></button> <!> <div class="h-5 w-px bg-white/20"></div> <div class="flex items-center gap-1"><!> <button class="text-white/80 hover:text-white text-xs hover:bg-white/10 px-1.5 py-0.5 rounded transition-colors" title="Add Floor" aria-label="Add Floor">+</button> <span class="text-white/40 text-[10px] ml-1"> </span></div> <div class="flex-1"></div> <button class="p-1.5 text-white/80 hover:text-white hover:bg-white/10 rounded transition-colors" title="Undo (Ctrl+Z)" aria-label="Undo"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="1 4 1 10 7 10"></polyline><path d="M3.51 15a9 9 0 1 0 2.13-9.36L1 10"></path></svg></button> <button class="p-1.5 text-white/80 hover:text-white hover:bg-white/10 rounded transition-colors" title="Redo (Ctrl+Y)" aria-label="Redo"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="23 4 23 10 17 10"></polyline><path d="M20.49 15a9 9 0 1 1-2.13-9.36L23 10"></path></svg></button> <div class="h-5 w-px bg-white/20"></div> <!> <!> <!> <div class="h-5 w-px bg-white/20"></div> <!> <!> <div class="h-5 w-px bg-white/20 shrink-0"></div> <div class="relative"><button class="px-3 py-1.5 text-sm text-white/90 hover:text-white hover:bg-white/10 rounded transition-colors flex items-center gap-1.5"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="7 10 12 15 17 10"></polyline><line x1="12" y1="15" x2="12" y2="3"></line></svg> Export</button> <!></div> <span><!></span> <button class="px-3 py-1.5 text-sm bg-white text-slate-800 font-semibold rounded-lg hover:bg-blue-50 transition-colors shadow-sm">Save</button></div>`);
60973
- var root_18$2 = /* @__PURE__ */ from_html(`<div class="absolute right-0 top-full mt-1 bg-white rounded-lg shadow-lg border border-gray-200 py-1 w-48 z-50"><button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="6 9 6 2 18 2 18 9"></polyline><path d="M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"></path><rect x="6" y="14" width="12" height="8"></rect></svg> Print Layout</button> <div class="h-px bg-gray-100 my-1"></div> <button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="18" height="18" rx="2"></rect><circle cx="8.5" cy="8.5" r="1.5"></circle><path d="M21 15l-5-5L5 21"></path></svg> Export 2D as PNG</button> <button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 2L2 7l10 5 10-5-10-5z"></path><path d="M2 17l10 5 10-5"></path><path d="M2 12l10 5 10-5"></path></svg> Export 3D as PNG</button> <button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 19V5"></path><path d="M5 12l7-7 7 7"></path></svg> Export as SVG</button> <button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><path d="M14 2v6h6"></path><path d="M8 16h2"></path><path d="M14 16h2"></path></svg> Export as DXF</button> <button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><path d="M14 2v6h6"></path><path d="M9 16h6"></path></svg> Export as DWG</button> <button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><path d="M14 2v6h6"></path><path d="M16 11v6"></path><path d="M8 11v6"></path><path d="M12 11v6"></path></svg> Export as PDF</button> <button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><path d="M14 2v6h6"></path></svg> Download JSON</button> <div class="h-px bg-gray-100 my-1"></div> <button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="17 8 12 3 7 8"></polyline><line x1="12" y1="3" x2="12" y2="15"></line></svg> Import JSON</button></div>`);
60974
- var root_17$2 = /* @__PURE__ */ from_html(`<div class="h-12 bg-gradient-to-r from-slate-800 to-slate-700 flex items-center justify-between px-4 gap-3 shrink-0 shadow-sm"><span class="font-semibold text-white text-sm px-2 py-0.5 rounded transition-colors"> </span> <div class="relative"><button class="px-3 py-1.5 text-sm text-white/90 hover:text-white hover:bg-white/10 rounded transition-colors flex items-center gap-1.5"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="7 10 12 15 17 10"></polyline><line x1="12" y1="15" x2="12" y2="3"></line></svg> Import</button> <!></div></div>`);
60975
- var root_19$3 = /* @__PURE__ */ from_html(`<div class="fixed inset-0 z-50 flex items-center justify-center bg-black/40"><div class="bg-white rounded-xl shadow-2xl w-[420px] max-h-[80vh] overflow-hidden"><div class="flex items-center justify-between px-5 py-3 border-b border-gray-200"><h2 class="text-base font-semibold text-gray-800">📐 Area Summary</h2> <button class="text-gray-400 hover:text-gray-600 text-xl leading-none">&times;</button></div> <div class="overflow-y-auto max-h-[calc(80vh-52px)] p-1"><!></div></div></div>`);
60976
- var root$5 = /* @__PURE__ */ from_html(`<!> <!> <!> <!>`, 1);
61033
+ var root_3$9 = /* @__PURE__ */ from_svg(`<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M8 3v3a2 2 0 0 1-2 2H3"></path><path d="M21 8h-3a2 2 0 0 1-2-2V3"></path><path d="M3 16h3a2 2 0 0 1 2 2v3"></path><path d="M16 21v-3a2 2 0 0 1 2-2h3"></path></svg>`);
61034
+ var root_4$8 = /* @__PURE__ */ from_svg(`<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M8 3H5a2 2 0 0 0-2 2v3"></path><path d="M21 8V5a2 2 0 0 0-2-2h-3"></path><path d="M3 16v3a2 2 0 0 0 2 2h3"></path><path d="M16 21h3a2 2 0 0 0 2-2v-3"></path></svg>`);
61035
+ var root_5$5 = /* @__PURE__ */ from_html(`<input type="text" class="bg-white/20 text-white font-semibold px-2 py-0.5 rounded border border-white/30 outline-none text-sm w-40"/>`);
61036
+ var root_6$5 = /* @__PURE__ */ from_html(`<button class="font-semibold text-white text-sm hover:bg-white/10 px-2 py-0.5 rounded transition-colors" title="Click to rename"> </button>`);
61037
+ var root_7$6 = /* @__PURE__ */ from_html(`<button> </button>`);
61038
+ var root_8$3 = /* @__PURE__ */ from_html(`<button aria-label="Snap to Grid"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="7" height="7"></rect><rect x="14" y="3" width="7" height="7"></rect><rect x="14" y="14" width="7" height="7"></rect><rect x="3" y="14" width="7" height="7"></rect></svg></button>`);
61039
+ var root_9$3 = /* @__PURE__ */ from_html(`<div class="flex bg-white/15 rounded-full p-0.5 shrink-0"><button title="Select mode (V)" aria-label="Select mode"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 3l7.07 16.97 2.51-7.39 7.39-2.51L3 3z"></path><path d="M13 13l6 6"></path></svg></button> <button title="Pan mode (H)" aria-label="Pan mode"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 11V6a2 2 0 0 0-4 0v1"></path><path d="M14 10V4a2 2 0 0 0-4 0v2"></path><path d="M10 10.5V6a2 2 0 0 0-4 0v8"></path><path d="M18 8a2 2 0 1 1 4 0v6a8 8 0 0 1-8 8h-2c-2.8 0-4.5-.86-5.99-2.34l-3.6-3.6a2 2 0 0 1 2.83-2.82L7 15"></path></svg></button></div>`);
61040
+ var root_10$4 = /* @__PURE__ */ from_html(`<button aria-label="Toggle Furniture"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="12" width="20" height="8" rx="1"></rect><path d="M4 12V7a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v5"></path><line x1="12" y1="12" x2="12" y2="20"></line></svg></button>`);
61041
+ var root_11$4 = /* @__PURE__ */ from_html(`<div class="flex items-center gap-1 bg-white/15 rounded-full p-0.5 shrink-0"><button class="w-7 h-7 flex items-center justify-center text-white/80 hover:text-white hover:bg-white/10 rounded-full transition-colors text-sm font-bold" title="Zoom Out (−)" aria-label="Zoom Out">−</button> <button class="px-2 py-1 text-xs font-medium text-white/80 hover:text-white hover:bg-white/10 rounded-full transition-colors min-w-[3rem] text-center" title="Reset Zoom (100%)"> </button> <button class="w-7 h-7 flex items-center justify-center text-white/80 hover:text-white hover:bg-white/10 rounded-full transition-colors text-sm font-bold" title="Zoom In (+)" aria-label="Zoom In">+</button></div>`);
61042
+ var root_13$2 = /* @__PURE__ */ from_html(`<div class="absolute right-0 top-full mt-1 bg-white rounded-lg shadow-lg border border-gray-200 py-1 w-56 z-50" role="menu"><button type="button" role="menuitemcheckbox" class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center justify-between gap-2"><span>Snap to grid</span> <span> </span></button> <button type="button" role="menuitemcheckbox" class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center justify-between gap-2"><span>Show furniture</span> <span> </span></button> <div class="h-px bg-gray-100 my-1"></div> <button type="button" role="menuitem" class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left">Version history</button> <button type="button" role="menuitem" class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left">Area summary</button> <div class="h-px bg-gray-100 my-1"></div> <button type="button" role="menuitem" class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left">Settings…</button></div>`);
61043
+ var root_12$2 = /* @__PURE__ */ from_html(`<div class="relative shrink-0"><button title="Settings &amp; tools" aria-label="Settings &amp; tools"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"></circle><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path></svg></button> <!></div>`);
61044
+ var root_14$2 = /* @__PURE__ */ from_html(`<button class="p-1.5 text-white/80 hover:text-white hover:bg-white/10 rounded transition-colors" title="Version History" aria-label="Version History"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><polyline points="12 6 12 12 16 14"></polyline></svg></button> <button class="px-2 py-1.5 text-white/80 hover:text-white hover:bg-white/10 rounded transition-colors" title="Area Summary" aria-label="Area Summary"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2"></rect><path d="M3 9h18"></path><path d="M9 3v18"></path></svg></button> <button class="px-2 py-1.5 text-white/80 hover:text-white hover:bg-white/10 rounded transition-colors" title="Settings" aria-label="Settings"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"></circle><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path></svg></button>`, 1);
61045
+ var root_16$1 = /* @__PURE__ */ from_html(`<button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="17 8 12 3 7 8"></polyline><line x1="12" y1="3" x2="12" y2="15"></line></svg> Import JSON</button>`);
61046
+ var root_15$2 = /* @__PURE__ */ from_html(`<div class="absolute right-0 top-full mt-1 bg-white rounded-lg shadow-lg border border-gray-200 py-1 w-48 z-50"><button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="6 9 6 2 18 2 18 9"></polyline><path d="M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"></path><rect x="6" y="14" width="12" height="8"></rect></svg> Print Layout</button> <div class="h-px bg-gray-100 my-1"></div> <button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="18" height="18" rx="2"></rect><circle cx="8.5" cy="8.5" r="1.5"></circle><path d="M21 15l-5-5L5 21"></path></svg> Export 2D as PNG</button> <button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 2L2 7l10 5 10-5-10-5z"></path><path d="M2 17l10 5 10-5"></path><path d="M2 12l10 5 10-5"></path></svg> Export 3D as PNG</button> <button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 19V5"></path><path d="M5 12l7-7 7 7"></path></svg> Export as SVG</button> <button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><path d="M14 2v6h6"></path><path d="M8 16h2"></path><path d="M14 16h2"></path></svg> Export as DXF</button> <button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><path d="M14 2v6h6"></path><path d="M9 16h6"></path></svg> Export as DWG</button> <button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><path d="M14 2v6h6"></path><path d="M16 11v6"></path><path d="M8 11v6"></path><path d="M12 11v6"></path></svg> Export as PDF</button> <button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><path d="M14 2v6h6"></path></svg> Download JSON</button> <div class="h-px bg-gray-100 my-1"></div> <!> <button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="12" y1="5" x2="12" y2="19"></line><line x1="5" y1="12" x2="19" y2="12"></line></svg> New Project</button></div>`);
61047
+ var root_2$10 = /* @__PURE__ */ from_html(`<div class="h-12 bg-gradient-to-r from-slate-800 to-slate-700 flex items-center px-4 gap-3 shrink-0 shadow-sm overflow-hidden"><button type="button"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="3" width="18" height="18" rx="2.5"></rect><path d="M9 3v18"></path></svg></button> <button type="button"><!></button> <!> <div class="h-5 w-px bg-white/20"></div> <div class="flex items-center gap-1"><!> <button class="text-white/80 hover:text-white text-xs hover:bg-white/10 px-1.5 py-0.5 rounded transition-colors" title="Add Floor" aria-label="Add Floor">+</button> <span class="text-white/40 text-[10px] ml-1"> </span></div> <div class="flex-1"></div> <button class="p-1.5 text-white/80 hover:text-white hover:bg-white/10 rounded transition-colors" title="Undo (Ctrl+Z)" aria-label="Undo"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="1 4 1 10 7 10"></polyline><path d="M3.51 15a9 9 0 1 0 2.13-9.36L1 10"></path></svg></button> <button class="p-1.5 text-white/80 hover:text-white hover:bg-white/10 rounded transition-colors" title="Redo (Ctrl+Y)" aria-label="Redo"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="23 4 23 10 17 10"></polyline><path d="M20.49 15a9 9 0 1 1-2.13-9.36L23 10"></path></svg></button> <div class="h-5 w-px bg-white/20"></div> <!> <!> <!> <div class="h-5 w-px bg-white/20"></div> <!> <!> <div class="h-5 w-px bg-white/20 shrink-0"></div> <div class="relative"><button class="px-3 py-1.5 text-sm text-white/90 hover:text-white hover:bg-white/10 rounded transition-colors flex items-center gap-1.5"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="7 10 12 15 17 10"></polyline><line x1="12" y1="15" x2="12" y2="3"></line></svg> Export</button> <!></div> <span><!></span> <button class="px-3 py-1.5 text-sm bg-white text-slate-800 font-semibold rounded-lg hover:bg-blue-50 transition-colors shadow-sm">Save</button></div>`);
61048
+ var root_21$3 = /* @__PURE__ */ from_html(`<div class="absolute right-0 top-full mt-1 bg-white rounded-lg shadow-lg border border-gray-200 py-1 w-48 z-50"><button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="6 9 6 2 18 2 18 9"></polyline><path d="M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"></path><rect x="6" y="14" width="12" height="8"></rect></svg> Print Layout</button> <div class="h-px bg-gray-100 my-1"></div> <button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="18" height="18" rx="2"></rect><circle cx="8.5" cy="8.5" r="1.5"></circle><path d="M21 15l-5-5L5 21"></path></svg> Export 2D as PNG</button> <button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 2L2 7l10 5 10-5-10-5z"></path><path d="M2 17l10 5 10-5"></path><path d="M2 12l10 5 10-5"></path></svg> Export 3D as PNG</button> <button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 19V5"></path><path d="M5 12l7-7 7 7"></path></svg> Export as SVG</button> <button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><path d="M14 2v6h6"></path><path d="M8 16h2"></path><path d="M14 16h2"></path></svg> Export as DXF</button> <button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><path d="M14 2v6h6"></path><path d="M9 16h6"></path></svg> Export as DWG</button> <button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><path d="M14 2v6h6"></path><path d="M16 11v6"></path><path d="M8 11v6"></path><path d="M12 11v6"></path></svg> Export as PDF</button> <button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><path d="M14 2v6h6"></path></svg> Download JSON</button> <div class="h-px bg-gray-100 my-1"></div> <button class="w-full px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left flex items-center gap-2"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="17 8 12 3 7 8"></polyline><line x1="12" y1="3" x2="12" y2="15"></line></svg> Import JSON</button></div>`);
61049
+ var root_20$3 = /* @__PURE__ */ from_html(`<div class="h-12 bg-gradient-to-r from-slate-800 to-slate-700 flex items-center justify-between px-4 gap-3 shrink-0 shadow-sm"><span class="font-semibold text-white text-sm px-2 py-0.5 rounded transition-colors"> </span> <div class="relative"><button class="px-3 py-1.5 text-sm text-white/90 hover:text-white hover:bg-white/10 rounded transition-colors flex items-center gap-1.5"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="7 10 12 15 17 10"></polyline><line x1="12" y1="15" x2="12" y2="3"></line></svg> Import</button> <!></div></div>`);
61050
+ var root_22$3 = /* @__PURE__ */ from_html(`<div class="fixed inset-0 z-50 flex items-center justify-center bg-black/40"><div class="bg-white rounded-xl shadow-2xl w-[420px] max-h-[80vh] overflow-hidden"><div class="flex items-center justify-between px-5 py-3 border-b border-gray-200"><h2 class="text-base font-semibold text-gray-800">📐 Area Summary</h2> <button class="text-gray-400 hover:text-gray-600 text-xl leading-none">&times;</button></div> <div class="overflow-y-auto max-h-[calc(80vh-52px)] p-1"><!></div></div></div>`);
61051
+ var root_1$11 = /* @__PURE__ */ from_html(`<!> <!> <!> <!>`, 1);
60977
61052
  function TopBar($$anchor, $$props) {
60978
61053
  push($$props, true);
60979
61054
  const $panMode = () => store_get(panMode, "$panMode", $$stores);
@@ -60991,6 +61066,7 @@ function TopBar($$anchor, $$props) {
60991
61066
  let headerNarrow = /* @__PURE__ */ state(false);
60992
61067
  let headerEl = /* @__PURE__ */ state(void 0);
60993
61068
  let toolsMenuRef = /* @__PURE__ */ state(void 0);
61069
+ let isFullscreen = /* @__PURE__ */ state(false);
60994
61070
  const useCompactTools = /* @__PURE__ */ user_derived(() => headerToolsMode() === "compact" || headerToolsMode() === "auto" && get(headerNarrow));
60995
61071
  let projectName = /* @__PURE__ */ state("");
60996
61072
  let mode = /* @__PURE__ */ state("2d");
@@ -61024,6 +61100,29 @@ function TopBar($$anchor, $$props) {
61024
61100
  if (get(floors).length <= 1) return;
61025
61101
  removeFloor(id);
61026
61102
  }
61103
+ /** Fullscreen the web-component host (or documentElement in standalone). */
61104
+ function fullscreenTarget() {
61105
+ var _$$get;
61106
+ const root = (_$$get = get(headerEl)) === null || _$$get === void 0 ? void 0 : _$$get.getRootNode();
61107
+ if (root instanceof ShadowRoot && root.host instanceof HTMLElement) return root.host;
61108
+ return document.documentElement;
61109
+ }
61110
+ function syncFullscreenState() {
61111
+ const el = fullscreenTarget();
61112
+ set(isFullscreen, document.fullscreenElement === el || !!document.fullscreenElement, true);
61113
+ }
61114
+ async function toggleFullscreen() {
61115
+ try {
61116
+ if (document.fullscreenElement) await document.exitFullscreen();
61117
+ else await fullscreenTarget().requestFullscreen();
61118
+ } catch (_unused) {}
61119
+ syncFullscreenState();
61120
+ }
61121
+ user_effect(() => {
61122
+ const onFs = () => syncFullscreenState();
61123
+ document.addEventListener("fullscreenchange", onFs);
61124
+ return () => document.removeEventListener("fullscreenchange", onFs);
61125
+ });
61027
61126
  async function save() {
61028
61127
  const p = get$1(currentProject);
61029
61128
  console.log("🚀 ~ save ~ p:", p);
@@ -61202,250 +61301,263 @@ function TopBar($$anchor, $$props) {
61202
61301
  input.click();
61203
61302
  set(exportOpen, false);
61204
61303
  }
61205
- var fragment = root$5();
61304
+ var fragment = root_1$11();
61206
61305
  var node = first_child(fragment);
61207
- var consequent_11 = ($$anchor) => {
61208
- var div = root_1$11();
61306
+ var consequent_12 = ($$anchor) => {
61307
+ var div = root_2$10();
61209
61308
  var button = child(div);
61210
- var node_1 = sibling(button, 2);
61309
+ var button_1 = sibling(button, 2);
61310
+ var node_1 = child(button_1);
61211
61311
  var consequent = ($$anchor) => {
61212
- var input_1 = root_2$10();
61312
+ append($$anchor, root_3$9());
61313
+ };
61314
+ var alternate = ($$anchor) => {
61315
+ append($$anchor, root_4$8());
61316
+ };
61317
+ if_block(node_1, ($$render) => {
61318
+ if (get(isFullscreen)) $$render(consequent);
61319
+ else $$render(alternate, -1);
61320
+ });
61321
+ reset(button_1);
61322
+ var node_2 = sibling(button_1, 2);
61323
+ var consequent_1 = ($$anchor) => {
61324
+ var input_1 = root_5$5();
61213
61325
  remove_input_defaults(input_1);
61214
61326
  event("blur", input_1, onNameBlur);
61215
61327
  delegated("keydown", input_1, onNameKeydown);
61216
61328
  bind_value(input_1, () => get(projectName), ($$value) => set(projectName, $$value));
61217
61329
  append($$anchor, input_1);
61218
61330
  };
61219
- var alternate = ($$anchor) => {
61220
- var button_1 = root_3$9();
61221
- var text_1 = child(button_1, true);
61222
- reset(button_1);
61331
+ var alternate_1 = ($$anchor) => {
61332
+ var button_2 = root_6$5();
61333
+ var text_1 = child(button_2, true);
61334
+ reset(button_2);
61223
61335
  template_effect(() => set_text(text_1, get(projectName)));
61224
- delegated("click", button_1, () => set(editingName, true));
61225
- append($$anchor, button_1);
61336
+ delegated("click", button_2, () => set(editingName, true));
61337
+ append($$anchor, button_2);
61226
61338
  };
61227
- if_block(node_1, ($$render) => {
61228
- if (get(editingName)) $$render(consequent);
61229
- else $$render(alternate, -1);
61339
+ if_block(node_2, ($$render) => {
61340
+ if (get(editingName)) $$render(consequent_1);
61341
+ else $$render(alternate_1, -1);
61230
61342
  });
61231
- var div_1 = sibling(node_1, 4);
61232
- var node_2 = child(div_1);
61233
- each(node_2, 17, () => get(floors), index$1, ($$anchor, fl) => {
61234
- var button_2 = root_4$8();
61235
- var text_2 = child(button_2, true);
61236
- reset(button_2);
61343
+ var div_1 = sibling(node_2, 4);
61344
+ var node_3 = child(div_1);
61345
+ each(node_3, 17, () => get(floors), index$1, ($$anchor, fl) => {
61346
+ var button_3 = root_7$6();
61347
+ var text_2 = child(button_3, true);
61348
+ reset(button_3);
61237
61349
  template_effect(() => {
61238
- set_class(button_2, 1, `px-2 py-0.5 text-xs rounded transition-colors ${get(fl).id === get(activeFloorId) ? "bg-white text-slate-800 font-semibold" : "text-white/80 hover:bg-white/10"}`);
61239
- set_attribute(button_2, "title", get(fl).id === get(activeFloorId) ? "Active floor (dbl-click to remove)" : "Click to switch, dbl-click to remove");
61350
+ set_class(button_3, 1, `px-2 py-0.5 text-xs rounded transition-colors ${get(fl).id === get(activeFloorId) ? "bg-white text-slate-800 font-semibold" : "text-white/80 hover:bg-white/10"}`);
61351
+ set_attribute(button_3, "title", get(fl).id === get(activeFloorId) ? "Active floor (dbl-click to remove)" : "Click to switch, dbl-click to remove");
61240
61352
  set_text(text_2, get(fl).name);
61241
61353
  });
61242
- delegated("click", button_2, () => setActiveFloor(get(fl).id));
61243
- delegated("dblclick", button_2, () => onRemoveFloor(get(fl).id));
61244
- append($$anchor, button_2);
61354
+ delegated("click", button_3, () => setActiveFloor(get(fl).id));
61355
+ delegated("dblclick", button_3, () => onRemoveFloor(get(fl).id));
61356
+ append($$anchor, button_3);
61245
61357
  });
61246
- var button_3 = sibling(node_2, 2);
61247
- var span = sibling(button_3, 2);
61358
+ var button_4 = sibling(node_3, 2);
61359
+ var span = sibling(button_4, 2);
61248
61360
  var text_3 = child(span);
61249
61361
  reset(span);
61250
61362
  reset(div_1);
61251
- var button_4 = sibling(div_1, 4);
61252
- var button_5 = sibling(button_4, 2);
61253
- var node_3 = sibling(button_5, 4);
61254
- var consequent_1 = ($$anchor) => {
61255
- var button_6 = root_5$5();
61256
- template_effect(() => {
61257
- set_class(button_6, 1, `p-1.5 rounded transition-colors ${get(snapOn) ? "text-white bg-white/20" : "text-white/40 hover:text-white/70 hover:bg-white/10"}`);
61258
- set_attribute(button_6, "title", `Snap to Grid (${get(snapOn) ? "On" : "Off"})`);
61259
- });
61260
- delegated("click", button_6, toggleSnap);
61261
- append($$anchor, button_6);
61262
- };
61263
- if_block(node_3, ($$render) => {
61264
- if (!get(useCompactTools)) $$render(consequent_1);
61265
- });
61266
- var node_4 = sibling(node_3, 2);
61363
+ var button_5 = sibling(div_1, 4);
61364
+ var button_6 = sibling(button_5, 2);
61365
+ var node_4 = sibling(button_6, 4);
61267
61366
  var consequent_2 = ($$anchor) => {
61268
- var div_2 = root_6$5();
61269
- var button_7 = child(div_2);
61270
- var button_8 = sibling(button_7, 2);
61271
- reset(div_2);
61367
+ var button_7 = root_8$3();
61272
61368
  template_effect(() => {
61273
- set_class(button_7, 1, `px-2 py-1 text-xs font-semibold rounded-full transition-colors ${!$panMode() ? "bg-white text-slate-800" : "text-white/80 hover:text-white"}`);
61274
- set_class(button_8, 1, `px-2 py-1 text-xs font-semibold rounded-full transition-colors ${$panMode() ? "bg-white text-slate-800" : "text-white/80 hover:text-white"}`);
61369
+ set_class(button_7, 1, `p-1.5 rounded transition-colors ${get(snapOn) ? "text-white bg-white/20" : "text-white/40 hover:text-white/70 hover:bg-white/10"}`);
61370
+ set_attribute(button_7, "title", `Snap to Grid (${get(snapOn) ? "On" : "Off"})`);
61275
61371
  });
61276
- delegated("click", button_7, () => panMode.set(false));
61277
- delegated("click", button_8, () => panMode.set(true));
61278
- append($$anchor, div_2);
61372
+ delegated("click", button_7, toggleSnap);
61373
+ append($$anchor, button_7);
61279
61374
  };
61280
61375
  if_block(node_4, ($$render) => {
61281
- if (get(mode) === "2d") $$render(consequent_2);
61376
+ if (!get(useCompactTools)) $$render(consequent_2);
61282
61377
  });
61283
61378
  var node_5 = sibling(node_4, 2);
61284
61379
  var consequent_3 = ($$anchor) => {
61285
- var button_9 = root_7$5();
61380
+ var div_2 = root_9$3();
61381
+ var button_8 = child(div_2);
61382
+ var button_9 = sibling(button_8, 2);
61383
+ reset(div_2);
61286
61384
  template_effect(() => {
61287
- set_class(button_9, 1, `p-1.5 rounded transition-colors ${$showFurnitureStore() ? "text-white bg-white/20" : "text-white/40 hover:text-white/70 hover:bg-white/10"}`);
61288
- set_attribute(button_9, "title", `Toggle Furniture (${$showFurnitureStore() ? "Visible" : "Hidden"})`);
61385
+ set_class(button_8, 1, `px-2 py-1 text-xs font-semibold rounded-full transition-colors ${!$panMode() ? "bg-white text-slate-800" : "text-white/80 hover:text-white"}`);
61386
+ set_class(button_9, 1, `px-2 py-1 text-xs font-semibold rounded-full transition-colors ${$panMode() ? "bg-white text-slate-800" : "text-white/80 hover:text-white"}`);
61289
61387
  });
61290
- delegated("click", button_9, toggleFurniture);
61291
- append($$anchor, button_9);
61388
+ delegated("click", button_8, () => panMode.set(false));
61389
+ delegated("click", button_9, () => panMode.set(true));
61390
+ append($$anchor, div_2);
61292
61391
  };
61293
61392
  if_block(node_5, ($$render) => {
61294
- if (!get(useCompactTools)) $$render(consequent_3);
61393
+ if (get(mode) === "2d") $$render(consequent_3);
61295
61394
  });
61296
- var node_6 = sibling(node_5, 4);
61395
+ var node_6 = sibling(node_5, 2);
61297
61396
  var consequent_4 = ($$anchor) => {
61298
- var div_3 = root_8$4();
61299
- var button_10 = child(div_3);
61300
- var button_11 = sibling(button_10, 2);
61301
- var text_4 = child(button_11);
61302
- reset(button_11);
61397
+ var button_10 = root_10$4();
61398
+ template_effect(() => {
61399
+ set_class(button_10, 1, `p-1.5 rounded transition-colors ${$showFurnitureStore() ? "text-white bg-white/20" : "text-white/40 hover:text-white/70 hover:bg-white/10"}`);
61400
+ set_attribute(button_10, "title", `Toggle Furniture (${$showFurnitureStore() ? "Visible" : "Hidden"})`);
61401
+ });
61402
+ delegated("click", button_10, toggleFurniture);
61403
+ append($$anchor, button_10);
61404
+ };
61405
+ if_block(node_6, ($$render) => {
61406
+ if (!get(useCompactTools)) $$render(consequent_4);
61407
+ });
61408
+ var node_7 = sibling(node_6, 4);
61409
+ var consequent_5 = ($$anchor) => {
61410
+ var div_3 = root_11$4();
61411
+ var button_11 = child(div_3);
61303
61412
  var button_12 = sibling(button_11, 2);
61413
+ var text_4 = child(button_12);
61414
+ reset(button_12);
61415
+ var button_13 = sibling(button_12, 2);
61304
61416
  reset(div_3);
61305
61417
  template_effect(($0) => set_text(text_4, `${$0 !== null && $0 !== void 0 ? $0 : ""}%`), [() => Math.round($canvasZoom() * 100)]);
61306
- delegated("click", button_10, () => canvasZoom.update((z) => Math.max(.1, z / 1.25)));
61307
- delegated("click", button_11, () => canvasZoom.set(1));
61308
- delegated("click", button_12, () => canvasZoom.update((z) => Math.min(10, z * 1.25)));
61418
+ delegated("click", button_11, () => canvasZoom.update((z) => Math.max(.1, z / 1.25)));
61419
+ delegated("click", button_12, () => canvasZoom.set(1));
61420
+ delegated("click", button_13, () => canvasZoom.update((z) => Math.min(10, z * 1.25)));
61309
61421
  append($$anchor, div_3);
61310
61422
  };
61311
- if_block(node_6, ($$render) => {
61312
- if (get(mode) === "2d") $$render(consequent_4);
61423
+ if_block(node_7, ($$render) => {
61424
+ if (get(mode) === "2d") $$render(consequent_5);
61313
61425
  });
61314
- var node_7 = sibling(node_6, 2);
61315
- var consequent_6 = ($$anchor) => {
61316
- var div_4 = root_9$3();
61317
- var button_13 = child(div_4);
61318
- var node_8 = sibling(button_13, 2);
61319
- var consequent_5 = ($$anchor) => {
61320
- var div_5 = root_10$3();
61321
- var button_14 = child(div_5);
61322
- var span_1 = sibling(child(button_14), 2);
61426
+ var node_8 = sibling(node_7, 2);
61427
+ var consequent_7 = ($$anchor) => {
61428
+ var div_4 = root_12$2();
61429
+ var button_14 = child(div_4);
61430
+ var node_9 = sibling(button_14, 2);
61431
+ var consequent_6 = ($$anchor) => {
61432
+ var div_5 = root_13$2();
61433
+ var button_15 = child(div_5);
61434
+ var span_1 = sibling(child(button_15), 2);
61323
61435
  var text_5 = child(span_1, true);
61324
61436
  reset(span_1);
61325
- reset(button_14);
61326
- var button_15 = sibling(button_14, 2);
61327
- var span_2 = sibling(child(button_15), 2);
61437
+ reset(button_15);
61438
+ var button_16 = sibling(button_15, 2);
61439
+ var span_2 = sibling(child(button_16), 2);
61328
61440
  var text_6 = child(span_2, true);
61329
61441
  reset(span_2);
61330
- reset(button_15);
61331
- var button_16 = sibling(button_15, 4);
61332
- var button_17 = sibling(button_16, 2);
61333
- var button_18 = sibling(button_17, 4);
61442
+ reset(button_16);
61443
+ var button_17 = sibling(button_16, 4);
61444
+ var button_18 = sibling(button_17, 2);
61445
+ var button_19 = sibling(button_18, 4);
61334
61446
  reset(div_5);
61335
61447
  template_effect(() => {
61336
- set_attribute(button_14, "aria-checked", get(snapOn));
61448
+ set_attribute(button_15, "aria-checked", get(snapOn));
61337
61449
  set_class(span_1, 1, `text-xs font-medium ${get(snapOn) ? "text-emerald-600" : "text-gray-400"}`);
61338
61450
  set_text(text_5, get(snapOn) ? "On" : "Off");
61339
- set_attribute(button_15, "aria-checked", $showFurnitureStore());
61451
+ set_attribute(button_16, "aria-checked", $showFurnitureStore());
61340
61452
  set_class(span_2, 1, `text-xs font-medium ${$showFurnitureStore() ? "text-emerald-600" : "text-gray-400"}`);
61341
61453
  set_text(text_6, $showFurnitureStore() ? "On" : "Off");
61342
61454
  });
61343
- delegated("click", button_14, toggleSnap);
61344
- delegated("click", button_15, toggleFurniture);
61345
- delegated("click", button_16, () => {
61455
+ delegated("click", button_15, toggleSnap);
61456
+ delegated("click", button_16, toggleFurniture);
61457
+ delegated("click", button_17, () => {
61346
61458
  set(toolsMenuOpen, false);
61347
61459
  set(versionHistoryOpen, true);
61348
61460
  });
61349
- delegated("click", button_17, () => {
61461
+ delegated("click", button_18, () => {
61350
61462
  set(toolsMenuOpen, false);
61351
61463
  set(areaOpen, true);
61352
61464
  });
61353
- delegated("click", button_18, () => {
61465
+ delegated("click", button_19, () => {
61354
61466
  set(toolsMenuOpen, false);
61355
61467
  set(settingsOpen, true);
61356
61468
  });
61357
61469
  append($$anchor, div_5);
61358
61470
  };
61359
- if_block(node_8, ($$render) => {
61360
- if (get(toolsMenuOpen)) $$render(consequent_5);
61471
+ if_block(node_9, ($$render) => {
61472
+ if (get(toolsMenuOpen)) $$render(consequent_6);
61361
61473
  });
61362
61474
  reset(div_4);
61363
61475
  bind_this(div_4, ($$value) => set(toolsMenuRef, $$value), () => get(toolsMenuRef));
61364
61476
  template_effect(() => {
61365
- set_class(button_13, 1, `px-2 py-1.5 text-white/80 hover:text-white hover:bg-white/10 rounded transition-colors ${get(toolsMenuOpen) ? "bg-white/15 text-white" : ""}`);
61366
- set_attribute(button_13, "aria-expanded", get(toolsMenuOpen));
61477
+ set_class(button_14, 1, `px-2 py-1.5 text-white/80 hover:text-white hover:bg-white/10 rounded transition-colors ${get(toolsMenuOpen) ? "bg-white/15 text-white" : ""}`);
61478
+ set_attribute(button_14, "aria-expanded", get(toolsMenuOpen));
61367
61479
  });
61368
- delegated("click", button_13, () => set(toolsMenuOpen, !get(toolsMenuOpen)));
61480
+ delegated("click", button_14, () => set(toolsMenuOpen, !get(toolsMenuOpen)));
61369
61481
  append($$anchor, div_4);
61370
61482
  };
61371
- var alternate_1 = ($$anchor) => {
61372
- var fragment_1 = root_11$4();
61373
- var button_19 = first_child(fragment_1);
61374
- var button_20 = sibling(button_19, 2);
61483
+ var alternate_2 = ($$anchor) => {
61484
+ var fragment_1 = root_14$2();
61485
+ var button_20 = first_child(fragment_1);
61375
61486
  var button_21 = sibling(button_20, 2);
61376
- delegated("click", button_19, () => set(versionHistoryOpen, true));
61377
- delegated("click", button_20, () => set(areaOpen, true));
61378
- delegated("click", button_21, () => set(settingsOpen, true));
61487
+ var button_22 = sibling(button_21, 2);
61488
+ delegated("click", button_20, () => set(versionHistoryOpen, true));
61489
+ delegated("click", button_21, () => set(areaOpen, true));
61490
+ delegated("click", button_22, () => set(settingsOpen, true));
61379
61491
  append($$anchor, fragment_1);
61380
61492
  };
61381
- if_block(node_7, ($$render) => {
61382
- if (get(useCompactTools)) $$render(consequent_6);
61383
- else $$render(alternate_1, -1);
61493
+ if_block(node_8, ($$render) => {
61494
+ if (get(useCompactTools)) $$render(consequent_7);
61495
+ else $$render(alternate_2, -1);
61384
61496
  });
61385
- var div_6 = sibling(node_7, 4);
61386
- var button_22 = child(div_6);
61387
- var node_9 = sibling(button_22, 2);
61388
- var consequent_8 = ($$anchor) => {
61389
- var div_7 = root_12$3();
61390
- var button_23 = child(div_7);
61391
- var button_24 = sibling(button_23, 4);
61392
- var button_25 = sibling(button_24, 2);
61497
+ var div_6 = sibling(node_8, 4);
61498
+ var button_23 = child(div_6);
61499
+ var node_10 = sibling(button_23, 2);
61500
+ var consequent_9 = ($$anchor) => {
61501
+ var div_7 = root_15$2();
61502
+ var button_24 = child(div_7);
61503
+ var button_25 = sibling(button_24, 4);
61393
61504
  var button_26 = sibling(button_25, 2);
61394
61505
  var button_27 = sibling(button_26, 2);
61395
61506
  var button_28 = sibling(button_27, 2);
61396
61507
  var button_29 = sibling(button_28, 2);
61397
61508
  var button_30 = sibling(button_29, 2);
61398
- var node_10 = sibling(button_30, 4);
61399
- var consequent_7 = ($$anchor) => {
61400
- var button_31 = root_13$2();
61401
- delegated("click", button_31, onImportJSON);
61402
- append($$anchor, button_31);
61509
+ var button_31 = sibling(button_30, 2);
61510
+ var node_11 = sibling(button_31, 4);
61511
+ var consequent_8 = ($$anchor) => {
61512
+ var button_32 = root_16$1();
61513
+ delegated("click", button_32, onImportJSON);
61514
+ append($$anchor, button_32);
61403
61515
  };
61404
- if_block(node_10, ($$render) => {
61405
- if (!$$props.viewOnly) $$render(consequent_7);
61516
+ if_block(node_11, ($$render) => {
61517
+ if (!$$props.viewOnly) $$render(consequent_8);
61406
61518
  });
61407
- var button_32 = sibling(node_10, 2);
61519
+ var button_33 = sibling(node_11, 2);
61408
61520
  reset(div_7);
61409
- delegated("click", button_23, () => {
61521
+ delegated("click", button_24, () => {
61410
61522
  set(exportOpen, false);
61411
61523
  window.dispatchEvent(new KeyboardEvent("keydown", {
61412
61524
  key: "p",
61413
61525
  ctrlKey: true
61414
61526
  }));
61415
61527
  });
61416
- delegated("click", button_24, onExport2DPNG);
61417
- delegated("click", button_25, onExport3DPNG);
61418
- delegated("click", button_26, onExportSVG);
61419
- delegated("click", button_27, onExportDXF);
61420
- delegated("click", button_28, onExportDWG);
61421
- delegated("click", button_29, onExportPDF);
61422
- delegated("click", button_30, onExportJSON);
61423
- delegated("click", button_32, newProject);
61528
+ delegated("click", button_25, onExport2DPNG);
61529
+ delegated("click", button_26, onExport3DPNG);
61530
+ delegated("click", button_27, onExportSVG);
61531
+ delegated("click", button_28, onExportDXF);
61532
+ delegated("click", button_29, onExportDWG);
61533
+ delegated("click", button_30, onExportPDF);
61534
+ delegated("click", button_31, onExportJSON);
61535
+ delegated("click", button_33, newProject);
61424
61536
  append($$anchor, div_7);
61425
61537
  };
61426
- if_block(node_9, ($$render) => {
61427
- if (get(exportOpen)) $$render(consequent_8);
61538
+ if_block(node_10, ($$render) => {
61539
+ if (get(exportOpen)) $$render(consequent_9);
61428
61540
  });
61429
61541
  reset(div_6);
61430
61542
  bind_this(div_6, ($$value) => exportRef = $$value, () => exportRef);
61431
61543
  var span_3 = sibling(div_6, 2);
61432
- var node_11 = child(span_3);
61433
- var consequent_9 = ($$anchor) => {
61544
+ var node_12 = child(span_3);
61545
+ var consequent_10 = ($$anchor) => {
61434
61546
  append($$anchor, text$1("Saving…"));
61435
61547
  };
61436
- var consequent_10 = ($$anchor) => {
61548
+ var consequent_11 = ($$anchor) => {
61437
61549
  append($$anchor, text$1("Saved ✓"));
61438
61550
  };
61439
- var alternate_2 = ($$anchor) => {
61551
+ var alternate_3 = ($$anchor) => {
61440
61552
  append($$anchor, text$1("Unsaved •"));
61441
61553
  };
61442
- if_block(node_11, ($$render) => {
61443
- if ($saveState() === "saving") $$render(consequent_9);
61444
- else if ($saveState() === "saved") $$render(consequent_10, 1);
61445
- else $$render(alternate_2, -1);
61554
+ if_block(node_12, ($$render) => {
61555
+ if ($saveState() === "saving") $$render(consequent_10);
61556
+ else if ($saveState() === "saved") $$render(consequent_11, 1);
61557
+ else $$render(alternate_3, -1);
61446
61558
  });
61447
61559
  reset(span_3);
61448
- var button_33 = sibling(span_3, 2);
61560
+ var button_34 = sibling(span_3, 2);
61449
61561
  reset(div);
61450
61562
  bind_this(div, ($$value) => set(headerEl, $$value), () => get(headerEl));
61451
61563
  template_effect(() => {
@@ -61454,81 +61566,86 @@ function TopBar($$anchor, $$props) {
61454
61566
  set_attribute(button, "title", showBuildSidebar() ? "Hide sidebar" : "Show sidebar");
61455
61567
  set_attribute(button, "aria-label", showBuildSidebar() ? "Hide sidebar" : "Show sidebar");
61456
61568
  set_attribute(button, "aria-pressed", showBuildSidebar());
61569
+ set_class(button_1, 1, `shrink-0 w-8 h-8 rounded-md flex items-center justify-center text-white/80 hover:text-white hover:bg-white/10 transition-colors ${get(isFullscreen) ? "bg-white/15 text-white" : ""}`);
61570
+ set_attribute(button_1, "title", get(isFullscreen) ? "Exit fullscreen (Esc)" : "Fullscreen editor");
61571
+ set_attribute(button_1, "aria-label", get(isFullscreen) ? "Exit fullscreen" : "Enter fullscreen");
61572
+ set_attribute(button_1, "aria-pressed", get(isFullscreen));
61457
61573
  set_text(text_3, `${(_$$get$length = get(floors).length) !== null && _$$get$length !== void 0 ? _$$get$length : ""}F`);
61458
61574
  set_class(span_3, 1, `text-[11px] font-medium transition-all duration-300 ${$saveState() === "saved" ? "text-emerald-400" : $saveState() === "saving" ? "text-amber-300 animate-pulse" : "text-white/50"}`);
61459
61575
  set_attribute(span_3, "title", get(lastSavedText) || "Not saved yet");
61460
61576
  });
61461
61577
  delegated("click", button, () => showBuildSidebar(!showBuildSidebar()));
61462
- delegated("click", button_3, onAddFloor);
61463
- delegated("click", button_4, function(...$$args) {
61578
+ delegated("click", button_1, toggleFullscreen);
61579
+ delegated("click", button_4, onAddFloor);
61580
+ delegated("click", button_5, function(...$$args) {
61464
61581
  undo === null || undo === void 0 || undo.apply(this, $$args);
61465
61582
  });
61466
- delegated("click", button_5, function(...$$args) {
61583
+ delegated("click", button_6, function(...$$args) {
61467
61584
  redo === null || redo === void 0 || redo.apply(this, $$args);
61468
61585
  });
61469
- delegated("click", button_22, () => {
61586
+ delegated("click", button_23, () => {
61470
61587
  set(exportOpen, !get(exportOpen));
61471
61588
  if (get(exportOpen)) triggerTip("first-export", 300, 60);
61472
61589
  });
61473
- delegated("click", button_33, save);
61590
+ delegated("click", button_34, save);
61474
61591
  append($$anchor, div);
61475
61592
  };
61476
- var alternate_3 = ($$anchor) => {
61477
- var div_8 = root_17$2();
61593
+ var alternate_4 = ($$anchor) => {
61594
+ var div_8 = root_20$3();
61478
61595
  var span_4 = child(div_8);
61479
61596
  var text_10 = child(span_4, true);
61480
61597
  reset(span_4);
61481
61598
  var div_9 = sibling(span_4, 2);
61482
- var button_34 = child(div_9);
61483
- var node_12 = sibling(button_34, 2);
61484
- var consequent_12 = ($$anchor) => {
61485
- var div_10 = root_18$2();
61486
- var button_35 = child(div_10);
61487
- var button_36 = sibling(button_35, 4);
61488
- var button_37 = sibling(button_36, 2);
61599
+ var button_35 = child(div_9);
61600
+ var node_13 = sibling(button_35, 2);
61601
+ var consequent_13 = ($$anchor) => {
61602
+ var div_10 = root_21$3();
61603
+ var button_36 = child(div_10);
61604
+ var button_37 = sibling(button_36, 4);
61489
61605
  var button_38 = sibling(button_37, 2);
61490
61606
  var button_39 = sibling(button_38, 2);
61491
61607
  var button_40 = sibling(button_39, 2);
61492
61608
  var button_41 = sibling(button_40, 2);
61493
61609
  var button_42 = sibling(button_41, 2);
61494
- var button_43 = sibling(button_42, 4);
61610
+ var button_43 = sibling(button_42, 2);
61611
+ var button_44 = sibling(button_43, 4);
61495
61612
  reset(div_10);
61496
- delegated("click", button_35, () => {
61613
+ delegated("click", button_36, () => {
61497
61614
  set(exportOpen, false);
61498
61615
  window.dispatchEvent(new KeyboardEvent("keydown", {
61499
61616
  key: "p",
61500
61617
  ctrlKey: true
61501
61618
  }));
61502
61619
  });
61503
- delegated("click", button_36, onExport2DPNG);
61504
- delegated("click", button_37, onExport3DPNG);
61505
- delegated("click", button_38, onExportSVG);
61506
- delegated("click", button_39, onExportDXF);
61507
- delegated("click", button_40, onExportDWG);
61508
- delegated("click", button_41, onExportPDF);
61509
- delegated("click", button_42, onExportJSON);
61510
- delegated("click", button_43, onImportJSON);
61620
+ delegated("click", button_37, onExport2DPNG);
61621
+ delegated("click", button_38, onExport3DPNG);
61622
+ delegated("click", button_39, onExportSVG);
61623
+ delegated("click", button_40, onExportDXF);
61624
+ delegated("click", button_41, onExportDWG);
61625
+ delegated("click", button_42, onExportPDF);
61626
+ delegated("click", button_43, onExportJSON);
61627
+ delegated("click", button_44, onImportJSON);
61511
61628
  append($$anchor, div_10);
61512
61629
  };
61513
- if_block(node_12, ($$render) => {
61514
- if (get(exportOpen)) $$render(consequent_12);
61630
+ if_block(node_13, ($$render) => {
61631
+ if (get(exportOpen)) $$render(consequent_13);
61515
61632
  });
61516
61633
  reset(div_9);
61517
61634
  bind_this(div_9, ($$value) => exportRef = $$value, () => exportRef);
61518
61635
  reset(div_8);
61519
61636
  template_effect(() => set_text(text_10, get(projectName)));
61520
- delegated("click", button_34, () => {
61637
+ delegated("click", button_35, () => {
61521
61638
  set(exportOpen, !get(exportOpen));
61522
61639
  if (get(exportOpen)) triggerTip("first-export", 300, 60);
61523
61640
  });
61524
61641
  append($$anchor, div_8);
61525
61642
  };
61526
61643
  if_block(node, ($$render) => {
61527
- if (!$$props.viewOnly) $$render(consequent_11);
61528
- else $$render(alternate_3, -1);
61644
+ if (!$$props.viewOnly) $$render(consequent_12);
61645
+ else $$render(alternate_4, -1);
61529
61646
  });
61530
- var node_13 = sibling(node, 2);
61531
- SettingsDialog(node_13, {
61647
+ var node_14 = sibling(node, 2);
61648
+ SettingsDialog(node_14, {
61532
61649
  get open() {
61533
61650
  return get(settingsOpen);
61534
61651
  },
@@ -61536,8 +61653,8 @@ function TopBar($$anchor, $$props) {
61536
61653
  set(settingsOpen, $$value, true);
61537
61654
  }
61538
61655
  });
61539
- var node_14 = sibling(node_13, 2);
61540
- VersionHistoryPanel(node_14, {
61656
+ var node_15 = sibling(node_14, 2);
61657
+ VersionHistoryPanel(node_15, {
61541
61658
  get open() {
61542
61659
  return get(versionHistoryOpen);
61543
61660
  },
@@ -61545,12 +61662,12 @@ function TopBar($$anchor, $$props) {
61545
61662
  set(versionHistoryOpen, $$value, true);
61546
61663
  }
61547
61664
  });
61548
- var node_15 = sibling(node_14, 2);
61549
- var consequent_13 = ($$anchor) => {
61550
- var div_11 = root_19$3();
61665
+ var node_16 = sibling(node_15, 2);
61666
+ var consequent_14 = ($$anchor) => {
61667
+ var div_11 = root_22$3();
61551
61668
  var div_12 = child(div_11);
61552
61669
  var div_13 = child(div_12);
61553
- var button_44 = sibling(child(div_13), 2);
61670
+ var button_45 = sibling(child(div_13), 2);
61554
61671
  reset(div_13);
61555
61672
  var div_14 = sibling(div_13, 2);
61556
61673
  AreaSummaryPanel(child(div_14), {});
@@ -61562,11 +61679,11 @@ function TopBar($$anchor, $$props) {
61562
61679
  if (e.key === "Escape") set(areaOpen, false);
61563
61680
  });
61564
61681
  delegated("click", div_12, (e) => e.stopPropagation());
61565
- delegated("click", button_44, () => set(areaOpen, false));
61682
+ delegated("click", button_45, () => set(areaOpen, false));
61566
61683
  append($$anchor, div_11);
61567
61684
  };
61568
- if_block(node_15, ($$render) => {
61569
- if (get(areaOpen)) $$render(consequent_13);
61685
+ if_block(node_16, ($$render) => {
61686
+ if (get(areaOpen)) $$render(consequent_14);
61570
61687
  });
61571
61688
  append($$anchor, fragment);
61572
61689
  pop();
@@ -62211,25 +62328,27 @@ delegate(["click"]);
62211
62328
  //#region src/lib/components/sidebar/BuildPanel.svelte
62212
62329
  init_client();
62213
62330
  init_index_client();
62214
- var root_7$4 = /* @__PURE__ */ from_html(`<button draggable="true"><div class="w-9 h-9 rounded-lg bg-amber-50 flex items-center justify-center"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#92400e" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path></path></svg></div> <span class="text-xs font-medium text-gray-600"> </span> <span class="text-[10px] text-gray-400"> </span></button>`);
62215
- var root_8$3 = /* @__PURE__ */ from_html(`<button draggable="true"><div class="w-9 h-9 rounded-lg bg-cyan-50 flex items-center justify-center"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#0e7490" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="16" rx="1"></rect><line x1="12" y1="4" x2="12" y2="20"></line><line x1="3" y1="12" x2="21" y2="12"></line></svg></div> <span class="text-xs font-medium text-gray-600"> </span> <span class="text-[10px] text-gray-400"> </span></button>`);
62331
+ var root_4$6 = /* @__PURE__ */ from_html(`Click path · nhấn <strong>✓</strong> trên toolbar để đóng · 🗑 xoá`, 1);
62332
+ var root_7$5 = /* @__PURE__ */ from_html(`<button draggable="true"><div class="w-9 h-9 rounded-lg bg-amber-50 flex items-center justify-center"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#92400e" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path></path></svg></div> <span class="text-xs font-medium text-gray-600"> </span> <span class="text-[10px] text-gray-400"> </span></button>`);
62333
+ var root_8$2 = /* @__PURE__ */ from_html(`<button draggable="true"><div class="w-9 h-9 rounded-lg bg-cyan-50 flex items-center justify-center"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#0e7490" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="16" rx="1"></rect><line x1="12" y1="4" x2="12" y2="20"></line><line x1="3" y1="12" x2="21" y2="12"></line></svg></div> <span class="text-xs font-medium text-gray-600"> </span> <span class="text-[10px] text-gray-400"> </span></button>`);
62216
62334
  var root_6$4 = /* @__PURE__ */ from_html(`<div class="grid grid-cols-2 gap-2 mb-3"></div> <h3 class="text-xs font-semibold text-gray-400 uppercase mb-2">Windows</h3> <div class="grid grid-cols-2 gap-2"></div>`, 1);
62217
- var root_1$9 = /* @__PURE__ */ from_html(`<div class="space-y-1"><h3 class="text-xs font-semibold text-gray-400 uppercase mb-2">Tools</h3> <button><div><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 3l7.07 16.97 2.51-7.39 7.39-2.51L3 3z"></path><path d="M13 13l6 6"></path></svg></div> <div class="text-left"><div class="font-medium">Select <span class="text-gray-400 text-xs ml-1">V</span></div> <div class="text-xs text-gray-400">Click to select elements</div></div></button> <button><div><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="8" width="18" height="8" rx="1"></rect><line x1="7" y1="8" x2="7" y2="16"></line><line x1="12" y1="8" x2="12" y2="16"></line><line x1="17" y1="8" x2="17" y2="16"></line></svg></div> <div class="text-left"><div class="font-medium">Draw Wall <span class="text-gray-400 text-xs ml-1">W</span></div> <div class="text-xs text-gray-400">Click to draw, dbl-click to finish</div></div></button> <h3 class="text-xs font-semibold text-gray-400 uppercase mb-2 mt-3">Camera FOV</h3> <button type="button"><div><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-dasharray="3 2"><path d="M7 4 L17 6 L20 14 L12 20 L4 12 Z"></path></svg></div> <div class="text-left"><div class="font-medium">Draw surveillance FOV</div> <div class="text-xs text-gray-400">Floor polygon → mapCoordinates</div></div></button> <p class="text-[10px] text-gray-400 mb-3 px-0.5">Select a camera, then draw on floor. Thumbnail opens beside for image FOV (coordinates). Separate from Zone tools below.</p> <h3 class="text-xs font-semibold text-gray-400 uppercase mb-2 mt-3">Zone</h3> <div class="grid grid-cols-3 gap-1.5 mb-1"><button type="button" title="Drag to create rectangle area"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-dasharray="3 2"><rect x="4" y="6" width="16" height="12" rx="1"></rect></svg> Rect</button> <button type="button" title="Click to place triangle area"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-dasharray="3 2"><path d="M12 4 L20 19 L4 19 Z"></path></svg> Triangle</button> <button type="button" title="Click points; click first point or Enter to close"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-dasharray="3 2"><path d="M7 4 L17 6 L20 14 L12 20 L4 12 Z"></path></svg> Polygon</button></div> <p class="text-[10px] text-gray-400 mb-2 px-0.5"><!></p> <h3 class="text-xs font-semibold text-gray-400 uppercase mb-2 mt-3">Structure</h3> <button><div><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 5h-5V2h-3v6h-4V5H7v6H2v3h5v3h3v-3h4v3h3v-6h5z"></path></svg></div> <div class="text-left"><div class="font-medium">Add Stairs</div> <div class="text-xs text-gray-400">Click to place stairs</div></div></button> <div class="flex gap-2"><button><div><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="6"></circle><line x1="6" y1="6" x2="18" y2="18"></line><line x1="18" y1="6" x2="6" y2="18"></line></svg></div> <div class="text-left"><div class="font-medium text-xs">Round Column</div></div></button> <button><div><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="6" y="6" width="12" height="12"></rect><line x1="6" y1="6" x2="18" y2="18"></line><line x1="18" y1="6" x2="6" y2="18"></line></svg></div> <div class="text-left"><div class="font-medium text-xs">Square Column</div></div></button></div> <h3 class="text-xs font-semibold text-gray-400 uppercase mb-2 mt-3">Annotate</h3> <button><div><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 7V4h16v3"></path><line x1="12" y1="4" x2="12" y2="20"></line><line x1="8" y1="20" x2="16" y2="20"></line></svg></div> <div class="text-left"><div class="font-medium">Text Label</div> <div class="text-xs text-gray-400">Add text annotations (T)</div></div></button> <button><div><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"></path><line x1="16" y1="5" x2="22" y2="5"></line><line x1="19" y1="2" x2="19" y2="8"></line><line x1="3" y1="12" x2="12" y2="12"></line></svg></div> <div class="text-left"><div class="font-medium">Dimension</div> <div class="text-xs text-gray-400">Add dimension annotations (N)</div></div></button> <button><div><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2 12h5l2-7 4 14 2-7h7"></path></svg></div> <div class="text-left"><div class="font-medium">Measure</div> <div class="text-xs text-gray-400">Measure distances (M)</div></div></button> <h3 class="text-xs font-semibold text-gray-400 uppercase mb-2 mt-3">Import</h3> <button class="w-full flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm transition-colors hover:bg-gray-50 text-gray-700"><div class="w-9 h-9 rounded-lg bg-gray-100 flex items-center justify-center"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><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="text-left"><div class="font-medium">Import Image</div> <div class="text-xs text-gray-400">Floor plan background</div></div></button> <button class="w-full flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm transition-colors hover:bg-gray-50 text-gray-700"><div class="w-9 h-9 rounded-lg bg-gray-100 flex items-center justify-center"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path><polyline points="9 22 9 12 15 12 15 22"></polyline></svg></div> <div class="text-left"><div class="font-medium">Import RoomPlan</div> <div class="text-xs text-gray-400">iOS LiDAR scan (.json/.zip)</div></div></button> <button class="w-full flex items-center justify-between px-1 py-2 mt-3"><h3 class="text-xs font-semibold text-gray-400 uppercase">Doors</h3> <span class="text-gray-400 text-xs"> </span></button> <!></div>`);
62218
- var root_10$2 = /* @__PURE__ */ from_html(`<button class="flex flex-col items-center gap-1.5 p-3 rounded-lg border-2 border-gray-100 hover:border-blue-300 hover:bg-blue-50 transition-colors cursor-grab active:cursor-grabbing" draggable="true"><div class="w-12 h-12 rounded-lg bg-gray-50 flex items-center justify-center text-2xl font-mono"> </div> <span class="text-xs font-medium text-gray-600"> </span></button>`);
62335
+ var root_1$9 = /* @__PURE__ */ from_html(`<div class="space-y-1"><h3 class="text-xs font-semibold text-gray-400 uppercase mb-2">Tools</h3> <button><div><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 3l7.07 16.97 2.51-7.39 7.39-2.51L3 3z"></path><path d="M13 13l6 6"></path></svg></div> <div class="text-left"><div class="font-medium">Select <span class="text-gray-400 text-xs ml-1">V</span></div> <div class="text-xs text-gray-400">Click to select elements</div></div></button> <button><div><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="8" width="18" height="8" rx="1"></rect><line x1="7" y1="8" x2="7" y2="16"></line><line x1="12" y1="8" x2="12" y2="16"></line><line x1="17" y1="8" x2="17" y2="16"></line></svg></div> <div class="text-left"><div class="font-medium">Draw Wall <span class="text-gray-400 text-xs ml-1">W</span></div> <div class="text-xs text-gray-400">Click to draw, dbl-click to finish</div></div></button> <h3 class="text-xs font-semibold text-gray-400 uppercase mb-2 mt-3">Camera FOV</h3> <button type="button"><div><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-dasharray="3 2"><path d="M7 4 L17 6 L20 14 L12 20 L4 12 Z"></path></svg></div> <div class="text-left"><div class="font-medium">Draw surveillance FOV</div> <div class="text-xs text-gray-400">Click path · ✓ toolbar to finish</div></div></button> <p class="text-[10px] text-gray-400 mb-3 px-0.5">Select a camera, draw on floor → <code class="font-mono">mapCoordinates</code>.
62336
+ Nhấn ✓ đóng polygon · 🗑 xoá. Click polygon để hiện lại toolbar.</p> <h3 class="text-xs font-semibold text-gray-400 uppercase mb-2 mt-3">Zone</h3> <div class="grid grid-cols-3 gap-1.5 mb-1"><button type="button" title="Drag to create rectangle area"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-dasharray="3 2"><rect x="4" y="6" width="16" height="12" rx="1"></rect></svg> Rect</button> <button type="button" title="Click to place triangle area"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-dasharray="3 2"><path d="M12 4 L20 19 L4 19 Z"></path></svg> Triangle</button> <button type="button" title="Click vertices; double-click or Enter to finish"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-dasharray="3 2"><path d="M7 4 L17 6 L20 14 L12 20 L4 12 Z"></path></svg> Polygon</button></div> <p class="text-[10px] text-gray-400 mb-2 px-0.5"><!></p> <h3 class="text-xs font-semibold text-gray-400 uppercase mb-2 mt-3">Structure</h3> <button><div><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 5h-5V2h-3v6h-4V5H7v6H2v3h5v3h3v-3h4v3h3v-6h5z"></path></svg></div> <div class="text-left"><div class="font-medium">Add Stairs</div> <div class="text-xs text-gray-400">Click to place stairs</div></div></button> <div class="flex gap-2"><button><div><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="6"></circle><line x1="6" y1="6" x2="18" y2="18"></line><line x1="18" y1="6" x2="6" y2="18"></line></svg></div> <div class="text-left"><div class="font-medium text-xs">Round Column</div></div></button> <button><div><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="6" y="6" width="12" height="12"></rect><line x1="6" y1="6" x2="18" y2="18"></line><line x1="18" y1="6" x2="6" y2="18"></line></svg></div> <div class="text-left"><div class="font-medium text-xs">Square Column</div></div></button></div> <h3 class="text-xs font-semibold text-gray-400 uppercase mb-2 mt-3">Annotate</h3> <button><div><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 7V4h16v3"></path><line x1="12" y1="4" x2="12" y2="20"></line><line x1="8" y1="20" x2="16" y2="20"></line></svg></div> <div class="text-left"><div class="font-medium">Text Label</div> <div class="text-xs text-gray-400">Add text annotations (T)</div></div></button> <button><div><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"></path><line x1="16" y1="5" x2="22" y2="5"></line><line x1="19" y1="2" x2="19" y2="8"></line><line x1="3" y1="12" x2="12" y2="12"></line></svg></div> <div class="text-left"><div class="font-medium">Dimension</div> <div class="text-xs text-gray-400">Add dimension annotations (N)</div></div></button> <button><div><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2 12h5l2-7 4 14 2-7h7"></path></svg></div> <div class="text-left"><div class="font-medium">Measure</div> <div class="text-xs text-gray-400">Measure distances (M)</div></div></button> <h3 class="text-xs font-semibold text-gray-400 uppercase mb-2 mt-3">Import</h3> <button class="w-full flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm transition-colors hover:bg-gray-50 text-gray-700"><div class="w-9 h-9 rounded-lg bg-gray-100 flex items-center justify-center"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><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="text-left"><div class="font-medium">Import Image</div> <div class="text-xs text-gray-400">Floor plan background</div></div></button> <button class="w-full flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm transition-colors hover:bg-gray-50 text-gray-700"><div class="w-9 h-9 rounded-lg bg-gray-100 flex items-center justify-center"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path><polyline points="9 22 9 12 15 12 15 22"></polyline></svg></div> <div class="text-left"><div class="font-medium">Import RoomPlan</div> <div class="text-xs text-gray-400">iOS LiDAR scan (.json/.zip)</div></div></button> <button class="w-full flex items-center justify-between px-1 py-2 mt-3"><h3 class="text-xs font-semibold text-gray-400 uppercase">Doors</h3> <span class="text-gray-400 text-xs"> </span></button> <!></div>`);
62337
+ var root_10$3 = /* @__PURE__ */ from_html(`<button class="flex flex-col items-center gap-1.5 p-3 rounded-lg border-2 border-gray-100 hover:border-blue-300 hover:bg-blue-50 transition-colors cursor-grab active:cursor-grabbing" draggable="true"><div class="w-12 h-12 rounded-lg bg-gray-50 flex items-center justify-center text-2xl font-mono"> </div> <span class="text-xs font-medium text-gray-600"> </span></button>`);
62219
62338
  var root_11$3 = /* @__PURE__ */ from_html(`<button class="flex flex-col items-center gap-1.5 p-3 rounded-lg border-2 border-gray-100 hover:border-green-300 hover:bg-green-50 transition-colors cursor-grab active:cursor-grabbing" draggable="true"><div class="w-12 h-12 rounded-lg bg-green-50 flex items-center justify-center text-lg"><!></div> <span class="text-xs font-medium text-gray-600"> </span> <span class="text-[10px] text-gray-400"> </span></button>`);
62220
62339
  var root_9$2 = /* @__PURE__ */ from_html(`<div class="space-y-2"><h3 class="text-xs font-semibold text-gray-400 uppercase mb-2">Room Presets</h3> <p class="text-xs text-gray-400 mb-3">Click to add a room shape to the canvas</p> <div class="grid grid-cols-2 gap-2"></div> <hr class="my-3 border-gray-200"/> <h3 class="text-xs font-semibold text-gray-400 uppercase mb-2">Room Templates</h3> <p class="text-xs text-gray-400 mb-3">Pre-furnished rooms — walls + furniture in one click</p> <div class="grid grid-cols-2 gap-2"></div></div>`);
62221
62340
  var root_20$2 = /* @__PURE__ */ from_html(`<button class="absolute right-2 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600 w-5 h-5 flex items-center justify-center rounded-full hover:bg-gray-100" title="Clear search"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg></button>`);
62222
62341
  var root_21$2 = /* @__PURE__ */ from_html(`<div class="text-[10px] text-gray-400 px-1"> </div>`);
62223
62342
  var root_22$2 = /* @__PURE__ */ from_html(`<button> </button>`);
62224
- var root_24$1 = /* @__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>`);
62225
- var root_23$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);
62226
- var root_26$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>`);
62343
+ var root_24$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>`);
62344
+ var root_23$1 = /* @__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);
62345
+ var root_26$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>`);
62227
62346
  var root_27$1 = /* @__PURE__ */ from_html(`<span class="text-xs font-medium text-gray-600"> </span>`);
62228
- var root_25$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>`);
62347
+ var root_25$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>`);
62229
62348
  var root_19$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>`);
62230
62349
  var root_28$1 = /* @__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>`);
62231
62350
  var root_29$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>`);
62232
- var root$4 = /* @__PURE__ */ from_html(`<div class="relative w-64 bg-white border-r border-gray-200 flex flex-col h-full overflow-hidden"><div class="flex border-b border-gray-200"><button>Build</button> <button>Rooms</button> <button>Objects</button></div> <div class="flex-1 overflow-y-auto p-3"><!></div> <button title="Layers Panel (L)" aria-label="Toggle Layers Panel">🗂</button> <button title="Undo History" aria-label="Toggle Undo History">⟲</button> <button class="absolute bottom-4 left-4 w-8 h-8 rounded-full bg-slate-700 text-white text-sm font-bold shadow-lg hover:bg-slate-600 transition-colors z-50" title="Keyboard Shortcuts (?)" aria-label="Keyboard Shortcuts">?</button></div> <!> <!>`, 1);
62351
+ var root$5 = /* @__PURE__ */ from_html(`<div class="relative w-64 bg-white border-r border-gray-200 flex flex-col h-full overflow-hidden"><div class="flex border-b border-gray-200"><button>Build</button> <button>Rooms</button> <button>Objects</button></div> <div class="flex-1 overflow-y-auto p-3"><!></div> <button title="Layers Panel (L)" aria-label="Toggle Layers Panel">🗂</button> <button title="Undo History" aria-label="Toggle Undo History">⟲</button> <button class="absolute bottom-4 left-4 w-8 h-8 rounded-full bg-slate-700 text-white text-sm font-bold shadow-lg hover:bg-slate-600 transition-colors z-50" title="Keyboard Shortcuts (?)" aria-label="Keyboard Shortcuts">?</button></div> <!> <!>`, 1);
62233
62352
  function BuildPanel($$anchor, $$props) {
62234
62353
  push($$props, true);
62235
62354
  let showLayers = prop($$props, "showLayers", 15), showUndoHistory = prop($$props, "showUndoHistory", 15), showHelp = prop($$props, "showHelp", 15);
@@ -62550,7 +62669,7 @@ function BuildPanel($$anchor, $$props) {
62550
62669
  "Electrical": "#2563eb",
62551
62670
  "Plumbing": "#0ea5e9"
62552
62671
  };
62553
- var fragment = root$4();
62672
+ var fragment = root$5();
62554
62673
  var div = first_child(fragment);
62555
62674
  var div_1 = child(div);
62556
62675
  var button = child(div_1);
@@ -62587,7 +62706,9 @@ function BuildPanel($$anchor, $$props) {
62587
62706
  append($$anchor, text$1("Click to place · then drag vertices"));
62588
62707
  };
62589
62708
  var consequent_2 = ($$anchor) => {
62590
- append($$anchor, text$1("Click vertices · Enter / click first point to close"));
62709
+ var fragment_1 = root_4$6();
62710
+ next(2);
62711
+ append($$anchor, fragment_1);
62591
62712
  };
62592
62713
  var alternate = ($$anchor) => {
62593
62714
  append($$anchor, text$1("Select a camera first, then draw its Zone"));
@@ -62629,32 +62750,32 @@ function BuildPanel($$anchor, $$props) {
62629
62750
  var button_16 = sibling(button_15, 2);
62630
62751
  var button_17 = sibling(button_16, 2);
62631
62752
  var span = sibling(child(button_17), 2);
62632
- var text_5 = child(span, true);
62753
+ var text_4 = child(span, true);
62633
62754
  reset(span);
62634
62755
  reset(button_17);
62635
62756
  var node_2 = sibling(button_17, 2);
62636
62757
  var consequent_3 = ($$anchor) => {
62637
- var fragment_1 = root_6$4();
62638
- var div_15 = first_child(fragment_1);
62758
+ var fragment_2 = root_6$4();
62759
+ var div_15 = first_child(fragment_2);
62639
62760
  each(div_15, 21, () => doorCatalog, index$1, ($$anchor, dc) => {
62640
- var button_18 = root_7$4();
62761
+ var button_18 = root_7$5();
62641
62762
  var div_16 = child(button_18);
62642
62763
  var svg = child(div_16);
62643
62764
  var path = child(svg);
62644
62765
  reset(svg);
62645
62766
  reset(div_16);
62646
62767
  var span_1 = sibling(div_16, 2);
62647
- var text_6 = child(span_1, true);
62768
+ var text_5 = child(span_1, true);
62648
62769
  reset(span_1);
62649
62770
  var span_2 = sibling(span_1, 2);
62650
- var text_7 = child(span_2, true);
62771
+ var text_6 = child(span_2, true);
62651
62772
  reset(span_2);
62652
62773
  reset(button_18);
62653
62774
  template_effect(() => {
62654
62775
  set_class(button_18, 1, `flex flex-col items-center gap-1 p-2.5 rounded-lg border-2 transition-colors cursor-grab active:cursor-grabbing ${get(currentTool) === "door" && get(selectedDoorType) === get(dc).type ? "border-blue-400 bg-blue-50" : "border-gray-100 hover:border-gray-200"}`);
62655
62776
  set_attribute(path, "d", get(dc).icon);
62656
- set_text(text_6, get(dc).name);
62657
- set_text(text_7, get(dc).desc);
62777
+ set_text(text_5, get(dc).name);
62778
+ set_text(text_6, get(dc).desc);
62658
62779
  });
62659
62780
  delegated("click", button_18, () => setDoorType(get(dc).type));
62660
62781
  event("dragstart", button_18, (e) => {
@@ -62667,18 +62788,18 @@ function BuildPanel($$anchor, $$props) {
62667
62788
  reset(div_15);
62668
62789
  var div_17 = sibling(div_15, 4);
62669
62790
  each(div_17, 21, () => windowCatalog, index$1, ($$anchor, wc) => {
62670
- var button_19 = root_8$3();
62791
+ var button_19 = root_8$2();
62671
62792
  var span_3 = sibling(child(button_19), 2);
62672
- var text_8 = child(span_3, true);
62793
+ var text_7 = child(span_3, true);
62673
62794
  reset(span_3);
62674
62795
  var span_4 = sibling(span_3, 2);
62675
- var text_9 = child(span_4, true);
62796
+ var text_8 = child(span_4, true);
62676
62797
  reset(span_4);
62677
62798
  reset(button_19);
62678
62799
  template_effect(() => {
62679
62800
  set_class(button_19, 1, `flex flex-col items-center gap-1 p-2.5 rounded-lg border-2 transition-colors cursor-grab active:cursor-grabbing ${get(currentTool) === "window" && get(selectedWindowType) === get(wc).type ? "border-blue-400 bg-blue-50" : "border-gray-100 hover:border-gray-200"}`);
62680
- set_text(text_8, get(wc).name);
62681
- set_text(text_9, get(wc).desc);
62801
+ set_text(text_7, get(wc).name);
62802
+ set_text(text_8, get(wc).desc);
62682
62803
  });
62683
62804
  delegated("click", button_19, () => setWindowType(get(wc).type));
62684
62805
  event("dragstart", button_19, (e) => {
@@ -62689,7 +62810,7 @@ function BuildPanel($$anchor, $$props) {
62689
62810
  append($$anchor, button_19);
62690
62811
  });
62691
62812
  reset(div_17);
62692
- append($$anchor, fragment_1);
62813
+ append($$anchor, fragment_2);
62693
62814
  };
62694
62815
  if_block(node_2, ($$render) => {
62695
62816
  if (get(constructionOpen)) $$render(consequent_3);
@@ -62717,7 +62838,7 @@ function BuildPanel($$anchor, $$props) {
62717
62838
  set_class(div_13, 1, `w-9 h-9 rounded-lg bg-gray-100 flex items-center justify-center ${get(currentTool) === "annotate" ? "bg-blue-100" : ""}`);
62718
62839
  set_class(button_14, 1, `w-full flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm transition-colors ${get(currentTool) === "measure" ? "bg-blue-50 text-slate-800 ring-1 ring-blue-200" : "hover:bg-gray-50 text-gray-700"}`);
62719
62840
  set_class(div_14, 1, `w-9 h-9 rounded-lg bg-gray-100 flex items-center justify-center ${get(currentTool) === "measure" ? "bg-blue-100" : ""}`);
62720
- set_text(text_5, get(constructionOpen) ? "▼" : "▶");
62841
+ set_text(text_4, get(constructionOpen) ? "▼" : "▶");
62721
62842
  });
62722
62843
  delegated("click", button_3, () => setTool("select"));
62723
62844
  delegated("click", button_4, () => setTool("wall"));
@@ -62740,17 +62861,17 @@ function BuildPanel($$anchor, $$props) {
62740
62861
  var div_18 = root_9$2();
62741
62862
  var div_19 = sibling(child(div_18), 4);
62742
62863
  each(div_19, 21, () => roomPresets, index$1, ($$anchor, preset) => {
62743
- var button_20 = root_10$2();
62864
+ var button_20 = root_10$3();
62744
62865
  var div_20 = child(button_20);
62745
- var text_10 = child(div_20, true);
62866
+ var text_9 = child(div_20, true);
62746
62867
  reset(div_20);
62747
62868
  var span_5 = sibling(div_20, 2);
62748
- var text_11 = child(span_5, true);
62869
+ var text_10 = child(span_5, true);
62749
62870
  reset(span_5);
62750
62871
  reset(button_20);
62751
62872
  template_effect(() => {
62752
- set_text(text_10, get(preset).icon);
62753
- set_text(text_11, get(preset).name);
62873
+ set_text(text_9, get(preset).icon);
62874
+ set_text(text_10, get(preset).name);
62754
62875
  });
62755
62876
  delegated("click", button_20, () => onPresetClick(get(preset).id));
62756
62877
  event("dragstart", button_20, (e) => {
@@ -62798,16 +62919,16 @@ function BuildPanel($$anchor, $$props) {
62798
62919
  });
62799
62920
  reset(div_22);
62800
62921
  var span_6 = sibling(div_22, 2);
62801
- var text_19 = child(span_6, true);
62922
+ var text_18 = child(span_6, true);
62802
62923
  reset(span_6);
62803
62924
  var span_7 = sibling(span_6, 2);
62804
- var text_20 = child(span_7);
62925
+ var text_19 = child(span_7);
62805
62926
  reset(span_7);
62806
62927
  reset(button_21);
62807
62928
  template_effect(() => {
62808
62929
  var _$$get$furniture$leng;
62809
- set_text(text_19, get(tmpl).name);
62810
- set_text(text_20, `${(_$$get$furniture$leng = get(tmpl).furniture.length) !== null && _$$get$furniture$leng !== void 0 ? _$$get$furniture$leng : ""} items`);
62930
+ set_text(text_18, get(tmpl).name);
62931
+ set_text(text_19, `${(_$$get$furniture$leng = get(tmpl).furniture.length) !== null && _$$get$furniture$leng !== void 0 ? _$$get$furniture$leng : ""} items`);
62811
62932
  });
62812
62933
  delegated("click", button_21, () => onPresetClick(get(tmpl).presetId, get(tmpl).name));
62813
62934
  event("dragstart", button_21, (e) => {
@@ -62839,11 +62960,11 @@ function BuildPanel($$anchor, $$props) {
62839
62960
  var node_5 = sibling(div_24, 2);
62840
62961
  var consequent_13 = ($$anchor) => {
62841
62962
  var div_25 = root_21$2();
62842
- var text_21 = child(div_25);
62963
+ var text_20 = child(div_25);
62843
62964
  reset(div_25);
62844
62965
  template_effect(() => {
62845
62966
  var _$$get$length, _$$get;
62846
- return set_text(text_21, `${(_$$get$length = get(filtered).length) !== null && _$$get$length !== void 0 ? _$$get$length : ""} result${get(filtered).length !== 1 ? "s" : ""} for "${(_$$get = get(search)) !== null && _$$get !== void 0 ? _$$get : ""}"`);
62967
+ return set_text(text_20, `${(_$$get$length = get(filtered).length) !== null && _$$get$length !== void 0 ? _$$get$length : ""} result${get(filtered).length !== 1 ? "s" : ""} for "${(_$$get = get(search)) !== null && _$$get !== void 0 ? _$$get : ""}"`);
62847
62968
  });
62848
62969
  append($$anchor, div_25);
62849
62970
  };
@@ -62853,17 +62974,17 @@ function BuildPanel($$anchor, $$props) {
62853
62974
  var div_26 = sibling(node_5, 2);
62854
62975
  var button_23 = child(div_26);
62855
62976
  var button_24 = sibling(button_23, 2);
62856
- var text_22 = child(button_24);
62977
+ var text_21 = child(button_24);
62857
62978
  reset(button_24);
62858
62979
  each(sibling(button_24, 2), 17, () => furnitureCategories, index$1, ($$anchor, cat) => {
62859
62980
  var button_25 = root_22$2();
62860
- var text_23 = child(button_25, true);
62981
+ var text_22 = child(button_25, true);
62861
62982
  reset(button_25);
62862
62983
  template_effect(() => {
62863
62984
  var _categoryColors$$$get;
62864
62985
  set_class(button_25, 1, `px-2 py-0.5 rounded-full text-[10px] font-medium ${get(selectedCategory) === get(cat) ? "text-white" : "text-gray-600 hover:bg-gray-200"}`);
62865
62986
  set_style(button_25, get(selectedCategory) === get(cat) ? `background-color: ${(_categoryColors$$$get = categoryColors[get(cat)]) !== null && _categoryColors$$$get !== void 0 ? _categoryColors$$$get : "#6b7280"}` : "background-color: #f3f4f6");
62866
- set_text(text_23, get(cat));
62987
+ set_text(text_22, get(cat));
62867
62988
  });
62868
62989
  delegated("click", button_25, () => set(selectedCategory, get(cat), true));
62869
62990
  append($$anchor, button_25);
@@ -62871,19 +62992,19 @@ function BuildPanel($$anchor, $$props) {
62871
62992
  reset(div_26);
62872
62993
  var node_7 = sibling(div_26, 2);
62873
62994
  var consequent_14 = ($$anchor) => {
62874
- var fragment_2 = root_23$2();
62875
- var div_27 = first_child(fragment_2);
62995
+ var fragment_3 = root_23$1();
62996
+ var div_27 = first_child(fragment_3);
62876
62997
  var div_28 = sibling(child(div_27), 2);
62877
62998
  each(div_28, 21, () => get(recentItems), index$1, ($$anchor, item) => {
62878
- var button_26 = root_24$1();
62999
+ var button_26 = root_24$2();
62879
63000
  var span_8 = child(button_26);
62880
- var text_24 = child(span_8, true);
63001
+ var text_23 = child(span_8, true);
62881
63002
  reset(span_8);
62882
63003
  var div_29 = sibling(span_8, 2);
62883
63004
  var div_30 = child(div_29);
62884
63005
  reset(div_29);
62885
63006
  var span_9 = sibling(div_29, 2);
62886
- var text_25 = child(span_9, true);
63007
+ var text_24 = child(span_9, true);
62887
63008
  reset(span_9);
62888
63009
  reset(button_26);
62889
63010
  template_effect(($0, $1, $2) => {
@@ -62891,10 +63012,10 @@ function BuildPanel($$anchor, $$props) {
62891
63012
  set_class(button_26, 1, `relative flex flex-col items-center gap-1 p-2.5 rounded-lg border-2 transition-colors cursor-grab active:cursor-grabbing ${get(currentPlacing) === get(item).id ? "border-blue-400 bg-blue-50 ring-1 ring-blue-300" : "border-gray-100 hover:border-blue-300 hover:bg-blue-50"}`);
62892
63013
  set_class(span_8, 1, `absolute top-1 right-1 text-[12px] leading-none cursor-pointer ${$0 !== null && $0 !== void 0 ? $0 : ""}`);
62893
63014
  set_attribute(span_8, "title", $1);
62894
- set_text(text_24, $2);
63015
+ set_text(text_23, $2);
62895
63016
  set_style(div_29, `background-color: ${(_$$get$color = get(item).color) !== null && _$$get$color !== void 0 ? _$$get$color : ""}20`);
62896
63017
  set_style(div_30, `background-color: ${(_$$get$color2 = get(item).color) !== null && _$$get$color2 !== void 0 ? _$$get$color2 : ""}; opacity: 0.7`);
62897
- set_text(text_25, get(item).name);
63018
+ set_text(text_24, get(item).name);
62898
63019
  }, [
62899
63020
  () => get(favoriteIds).includes(get(item).id) ? "text-pink-500" : "text-gray-300 hover:text-pink-400",
62900
63021
  () => get(favoriteIds).includes(get(item).id) ? "Remove from favorites" : "Add to favorites",
@@ -62925,7 +63046,7 @@ function BuildPanel($$anchor, $$props) {
62925
63046
  reset(div_28);
62926
63047
  reset(div_27);
62927
63048
  next(2);
62928
- append($$anchor, fragment_2);
63049
+ append($$anchor, fragment_3);
62929
63050
  };
62930
63051
  if_block(node_7, ($$render) => {
62931
63052
  if (!get(search) && get(selectedCategory) === "All" && get(recentItems).length > 0) $$render(consequent_14);
@@ -62933,9 +63054,9 @@ function BuildPanel($$anchor, $$props) {
62933
63054
  var div_31 = sibling(node_7, 2);
62934
63055
  each(div_31, 21, () => get(filtered), index$1, ($$anchor, item) => {
62935
63056
  const s = /* @__PURE__ */ user_derived(() => get(search).toLowerCase());
62936
- var button_27 = root_25$2();
63057
+ var button_27 = root_25$1();
62937
63058
  var span_10 = child(button_27);
62938
- var text_26 = child(span_10, true);
63059
+ var text_25 = child(span_10, true);
62939
63060
  reset(span_10);
62940
63061
  var div_32 = sibling(span_10, 2);
62941
63062
  var div_33 = child(div_32);
@@ -62943,17 +63064,17 @@ function BuildPanel($$anchor, $$props) {
62943
63064
  var node_8 = sibling(div_32, 2);
62944
63065
  var consequent_15 = ($$anchor) => {
62945
63066
  const idx = /* @__PURE__ */ user_derived(() => get(item).name.toLowerCase().indexOf(get(s)));
62946
- var span_11 = root_26$2();
62947
- var text_27 = child(span_11, true);
62948
- var mark = sibling(text_27);
62949
- var text_28 = child(mark, true);
63067
+ var span_11 = root_26$1();
63068
+ var text_26 = child(span_11, true);
63069
+ var mark = sibling(text_26);
63070
+ var text_27 = child(mark, true);
62950
63071
  reset(mark);
62951
- var text_29 = sibling(mark, 1, true);
63072
+ var text_28 = sibling(mark, 1, true);
62952
63073
  reset(span_11);
62953
63074
  template_effect(($0, $1, $2) => {
62954
- set_text(text_27, $0);
62955
- set_text(text_28, $1);
62956
- set_text(text_29, $2);
63075
+ set_text(text_26, $0);
63076
+ set_text(text_27, $1);
63077
+ set_text(text_28, $2);
62957
63078
  }, [
62958
63079
  () => get(item).name.slice(0, get(idx)),
62959
63080
  () => get(item).name.slice(get(idx), get(idx) + get(s).length),
@@ -62964,9 +63085,9 @@ function BuildPanel($$anchor, $$props) {
62964
63085
  var d = /* @__PURE__ */ user_derived(() => get(s) && get(item).name.toLowerCase().includes(get(s)));
62965
63086
  var alternate_2 = ($$anchor) => {
62966
63087
  var span_12 = root_27$1();
62967
- var text_30 = child(span_12, true);
63088
+ var text_29 = child(span_12, true);
62968
63089
  reset(span_12);
62969
- template_effect(() => set_text(text_30, get(item).name));
63090
+ template_effect(() => set_text(text_29, get(item).name));
62970
63091
  append($$anchor, span_12);
62971
63092
  };
62972
63093
  if_block(node_8, ($$render) => {
@@ -62974,7 +63095,7 @@ function BuildPanel($$anchor, $$props) {
62974
63095
  else $$render(alternate_2, -1);
62975
63096
  });
62976
63097
  var span_13 = sibling(node_8, 2);
62977
- var text_31 = child(span_13);
63098
+ var text_30 = child(span_13);
62978
63099
  reset(span_13);
62979
63100
  reset(button_27);
62980
63101
  template_effect(($0, $1, $2) => {
@@ -62982,10 +63103,10 @@ function BuildPanel($$anchor, $$props) {
62982
63103
  set_class(button_27, 1, `relative flex flex-col items-center gap-1 p-3 rounded-lg border-2 transition-colors cursor-grab active:cursor-grabbing ${get(currentPlacing) === get(item).id ? "border-blue-400 bg-blue-50 ring-1 ring-blue-300" : "border-gray-100 hover:border-blue-300 hover:bg-blue-50"}`);
62983
63104
  set_class(span_10, 1, `absolute top-1 right-1 text-[12px] leading-none cursor-pointer ${$0 !== null && $0 !== void 0 ? $0 : ""}`);
62984
63105
  set_attribute(span_10, "title", $1);
62985
- set_text(text_26, $2);
63106
+ set_text(text_25, $2);
62986
63107
  set_style(div_32, `background-color: ${(_$$get$color3 = get(item).color) !== null && _$$get$color3 !== void 0 ? _$$get$color3 : ""}20`);
62987
63108
  set_style(div_33, `background-color: ${(_$$get$color4 = get(item).color) !== null && _$$get$color4 !== void 0 ? _$$get$color4 : ""}; opacity: 0.7`);
62988
- set_text(text_31, `${(_$$get$width = get(item).width) !== null && _$$get$width !== void 0 ? _$$get$width : ""}×${(_$$get$depth = get(item).depth) !== null && _$$get$depth !== void 0 ? _$$get$depth : ""}cm`);
63109
+ set_text(text_30, `${(_$$get$width = get(item).width) !== null && _$$get$width !== void 0 ? _$$get$width : ""}×${(_$$get$depth = get(item).depth) !== null && _$$get$depth !== void 0 ? _$$get$depth : ""}cm`);
62989
63110
  }, [
62990
63111
  () => get(favoriteIds).includes(get(item).id) ? "text-pink-500" : "text-gray-300 hover:text-pink-400",
62991
63112
  () => get(favoriteIds).includes(get(item).id) ? "Remove from favorites" : "Add to favorites",
@@ -63018,7 +63139,7 @@ function BuildPanel($$anchor, $$props) {
63018
63139
  template_effect(() => {
63019
63140
  set_class(button_23, 1, `px-2 py-0.5 rounded-full text-[10px] font-medium ${get(selectedCategory) === "All" ? "bg-blue-600 text-white" : "bg-gray-100 text-gray-600 hover:bg-gray-200"}`);
63020
63141
  set_class(button_24, 1, `px-2 py-0.5 rounded-full text-[10px] font-medium ${get(selectedCategory) === "Favorites" ? "bg-pink-500 text-white" : "bg-gray-100 text-gray-600 hover:bg-gray-200"}`);
63021
- set_text(text_22, `♥ Favorites${get(favoriteIds).length ? ` (${get(favoriteIds).length})` : ""}`);
63142
+ set_text(text_21, `♥ Favorites${get(favoriteIds).length ? ` (${get(favoriteIds).length})` : ""}`);
63022
63143
  });
63023
63144
  bind_value(input_1, () => get(search), ($$value) => set(search, $$value));
63024
63145
  delegated("click", button_23, () => set(selectedCategory, "All"));
@@ -63050,14 +63171,14 @@ function BuildPanel($$anchor, $$props) {
63050
63171
  var div_39 = sibling(div_36, 2);
63051
63172
  var div_40 = child(div_39);
63052
63173
  var span_14 = child(div_40);
63053
- var text_32 = child(span_14, true);
63174
+ var text_31 = child(span_14, true);
63054
63175
  reset(span_14);
63055
63176
  var span_15 = sibling(span_14, 2);
63056
- var text_33 = child(span_15, true);
63177
+ var text_32 = child(span_15, true);
63057
63178
  reset(span_15);
63058
63179
  reset(div_40);
63059
63180
  var div_41 = sibling(div_40, 2);
63060
- var text_34 = child(div_41);
63181
+ var text_33 = child(div_41);
63061
63182
  reset(div_41);
63062
63183
  reset(div_39);
63063
63184
  reset(div_35);
@@ -63067,10 +63188,10 @@ function BuildPanel($$anchor, $$props) {
63067
63188
  set_style(div_34, `left: ${(_$$get$x = get(hoverPos).x) !== null && _$$get$x !== void 0 ? _$$get$x : ""}px; top: ${(_$$get$y = get(hoverPos).y) !== null && _$$get$y !== void 0 ? _$$get$y : ""}px;`);
63068
63189
  set_style(div_37, `background-color: ${(_$$get$color5 = get(item).color) !== null && _$$get$color5 !== void 0 ? _$$get$color5 : ""}20`);
63069
63190
  set_style(div_38, `background-color: ${(_$$get$color6 = get(item).color) !== null && _$$get$color6 !== void 0 ? _$$get$color6 : ""}; opacity: 0.7`);
63070
- set_text(text_32, get(item).name);
63191
+ set_text(text_31, get(item).name);
63071
63192
  set_style(span_15, `background-color: ${(_ref = (_categoryColors$$$get2 = categoryColors[get(item).category]) !== null && _categoryColors$$$get2 !== void 0 ? _categoryColors$$$get2 : "#6b7280") !== null && _ref !== void 0 ? _ref : ""}`);
63072
- set_text(text_33, get(item).category);
63073
- set_text(text_34, `${(_$$get$width2 = get(item).width) !== null && _$$get$width2 !== void 0 ? _$$get$width2 : ""} × ${(_$$get$depth2 = get(item).depth) !== null && _$$get$depth2 !== void 0 ? _$$get$depth2 : ""} × ${(_$$get$height = get(item).height) !== null && _$$get$height !== void 0 ? _$$get$height : ""} cm`);
63193
+ set_text(text_32, get(item).category);
63194
+ set_text(text_33, `${(_$$get$width2 = get(item).width) !== null && _$$get$width2 !== void 0 ? _$$get$width2 : ""} × ${(_$$get$depth2 = get(item).depth) !== null && _$$get$depth2 !== void 0 ? _$$get$depth2 : ""} × ${(_$$get$height = get(item).height) !== null && _$$get$height !== void 0 ? _$$get$height : ""} cm`);
63074
63195
  });
63075
63196
  append($$anchor, div_34);
63076
63197
  };
@@ -63082,7 +63203,7 @@ function BuildPanel($$anchor, $$props) {
63082
63203
  var div_42 = root_29$1();
63083
63204
  var div_43 = child(div_42);
63084
63205
  var p_2 = sibling(child(div_43), 2);
63085
- var text_35 = child(p_2, true);
63206
+ var text_34 = child(p_2, true);
63086
63207
  reset(p_2);
63087
63208
  var div_44 = sibling(p_2, 2);
63088
63209
  var label = child(div_44);
@@ -63096,7 +63217,7 @@ function BuildPanel($$anchor, $$props) {
63096
63217
  var div_45 = sibling(input_3, 2);
63097
63218
  var div_46 = child(div_45);
63098
63219
  var span_16 = sibling(child(div_46));
63099
- var text_36 = child(span_16, true);
63220
+ var text_35 = child(span_16, true);
63100
63221
  reset(span_16);
63101
63222
  reset(div_46);
63102
63223
  next(2);
@@ -63114,8 +63235,8 @@ function BuildPanel($$anchor, $$props) {
63114
63235
  reset(div_43);
63115
63236
  reset(div_42);
63116
63237
  template_effect(() => {
63117
- set_text(text_35, get(importFileName));
63118
- set_text(text_36, "v5");
63238
+ set_text(text_34, get(importFileName));
63239
+ set_text(text_35, "v5");
63119
63240
  });
63120
63241
  delegated("click", div_42, cancelImport);
63121
63242
  delegated("click", div_43, (e) => e.stopPropagation());
@@ -63485,42 +63606,521 @@ function handleGlobalShortcut(e, ctx = {}) {
63485
63606
  return false;
63486
63607
  }
63487
63608
  //#endregion
63609
+ //#region src/lib/components/editor/PolygonFloatToolbar.svelte
63610
+ init_client();
63611
+ var root_1$8 = /* @__PURE__ */ from_html(`<button type="button" aria-label="Confirm polygon"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20 6 9 17l-5-5"></path></svg></button>`);
63612
+ var root$4 = /* @__PURE__ */ from_html(`<div class="absolute z-40 flex items-center gap-1.5 px-1.5 py-1 rounded-full bg-white/95 shadow-lg border border-gray-200 pointer-events-auto" role="toolbar" aria-label="Polygon actions"><!> <button type="button" title="Delete polygon" aria-label="Delete polygon"><svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 6h18"></path><path d="M8 6V4h8v2"></path><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6"></path><path d="M10 11v6M14 11v6"></path></svg></button></div>`);
63613
+ function PolygonFloatToolbar($$anchor, $$props) {
63614
+ push($$props, true);
63615
+ /**
63616
+ * Floating confirm / delete toolbar for polygon drafts & selection
63617
+ * (zone, floor FOV, image FOV) — matches host reference UX.
63618
+ */
63619
+ let canConfirm = prop($$props, "canConfirm", 3, false), showConfirm = prop($$props, "showConfirm", 3, true), canDelete = prop($$props, "canDelete", 3, true);
63620
+ var div = root$4();
63621
+ var node = child(div);
63622
+ var consequent = ($$anchor) => {
63623
+ var button = root_1$8();
63624
+ template_effect(() => {
63625
+ set_class(button, 1, `w-8 h-8 rounded-full flex items-center justify-center transition-colors ${canConfirm() ? "bg-emerald-100 text-emerald-700 hover:bg-emerald-200" : "bg-gray-100 text-gray-300 cursor-not-allowed"}`);
63626
+ set_attribute(button, "title", canConfirm() ? "Finish polygon" : "Need at least 3 points");
63627
+ button.disabled = !canConfirm();
63628
+ });
63629
+ delegated("click", button, () => {
63630
+ var _$$props$onConfirm;
63631
+ return canConfirm() && ((_$$props$onConfirm = $$props.onConfirm) === null || _$$props$onConfirm === void 0 ? void 0 : _$$props$onConfirm.call($$props));
63632
+ });
63633
+ append($$anchor, button);
63634
+ };
63635
+ if_block(node, ($$render) => {
63636
+ if (showConfirm()) $$render(consequent);
63637
+ });
63638
+ var button_1 = sibling(node, 2);
63639
+ reset(div);
63640
+ template_effect(() => {
63641
+ var _$$props$x, _$$props$y;
63642
+ set_style(div, `left: ${(_$$props$x = $$props.x) !== null && _$$props$x !== void 0 ? _$$props$x : ""}px; top: ${(_$$props$y = $$props.y) !== null && _$$props$y !== void 0 ? _$$props$y : ""}px; transform: translate(-50%, -120%);`);
63643
+ set_class(button_1, 1, `w-8 h-8 rounded-full flex items-center justify-center transition-colors ${canDelete() ? "bg-rose-100 text-rose-600 hover:bg-rose-200" : "bg-gray-100 text-gray-300 cursor-not-allowed"}`);
63644
+ button_1.disabled = !canDelete();
63645
+ });
63646
+ delegated("mousedown", div, (e) => e.stopPropagation());
63647
+ delegated("click", div, (e) => e.stopPropagation());
63648
+ delegated("click", button_1, () => {
63649
+ var _$$props$onDelete;
63650
+ return canDelete() && ((_$$props$onDelete = $$props.onDelete) === null || _$$props$onDelete === void 0 ? void 0 : _$$props$onDelete.call($$props));
63651
+ });
63652
+ append($$anchor, div);
63653
+ pop();
63654
+ }
63655
+ delegate(["mousedown", "click"]);
63656
+ //#endregion
63657
+ //#region src/lib/components/sidebar/CameraFovEditor.svelte
63658
+ init_client();
63659
+ init_index_client();
63660
+ var root_3$7 = /* @__PURE__ */ from_html(`<button type="button" class="text-[10px] px-1.5 py-0.5 rounded border border-blue-300 text-blue-700 bg-blue-50 hover:bg-blue-100"> </button>`);
63661
+ var root_2$8 = /* @__PURE__ */ from_html(`<div class="flex items-center justify-between gap-2"><span class="text-xs font-medium text-gray-600">Camera FOV (image)</span> <!></div>`);
63662
+ var root_6$3 = /* @__PURE__ */ from_html(`Click vertices · nhấn <strong>✓</strong> `, 1);
63663
+ var root_7$4 = /* @__PURE__ */ from_html(` <!>`, 1);
63664
+ var root_10$2 = /* @__PURE__ */ from_html(`<p class="text-[10px] text-amber-700 bg-amber-50 border border-amber-200 rounded px-1.5 py-1"> </p>`);
63665
+ var root_5$4 = /* @__PURE__ */ from_html(`<p class="text-[10px] text-gray-500 leading-snug"><!></p> <!>`, 1);
63666
+ var root_1$7 = /* @__PURE__ */ from_html(`<div class="border border-gray-200 rounded-lg p-2 bg-gray-50 space-y-2"><!> <div class="relative inline-block max-w-full"><canvas></canvas> <!></div> <!></div>`);
63667
+ var root_11$2 = /* @__PURE__ */ from_html(`<p class="text-xs text-gray-400">No thumbnail URL from host.</p>`);
63668
+ function CameraFovEditor($$anchor, $$props) {
63669
+ push($$props, true);
63670
+ let coordinates = prop($$props, "coordinates", 3, ""), mapCoordinates = prop($$props, "mapCoordinates", 3, ""), readOnly = prop($$props, "readOnly", 3, false);
63671
+ let canvasEl = /* @__PURE__ */ state(void 0);
63672
+ let imgEl = /* @__PURE__ */ state(null);
63673
+ let imgSize = /* @__PURE__ */ state(null);
63674
+ let draft = /* @__PURE__ */ state(proxy([]));
63675
+ let cursor = /* @__PURE__ */ state(null);
63676
+ let draggingIdx = /* @__PURE__ */ state(null);
63677
+ let editing = /* @__PURE__ */ state(false);
63678
+ /** Fits Properties panel ~420px minus padding. */
63679
+ const displayW = 380;
63680
+ const FOV_COLOR = "#3b82f6";
63681
+ let matchOk = /* @__PURE__ */ user_derived(() => fovPointCountsMatch(coordinates(), mapCoordinates()));
63682
+ let mapN = /* @__PURE__ */ user_derived(() => countCoordinatePoints(mapCoordinates()));
63683
+ let imgN = /* @__PURE__ */ user_derived(() => countCoordinatePoints(coordinates()));
63684
+ /** Click committed polygon → show toolbar (also while drawing). */
63685
+ let polySelected = /* @__PURE__ */ state(false);
63686
+ let showFloatTb = /* @__PURE__ */ user_derived(() => !readOnly() && (get(editing) && get(draft).length > 0 || get(polySelected) && get(draft).length >= 3));
63687
+ let floatTbPos = /* @__PURE__ */ user_derived(() => {
63688
+ if (!get(showFloatTb) || !get(draft).length) return null;
63689
+ const anchor = polygonToolbarAnchor(get(draft));
63690
+ if (!anchor) return null;
63691
+ const s = scale();
63692
+ return {
63693
+ x: anchor.x * s,
63694
+ y: anchor.y * s
63695
+ };
63696
+ });
63697
+ function samePoints(a, b) {
63698
+ if (a.length !== b.length) return false;
63699
+ for (let i = 0; i < a.length; i++) if (a[i].x !== b[i].x || a[i].y !== b[i].y) return false;
63700
+ return true;
63701
+ }
63702
+ user_effect(() => {
63703
+ var _$$props$thumbnailUrl;
63704
+ const url = (_$$props$thumbnailUrl = $$props.thumbnailUrl) === null || _$$props$thumbnailUrl === void 0 ? void 0 : _$$props$thumbnailUrl.trim();
63705
+ if (!url) {
63706
+ set(imgEl, null);
63707
+ set(imgSize, null);
63708
+ return;
63709
+ }
63710
+ let cancelled = false;
63711
+ const img = new Image();
63712
+ img.onload = () => {
63713
+ if (cancelled) return;
63714
+ set(imgEl, img, true);
63715
+ set(imgSize, {
63716
+ w: img.naturalWidth,
63717
+ h: img.naturalHeight
63718
+ }, true);
63719
+ };
63720
+ img.onerror = () => {
63721
+ if (cancelled) return;
63722
+ set(imgEl, null);
63723
+ set(imgSize, null);
63724
+ };
63725
+ img.src = url;
63726
+ return () => {
63727
+ cancelled = true;
63728
+ };
63729
+ });
63730
+ user_effect(() => {
63731
+ const coords = coordinates();
63732
+ const size = get(imgSize);
63733
+ const el = get(canvasEl);
63734
+ const isEditing = get(editing);
63735
+ if (!size || !el) return;
63736
+ untrack(() => {
63737
+ if (!isEditing) {
63738
+ const next = coordinatesToImagePoints(coords, size);
63739
+ if (!samePoints(get(draft), next)) set(draft, next, true);
63740
+ }
63741
+ redraw();
63742
+ });
63743
+ });
63744
+ function scale() {
63745
+ if (!get(imgSize)) return 1;
63746
+ return displayW / get(imgSize).w;
63747
+ }
63748
+ function canvasH() {
63749
+ if (!get(imgSize)) return 135;
63750
+ return Math.round(get(imgSize).h * scale());
63751
+ }
63752
+ function toImage(e) {
63753
+ if (!get(canvasEl) || !get(imgSize)) return null;
63754
+ const rect = get(canvasEl).getBoundingClientRect();
63755
+ const s = scale();
63756
+ return {
63757
+ x: (e.clientX - rect.left) / s,
63758
+ y: (e.clientY - rect.top) / s
63759
+ };
63760
+ }
63761
+ function redraw() {
63762
+ if (!get(canvasEl) || !get(imgEl) || !get(imgSize)) return;
63763
+ const s = scale();
63764
+ const w = displayW;
63765
+ const h = canvasH();
63766
+ if (get(canvasEl).width !== w || get(canvasEl).height !== h) {
63767
+ get(canvasEl).width = w;
63768
+ get(canvasEl).height = h;
63769
+ }
63770
+ const ctx = get(canvasEl).getContext("2d");
63771
+ if (!ctx) return;
63772
+ ctx.clearRect(0, 0, w, h);
63773
+ ctx.drawImage(get(imgEl), 0, 0, w, h);
63774
+ const placed = get(draft);
63775
+ const pts = [...placed];
63776
+ if (get(editing) && get(cursor)) pts.push(get(cursor));
63777
+ if (pts.length >= 1) {
63778
+ ctx.save();
63779
+ ctx.strokeStyle = FOV_COLOR;
63780
+ ctx.fillStyle = "rgba(59,130,246,0.28)";
63781
+ ctx.lineWidth = 2;
63782
+ ctx.lineJoin = "round";
63783
+ if (pts.length >= 2) {
63784
+ ctx.beginPath();
63785
+ ctx.moveTo(pts[0].x * s, pts[0].y * s);
63786
+ for (let i = 1; i < pts.length; i++) ctx.lineTo(pts[i].x * s, pts[i].y * s);
63787
+ if (!get(editing) && placed.length >= 3) {
63788
+ ctx.closePath();
63789
+ ctx.fill();
63790
+ } else if (get(editing)) ctx.setLineDash([6, 4]);
63791
+ ctx.stroke();
63792
+ ctx.setLineDash([]);
63793
+ }
63794
+ if (get(editing) && get(cursor) && placed.length >= 3) {
63795
+ ctx.globalAlpha = .45;
63796
+ ctx.setLineDash([4, 4]);
63797
+ ctx.beginPath();
63798
+ ctx.moveTo(get(cursor).x * s, get(cursor).y * s);
63799
+ ctx.lineTo(placed[0].x * s, placed[0].y * s);
63800
+ ctx.stroke();
63801
+ ctx.setLineDash([]);
63802
+ ctx.globalAlpha = 1;
63803
+ }
63804
+ for (let i = 0; i < placed.length; i++) drawVertexIndexBadge(ctx, placed[i].x * s, placed[i].y * s, i, FOV_COLOR, 10);
63805
+ ctx.restore();
63806
+ }
63807
+ }
63808
+ function hitVertex(p) {
63809
+ if (!get(imgSize)) return -1;
63810
+ const tol = 8 / scale();
63811
+ for (let i = 0; i < get(draft).length; i++) if (Math.hypot(get(draft)[i].x - p.x, get(draft)[i].y - p.y) <= tol) return i;
63812
+ return -1;
63813
+ }
63814
+ function pointInImagePoly(p, poly) {
63815
+ if (poly.length < 3) return false;
63816
+ let inside = false;
63817
+ for (let i = 0, j = poly.length - 1; i < poly.length; j = i++) {
63818
+ const xi = poly[i].x, yi = poly[i].y;
63819
+ const xj = poly[j].x, yj = poly[j].y;
63820
+ if (yi > p.y !== yj > p.y && p.x < (xj - xi) * (p.y - yi) / (yj - yi || Number.EPSILON) + xi) inside = !inside;
63821
+ }
63822
+ return inside;
63823
+ }
63824
+ function onDown(e) {
63825
+ const p = toImage(e);
63826
+ if (!p || !get(imgSize)) return;
63827
+ if (!get(editing)) {
63828
+ const vi = hitVertex(p);
63829
+ if (vi >= 0) {
63830
+ set(polySelected, true);
63831
+ set(draggingIdx, vi, true);
63832
+ return;
63833
+ }
63834
+ if (get(draft).length >= 3 && pointInImagePoly(p, get(draft))) {
63835
+ set(polySelected, true);
63836
+ return;
63837
+ }
63838
+ set(polySelected, false);
63839
+ return;
63840
+ }
63841
+ set(draft, [...get(draft), p], true);
63842
+ set(polySelected, true);
63843
+ redraw();
63844
+ }
63845
+ function onDblClick(e) {
63846
+ if (readOnly() || !get(editing)) return;
63847
+ e.preventDefault();
63848
+ if (get(draft).length >= 3) commitDraft();
63849
+ }
63850
+ function onMove(e) {
63851
+ const p = toImage(e);
63852
+ if (!p) return;
63853
+ if (get(draggingIdx) != null) {
63854
+ const next = get(draft).map((pt) => ({ ...pt }));
63855
+ next[get(draggingIdx)] = p;
63856
+ set(draft, next, true);
63857
+ redraw();
63858
+ return;
63859
+ }
63860
+ if (get(editing)) {
63861
+ set(cursor, p, true);
63862
+ redraw();
63863
+ }
63864
+ }
63865
+ function onUp() {
63866
+ if (get(draggingIdx) != null) {
63867
+ set(draggingIdx, null);
63868
+ commitDraft();
63869
+ }
63870
+ }
63871
+ function onKeyDown(e) {
63872
+ if (readOnly() || !get(editing)) return;
63873
+ if (e.key === "Enter" && get(draft).length >= 3) {
63874
+ e.preventDefault();
63875
+ e.stopPropagation();
63876
+ commitDraft();
63877
+ }
63878
+ if (e.key === "Escape") {
63879
+ e.preventDefault();
63880
+ set(editing, false);
63881
+ set(cursor, null);
63882
+ set(draft, coordinatesToImagePoints(coordinates(), get(imgSize)), true);
63883
+ redraw();
63884
+ }
63885
+ }
63886
+ function commitDraft() {
63887
+ if (!get(imgSize) || get(draft).length < 3) return;
63888
+ const str = imagePointsToCoordinates(get(draft), get(imgSize));
63889
+ if (!str) return;
63890
+ setCameraImageCoordinates($$props.serial, str);
63891
+ set(editing, false);
63892
+ set(cursor, null);
63893
+ set(polySelected, true);
63894
+ redraw();
63895
+ }
63896
+ function startDraw() {
63897
+ set(draft, [], true);
63898
+ set(cursor, null);
63899
+ set(editing, true);
63900
+ set(polySelected, true);
63901
+ redraw();
63902
+ }
63903
+ function clearFov() {
63904
+ set(draft, [], true);
63905
+ set(editing, false);
63906
+ set(cursor, null);
63907
+ set(polySelected, false);
63908
+ setCameraImageCoordinates($$props.serial, null);
63909
+ redraw();
63910
+ }
63911
+ function onFloatConfirm() {
63912
+ if (get(editing) && get(draft).length >= 3) commitDraft();
63913
+ }
63914
+ function onFloatDelete() {
63915
+ if (get(editing)) {
63916
+ set(draft, [], true);
63917
+ set(cursor, null);
63918
+ set(editing, false);
63919
+ set(polySelected, false);
63920
+ redraw();
63921
+ return;
63922
+ }
63923
+ clearFov();
63924
+ }
63925
+ var fragment = comment();
63926
+ event("keydown", $window, onKeyDown);
63927
+ var node = first_child(fragment);
63928
+ var consequent_8 = ($$anchor) => {
63929
+ var div = root_1$7();
63930
+ var node_1 = child(div);
63931
+ var consequent_1 = ($$anchor) => {
63932
+ var div_1 = root_2$8();
63933
+ var node_2 = sibling(child(div_1), 2);
63934
+ var consequent = ($$anchor) => {
63935
+ var button = root_3$7();
63936
+ var text = child(button, true);
63937
+ reset(button);
63938
+ template_effect(() => set_text(text, get(imgN) >= 3 ? "Redraw" : "Draw"));
63939
+ delegated("click", button, startDraw);
63940
+ append($$anchor, button);
63941
+ };
63942
+ if_block(node_2, ($$render) => {
63943
+ if (!get(editing)) $$render(consequent);
63944
+ });
63945
+ reset(div_1);
63946
+ append($$anchor, div_1);
63947
+ };
63948
+ if_block(node_1, ($$render) => {
63949
+ if (!readOnly()) $$render(consequent_1);
63950
+ });
63951
+ var div_2 = sibling(node_1, 2);
63952
+ var canvas = child(div_2);
63953
+ set_style(canvas, "max-width: 380px; height: auto;");
63954
+ bind_this(canvas, ($$value) => set(canvasEl, $$value), () => get(canvasEl));
63955
+ var node_3 = sibling(canvas, 2);
63956
+ var consequent_2 = ($$anchor) => {
63957
+ {
63958
+ let $0 = /* @__PURE__ */ user_derived(() => get(editing) && get(draft).length >= 3);
63959
+ PolygonFloatToolbar($$anchor, {
63960
+ get x() {
63961
+ return get(floatTbPos).x;
63962
+ },
63963
+ get y() {
63964
+ return get(floatTbPos).y;
63965
+ },
63966
+ get showConfirm() {
63967
+ return get(editing);
63968
+ },
63969
+ get canConfirm() {
63970
+ return get($0);
63971
+ },
63972
+ onConfirm: onFloatConfirm,
63973
+ onDelete: onFloatDelete
63974
+ });
63975
+ }
63976
+ };
63977
+ if_block(node_3, ($$render) => {
63978
+ if (get(showFloatTb) && get(floatTbPos)) $$render(consequent_2);
63979
+ });
63980
+ reset(div_2);
63981
+ var node_4 = sibling(div_2, 2);
63982
+ var consequent_7 = ($$anchor) => {
63983
+ var fragment_2 = root_5$4();
63984
+ var p_1 = first_child(fragment_2);
63985
+ var node_5 = child(p_1);
63986
+ var consequent_3 = ($$anchor) => {
63987
+ var fragment_3 = root_6$3();
63988
+ var text_1 = sibling(first_child(fragment_3), 2);
63989
+ template_effect(() => set_text(text_1, ` trên toolbar để đóng polygon (≥3) · 🗑 xoá`));
63990
+ append($$anchor, fragment_3);
63991
+ };
63992
+ var consequent_5 = ($$anchor) => {
63993
+ var fragment_4 = root_7$4();
63994
+ var text_2 = first_child(fragment_4);
63995
+ var node_6 = sibling(text_2);
63996
+ var consequent_4 = ($$anchor) => {
63997
+ var text_3 = text$1();
63998
+ template_effect(() => {
63999
+ var _$$get;
64000
+ return set_text(text_3, `· floor ${(_$$get = get(mapN)) !== null && _$$get !== void 0 ? _$$get : ""} pts`);
64001
+ });
64002
+ append($$anchor, text_3);
64003
+ };
64004
+ if_block(node_6, ($$render) => {
64005
+ if (get(mapN) > 0) $$render(consequent_4);
64006
+ });
64007
+ template_effect(() => {
64008
+ var _$$get2;
64009
+ return set_text(text_2, `${(_$$get2 = get(imgN)) !== null && _$$get2 !== void 0 ? _$$get2 : ""} points — click polygon để hiện toolbar `);
64010
+ });
64011
+ append($$anchor, fragment_4);
64012
+ };
64013
+ var alternate = ($$anchor) => {
64014
+ var text_4 = text$1();
64015
+ template_effect(() => set_text(text_4, `Draw FOV polygon on camera thumbnail (≥3 pts)`));
64016
+ append($$anchor, text_4);
64017
+ };
64018
+ if_block(node_5, ($$render) => {
64019
+ if (get(editing)) $$render(consequent_3);
64020
+ else if (get(imgN) >= 3) $$render(consequent_5, 1);
64021
+ else $$render(alternate, -1);
64022
+ });
64023
+ reset(p_1);
64024
+ var node_7 = sibling(p_1, 2);
64025
+ var consequent_6 = ($$anchor) => {
64026
+ var p_2 = root_10$2();
64027
+ var text_5 = child(p_2);
64028
+ reset(p_2);
64029
+ template_effect(() => {
64030
+ var _$$get3, _$$get4;
64031
+ return set_text(text_5, `Point count mismatch: image ${(_$$get3 = get(imgN)) !== null && _$$get3 !== void 0 ? _$$get3 : ""} ≠ floor ${(_$$get4 = get(mapN)) !== null && _$$get4 !== void 0 ? _$$get4 : ""}. Heatmap transform needs the same N and order.`);
64032
+ });
64033
+ append($$anchor, p_2);
64034
+ };
64035
+ if_block(node_7, ($$render) => {
64036
+ if (!get(matchOk)) $$render(consequent_6);
64037
+ });
64038
+ append($$anchor, fragment_2);
64039
+ };
64040
+ if_block(node_4, ($$render) => {
64041
+ if (!readOnly()) $$render(consequent_7);
64042
+ });
64043
+ reset(div);
64044
+ template_effect(() => set_class(canvas, 1, `w-full rounded border border-gray-200 bg-black/5 touch-none ${readOnly() ? "cursor-default" : "cursor-crosshair"}`));
64045
+ delegated("mousedown", canvas, function(...$$args) {
64046
+ var _ref;
64047
+ (_ref = readOnly() ? void 0 : onDown) === null || _ref === void 0 || _ref.apply(this, $$args);
64048
+ });
64049
+ delegated("mousemove", canvas, function(...$$args) {
64050
+ var _ref2;
64051
+ (_ref2 = readOnly() ? void 0 : onMove) === null || _ref2 === void 0 || _ref2.apply(this, $$args);
64052
+ });
64053
+ delegated("mouseup", canvas, function(...$$args) {
64054
+ var _ref3;
64055
+ (_ref3 = readOnly() ? void 0 : onUp) === null || _ref3 === void 0 || _ref3.apply(this, $$args);
64056
+ });
64057
+ event("mouseleave", canvas, function(...$$args) {
64058
+ var _ref4;
64059
+ (_ref4 = readOnly() ? void 0 : onUp) === null || _ref4 === void 0 || _ref4.apply(this, $$args);
64060
+ });
64061
+ delegated("dblclick", canvas, function(...$$args) {
64062
+ var _ref5;
64063
+ (_ref5 = readOnly() ? void 0 : onDblClick) === null || _ref5 === void 0 || _ref5.apply(this, $$args);
64064
+ });
64065
+ append($$anchor, div);
64066
+ };
64067
+ var d = /* @__PURE__ */ user_derived(() => {
64068
+ var _$$props$thumbnailUrl2;
64069
+ return (_$$props$thumbnailUrl2 = $$props.thumbnailUrl) === null || _$$props$thumbnailUrl2 === void 0 ? void 0 : _$$props$thumbnailUrl2.trim();
64070
+ });
64071
+ var alternate_1 = ($$anchor) => {
64072
+ append($$anchor, root_11$2());
64073
+ };
64074
+ if_block(node, ($$render) => {
64075
+ if (get(d)) $$render(consequent_8);
64076
+ else $$render(alternate_1, -1);
64077
+ });
64078
+ append($$anchor, fragment);
64079
+ pop();
64080
+ }
64081
+ delegate([
64082
+ "click",
64083
+ "mousedown",
64084
+ "mousemove",
64085
+ "mouseup",
64086
+ "dblclick"
64087
+ ]);
64088
+ //#endregion
63488
64089
  //#region src/lib/components/sidebar/PropertiesPanel.svelte
63489
64090
  init_client();
63490
- var root_3$7 = /* @__PURE__ */ from_html(`<button></button>`);
63491
- var root_4$6 = /* @__PURE__ */ from_html(`<button><span class="bg-white/80 backdrop-blur-sm rounded px-1 py-0.5 mb-0.5 text-gray-700"> </span></button>`);
63492
- var root_2$8 = /* @__PURE__ */ from_html(`<div class="space-y-2"><span class="text-xs text-gray-500">Color</span> <div class="grid grid-cols-6 gap-1.5"></div> <label 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"/></label> <span class="text-xs text-gray-500">Texture</span> <div class="grid grid-cols-3 gap-1.5"><button>None</button> <!></div></div>`);
63493
- var root_6$3 = /* @__PURE__ */ from_html(`<button></button>`);
64091
+ var root_3$6 = /* @__PURE__ */ from_html(`<button></button>`);
64092
+ var root_4$5 = /* @__PURE__ */ from_html(`<button><span class="bg-white/80 backdrop-blur-sm rounded px-1 py-0.5 mb-0.5 text-gray-700"> </span></button>`);
64093
+ var root_2$7 = /* @__PURE__ */ from_html(`<div class="space-y-2"><span class="text-xs text-gray-500">Color</span> <div class="grid grid-cols-6 gap-1.5"></div> <label 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"/></label> <span class="text-xs text-gray-500">Texture</span> <div class="grid grid-cols-3 gap-1.5"><button>None</button> <!></div></div>`);
64094
+ var root_6$2 = /* @__PURE__ */ from_html(`<button></button>`);
63494
64095
  var root_7$3 = /* @__PURE__ */ from_html(`<button><span class="bg-white/80 backdrop-blur-sm rounded px-1 py-0.5 mb-0.5 text-gray-700"> </span></button>`);
63495
- var root_5$4 = /* @__PURE__ */ from_html(`<div class="space-y-2"><span class="text-xs text-gray-500">Color</span> <div class="grid grid-cols-6 gap-1.5"></div> <label 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"/></label> <span class="text-xs text-gray-500">Texture</span> <div class="grid grid-cols-3 gap-1.5"><button>None</button> <!></div></div>`);
63496
- var root_1$8 = /* @__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> Wall Properties</h3> <div class="space-y-3"><label class="block"><span class="text-xs text-gray-500"> </span> <input type="number" disabled="" class="w-full px-2 py-1 border border-gray-200 rounded text-sm bg-gray-50"/></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> <div class="flex items-center gap-2"><span class="text-xs text-gray-500">Curved</span> <button> </button></div> <div><div class="flex border-b border-gray-200 mb-3"><button>Interior</button> <button>Exterior</button></div> <!></div></div>`, 1);
63497
- var root_8$2 = /* @__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-amber-100 rounded flex items-center justify-center text-xs">🚪</span> Door Properties</h3> <div class="space-y-3"><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" 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"> </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">Type</span> <select class="w-full px-2 py-1 border border-gray-200 rounded text-sm"><option>Single</option><option>Double</option><option>Sliding</option><option>French</option><option>Pocket</option><option>Bifold</option></select></label> <label class="block"><span class="text-xs text-gray-500">Hinge Side</span> <div class="flex gap-2"><button>Left</button> <button>Right</button></div></label> <label class="block"><span class="text-xs text-gray-500">Opens</span> <div class="flex gap-2"><button>Inward</button> <button>Outward</button></div></label></div>`, 1);
64096
+ var root_5$3 = /* @__PURE__ */ from_html(`<div class="space-y-2"><span class="text-xs text-gray-500">Color</span> <div class="grid grid-cols-6 gap-1.5"></div> <label 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"/></label> <span class="text-xs text-gray-500">Texture</span> <div class="grid grid-cols-3 gap-1.5"><button>None</button> <!></div></div>`);
64097
+ var root_1$6 = /* @__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> Wall Properties</h3> <div class="space-y-3"><label class="block"><span class="text-xs text-gray-500"> </span> <input type="number" disabled="" class="w-full px-2 py-1 border border-gray-200 rounded text-sm bg-gray-50"/></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> <div class="flex items-center gap-2"><span class="text-xs text-gray-500">Curved</span> <button> </button></div> <div><div class="flex border-b border-gray-200 mb-3"><button>Interior</button> <button>Exterior</button></div> <!></div></div>`, 1);
64098
+ var root_8$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-amber-100 rounded flex items-center justify-center text-xs">🚪</span> Door Properties</h3> <div class="space-y-3"><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" 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"> </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">Type</span> <select class="w-full px-2 py-1 border border-gray-200 rounded text-sm"><option>Single</option><option>Double</option><option>Sliding</option><option>French</option><option>Pocket</option><option>Bifold</option></select></label> <label class="block"><span class="text-xs text-gray-500">Hinge Side</span> <div class="flex gap-2"><button>Left</button> <button>Right</button></div></label> <label class="block"><span class="text-xs text-gray-500">Opens</span> <div class="flex gap-2"><button>Inward</button> <button>Outward</button></div></label></div>`, 1);
63498
64099
  var root_9$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-cyan-100 rounded flex items-center justify-center text-xs">🪟</span> Window 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>Standard</option><option>Fixed</option><option>Casement</option><option>Sliding</option><option>Bay</option></select></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" 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"> </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></div>`, 1);
63499
64100
  var root_13$1 = /* @__PURE__ */ from_html(`<option> </option>`);
63500
- var root_12$2 = /* @__PURE__ */ from_html(`<label class="block"><span class="text-xs text-gray-500">Camera</span> <select class="w-full px-2 py-1 border border-gray-200 rounded text-sm bg-white"><option>Select camera...</option><!></select></label>`);
64101
+ var root_12$1 = /* @__PURE__ */ from_html(`<label class="block"><span class="text-xs text-gray-500">Camera</span> <select class="w-full px-2 py-1 border border-gray-200 rounded text-sm bg-white"><option>Select camera...</option><!></select></label>`);
63501
64102
  var root_14$1 = /* @__PURE__ */ from_html(`<label class="block"><span class="text-xs text-gray-500"> </span> <input type="text"/></label>`);
63502
- var root_17$1 = /* @__PURE__ */ from_html(`<div> </div>`);
63503
- var root_18$1 = /* @__PURE__ */ from_html(`<div> </div>`);
63504
- var root_16$1 = /* @__PURE__ */ from_html(`<div class="text-[10px] text-gray-500 space-y-0.5 font-mono break-all"><!> <!></div>`);
63505
- var root_15 = /* @__PURE__ */ from_html(`<p class="text-[10px] text-gray-400 mt-2 leading-snug">FOV: use <strong>Draw surveillance FOV</strong> on the floor (<code class="font-mono">mapCoordinates</code>).
63506
- Select camera + host <code class="font-mono">cameraThumbnail</code> → panel beside canvas (<code class="font-mono">coordinates</code>).</p> <!>`, 1);
63507
- var root_11$2 = /* @__PURE__ */ from_html(`<!> <!> <!>`, 1);
63508
- var root_19$1 = /* @__PURE__ */ from_html(`<button></button>`);
64103
+ var root_15$1 = /* @__PURE__ */ from_html(`<p class="text-[10px] text-gray-400 mt-2 leading-snug">FOV sàn: tool <strong>Camera FOV</strong> → <code class="font-mono">mapCoordinates</code>.
64104
+ FOV ảnh: vẽ trên thumbnail · đỉnh đánh số 0…n · double-click / Enter / Done để kết thúc.</p>`);
64105
+ var root_16 = /* @__PURE__ */ from_html(`<div class="pt-1 space-y-1.5"><div class="text-xs font-semibold text-gray-700">Camera thumbnail</div> <!></div>`);
64106
+ var root_17$1 = /* @__PURE__ */ from_html(`<p class="text-[10px] text-amber-700 bg-amber-50 border border-amber-100 rounded px-1.5 py-1">Host chưa gửi <code class="font-mono">cameraThumbnail</code> cho cam này.</p>`);
64107
+ var root_11$1 = /* @__PURE__ */ from_html(`<!> <!> <!> <!>`, 1);
64108
+ var root_18$1 = /* @__PURE__ */ from_html(`<button></button>`);
63509
64109
  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);
63510
- var root_21$1 = /* @__PURE__ */ from_html(`<option> </option>`);
63511
- var root_22$1 = /* @__PURE__ */ from_html(`<button></button>`);
63512
- var root_25$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>`);
63513
- var root_23$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>`);
63514
- var root_20$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);
63515
- var root_26$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);
63516
- var root_28 = /* @__PURE__ */ from_html(`<button></button>`);
63517
- var root_29 = /* @__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>`);
63518
- var root_27 = /* @__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);
63519
- var root_31 = /* @__PURE__ */ from_html(`<div class="text-xs text-gray-500">Camera: <span class="text-gray-700 font-mono"> </span></div>`);
63520
- var root_32 = /* @__PURE__ */ from_html(`<button type="button"></button>`);
63521
- var root_30 = /* @__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 rounded flex items-center justify-center text-xs">⬡</span> Zone</h3> <label class="block"><span class="text-xs text-gray-500">Name</span> <input type="text" class="w-full px-2 py-1 border border-gray-200 rounded text-sm" title="From assignedCameras.zone when linked"/></label> <!> <div class="text-xs text-gray-500">Shape: <span class="text-gray-700 capitalize"> </span></div> <label class="block"><span class="text-xs text-gray-500">Color</span> <div class="flex flex-wrap gap-1.5 mt-1"><!> <input type="color" class="w-8 h-6 rounded border border-gray-200 cursor-pointer"/></div></label> <label class="block"><span class="text-xs text-gray-500">Fill opacity</span> <input type="range" min="0" max="0.4" step="0.02" class="w-full"/></label></div>`);
63522
- var root_33 = /* @__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>`);
63523
- var root_34 = /* @__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>`);
64110
+ var root_20$1 = /* @__PURE__ */ from_html(`<option> </option>`);
64111
+ var root_21$1 = /* @__PURE__ */ from_html(`<button></button>`);
64112
+ var root_24$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>`);
64113
+ var root_22$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>`);
64114
+ var root_19$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);
64115
+ 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> 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);
64116
+ var root_27 = /* @__PURE__ */ from_html(`<button></button>`);
64117
+ var root_28 = /* @__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>`);
64118
+ var root_26 = /* @__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);
64119
+ var root_30 = /* @__PURE__ */ from_html(`<div class="text-xs text-gray-500">Camera: <span class="text-gray-700 font-mono"> </span></div>`);
64120
+ var root_31 = /* @__PURE__ */ from_html(`<button type="button"></button>`);
64121
+ var root_29 = /* @__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 rounded flex items-center justify-center text-xs">⬡</span> Zone</h3> <label class="block"><span class="text-xs text-gray-500">Name</span> <input type="text" class="w-full px-2 py-1 border border-gray-200 rounded text-sm" title="From assignedCameras.zone when linked"/></label> <!> <div class="text-xs text-gray-500">Shape: <span class="text-gray-700 capitalize"> </span></div> <label class="block"><span class="text-xs text-gray-500">Color</span> <div class="flex flex-wrap gap-1.5 mt-1"><!> <input type="color" class="w-8 h-6 rounded border border-gray-200 cursor-pointer"/></div></label> <label class="block"><span class="text-xs text-gray-500">Fill opacity</span> <input type="range" min="0" max="0.4" step="0.02" class="w-full"/></label></div>`);
64122
+ var root_32 = /* @__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>`);
64123
+ var root_33 = /* @__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>`);
63524
64124
  var root$3 = /* @__PURE__ */ from_html(`<div data-properties-panel="" style="top: 0; bottom: 0;"><!> <!></div>`);
63525
64125
  function PropertiesPanel($$anchor, $$props) {
63526
64126
  push($$props, true);
@@ -63558,8 +64158,7 @@ function PropertiesPanel($$anchor, $$props) {
63558
64158
  function unitLabel() {
63559
64159
  return get(settings).units === "imperial" ? "in" : "cm";
63560
64160
  }
63561
- let is3D = prop($$props, "is3D", 3, false), siteCameras = prop($$props, "siteCameras", 19, () => []);
63562
- prop($$props, "cameraThumbnail", 3, "");
64161
+ let is3D = prop($$props, "is3D", 3, false), siteCameras = prop($$props, "siteCameras", 19, () => []), cameraThumbnail = prop($$props, "cameraThumbnail", 3, "");
63563
64162
  let wallSideTab = /* @__PURE__ */ state("interior");
63564
64163
  let selectedWall = /* @__PURE__ */ user_derived(() => {
63565
64164
  var _$$get$walls$find, _$$get;
@@ -64040,11 +64639,15 @@ function PropertiesPanel($$anchor, $$props) {
64040
64639
  }
64041
64640
  ];
64042
64641
  let hasSelection = /* @__PURE__ */ user_derived(() => !!get(selectedWall) || !!get(selectedDoor) || !!get(selectedWindow) || !!get(selectedFurniture) || !!get(selectedRoom) || !!get(selectedStair) || !!get(selectedColumn) || !!get(selectedTextAnnotation) || !!get(selectedZone) || !is3D() && get(hasBgImage));
64642
+ let showCameraThumbnail = /* @__PURE__ */ user_derived(() => {
64643
+ var _$$get15, _cameraThumbnail;
64644
+ return ((_$$get15 = get(selectedFurniture)) === null || _$$get15 === void 0 ? void 0 : _$$get15.catalogId) === "camera" && !!((_cameraThumbnail = cameraThumbnail()) === null || _cameraThumbnail === void 0 ? void 0 : _cameraThumbnail.trim());
64645
+ });
64043
64646
  var div = root$3();
64044
64647
  let classes;
64045
64648
  var node = child(div);
64046
64649
  var consequent_1 = ($$anchor) => {
64047
- var fragment = root_1$8();
64650
+ var fragment = root_1$6();
64048
64651
  var div_1 = sibling(first_child(fragment), 2);
64049
64652
  var label = child(div_1);
64050
64653
  var span = child(label);
@@ -64081,10 +64684,10 @@ function PropertiesPanel($$anchor, $$props) {
64081
64684
  var consequent = ($$anchor) => {
64082
64685
  const sideColor = /* @__PURE__ */ user_derived(() => get(selectedWall).interiorColor || get(selectedWall).color);
64083
64686
  const sideTex = /* @__PURE__ */ user_derived(() => get(selectedWall).interiorTexture === "none" ? void 0 : get(selectedWall).interiorTexture || get(selectedWall).texture);
64084
- var div_5 = root_2$8();
64687
+ var div_5 = root_2$7();
64085
64688
  var div_6 = sibling(child(div_5), 2);
64086
64689
  each(div_6, 21, () => wallColors, index$1, ($$anchor, wc) => {
64087
- var button_3 = root_3$7();
64690
+ var button_3 = root_3$6();
64088
64691
  template_effect(() => {
64089
64692
  var _$$get$color;
64090
64693
  set_class(button_3, 1, `w-7 h-7 rounded-md border-2 hover:border-gray-300 transition-colors ${get(sideColor) === get(wc).color ? "border-blue-500 ring-1 ring-blue-200" : "border-gray-200"}`);
@@ -64115,7 +64718,7 @@ function PropertiesPanel($$anchor, $$props) {
64115
64718
  "subway-tile": images.subwayTile
64116
64719
  }[get(wc).id]) !== null && _redBrick$exposedBr !== void 0 ? _redBrick$exposedBr : "";
64117
64720
  });
64118
- var button_5 = root_4$6();
64721
+ var button_5 = root_4$5();
64119
64722
  var span_3 = child(button_5);
64120
64723
  var text_4 = child(span_3, true);
64121
64724
  reset(span_3);
@@ -64150,10 +64753,10 @@ function PropertiesPanel($$anchor, $$props) {
64150
64753
  var alternate = ($$anchor) => {
64151
64754
  const sideColor = /* @__PURE__ */ user_derived(() => get(selectedWall).exteriorColor || get(selectedWall).color);
64152
64755
  const sideTex = /* @__PURE__ */ user_derived(() => get(selectedWall).exteriorTexture === "none" ? void 0 : get(selectedWall).exteriorTexture || get(selectedWall).texture);
64153
- var div_8 = root_5$4();
64756
+ var div_8 = root_5$3();
64154
64757
  var div_9 = sibling(child(div_8), 2);
64155
64758
  each(div_9, 21, () => wallColors, index$1, ($$anchor, wc) => {
64156
- var button_6 = root_6$3();
64759
+ var button_6 = root_6$2();
64157
64760
  template_effect(() => {
64158
64761
  var _$$get$color2;
64159
64762
  set_class(button_6, 1, `w-7 h-7 rounded-md border-2 hover:border-gray-300 transition-colors ${get(sideColor) === get(wc).color ? "border-blue-500 ring-1 ring-blue-200" : "border-gray-200"}`);
@@ -64262,7 +64865,7 @@ function PropertiesPanel($$anchor, $$props) {
64262
64865
  append($$anchor, fragment);
64263
64866
  };
64264
64867
  var consequent_2 = ($$anchor) => {
64265
- var fragment_1 = root_8$2();
64868
+ var fragment_1 = root_8$1();
64266
64869
  var div_11 = sibling(first_child(fragment_1), 2);
64267
64870
  var label_5 = child(div_11);
64268
64871
  var span_5 = child(label_5);
@@ -64324,7 +64927,7 @@ function PropertiesPanel($$anchor, $$props) {
64324
64927
  reset(label_11);
64325
64928
  reset(div_11);
64326
64929
  template_effect(($0, $1, $2, $3, $4, $5, $6, $7) => {
64327
- var _$$get15, _$$get16, _$$get17, _$$get18;
64930
+ var _$$get16, _$$get17, _$$get18, _$$get19;
64328
64931
  set_text(text_6, `Width (${$0 !== null && $0 !== void 0 ? $0 : ""})`);
64329
64932
  set_value(input_5, $1);
64330
64933
  set_text(text_7, `Distance from A (${$2 !== null && $2 !== void 0 ? $2 : ""})`);
@@ -64337,10 +64940,10 @@ function PropertiesPanel($$anchor, $$props) {
64337
64940
  var _select$__value;
64338
64941
  select.value = (_select$__value = select.__value = get(selectedDoor).type) !== null && _select$__value !== void 0 ? _select$__value : "", select_option(select, get(selectedDoor).type);
64339
64942
  }
64340
- set_class(button_9, 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) === "left" ? "bg-blue-100 border-blue-400 text-blue-700" : "border-gray-200 hover:bg-gray-50"}`);
64341
- set_class(button_10, 1, `flex-1 px-2 py-1.5 border rounded text-sm transition-colors ${((_$$get16 = get(selectedDoor)) === null || _$$get16 === void 0 ? void 0 : _$$get16.swingDirection) === "right" ? "bg-blue-100 border-blue-400 text-blue-700" : "border-gray-200 hover:bg-gray-50"}`);
64342
- set_class(button_11, 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"}`);
64343
- set_class(button_12, 1, `flex-1 px-2 py-1.5 border rounded text-sm transition-colors ${((_$$get18 = get(selectedDoor)) === null || _$$get18 === void 0 ? void 0 : _$$get18.flipSide) ? "bg-blue-100 border-blue-400 text-blue-700" : "border-gray-200 hover:bg-gray-50"}`);
64943
+ set_class(button_9, 1, `flex-1 px-2 py-1.5 border rounded text-sm transition-colors ${((_$$get16 = get(selectedDoor)) === null || _$$get16 === void 0 ? void 0 : _$$get16.swingDirection) === "left" ? "bg-blue-100 border-blue-400 text-blue-700" : "border-gray-200 hover:bg-gray-50"}`);
64944
+ set_class(button_10, 1, `flex-1 px-2 py-1.5 border rounded text-sm transition-colors ${((_$$get17 = get(selectedDoor)) === null || _$$get17 === void 0 ? void 0 : _$$get17.swingDirection) === "right" ? "bg-blue-100 border-blue-400 text-blue-700" : "border-gray-200 hover:bg-gray-50"}`);
64945
+ set_class(button_11, 1, `flex-1 px-2 py-1.5 border rounded text-sm transition-colors ${!((_$$get18 = get(selectedDoor)) === null || _$$get18 === void 0 ? void 0 : _$$get18.flipSide) ? "bg-blue-100 border-blue-400 text-blue-700" : "border-gray-200 hover:bg-gray-50"}`);
64946
+ set_class(button_12, 1, `flex-1 px-2 py-1.5 border rounded text-sm transition-colors ${((_$$get19 = get(selectedDoor)) === null || _$$get19 === void 0 ? void 0 : _$$get19.flipSide) ? "bg-blue-100 border-blue-400 text-blue-700" : "border-gray-200 hover:bg-gray-50"}`);
64344
64947
  }, [
64345
64948
  () => unitLabel(),
64346
64949
  () => displayValue(get(selectedDoor).width),
@@ -64464,7 +65067,7 @@ function PropertiesPanel($$anchor, $$props) {
64464
65067
  delegated("input", input_13, onWindowSill);
64465
65068
  append($$anchor, fragment_2);
64466
65069
  };
64467
- var consequent_10 = ($$anchor) => {
65070
+ var consequent_9 = ($$anchor) => {
64468
65071
  var fragment_3 = root_10$1();
64469
65072
  var h3 = first_child(fragment_3);
64470
65073
  var span_14 = child(h3);
@@ -64477,11 +65080,11 @@ function PropertiesPanel($$anchor, $$props) {
64477
65080
  reset(h3);
64478
65081
  var div_15 = sibling(h3, 2);
64479
65082
  var node_4 = child(div_15);
64480
- var consequent_9 = ($$anchor) => {
64481
- var fragment_4 = root_11$2();
65083
+ var consequent_8 = ($$anchor) => {
65084
+ var fragment_4 = root_11$1();
64482
65085
  var node_5 = first_child(fragment_4);
64483
65086
  var consequent_4 = ($$anchor) => {
64484
- var label_18 = root_12$2();
65087
+ var label_18 = root_12$1();
64485
65088
  var select_2 = sibling(child(label_18), 2);
64486
65089
  var option_11 = child(select_2);
64487
65090
  option_11.value = option_11.__value = "";
@@ -64528,61 +65131,62 @@ function PropertiesPanel($$anchor, $$props) {
64528
65131
  append($$anchor, label_19);
64529
65132
  });
64530
65133
  var node_8 = sibling(node_7, 2);
64531
- var consequent_8 = ($$anchor) => {
64532
- var fragment_5 = root_15();
64533
- var node_9 = sibling(first_child(fragment_5), 2);
64534
- var consequent_7 = ($$anchor) => {
64535
- var div_16 = root_16$1();
64536
- var node_10 = child(div_16);
64537
- var consequent_5 = ($$anchor) => {
64538
- var div_17 = root_17$1();
64539
- var text_20 = child(div_17);
64540
- reset(div_17);
64541
- template_effect(() => {
64542
- var _$$get$props$mapCoord;
64543
- return set_text(text_20, `map: ${(_$$get$props$mapCoord = get(selectedFurniture).props.mapCoordinates) !== null && _$$get$props$mapCoord !== void 0 ? _$$get$props$mapCoord : ""}`);
64544
- });
64545
- append($$anchor, div_17);
64546
- };
64547
- if_block(node_10, ($$render) => {
64548
- var _$$get$props2;
64549
- if ((_$$get$props2 = get(selectedFurniture).props) === null || _$$get$props2 === void 0 ? void 0 : _$$get$props2.mapCoordinates) $$render(consequent_5);
65134
+ var consequent_5 = ($$anchor) => {
65135
+ append($$anchor, root_15$1());
65136
+ };
65137
+ if_block(node_8, ($$render) => {
65138
+ if (get(selectedFurniture).serial) $$render(consequent_5);
65139
+ });
65140
+ var node_9 = sibling(node_8, 2);
65141
+ var consequent_6 = ($$anchor) => {
65142
+ var div_16 = root_16();
65143
+ var node_10 = sibling(child(div_16), 2);
65144
+ {
65145
+ let $0 = /* @__PURE__ */ user_derived(() => {
65146
+ var _$$get$props$coordina, _$$get$props2;
65147
+ return (_$$get$props$coordina = (_$$get$props2 = get(selectedFurniture).props) === null || _$$get$props2 === void 0 ? void 0 : _$$get$props2.coordinates) !== null && _$$get$props$coordina !== void 0 ? _$$get$props$coordina : "";
64550
65148
  });
64551
- var node_11 = sibling(node_10, 2);
64552
- var consequent_6 = ($$anchor) => {
64553
- var div_18 = root_18$1();
64554
- var text_21 = child(div_18);
64555
- reset(div_18);
64556
- template_effect(() => {
64557
- var _$$get$props$coordina;
64558
- return set_text(text_21, `img: ${(_$$get$props$coordina = get(selectedFurniture).props.coordinates) !== null && _$$get$props$coordina !== void 0 ? _$$get$props$coordina : ""}`);
64559
- });
64560
- append($$anchor, div_18);
64561
- };
64562
- if_block(node_11, ($$render) => {
64563
- var _$$get$props3;
64564
- if ((_$$get$props3 = get(selectedFurniture).props) === null || _$$get$props3 === void 0 ? void 0 : _$$get$props3.coordinates) $$render(consequent_6);
65149
+ let $1 = /* @__PURE__ */ user_derived(() => {
65150
+ var _$$get$props$mapCoord, _$$get$props3;
65151
+ return (_$$get$props$mapCoord = (_$$get$props3 = get(selectedFurniture).props) === null || _$$get$props3 === void 0 ? void 0 : _$$get$props3.mapCoordinates) !== null && _$$get$props$mapCoord !== void 0 ? _$$get$props$mapCoord : "";
64565
65152
  });
64566
- reset(div_16);
64567
- append($$anchor, div_16);
64568
- };
64569
- if_block(node_9, ($$render) => {
64570
- var _$$get$props4, _$$get$props5;
64571
- if (((_$$get$props4 = get(selectedFurniture).props) === null || _$$get$props4 === void 0 ? void 0 : _$$get$props4.mapCoordinates) || ((_$$get$props5 = get(selectedFurniture).props) === null || _$$get$props5 === void 0 ? void 0 : _$$get$props5.coordinates)) $$render(consequent_7);
64572
- });
64573
- append($$anchor, fragment_5);
65153
+ CameraFovEditor(node_10, {
65154
+ get serial() {
65155
+ return get(selectedFurniture).serial;
65156
+ },
65157
+ get thumbnailUrl() {
65158
+ return cameraThumbnail();
65159
+ },
65160
+ get coordinates() {
65161
+ return get($0);
65162
+ },
65163
+ get mapCoordinates() {
65164
+ return get($1);
65165
+ }
65166
+ });
65167
+ }
65168
+ reset(div_16);
65169
+ append($$anchor, div_16);
64574
65170
  };
64575
- if_block(node_8, ($$render) => {
64576
- if (get(selectedFurniture).serial) $$render(consequent_8);
65171
+ var consequent_7 = ($$anchor) => {
65172
+ append($$anchor, root_17$1());
65173
+ };
65174
+ var d_1 = /* @__PURE__ */ user_derived(() => {
65175
+ var _cameraThumbnail2;
65176
+ return get(selectedFurniture).serial && !((_cameraThumbnail2 = cameraThumbnail()) === null || _cameraThumbnail2 === void 0 ? void 0 : _cameraThumbnail2.trim());
65177
+ });
65178
+ if_block(node_9, ($$render) => {
65179
+ if (get(showCameraThumbnail) && get(selectedFurniture).serial) $$render(consequent_6);
65180
+ else if (get(d_1)) $$render(consequent_7, 1);
64577
65181
  });
64578
65182
  append($$anchor, fragment_4);
64579
65183
  };
64580
65184
  if_block(node_4, ($$render) => {
64581
- if (get(selectedFurniture).catalogId === "camera") $$render(consequent_9);
65185
+ if (get(selectedFurniture).catalogId === "camera") $$render(consequent_8);
64582
65186
  });
64583
- var div_19 = sibling(node_4, 2);
64584
- var div_20 = sibling(child(div_19), 2);
64585
- each(div_20, 20, () => [
65187
+ var div_17 = sibling(node_4, 2);
65188
+ var div_18 = sibling(child(div_17), 2);
65189
+ each(div_18, 20, () => [
64586
65190
  "#ffffff",
64587
65191
  "#f5f5dc",
64588
65192
  "#d2b48c",
@@ -64594,7 +65198,7 @@ function PropertiesPanel($$anchor, $$props) {
64594
65198
  "#dc143c",
64595
65199
  "#228b22"
64596
65200
  ], index$1, ($$anchor, color) => {
64597
- var button_14 = root_19$1();
65201
+ var button_14 = root_18$1();
64598
65202
  template_effect(($0) => {
64599
65203
  set_class(button_14, 1, `w-6 h-6 rounded border-2 hover:border-gray-300 transition-colors ${$0 !== null && $0 !== void 0 ? $0 : ""}`);
64600
65204
  set_style(button_14, `background-color: ${color !== null && color !== void 0 ? color : ""}`);
@@ -64606,29 +65210,29 @@ function PropertiesPanel($$anchor, $$props) {
64606
65210
  delegated("click", button_14, () => onFurnitureColor(color));
64607
65211
  append($$anchor, button_14);
64608
65212
  });
64609
- reset(div_20);
64610
- var div_21 = sibling(div_20, 2);
64611
- var input_15 = sibling(child(div_21), 2);
65213
+ reset(div_18);
65214
+ var div_19 = sibling(div_18, 2);
65215
+ var input_15 = sibling(child(div_19), 2);
64612
65216
  remove_input_defaults(input_15);
64613
- reset(div_21);
64614
65217
  reset(div_19);
64615
- var label_20 = sibling(div_19, 2);
65218
+ reset(div_17);
65219
+ var label_20 = sibling(div_17, 2);
64616
65220
  var span_16 = child(label_20);
64617
- var text_22 = child(span_16);
65221
+ var text_20 = child(span_16);
64618
65222
  reset(span_16);
64619
65223
  var input_16 = sibling(span_16, 2);
64620
65224
  remove_input_defaults(input_16);
64621
65225
  reset(label_20);
64622
65226
  var label_21 = sibling(label_20, 2);
64623
65227
  var span_17 = child(label_21);
64624
- var text_23 = child(span_17);
65228
+ var text_21 = child(span_17);
64625
65229
  reset(span_17);
64626
65230
  var input_17 = sibling(span_17, 2);
64627
65231
  remove_input_defaults(input_17);
64628
65232
  reset(label_21);
64629
65233
  var label_22 = sibling(label_21, 2);
64630
65234
  var span_18 = child(label_22);
64631
- var text_24 = child(span_18);
65235
+ var text_22 = child(span_18);
64632
65236
  reset(span_18);
64633
65237
  var input_18 = sibling(span_18, 2);
64634
65238
  remove_input_defaults(input_18);
@@ -64659,15 +65263,15 @@ function PropertiesPanel($$anchor, $$props) {
64659
65263
  var input_19 = sibling(child(label_24), 2);
64660
65264
  remove_input_defaults(input_19);
64661
65265
  reset(label_24);
64662
- var div_22 = sibling(label_24, 2);
64663
- var button_15 = child(div_22);
65266
+ var div_20 = sibling(label_24, 2);
65267
+ var button_15 = child(div_20);
64664
65268
  var button_16 = sibling(button_15, 2);
64665
- reset(div_22);
64666
- var div_23 = sibling(div_22, 2);
64667
- var button_17 = child(div_23);
65269
+ reset(div_20);
65270
+ var div_21 = sibling(div_20, 2);
65271
+ var button_17 = child(div_21);
64668
65272
  var button_18 = sibling(button_17, 2);
64669
- reset(div_23);
64670
- var button_19 = sibling(div_23, 2);
65273
+ reset(div_21);
65274
+ var button_19 = sibling(div_21, 2);
64671
65275
  reset(div_15);
64672
65276
  template_effect(($0, $1, $2, $3, $4, $5, $6, $7, $8, $9) => {
64673
65277
  var _$$get$material;
@@ -64677,11 +65281,11 @@ function PropertiesPanel($$anchor, $$props) {
64677
65281
  set_attribute(button_13, "title", get(selectedFurniture).locked ? "Unlock (Ctrl+L)" : "Lock (Ctrl+L)");
64678
65282
  set_text(text_17, get(selectedFurniture).locked ? "🔒 Locked" : "🔓");
64679
65283
  set_value(input_15, $2);
64680
- set_text(text_22, `Width (${$3 !== null && $3 !== void 0 ? $3 : ""})`);
65284
+ set_text(text_20, `Width (${$3 !== null && $3 !== void 0 ? $3 : ""})`);
64681
65285
  set_value(input_16, $4);
64682
- set_text(text_23, `Depth (${$5 !== null && $5 !== void 0 ? $5 : ""})`);
65286
+ set_text(text_21, `Depth (${$5 !== null && $5 !== void 0 ? $5 : ""})`);
64683
65287
  set_value(input_17, $6);
64684
- set_text(text_24, `Height (${$7 !== null && $7 !== void 0 ? $7 : ""})`);
65288
+ set_text(text_22, `Height (${$7 !== null && $7 !== void 0 ? $7 : ""})`);
64685
65289
  set_value(input_18, $8);
64686
65290
  if (select_3_value !== (select_3_value = (_$$get$material = get(selectedFurniture).material) !== null && _$$get$material !== void 0 ? _$$get$material : "Wood")) {
64687
65291
  var _select_3$__value, _$$get$material2, _$$get$material3;
@@ -64756,19 +65360,19 @@ function PropertiesPanel($$anchor, $$props) {
64756
65360
  delegated("click", button_19, resetFurnitureDefaults);
64757
65361
  append($$anchor, fragment_3);
64758
65362
  };
64759
- var consequent_12 = ($$anchor) => {
64760
- var fragment_6 = root_20$1();
64761
- var div_24 = sibling(first_child(fragment_6), 2);
64762
- var label_25 = child(div_24);
65363
+ var consequent_11 = ($$anchor) => {
65364
+ var fragment_5 = root_19$1();
65365
+ var div_22 = sibling(first_child(fragment_5), 2);
65366
+ var label_25 = child(div_22);
64763
65367
  var select_4 = sibling(child(label_25), 2);
64764
65368
  each(select_4, 21, () => roomTypes, index$1, ($$anchor, rt) => {
64765
- var option_21 = root_21$1();
64766
- var text_25 = child(option_21);
65369
+ var option_21 = root_20$1();
65370
+ var text_23 = child(option_21);
64767
65371
  reset(option_21);
64768
65372
  var option_21_value = {};
64769
65373
  template_effect(() => {
64770
65374
  var _$$get$icon, _$$get$label;
64771
- set_text(text_25, `${(_$$get$icon = get(rt).icon) !== null && _$$get$icon !== void 0 ? _$$get$icon : ""} ${(_$$get$label = get(rt).label) !== null && _$$get$label !== void 0 ? _$$get$label : ""}`);
65375
+ 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 : ""}`);
64772
65376
  if (option_21_value !== (option_21_value = get(rt).id)) {
64773
65377
  var _option_21$__value;
64774
65378
  option_21.value = (_option_21$__value = option_21.__value = get(rt).id) !== null && _option_21$__value !== void 0 ? _option_21$__value : "";
@@ -64798,15 +65402,15 @@ function PropertiesPanel($$anchor, $$props) {
64798
65402
  var select_5_value;
64799
65403
  init_select(select_5);
64800
65404
  reset(label_27);
64801
- var div_25 = sibling(label_27, 2);
64802
- var p = sibling(child(div_25), 2);
64803
- var text_26 = child(p, true);
64804
- reset(p);
64805
- reset(div_25);
64806
- var div_26 = sibling(div_25, 2);
64807
- var div_27 = sibling(child(div_26), 2);
64808
- each(div_27, 21, () => roomColorPresets, index$1, ($$anchor, preset) => {
64809
- var button_20 = root_22$1();
65405
+ var div_23 = sibling(label_27, 2);
65406
+ var p_2 = sibling(child(div_23), 2);
65407
+ var text_24 = child(p_2, true);
65408
+ reset(p_2);
65409
+ reset(div_23);
65410
+ var div_24 = sibling(div_23, 2);
65411
+ var div_25 = sibling(child(div_24), 2);
65412
+ each(div_25, 21, () => roomColorPresets, index$1, ($$anchor, preset) => {
65413
+ var button_20 = root_21$1();
64810
65414
  template_effect(() => {
64811
65415
  var _$$get$color5;
64812
65416
  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"}`);
@@ -64816,57 +65420,57 @@ function PropertiesPanel($$anchor, $$props) {
64816
65420
  delegated("click", button_20, () => onRoomColor(get(preset).color));
64817
65421
  append($$anchor, button_20);
64818
65422
  });
64819
- reset(div_27);
64820
- var div_28 = sibling(div_27, 2);
64821
- var input_21 = sibling(child(div_28), 2);
65423
+ reset(div_25);
65424
+ var div_26 = sibling(div_25, 2);
65425
+ var input_21 = sibling(child(div_26), 2);
64822
65426
  remove_input_defaults(input_21);
64823
- reset(div_28);
64824
65427
  reset(div_26);
64825
- var div_29 = sibling(div_26, 2);
64826
- var div_30 = sibling(child(div_29), 2);
64827
- each(div_30, 21, () => textureGroups, index$1, ($$anchor, group) => {
64828
- var div_31 = root_23$1();
64829
- var span_19 = child(div_31);
64830
- var text_27 = child(span_19, true);
65428
+ reset(div_24);
65429
+ var div_27 = sibling(div_24, 2);
65430
+ var div_28 = sibling(child(div_27), 2);
65431
+ each(div_28, 21, () => textureGroups, index$1, ($$anchor, group) => {
65432
+ var div_29 = root_22$1();
65433
+ var span_19 = child(div_29);
65434
+ var text_25 = child(span_19, true);
64831
65435
  reset(span_19);
64832
- var div_32 = sibling(span_19, 2);
64833
- each(div_32, 21, () => get(group).ids, index$1, ($$anchor, matId) => {
65436
+ var div_30 = sibling(span_19, 2);
65437
+ each(div_30, 21, () => get(group).ids, index$1, ($$anchor, matId) => {
64834
65438
  const mat = /* @__PURE__ */ user_derived(() => floorMaterials.find((m) => m.id === get(matId)));
64835
- var fragment_7 = comment();
64836
- var node_12 = first_child(fragment_7);
64837
- var consequent_11 = ($$anchor) => {
65439
+ var fragment_6 = comment();
65440
+ var node_11 = first_child(fragment_6);
65441
+ var consequent_10 = ($$anchor) => {
64838
65442
  const texPath = /* @__PURE__ */ user_derived(() => {
64839
65443
  var _floorTexPaths$$$get$;
64840
65444
  return (_floorTexPaths$$$get$ = floorTexPaths[get(mat).id]) !== null && _floorTexPaths$$$get$ !== void 0 ? _floorTexPaths$$$get$ : "";
64841
65445
  });
64842
- var button_21 = root_25$1();
64843
- var div_33 = child(button_21);
64844
- var div_34 = sibling(div_33, 2);
64845
- var text_28 = child(div_34, true);
64846
- reset(div_34);
65446
+ var button_21 = root_24$1();
65447
+ var div_31 = child(button_21);
65448
+ var div_32 = sibling(div_31, 2);
65449
+ var text_26 = child(div_32, true);
65450
+ reset(div_32);
64847
65451
  reset(button_21);
64848
65452
  template_effect(() => {
64849
65453
  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"}`);
64850
65454
  set_attribute(button_21, "title", get(mat).name);
64851
- set_style(div_33, get(texPath) ? `background-image: url(${get(texPath)}); background-size: cover; background-position: center;` : `background-color: ${get(mat).color}`);
64852
- set_text(text_28, get(mat).name);
65455
+ set_style(div_31, get(texPath) ? `background-image: url(${get(texPath)}); background-size: cover; background-position: center;` : `background-color: ${get(mat).color}`);
65456
+ set_text(text_26, get(mat).name);
64853
65457
  });
64854
65458
  delegated("click", button_21, () => onRoomFloor(get(mat).id));
64855
65459
  append($$anchor, button_21);
64856
65460
  };
64857
- if_block(node_12, ($$render) => {
64858
- if (get(mat)) $$render(consequent_11);
65461
+ if_block(node_11, ($$render) => {
65462
+ if (get(mat)) $$render(consequent_10);
64859
65463
  });
64860
- append($$anchor, fragment_7);
65464
+ append($$anchor, fragment_6);
64861
65465
  });
64862
- reset(div_32);
64863
- reset(div_31);
64864
- template_effect(() => set_text(text_27, get(group).label));
64865
- append($$anchor, div_31);
65466
+ reset(div_30);
65467
+ reset(div_29);
65468
+ template_effect(() => set_text(text_25, get(group).label));
65469
+ append($$anchor, div_29);
64866
65470
  });
64867
- reset(div_30);
64868
- reset(div_29);
64869
- reset(div_24);
65471
+ reset(div_28);
65472
+ reset(div_27);
65473
+ reset(div_22);
64870
65474
  template_effect(($0) => {
64871
65475
  var _$$get$roomType, _$$get$color6;
64872
65476
  if (select_4_value !== (select_4_value = get(selectedRoomType))) {
@@ -64878,7 +65482,7 @@ function PropertiesPanel($$anchor, $$props) {
64878
65482
  var _select_5$__value, _$$get$roomType2, _$$get$roomType3;
64879
65483
  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");
64880
65484
  }
64881
- set_text(text_26, $0);
65485
+ set_text(text_24, $0);
64882
65486
  set_value(input_21, (_$$get$color6 = get(selectedRoom).color) !== null && _$$get$color6 !== void 0 ? _$$get$color6 : "#ffffff");
64883
65487
  }, [() => formatArea(get(selectedRoom).area, get(settings).units)]);
64884
65488
  delegated("change", select_4, onRoomType);
@@ -64891,12 +65495,12 @@ function PropertiesPanel($$anchor, $$props) {
64891
65495
  }
64892
65496
  });
64893
65497
  delegated("input", input_21, (e) => onRoomColor(e.target.value));
64894
- append($$anchor, fragment_6);
65498
+ append($$anchor, fragment_5);
64895
65499
  };
64896
- var consequent_13 = ($$anchor) => {
64897
- var fragment_8 = root_26$1();
64898
- var div_35 = sibling(first_child(fragment_8), 2);
64899
- var label_28 = child(div_35);
65500
+ var consequent_12 = ($$anchor) => {
65501
+ var fragment_7 = root_25();
65502
+ var div_33 = sibling(first_child(fragment_7), 2);
65503
+ var label_28 = child(div_33);
64900
65504
  var select_6 = sibling(child(label_28), 2);
64901
65505
  var option_26 = child(select_6);
64902
65506
  option_26.value = option_26.__value = "straight";
@@ -64912,14 +65516,14 @@ function PropertiesPanel($$anchor, $$props) {
64912
65516
  reset(label_28);
64913
65517
  var label_29 = sibling(label_28, 2);
64914
65518
  var span_20 = child(label_29);
64915
- var text_29 = child(span_20);
65519
+ var text_27 = child(span_20);
64916
65520
  reset(span_20);
64917
65521
  var input_22 = sibling(span_20, 2);
64918
65522
  remove_input_defaults(input_22);
64919
65523
  reset(label_29);
64920
65524
  var label_30 = sibling(label_29, 2);
64921
65525
  var span_21 = child(label_30);
64922
- var text_30 = child(span_21);
65526
+ var text_28 = child(span_21);
64923
65527
  reset(span_21);
64924
65528
  var input_23 = sibling(span_21, 2);
64925
65529
  remove_input_defaults(input_23);
@@ -64929,24 +65533,24 @@ function PropertiesPanel($$anchor, $$props) {
64929
65533
  remove_input_defaults(input_24);
64930
65534
  reset(label_31);
64931
65535
  var label_32 = sibling(label_31, 2);
64932
- var div_36 = sibling(child(label_32), 2);
64933
- var button_22 = child(div_36);
65536
+ var div_34 = sibling(child(label_32), 2);
65537
+ var button_22 = child(div_34);
64934
65538
  var button_23 = sibling(button_22, 2);
64935
- reset(div_36);
65539
+ reset(div_34);
64936
65540
  reset(label_32);
64937
65541
  var label_33 = sibling(label_32, 2);
64938
65542
  var input_25 = sibling(child(label_33), 2);
64939
65543
  remove_input_defaults(input_25);
64940
65544
  reset(label_33);
64941
- reset(div_35);
65545
+ reset(div_33);
64942
65546
  template_effect(($0, $1, $2, $3) => {
64943
65547
  if (select_6_value !== (select_6_value = get(selectedStair).stairType || "straight")) {
64944
65548
  var _select_6$__value;
64945
65549
  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");
64946
65550
  }
64947
- set_text(text_29, `Width (${$0 !== null && $0 !== void 0 ? $0 : ""})`);
65551
+ set_text(text_27, `Width (${$0 !== null && $0 !== void 0 ? $0 : ""})`);
64948
65552
  set_value(input_22, $1);
64949
- set_text(text_30, `Depth (${$2 !== null && $2 !== void 0 ? $2 : ""})`);
65553
+ set_text(text_28, `Depth (${$2 !== null && $2 !== void 0 ? $2 : ""})`);
64950
65554
  set_value(input_23, $3);
64951
65555
  set_value(input_24, get(selectedStair).riserCount);
64952
65556
  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"}`);
@@ -64965,35 +65569,35 @@ function PropertiesPanel($$anchor, $$props) {
64965
65569
  delegated("click", button_22, () => updateStair(get(selectedStair).id, { direction: "up" }));
64966
65570
  delegated("click", button_23, () => updateStair(get(selectedStair).id, { direction: "down" }));
64967
65571
  delegated("input", input_25, (e) => updateStair(get(selectedStair).id, { rotation: Number(e.target.value) }));
64968
- append($$anchor, fragment_8);
65572
+ append($$anchor, fragment_7);
64969
65573
  };
64970
- var consequent_15 = ($$anchor) => {
64971
- var fragment_9 = root_27();
64972
- var div_37 = sibling(first_child(fragment_9), 2);
64973
- var label_34 = child(div_37);
64974
- var div_38 = sibling(child(label_34), 2);
64975
- var button_24 = child(div_38);
65574
+ var consequent_14 = ($$anchor) => {
65575
+ var fragment_8 = root_26();
65576
+ var div_35 = sibling(first_child(fragment_8), 2);
65577
+ var label_34 = child(div_35);
65578
+ var div_36 = sibling(child(label_34), 2);
65579
+ var button_24 = child(div_36);
64976
65580
  var button_25 = sibling(button_24, 2);
64977
- reset(div_38);
65581
+ reset(div_36);
64978
65582
  reset(label_34);
64979
65583
  var label_35 = sibling(label_34, 2);
64980
65584
  var span_22 = child(label_35);
64981
- var text_31 = child(span_22);
65585
+ var text_29 = child(span_22);
64982
65586
  reset(span_22);
64983
65587
  var input_26 = sibling(span_22, 2);
64984
65588
  remove_input_defaults(input_26);
64985
65589
  reset(label_35);
64986
65590
  var label_36 = sibling(label_35, 2);
64987
65591
  var span_23 = child(label_36);
64988
- var text_32 = child(span_23);
65592
+ var text_30 = child(span_23);
64989
65593
  reset(span_23);
64990
65594
  var input_27 = sibling(span_23, 2);
64991
65595
  remove_input_defaults(input_27);
64992
65596
  reset(label_36);
64993
- var div_39 = sibling(label_36, 2);
64994
- var div_40 = sibling(child(div_39), 2);
64995
- each(div_40, 21, () => columnColorPresets, index$1, ($$anchor, preset) => {
64996
- var button_26 = root_28();
65597
+ var div_37 = sibling(label_36, 2);
65598
+ var div_38 = sibling(child(div_37), 2);
65599
+ each(div_38, 21, () => columnColorPresets, index$1, ($$anchor, preset) => {
65600
+ var button_26 = root_27();
64997
65601
  template_effect(() => {
64998
65602
  var _$$get$color7;
64999
65603
  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"}`);
@@ -65003,15 +65607,15 @@ function PropertiesPanel($$anchor, $$props) {
65003
65607
  delegated("click", button_26, () => updateColumn(get(selectedColumn).id, { color: get(preset).color }));
65004
65608
  append($$anchor, button_26);
65005
65609
  });
65006
- reset(div_40);
65007
- var div_41 = sibling(div_40, 2);
65008
- var input_28 = sibling(child(div_41), 2);
65610
+ reset(div_38);
65611
+ var div_39 = sibling(div_38, 2);
65612
+ var input_28 = sibling(child(div_39), 2);
65009
65613
  remove_input_defaults(input_28);
65010
- reset(div_41);
65011
65614
  reset(div_39);
65012
- var node_13 = sibling(div_39, 2);
65013
- var consequent_14 = ($$anchor) => {
65014
- var label_37 = root_29();
65615
+ reset(div_37);
65616
+ var node_12 = sibling(div_37, 2);
65617
+ var consequent_13 = ($$anchor) => {
65618
+ var label_37 = root_28();
65015
65619
  var input_29 = sibling(child(label_37), 2);
65016
65620
  remove_input_defaults(input_29);
65017
65621
  reset(label_37);
@@ -65019,16 +65623,16 @@ function PropertiesPanel($$anchor, $$props) {
65019
65623
  delegated("input", input_29, (e) => updateColumn(get(selectedColumn).id, { rotation: Number(e.target.value) }));
65020
65624
  append($$anchor, label_37);
65021
65625
  };
65022
- if_block(node_13, ($$render) => {
65023
- if (get(selectedColumn).shape === "square") $$render(consequent_14);
65626
+ if_block(node_12, ($$render) => {
65627
+ if (get(selectedColumn).shape === "square") $$render(consequent_13);
65024
65628
  });
65025
- reset(div_37);
65629
+ reset(div_35);
65026
65630
  template_effect(($0, $1, $2, $3) => {
65027
65631
  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"}`);
65028
65632
  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"}`);
65029
- set_text(text_31, `${get(selectedColumn).shape === "round" ? "Diameter" : "Side Length"} (${$0 !== null && $0 !== void 0 ? $0 : ""})`);
65633
+ set_text(text_29, `${get(selectedColumn).shape === "round" ? "Diameter" : "Side Length"} (${$0 !== null && $0 !== void 0 ? $0 : ""})`);
65030
65634
  set_value(input_26, $1);
65031
- set_text(text_32, `Height (${$2 !== null && $2 !== void 0 ? $2 : ""})`);
65635
+ set_text(text_30, `Height (${$2 !== null && $2 !== void 0 ? $2 : ""})`);
65032
65636
  set_value(input_27, $3);
65033
65637
  set_value(input_28, get(selectedColumn).color);
65034
65638
  }, [
@@ -65042,11 +65646,11 @@ function PropertiesPanel($$anchor, $$props) {
65042
65646
  delegated("input", input_26, (e) => updateColumn(get(selectedColumn).id, { diameter: inputToCm(Number(e.target.value)) }));
65043
65647
  delegated("input", input_27, (e) => updateColumn(get(selectedColumn).id, { height: inputToCm(Number(e.target.value)) }));
65044
65648
  delegated("input", input_28, (e) => updateColumn(get(selectedColumn).id, { color: e.target.value }));
65045
- append($$anchor, fragment_9);
65649
+ append($$anchor, fragment_8);
65046
65650
  };
65047
- var consequent_17 = ($$anchor) => {
65048
- var div_42 = root_30();
65049
- var h3_1 = child(div_42);
65651
+ var consequent_16 = ($$anchor) => {
65652
+ var div_40 = root_29();
65653
+ var h3_1 = child(div_40);
65050
65654
  var span_24 = child(h3_1);
65051
65655
  next();
65052
65656
  reset(h3_1);
@@ -65054,62 +65658,62 @@ function PropertiesPanel($$anchor, $$props) {
65054
65658
  var input_30 = sibling(child(label_38), 2);
65055
65659
  remove_input_defaults(input_30);
65056
65660
  reset(label_38);
65057
- var node_14 = sibling(label_38, 2);
65058
- var consequent_16 = ($$anchor) => {
65059
- var div_43 = root_31();
65060
- var span_25 = sibling(child(div_43));
65061
- var text_33 = child(span_25, true);
65661
+ var node_13 = sibling(label_38, 2);
65662
+ var consequent_15 = ($$anchor) => {
65663
+ var div_41 = root_30();
65664
+ var span_25 = sibling(child(div_41));
65665
+ var text_31 = child(span_25, true);
65062
65666
  reset(span_25);
65063
- reset(div_43);
65064
- template_effect(() => set_text(text_33, get(selectedZone).cameraSerial));
65065
- append($$anchor, div_43);
65667
+ reset(div_41);
65668
+ template_effect(() => set_text(text_31, get(selectedZone).cameraSerial));
65669
+ append($$anchor, div_41);
65066
65670
  };
65067
- if_block(node_14, ($$render) => {
65068
- if (get(selectedZone).cameraSerial) $$render(consequent_16);
65671
+ if_block(node_13, ($$render) => {
65672
+ if (get(selectedZone).cameraSerial) $$render(consequent_15);
65069
65673
  });
65070
- var div_44 = sibling(node_14, 2);
65071
- var span_26 = sibling(child(div_44));
65072
- var text_34 = child(span_26, true);
65674
+ var div_42 = sibling(node_13, 2);
65675
+ var span_26 = sibling(child(div_42));
65676
+ var text_32 = child(span_26, true);
65073
65677
  reset(span_26);
65074
- reset(div_44);
65075
- var label_39 = sibling(div_44, 2);
65076
- var div_45 = sibling(child(label_39), 2);
65077
- var node_15 = child(div_45);
65078
- each(node_15, 17, () => ZONE_COLOR_PALETTE, index$1, ($$anchor, c) => {
65079
- var button_27 = root_32();
65678
+ reset(div_42);
65679
+ var label_39 = sibling(div_42, 2);
65680
+ var div_43 = sibling(child(label_39), 2);
65681
+ var node_14 = child(div_43);
65682
+ each(node_14, 17, () => ZONE_COLOR_PALETTE, index$1, ($$anchor, c) => {
65683
+ var button_27 = root_31();
65080
65684
  template_effect(() => {
65081
- var _$$get19;
65685
+ var _$$get20;
65082
65686
  set_class(button_27, 1, `w-6 h-6 rounded border-2 ${get(selectedZone).color === get(c) ? "border-slate-800" : "border-transparent"}`);
65083
- set_style(button_27, `background:${(_$$get19 = get(c)) !== null && _$$get19 !== void 0 ? _$$get19 : ""}`);
65687
+ set_style(button_27, `background:${(_$$get20 = get(c)) !== null && _$$get20 !== void 0 ? _$$get20 : ""}`);
65084
65688
  });
65085
65689
  delegated("click", button_27, () => updateZone(get(selectedZone).id, { color: get(c) }));
65086
65690
  append($$anchor, button_27);
65087
65691
  });
65088
- var input_31 = sibling(node_15, 2);
65692
+ var input_31 = sibling(node_14, 2);
65089
65693
  remove_input_defaults(input_31);
65090
- reset(div_45);
65694
+ reset(div_43);
65091
65695
  reset(label_39);
65092
65696
  var label_40 = sibling(label_39, 2);
65093
65697
  var input_32 = sibling(child(label_40), 2);
65094
65698
  remove_input_defaults(input_32);
65095
65699
  reset(label_40);
65096
- reset(div_42);
65700
+ reset(div_40);
65097
65701
  template_effect(() => {
65098
65702
  var _$$get$color8, _$$get$color9, _$$get$fillOpacity;
65099
65703
  set_style(span_24, `background:${(_$$get$color8 = get(selectedZone).color) !== null && _$$get$color8 !== void 0 ? _$$get$color8 : ""}22;color:${(_$$get$color9 = get(selectedZone).color) !== null && _$$get$color9 !== void 0 ? _$$get$color9 : ""}`);
65100
65704
  set_value(input_30, get(selectedZone).name);
65101
- set_text(text_34, get(selectedZone).shape);
65705
+ set_text(text_32, get(selectedZone).shape);
65102
65706
  set_value(input_31, get(selectedZone).color);
65103
65707
  set_value(input_32, (_$$get$fillOpacity = get(selectedZone).fillOpacity) !== null && _$$get$fillOpacity !== void 0 ? _$$get$fillOpacity : .1);
65104
65708
  });
65105
65709
  delegated("input", input_30, (e) => updateZone(get(selectedZone).id, { name: e.target.value }));
65106
65710
  delegated("input", input_31, (e) => updateZone(get(selectedZone).id, { color: e.target.value }));
65107
65711
  delegated("input", input_32, (e) => updateZone(get(selectedZone).id, { fillOpacity: Number(e.target.value) }));
65108
- append($$anchor, div_42);
65712
+ append($$anchor, div_40);
65109
65713
  };
65110
- var consequent_18 = ($$anchor) => {
65111
- var div_46 = root_33();
65112
- var label_41 = sibling(child(div_46), 2);
65714
+ var consequent_17 = ($$anchor) => {
65715
+ var div_44 = root_32();
65716
+ var label_41 = sibling(child(div_44), 2);
65113
65717
  var input_33 = sibling(child(label_41), 2);
65114
65718
  remove_input_defaults(input_33);
65115
65719
  reset(label_41);
@@ -65118,13 +65722,13 @@ function PropertiesPanel($$anchor, $$props) {
65118
65722
  remove_input_defaults(input_34);
65119
65723
  reset(label_42);
65120
65724
  var label_43 = sibling(label_42, 2);
65121
- var div_47 = sibling(child(label_43), 2);
65122
- var input_35 = child(div_47);
65725
+ var div_45 = sibling(child(label_43), 2);
65726
+ var input_35 = child(div_45);
65123
65727
  remove_input_defaults(input_35);
65124
65728
  var span_27 = sibling(input_35, 2);
65125
- var text_35 = child(span_27, true);
65729
+ var text_33 = child(span_27, true);
65126
65730
  reset(span_27);
65127
- reset(div_47);
65731
+ reset(div_45);
65128
65732
  reset(label_43);
65129
65733
  var label_44 = sibling(label_43, 2);
65130
65734
  var input_36 = sibling(child(label_44), 2);
@@ -65138,12 +65742,12 @@ function PropertiesPanel($$anchor, $$props) {
65138
65742
  var input_38 = sibling(child(label_46), 2);
65139
65743
  remove_input_defaults(input_38);
65140
65744
  reset(label_46);
65141
- reset(div_46);
65745
+ reset(div_44);
65142
65746
  template_effect(($0, $1) => {
65143
65747
  set_value(input_33, get(selectedTextAnnotation).text);
65144
65748
  set_value(input_34, get(selectedTextAnnotation).fontSize);
65145
65749
  set_value(input_35, get(selectedTextAnnotation).color);
65146
- set_text(text_35, get(selectedTextAnnotation).color);
65750
+ set_text(text_33, get(selectedTextAnnotation).color);
65147
65751
  set_value(input_36, get(selectedTextAnnotation).rotation);
65148
65752
  set_value(input_37, $0);
65149
65753
  set_value(input_38, $1);
@@ -65154,24 +65758,24 @@ function PropertiesPanel($$anchor, $$props) {
65154
65758
  delegated("input", input_36, (e) => updateTextAnnotation(get(selectedTextAnnotation).id, { rotation: Number(e.target.value) }));
65155
65759
  delegated("input", input_37, (e) => updateTextAnnotation(get(selectedTextAnnotation).id, { x: Number(e.target.value) }));
65156
65760
  delegated("input", input_38, (e) => updateTextAnnotation(get(selectedTextAnnotation).id, { y: Number(e.target.value) }));
65157
- append($$anchor, div_46);
65761
+ append($$anchor, div_44);
65158
65762
  };
65159
65763
  if_block(node, ($$render) => {
65160
65764
  if (get(selectedWall)) $$render(consequent_1);
65161
65765
  else if (get(selectedDoor)) $$render(consequent_2, 1);
65162
65766
  else if (get(selectedWindow)) $$render(consequent_3, 2);
65163
- else if (get(selectedFurniture)) $$render(consequent_10, 3);
65164
- else if (get(selectedRoom)) $$render(consequent_12, 4);
65165
- else if (get(selectedStair)) $$render(consequent_13, 5);
65166
- else if (get(selectedColumn)) $$render(consequent_15, 6);
65167
- else if (get(selectedZone)) $$render(consequent_17, 7);
65168
- else if (get(selectedTextAnnotation)) $$render(consequent_18, 8);
65767
+ else if (get(selectedFurniture)) $$render(consequent_9, 3);
65768
+ else if (get(selectedRoom)) $$render(consequent_11, 4);
65769
+ else if (get(selectedStair)) $$render(consequent_12, 5);
65770
+ else if (get(selectedColumn)) $$render(consequent_14, 6);
65771
+ else if (get(selectedZone)) $$render(consequent_16, 7);
65772
+ else if (get(selectedTextAnnotation)) $$render(consequent_17, 8);
65169
65773
  });
65170
- var node_16 = sibling(node, 2);
65171
- var consequent_19 = ($$anchor) => {
65172
- var div_48 = root_34();
65173
- var div_49 = sibling(child(div_48), 2);
65174
- var label_47 = child(div_49);
65774
+ var node_15 = sibling(node, 2);
65775
+ var consequent_18 = ($$anchor) => {
65776
+ var div_46 = root_33();
65777
+ var div_47 = sibling(child(div_46), 2);
65778
+ var label_47 = child(div_47);
65175
65779
  var input_39 = sibling(child(label_47), 2);
65176
65780
  remove_input_defaults(input_39);
65177
65781
  reset(label_47);
@@ -65183,21 +65787,21 @@ function PropertiesPanel($$anchor, $$props) {
65183
65787
  var input_41 = sibling(child(label_49), 2);
65184
65788
  remove_input_defaults(input_41);
65185
65789
  reset(label_49);
65186
- var div_50 = sibling(label_49, 2);
65187
- var button_28 = child(div_50);
65188
- var text_36 = child(button_28, true);
65790
+ var div_48 = sibling(label_49, 2);
65791
+ var button_28 = child(div_48);
65792
+ var text_34 = child(button_28, true);
65189
65793
  reset(button_28);
65190
65794
  var button_29 = sibling(button_28, 2);
65191
- reset(div_50);
65192
- var button_30 = sibling(div_50, 2);
65193
- reset(div_49);
65194
65795
  reset(div_48);
65796
+ var button_30 = sibling(div_48, 2);
65797
+ reset(div_47);
65798
+ reset(div_46);
65195
65799
  template_effect(() => {
65196
65800
  set_value(input_39, get(floor).backgroundImage.opacity);
65197
65801
  set_value(input_40, get(floor).backgroundImage.scale);
65198
65802
  set_value(input_41, get(floor).backgroundImage.rotation);
65199
65803
  set_class(button_28, 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"}`);
65200
- set_text(text_36, get(floor).backgroundImage.locked ? "🔒 Locked" : "🔓 Unlocked");
65804
+ set_text(text_34, get(floor).backgroundImage.locked ? "🔒 Locked" : "🔓 Unlocked");
65201
65805
  });
65202
65806
  delegated("input", input_39, (e) => updateBackgroundImage({ opacity: Number(e.target.value) }));
65203
65807
  delegated("input", input_40, (e) => updateBackgroundImage({ scale: Number(e.target.value) }));
@@ -65208,14 +65812,14 @@ function PropertiesPanel($$anchor, $$props) {
65208
65812
  calibrationMode.set(true);
65209
65813
  });
65210
65814
  delegated("click", button_30, () => setBackgroundImage(void 0));
65211
- append($$anchor, div_48);
65815
+ append($$anchor, div_46);
65212
65816
  };
65213
- if_block(node_16, ($$render) => {
65214
- var _$$get20;
65215
- if (get(hasBgImage) && ((_$$get20 = get(floor)) === null || _$$get20 === void 0 ? void 0 : _$$get20.backgroundImage)) $$render(consequent_19);
65817
+ if_block(node_15, ($$render) => {
65818
+ var _$$get21;
65819
+ if (get(hasBgImage) && ((_$$get21 = get(floor)) === null || _$$get21 === void 0 ? void 0 : _$$get21.backgroundImage)) $$render(consequent_18);
65216
65820
  });
65217
65821
  reset(div);
65218
- 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 absolute right-0 z-40 shadow-lg`, null, classes, { hidden: !get(hasSelection) }));
65822
+ template_effect(() => classes = set_class(div, 1, "w-[420px] shrink-0 bg-white border-l border-gray-200 flex flex-col overflow-y-auto p-3 absolute right-0 z-40 shadow-lg", null, classes, { hidden: !get(hasSelection) }));
65219
65823
  delegated("keydown", div, stopShortcutBubble);
65220
65824
  event("keydown", div, stopShortcutBubble, true);
65221
65825
  append($$anchor, div);
@@ -65231,11 +65835,11 @@ delegate([
65231
65835
  //#endregion
65232
65836
  //#region src/lib/components/sidebar/LayersPanel.svelte
65233
65837
  init_client();
65234
- var root_3$6 = /* @__PURE__ */ from_html(`<button><span class="text-[10px]"> </span> <span class="truncate flex-1"> </span></button>`);
65235
- var root_4$5 = /* @__PURE__ */ from_html(`<div class="pl-7 pr-2 py-1 text-gray-300 italic">Empty</div>`);
65236
- var root_2$7 = /* @__PURE__ */ from_html(`<!> <!>`, 1);
65237
- var root_1$7 = /* @__PURE__ */ from_html(`<div class="border-b border-gray-50 relative"><button class="w-full flex items-center gap-1.5 px-2 py-1.5 hover:bg-gray-50 text-left"><span class="text-[10px] text-gray-400 w-3"> </span> <span> </span> <span class="font-medium text-gray-700 flex-1"> </span> <span class="text-gray-400 mr-1"> </span></button> <span role="button" tabindex="0">👁</span> <!></div>`);
65238
- var root_5$3 = /* @__PURE__ */ from_html(`<div class="p-4 text-gray-400 text-center">No elements</div>`);
65838
+ var root_3$5 = /* @__PURE__ */ from_html(`<button><span class="text-[10px]"> </span> <span class="truncate flex-1"> </span></button>`);
65839
+ var root_4$4 = /* @__PURE__ */ from_html(`<div class="pl-7 pr-2 py-1 text-gray-300 italic">Empty</div>`);
65840
+ var root_2$6 = /* @__PURE__ */ from_html(`<!> <!>`, 1);
65841
+ var root_1$5 = /* @__PURE__ */ from_html(`<div class="border-b border-gray-50 relative"><button class="w-full flex items-center gap-1.5 px-2 py-1.5 hover:bg-gray-50 text-left"><span class="text-[10px] text-gray-400 w-3"> </span> <span> </span> <span class="font-medium text-gray-700 flex-1"> </span> <span class="text-gray-400 mr-1"> </span></button> <span role="button" tabindex="0">👁</span> <!></div>`);
65842
+ var root_5$2 = /* @__PURE__ */ from_html(`<div class="p-4 text-gray-400 text-center">No elements</div>`);
65239
65843
  var root$2 = /* @__PURE__ */ from_html(`<div class="w-56 bg-white border-l border-gray-200 flex flex-col overflow-hidden text-xs select-none"><div class="px-3 py-2 border-b border-gray-100 font-semibold text-gray-700 text-sm flex items-center gap-1.5">🗂 Layers</div> <div class="flex-1 overflow-y-auto"><!> <!></div></div>`);
65240
65844
  function LayersPanel($$anchor, $$props) {
65241
65845
  push($$props, true);
@@ -65399,7 +66003,7 @@ function LayersPanel($$anchor, $$props) {
65399
66003
  var div_1 = sibling(child(div), 2);
65400
66004
  var node = child(div_1);
65401
66005
  each(node, 17, () => get(categories), index$1, ($$anchor, cat) => {
65402
- var div_2 = root_1$7();
66006
+ var div_2 = root_1$5();
65403
66007
  var button = child(div_2);
65404
66008
  var span = child(button);
65405
66009
  var text = child(span, true);
@@ -65418,10 +66022,10 @@ function LayersPanel($$anchor, $$props) {
65418
66022
  let classes;
65419
66023
  var node_1 = sibling(span_4, 2);
65420
66024
  var consequent_1 = ($$anchor) => {
65421
- var fragment = root_2$7();
66025
+ var fragment = root_2$6();
65422
66026
  var node_2 = first_child(fragment);
65423
66027
  each(node_2, 17, () => get(cat).items, index$1, ($$anchor, item) => {
65424
- var button_1 = root_3$6();
66028
+ var button_1 = root_3$5();
65425
66029
  let classes_1;
65426
66030
  var span_5 = child(button_1);
65427
66031
  var text_4 = child(span_5, true);
@@ -65444,7 +66048,7 @@ function LayersPanel($$anchor, $$props) {
65444
66048
  });
65445
66049
  var node_3 = sibling(node_2, 2);
65446
66050
  var consequent = ($$anchor) => {
65447
- append($$anchor, root_4$5());
66051
+ append($$anchor, root_4$4());
65448
66052
  };
65449
66053
  if_block(node_3, ($$render) => {
65450
66054
  if (get(cat).items.length === 0) $$render(consequent);
@@ -65478,7 +66082,7 @@ function LayersPanel($$anchor, $$props) {
65478
66082
  });
65479
66083
  var node_4 = sibling(node, 2);
65480
66084
  var consequent_2 = ($$anchor) => {
65481
- append($$anchor, root_5$3());
66085
+ append($$anchor, root_5$2());
65482
66086
  };
65483
66087
  if_block(node_4, ($$render) => {
65484
66088
  if (get(categories).length === 0) $$render(consequent_2);
@@ -65490,367 +66094,6 @@ function LayersPanel($$anchor, $$props) {
65490
66094
  }
65491
66095
  delegate(["click", "keydown"]);
65492
66096
  //#endregion
65493
- //#region src/lib/components/sidebar/CameraFovEditor.svelte
65494
- init_client();
65495
- init_index_client();
65496
- var root_3$5 = /* @__PURE__ */ from_html(`<button type="button" class="text-[10px] px-1.5 py-0.5 rounded border border-gray-300 hover:bg-white">Done</button> <button type="button" class="text-[10px] px-1.5 py-0.5 rounded border border-gray-300 hover:bg-white">Cancel</button>`, 1);
65497
- var root_5$2 = /* @__PURE__ */ from_html(`<button type="button" class="text-[10px] px-1.5 py-0.5 rounded border border-red-200 text-red-600 hover:bg-red-50">Clear</button>`);
65498
- var root_4$4 = /* @__PURE__ */ from_html(`<button type="button" class="text-[10px] px-1.5 py-0.5 rounded border border-blue-300 text-blue-700 bg-blue-50 hover:bg-blue-100"> </button> <!>`, 1);
65499
- var root_2$6 = /* @__PURE__ */ from_html(`<div class="flex items-center justify-between gap-2"><span class="text-xs font-medium text-gray-600">Camera FOV (image)</span> <div class="flex gap-1"><!></div></div>`);
65500
- var root_8$1 = /* @__PURE__ */ from_html(` <!>`, 1);
65501
- var root_11$1 = /* @__PURE__ */ from_html(`<p class="text-[10px] text-amber-700 bg-amber-50 border border-amber-200 rounded px-1.5 py-1"> </p>`);
65502
- var root_6$2 = /* @__PURE__ */ from_html(`<p class="text-[10px] text-gray-500 leading-snug"><!></p> <!>`, 1);
65503
- var root_1$6 = /* @__PURE__ */ from_html(`<div class="border border-gray-200 rounded-lg p-2 bg-gray-50 space-y-2"><!> <canvas></canvas> <!></div>`);
65504
- var root_12$1 = /* @__PURE__ */ from_html(`<p class="text-xs text-gray-400">No thumbnail URL from host.</p>`);
65505
- function CameraFovEditor($$anchor, $$props) {
65506
- push($$props, true);
65507
- let coordinates = prop($$props, "coordinates", 3, ""), mapCoordinates = prop($$props, "mapCoordinates", 3, ""), readOnly = prop($$props, "readOnly", 3, false);
65508
- let canvasEl = /* @__PURE__ */ state(void 0);
65509
- let imgEl = /* @__PURE__ */ state(null);
65510
- let imgSize = /* @__PURE__ */ state(null);
65511
- let draft = /* @__PURE__ */ state(proxy([]));
65512
- let cursor = /* @__PURE__ */ state(null);
65513
- let draggingIdx = /* @__PURE__ */ state(null);
65514
- let editing = /* @__PURE__ */ state(false);
65515
- const displayW = 288;
65516
- let matchOk = /* @__PURE__ */ user_derived(() => fovPointCountsMatch(coordinates(), mapCoordinates()));
65517
- let mapN = /* @__PURE__ */ user_derived(() => countCoordinatePoints(mapCoordinates()));
65518
- let imgN = /* @__PURE__ */ user_derived(() => countCoordinatePoints(coordinates()));
65519
- function samePoints(a, b) {
65520
- if (a.length !== b.length) return false;
65521
- for (let i = 0; i < a.length; i++) if (a[i].x !== b[i].x || a[i].y !== b[i].y) return false;
65522
- return true;
65523
- }
65524
- user_effect(() => {
65525
- var _$$props$thumbnailUrl;
65526
- const url = (_$$props$thumbnailUrl = $$props.thumbnailUrl) === null || _$$props$thumbnailUrl === void 0 ? void 0 : _$$props$thumbnailUrl.trim();
65527
- if (!url) {
65528
- set(imgEl, null);
65529
- set(imgSize, null);
65530
- return;
65531
- }
65532
- let cancelled = false;
65533
- const img = new Image();
65534
- img.onload = () => {
65535
- if (cancelled) return;
65536
- set(imgEl, img, true);
65537
- set(imgSize, {
65538
- w: img.naturalWidth,
65539
- h: img.naturalHeight
65540
- }, true);
65541
- };
65542
- img.onerror = () => {
65543
- if (cancelled) return;
65544
- set(imgEl, null);
65545
- set(imgSize, null);
65546
- };
65547
- img.src = url;
65548
- return () => {
65549
- cancelled = true;
65550
- };
65551
- });
65552
- user_effect(() => {
65553
- const coords = coordinates();
65554
- const size = get(imgSize);
65555
- const el = get(canvasEl);
65556
- const isEditing = get(editing);
65557
- if (!size || !el) return;
65558
- untrack(() => {
65559
- if (!isEditing) {
65560
- const next = coordinatesToImagePoints(coords, size);
65561
- if (!samePoints(get(draft), next)) set(draft, next, true);
65562
- }
65563
- redraw();
65564
- });
65565
- });
65566
- function scale() {
65567
- if (!get(imgSize)) return 1;
65568
- return displayW / get(imgSize).w;
65569
- }
65570
- function canvasH() {
65571
- if (!get(imgSize)) return 135;
65572
- return Math.round(get(imgSize).h * scale());
65573
- }
65574
- function toImage(e) {
65575
- if (!get(canvasEl) || !get(imgSize)) return null;
65576
- const rect = get(canvasEl).getBoundingClientRect();
65577
- const s = scale();
65578
- return {
65579
- x: (e.clientX - rect.left) / s,
65580
- y: (e.clientY - rect.top) / s
65581
- };
65582
- }
65583
- function redraw() {
65584
- if (!get(canvasEl) || !get(imgEl) || !get(imgSize)) return;
65585
- const s = scale();
65586
- const w = displayW;
65587
- const h = canvasH();
65588
- if (get(canvasEl).width !== w || get(canvasEl).height !== h) {
65589
- get(canvasEl).width = w;
65590
- get(canvasEl).height = h;
65591
- }
65592
- const ctx = get(canvasEl).getContext("2d");
65593
- if (!ctx) return;
65594
- ctx.clearRect(0, 0, w, h);
65595
- ctx.drawImage(get(imgEl), 0, 0, w, h);
65596
- const pts = [...get(draft)];
65597
- if (get(editing) && get(cursor)) pts.push(get(cursor));
65598
- if (pts.length) {
65599
- ctx.save();
65600
- ctx.strokeStyle = "#22c55e";
65601
- ctx.fillStyle = "rgba(34,197,94,0.25)";
65602
- ctx.lineWidth = 2;
65603
- ctx.beginPath();
65604
- ctx.moveTo(pts[0].x * s, pts[0].y * s);
65605
- for (let i = 1; i < pts.length; i++) ctx.lineTo(pts[i].x * s, pts[i].y * s);
65606
- if (!get(editing) && get(draft).length >= 3) {
65607
- ctx.closePath();
65608
- ctx.fill();
65609
- }
65610
- ctx.stroke();
65611
- for (const p of get(draft)) {
65612
- ctx.beginPath();
65613
- ctx.fillStyle = "#fff";
65614
- ctx.strokeStyle = "#22c55e";
65615
- ctx.arc(p.x * s, p.y * s, 4, 0, Math.PI * 2);
65616
- ctx.fill();
65617
- ctx.stroke();
65618
- }
65619
- ctx.restore();
65620
- }
65621
- }
65622
- function hitVertex(p) {
65623
- if (!get(imgSize)) return -1;
65624
- const tol = 8 / scale();
65625
- for (let i = 0; i < get(draft).length; i++) if (Math.hypot(get(draft)[i].x - p.x, get(draft)[i].y - p.y) <= tol) return i;
65626
- return -1;
65627
- }
65628
- function onDown(e) {
65629
- const p = toImage(e);
65630
- if (!p || !get(imgSize)) return;
65631
- if (!get(editing)) {
65632
- const vi = hitVertex(p);
65633
- if (vi >= 0) {
65634
- set(draggingIdx, vi, true);
65635
- return;
65636
- }
65637
- return;
65638
- }
65639
- if (get(draft).length >= 3 && Math.hypot(p.x - get(draft)[0].x, p.y - get(draft)[0].y) < 10 / scale()) {
65640
- commitDraft();
65641
- return;
65642
- }
65643
- set(draft, [...get(draft), p], true);
65644
- redraw();
65645
- }
65646
- function onMove(e) {
65647
- const p = toImage(e);
65648
- if (!p) return;
65649
- if (get(draggingIdx) != null) {
65650
- const next = get(draft).map((pt) => ({ ...pt }));
65651
- next[get(draggingIdx)] = p;
65652
- set(draft, next, true);
65653
- redraw();
65654
- return;
65655
- }
65656
- if (get(editing)) {
65657
- set(cursor, p, true);
65658
- redraw();
65659
- }
65660
- }
65661
- function onUp() {
65662
- if (get(draggingIdx) != null) {
65663
- set(draggingIdx, null);
65664
- commitDraft();
65665
- }
65666
- }
65667
- function commitDraft() {
65668
- if (!get(imgSize) || get(draft).length < 3) return;
65669
- const str = imagePointsToCoordinates(get(draft), get(imgSize));
65670
- if (!str) return;
65671
- setCameraImageCoordinates($$props.serial, str);
65672
- set(editing, false);
65673
- set(cursor, null);
65674
- redraw();
65675
- }
65676
- function startDraw() {
65677
- set(draft, [], true);
65678
- set(cursor, null);
65679
- set(editing, true);
65680
- redraw();
65681
- }
65682
- function clearFov() {
65683
- set(draft, [], true);
65684
- set(editing, false);
65685
- set(cursor, null);
65686
- setCameraImageCoordinates($$props.serial, null);
65687
- redraw();
65688
- }
65689
- function finishEdit() {
65690
- if (get(draft).length >= 3) commitDraft();
65691
- else {
65692
- set(editing, false);
65693
- set(cursor, null);
65694
- set(draft, coordinatesToImagePoints(coordinates(), get(imgSize)), true);
65695
- redraw();
65696
- }
65697
- }
65698
- var fragment = comment();
65699
- var node = first_child(fragment);
65700
- var consequent_8 = ($$anchor) => {
65701
- var div = root_1$6();
65702
- var node_1 = child(div);
65703
- var consequent_2 = ($$anchor) => {
65704
- var div_1 = root_2$6();
65705
- var div_2 = sibling(child(div_1), 2);
65706
- var node_2 = child(div_2);
65707
- var consequent = ($$anchor) => {
65708
- var fragment_1 = root_3$5();
65709
- var button = first_child(fragment_1);
65710
- var button_1 = sibling(button, 2);
65711
- delegated("click", button, finishEdit);
65712
- delegated("click", button_1, () => {
65713
- set(editing, false);
65714
- set(draft, coordinatesToImagePoints(coordinates(), get(imgSize)), true);
65715
- set(cursor, null);
65716
- redraw();
65717
- });
65718
- append($$anchor, fragment_1);
65719
- };
65720
- var alternate = ($$anchor) => {
65721
- var fragment_2 = root_4$4();
65722
- var button_2 = first_child(fragment_2);
65723
- var text = child(button_2, true);
65724
- reset(button_2);
65725
- var node_3 = sibling(button_2, 2);
65726
- var consequent_1 = ($$anchor) => {
65727
- var button_3 = root_5$2();
65728
- delegated("click", button_3, clearFov);
65729
- append($$anchor, button_3);
65730
- };
65731
- if_block(node_3, ($$render) => {
65732
- if (get(imgN) > 0) $$render(consequent_1);
65733
- });
65734
- template_effect(() => set_text(text, get(imgN) >= 3 ? "Redraw" : "Draw"));
65735
- delegated("click", button_2, startDraw);
65736
- append($$anchor, fragment_2);
65737
- };
65738
- if_block(node_2, ($$render) => {
65739
- if (get(editing)) $$render(consequent);
65740
- else $$render(alternate, -1);
65741
- });
65742
- reset(div_2);
65743
- reset(div_1);
65744
- append($$anchor, div_1);
65745
- };
65746
- if_block(node_1, ($$render) => {
65747
- if (!readOnly()) $$render(consequent_2);
65748
- });
65749
- var canvas = sibling(node_1, 2);
65750
- set_style(canvas, "max-width: 288px; height: auto;");
65751
- bind_this(canvas, ($$value) => set(canvasEl, $$value), () => get(canvasEl));
65752
- var node_4 = sibling(canvas, 2);
65753
- var consequent_7 = ($$anchor) => {
65754
- var fragment_3 = root_6$2();
65755
- var p_1 = first_child(fragment_3);
65756
- var node_5 = child(p_1);
65757
- var consequent_3 = ($$anchor) => {
65758
- var text_1 = text$1();
65759
- template_effect(() => set_text(text_1, `Click vertices · click first point to close (≥3)`));
65760
- append($$anchor, text_1);
65761
- };
65762
- var consequent_5 = ($$anchor) => {
65763
- var fragment_5 = root_8$1();
65764
- var text_2 = first_child(fragment_5);
65765
- var node_6 = sibling(text_2);
65766
- var consequent_4 = ($$anchor) => {
65767
- var text_3 = text$1();
65768
- template_effect(() => {
65769
- var _$$get;
65770
- return set_text(text_3, `· floor ${(_$$get = get(mapN)) !== null && _$$get !== void 0 ? _$$get : ""} pts`);
65771
- });
65772
- append($$anchor, text_3);
65773
- };
65774
- if_block(node_6, ($$render) => {
65775
- if (get(mapN) > 0) $$render(consequent_4);
65776
- });
65777
- template_effect(() => {
65778
- var _$$get2;
65779
- return set_text(text_2, `${(_$$get2 = get(imgN)) !== null && _$$get2 !== void 0 ? _$$get2 : ""} points on image `);
65780
- });
65781
- append($$anchor, fragment_5);
65782
- };
65783
- var alternate_1 = ($$anchor) => {
65784
- var text_4 = text$1();
65785
- template_effect(() => set_text(text_4, `Draw FOV polygon on camera thumbnail (≥3 pts)`));
65786
- append($$anchor, text_4);
65787
- };
65788
- if_block(node_5, ($$render) => {
65789
- if (get(editing)) $$render(consequent_3);
65790
- else if (get(imgN) >= 3) $$render(consequent_5, 1);
65791
- else $$render(alternate_1, -1);
65792
- });
65793
- reset(p_1);
65794
- var node_7 = sibling(p_1, 2);
65795
- var consequent_6 = ($$anchor) => {
65796
- var p_2 = root_11$1();
65797
- var text_5 = child(p_2);
65798
- reset(p_2);
65799
- template_effect(() => {
65800
- var _$$get3, _$$get4;
65801
- return set_text(text_5, `Point count mismatch: image ${(_$$get3 = get(imgN)) !== null && _$$get3 !== void 0 ? _$$get3 : ""} ≠ floor ${(_$$get4 = get(mapN)) !== null && _$$get4 !== void 0 ? _$$get4 : ""}. Heatmap transform needs the same N and order.`);
65802
- });
65803
- append($$anchor, p_2);
65804
- };
65805
- if_block(node_7, ($$render) => {
65806
- if (!get(matchOk)) $$render(consequent_6);
65807
- });
65808
- append($$anchor, fragment_3);
65809
- };
65810
- if_block(node_4, ($$render) => {
65811
- if (!readOnly()) $$render(consequent_7);
65812
- });
65813
- reset(div);
65814
- template_effect(() => set_class(canvas, 1, `w-full rounded border border-gray-200 bg-black/5 touch-none ${readOnly() ? "cursor-default" : "cursor-crosshair"}`));
65815
- delegated("mousedown", canvas, function(...$$args) {
65816
- var _ref;
65817
- (_ref = readOnly() ? void 0 : onDown) === null || _ref === void 0 || _ref.apply(this, $$args);
65818
- });
65819
- delegated("mousemove", canvas, function(...$$args) {
65820
- var _ref2;
65821
- (_ref2 = readOnly() ? void 0 : onMove) === null || _ref2 === void 0 || _ref2.apply(this, $$args);
65822
- });
65823
- delegated("mouseup", canvas, function(...$$args) {
65824
- var _ref3;
65825
- (_ref3 = readOnly() ? void 0 : onUp) === null || _ref3 === void 0 || _ref3.apply(this, $$args);
65826
- });
65827
- event("mouseleave", canvas, function(...$$args) {
65828
- var _ref4;
65829
- (_ref4 = readOnly() ? void 0 : onUp) === null || _ref4 === void 0 || _ref4.apply(this, $$args);
65830
- });
65831
- append($$anchor, div);
65832
- };
65833
- var d = /* @__PURE__ */ user_derived(() => {
65834
- var _$$props$thumbnailUrl2;
65835
- return (_$$props$thumbnailUrl2 = $$props.thumbnailUrl) === null || _$$props$thumbnailUrl2 === void 0 ? void 0 : _$$props$thumbnailUrl2.trim();
65836
- });
65837
- var alternate_2 = ($$anchor) => {
65838
- append($$anchor, root_12$1());
65839
- };
65840
- if_block(node, ($$render) => {
65841
- if (get(d)) $$render(consequent_8);
65842
- else $$render(alternate_2, -1);
65843
- });
65844
- append($$anchor, fragment);
65845
- pop();
65846
- }
65847
- delegate([
65848
- "click",
65849
- "mousedown",
65850
- "mousemove",
65851
- "mouseup"
65852
- ]);
65853
- //#endregion
65854
66097
  //#region src/lib/components/editor/ContextMenu.svelte
65855
66098
  init_client();
65856
66099
  init_index_client();
@@ -65860,7 +66103,7 @@ var root_4$3 = /* @__PURE__ */ from_html(`<button class="ctx-item svelte-wxo1tu"
65860
66103
  var root_5$1 = /* @__PURE__ */ from_html(`<button class="ctx-item svelte-wxo1tu" role="menuitem"><span class="ctx-icon svelte-wxo1tu">✏️</span> Rename Room</button> <button class="ctx-item svelte-wxo1tu" role="menuitem"><span class="ctx-icon svelte-wxo1tu">🎨</span> Change Floor Texture</button> <div class="ctx-sep svelte-wxo1tu"></div> <button class="ctx-item ctx-danger svelte-wxo1tu" role="menuitem"><span class="ctx-icon svelte-wxo1tu">🗑️</span> Delete Room</button>`, 1);
65861
66104
  var root_7$2 = /* @__PURE__ */ from_html(`<button class="ctx-item svelte-wxo1tu" role="menuitem"><span class="ctx-icon svelte-wxo1tu">📋</span> Paste</button> <div class="ctx-sep svelte-wxo1tu"></div>`, 1);
65862
66105
  var root_6$1 = /* @__PURE__ */ from_html(`<!> <button class="ctx-item svelte-wxo1tu" role="menuitem"><span class="ctx-icon svelte-wxo1tu">⬜</span> Select All</button> <button class="ctx-item svelte-wxo1tu" role="menuitem"><span class="ctx-icon svelte-wxo1tu">📦</span> Group Selected (Ctrl+G)</button> <button class="ctx-item svelte-wxo1tu" role="menuitem"><span class="ctx-icon svelte-wxo1tu">📤</span> Ungroup (Ctrl+Shift+G)</button> <button class="ctx-item svelte-wxo1tu" role="menuitem"><span class="ctx-icon svelte-wxo1tu">🧱</span> Add Wall</button> <div class="ctx-sep svelte-wxo1tu"></div> <button class="ctx-item svelte-wxo1tu" role="menuitem"><span class="ctx-icon svelte-wxo1tu">🔍</span> Zoom to Fit</button>`, 1);
65863
- var root_1$5 = /* @__PURE__ */ from_html(`<div class="fixed z-[9999] bg-white border border-gray-200 rounded-lg shadow-xl py-1 min-w-[180px] text-sm select-none" role="menu"><!></div>`);
66106
+ var root_1$4 = /* @__PURE__ */ from_html(`<div class="fixed z-[9999] bg-white border border-gray-200 rounded-lg shadow-xl py-1 min-w-[180px] text-sm select-none" role="menu"><!></div>`);
65864
66107
  function ContextMenu($$anchor, $$props) {
65865
66108
  push($$props, true);
65866
66109
  let menuEl;
@@ -65899,7 +66142,7 @@ function ContextMenu($$anchor, $$props) {
65899
66142
  var fragment = comment();
65900
66143
  var node = first_child(fragment);
65901
66144
  var consequent_6 = ($$anchor) => {
65902
- var div = root_1$5();
66145
+ var div = root_1$4();
65903
66146
  var node_1 = child(div);
65904
66147
  var consequent = ($$anchor) => {
65905
66148
  var fragment_1 = root_2$5();
@@ -66284,34 +66527,30 @@ function findZoneAt(wp, zones, zoom) {
66284
66527
  //#region src/lib/components/editor/FloorPlanCanvas.svelte
66285
66528
  init_client();
66286
66529
  init_index_client();
66287
- var root_2$4 = /* @__PURE__ */ from_html(`<input type="text" class="absolute bg-white border-2 border-blue-500 rounded px-2 py-1 text-sm text-center shadow-lg outline-none"/>`);
66288
66530
  var root_3$3 = /* @__PURE__ */ from_html(`<input type="text" class="absolute bg-white border-2 border-blue-500 rounded px-2 py-1 text-sm text-center shadow-lg outline-none"/>`);
66289
- var root_4$2 = /* @__PURE__ */ from_html(`<div class="absolute inset-0 flex items-center justify-center pointer-events-none"><div class="text-center opacity-60"><div class="text-5xl mb-3">🏠</div> <div class="text-sm font-medium text-gray-500">Start building your floor plan</div> <div class="text-xs text-gray-400 mt-1">Draw walls with <span class="font-mono bg-gray-100 px-1 rounded">W</span> or drag items from the sidebar</div></div></div>`);
66290
- var root_5 = /* @__PURE__ */ from_html(`<canvas width="180" height="120" class="absolute bottom-10 right-2 rounded-lg shadow-lg border border-gray-300 cursor-crosshair bg-white" style="z-index: 15;"></canvas>`);
66291
- var root_7$1 = /* @__PURE__ */ from_html(`<span> </span> <span> </span> <span class="text-gray-300">|</span>`, 1);
66292
- var root_9 = /* @__PURE__ */ from_html(`<span> </span>`);
66531
+ var root_4$2 = /* @__PURE__ */ from_html(`<input type="text" class="absolute bg-white border-2 border-blue-500 rounded px-2 py-1 text-sm text-center shadow-lg outline-none"/>`);
66532
+ var root_5 = /* @__PURE__ */ from_html(`<div class="absolute inset-0 flex items-center justify-center pointer-events-none"><div class="text-center opacity-60"><div class="text-5xl mb-3">🏠</div> <div class="text-sm font-medium text-gray-500">Start building your floor plan</div> <div class="text-xs text-gray-400 mt-1">Draw walls with <span class="font-mono bg-gray-100 px-1 rounded">W</span> or drag items from the sidebar</div></div></div>`);
66533
+ var root_6 = /* @__PURE__ */ from_html(`<canvas width="180" height="120" class="absolute bottom-10 right-2 rounded-lg shadow-lg border border-gray-300 cursor-crosshair bg-white" style="z-index: 15;"></canvas>`);
66534
+ var root_8 = /* @__PURE__ */ from_html(`<span> </span> <span> </span> <span class="text-gray-300">|</span>`, 1);
66293
66535
  var root_10 = /* @__PURE__ */ from_html(`<span> </span>`);
66294
66536
  var root_11 = /* @__PURE__ */ from_html(`<span> </span>`);
66295
- var root_8 = /* @__PURE__ */ from_html(`<span> </span> <!> <!> <!> <span class="text-gray-300">|</span>`, 1);
66296
- var root_12 = /* @__PURE__ */ from_html(`<span class="text-blue-600 font-medium"> </span> <span class="text-gray-300">|</span>`, 1);
66297
- var root_6 = /* @__PURE__ */ from_html(`<div class="absolute bottom-2 right-2 bg-white/80 rounded px-2 py-1 text-xs text-gray-500 flex gap-3"><!> <!> <!> <span> </span> <button class="hover:text-gray-700" title="Zoom to Fit (F)">⊞ Fit</button> <button class="hover:text-gray-700" title="Toggle Grid (G)"> </button> <button class="hover:text-gray-700" title="Toggle Snap to Grid (S)"> </button> <button class="hover:text-gray-700" title="Toggle Furniture"> </button> <button class="hover:text-gray-700" title="Layer Visibility">🗂 Layers</button> <button class="hover:text-gray-700" title="Toggle Rulers"> </button> <button class="hover:text-gray-700" title="Toggle Mini-map"> </button></div>`);
66298
- var root_14 = /* @__PURE__ */ from_html(`<label class="flex items-center gap-2 py-0.5 cursor-pointer hover:bg-gray-50 rounded px-1"><input type="checkbox" class="accent-blue-500"/> <span> </span></label>`);
66299
- var root_13 = /* @__PURE__ */ from_html(`<div class="absolute bottom-12 right-2 z-20 bg-white rounded-lg shadow-lg border border-gray-200 p-3 text-xs min-w-[160px]"><div class="font-semibold text-gray-700 mb-2">Layers</div> <!> <hr class="my-1 border-gray-100"/> <label class="flex items-center gap-2 py-0.5 cursor-pointer hover:bg-gray-50 rounded px-1"><input type="checkbox" class="accent-blue-500"/> <span>Room Labels</span></label> <label class="flex items-center gap-2 py-0.5 cursor-pointer hover:bg-gray-50 rounded px-1"><input type="checkbox" class="accent-blue-500"/> <span>Dimensions</span></label></div>`);
66300
- var root_17 = /* @__PURE__ */ from_html(`<button class="w-7 h-7 flex items-center justify-center rounded hover:bg-gray-100 text-gray-500 hover:text-gray-700" title="Flip swing" aria-label="Flip swing"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M7 16V4m0 0L3 8m4-4l4 4M17 8v12m0 0l4-4m-4 4l-4-4"></path></svg></button>`);
66301
- var root_18 = /* @__PURE__ */ from_html(`<button class="w-7 h-7 flex items-center justify-center rounded hover:bg-gray-100 text-gray-500 hover:text-gray-700" title="Split wall at midpoint" aria-label="Split wall at midpoint"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 2v20M4 12h4M16 12h4"></path></svg></button>`);
66302
- var root_16 = /* @__PURE__ */ from_html(`<div class="absolute z-40 flex items-center gap-0.5 bg-white rounded-lg shadow-lg border border-gray-200 px-1 py-0.5"><button class="w-7 h-7 flex items-center justify-center rounded hover:bg-gray-100 text-gray-500 hover:text-gray-700" title="Duplicate" aria-label="Duplicate"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="9" y="9" width="13" height="13" rx="2"></rect><path d="M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1"></path></svg></button> <!> <!> <div class="w-px h-5 bg-gray-200 mx-0.5"></div> <button class="w-7 h-7 flex items-center justify-center rounded hover:bg-red-50 text-gray-400 hover:text-red-600" title="Delete" aria-label="Delete"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 6h18M8 6V4a2 2 0 012-2h4a2 2 0 012 2v2m3 0v14a2 2 0 01-2 2H7a2 2 0 01-2-2V6h14"></path></svg></button></div>`);
66303
- var root_19 = /* @__PURE__ */ from_html(`<div class="absolute top-2 left-1/2 -translate-x-1/2 bg-blue-600 text-white px-3 py-1 rounded-full text-xs shadow">Click to add wall segment · Double-click to finish · C to close loop ·
66537
+ var root_12 = /* @__PURE__ */ from_html(`<span> </span>`);
66538
+ var root_9 = /* @__PURE__ */ from_html(`<span> </span> <!> <!> <!> <span class="text-gray-300">|</span>`, 1);
66539
+ var root_13 = /* @__PURE__ */ from_html(`<span class="text-blue-600 font-medium"> </span> <span class="text-gray-300">|</span>`, 1);
66540
+ var root_7$1 = /* @__PURE__ */ from_html(`<div class="absolute bottom-2 right-2 bg-white/80 rounded px-2 py-1 text-xs text-gray-500 flex gap-3"><!> <!> <!> <span> </span> <button class="hover:text-gray-700" title="Zoom to Fit (F)">⊞ Fit</button> <button class="hover:text-gray-700" title="Toggle Grid (G)"> </button> <button class="hover:text-gray-700" title="Toggle Snap to Grid (S)"> </button> <button class="hover:text-gray-700" title="Toggle Furniture"> </button> <button class="hover:text-gray-700" title="Layer Visibility">🗂 Layers</button> <button class="hover:text-gray-700" title="Toggle Rulers"> </button> <button class="hover:text-gray-700" title="Toggle Mini-map"> </button></div>`);
66541
+ var root_15 = /* @__PURE__ */ from_html(`<label class="flex items-center gap-2 py-0.5 cursor-pointer hover:bg-gray-50 rounded px-1"><input type="checkbox" class="accent-blue-500"/> <span> </span></label>`);
66542
+ var root_14 = /* @__PURE__ */ from_html(`<div class="absolute bottom-12 right-2 z-20 bg-white rounded-lg shadow-lg border border-gray-200 p-3 text-xs min-w-[160px]"><div class="font-semibold text-gray-700 mb-2">Layers</div> <!> <hr class="my-1 border-gray-100"/> <label class="flex items-center gap-2 py-0.5 cursor-pointer hover:bg-gray-50 rounded px-1"><input type="checkbox" class="accent-blue-500"/> <span>Room Labels</span></label> <label class="flex items-center gap-2 py-0.5 cursor-pointer hover:bg-gray-50 rounded px-1"><input type="checkbox" class="accent-blue-500"/> <span>Dimensions</span></label></div>`);
66543
+ var root_18 = /* @__PURE__ */ from_html(`<button class="w-7 h-7 flex items-center justify-center rounded hover:bg-gray-100 text-gray-500 hover:text-gray-700" title="Flip swing" aria-label="Flip swing"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M7 16V4m0 0L3 8m4-4l4 4M17 8v12m0 0l4-4m-4 4l-4-4"></path></svg></button>`);
66544
+ var root_19 = /* @__PURE__ */ from_html(`<button class="w-7 h-7 flex items-center justify-center rounded hover:bg-gray-100 text-gray-500 hover:text-gray-700" title="Split wall at midpoint" aria-label="Split wall at midpoint"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 2v20M4 12h4M16 12h4"></path></svg></button>`);
66545
+ var root_17 = /* @__PURE__ */ from_html(`<div class="absolute z-40 flex items-center gap-0.5 bg-white rounded-lg shadow-lg border border-gray-200 px-1 py-0.5"><button class="w-7 h-7 flex items-center justify-center rounded hover:bg-gray-100 text-gray-500 hover:text-gray-700" title="Duplicate" aria-label="Duplicate"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="9" y="9" width="13" height="13" rx="2"></rect><path d="M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1"></path></svg></button> <!> <!> <div class="w-px h-5 bg-gray-200 mx-0.5"></div> <button class="w-7 h-7 flex items-center justify-center rounded hover:bg-red-50 text-gray-400 hover:text-red-600" title="Delete" aria-label="Delete"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 6h18M8 6V4a2 2 0 012-2h4a2 2 0 012 2v2m3 0v14a2 2 0 01-2 2H7a2 2 0 01-2-2V6h14"></path></svg></button></div>`);
66546
+ var root_20 = /* @__PURE__ */ from_html(`<div class="absolute top-2 left-1/2 -translate-x-1/2 bg-blue-600 text-white px-3 py-1 rounded-full text-xs shadow">Click to add wall segment · Double-click to finish · C to close loop ·
66304
66547
  Esc to cancel</div>`);
66305
- var root_20 = /* @__PURE__ */ from_html(`<div class="absolute top-2 left-1/2 -translate-x-1/2 bg-purple-600 text-white px-3 py-1 rounded-full text-xs shadow"> </div>`);
66306
- var root_21 = /* @__PURE__ */ from_html(`<div class="absolute top-2 left-1/2 -translate-x-1/2 bg-red-600 text-white px-3 py-1 rounded-full text-xs shadow">Right-click two points to measure · M to exit · Esc to cancel</div>`);
66307
- var root_22 = /* @__PURE__ */ from_html(`<div class="absolute top-2 left-1/2 -translate-x-1/2 bg-emerald-600 text-white px-3 py-1 rounded-full text-xs shadow">Click to place text label · Esc to cancel</div>`);
66308
- var root_23 = /* @__PURE__ */ from_html(`<div class="absolute top-2 left-1/2 -translate-x-1/2 bg-indigo-600 text-white px-3 py-1 rounded-full text-xs shadow"> </div>`);
66309
- var root_1$4 = /* @__PURE__ */ from_html(`<!> <!> <!> <!> <!> <!> <!> <!> <!> <!> <!> <!> <div class="absolute bottom-3 left-3 z-20 flex items-center gap-1 bg-white rounded-lg shadow-lg border border-gray-200 px-1 py-0.5"><button class="w-7 h-7 flex items-center justify-center rounded hover:bg-gray-100 text-gray-600 hover:text-gray-800 font-bold text-lg" title="Zoom Out (−)" aria-label="Zoom out">−</button> <button class="min-w-[3.5rem] h-7 flex items-center justify-center rounded hover:bg-gray-100 text-xs font-medium text-gray-600 hover:text-gray-800 tabular-nums" title="Reset to 100%" aria-label="Zoom to 100%"> </button> <button class="w-7 h-7 flex items-center justify-center rounded hover:bg-gray-100 text-gray-600 hover:text-gray-800 font-bold text-lg" title="Zoom In (+)" aria-label="Zoom in">+</button> <div class="w-px h-5 bg-gray-200"></div> <button class="w-7 h-7 flex items-center justify-center rounded hover:bg-gray-100 text-gray-500 hover:text-gray-700 text-sm" title="Zoom to Fit (F)" aria-label="Zoom to fit">⊞</button></div> <!>`, 1);
66310
- var root_25 = /* @__PURE__ */ from_html(`<span class="font-mono text-gray-400 font-normal text-xs ml-1"> </span>`);
66311
- var root_26 = /* @__PURE__ */ from_html(`<p class="text-[10px] text-gray-400 leading-snug">Draw FOV on the image (<code class="font-mono">coordinates</code>).
66312
- Tool <strong>Camera FOV</strong> on the floor → <code class="font-mono">mapCoordinates</code>.</p>`);
66313
- var root_24 = /* @__PURE__ */ from_html(`<aside class="w-80 shrink-0 h-full border-l border-gray-200 bg-white overflow-y-auto p-3 flex flex-col gap-2 shadow-sm z-10" aria-label="Camera thumbnail panel"><div class="text-sm font-semibold text-gray-800">Camera thumbnail <!></div> <!> <!></aside>`);
66314
- var root$1 = /* @__PURE__ */ from_html(`<div class="w-full h-full relative overflow-hidden flex" role="application"><div class="flex-1 min-w-0 h-full relative overflow-hidden"><div class="w-full h-full"><canvas aria-label="Floor plan editor canvas"></canvas></div> <!></div> <!></div>`);
66548
+ var root_21 = /* @__PURE__ */ from_html(`<div class="absolute top-2 left-1/2 -translate-x-1/2 bg-purple-600 text-white px-3 py-1 rounded-full text-xs shadow"> </div>`);
66549
+ var root_22 = /* @__PURE__ */ from_html(`<div class="absolute top-2 left-1/2 -translate-x-1/2 bg-red-600 text-white px-3 py-1 rounded-full text-xs shadow">Right-click two points to measure · M to exit · Esc to cancel</div>`);
66550
+ var root_23 = /* @__PURE__ */ from_html(`<div class="absolute top-2 left-1/2 -translate-x-1/2 bg-emerald-600 text-white px-3 py-1 rounded-full text-xs shadow">Click to place text label · Esc to cancel</div>`);
66551
+ var root_24 = /* @__PURE__ */ from_html(`<div class="absolute top-2 left-1/2 -translate-x-1/2 bg-indigo-600 text-white px-3 py-1 rounded-full text-xs shadow"> </div>`);
66552
+ var root_2$4 = /* @__PURE__ */ from_html(`<!> <!> <!> <!> <!> <!> <!> <!> <!> <!> <!> <!> <div class="absolute bottom-3 left-3 z-20 flex items-center gap-1 bg-white rounded-lg shadow-lg border border-gray-200 px-1 py-0.5"><button class="w-7 h-7 flex items-center justify-center rounded hover:bg-gray-100 text-gray-600 hover:text-gray-800 font-bold text-lg" title="Zoom Out (−)" aria-label="Zoom out">−</button> <button class="min-w-[3.5rem] h-7 flex items-center justify-center rounded hover:bg-gray-100 text-xs font-medium text-gray-600 hover:text-gray-800 tabular-nums" title="Reset to 100%" aria-label="Zoom to 100%"> </button> <button class="w-7 h-7 flex items-center justify-center rounded hover:bg-gray-100 text-gray-600 hover:text-gray-800 font-bold text-lg" title="Zoom In (+)" aria-label="Zoom in">+</button> <div class="w-px h-5 bg-gray-200"></div> <button class="w-7 h-7 flex items-center justify-center rounded hover:bg-gray-100 text-gray-500 hover:text-gray-700 text-sm" title="Zoom to Fit (F)" aria-label="Zoom to fit">⊞</button></div> <!>`, 1);
66553
+ var root$1 = /* @__PURE__ */ from_html(`<div class="w-full h-full relative overflow-hidden flex" role="application"><div class="flex-1 min-w-0 h-full relative overflow-hidden"><div class="w-full h-full relative"><canvas aria-label="Floor plan editor canvas"></canvas> <!></div> <!></div></div>`);
66315
66554
  function FloorPlanCanvas($$anchor, $$props) {
66316
66555
  push($$props, true);
66317
66556
  const $panMode = () => store_get(panMode, "$panMode", $$stores);
@@ -66403,16 +66642,8 @@ function FloorPlanCanvas($$anchor, $$props) {
66403
66642
  /** Camera surveillance FOV polygon draft (floor → mapCoordinates) — not floors[].zones */
66404
66643
  let fovPolyDraft = /* @__PURE__ */ state(proxy([]));
66405
66644
  let fovCursor = /* @__PURE__ */ state(null);
66406
- let fovSideCam = /* @__PURE__ */ user_derived(resolveFovCamera);
66407
- /** Host `cameraThumbnail` → side panel beside floor (never floor background). */
66408
- let showFovSidePanel = /* @__PURE__ */ user_derived(() => {
66409
- var _cameraThumbnail;
66410
- return !!((_cameraThumbnail = cameraThumbnail()) === null || _cameraThumbnail === void 0 ? void 0 : _cameraThumbnail.trim());
66411
- });
66412
- let fovPanelSerial = /* @__PURE__ */ user_derived(() => {
66413
- var _$$get, _selectedCameraSerial;
66414
- return ((_$$get = get(fovSideCam)) === null || _$$get === void 0 || (_$$get = _$$get.serial) === null || _$$get === void 0 ? void 0 : _$$get.trim()) || ((_selectedCameraSerial = selectedCameraSerial()) === null || _selectedCameraSerial === void 0 ? void 0 : _selectedCameraSerial.trim()) || "";
66415
- });
66645
+ /** Selected committed floor FOV (by camera serial) — shows float toolbar */
66646
+ let selectedFovSerial = /* @__PURE__ */ state(null);
66416
66647
  let editingTextAnnotationId = /* @__PURE__ */ state(null);
66417
66648
  let editingTextAnnotationPos = /* @__PURE__ */ state(proxy({
66418
66649
  x: 0,
@@ -66524,8 +66755,8 @@ function FloorPlanCanvas($$anchor, $$props) {
66524
66755
  let calPoints = /* @__PURE__ */ state(proxy([]));
66525
66756
  let bgImage = /* @__PURE__ */ state(null);
66526
66757
  user_effect(() => {
66527
- var _$$get2;
66528
- const url = (_$$get2 = get(currentFloor)) === null || _$$get2 === void 0 || (_$$get2 = _$$get2.backgroundImage) === null || _$$get2 === void 0 ? void 0 : _$$get2.dataUrl;
66758
+ var _$$get;
66759
+ const url = (_$$get = get(currentFloor)) === null || _$$get === void 0 || (_$$get = _$$get.backgroundImage) === null || _$$get === void 0 ? void 0 : _$$get.dataUrl;
66529
66760
  if (!url) {
66530
66761
  set(bgImage, null);
66531
66762
  return;
@@ -66716,9 +66947,9 @@ function FloorPlanCanvas($$anchor, $$props) {
66716
66947
  return (_ref = (_$$get$furniture$find = get(currentFloor).furniture.find((f) => f.catalogId === "camera" && !!f.serial && !used.has(f.serial))) !== null && _$$get$furniture$find !== void 0 ? _$$get$furniture$find : get(currentFloor).furniture.find((f) => f.catalogId === "camera" && !!f.serial)) !== null && _ref !== void 0 ? _ref : null;
66717
66948
  }
66718
66949
  function commitAreaShape(shape, points) {
66719
- var _$$get$zones$length, _$$get3;
66950
+ var _$$get$zones$length, _$$get2;
66720
66951
  const cam = resolveAreaCameraTarget();
66721
- const idx = (_$$get$zones$length = (_$$get3 = get(currentFloor)) === null || _$$get3 === void 0 || (_$$get3 = _$$get3.zones) === null || _$$get3 === void 0 ? void 0 : _$$get3.length) !== null && _$$get$zones$length !== void 0 ? _$$get$zones$length : 0;
66952
+ const idx = (_$$get$zones$length = (_$$get2 = get(currentFloor)) === null || _$$get2 === void 0 || (_$$get2 = _$$get2.zones) === null || _$$get2 === void 0 ? void 0 : _$$get2.length) !== null && _$$get$zones$length !== void 0 ? _$$get$zones$length : 0;
66722
66953
  if (cam === null || cam === void 0 ? void 0 : cam.serial) {
66723
66954
  const style = resolveCameraAreaStyle(cam, idx);
66724
66955
  return upsertCameraZone(shape, points, {
@@ -66734,11 +66965,11 @@ function FloorPlanCanvas($$anchor, $$props) {
66734
66965
  }
66735
66966
  /** Camera for FOV tool: selected camera furniture, else host selectedCameraSerial. */
66736
66967
  function resolveFovCamera() {
66737
- var _selectedCameraSerial2;
66968
+ var _selectedCameraSerial;
66738
66969
  if (!get(currentFloor)) return null;
66739
66970
  const sel = get(currentFloor).furniture.find((f) => f.id === get(currentSelectedId) && f.catalogId === "camera" && f.serial);
66740
66971
  if (sel) return sel;
66741
- const hostSerial = (_selectedCameraSerial2 = selectedCameraSerial()) === null || _selectedCameraSerial2 === void 0 ? void 0 : _selectedCameraSerial2.trim();
66972
+ const hostSerial = (_selectedCameraSerial = selectedCameraSerial()) === null || _selectedCameraSerial === void 0 ? void 0 : _selectedCameraSerial.trim();
66742
66973
  if (hostSerial) {
66743
66974
  var _$$get$furniture$find2;
66744
66975
  return (_$$get$furniture$find2 = get(currentFloor).furniture.find((f) => f.catalogId === "camera" && f.serial === hostSerial)) !== null && _$$get$furniture$find2 !== void 0 ? _$$get$furniture$find2 : null;
@@ -66751,23 +66982,144 @@ function FloorPlanCanvas($$anchor, $$props) {
66751
66982
  setCameraMapCoordinatesFromWorld(cam.serial, points);
66752
66983
  set(fovPolyDraft, [], true);
66753
66984
  set(fovCursor, null);
66985
+ set(selectedFovSerial, cam.serial, true);
66754
66986
  selectedTool.set("select");
66755
66987
  selectedElementId.set(cam.id);
66756
66988
  }
66989
+ function findFovCameraAt(wp) {
66990
+ if (!get(currentFloor)) return null;
66991
+ const bounds = getInteriorFloorBounds(get(currentFloor));
66992
+ if (!bounds) return null;
66993
+ const cams = [...get(currentFloor).furniture].filter((f) => f.catalogId === "camera" && f.serial).reverse();
66994
+ for (const fi of cams) {
66995
+ var _fi$props;
66996
+ const pts = mapCoordinatesToWorldPoints((_fi$props = fi.props) === null || _fi$props === void 0 ? void 0 : _fi$props.mapCoordinates, bounds);
66997
+ if (pts.length >= 3 && pointInPolygon(wp, pts)) return fi;
66998
+ }
66999
+ return null;
67000
+ }
67001
+ function clearSelectedFovMap() {
67002
+ var _$$get3;
67003
+ const serial = (_$$get3 = get(selectedFovSerial)) === null || _$$get3 === void 0 ? void 0 : _$$get3.trim();
67004
+ if (!serial) return;
67005
+ setCameraMapCoordinatesFromWorld(serial, null);
67006
+ set(selectedFovSerial, null);
67007
+ }
67008
+ function floorPolyToolbar() {
67009
+ var _$$get4;
67010
+ if ($$props.viewOnly) return null;
67011
+ if (get(currentTool) === "zone" && get(currentZoneShape) === "polygon" && get(zonePolyDraft).length) {
67012
+ const a = polygonToolbarAnchor(get(zonePolyDraft));
67013
+ if (!a) return null;
67014
+ const s = worldToScreen(a.x, a.y);
67015
+ return {
67016
+ mode: "zone-draft",
67017
+ x: s.x,
67018
+ y: s.y,
67019
+ canConfirm: get(zonePolyDraft).length >= 3,
67020
+ showConfirm: true
67021
+ };
67022
+ }
67023
+ if (get(currentTool) === "cameraFov" && get(fovPolyDraft).length) {
67024
+ const a = polygonToolbarAnchor(get(fovPolyDraft));
67025
+ if (!a) return null;
67026
+ const s = worldToScreen(a.x, a.y);
67027
+ return {
67028
+ mode: "fov-draft",
67029
+ x: s.x,
67030
+ y: s.y,
67031
+ canConfirm: get(fovPolyDraft).length >= 3,
67032
+ showConfirm: true
67033
+ };
67034
+ }
67035
+ if (get(selectedZoneId) && ((_$$get4 = get(currentFloor)) === null || _$$get4 === void 0 ? void 0 : _$$get4.zones)) {
67036
+ var _z$points;
67037
+ const z = get(currentFloor).zones.find((zz) => zz.id === get(selectedZoneId));
67038
+ if (z === null || z === void 0 || (_z$points = z.points) === null || _z$points === void 0 ? void 0 : _z$points.length) {
67039
+ const a = polygonToolbarAnchor(z.points);
67040
+ if (!a) return null;
67041
+ const s = worldToScreen(a.x, a.y);
67042
+ return {
67043
+ mode: "zone",
67044
+ x: s.x,
67045
+ y: s.y,
67046
+ canConfirm: false,
67047
+ showConfirm: false
67048
+ };
67049
+ }
67050
+ }
67051
+ if (get(selectedFovSerial) && get(currentFloor)) {
67052
+ const bounds = getInteriorFloorBounds(get(currentFloor));
67053
+ const cam = get(currentFloor).furniture.find((f) => f.catalogId === "camera" && f.serial === get(selectedFovSerial));
67054
+ if (cam && bounds) {
67055
+ var _cam$props;
67056
+ const pts = mapCoordinatesToWorldPoints((_cam$props = cam.props) === null || _cam$props === void 0 ? void 0 : _cam$props.mapCoordinates, bounds);
67057
+ if (pts.length >= 3) {
67058
+ const a = polygonToolbarAnchor(pts);
67059
+ if (!a) return null;
67060
+ const s = worldToScreen(a.x, a.y);
67061
+ return {
67062
+ mode: "fov",
67063
+ x: s.x,
67064
+ y: s.y,
67065
+ canConfirm: false,
67066
+ showConfirm: false
67067
+ };
67068
+ }
67069
+ }
67070
+ }
67071
+ return null;
67072
+ }
67073
+ let polyTb = /* @__PURE__ */ user_derived(floorPolyToolbar);
67074
+ function onPolyTbConfirm() {
67075
+ const tb = floorPolyToolbar();
67076
+ if (!(tb === null || tb === void 0 ? void 0 : tb.canConfirm)) return;
67077
+ if (tb.mode === "zone-draft" && get(zonePolyDraft).length >= 3) {
67078
+ const id = commitAreaShape("polygon", get(zonePolyDraft));
67079
+ set(zonePolyDraft, [], true);
67080
+ set(zoneCursor, null);
67081
+ set(selectedZoneId, id, true);
67082
+ selectedElementId.set(id);
67083
+ selectedTool.set("select");
67084
+ return;
67085
+ }
67086
+ if (tb.mode === "fov-draft" && get(fovPolyDraft).length >= 3) commitFovFloorPolygon(get(fovPolyDraft));
67087
+ }
67088
+ function onPolyTbDelete() {
67089
+ const tb = floorPolyToolbar();
67090
+ if (!tb) return;
67091
+ if (tb.mode === "zone-draft") {
67092
+ set(zonePolyDraft, [], true);
67093
+ set(zoneCursor, null);
67094
+ return;
67095
+ }
67096
+ if (tb.mode === "fov-draft") {
67097
+ set(fovPolyDraft, [], true);
67098
+ set(fovCursor, null);
67099
+ return;
67100
+ }
67101
+ if (tb.mode === "zone" && get(selectedZoneId)) {
67102
+ removeZone(get(selectedZoneId));
67103
+ set(selectedZoneId, null);
67104
+ selectedElementId.set(null);
67105
+ return;
67106
+ }
67107
+ if (tb.mode === "fov") clearSelectedFovMap();
67108
+ }
66757
67109
  function drawCameraFovOverlays() {
66758
67110
  if (!ctx || !get(currentFloor)) return;
66759
67111
  const bounds = getInteriorFloorBounds(get(currentFloor));
66760
67112
  if (!bounds) return;
66761
67113
  const active = resolveFovCamera();
66762
67114
  for (const fi of get(currentFloor).furniture) {
66763
- var _fi$props, _fi$props2;
67115
+ var _fi$props2, _fi$props3;
66764
67116
  if (fi.catalogId !== "camera" || !fi.serial) continue;
66765
- const mapStr = (_fi$props = fi.props) === null || _fi$props === void 0 ? void 0 : _fi$props.mapCoordinates;
67117
+ const mapStr = (_fi$props2 = fi.props) === null || _fi$props2 === void 0 ? void 0 : _fi$props2.mapCoordinates;
66766
67118
  if (!mapStr) continue;
66767
67119
  const pts = mapCoordinatesToWorldPoints(mapStr, bounds);
66768
67120
  if (pts.length < 2) continue;
66769
67121
  const isActive = (active === null || active === void 0 ? void 0 : active.id) === fi.id;
66770
- const color = ((_fi$props2 = fi.props) === null || _fi$props2 === void 0 ? void 0 : _fi$props2.zoneColor) || fi.color || "#22c55e";
67122
+ const color = ((_fi$props3 = fi.props) === null || _fi$props3 === void 0 ? void 0 : _fi$props3.zoneColor) || fi.color || "#22c55e";
66771
67123
  ctx.save();
66772
67124
  ctx.strokeStyle = color;
66773
67125
  ctx.fillStyle = color;
@@ -66786,6 +67138,10 @@ function FloorPlanCanvas($$anchor, $$props) {
66786
67138
  ctx.globalAlpha = 1;
66787
67139
  ctx.stroke();
66788
67140
  ctx.setLineDash([]);
67141
+ for (let i = 0; i < pts.length; i++) {
67142
+ const s = worldToScreen(pts[i].x, pts[i].y);
67143
+ drawVertexIndexBadge(ctx, s.x, s.y, i, color, isActive ? 9 : 7);
67144
+ }
66789
67145
  ctx.restore();
66790
67146
  }
66791
67147
  if (get(currentTool) === "cameraFov" && (get(fovPolyDraft).length || get(fovCursor))) {
@@ -66809,17 +67165,21 @@ function FloorPlanCanvas($$anchor, $$props) {
66809
67165
  }
66810
67166
  ctx.stroke();
66811
67167
  }
66812
- ctx.globalAlpha = 1;
66813
- ctx.setLineDash([]);
66814
- for (const p of get(fovPolyDraft)) {
66815
- const s = worldToScreen(p.x, p.y);
67168
+ if (get(fovCursor) && get(fovPolyDraft).length >= 3) {
67169
+ const a = worldToScreen(get(fovCursor).x, get(fovCursor).y);
67170
+ const b = worldToScreen(get(fovPolyDraft)[0].x, get(fovPolyDraft)[0].y);
67171
+ ctx.globalAlpha = .35;
66816
67172
  ctx.beginPath();
66817
- ctx.fillStyle = "#fff";
66818
- ctx.strokeStyle = color;
66819
- ctx.arc(s.x, s.y, 4, 0, Math.PI * 2);
66820
- ctx.fill();
67173
+ ctx.moveTo(a.x, a.y);
67174
+ ctx.lineTo(b.x, b.y);
66821
67175
  ctx.stroke();
66822
67176
  }
67177
+ ctx.globalAlpha = 1;
67178
+ ctx.setLineDash([]);
67179
+ for (let i = 0; i < get(fovPolyDraft).length; i++) {
67180
+ const s = worldToScreen(get(fovPolyDraft)[i].x, get(fovPolyDraft)[i].y);
67181
+ drawVertexIndexBadge(ctx, s.x, s.y, i, color, 9);
67182
+ }
66823
67183
  ctx.restore();
66824
67184
  }
66825
67185
  }
@@ -67236,9 +67596,9 @@ function FloorPlanCanvas($$anchor, $$props) {
67236
67596
  }
67237
67597
  }
67238
67598
  function drawMeasurement() {
67239
- var _$$get4;
67599
+ var _$$get5;
67240
67600
  if (!get(measureStart)) return;
67241
- const end = (_$$get4 = get(measureEnd)) !== null && _$$get4 !== void 0 ? _$$get4 : get(mousePos);
67601
+ const end = (_$$get5 = get(measureEnd)) !== null && _$$get5 !== void 0 ? _$$get5 : get(mousePos);
67242
67602
  const s = worldToScreen(get(measureStart).x, get(measureStart).y);
67243
67603
  const e = worldToScreen(end.x, end.y);
67244
67604
  ctx.strokeStyle = "#ef4444";
@@ -67406,8 +67766,8 @@ function FloorPlanCanvas($$anchor, $$props) {
67406
67766
  drawColumn(getCS(), col, selected);
67407
67767
  }
67408
67768
  function drawFloorPlateBackground() {
67409
- var _$$get5;
67410
- if (!((_$$get5 = get(currentFloor)) === null || _$$get5 === void 0 || (_$$get5 = _$$get5.walls) === null || _$$get5 === void 0 ? void 0 : _$$get5.length)) return;
67769
+ var _$$get6;
67770
+ if (!((_$$get6 = get(currentFloor)) === null || _$$get6 === void 0 || (_$$get6 = _$$get6.walls) === null || _$$get6 === void 0 ? void 0 : _$$get6.length)) return;
67411
67771
  const bounds = getFloorBounds(get(currentFloor), { includeWallThickness: true });
67412
67772
  if (!bounds) return;
67413
67773
  const topLeft = worldToScreen(bounds.minX, bounds.minY);
@@ -67416,8 +67776,8 @@ function FloorPlanCanvas($$anchor, $$props) {
67416
67776
  ctx.fillRect(topLeft.x, topLeft.y, bottomRight.x - topLeft.x, bottomRight.y - topLeft.y);
67417
67777
  }
67418
67778
  function drawBackgroundImage() {
67419
- var _$$get6;
67420
- if (!get(bgImage) || !((_$$get6 = get(currentFloor)) === null || _$$get6 === void 0 ? void 0 : _$$get6.backgroundImage)) return;
67779
+ var _$$get7;
67780
+ if (!get(bgImage) || !((_$$get7 = get(currentFloor)) === null || _$$get7 === void 0 ? void 0 : _$$get7.backgroundImage)) return;
67421
67781
  const bg = get(currentFloor).backgroundImage;
67422
67782
  ctx.save();
67423
67783
  ctx.globalAlpha = bg.opacity;
@@ -68131,8 +68491,8 @@ function FloorPlanCanvas($$anchor, $$props) {
68131
68491
  }
68132
68492
  drawFloorHeatmapLayer();
68133
68493
  if (get(layerVis).zones && (floor === null || floor === void 0 || (_floor$zones = floor.zones) === null || _floor$zones === void 0 ? void 0 : _floor$zones.length)) {
68134
- var _$$get7;
68135
- const zoneSel = (_$$get7 = get(selectedZoneId)) !== null && _$$get7 !== void 0 ? _$$get7 : floor.zones.some((z) => z.id === get(currentSelectedId)) ? get(currentSelectedId) : null;
68494
+ var _$$get8;
68495
+ const zoneSel = (_$$get8 = get(selectedZoneId)) !== null && _$$get8 !== void 0 ? _$$get8 : floor.zones.some((z) => z.id === get(currentSelectedId)) ? get(currentSelectedId) : null;
68136
68496
  drawZones(getCS(), floor, zoneSel);
68137
68497
  }
68138
68498
  if (get(showFurniture)) for (const fi of floor.furniture) drawFurniture(fi, isSelected(fi.id));
@@ -68481,7 +68841,7 @@ function FloorPlanCanvas($$anchor, $$props) {
68481
68841
  return findRoomAt(p, get(detectedRooms), get(currentFloor).walls);
68482
68842
  }
68483
68843
  function onMouseDown(e) {
68484
- var _$$get8, _$$get9;
68844
+ var _$$get10;
68485
68845
  if ($$props.viewOnly) return;
68486
68846
  markDirty();
68487
68847
  if (e.button === 1 || e.button === 0 && (get(spaceDown) || $panMode() || e.shiftKey && get(currentTool) === "select")) {
@@ -68605,34 +68965,50 @@ function FloorPlanCanvas($$anchor, $$props) {
68605
68965
  set(fovPolyDraft, [...get(fovPolyDraft), snapped], true);
68606
68966
  return;
68607
68967
  }
68608
- if (tool === "select" && ((_$$get8 = get(currentFloor)) === null || _$$get8 === void 0 || (_$$get8 = _$$get8.zones) === null || _$$get8 === void 0 ? void 0 : _$$get8.length) && get(layerVis).zones) {
68609
- if (!(get(showFurniture) && (!!findFurnitureAt$1(wp) || !!findHandleAt$1(wp)) || get(layerVis).columns && !!findColumnAt$1(wp) || get(showStairs) && !!findStairAt$1(wp))) {
68610
- const zHit = findZoneAt(wp, get(currentFloor).zones, get(zoom));
68611
- if (zHit) {
68612
- set(selectedZoneId, zHit.id, true);
68613
- selectedElementId.set(zHit.id);
68968
+ if (tool === "select") {
68969
+ const objectAboveZone = get(showFurniture) && (!!findFurnitureAt$1(wp) || !!findHandleAt$1(wp)) || get(layerVis).columns && !!findColumnAt$1(wp) || get(showStairs) && !!findStairAt$1(wp);
68970
+ if (!objectAboveZone) {
68971
+ var _$$get9;
68972
+ if (((_$$get9 = get(currentFloor)) === null || _$$get9 === void 0 || (_$$get9 = _$$get9.zones) === null || _$$get9 === void 0 ? void 0 : _$$get9.length) && get(layerVis).zones) {
68973
+ const zHit = findZoneAt(wp, get(currentFloor).zones, get(zoom));
68974
+ if (zHit) {
68975
+ set(selectedZoneId, zHit.id, true);
68976
+ set(selectedFovSerial, null);
68977
+ selectedElementId.set(zHit.id);
68978
+ set(selectedTextAnnotationId, null);
68979
+ set(selectedAnnotationId, null);
68980
+ set(selectedMeasurementId, null);
68981
+ const vIdx = findZoneVertexAt(wp, zHit, get(zoom));
68982
+ beginUndoGroup();
68983
+ if (vIdx >= 0) {
68984
+ set(draggingZoneId, zHit.id, true);
68985
+ set(draggingZoneVertex, vIdx, true);
68986
+ } else {
68987
+ set(draggingZoneId, zHit.id, true);
68988
+ set(draggingZoneVertex, null);
68989
+ set(zoneDragLast, {
68990
+ x: wp.x,
68991
+ y: wp.y
68992
+ }, true);
68993
+ }
68994
+ return;
68995
+ }
68996
+ }
68997
+ const fovHit = findFovCameraAt(wp);
68998
+ if (fovHit === null || fovHit === void 0 ? void 0 : fovHit.serial) {
68999
+ set(selectedFovSerial, fovHit.serial, true);
69000
+ set(selectedZoneId, null);
69001
+ selectedElementId.set(fovHit.id);
68614
69002
  set(selectedTextAnnotationId, null);
68615
69003
  set(selectedAnnotationId, null);
68616
69004
  set(selectedMeasurementId, null);
68617
- const vIdx = findZoneVertexAt(wp, zHit, get(zoom));
68618
- beginUndoGroup();
68619
- if (vIdx >= 0) {
68620
- set(draggingZoneId, zHit.id, true);
68621
- set(draggingZoneVertex, vIdx, true);
68622
- } else {
68623
- set(draggingZoneId, zHit.id, true);
68624
- set(draggingZoneVertex, null);
68625
- set(zoneDragLast, {
68626
- x: wp.x,
68627
- y: wp.y
68628
- }, true);
68629
- }
68630
69005
  return;
68631
69006
  }
68632
69007
  }
68633
69008
  set(selectedZoneId, null);
69009
+ if (!objectAboveZone) set(selectedFovSerial, null);
68634
69010
  }
68635
- if (tool === "select" && ((_$$get9 = get(currentFloor)) === null || _$$get9 === void 0 ? void 0 : _$$get9.guides)) {
69011
+ if (tool === "select" && ((_$$get10 = get(currentFloor)) === null || _$$get10 === void 0 ? void 0 : _$$get10.guides)) {
68636
69012
  const GUIDE_HIT = 6 / get(zoom);
68637
69013
  for (const g of get(currentFloor).guides) {
68638
69014
  if (g.orientation === "horizontal" && Math.abs(wp.y - g.position) < GUIDE_HIT) {
@@ -68701,9 +69077,9 @@ function FloorPlanCanvas($$anchor, $$props) {
68701
69077
  const dist = Math.hypot(newPts[1].x - newPts[0].x, newPts[1].y - newPts[0].y);
68702
69078
  const realDist = prompt("Enter the real-world distance between these two points (in cm):");
68703
69079
  if (realDist && Number(realDist) > 0) {
68704
- var _$$get10;
69080
+ var _$$get11;
68705
69081
  const pixelsPerCm = dist / Number(realDist);
68706
- if ((_$$get10 = get(currentFloor)) === null || _$$get10 === void 0 ? void 0 : _$$get10.backgroundImage) updateBackgroundImage({ scale: get(currentFloor).backgroundImage.scale * (1 / pixelsPerCm) });
69082
+ if ((_$$get11 = get(currentFloor)) === null || _$$get11 === void 0 ? void 0 : _$$get11.backgroundImage) updateBackgroundImage({ scale: get(currentFloor).backgroundImage.scale * (1 / pixelsPerCm) });
68707
69083
  }
68708
69084
  calibrationMode.set(false);
68709
69085
  return [];
@@ -68930,7 +69306,12 @@ function FloorPlanCanvas($$anchor, $$props) {
68930
69306
  }
68931
69307
  const fi = findFurnitureAt$1(wp);
68932
69308
  if (fi) {
69309
+ var _fi$props4;
68933
69310
  selectElement(fi.id, e.shiftKey, e.ctrlKey || e.metaKey);
69311
+ if (fi.catalogId === "camera" && fi.serial && ((_fi$props4 = fi.props) === null || _fi$props4 === void 0 ? void 0 : _fi$props4.mapCoordinates)) {
69312
+ set(selectedFovSerial, fi.serial, true);
69313
+ set(selectedZoneId, null);
69314
+ } else set(selectedFovSerial, null);
68934
69315
  if (!e.shiftKey && !fi.locked) {
68935
69316
  set(draggingFurnitureId, fi.id, true);
68936
69317
  commitFurnitureMove();
@@ -68987,6 +69368,8 @@ function FloorPlanCanvas($$anchor, $$props) {
68987
69368
  if (!e.shiftKey) {
68988
69369
  selectedElementId.set(null);
68989
69370
  selectedElementIds.set(/* @__PURE__ */ new Set());
69371
+ set(selectedFovSerial, null);
69372
+ set(selectedZoneId, null);
68990
69373
  }
68991
69374
  selectedRoomId.set(null);
68992
69375
  }
@@ -69086,7 +69469,7 @@ function FloorPlanCanvas($$anchor, $$props) {
69086
69469
  }
69087
69470
  }
69088
69471
  function onMouseMove(e) {
69089
- var _$$get11, _$$get12, _$$get13, _$$get14, _$$get15;
69472
+ var _$$get12, _$$get13, _$$get14, _$$get15, _$$get16;
69090
69473
  if ($$props.viewOnly) return;
69091
69474
  markDirty();
69092
69475
  const rect = canvas.getBoundingClientRect();
@@ -69106,7 +69489,7 @@ function FloorPlanCanvas($$anchor, $$props) {
69106
69489
  x: snap(get(mousePos).x),
69107
69490
  y: snap(get(mousePos).y)
69108
69491
  }, true);
69109
- if (get(draggingZoneId) && ((_$$get11 = get(currentFloor)) === null || _$$get11 === void 0 ? void 0 : _$$get11.zones)) {
69492
+ if (get(draggingZoneId) && ((_$$get12 = get(currentFloor)) === null || _$$get12 === void 0 ? void 0 : _$$get12.zones)) {
69110
69493
  const z = get(currentFloor).zones.find((z) => z.id === get(draggingZoneId));
69111
69494
  if (z) {
69112
69495
  const snapped = {
@@ -69144,7 +69527,7 @@ function FloorPlanCanvas($$anchor, $$props) {
69144
69527
  } : r));
69145
69528
  return;
69146
69529
  }
69147
- if (get(draggingGuideId) && ((_$$get12 = get(currentFloor)) === null || _$$get12 === void 0 ? void 0 : _$$get12.guides)) {
69530
+ if (get(draggingGuideId) && ((_$$get13 = get(currentFloor)) === null || _$$get13 === void 0 ? void 0 : _$$get13.guides)) {
69148
69531
  const g = get(currentFloor).guides.find((g) => g.id === get(draggingGuideId));
69149
69532
  if (g) {
69150
69533
  const newPos = g.orientation === "horizontal" ? get(mousePos).y : get(mousePos).x;
@@ -69300,7 +69683,7 @@ function FloorPlanCanvas($$anchor, $$props) {
69300
69683
  }
69301
69684
  }
69302
69685
  }
69303
- if (get(draggingTextAnnotationId) && ((_$$get13 = get(currentFloor)) === null || _$$get13 === void 0 ? void 0 : _$$get13.textAnnotations)) {
69686
+ if (get(draggingTextAnnotationId) && ((_$$get14 = get(currentFloor)) === null || _$$get14 === void 0 ? void 0 : _$$get14.textAnnotations)) {
69304
69687
  const basePos = {
69305
69688
  x: get(mousePos).x - textAnnotationDragOffset.x,
69306
69689
  y: get(mousePos).y - textAnnotationDragOffset.y
@@ -69317,7 +69700,7 @@ function FloorPlanCanvas($$anchor, $$props) {
69317
69700
  }, true);
69318
69701
  }
69319
69702
  }
69320
- if (get(draggingColumnId) && ((_$$get14 = get(currentFloor)) === null || _$$get14 === void 0 ? void 0 : _$$get14.columns)) {
69703
+ if (get(draggingColumnId) && ((_$$get15 = get(currentFloor)) === null || _$$get15 === void 0 ? void 0 : _$$get15.columns)) {
69321
69704
  const basePos = {
69322
69705
  x: get(mousePos).x - columnDragOffset.x,
69323
69706
  y: get(mousePos).y - columnDragOffset.y
@@ -69327,7 +69710,7 @@ function FloorPlanCanvas($$anchor, $$props) {
69327
69710
  y: snap(basePos.y)
69328
69711
  });
69329
69712
  }
69330
- if (get(draggingStairId) && ((_$$get15 = get(currentFloor)) === null || _$$get15 === void 0 ? void 0 : _$$get15.stairs)) {
69713
+ if (get(draggingStairId) && ((_$$get16 = get(currentFloor)) === null || _$$get16 === void 0 ? void 0 : _$$get16.stairs)) {
69331
69714
  const basePos = {
69332
69715
  x: get(mousePos).x - stairDragOffset.x,
69333
69716
  y: get(mousePos).y - stairDragOffset.y
@@ -69338,12 +69721,12 @@ function FloorPlanCanvas($$anchor, $$props) {
69338
69721
  });
69339
69722
  }
69340
69723
  if (get(draggingFurnitureId)) {
69341
- var _$$get16;
69724
+ var _$$get17;
69342
69725
  const basePos = {
69343
69726
  x: get(mousePos).x - dragOffset.x,
69344
69727
  y: get(mousePos).y - dragOffset.y
69345
69728
  };
69346
- const fi = (_$$get16 = get(currentFloor)) === null || _$$get16 === void 0 ? void 0 : _$$get16.furniture.find((f) => f.id === get(draggingFurnitureId));
69729
+ const fi = (_$$get17 = get(currentFloor)) === null || _$$get17 === void 0 ? void 0 : _$$get17.furniture.find((f) => f.id === get(draggingFurnitureId));
69347
69730
  if (fi) {
69348
69731
  const wallSnap = snapFurnitureToWall(basePos, fi.catalogId, fi.rotation);
69349
69732
  if (wallSnap) {
@@ -69356,13 +69739,13 @@ function FloorPlanCanvas($$anchor, $$props) {
69356
69739
  wallAngle: wallSnap.wallAngle
69357
69740
  }, true);
69358
69741
  } else {
69359
- var _$$get17;
69742
+ var _$$get18;
69360
69743
  const snapped = {
69361
69744
  x: snap(basePos.x),
69362
69745
  y: snap(basePos.y)
69363
69746
  };
69364
69747
  const GUIDE_SNAP = 10;
69365
- if ((_$$get17 = get(currentFloor)) === null || _$$get17 === void 0 ? void 0 : _$$get17.guides) for (const g of get(currentFloor).guides) {
69748
+ if ((_$$get18 = get(currentFloor)) === null || _$$get18 === void 0 ? void 0 : _$$get18.guides) for (const g of get(currentFloor).guides) {
69366
69749
  if (g.orientation === "horizontal" && Math.abs(snapped.y - g.position) < GUIDE_SNAP) snapped.y = g.position;
69367
69750
  if (g.orientation === "vertical" && Math.abs(snapped.x - g.position) < GUIDE_SNAP) snapped.x = g.position;
69368
69751
  }
@@ -70099,8 +70482,8 @@ function FloorPlanCanvas($$anchor, $$props) {
70099
70482
  }
70100
70483
  }
70101
70484
  let cursorStyle = /* @__PURE__ */ user_derived(() => {
70102
- var _$$get18;
70103
- 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(draggingZoneId) ? "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" : ((_$$get18 = get(draggingHandle)) === null || _$$get18 === void 0 ? void 0 : _$$get18.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";
70485
+ var _$$get19;
70486
+ 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(draggingZoneId) ? "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" : ((_$$get19 = get(draggingHandle)) === null || _$$get19 === void 0 ? void 0 : _$$get19.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";
70104
70487
  });
70105
70488
  var div = root$1();
70106
70489
  event("keydown", $window, onKeyDown);
@@ -70110,14 +70493,36 @@ function FloorPlanCanvas($$anchor, $$props) {
70110
70493
  var canvas_1 = child(div_2);
70111
70494
  let classes;
70112
70495
  bind_this(canvas_1, ($$value) => canvas = $$value, () => canvas);
70496
+ var node = sibling(canvas_1, 2);
70497
+ var consequent = ($$anchor) => {
70498
+ PolygonFloatToolbar($$anchor, {
70499
+ get x() {
70500
+ return get(polyTb).x;
70501
+ },
70502
+ get y() {
70503
+ return get(polyTb).y;
70504
+ },
70505
+ get showConfirm() {
70506
+ return get(polyTb).showConfirm;
70507
+ },
70508
+ get canConfirm() {
70509
+ return get(polyTb).canConfirm;
70510
+ },
70511
+ onConfirm: onPolyTbConfirm,
70512
+ onDelete: onPolyTbDelete
70513
+ });
70514
+ };
70515
+ if_block(node, ($$render) => {
70516
+ if (get(polyTb)) $$render(consequent);
70517
+ });
70113
70518
  reset(div_2);
70114
70519
  bind_this(div_2, ($$value) => canvasFrame = $$value, () => canvasFrame);
70115
- var node = sibling(div_2, 2);
70116
- var consequent_21 = ($$anchor) => {
70117
- var fragment = root_1$4();
70118
- var node_1 = first_child(fragment);
70119
- var consequent = ($$anchor) => {
70120
- var input = root_2$4();
70520
+ var node_1 = sibling(div_2, 2);
70521
+ var consequent_22 = ($$anchor) => {
70522
+ var fragment_1 = root_2$4();
70523
+ var node_2 = first_child(fragment_1);
70524
+ var consequent_1 = ($$anchor) => {
70525
+ var input = root_3$3();
70121
70526
  remove_input_defaults(input);
70122
70527
  autofocus(input, true);
70123
70528
  template_effect(() => {
@@ -70150,12 +70555,12 @@ function FloorPlanCanvas($$anchor, $$props) {
70150
70555
  });
70151
70556
  append($$anchor, input);
70152
70557
  };
70153
- if_block(node_1, ($$render) => {
70154
- if (get(editingRoomId)) $$render(consequent);
70558
+ if_block(node_2, ($$render) => {
70559
+ if (get(editingRoomId)) $$render(consequent_1);
70155
70560
  });
70156
- var node_2 = sibling(node_1, 2);
70157
- var consequent_1 = ($$anchor) => {
70158
- var input_1 = root_3$3();
70561
+ var node_3 = sibling(node_2, 2);
70562
+ var consequent_2 = ($$anchor) => {
70563
+ var input_1 = root_4$2();
70159
70564
  remove_input_defaults(input_1);
70160
70565
  autofocus(input_1, true);
70161
70566
  template_effect(() => {
@@ -70177,8 +70582,8 @@ function FloorPlanCanvas($$anchor, $$props) {
70177
70582
  }
70178
70583
  set(editingTextAnnotationId, null);
70179
70584
  } else if (e.key === "Escape") {
70180
- var _$$get19;
70181
- if ((_$$get19 = get(currentFloor)) === null || _$$get19 === void 0 ? void 0 : _$$get19.textAnnotations) {
70585
+ var _$$get20;
70586
+ if ((_$$get20 = get(currentFloor)) === null || _$$get20 === void 0 ? void 0 : _$$get20.textAnnotations) {
70182
70587
  const ta = get(currentFloor).textAnnotations.find((t) => t.id === get(editingTextAnnotationId));
70183
70588
  if (ta && ta.text === "Text" && !get(editingTextAnnotationValue).trim()) {
70184
70589
  removeTextAnnotation(get(editingTextAnnotationId));
@@ -70202,33 +70607,33 @@ function FloorPlanCanvas($$anchor, $$props) {
70202
70607
  });
70203
70608
  append($$anchor, input_1);
70204
70609
  };
70205
- if_block(node_2, ($$render) => {
70206
- if (get(editingTextAnnotationId)) $$render(consequent_1);
70207
- });
70208
- var node_3 = sibling(node_2, 2);
70209
- var consequent_2 = ($$anchor) => {
70210
- append($$anchor, root_4$2());
70211
- };
70212
70610
  if_block(node_3, ($$render) => {
70213
- if (get(currentFloor) && get(currentFloor).walls.length === 0 && get(currentFloor).furniture.length === 0 && get(currentFloor).doors.length === 0 && !$$props.viewOnly) $$render(consequent_2);
70611
+ if (get(editingTextAnnotationId)) $$render(consequent_2);
70214
70612
  });
70215
70613
  var node_4 = sibling(node_3, 2);
70216
70614
  var consequent_3 = ($$anchor) => {
70217
- var canvas_2 = root_5();
70615
+ append($$anchor, root_5());
70616
+ };
70617
+ if_block(node_4, ($$render) => {
70618
+ if (get(currentFloor) && get(currentFloor).walls.length === 0 && get(currentFloor).furniture.length === 0 && get(currentFloor).doors.length === 0 && !$$props.viewOnly) $$render(consequent_3);
70619
+ });
70620
+ var node_5 = sibling(node_4, 2);
70621
+ var consequent_4 = ($$anchor) => {
70622
+ var canvas_2 = root_6();
70218
70623
  bind_this(canvas_2, ($$value) => minimapCanvas = $$value, () => minimapCanvas);
70219
70624
  delegated("click", canvas_2, onMinimapClick);
70220
70625
  append($$anchor, canvas_2);
70221
70626
  };
70222
- if_block(node_4, ($$render) => {
70223
- if (!$$props.viewOnly && get(showMinimap) && get(currentFloor) && get(currentFloor).walls.length > 0) $$render(consequent_3);
70627
+ if_block(node_5, ($$render) => {
70628
+ if (!$$props.viewOnly && get(showMinimap) && get(currentFloor) && get(currentFloor).walls.length > 0) $$render(consequent_4);
70224
70629
  });
70225
- var node_5 = sibling(node_4, 2);
70226
- var consequent_10 = ($$anchor) => {
70227
- var div_4 = root_6();
70228
- var node_6 = child(div_4);
70229
- var consequent_4 = ($$anchor) => {
70230
- var fragment_1 = root_7$1();
70231
- var span = first_child(fragment_1);
70630
+ var node_6 = sibling(node_5, 2);
70631
+ var consequent_11 = ($$anchor) => {
70632
+ var div_4 = root_7$1();
70633
+ var node_7 = child(div_4);
70634
+ var consequent_5 = ($$anchor) => {
70635
+ var fragment_2 = root_8();
70636
+ var span = first_child(fragment_2);
70232
70637
  var text_1 = child(span);
70233
70638
  reset(span);
70234
70639
  var span_1 = sibling(span, 2);
@@ -70240,20 +70645,20 @@ function FloorPlanCanvas($$anchor, $$props) {
70240
70645
  set_text(text_1, `${(_$$get$length = get(detectedRooms).length) !== null && _$$get$length !== void 0 ? _$$get$length : ""} room${get(detectedRooms).length !== 1 ? "s" : ""}`);
70241
70646
  set_text(text_2, $0);
70242
70647
  }, [() => formatArea(get(detectedRooms).reduce((s, r) => s + r.area, 0), $projectSettings().units)]);
70243
- append($$anchor, fragment_1);
70648
+ append($$anchor, fragment_2);
70244
70649
  };
70245
- if_block(node_6, ($$render) => {
70246
- if (get(detectedRooms).length > 0) $$render(consequent_4);
70650
+ if_block(node_7, ($$render) => {
70651
+ if (get(detectedRooms).length > 0) $$render(consequent_5);
70247
70652
  });
70248
- var node_7 = sibling(node_6, 2);
70249
- var consequent_8 = ($$anchor) => {
70250
- var fragment_2 = root_8();
70251
- var span_2 = first_child(fragment_2);
70653
+ var node_8 = sibling(node_7, 2);
70654
+ var consequent_9 = ($$anchor) => {
70655
+ var fragment_3 = root_9();
70656
+ var span_2 = first_child(fragment_3);
70252
70657
  var text_3 = child(span_2);
70253
70658
  reset(span_2);
70254
- var node_8 = sibling(span_2, 2);
70255
- var consequent_5 = ($$anchor) => {
70256
- var span_3 = root_9();
70659
+ var node_9 = sibling(span_2, 2);
70660
+ var consequent_6 = ($$anchor) => {
70661
+ var span_3 = root_10();
70257
70662
  var text_4 = child(span_3);
70258
70663
  reset(span_3);
70259
70664
  template_effect(() => {
@@ -70262,12 +70667,12 @@ function FloorPlanCanvas($$anchor, $$props) {
70262
70667
  });
70263
70668
  append($$anchor, span_3);
70264
70669
  };
70265
- if_block(node_8, ($$render) => {
70266
- if (get(currentFloor).doors.length > 0) $$render(consequent_5);
70670
+ if_block(node_9, ($$render) => {
70671
+ if (get(currentFloor).doors.length > 0) $$render(consequent_6);
70267
70672
  });
70268
- var node_9 = sibling(node_8, 2);
70269
- var consequent_6 = ($$anchor) => {
70270
- var span_4 = root_10();
70673
+ var node_10 = sibling(node_9, 2);
70674
+ var consequent_7 = ($$anchor) => {
70675
+ var span_4 = root_11();
70271
70676
  var text_5 = child(span_4);
70272
70677
  reset(span_4);
70273
70678
  template_effect(() => {
@@ -70276,12 +70681,12 @@ function FloorPlanCanvas($$anchor, $$props) {
70276
70681
  });
70277
70682
  append($$anchor, span_4);
70278
70683
  };
70279
- if_block(node_9, ($$render) => {
70280
- if (get(currentFloor).windows.length > 0) $$render(consequent_6);
70684
+ if_block(node_10, ($$render) => {
70685
+ if (get(currentFloor).windows.length > 0) $$render(consequent_7);
70281
70686
  });
70282
- var node_10 = sibling(node_9, 2);
70283
- var consequent_7 = ($$anchor) => {
70284
- var span_5 = root_11();
70687
+ var node_11 = sibling(node_10, 2);
70688
+ var consequent_8 = ($$anchor) => {
70689
+ var span_5 = root_12();
70285
70690
  var text_6 = child(span_5);
70286
70691
  reset(span_5);
70287
70692
  template_effect(() => {
@@ -70290,23 +70695,23 @@ function FloorPlanCanvas($$anchor, $$props) {
70290
70695
  });
70291
70696
  append($$anchor, span_5);
70292
70697
  };
70293
- if_block(node_10, ($$render) => {
70294
- if (get(currentFloor).furniture.length > 0) $$render(consequent_7);
70698
+ if_block(node_11, ($$render) => {
70699
+ if (get(currentFloor).furniture.length > 0) $$render(consequent_8);
70295
70700
  });
70296
70701
  next(2);
70297
70702
  template_effect(() => {
70298
70703
  var _$$get$walls$length;
70299
70704
  return set_text(text_3, `${(_$$get$walls$length = get(currentFloor).walls.length) !== null && _$$get$walls$length !== void 0 ? _$$get$walls$length : ""} wall${get(currentFloor).walls.length !== 1 ? "s" : ""}`);
70300
70705
  });
70301
- append($$anchor, fragment_2);
70706
+ append($$anchor, fragment_3);
70302
70707
  };
70303
- if_block(node_7, ($$render) => {
70304
- if (get(currentFloor)) $$render(consequent_8);
70708
+ if_block(node_8, ($$render) => {
70709
+ if (get(currentFloor)) $$render(consequent_9);
70305
70710
  });
70306
- var node_11 = sibling(node_7, 2);
70307
- var consequent_9 = ($$anchor) => {
70308
- var fragment_3 = root_12();
70309
- var span_6 = first_child(fragment_3);
70711
+ var node_12 = sibling(node_8, 2);
70712
+ var consequent_10 = ($$anchor) => {
70713
+ var fragment_4 = root_13();
70714
+ var span_6 = first_child(fragment_4);
70310
70715
  var text_7 = child(span_6);
70311
70716
  reset(span_6);
70312
70717
  next(2);
@@ -70314,12 +70719,12 @@ function FloorPlanCanvas($$anchor, $$props) {
70314
70719
  var _$$get$size;
70315
70720
  return set_text(text_7, `${(_$$get$size = get(currentSelectedIds).size) !== null && _$$get$size !== void 0 ? _$$get$size : ""} selected`);
70316
70721
  });
70317
- append($$anchor, fragment_3);
70722
+ append($$anchor, fragment_4);
70318
70723
  };
70319
- if_block(node_11, ($$render) => {
70320
- if (get(currentSelectedIds).size > 1) $$render(consequent_9);
70724
+ if_block(node_12, ($$render) => {
70725
+ if (get(currentSelectedIds).size > 1) $$render(consequent_10);
70321
70726
  });
70322
- var span_7 = sibling(node_11, 2);
70727
+ var span_7 = sibling(node_12, 2);
70323
70728
  var text_8 = child(span_7);
70324
70729
  reset(span_7);
70325
70730
  var button = sibling(span_7, 2);
@@ -70363,14 +70768,14 @@ function FloorPlanCanvas($$anchor, $$props) {
70363
70768
  delegated("click", button_6, () => set(showMinimap, !get(showMinimap)));
70364
70769
  append($$anchor, div_4);
70365
70770
  };
70366
- if_block(node_5, ($$render) => {
70367
- if (!$$props.viewOnly) $$render(consequent_10);
70771
+ if_block(node_6, ($$render) => {
70772
+ if (!$$props.viewOnly) $$render(consequent_11);
70368
70773
  });
70369
- var node_12 = sibling(node_5, 2);
70370
- var consequent_11 = ($$anchor) => {
70371
- var div_5 = root_13();
70372
- var node_13 = sibling(child(div_5), 2);
70373
- each(node_13, 16, () => [
70774
+ var node_13 = sibling(node_6, 2);
70775
+ var consequent_12 = ($$anchor) => {
70776
+ var div_5 = root_14();
70777
+ var node_14 = sibling(child(div_5), 2);
70778
+ each(node_14, 16, () => [
70374
70779
  ["walls", "Walls"],
70375
70780
  ["doors", "Doors"],
70376
70781
  ["windows", "Windows"],
@@ -70384,7 +70789,7 @@ function FloorPlanCanvas($$anchor, $$props) {
70384
70789
  var $$array = /* @__PURE__ */ user_derived(() => to_array($$item, 2));
70385
70790
  let key = () => get($$array)[0];
70386
70791
  let label = () => get($$array)[1];
70387
- var label_1 = root_14();
70792
+ var label_1 = root_15();
70388
70793
  var input_2 = child(label_1);
70389
70794
  remove_input_defaults(input_2);
70390
70795
  var span_8 = sibling(input_2, 2);
@@ -70401,7 +70806,7 @@ function FloorPlanCanvas($$anchor, $$props) {
70401
70806
  })));
70402
70807
  append($$anchor, label_1);
70403
70808
  });
70404
- var label_2 = sibling(node_13, 4);
70809
+ var label_2 = sibling(node_14, 4);
70405
70810
  var input_3 = child(label_2);
70406
70811
  remove_input_defaults(input_3);
70407
70812
  next(2);
@@ -70416,11 +70821,11 @@ function FloorPlanCanvas($$anchor, $$props) {
70416
70821
  bind_checked(input_4, () => get(showDimensions), ($$value) => set(showDimensions, $$value));
70417
70822
  append($$anchor, div_5);
70418
70823
  };
70419
- if_block(node_12, ($$render) => {
70420
- if (get(showLayerPanel)) $$render(consequent_11);
70824
+ if_block(node_13, ($$render) => {
70825
+ if (get(showLayerPanel)) $$render(consequent_12);
70421
70826
  });
70422
- var node_14 = sibling(node_12, 2);
70423
- var consequent_15 = ($$anchor) => {
70827
+ var node_15 = sibling(node_13, 2);
70828
+ var consequent_16 = ($$anchor) => {
70424
70829
  const el = /* @__PURE__ */ user_derived(() => (() => {
70425
70830
  const f = get(currentFloor);
70426
70831
  const wall = f.walls.find((w) => w.id === get(currentSelectedId));
@@ -70452,25 +70857,25 @@ function FloorPlanCanvas($$anchor, $$props) {
70452
70857
  };
70453
70858
  return null;
70454
70859
  })());
70455
- var fragment_4 = comment();
70456
- var node_15 = first_child(fragment_4);
70457
- var consequent_14 = ($$anchor) => {
70458
- var div_6 = root_16();
70860
+ var fragment_5 = comment();
70861
+ var node_16 = first_child(fragment_5);
70862
+ var consequent_15 = ($$anchor) => {
70863
+ var div_6 = root_17();
70459
70864
  var button_7 = child(div_6);
70460
- var node_16 = sibling(button_7, 2);
70461
- var consequent_12 = ($$anchor) => {
70462
- var button_8 = root_17();
70865
+ var node_17 = sibling(button_7, 2);
70866
+ var consequent_13 = ($$anchor) => {
70867
+ var button_8 = root_18();
70463
70868
  delegated("click", button_8, () => {
70464
70869
  if (get(el).door) updateDoor(get(el).door.id, { swingDirection: get(el).door.swingDirection === "left" ? "right" : "left" });
70465
70870
  });
70466
70871
  append($$anchor, button_8);
70467
70872
  };
70468
- if_block(node_16, ($$render) => {
70469
- if (get(el).type === "door" && get(el).door) $$render(consequent_12);
70873
+ if_block(node_17, ($$render) => {
70874
+ if (get(el).type === "door" && get(el).door) $$render(consequent_13);
70470
70875
  });
70471
- var node_17 = sibling(node_16, 2);
70472
- var consequent_13 = ($$anchor) => {
70473
- var button_9 = root_18();
70876
+ var node_18 = sibling(node_17, 2);
70877
+ var consequent_14 = ($$anchor) => {
70878
+ var button_9 = root_19();
70474
70879
  delegated("click", button_9, () => {
70475
70880
  if (get(currentSelectedId)) {
70476
70881
  if (splitWall(get(currentSelectedId), .5)) selectedElementId.set(null);
@@ -70478,10 +70883,10 @@ function FloorPlanCanvas($$anchor, $$props) {
70478
70883
  });
70479
70884
  append($$anchor, button_9);
70480
70885
  };
70481
- if_block(node_17, ($$render) => {
70482
- if (get(el).type === "wall" && get(currentSelectedId) && get(currentSelectedIds).size === 0) $$render(consequent_13);
70886
+ if_block(node_18, ($$render) => {
70887
+ if (get(el).type === "wall" && get(currentSelectedId) && get(currentSelectedIds).size === 0) $$render(consequent_14);
70483
70888
  });
70484
- var button_10 = sibling(node_17, 4);
70889
+ var button_10 = sibling(node_18, 4);
70485
70890
  reset(div_6);
70486
70891
  template_effect(() => {
70487
70892
  var _$$get$pos$x;
@@ -70510,62 +70915,62 @@ function FloorPlanCanvas($$anchor, $$props) {
70510
70915
  });
70511
70916
  append($$anchor, div_6);
70512
70917
  };
70513
- if_block(node_15, ($$render) => {
70514
- if (get(el)) $$render(consequent_14);
70918
+ if_block(node_16, ($$render) => {
70919
+ if (get(el)) $$render(consequent_15);
70515
70920
  });
70516
- append($$anchor, fragment_4);
70921
+ append($$anchor, fragment_5);
70517
70922
  };
70518
- if_block(node_14, ($$render) => {
70519
- if ((get(currentSelectedId) || get(currentSelectedIds).size > 0) && get(currentFloor) && get(currentTool) === "select") $$render(consequent_15);
70923
+ if_block(node_15, ($$render) => {
70924
+ if ((get(currentSelectedId) || get(currentSelectedIds).size > 0) && get(currentFloor) && get(currentTool) === "select") $$render(consequent_16);
70520
70925
  });
70521
- var node_18 = sibling(node_14, 2);
70522
- var consequent_16 = ($$anchor) => {
70523
- append($$anchor, root_19());
70926
+ var node_19 = sibling(node_15, 2);
70927
+ var consequent_17 = ($$anchor) => {
70928
+ append($$anchor, root_20());
70524
70929
  };
70525
- if_block(node_18, ($$render) => {
70526
- if (get(currentTool) === "wall" && get(wallStart)) $$render(consequent_16);
70930
+ if_block(node_19, ($$render) => {
70931
+ if (get(currentTool) === "wall" && get(wallStart)) $$render(consequent_17);
70527
70932
  });
70528
- var node_19 = sibling(node_18, 2);
70529
- var consequent_17 = ($$anchor) => {
70530
- var div_8 = root_20();
70933
+ var node_20 = sibling(node_19, 2);
70934
+ var consequent_18 = ($$anchor) => {
70935
+ var div_8 = root_21();
70531
70936
  var text_15 = child(div_8);
70532
70937
  reset(div_8);
70533
70938
  template_effect(() => {
70534
- var _$$get20;
70535
- return set_text(text_15, `Click to place · Scroll or R to rotate (${(_$$get20 = get(currentPlacingRotation)) !== null && _$$get20 !== void 0 ? _$$get20 : ""}°) · Esc
70939
+ var _$$get21;
70940
+ return set_text(text_15, `Click to place · Scroll or R to rotate (${(_$$get21 = get(currentPlacingRotation)) !== null && _$$get21 !== void 0 ? _$$get21 : ""}°) · Esc
70536
70941
  to cancel`);
70537
70942
  });
70538
70943
  append($$anchor, div_8);
70539
70944
  };
70540
- if_block(node_19, ($$render) => {
70541
- if (get(currentPlacingId) && get(currentTool) === "furniture") $$render(consequent_17);
70542
- });
70543
- var node_20 = sibling(node_19, 2);
70544
- var consequent_18 = ($$anchor) => {
70545
- append($$anchor, root_21());
70546
- };
70547
70945
  if_block(node_20, ($$render) => {
70548
- if (get(measuring)) $$render(consequent_18);
70946
+ if (get(currentPlacingId) && get(currentTool) === "furniture") $$render(consequent_18);
70549
70947
  });
70550
70948
  var node_21 = sibling(node_20, 2);
70551
70949
  var consequent_19 = ($$anchor) => {
70552
70950
  append($$anchor, root_22());
70553
70951
  };
70554
70952
  if_block(node_21, ($$render) => {
70555
- if (get(textAnnotationMode)) $$render(consequent_19);
70953
+ if (get(measuring)) $$render(consequent_19);
70556
70954
  });
70557
70955
  var node_22 = sibling(node_21, 2);
70558
70956
  var consequent_20 = ($$anchor) => {
70559
- var div_11 = root_23();
70957
+ append($$anchor, root_23());
70958
+ };
70959
+ if_block(node_22, ($$render) => {
70960
+ if (get(textAnnotationMode)) $$render(consequent_20);
70961
+ });
70962
+ var node_23 = sibling(node_22, 2);
70963
+ var consequent_21 = ($$anchor) => {
70964
+ var div_11 = root_24();
70560
70965
  var text_16 = child(div_11);
70561
70966
  reset(div_11);
70562
70967
  template_effect(() => set_text(text_16, `${get(annotationStart) ? "Click second point to create annotation" : "Click first point"} · N to exit · Esc to cancel`));
70563
70968
  append($$anchor, div_11);
70564
70969
  };
70565
- if_block(node_22, ($$render) => {
70566
- if (get(annotating)) $$render(consequent_20);
70970
+ if_block(node_23, ($$render) => {
70971
+ if (get(annotating)) $$render(consequent_21);
70567
70972
  });
70568
- var div_12 = sibling(node_22, 2);
70973
+ var div_12 = sibling(node_23, 2);
70569
70974
  var button_11 = child(div_12);
70570
70975
  var button_12 = sibling(button_11, 2);
70571
70976
  var text_17 = child(button_12);
@@ -70625,70 +71030,12 @@ function FloorPlanCanvas($$anchor, $$props) {
70625
71030
  markDirty();
70626
71031
  });
70627
71032
  delegated("click", button_14, () => zoomToFit());
70628
- append($$anchor, fragment);
71033
+ append($$anchor, fragment_1);
70629
71034
  };
70630
- if_block(node, ($$render) => {
70631
- if (!$$props.viewOnly) $$render(consequent_21);
71035
+ if_block(node_1, ($$render) => {
71036
+ if (!$$props.viewOnly) $$render(consequent_22);
70632
71037
  });
70633
71038
  reset(div_1);
70634
- var node_24 = sibling(div_1, 2);
70635
- var consequent_24 = ($$anchor) => {
70636
- var aside = root_24();
70637
- var div_13 = child(aside);
70638
- var node_25 = sibling(child(div_13));
70639
- var consequent_22 = ($$anchor) => {
70640
- var span_9 = root_25();
70641
- var text_18 = child(span_9, true);
70642
- reset(span_9);
70643
- template_effect(() => set_text(text_18, get(fovPanelSerial)));
70644
- append($$anchor, span_9);
70645
- };
70646
- if_block(node_25, ($$render) => {
70647
- if (get(fovPanelSerial)) $$render(consequent_22);
70648
- });
70649
- reset(div_13);
70650
- var node_26 = sibling(div_13, 2);
70651
- var consequent_23 = ($$anchor) => {
70652
- append($$anchor, root_26());
70653
- };
70654
- if_block(node_26, ($$render) => {
70655
- if (!$$props.viewOnly && get(fovPanelSerial)) $$render(consequent_23);
70656
- });
70657
- var node_27 = sibling(node_26, 2);
70658
- {
70659
- let $0 = /* @__PURE__ */ user_derived(() => {
70660
- var _$$get$props$coordina, _$$get21;
70661
- return (_$$get$props$coordina = (_$$get21 = get(fovSideCam)) === null || _$$get21 === void 0 || (_$$get21 = _$$get21.props) === null || _$$get21 === void 0 ? void 0 : _$$get21.coordinates) !== null && _$$get$props$coordina !== void 0 ? _$$get$props$coordina : "";
70662
- });
70663
- let $1 = /* @__PURE__ */ user_derived(() => {
70664
- var _$$get$props$mapCoord, _$$get22;
70665
- return (_$$get$props$mapCoord = (_$$get22 = get(fovSideCam)) === null || _$$get22 === void 0 || (_$$get22 = _$$get22.props) === null || _$$get22 === void 0 ? void 0 : _$$get22.mapCoordinates) !== null && _$$get$props$mapCoord !== void 0 ? _$$get$props$mapCoord : "";
70666
- });
70667
- let $2 = /* @__PURE__ */ user_derived(() => $$props.viewOnly || !get(fovPanelSerial));
70668
- CameraFovEditor(node_27, {
70669
- get serial() {
70670
- return get(fovPanelSerial);
70671
- },
70672
- get thumbnailUrl() {
70673
- return cameraThumbnail();
70674
- },
70675
- get coordinates() {
70676
- return get($0);
70677
- },
70678
- get mapCoordinates() {
70679
- return get($1);
70680
- },
70681
- get readOnly() {
70682
- return get($2);
70683
- }
70684
- });
70685
- }
70686
- reset(aside);
70687
- append($$anchor, aside);
70688
- };
70689
- if_block(node_24, ($$render) => {
70690
- if (get(showFovSidePanel)) $$render(consequent_24);
70691
- });
70692
71039
  reset(div);
70693
71040
  template_effect(($0) => {
70694
71041
  set_style(div_2, $0);
@@ -72425,6 +72772,12 @@ function _ensureShadowRoot() {
72425
72772
  width: 100%;
72426
72773
  height: 100%;
72427
72774
  }
72775
+ :host:fullscreen,
72776
+ :host:-webkit-full-screen {
72777
+ width: 100vw;
72778
+ height: 100vh;
72779
+ background: #fff;
72780
+ }
72428
72781
  `;
72429
72782
  shadow.appendChild(style);
72430
72783
  _classPrivateFieldSet2(_wrapper, this, document.createElement("div"));