(function () {
  const WIDGET_SHELL_SELECTOR = ".js-gia-widget-shell";
  const WIDGET_SPAWN_SELECTOR = ".js-widget-spawn-trigger";
  const WIDGET_LOAD_TARGET_SELECTOR = '[hx-target="#widgets-here"], [data-widget-url]';
  const WIDGET_ACTION_SELECTOR = ".js-gia-widget-action";
  const TASKBAR_SELECTOR = "#gia-taskbar";
  const TASKBAR_ITEMS_SELECTOR = "#gia-taskbar-items";
  const WORKSPACE_STASH_SELECTOR = "#gia-workspace-stash";
  const SNAP_ASSISTANT_SELECTOR = "#gia-snap-assistant";
  const SNAP_ASSISTANT_OPTIONS_SELECTOR = "#gia-snap-assistant-options";
  const SNAP_ASSISTANT_CLOSE_SELECTOR = ".js-gia-snap-assistant-close";
  const MOBILE_MEDIA_QUERY = "(max-width: 768px)";
  const DESKTOP_MEDIA_QUERY = "(min-width: 1216px)";
  const GRID_COLUMNS = 12;
  const GRID_ROWS = 12;
  const MIN_QUARTER_TILE_HEIGHT = 340;
  const MIN_QUARTER_TILE_WIDTH = 420;
  const assetPromises = {
    styles: {},
    scripts: {},
  };
  let widgetShellProcessingChain = Promise.resolve();
  const workspaceState = {
    order: [],
    minimized: new Map(),
    pendingWidgetIds: new Set(),
    activeWidgetId: "",
    anchorWidgetId: "",
    pendingSpawnSourceId: "",
    pendingSpawnTs: 0,
    lastSpawnedId: "",
    snapLeftId: "",
    snapRightId: "",
    snapTopId: "",
    snapBottomId: "",
    snapAssistantSourceId: "",
    snapAssistantMode: "",
  };

  function withDocumentRoot(root) {
    return root && typeof root.querySelectorAll === "function" ? root : document;
  }

  function toArray(value) {
    return Array.isArray(value) ? value : Array.from(value || []);
  }

  function getGridElement() {
    return window.gridElement || document.getElementById("grid-stack-main");
  }

  function getTaskbar() {
    return document.querySelector(TASKBAR_SELECTOR);
  }

  function getTaskbarItems() {
    return document.querySelector(TASKBAR_ITEMS_SELECTOR);
  }

  function getWorkspaceStash() {
    return document.querySelector(WORKSPACE_STASH_SELECTOR);
  }

  function getSnapAssistant() {
    return document.querySelector(SNAP_ASSISTANT_SELECTOR);
  }

  function getSnapAssistantOptions() {
    return document.querySelector(SNAP_ASSISTANT_OPTIONS_SELECTOR);
  }

  function getGridViewportMetrics() {
    const gridElement = getGridElement();
    const gridColumn = gridElement && gridElement.parentElement ? gridElement.parentElement : null;
    const main = gridColumn && gridColumn.parentElement ? gridColumn.parentElement : null;
    const source = gridColumn || main;
    const rect = source && source.getBoundingClientRect ? source.getBoundingClientRect() : null;
    return {
      width: Math.max(0, Math.floor((rect && rect.width) || window.innerWidth || 0)),
      height: Math.max(0, Math.floor((rect && rect.height) || window.innerHeight || 0)),
    };
  }

  function getWidgetNode(widgetId) {
    const id = String(widgetId || "").trim();
    return id ? document.getElementById(id) : null;
  }

  function writeGridPositionAttrs(widgetNode, layoutItem) {
    if (!widgetNode || !layoutItem) {
      return;
    }
    widgetNode.setAttribute("gs-id", String(widgetNode.id || ""));
    ["x", "y", "w", "h"].forEach(function (key) {
      const value = Number(layoutItem[key]);
      if (!Number.isFinite(value)) {
        return;
      }
      const attr = "gs-" + key;
      if ((key === "w" || key === "h") && value <= 1) {
        widgetNode.removeAttribute(attr);
        return;
      }
      widgetNode.setAttribute(attr, String(value));
    });
  }

  function syncKnownWidgetOrder() {
    const ordered = workspaceState.order.filter(function (widgetId, index, items) {
      return !!widgetId && items.indexOf(widgetId) === index && hasWidget(widgetId);
    });
    toArray(document.querySelectorAll(".grid-stack-item[id]")).forEach(function (node) {
      if (!ordered.includes(node.id)) {
        ordered.push(node.id);
      }
    });
    workspaceState.order = ordered;
    return ordered;
  }

  function getVisibleWidgetNodes() {
    const gridElement = getGridElement();
    return syncKnownWidgetOrder()
      .map(getWidgetNode)
      .filter(function (node) {
        return !!(node && node.parentElement === gridElement);
      });
  }

  function getVisibleWidgetIds() {
    return getVisibleWidgetNodes().map(function (node) {
      return node.id;
    });
  }

  function hasWidget(widgetId) {
    return !!getWidgetNode(widgetId);
  }

  function getAnchorWidgetId(visibleIds) {
    const ids = Array.isArray(visibleIds) && visibleIds.length
      ? visibleIds.map(function (value) {
          return String(value || "").trim();
        })
      : getVisibleWidgetIds();
    const explicitAnchorId = String(workspaceState.anchorWidgetId || "").trim();
    if (
      explicitAnchorId
      && ids.includes(explicitAnchorId)
      && !workspaceState.minimized.has(explicitAnchorId)
    ) {
      return explicitAnchorId;
    }
    return "";
  }

  function executeWidgetScript(scriptNode) {
    if (!scriptNode) {
      return;
    }
    const replacement = document.createElement("script");
    toArray(scriptNode.attributes).forEach(function (attribute) {
      replacement.setAttribute(attribute.name, attribute.value);
    });
    replacement.text = scriptNode.textContent || "";
    document.body.appendChild(replacement);
    replacement.remove();
    scriptNode.remove();
  }

  function parseAssetList(value) {
    return String(value || "")
      .split("|")
      .map(function (item) {
        return String(item || "").trim();
      })
      .filter(Boolean);
  }

  function findStylesheet(href) {
    return toArray(document.querySelectorAll('link[rel="stylesheet"]')).find(
      function (node) {
        return node.getAttribute("href") === href;
      }
    );
  }

  function findScript(src) {
    return toArray(document.querySelectorAll("script[src]")).find(function (node) {
      return node.getAttribute("src") === src;
    });
  }

  function ensureStylesheet(href) {
    if (!href) {
      return Promise.resolve(null);
    }
    if (assetPromises.styles[href]) {
      return assetPromises.styles[href];
    }
    const existing = findStylesheet(href);
    if (existing) {
      assetPromises.styles[href] = Promise.resolve(existing);
      return assetPromises.styles[href];
    }
    assetPromises.styles[href] = new Promise(function (resolve) {
      const node = document.createElement("link");
      node.rel = "stylesheet";
      node.href = href;
      node.addEventListener(
        "load",
        function () {
          resolve(node);
        },
        { once: true }
      );
      node.addEventListener(
        "error",
        function () {
          resolve(node);
        },
        { once: true }
      );
      document.head.appendChild(node);
    });
    return assetPromises.styles[href];
  }

  function ensureScript(src) {
    if (!src) {
      return Promise.resolve(null);
    }
    if (assetPromises.scripts[src]) {
      return assetPromises.scripts[src];
    }
    const existing = findScript(src);
    if (existing) {
      assetPromises.scripts[src] = Promise.resolve(existing);
      return assetPromises.scripts[src];
    }
    assetPromises.scripts[src] = new Promise(function (resolve) {
      const node = document.createElement("script");
      node.src = src;
      node.async = false;
      node.addEventListener(
        "load",
        function () {
          resolve(node);
        },
        { once: true }
      );
      node.addEventListener(
        "error",
        function () {
          resolve(node);
        },
        { once: true }
      );
      document.head.appendChild(node);
    });
    return assetPromises.scripts[src];
  }

  function ensureContainerAssets(container) {
    if (!container) {
      return Promise.resolve();
    }
    const styleHrefs = parseAssetList(container.getAttribute("data-gia-style-hrefs"));
    const scriptSrcs = parseAssetList(container.getAttribute("data-gia-script-srcs"));
    const styleTasks = styleHrefs.map(function (href) {
      return ensureStylesheet(href);
    });
    const scriptChain = scriptSrcs.reduce(function (promise, src) {
      return promise.then(function () {
        return ensureScript(src);
      });
    }, Promise.resolve());
    return Promise.all(styleTasks).then(function () {
      return scriptChain;
    });
  }

  function getWidgetTitle(widgetNode) {
    if (!widgetNode) {
      return "Window";
    }
    const heading = widgetNode.querySelector(".gia-widget-title");
    const title = String(heading ? heading.textContent || "" : "").trim();
    return title || "Window";
  }

  function getWidgetIconClass(widgetNode) {
    if (!widgetNode) {
      return "fa-solid fa-window-maximize";
    }
    const icon = widgetNode.querySelector(".gia-widget-heading-icon i");
    const value = String(icon ? icon.className || "" : "").trim();
    return value || "fa-solid fa-window-maximize";
  }

  function getWidgetMeta(widgetId) {
    const node = getWidgetNode(widgetId);
    const minimizedMeta = workspaceState.minimized.get(widgetId) || null;
    return {
      id: widgetId,
      node: node,
      minimized: workspaceState.minimized.has(widgetId),
      title: minimizedMeta && minimizedMeta.title
        ? String(minimizedMeta.title)
        : getWidgetTitle(node),
      iconClass: minimizedMeta && minimizedMeta.iconClass
        ? String(minimizedMeta.iconClass)
        : getWidgetIconClass(node),
    };
  }

  function normalizeComposeWidgetSegment(value) {
    const cleaned = String(value || "")
      .trim()
      .toLowerCase()
      .replace(/[^a-z0-9]+/g, "-")
      .replace(/^-+|-+$/g, "");
    return cleaned || "none";
  }

  function buildComposeWidgetIdFromUrl(urlValue) {
    const raw = String(urlValue || "").trim();
    if (!raw) {
      return "";
    }
    try {
      const parsed = new URL(raw, window.location.origin);
      if (!/\/compose\/widget\/?$/.test(parsed.pathname)) {
        return "";
      }
      const service = normalizeComposeWidgetSegment(parsed.searchParams.get("service"));
      const identifier = normalizeComposeWidgetSegment(
        String(parsed.searchParams.get("identifier") || "").split("@", 1)[0]
      );
      const person = normalizeComposeWidgetSegment(parsed.searchParams.get("person"));
      return ["widget", "compose-widget", service, identifier, person].join("-");
    } catch (_err) {
      return "";
    }
  }

  function getWidgetUrlFromTrigger(trigger) {
    if (!trigger || typeof trigger.getAttribute !== "function") {
      return "";
    }
    return String(
      trigger.getAttribute("data-widget-url")
      || trigger.getAttribute("hx-get")
      || ""
    ).trim();
  }

  function getRequestedWidgetIdFromTrigger(trigger) {
    if (!trigger || typeof trigger.getAttribute !== "function") {
      return "";
    }
    const explicitId = String(trigger.getAttribute("data-gia-widget-id") || "").trim();
    if (explicitId) {
      return explicitId;
    }
    return buildComposeWidgetIdFromUrl(getWidgetUrlFromTrigger(trigger));
  }

  function clearPendingWidgetRequest(trigger) {
    if (!trigger || !trigger.dataset) {
      return;
    }
    const widgetId = String(trigger.dataset.giaPendingWidgetId || "").trim();
    if (widgetId) {
      workspaceState.pendingWidgetIds.delete(widgetId);
    }
    delete trigger.dataset.giaPendingWidgetId;
  }

  function activateExistingWidget(widgetId) {
    const id = String(widgetId || "").trim();
    if (!id || !hasWidget(id)) {
      return false;
    }
    if (workspaceState.minimized.has(id)) {
      restoreWidget(id);
    } else {
      setActiveWidget(id);
      syncWidgetChrome();
      renderTaskbar();
    }
    if (window.GIAComposePanel && typeof window.GIAComposePanel.scrollWidgetToLatest === "function") {
      window.GIAComposePanel.scrollWidgetToLatest(id);
    }
    return true;
  }

  function clearSnapAssistant() {
    workspaceState.snapAssistantSourceId = "";
    workspaceState.snapAssistantMode = "";
    const assistant = getSnapAssistant();
    if (assistant) {
      assistant.classList.add("is-hidden");
    }
    const options = getSnapAssistantOptions();
    if (options) {
      options.innerHTML = "";
    }
  }

  function normalizeSnapState() {
    if (
      workspaceState.anchorWidgetId
      && (
        !hasWidget(workspaceState.anchorWidgetId)
        || workspaceState.minimized.has(workspaceState.anchorWidgetId)
      )
    ) {
      workspaceState.anchorWidgetId = "";
    }
    if (!hasWidget(workspaceState.snapLeftId)) {
      workspaceState.snapLeftId = "";
    }
    if (!hasWidget(workspaceState.snapRightId)) {
      workspaceState.snapRightId = "";
    }
    if (!hasWidget(workspaceState.snapTopId)) {
      workspaceState.snapTopId = "";
    }
    if (!hasWidget(workspaceState.snapBottomId)) {
      workspaceState.snapBottomId = "";
    }
    if (workspaceState.snapLeftId && workspaceState.snapLeftId === workspaceState.snapRightId) {
      workspaceState.snapRightId = "";
    }
    if (workspaceState.snapTopId && workspaceState.snapTopId === workspaceState.snapBottomId) {
      workspaceState.snapBottomId = "";
    }
    if (workspaceState.snapTopId || workspaceState.snapBottomId) {
      workspaceState.snapLeftId = "";
      workspaceState.snapRightId = "";
    }
    if (workspaceState.snapLeftId || workspaceState.snapRightId) {
      workspaceState.snapTopId = "";
      workspaceState.snapBottomId = "";
    }
    if (
      workspaceState.snapAssistantSourceId
      && workspaceState.snapAssistantSourceId !== workspaceState.snapLeftId
      && workspaceState.snapAssistantSourceId !== workspaceState.snapTopId
    ) {
      workspaceState.snapAssistantSourceId = "";
      workspaceState.snapAssistantMode = "";
    }
  }

  function getSnapAssistantMeta() {
    if (workspaceState.snapAssistantMode === "vertical") {
      return {
        title: "Snap Bottom",
        message: "Choose a second window for the bottom side.",
      };
    }
    return {
      title: "Snap Right",
      message: "Choose a second window for the right side.",
    };
  }

  function setActiveWidget(widgetId) {
    const id = String(widgetId || "").trim();
    if (!id) {
      return;
    }
    workspaceState.activeWidgetId = id;
    toArray(document.querySelectorAll(".grid-stack-item.is-gia-active")).forEach(
      function (node) {
        node.classList.remove("is-gia-active");
      }
    );
    const widgetNode = getWidgetNode(id);
    if (widgetNode) {
      widgetNode.classList.add("is-gia-active");
    }
    syncWidgetChrome();
    renderTaskbar();
  }

  function syncWidgetChrome() {
    const anchorId = getAnchorWidgetId(syncKnownWidgetOrder());
    toArray(document.querySelectorAll(".grid-stack-item[id]")).forEach(function (node) {
      const widgetId = String(node.id || "").trim();
      const spawned = widgetId && widgetId === workspaceState.lastSpawnedId;
      const gridNode = node.gridstackNode || null;
      const atLeftEdge = !!(
        gridNode
        && Number(gridNode.x || 0) === 0
        && Number(gridNode.w || GRID_COLUMNS) < GRID_COLUMNS
      );
      const atRightEdge = !!(
        gridNode
        && Number((gridNode.x || 0) + (gridNode.w || GRID_COLUMNS)) === GRID_COLUMNS
        && Number(gridNode.w || GRID_COLUMNS) < GRID_COLUMNS
      );
      node.classList.toggle("is-gia-anchor", widgetId === anchorId);
      node.classList.toggle("is-gia-spawned", spawned);
      node.querySelectorAll('.js-gia-widget-action[data-gia-action="snap-left"]').forEach(
        function (button) {
          const icon = button.querySelector("i");
          const label = atLeftEdge ? "Choose window for right side" : "Snap window left";
          button.setAttribute("aria-label", label);
          button.setAttribute("title", label);
          button.classList.toggle("is-link", atLeftEdge);
          if (icon) {
            icon.className = atLeftEdge
              ? "fa-solid fa-table-columns"
              : "fa-solid fa-arrow-left";
          }
        }
      );
      node.querySelectorAll('.js-gia-widget-action[data-gia-action="snap-right"]').forEach(
        function (button) {
          const icon = button.querySelector("i");
          const label = atRightEdge ? "Choose window for left side" : "Snap window right";
          button.setAttribute("aria-label", label);
          button.setAttribute("title", label);
          button.classList.toggle("is-link", atRightEdge);
          if (icon) {
            icon.className = atRightEdge
              ? "fa-solid fa-table-columns"
              : "fa-solid fa-arrow-right";
          }
        }
      );
    });
  }

  function flashSpawnedWidget(widgetNode) {
    if (!widgetNode || !widgetNode.id) {
      return;
    }
    workspaceState.lastSpawnedId = widgetNode.id;
    syncWidgetChrome();
    window.setTimeout(function () {
      if (workspaceState.lastSpawnedId === widgetNode.id) {
        workspaceState.lastSpawnedId = "";
        syncWidgetChrome();
      }
    }, 1800);
  }

  function bindWidgetLifecycle(widgetNode) {
    if (!widgetNode || widgetNode.dataset.giaWidgetBound === "1") {
      return;
    }
    widgetNode.dataset.giaWidgetBound = "1";
    widgetNode.addEventListener("pointerdown", function () {
      setActiveWidget(widgetNode.id);
    });
  }

  function registerWidget(widgetNode, insertIndex) {
    if (!widgetNode || !widgetNode.id) {
      return;
    }
    if (!workspaceState.order.includes(widgetNode.id)) {
      if (typeof insertIndex === "number" && insertIndex >= 0) {
        const boundedIndex = Math.min(insertIndex, workspaceState.order.length);
        workspaceState.order.splice(boundedIndex, 0, widgetNode.id);
      } else {
        workspaceState.order.push(widgetNode.id);
      }
    }
    bindWidgetLifecycle(widgetNode);
    setActiveWidget(widgetNode.id);
  }

  function rememberPendingSpawn(trigger) {
    const sourceWidget = trigger && trigger.closest
      ? trigger.closest(".grid-stack-item[id]")
      : null;
    const sourceId = String(sourceWidget && sourceWidget.id ? sourceWidget.id : "").trim();
    workspaceState.pendingSpawnSourceId = sourceId;
    workspaceState.pendingSpawnTs = Date.now();
    if (sourceId) {
      workspaceState.anchorWidgetId = sourceId;
      syncWidgetChrome();
      renderTaskbar();
    }
  }

  function consumePendingSpawnContext() {
    const sourceId = String(workspaceState.pendingSpawnSourceId || "").trim();
    const spawnTs = Number(workspaceState.pendingSpawnTs || 0);
    workspaceState.pendingSpawnSourceId = "";
    workspaceState.pendingSpawnTs = 0;
    if (!sourceId || (spawnTs > 0 && Date.now() - spawnTs > 15000)) {
      return { sourceId: "" };
    }
    return { sourceId: sourceId };
  }

  function renderTaskbar() {
    const taskbar = getTaskbar();
    const itemsNode = getTaskbarItems();
    if (!taskbar || !itemsNode) {
      return;
    }
    const widgetIds = syncKnownWidgetOrder();
    itemsNode.innerHTML = "";
    if (!widgetIds.length) {
      taskbar.classList.add("is-hidden");
      return;
    }
    widgetIds.forEach(function (widgetId) {
      const widgetNode = getWidgetNode(widgetId);
      const minimized = workspaceState.minimized.has(widgetId);
      const meta = minimized
        ? (workspaceState.minimized.get(widgetId) || {})
        : {
            title: getWidgetTitle(widgetNode),
            iconClass: getWidgetIconClass(widgetNode),
          };
      const item = document.createElement("li");
      if (widgetId === workspaceState.activeWidgetId) {
        item.classList.add("is-active");
      }
      item.classList.add(minimized ? "is-minimized" : "is-open");
      const link = document.createElement("a");
      link.href = "#";
      link.className = "js-gia-taskbar-item";
      link.dataset.giaWidgetId = widgetId;
      link.dataset.giaWidgetState = minimized ? "minimized" : "open";
      link.setAttribute(
        "aria-label",
        (minimized ? "Restore " : "Minimize ") + String(meta.title || "window")
      );
      const iconWrap = document.createElement("span");
      iconWrap.className = "icon is-small";
      const icon = document.createElement("i");
      icon.className = String(meta.iconClass || "fa-solid fa-window-maximize");
      iconWrap.appendChild(icon);
      const label = document.createElement("span");
      label.textContent = String(meta.title || "Window");
      link.appendChild(iconWrap);
      link.appendChild(label);
      item.appendChild(link);
      itemsNode.appendChild(item);
    });
    syncWidgetChrome();
    taskbar.classList.remove("is-hidden");
  }

  function buildSnapAssistantOption(widgetMeta) {
    const button = document.createElement("button");
    button.type = "button";
    button.className = "button is-light js-gia-snap-target";
    button.dataset.giaWidgetId = widgetMeta.id;
    if (widgetMeta.minimized) {
      button.dataset.giaWidgetState = "minimized";
    }
    const leftGroup = document.createElement("span");
    leftGroup.className = "is-inline-flex is-align-items-center";
    const iconWrap = document.createElement("span");
    iconWrap.className = "icon is-small mr-2";
    const icon = document.createElement("i");
    icon.className = widgetMeta.iconClass;
    iconWrap.appendChild(icon);
    const label = document.createElement("span");
    label.textContent = widgetMeta.title;
    leftGroup.appendChild(iconWrap);
    leftGroup.appendChild(label);
    const actionLabel = document.createElement("span");
    actionLabel.textContent = widgetMeta.minimized ? "Restore" : "Use";
    button.appendChild(leftGroup);
    button.appendChild(actionLabel);
    return button;
  }

  function renderSnapAssistant() {
    const assistant = getSnapAssistant();
    const options = getSnapAssistantOptions();
    if (!assistant || !options) {
      return;
    }
    normalizeSnapState();
    const sourceId = workspaceState.snapAssistantSourceId;
    if (!sourceId) {
      clearSnapAssistant();
      return;
    }
    const candidates = syncKnownWidgetOrder().filter(function (widgetId) {
      return widgetId !== sourceId && hasWidget(widgetId);
    });
    if (!candidates.length) {
      clearSnapAssistant();
      return;
    }
    options.innerHTML = "";
    candidates.forEach(function (widgetId) {
      options.appendChild(buildSnapAssistantOption(getWidgetMeta(widgetId)));
    });
    const meta = getSnapAssistantMeta();
    const headingText = assistant.querySelector(".gia-snap-assistant-title");
    if (headingText) {
      headingText.textContent = meta.title;
    }
    const bodyText = assistant.querySelector(".gia-snap-assistant-message");
    if (bodyText) {
      bodyText.textContent = meta.message;
    }
    assistant.classList.remove("is-hidden");
  }

  function getLayoutProfile() {
    const isMobile = window.matchMedia(MOBILE_MEDIA_QUERY).matches;
    const isDesktop = window.matchMedia(DESKTOP_MEDIA_QUERY).matches;
    const viewport = getGridViewportMetrics();
    const canFitQuarterTiles = (
      isDesktop
      && viewport.width >= MIN_QUARTER_TILE_WIDTH * 2
      && viewport.height >= MIN_QUARTER_TILE_HEIGHT * 2
    );
    return {
      isMobile: isMobile,
      isDesktop: isDesktop,
      maxVisible: isMobile ? 1 : canFitQuarterTiles ? 4 : 2,
    };
  }

  function syncGridMetrics() {
    if (!window.grid || typeof window.grid.cellHeight !== "function") {
      return;
    }
    const gridElement = getGridElement();
    if (!gridElement) {
      return;
    }
    const viewport = getGridViewportMetrics();
    const height = Math.max(240, viewport.height || 0);
    const cellHeight = Math.max(32, Math.floor(height / GRID_ROWS));
    gridElement.style.height = height + "px";
    window.grid.cellHeight(cellHeight);
    if (typeof window.grid.setAnimation === "function") {
      window.grid.setAnimation(!window.matchMedia(MOBILE_MEDIA_QUERY).matches);
    }
    if (typeof window.grid.column === "function") {
      window.grid.column(GRID_COLUMNS);
    }
  }

  function buildDefaultLayout(widgetNodes, profile) {
    if (!widgetNodes.length) {
      return [];
    }
    if (profile.isMobile) {
      return [
        {
          node: widgetNodes[0],
          x: 0,
          y: 0,
          w: GRID_COLUMNS,
          h: GRID_ROWS,
        },
      ];
    }
    if (widgetNodes.length === 1) {
      return [
        {
          node: widgetNodes[0],
          x: 0,
          y: 0,
          w: GRID_COLUMNS,
          h: GRID_ROWS,
        },
      ];
    }
    if (!profile.isDesktop) {
      return widgetNodes.slice(0, 2).map(function (node, index) {
        return {
          node: node,
          x: 0,
          y: index * (GRID_ROWS / 2),
          w: GRID_COLUMNS,
          h: GRID_ROWS / 2,
        };
      });
    }
    if (widgetNodes.length === 2) {
      return widgetNodes.map(function (node, index) {
        return {
          node: node,
          x: index * (GRID_COLUMNS / 2),
          y: 0,
          w: GRID_COLUMNS / 2,
          h: GRID_ROWS,
        };
      });
    }
    if (widgetNodes.length === 3) {
      const dominantNode = widgetNodes.find(function (node) {
        return node.id === workspaceState.activeWidgetId;
      }) || widgetNodes[widgetNodes.length - 1];
      const secondaryNodes = widgetNodes.filter(function (node) {
        return node !== dominantNode;
      });
      return [
        {
          node: dominantNode,
          x: 0,
          y: 0,
          w: GRID_COLUMNS / 2,
          h: GRID_ROWS,
        },
        {
          node: secondaryNodes[0],
          x: GRID_COLUMNS / 2,
          y: 0,
          w: GRID_COLUMNS / 2,
          h: GRID_ROWS / 2,
        },
        {
          node: secondaryNodes[1],
          x: GRID_COLUMNS / 2,
          y: GRID_ROWS / 2,
          w: GRID_COLUMNS / 2,
          h: GRID_ROWS / 2,
        },
      ];
    }
    return widgetNodes.slice(0, 4).map(function (node, index) {
      return {
        node: node,
        x: (index % 2) * (GRID_COLUMNS / 2),
        y: Math.floor(index / 2) * (GRID_ROWS / 2),
        w: GRID_COLUMNS / 2,
        h: GRID_ROWS / 2,
      };
    });
  }

  function buildWorkspaceLayoutItems(widgetNodes, profile) {
    const snappedLayout = buildSnappedLayout(profile);
    const anchoredLayout = snappedLayout ? null : buildAnchoredLayout(widgetNodes, profile);
    return snappedLayout || anchoredLayout || buildDefaultLayout(widgetNodes, profile);
  }

  function buildIncomingLayout(widgetNode, spawnSourceId) {
    if (!widgetNode) {
      return null;
    }
    const sourceId = String(spawnSourceId || "").trim();
    const profile = getLayoutProfile();
    const existingNodes = getVisibleWidgetNodes().filter(function (node) {
      return node.id !== widgetNode.id;
    });
    let widgetNodes = existingNodes.slice();
    if (sourceId) {
      const sourceIndex = widgetNodes.findIndex(function (node) {
        return node.id === sourceId;
      });
      if (sourceIndex >= 0) {
        widgetNodes.splice(sourceIndex + 1, 0, widgetNode);
      } else {
        widgetNodes.push(widgetNode);
      }
    } else {
      widgetNodes.push(widgetNode);
    }
    const previousSpawnedId = workspaceState.lastSpawnedId;
    if (sourceId && sourceId !== widgetNode.id) {
      workspaceState.lastSpawnedId = widgetNode.id;
    }
    const layoutItems = buildWorkspaceLayoutItems(widgetNodes, profile);
    workspaceState.lastSpawnedId = previousSpawnedId;
    return layoutItems.find(function (item) {
      return item && item.node === widgetNode;
    }) || null;
  }

  function buildAnchoredLayout(widgetNodes, profile) {
    if (!widgetNodes.length || widgetNodes.length < 2) {
      return null;
    }
    const anchorId = getAnchorWidgetId(
      widgetNodes.map(function (node) {
        return node.id;
      })
    );
    if (!anchorId) {
      return null;
    }
    const anchorNode = widgetNodes.find(function (node) {
      return node.id === anchorId;
    });
    if (!anchorNode) {
      return null;
    }
    let secondaryNodes = widgetNodes.filter(function (node) {
      return node.id !== anchorId;
    });
    const spawnedIndex = secondaryNodes.findIndex(function (node) {
      return node.id === workspaceState.lastSpawnedId;
    });
    if (spawnedIndex > 0) {
      secondaryNodes = [secondaryNodes[spawnedIndex]].concat(
        secondaryNodes.filter(function (_node, index) {
          return index !== spawnedIndex;
        })
      );
    }
    if (!secondaryNodes.length) {
      return null;
    }
    if (profile.isMobile || !profile.isDesktop) {
      return [
        {
          node: anchorNode,
          x: 0,
          y: 0,
          w: GRID_COLUMNS,
          h: GRID_ROWS / 2,
        },
        {
          node: secondaryNodes[0],
          x: 0,
          y: GRID_ROWS / 2,
          w: GRID_COLUMNS,
          h: GRID_ROWS / 2,
        },
      ];
    }
    const stackedNodes = secondaryNodes.slice(0, 3);
    const layoutItems = [
      {
        node: anchorNode,
        x: 0,
        y: 0,
        w: GRID_COLUMNS / 2,
        h: GRID_ROWS,
      },
    ];
    const baseHeight = Math.floor(GRID_ROWS / stackedNodes.length);
    let offsetY = 0;
    stackedNodes.forEach(function (node, index) {
      const height = index === stackedNodes.length - 1
        ? GRID_ROWS - offsetY
        : baseHeight;
      layoutItems.push({
        node: node,
        x: GRID_COLUMNS / 2,
        y: offsetY,
        w: GRID_COLUMNS / 2,
        h: height,
      });
      offsetY += height;
    });
    return layoutItems;
  }

  function buildSnappedLayout(profile) {
    const gridElement = getGridElement();
    const leftNode = getWidgetNode(workspaceState.snapLeftId);
    const rightNode = getWidgetNode(workspaceState.snapRightId);
    if (
      leftNode
      && rightNode
      && leftNode.parentElement === gridElement
      && rightNode.parentElement === gridElement
      && !profile.isMobile
    ) {
      return [
        {
          node: leftNode,
          x: 0,
          y: 0,
          w: GRID_COLUMNS / 2,
          h: GRID_ROWS,
        },
        {
          node: rightNode,
          x: GRID_COLUMNS / 2,
          y: 0,
          w: GRID_COLUMNS / 2,
          h: GRID_ROWS,
        },
      ];
    }
    const topNode = getWidgetNode(workspaceState.snapTopId);
    const bottomNode = getWidgetNode(workspaceState.snapBottomId);
    if (
      !topNode
      || !bottomNode
      || topNode.parentElement !== gridElement
      || bottomNode.parentElement !== gridElement
    ) {
      return null;
    }
    return [
      {
        node: topNode,
        x: 0,
        y: 0,
        w: GRID_COLUMNS,
        h: GRID_ROWS / 2,
      },
      {
        node: bottomNode,
        x: 0,
        y: GRID_ROWS / 2,
        w: GRID_COLUMNS,
        h: GRID_ROWS / 2,
      },
    ];
  }

  function detachWidgetFromGrid(widgetNode) {
    if (
      widgetNode
      && window.grid
      && typeof window.grid.removeWidget === "function"
      && widgetNode.parentElement === getGridElement()
    ) {
      window.grid.removeWidget(widgetNode, false, false);
    }
  }

  function attachWidgetToGrid(widgetNode) {
    if (!widgetNode || !window.grid || !getGridElement()) {
      return;
    }
    widgetNode.classList.remove("is-hidden");
    if (widgetNode.parentElement !== getGridElement()) {
      getGridElement().appendChild(widgetNode);
    }
    if (typeof window.grid.makeWidget === "function") {
      window.grid.makeWidget(widgetNode);
    }
    if (window.htmx && typeof window.htmx.process === "function") {
      window.htmx.process(widgetNode);
    }
  }

  function chooseFallbackActiveWidget() {
    const visibleIds = getVisibleWidgetIds();
    if (!visibleIds.length) {
      workspaceState.activeWidgetId = "";
      return;
    }
    const anchorId = getAnchorWidgetId(visibleIds);
    workspaceState.activeWidgetId = anchorId || visibleIds[visibleIds.length - 1];
  }

  function minimizeWidget(widgetId, options) {
    const config = options || {};
    const widgetNode = getWidgetNode(widgetId);
    if (!widgetNode || workspaceState.minimized.has(widgetId)) {
      return;
    }
    workspaceState.minimized.set(widgetId, {
      title: getWidgetTitle(widgetNode),
      iconClass: getWidgetIconClass(widgetNode),
      ts: Date.now(),
    });
    if (workspaceState.activeWidgetId === widgetId) {
      chooseFallbackActiveWidget();
    }
    if (workspaceState.lastSpawnedId === widgetId) {
      workspaceState.lastSpawnedId = "";
    }
    if (workspaceState.snapLeftId === widgetId) {
      workspaceState.snapLeftId = "";
      workspaceState.snapRightId = "";
      clearSnapAssistant();
    }
    if (workspaceState.snapRightId === widgetId) {
      workspaceState.snapRightId = "";
      clearSnapAssistant();
    }
    if (workspaceState.snapTopId === widgetId) {
      workspaceState.snapTopId = "";
      workspaceState.snapBottomId = "";
      clearSnapAssistant();
    }
    if (workspaceState.snapBottomId === widgetId) {
      workspaceState.snapBottomId = "";
      clearSnapAssistant();
    }
    if (workspaceState.anchorWidgetId === widgetId) {
      workspaceState.anchorWidgetId = "";
    }
    detachWidgetFromGrid(widgetNode);
    const stash = getWorkspaceStash();
    if (stash) {
      stash.appendChild(widgetNode);
    }
    widgetNode.classList.add("is-hidden");
    renderTaskbar();
    if (!config.skipLayout) {
      layoutWorkspace();
    }
  }

  function restoreWidget(widgetId, options) {
    const config = options || {};
    const widgetNode = getWidgetNode(widgetId);
    if (!widgetNode || !workspaceState.minimized.has(widgetId)) {
      return;
    }
    workspaceState.minimized.delete(widgetId);
    attachWidgetToGrid(widgetNode);
    registerWidget(widgetNode);
    renderTaskbar();
    if (!config.skipLayout) {
      layoutWorkspace();
    }
  }

  function clearWidgetState(widgetId) {
    workspaceState.order = workspaceState.order.filter(function (item) {
      return item !== widgetId;
    });
    workspaceState.minimized.delete(widgetId);
    if (workspaceState.activeWidgetId === widgetId) {
      workspaceState.activeWidgetId = "";
    }
    if (workspaceState.anchorWidgetId === widgetId) {
      workspaceState.anchorWidgetId = "";
    }
    if (workspaceState.lastSpawnedId === widgetId) {
      workspaceState.lastSpawnedId = "";
    }
    if (workspaceState.snapLeftId === widgetId) {
      workspaceState.snapLeftId = "";
    }
    if (workspaceState.snapRightId === widgetId) {
      workspaceState.snapRightId = "";
    }
    if (workspaceState.snapTopId === widgetId) {
      workspaceState.snapTopId = "";
    }
    if (workspaceState.snapBottomId === widgetId) {
      workspaceState.snapBottomId = "";
    }
    if (workspaceState.snapAssistantSourceId === widgetId) {
      clearSnapAssistant();
    }
  }

  function removeWidget(widgetId) {
    const widgetNode = getWidgetNode(widgetId);
    if (!widgetNode) {
      return;
    }
    clearWidgetState(widgetId);
    if (
      window.grid
      && typeof window.grid.removeWidget === "function"
      && widgetNode.parentElement === getGridElement()
    ) {
      window.grid.removeWidget(widgetNode, true, false);
    } else {
      widgetNode.remove();
    }
    chooseFallbackActiveWidget();
    renderTaskbar();
    layoutWorkspace();
  }

  function enforceVisibleLimit(profile) {
    normalizeSnapState();
    const snappedLayout = buildSnappedLayout(profile);
    const anchorId = getAnchorWidgetId(syncKnownWidgetOrder());
    const visibleIds = getVisibleWidgetIds();
    const hardProtectedIds = new Set([anchorId].filter(Boolean));
    const softProtectedIds = new Set(
      [
        workspaceState.activeWidgetId,
        workspaceState.snapLeftId,
        workspaceState.snapRightId,
        workspaceState.snapTopId,
        workspaceState.snapBottomId,
      ].filter(Boolean)
    );
    const anchoredMobileSplit = !snappedLayout && !!anchorId && profile.isMobile;
    const maxVisible = snappedLayout ? 2 : anchoredMobileSplit ? 2 : profile.maxVisible;
    if (visibleIds.length <= maxVisible) {
      return;
    }
    const removableIds = visibleIds.filter(function (widgetId) {
      return !hardProtectedIds.has(widgetId) && !softProtectedIds.has(widgetId);
    });
    while (getVisibleWidgetIds().length > maxVisible && removableIds.length) {
      minimizeWidget(removableIds.shift(), { skipLayout: true });
    }
    const remainingIds = getVisibleWidgetIds();
    while (remainingIds.length > maxVisible) {
      const candidate = remainingIds.find(function (widgetId) {
        return !hardProtectedIds.has(widgetId) && !softProtectedIds.has(widgetId);
      }) || remainingIds.find(function (widgetId) {
        return !hardProtectedIds.has(widgetId);
      });
      if (!candidate) {
        break;
      }
      minimizeWidget(candidate, { skipLayout: true });
      remainingIds.splice(remainingIds.indexOf(candidate), 1);
    }
  }

  function applyLayout(layoutItems) {
    if (!window.grid || !layoutItems.length) {
      return;
    }
    syncGridMetrics();
    layoutItems.forEach(function (item) {
      writeGridPositionAttrs(item.node, item);
    });
    const canLoadAtomically = typeof window.grid.load === "function"
      && layoutItems.every(function (item) {
        return !!(
          item
          && item.node
          && item.node.id
          && item.node.gridstackNode
          && String(item.node.gridstackNode.id || "") === String(item.node.id || "")
        );
      });
    if (canLoadAtomically) {
      window.grid.load(
        layoutItems.map(function (item) {
          return {
            id: item.node.id,
            x: item.x,
            y: item.y,
            w: item.w,
            h: item.h,
          };
        }),
        false
      );
      return;
    }
    if (typeof window.grid.batchUpdate === "function") {
      window.grid.batchUpdate(true);
    }
    layoutItems.forEach(function (item) {
      window.grid.update(item.node, {
        x: item.x,
        y: item.y,
        w: item.w,
        h: item.h,
      });
    });
    if (typeof window.grid.batchUpdate === "function") {
      window.grid.batchUpdate(false);
    }
  }

  function layoutWorkspace() {
    if (!window.grid || !getGridElement()) {
      return;
    }
    normalizeSnapState();
    const profile = getLayoutProfile();
    enforceVisibleLimit(profile);
    renderSnapAssistant();
    const visibleNodes = getVisibleWidgetNodes();
    const layoutItems = buildWorkspaceLayoutItems(visibleNodes, profile);
    applyLayout(layoutItems);
    if (!workspaceState.activeWidgetId && layoutItems.length) {
      setActiveWidget(layoutItems[layoutItems.length - 1].node.id);
    } else if (workspaceState.activeWidgetId) {
      const activeNode = getWidgetNode(workspaceState.activeWidgetId);
      if (activeNode) {
        activeNode.classList.add("is-gia-active");
      }
    }
    renderTaskbar();
  }

  function tileWidget(widgetId) {
    if (!widgetId) {
      return;
    }
    if (workspaceState.snapLeftId === widgetId || workspaceState.snapRightId === widgetId) {
      workspaceState.snapLeftId = "";
      workspaceState.snapRightId = "";
    }
    if (workspaceState.snapTopId === widgetId || workspaceState.snapBottomId === widgetId) {
      workspaceState.snapTopId = "";
      workspaceState.snapBottomId = "";
    }
    if (workspaceState.snapAssistantSourceId === widgetId) {
      clearSnapAssistant();
    }
    setActiveWidget(widgetId);
    layoutWorkspace();
  }

  function getSnapCandidateIds(excludeId, options) {
    const config = options || {};
    const candidates = [];
    const pushCandidate = function (widgetId) {
      const id = String(widgetId || "").trim();
      if (!id || id === excludeId || candidates.includes(id) || !hasWidget(id)) {
        return;
      }
      candidates.push(id);
    };
    const visibleIds = getVisibleWidgetIds().filter(function (widgetId) {
      return widgetId !== excludeId;
    });
    pushCandidate(getAnchorWidgetId(visibleIds));
    pushCandidate(workspaceState.activeWidgetId);
    visibleIds.forEach(pushCandidate);
    if (config.includeMinimized) {
      getLockedWidgetIds().forEach(pushCandidate);
      syncKnownWidgetOrder().forEach(function (widgetId) {
        if (workspaceState.minimized.has(widgetId)) {
          pushCandidate(widgetId);
        }
      });
    }
    return candidates;
  }

  function chooseSnapCandidate(excludeId, options) {
    const candidates = getSnapCandidateIds(excludeId, options);
    return candidates.length ? candidates[0] : "";
  }

  function ensureWidgetVisible(widgetId) {
    const id = String(widgetId || "").trim();
    if (!id) {
      return "";
    }
    if (workspaceState.minimized.has(id)) {
      restoreWidget(id, { skipLayout: true });
    }
    return id;
  }

  function snapWidgetLeft(widgetId) {
    const id = String(widgetId || "").trim();
    if (!id) {
      return;
    }
    const candidates = getSnapCandidateIds(id, { includeMinimized: true });
    workspaceState.snapTopId = "";
    workspaceState.snapBottomId = "";
    workspaceState.snapLeftId = id;
    if (candidates.length === 1) {
      workspaceState.snapRightId = ensureWidgetVisible(candidates[0]);
      clearSnapAssistant();
    } else {
      workspaceState.snapRightId = "";
      workspaceState.snapAssistantSourceId = id;
      workspaceState.snapAssistantMode = "horizontal";
    }
    setActiveWidget(id);
    layoutWorkspace();
  }

  function snapWidgetRight(widgetId) {
    const id = String(widgetId || "").trim();
    if (!id) {
      return;
    }
    if (!workspaceState.snapLeftId || workspaceState.snapLeftId === id) {
      workspaceState.snapLeftId = ensureWidgetVisible(
        chooseSnapCandidate(id, { includeMinimized: true })
      );
    }
    workspaceState.snapTopId = "";
    workspaceState.snapBottomId = "";
    workspaceState.snapRightId = id;
    clearSnapAssistant();
    setActiveWidget(id);
    layoutWorkspace();
  }

  function chooseSnapRight(widgetId) {
    const id = String(widgetId || "").trim();
    if (!id) {
      return;
    }
    ensureWidgetVisible(id);
    workspaceState.snapTopId = "";
    workspaceState.snapBottomId = "";
    workspaceState.snapRightId = id;
    clearSnapAssistant();
    setActiveWidget(id);
    layoutWorkspace();
  }

  function snapWidgetTop(widgetId) {
    const id = String(widgetId || "").trim();
    if (!id) {
      return;
    }
    const partnerId = ensureWidgetVisible(
      chooseSnapCandidate(id, { includeMinimized: true })
    );
    workspaceState.snapLeftId = "";
    workspaceState.snapRightId = "";
    workspaceState.snapTopId = id;
    workspaceState.snapBottomId = partnerId;
    clearSnapAssistant();
    setActiveWidget(id);
    layoutWorkspace();
  }

  function snapWidgetBottom(widgetId) {
    const id = String(widgetId || "").trim();
    if (!id) {
      return;
    }
    const partnerId = ensureWidgetVisible(
      chooseSnapCandidate(id, { includeMinimized: true })
    );
    workspaceState.snapLeftId = "";
    workspaceState.snapRightId = "";
    workspaceState.snapTopId = partnerId;
    workspaceState.snapBottomId = id;
    clearSnapAssistant();
    setActiveWidget(id);
    layoutWorkspace();
  }

  function chooseSnapBottom(widgetId) {
    const id = String(widgetId || "").trim();
    if (!id) {
      return;
    }
    ensureWidgetVisible(id);
    workspaceState.snapLeftId = "";
    workspaceState.snapRightId = "";
    workspaceState.snapBottomId = id;
    clearSnapAssistant();
    setActiveWidget(id);
    layoutWorkspace();
  }

  function replaceExistingWidget(widgetNode) {
    if (!widgetNode || !widgetNode.id) {
      return -1;
    }
    const existingWidget = document.getElementById(widgetNode.id);
    if (!existingWidget) {
      return -1;
    }
    const previousIndex = workspaceState.order.indexOf(widgetNode.id);
    clearWidgetState(widgetNode.id);
    if (
      window.grid
      && typeof window.grid.removeWidget === "function"
      && existingWidget.parentElement === getGridElement()
    ) {
      window.grid.removeWidget(existingWidget, true, false);
    } else {
      existingWidget.remove();
    }
    return previousIndex;
  }

  function processWidgetShell(container) {
    if (!container || container.dataset.giaWidgetProcessed === "1") {
      return Promise.resolve();
    }
    container.dataset.giaWidgetProcessed = "1";
    const spawnContext = consumePendingSpawnContext();
    const widgetNode = container.firstElementChild
      ? container.firstElementChild.cloneNode(true)
      : null;
    if (!widgetNode) {
      container.remove();
      return Promise.resolve();
    }
    const scripts = toArray(widgetNode.querySelectorAll("script"));
    const previousIndex = replaceExistingWidget(widgetNode);
    container.remove();
    if (!window.grid || !getGridElement()) {
      return Promise.resolve();
    }
    const initialLayout = buildIncomingLayout(widgetNode, spawnContext.sourceId);
    if (initialLayout) {
      writeGridPositionAttrs(widgetNode, initialLayout);
    }
    getGridElement().appendChild(widgetNode);
    if (typeof window.grid.makeWidget === "function") {
      window.grid.makeWidget(widgetNode);
    } else if (typeof window.grid.addWidget === "function") {
      window.grid.addWidget(widgetNode);
    }
    if (window.htmx && typeof window.htmx.process === "function") {
      window.htmx.process(widgetNode);
    }
    window.giaEnableWidgetSpawnButtons(widgetNode);
    const liveWidget = widgetNode.id ? document.getElementById(widgetNode.id) : widgetNode;
    if (liveWidget && liveWidget.id) {
      workspaceState.pendingWidgetIds.delete(liveWidget.id);
    }
    let insertIndex = previousIndex;
    if (spawnContext.sourceId && spawnContext.sourceId !== liveWidget.id) {
      const sourceIndex = workspaceState.order.indexOf(spawnContext.sourceId);
      if (sourceIndex >= 0) {
        insertIndex = sourceIndex + 1;
      }
      workspaceState.anchorWidgetId = spawnContext.sourceId;
      liveWidget.dataset.giaSpawnSourceId = spawnContext.sourceId;
    } else {
      delete liveWidget.dataset.giaSpawnSourceId;
    }
    registerWidget(liveWidget, insertIndex);
    return ensureContainerAssets(container).then(function () {
      scripts.forEach(executeWidgetScript);
      if (window.GIAComposePanel && typeof window.GIAComposePanel.initAll === "function") {
        window.GIAComposePanel.initAll(liveWidget);
      }
      if (spawnContext.sourceId && spawnContext.sourceId !== liveWidget.id) {
        flashSpawnedWidget(liveWidget);
      }
      layoutWorkspace();
    });
  }

  function processPendingWidgetShells(root) {
    const scope = withDocumentRoot(root);
    const containers = [];
    if (
      scope !== document
      && typeof scope.matches === "function"
      && scope.matches(WIDGET_SHELL_SELECTOR)
    ) {
      containers.push(scope);
    }
    scope.querySelectorAll(WIDGET_SHELL_SELECTOR).forEach(function (node) {
      containers.push(node);
    });
    widgetShellProcessingChain = widgetShellProcessingChain
      .catch(function () {
        return null;
      })
      .then(function () {
        return containers.reduce(function (promise, containerNode) {
          return promise.then(function () {
            return processWidgetShell(containerNode);
          });
        }, Promise.resolve());
      })
      .finally(function () {
        layoutWorkspace();
        window.giaEnableWidgetSpawnButtons(document);
      });
    return widgetShellProcessingChain;
  }

  function enableFloatingWindowInteractions(windowEl) {
    if (!windowEl || windowEl.dataset.giaWindowInteractive === "1") {
      return;
    }
    windowEl.dataset.giaWindowInteractive = "1";
    windowEl.setAttribute("unmovable", "");
    const heading = windowEl.querySelector(".panel-heading");
    if (!heading) {
      return;
    }
    let dragging = false;
    let startX = 0;
    let startY = 0;
    let startLeft = 0;
    let startTop = 0;

    const onMove = function (event) {
      if (!dragging) {
        return;
      }
      const deltaX = event.clientX - startX;
      const deltaY = event.clientY - startY;
      windowEl.style.left = startLeft + deltaX + "px";
      windowEl.style.top = startTop + deltaY + "px";
      windowEl.style.right = "auto";
      windowEl.style.bottom = "auto";
    };

    const stopDrag = function () {
      dragging = false;
      document.removeEventListener("pointermove", onMove);
      document.removeEventListener("pointerup", stopDrag);
    };

    heading.addEventListener("pointerdown", function (event) {
      if (event.button !== 0) {
        return;
      }
      const interactive = event.target.closest(
        "button, a, input, textarea, select, label, .delete, .icon"
      );
      if (interactive) {
        return;
      }
      const windowRect = windowEl.getBoundingClientRect();
      windowEl.style.position = "fixed";
      startLeft = windowRect.left;
      startTop = windowRect.top;
      startX = event.clientX;
      startY = event.clientY;
      dragging = true;
      document.addEventListener("pointermove", onMove);
      document.addEventListener("pointerup", stopDrag);
      event.preventDefault();
    });
  }

  function positionFloatingWindow(windowEl) {
    if (!windowEl) {
      return;
    }
    const margin = 12;
    const rect = windowEl.getBoundingClientRect();
    const anchor = window.giaWindowAnchor || null;
    windowEl.style.position = "fixed";
    if (!anchor || Date.now() - anchor.ts > 10000) {
      const fallbackLeft = Math.max(margin, Math.round((window.innerWidth - rect.width) / 2));
      const fallbackTop = Math.max(margin, Math.round((window.innerHeight - rect.height) / 2));
      windowEl.style.left = fallbackLeft + "px";
      windowEl.style.top = fallbackTop + "px";
      return;
    }
    const desiredLeftViewport = anchor.left;
    const desiredTopViewport = anchor.bottom + 6;
    const maxLeftViewport = window.innerWidth - rect.width - margin;
    const maxTopViewport = window.innerHeight - rect.height - margin;
    const boundedLeftViewport = Math.max(
      margin,
      Math.min(desiredLeftViewport, maxLeftViewport)
    );
    const boundedTopViewport = Math.max(
      margin,
      Math.min(desiredTopViewport, maxTopViewport)
    );
    windowEl.style.left = boundedLeftViewport + "px";
    windowEl.style.top = boundedTopViewport + "px";
    windowEl.style.right = "auto";
    windowEl.style.bottom = "auto";
    windowEl.style.transform = "none";
    window.giaWindowAnchor = null;
  }

  function handleWidgetAction(action, widgetId) {
    if (!action || !widgetId) {
      return;
    }
    if (action === "close") {
      removeWidget(widgetId);
      return;
    }
    if (action === "minimize") {
      minimizeWidget(widgetId);
      return;
    }
    if (action === "tile") {
      tileWidget(widgetId);
      return;
    }
    if (action === "snap-left") {
      snapWidgetLeft(widgetId);
      return;
    }
    if (action === "snap-top") {
      snapWidgetTop(widgetId);
      return;
    }
    if (action === "snap-right") {
      snapWidgetRight(widgetId);
      return;
    }
    if (action === "snap-bottom") {
      snapWidgetBottom(widgetId);
    }
  }

  function initWorkspaceShell() {
    if (window.giaWorkspaceShellInitialised) {
      processPendingWidgetShells(document);
      return;
    }

    const gridElement = document.getElementById("grid-stack-main");
    if (!gridElement || !window.GridStack) {
      return;
    }

    window.giaWorkspaceShellInitialised = true;
    window.gridElement = gridElement;
    window.giaWindowAnchor = null;
    document.body.classList.add("gia-has-workspace");
    document.documentElement.classList.add("gia-has-workspace-root");

    window.giaPrepareWidgetTarget = function () {
      return document.getElementById("widgets-here");
    };

    window.giaCanSpawnWidgets = function () {
      return !!(
        window.grid &&
        typeof window.grid.addWidget === "function" &&
        document.getElementById("widgets-here")
      );
    };

    window.giaEnableWidgetSpawnButtons = function (root) {
      const scope = withDocumentRoot(root);
      const canSpawn = window.giaCanSpawnWidgets();
      scope.querySelectorAll(WIDGET_SPAWN_SELECTOR).forEach(function (button) {
        const widgetUrl = String(
          button.getAttribute("data-widget-url")
          || button.getAttribute("hx-get")
          || ""
        ).trim();
        const visible = canSpawn && !!widgetUrl;
        button.classList.toggle("is-hidden", !visible);
        button.setAttribute("aria-hidden", visible ? "false" : "true");
      });
    };

    window.giaPrepareWindowAnchor = function (trigger) {
      if (!trigger || !trigger.getBoundingClientRect) {
        window.giaWindowAnchor = null;
        return;
      }
      const rect = trigger.getBoundingClientRect();
      window.giaWindowAnchor = {
        left: rect.left,
        right: rect.right,
        top: rect.top,
        bottom: rect.bottom,
        width: rect.width,
        height: rect.height,
        ts: Date.now(),
      };
    };

    window.giaPositionFloatingWindow = positionFloatingWindow;
    window.giaEnableFloatingWindowInteractions = enableFloatingWindowInteractions;
    window.giaCompactGrid = layoutWorkspace;
    window.giaRemoveWidget = removeWidget;
    window.giaMinimizeWidget = minimizeWidget;
    window.giaRestoreWidget = restoreWidget;
    window.giaProcessWidgetShells = processPendingWidgetShells;

    window.grid = window.GridStack.init(
      {
        animate: true,
        auto: false,
        cellHeight: 40,
        column: GRID_COLUMNS,
        float: false,
        margin: 8,
        removable: false,
        staticGrid: true,
      },
      gridElement
    );

    document.addEventListener("click", function (event) {
      const spawnTrigger = event.target.closest(WIDGET_SPAWN_SELECTOR)
        || event.target.closest(WIDGET_LOAD_TARGET_SELECTOR);
      if (spawnTrigger) {
        rememberPendingSpawn(spawnTrigger);
        window.giaPrepareWidgetTarget();
      }

      const widgetAction = event.target.closest(WIDGET_ACTION_SELECTOR);
      if (widgetAction) {
        event.preventDefault();
        event.stopPropagation();
        handleWidgetAction(
          String(widgetAction.dataset.giaAction || ""),
          String(widgetAction.dataset.giaWidgetId || "")
        );
        return;
      }

      const taskbarItem = event.target.closest(".js-gia-taskbar-item");
      if (taskbarItem) {
        event.preventDefault();
        const widgetId = String(taskbarItem.dataset.giaWidgetId || "");
        if (workspaceState.minimized.has(widgetId)) {
          restoreWidget(widgetId);
        } else {
          minimizeWidget(widgetId);
        }
        return;
      }

      const snapTarget = event.target.closest(".js-gia-snap-target");
      if (snapTarget) {
        event.preventDefault();
        if (workspaceState.snapAssistantMode === "vertical") {
          chooseSnapBottom(String(snapTarget.dataset.giaWidgetId || ""));
        } else {
          chooseSnapRight(String(snapTarget.dataset.giaWidgetId || ""));
        }
        return;
      }

      if (event.target.closest(SNAP_ASSISTANT_CLOSE_SELECTOR)) {
        event.preventDefault();
        clearSnapAssistant();
      }
    });

    document.body.addEventListener("htmx:beforeRequest", function (event) {
      const trigger = event && event.detail ? event.detail.elt : null;
      if (!trigger || typeof trigger.getAttribute !== "function") {
        return;
      }
      const target = event.detail ? event.detail.target : null;
      const targetId = String((target && target.id) || trigger.getAttribute("hx-target") || "")
        .replace(/^#/, "")
        .trim();
      if (targetId !== "widgets-here") {
        return;
      }
      const widgetId = getRequestedWidgetIdFromTrigger(trigger);
      if (!widgetId) {
        return;
      }
      if (workspaceState.pendingWidgetIds.has(widgetId) || hasWidget(widgetId)) {
        event.preventDefault();
        activateExistingWidget(widgetId);
        return;
      }
      workspaceState.pendingWidgetIds.add(widgetId);
      trigger.dataset.giaPendingWidgetId = widgetId;
    });

    document.body.addEventListener("htmx:afterRequest", function (event) {
      const trigger = event && event.detail ? event.detail.elt : null;
      if (!trigger || !trigger.dataset || !trigger.dataset.giaPendingWidgetId) {
        return;
      }
      if (event.detail && event.detail.successful) {
        return;
      }
      clearPendingWidgetRequest(trigger);
    });

    document.body.addEventListener("htmx:afterSwap", function (event) {
      const target = (event && event.target) || document;
      window.giaEnableWidgetSpawnButtons(target);
      if (((target && target.id) || "") === "widgets-here") {
        processPendingWidgetShells(target);
        return;
      }
      if (((target && target.id) || "") !== "windows-here") {
        return;
      }
      target.querySelectorAll(".floating-window").forEach(function (floatingWindow) {
        window.setTimeout(function () {
          positionFloatingWindow(floatingWindow);
          enableFloatingWindowInteractions(floatingWindow);
        }, 0);
      });
    });

    document.addEventListener("load-widget", function (event) {
      processPendingWidgetShells(event && event.detail && event.detail.root);
    });
    document.addEventListener("gia:load-widget", function (event) {
      processPendingWidgetShells(event && event.detail && event.detail.root);
    });

    window.addEventListener("resize", function () {
      window.requestAnimationFrame(layoutWorkspace);
    });

    window.giaEnableWidgetSpawnButtons(document);
    processPendingWidgetShells(document);
    window.requestAnimationFrame(layoutWorkspace);
  }

  if (document.readyState === "loading") {
    document.addEventListener("DOMContentLoaded", initWorkspaceShell);
  } else {
    initWorkspaceShell();
  }
})();
