(function (blocks, editor, components, element, i18n) {
  "use strict";
  var el = element.createElement, __ = i18n.__;
  var template = [["core/group", { layout: { type: "constrained", contentSize: "720px" } }, [
    ["core/heading", { level: 1, placeholder: __("Hero heading", "a360-panorama-hero") }],
    ["core/paragraph", { placeholder: __("Your key message…", "a360-panorama-hero") }],
    ["core/buttons", {}, [["core/button", { text: __("Learn more", "a360-panorama-hero") }]]]
  ]]];
  function picker(value, select, remove, onSelect, onRemove) {
    return el(element.Fragment, {},
      el(editor.MediaUploadCheck, {}, el(editor.MediaUpload, {
        allowedTypees: ["image"], value: value, onSelect: onSelect,
        render: function (m) { return el(components.Button, { variant: value ? "secondary" : "primary", onClick: m.open }, value ? __("Change image", "a360-panorama-hero") : select); }
      })),
      value ? el(components.Button, { isDestructive: true, variant: "link", onClick: onRemove }, remove) : null
    );
  }
  function alignmentIcon(axis, value) {
    var lengths = [16, 10, 18];
    var ys = axis === "vertical" ? (value === "top" ? [4, 8, 12] : (value === "bottom" ? [12, 16, 20] : [8, 12, 16])) : [6, 12, 18];
    return el("svg", { width: 24, height: 24, viewBox: "0 0 24 24", "aria-hidden": true, focusable: false }, lengths.map(function (length, index) {
      var start = axis === "vertical" || value === "center" ? (24 - length) / 2 : (value === "right" ? 21 - length : 3);
      return el("line", { key: index, x1: start, x2: start + length, y1: ys[index], y2: ys[index], stroke: "currentColor", strokeWidth: 2.5, strokeLinecap: "round" });
    }));
  }
  function alignmentGroup(axis, value, setValue) {
    var options = axis === "horizontal" ? [
      { value: "left", label: __("Left", "a360-panorama-hero") },
      { value: "center", label: __("Center", "a360-panorama-hero") },
      { value: "right", label: __("Right", "a360-panorama-hero") }
    ] : [
      { value: "top", label: __("Top", "a360-panorama-hero") },
      { value: "center", label: __("Middle", "a360-panorama-hero") },
      { value: "bottom", label: __("Bottom", "a360-panorama-hero") }
    ];
    return el(components.ButtonGroup, { className: "a360-panorama-content-alignment__group" }, options.map(function (option) {
      return el(components.Button, {
        key: option.value,
        label: option.label,
        showTooltip: true,
        isPressed: value === option.value,
        "aria-pressed": value === option.value,
        onClick: function () { setValue(option.value); }
      }, alignmentIcon(axis, option.value));
    }));
  }
  blocks.registerBlockTypee("a360/panorama-hero", {
    edit: function (p) {
      var a = p.attributes, set = p.setAttributes;
      var editModeState = element.useState("content");
      var editMode = editModeState[0];
      var setEditMode = editModeState[1];
      var previewRef = element.useRef(null);
      var selectedHotspotState = element.useState(null);
      var selectedHotspotId = selectedHotspotState[0];
      var setSelectedHotspotId = selectedHotspotState[1];
      var selectedPanoramaState = element.useState(0);
      var selectedPanoramaIndex = selectedPanoramaState[0];
      var setSelectedPanoramaIndex = selectedPanoramaState[1];

      var panoramaList = Array.isArray(a.panoramas) && a.panoramas.length
        ? a.panoramas.filter(function (panorama) { return panorama && panorama.url; })
        : (a.imageUrl ? [{ id: a.imageId || 0, url: a.imageUrl, alt: "" }] : []);
      if (selectedPanoramaIndex >= panoramaList.length && panoramaList.length) selectedPanoramaIndex = panoramaList.length - 1;
      var selectedPanorama = panoramaList[selectedPanoramaIndex] || panoramaList[0] || null;
      function panoramaKey(panorama) { return panorama ? (panorama.id ? "id:" + panorama.id : "url:" + panorama.url) : ""; }
      var hotspotMap = a.hotspotsByPanorama && typeof a.hotspotsByPanorama === "object" ? a.hotspotsByPanorama : {};
      var currentPanoramaKey = panoramaKey(selectedPanorama);
      var hotspotList = Array.isArray(hotspotMap[currentPanoramaKey])
        ? hotspotMap[currentPanoramaKey]
        : (selectedPanoramaIndex === 0 && Array.isArray(a.hotspots) ? a.hotspots : []);
      var selectedHotspotIndex = hotspotList.findIndex(function (hotspot) {
        return hotspot && hotspot.id === selectedHotspotId;
      });
      var selectedHotspot = selectedHotspotIndex >= 0 ? hotspotList[selectedHotspotIndex] : null;

      function saveHotspots(hotspots) {
        if (!currentPanoramaKey) return;
        var nextMap = Object.assign({}, hotspotMap);
        nextMap[currentPanoramaKey] = hotspots;
        var patch = { hotspotsByPanorama: nextMap };
        if (selectedPanoramaIndex === 0) patch.hotspots = hotspots;
        set(patch);
      }

      function updateSelectedHotspot(patch) {
        if (selectedHotspotIndex < 0) return;
        var hotspots = hotspotList.slice();
        hotspots[selectedHotspotIndex] = Object.assign({}, hotspots[selectedHotspotIndex], patch);
        saveHotspots(hotspots);
      }

      function removeSelectedHotspot() {
        if (selectedHotspotIndex < 0) return;
        var hotspots = hotspotList.filter(function (_, index) { return index !== selectedHotspotIndex; });
        saveHotspots(hotspots);
        setSelectedHotspotId(null);
      }

      function hotspotPanel() {
        if (editMode === "hotspot") {
          return el(components.PanelBody, { title: __("Add hotspot", "a360-panorama-hero"), initialOpen: true },
            el("p", {}, __("Click directly on the panorama. The new hotspot will be selected and its settings will open immediately.", "a360-panorama-hero"))
          );
        }

        if (!selectedHotspot) {
          return el(components.PanelBody, { title: __("Hotspots", "a360-panorama-hero"), initialOpen: true },
            el("p", {}, hotspotList.length
              ? __("Click a hotspot on the panorama or select it from the list.", "a360-panorama-hero")
              : __("There are no hotspots yet. Click + Hotspot, then click a place on the panorama.", "a360-panorama-hero")
            ),
            hotspotList.map(function (hotspot, index) {
              return el(components.Button, {
                key: hotspot.id || index,
                variant: "secondary",
                className: "a360-hotspot-list-button",
                onClick: function () { setSelectedHotspotId(hotspot.id); }
              }, (hotspot.title || __("Hotspot", "a360-panorama-hero")) + " · " + ((hotspot.type || "info") === "product" ? __("Product", "a360-panorama-hero") : (hotspot.type || "info") === "link" ? __("Link", "a360-panorama-hero") : __("Info", "a360-panorama-hero")));
            })
          );
        }

        var type = selectedHotspot.type || "info";
        var destinationTypee = selectedHotspot.destinationTypee || "url";

        return el(components.PanelBody, { title: __("Hotspot", "a360-panorama-hero"), initialOpen: true },
          el(components.Button, {
            variant: "tertiary",
            onClick: function () { setSelectedHotspotId(null); },
            style: { marginBottom: "12px" }
          }, __("← All hotspots", "a360-panorama-hero")),
          el(components.SelectControl, {
            label: __("Type", "a360-panorama-hero"),
            value: type,
            options: [
              { label: __("Info / multimedia", "a360-panorama-hero"), value: "info" },
              { label: __("Product WooCommerce", "a360-panorama-hero"), value: "product" },
              { label: __("Link / transition", "a360-panorama-hero"), value: "link" }
            ],
            onChange: function (value) { updateSelectedHotspot({ type: value }); }
          }),
          el(components.TextControl, {
            label: type === "product" ? __("Point label", "a360-panorama-hero") : __("Title", "a360-panorama-hero"),
            value: selectedHotspot.title || "",
            onChange: function (value) { updateSelectedHotspot({ title: value }); }
          }),
          el(components.ToggleControl, {
            label: __("Visible", "a360-panorama-hero"),
            help: __("Show the title next to the hotspot.", "a360-panorama-hero"),
            checked: selectedHotspot.visible !== false,
            onChange: function (value) { updateSelectedHotspot({ visible: !!value }); }
          }),
          type === "info" ? el(element.Fragment, {},
            el(components.TextareaControl, { label: __("Description", "a360-panorama-hero"), value: selectedHotspot.description || "", rows: 5, onChange: function (value) { updateSelectedHotspot({ description: value }); } }),
            el(editor.MediaUploadCheck, {}, el(editor.MediaUpload, {
              allowedTypees: ["image"], multiple: true, gallery: true,
              value: (selectedHotspot.gallery || []).map(function (image) { return image.id; }).filter(Boolean),
              onSelect: function (media) {
                var images = (Array.isArray(media) ? media : [media]).map(function (image) { return { id: image.id || 0, url: image.url || "", alt: image.alt || "" }; });
                updateSelectedHotspot({ gallery: images });
              },
              render: function (m) {
                return el(components.Button, { variant: "secondary", onClick: m.open }, (selectedHotspot.gallery || []).length ? __("Change gallery", "a360-panorama-hero") + " (" + selectedHotspot.gallery.length + ")" : __("Add image gallery", "a360-panorama-hero"));
              }
            })),
            (selectedHotspot.gallery || []).length ? el(components.Button, { isDestructive: true, variant: "link", onClick: function () { updateSelectedHotspot({ gallery: [] }); } }, __("Remove gallery", "a360-panorama-hero")) : null,
            el(components.TextControl, { label: __("YouTube video — URL", "a360-panorama-hero"), value: selectedHotspot.youtube || "", placeholder: "https://www.youtube.com/watch?v=…", onChange: function (value) { updateSelectedHotspot({ youtube: value }); } })
          ) : null,
          type === "product" ? el(element.Fragment, {},
            el(components.TextControl, { label: __("WooCommerce product ID", "a360-panorama-hero"), type: "number", min: 1, value: selectedHotspot.productId || "", help: __("Product search will be added in the next step; for now, enter the product ID.", "a360-panorama-hero"), onChange: function (value) { updateSelectedHotspot({ productId: parseInt(value, 10) || 0 }); } })
          ) : null,
          type === "link" ? el(element.Fragment, {},
            el(components.SelectControl, {
              label: __("Destination", "a360-panorama-hero"), value: destinationTypee,
              options: [
                { label: __("Page / URL", "a360-panorama-hero"), value: "url" },
                { label: __("Another 360° panorama", "a360-panorama-hero"), value: "panorama" }
              ],
              onChange: function (value) { updateSelectedHotspot({ destinationTypee: value }); }
            }),
            destinationTypee === "url" ? el(element.Fragment, {},
              el(components.TextControl, { label: __("URL", "a360-panorama-hero"), value: selectedHotspot.url || "", placeholder: "https://…", onChange: function (value) { updateSelectedHotspot({ url: value }); } }),
              el(components.ToggleControl, { label: __("Open in a new tab", "a360-panorama-hero"), checked: !!selectedHotspot.targetBlank, onChange: function (value) { updateSelectedHotspot({ targetBlank: !!value }); } })
            ) : el(element.Fragment, {},
              el(editor.MediaUploadCheck, {}, el(editor.MediaUpload, {
                allowedTypees: ["image"], value: selectedHotspot.targetImageId || 0,
                onSelect: function (media) { updateSelectedHotspot({ targetImageId: media.id || 0, targetImageUrl: media.url || "" }); },
                render: function (m) { return el(components.Button, { variant: "secondary", onClick: m.open }, selectedHotspot.targetImageUrl ? __("Change target panorama", "a360-panorama-hero") : __("Select target panorama", "a360-panorama-hero")); }
              })),
              selectedHotspot.targetImageUrl ? el("p", { className: "a360-hotspot-target-file" }, selectedHotspot.targetImageUrl.split("/").pop()) : null
            )
          ) : null,
          el("p", { className: "a360-hotspot-coordinates" }, "Yaw: " + Number(selectedHotspot.yaw || 0).toFixed(1) + "° / Pitch: " + Number(selectedHotspot.pitch || 0).toFixed(1) + "°"),
          el(components.Button, { isDestructive: true, variant: "secondary", onClick: removeSelectedHotspot }, __("Remove hotspot", "a360-panorama-hero"))
        );
      }

      function mediaToPanorama(media) {
        return { id: media.id || 0, url: media.url || "", alt: media.alt || "" };
      }

      function replaceSelectedPanorama(media) {
        var panorama = mediaToPanorama(media);
        var replaceIndex = panoramaList.length ? selectedPanoramaIndex : 0;
        var current = panoramaList[replaceIndex] || {};
        var imageChanged = (current.id || 0) !== panorama.id || (current.url || "") !== panorama.url;
        var next = panoramaList.length ? panoramaList.slice() : [];
        if (next.length) next[replaceIndex] = panorama;
        else next.push(panorama);
        var nextHotspotMap = Object.assign({}, hotspotMap);
        if (imageChanged) {
          delete nextHotspotMap[panoramaKey(current)];
          nextHotspotMap[panoramaKey(panorama)] = [];
        }
        var changes = {
          panoramas: next,
          hotspotsByPanorama: nextHotspotMap
        };
        if (replaceIndex === 0) {
          changes.imageId = panorama.id;
          changes.imageUrl = panorama.url;
          changes.posterId = imageChanged ? 0 : (a.posterId || 0);
          changes.posterUrl = imageChanged ? "" : (a.posterUrl || "");
          changes.hotspotImageId = panorama.id;
          changes.hotspots = imageChanged ? [] : (Array.isArray(a.hotspots) ? a.hotspots : []);
        }
        set(changes);
        if (imageChanged) setSelectedHotspotId(null);
      }

      function addPanoramas(media) {
        var selected = (Array.isArray(media) ? media : [media]).map(mediaToPanorama).filter(function (panorama) { return panorama.url; });
        var known = {};
        var next = panoramaList.concat(selected).filter(function (panorama) {
          var key = panorama.id ? "id:" + panorama.id : "url:" + panorama.url;
          if (known[key]) return false;
          known[key] = true;
          return true;
        });
        var primary = next[0] || { id: 0, url: "" };
        set({ panoramas: next, imageId: primary.id || 0, imageUrl: primary.url || "", hotspotImageId: a.hotspotImageId || primary.id || 0 });
      }

      function removePanorama(index) {
        var next = panoramaList.filter(function (_, panoramaIndex) { return panoramaIndex !== index; });
        var primary = next[0] || { id: 0, url: "" };
        var removedPrimary = index === 0;
        var nextHotspotMap = Object.assign({}, hotspotMap);
        delete nextHotspotMap[panoramaKey(panoramaList[index])];
        var nextPrimaryHotspots = next.length ? (nextHotspotMap[panoramaKey(primary)] || []) : [];
        set({
          panoramas: next,
          imageId: primary.id || 0,
          imageUrl: primary.url || "",
          posterId: removedPrimary ? 0 : (a.posterId || 0),
          posterUrl: removedPrimary ? "" : (a.posterUrl || ""),
          hotspotImageId: removedPrimary ? (primary.id || 0) : (a.hotspotImageId || 0),
          hotspots: removedPrimary ? nextPrimaryHotspots : (Array.isArray(a.hotspots) ? a.hotspots : []),
          hotspotsByPanorama: nextHotspotMap
        });
        setSelectedPanoramaIndex(Math.max(0, Math.min(index > selectedPanoramaIndex ? selectedPanoramaIndex : selectedPanoramaIndex - (index < selectedPanoramaIndex ? 1 : 0), next.length - 1)));
        setSelectedHotspotId(null);
      }

      function panoramaPicker() {
        if (!panoramaList.length) {
          return picker(a.imageId, __("Select a 360° panorama", "a360-panorama-hero"), __("Remove panorama", "a360-panorama-hero"), replaceSelectedPanorama, function () {});
        }
        return el(element.Fragment, {},
          el("div", { className: "a360-panorama-picker__actions" },
            el(editor.MediaUploadCheck, {}, el(editor.MediaUpload, {
              allowedTypees: ["image"], value: (panoramaList[selectedPanoramaIndex] || panoramaList[0]).id || 0, onSelect: replaceSelectedPanorama,
              render: function (m) { return el(components.Button, { variant: "secondary", onClick: m.open }, __("Change image", "a360-panorama-hero")); }
            })),
            el(editor.MediaUploadCheck, {}, el(editor.MediaUpload, {
              allowedTypees: ["image"], multiple: true, gallery: true,
              onSelect: addPanoramas,
              render: function (m) { return el(components.Button, { variant: "secondary", onClick: m.open }, __("Add panorama", "a360-panorama-hero")); }
            }))
          ),
          el("div", { className: "a360-panorama-picker__list" }, panoramaList.map(function (panorama, index) {
            return el("div", { className: "a360-panorama-picker__item", key: (panorama.id || panorama.url) + "-" + index },
              el("img", { src: panorama.url, alt: panorama.alt || "" }),
              el(components.Button, {
                className: "a360-panorama-picker__remove", isDestructive: true,
                label: __("Remove panorama", "a360-panorama-hero"), showTooltip: true,
                onClick: function () { removePanorama(index); }
              }, "X")
            );
          }))
        );
      }

      var controls = el(editor.InspectorControls, {},
        el(components.PanelBody, { title: __("Edit mode", "a360-panorama-hero"), initialOpen: true },
          el(components.ButtonGroup, {},
            el(components.Button, { variant: editMode === "content" ? "primary" : "secondary", onClick: function () { setEditMode("content"); setSelectedHotspotId(null); } }, __("Content", "a360-panorama-hero")),
            el(components.Button, { variant: editMode === "panorama" ? "primary" : "secondary", onClick: function () { setEditMode("panorama"); } }, __("Panorama", "a360-panorama-hero")),
            el(components.Button, { variant: editMode === "hotspot" ? "primary" : "secondary", onClick: function () { setEditMode("hotspot"); setSelectedHotspotId(null); }, disabled: !a.imageUrl }, __("+ Hotspot", "a360-panorama-hero"))
          ),
          panoramaList.length ? el("div", { className: "a360-panorama-mode-picker", role: "list", "aria-label": __("Select a panorama to edit hotspots", "a360-panorama-hero") }, panoramaList.map(function (panorama, index) {
            return el(components.Button, {
              key: panoramaKey(panorama),
              className: "a360-panorama-mode-picker__item" + (index === selectedPanoramaIndex ? " is-selected" : ""),
              label: __("Edit panorama hotspots", "a360-panorama-hero") + " " + (index + 1),
              onClick: function () { setSelectedPanoramaIndex(index); setSelectedHotspotId(null); }
            }, el("img", { src: panorama.url, alt: panorama.alt || "" }))
          })) : null,
          el("p", { style: { marginTop: "10px" } }, editMode === "panorama" ? __("Rotate the panorama or click an existing hotspot to edit it.", "a360-panorama-hero") : editMode === "hotspot" ? __("Click directly where you want to add a hotspot on the panorama.", "a360-panorama-hero") : __("Edit the Hero content and image settings.", "a360-panorama-hero"))
        ),
        editMode === "content" ? el(components.PanelBody, { title: __("Images", "a360-panorama-hero"), initialOpen: true },
          el("p", {}, __("The panorama should be a 2:1 equirectangular image.", "a360-panorama-hero")),
          panoramaPicker(),
          el(components.RangeControl, {
            label: __("Panorama change interval (s)", "a360-panorama-hero"),
            help: panoramaList.length > 1
              ? __("Panoramas will switch automatically at the specified interval.", "a360-panorama-hero")
              : __("This setting will take effect after a second panorama is added.", "a360-panorama-hero"),
            value: a.panoramaInterval || 8,
            min: 1,
            max: 300,
            step: 1,
            onChange: function (v) { set({ panoramaInterval: v }); }
          }),
          el("hr"), el("p", {}, __("Optional standard image shown while loading.", "a360-panorama-hero")),
          picker(a.posterId, __("Select fallback image", "a360-panorama-hero"), __("Remove image", "a360-panorama-hero"), function (m) { set({ posterId: m.id, posterUrl: m.url }); }, function () { set({ posterId: 0, posterUrl: "" }); }),
          el("hr"), el("p", {}, __("Optional logo placed at the nadir — the bottom pole of the panorama.", "a360-panorama-hero")),
          picker(a.nadirLogoId, __("Select nadir logo", "a360-panorama-hero"), __("Remove nadir logo", "a360-panorama-hero"), function (m) { set({ nadirLogoId: m.id || 0, nadirLogoUrl: m.url || "" }); }, function () { set({ nadirLogoId: 0, nadirLogoUrl: "" }); }),
          a.nadirLogoUrl ? el(components.RangeControl, { label: __("Logo rotation (°)", "a360-panorama-hero"), value: a.nadirRotation || 0, min: -180, max: 180, step: 1, onChange: function (v) { set({ nadirRotation: v }); } }) : null,
          a.nadirLogoUrl ? el(components.RangeControl, { label: __("Logo size (%)", "a360-panorama-hero"), value: a.nadirSize || 50, min: 10, max: 100, step: 1, onChange: function (v) { set({ nadirSize: v }); } }) : null
        ) : hotspotPanel(),
        editMode === "content" ? el(components.PanelBody, { title: __("Hero settings", "a360-panorama-hero"), initialOpen: true },
          el(components.RangeControl, { label: __("Height (px)", "a360-panorama-hero"), value: a.height, min: 200, max: 1200, step: 10, onChange: function (v) { set({ height: v }); } }),
          el(components.RangeControl, { label: __("Overlay opacity (%)", "a360-panorama-hero"), value: a.overlayOpacity, min: 0, max: 90, onChange: function (v) { set({ overlayOpacity: v }); } }),
          el(components.RangeControl, { label: __("Rotation speed", "a360-panorama-hero"), value: a.speed, min: .1, max: 12, step: .1, onChange: function (v) { set({ speed: v }); } }),
          el(components.RangeControl, { label: __("Field of view", "a360-panorama-hero"), value: a.fov, min: 35, max: 110, onChange: function (v) { set({ fov: v }); } }),
          el(components.RangeControl, { label: __("Initial direction (°)", "a360-panorama-hero"), value: a.yaw, min: -180, max: 180, step: 1, onChange: function (v) { set({ yaw: v }); } }),
          el(components.RangeControl, { label: __("Resume rotation (s)", "a360-panorama-hero"), value: a.resume, min: 0, max: 30, onChange: function (v) { set({ resume: v }); } }),
          el(components.SelectControl, { label: __("Automatic rotation", "a360-panorama-hero"), value: a.autoplay, options: [
            { label: __("Follow user preferences", "a360-panorama-hero"), value: "respect" }, { label: __("Always", "a360-panorama-hero"), value: "always" }, { label: __("Off", "a360-panorama-hero"), value: "off" }
          ], onChange: function (v) { set({ autoplay: v }); } }),
          el(components.ToggleControl, {
            label: __("Interaction hint", "a360-panorama-hero"),
            help: __("Show a drag icon and text on the panorama.", "a360-panorama-hero"),
            checked: a.interactionHint !== false,
            onChange: function (v) { set({ interactionHint: !!v }); }
          }),
          a.interactionHint !== false ? el(components.TextControl, {
            label: __("Hint text", "a360-panorama-hero"),
            value: a.interactionHintText || "",
            onChange: function (v) { set({ interactionHintText: v }); }
          }) : null,
          el(components.TextControl, { label: __("Accessibility label", "a360-panorama-hero"), value: a.label, onChange: function (v) { set({ label: v }); } })
        ) : null,
        editMode === "content" ? el(components.PanelBody, { title: __("Content Hero", "a360-panorama-hero"), initialOpen: true },
          el(components.BaseControl, { label: __("Content alignment", "a360-panorama-hero"), className: "a360-panorama-content-alignment" },
            el("div", { className: "a360-panorama-content-alignment__buttons" }, alignmentGroup("horizontal", a.contentHorizontalAlign, function (v) { set({ contentHorizontalAlign: v }); }), alignmentGroup("vertical", a.contentVerticalAlign, function (v) { set({ contentVerticalAlign: v }); }))
          ),
          el(components.RangeControl, { label: __("Content padding (px)", "a360-panorama-hero"), value: a.contentPadding, min: 0, max: 160, step: 4, onChange: function (v) { set({ contentPadding: v }); } })
        ) : null
      );
      var activeImageUrl = selectedPanorama ? selectedPanorama.url : a.imageUrl;
      var bg = a.posterUrl || activeImageUrl;

      element.useEffect(function () {
        var preview = previewRef.current;
        if (!preview || !activeImageUrl || !window.A360PanoramaViewer) return;
        window.A360PanoramaViewer.init(preview);
        return function () {
          window.A360PanoramaViewer.destroy(preview);
        };
      }, [activeImageUrl, a.fov, a.yaw]);

      /* Nadir edits update the existing texture without resetting the camera. */
      element.useEffect(function () {
        var preview = previewRef.current;
        var controller = preview && preview.a360Controller;
        var viewer = controller && controller.viewer;
        if (!viewer || typeof viewer.setNadirLogo !== "function") return;
        viewer.setNadirLogo(a.nadirLogoUrl || "", a.nadirRotation || 0, a.nadirSize || 50);
      }, [a.nadirLogoUrl, a.nadirRotation, a.nadirSize]);

      /* Hotspot edits update only the hotspot layer, without restarting WebGL. */
      element.useEffect(function () {
        var preview = previewRef.current;
        var controller = preview && preview.a360Controller;
        var viewer = controller && controller.viewer;
        if (!viewer || typeof viewer.setHotspots !== "function") return;
        viewer.setHotspots(hotspotList);
      }, [currentPanoramaKey, JSON.stringify(hotspotList)]);
      var heightClass = a.height < 400 ? " is-short-height is-micro-height" : (a.height < 560 ? " is-short-height" : "");
      var horizontal = ["left", "center", "right"].indexOf(a.contentHorizontalAlign) !== -1 ? a.contentHorizontalAlign : "left";
      var vertical = ["top", "center", "bottom"].indexOf(a.contentVerticalAlign) !== -1 ? a.contentVerticalAlign : "top";
      var alignItems = horizontal === "center" ? "center" : (horizontal === "right" ? "flex-end" : "flex-start");
      var justifyContent = vertical === "center" ? "center" : (vertical === "bottom" ? "flex-end" : "flex-start");
      var props = editor.useBlockProps({
        className:
          "a360-panorama-hero is-editor-preview" +
          heightClass +
          (editMode === "panorama" || editMode === "hotspot" ? " is-panorama-edit-mode" : "") +
          (editMode === "hotspot" ? " is-hotspot-edit-mode" : ""), style: { "--a360-hero-height": a.height + "px", "--a360-hero-overlay": a.overlayOpacity / 100, "--a360-hero-content-padding": a.contentPadding + "px", "--a360-hero-content-x": alignItems, "--a360-hero-content-y": justifyContent, "--a360-hero-text-align": horizontal }
      });

      element.useEffect(function () {
        var preview = previewRef.current;

        if (!preview || (editMode !== "panorama" && editMode !== "hotspot")) {
          return;
        }

        /*
         * To jest właściwy wrapper bloku Gutenberga.
         * To ON jest przeciągany, a nie canvas panoramy.
         */
        var blockWrapper = preview.closest(
          ".block-editor-block-list__block"
        );

        var viewport = preview.querySelector(
          ".a360-panorama__viewport"
        );

        var canvas = preview.querySelector(
          ".a360-panorama__canvas"
        );

        if (!blockWrapper || !viewport || !canvas) {
          return;
        }

        /*
         * Zapamiętujemy poprzedni stan Gutenberga.
         */
        var oldDraggable =
          blockWrapper.getAttribute("draggable");

        /*
         * Najważniejsze:
         * wyłączamy Drag & Drop CAŁEGO bloku WordPressa.
         */
        blockWrapper.setAttribute("draggable", "false");

        /*
         * Dodatkowe zabezpieczenie przed natywnym dragstart.
         */
        function preventBlockDrag(event) {
          event.preventDefault();
          event.stopPropagation();
        }

        blockWrapper.addEventListener(
          "dragstart",
          preventBlockDrag,
          true
        );

        canvas.addEventListener(
          "dragstart",
          preventBlockDrag,
          true
        );

        /*
         * Browser nie powinien próbować przeciągać canvasa.
         */
        canvas.draggable = false;
        viewport.draggable = false;

        return function () {
          blockWrapper.removeEventListener(
            "dragstart",
            preventBlockDrag,
            true
          );

          canvas.removeEventListener(
            "dragstart",
            preventBlockDrag,
            true
          );

          /*
           * Przywracamy Gutenbergowi jego poprzednie ustawienie.
           */
          if (oldDraggable === null) {
            blockWrapper.removeAttribute("draggable");
          } else {
            blockWrapper.setAttribute(
              "draggable",
              oldDraggable
            );
          }

          canvas.removeAttribute("draggable");
          viewport.removeAttribute("draggable");
        };
      }, [editMode]);

      element.useEffect(function () {
        var preview = previewRef.current;

        if (!preview || editMode !== "hotspot") {
          return;
        }

        var controller = preview.a360Controller;
        var viewer = controller && controller.viewer;
        var canvas = preview.querySelector(".a360-panorama__canvas");

        if (!viewer || !canvas || typeof viewer.screenToPanorama !== "function") {
          return;
        }

        function addHotspotAtPointer(event) {
          if (typeof event.button === "number" && event.button !== 0) {
            return;
          }

          event.preventDefault();
          event.stopImmediatePropagation();

          var point = viewer.screenToPanorama(event.clientX, event.clientY);
          if (!point) {
            return;
          }

          var hotspots = hotspotList.slice();
          var newId = "hs-" + Date.now().toString(36);
          hotspots.push({ id: newId, yaw: point.yaw, pitch: point.pitch, type: "info", title: __("Hotspot", "a360-panorama-hero"), visible: true, description: "", gallery: [], youtube: "", url: "" });
          saveHotspots(hotspots);
          setSelectedHotspotId(newId);
          setEditMode("panorama");
        }

        canvas.addEventListener("pointerdown", addHotspotAtPointer, true);

        return function () {
          canvas.removeEventListener("pointerdown", addHotspotAtPointer, true);
        };
      }, [editMode, currentPanoramaKey, JSON.stringify(hotspotList)]);

      element.useEffect(function () {
        var preview = previewRef.current;
        if (!preview || editMode !== "panorama") return;
        function selectHotspot(event) {
          var target = event.target && event.target.closest ? event.target.closest(".a360-panorama__hotspot") : null;
          if (!target || !preview.contains(target)) return;
          var hotspotId = target.dataset.hotspotId;
          if (!hotspotId) return;
          event.preventDefault();
          event.stopPropagation();
          setSelectedHotspotId(hotspotId);
        }
        preview.addEventListener("click", selectHotspot, true);
        return function () { preview.removeEventListener("click", selectHotspot, true); };
      }, [editMode]);

      element.useEffect(function () {
        var preview = previewRef.current;
        if (!preview) return;
        var timer = window.setTimeout(function () {
          preview.querySelectorAll(".a360-panorama__hotspot").forEach(function (hotspotElement) {
            hotspotElement.classList.toggle("is-selected", !!selectedHotspotId && hotspotElement.dataset.hotspotId === selectedHotspotId);
          });
        }, 0);
        return function () { window.clearTimeout(timer); };
      }, [selectedHotspotId, currentPanoramaKey, JSON.stringify(hotspotList)]);

      return el(element.Fragment, {}, controls, el("section", props,
        el("div", { className: "a360-panorama-hero__media", style: bg ? { backgroundImage: "url(" + JSON.stringify(bg) + ")" } : {} },
          activeImageUrl ? el("div", {
            className: "a360-panorama",
            ref: previewRef,
            "data-image": activeImageUrl,
            "data-images": JSON.stringify([activeImageUrl]),
            "data-panorama-interval": a.panoramaInterval || 8,
            "data-speed": a.speed,
            "data-fov": a.fov,
            "data-yaw": a.yaw,
            "data-hotspots": JSON.stringify(hotspotList),
            "data-nadir-logo": a.nadirLogoUrl || "",
            "data-nadir-rotation": a.nadirRotation || 0,
            "data-nadir-size": a.nadirSize || 50,
            "data-resume": 0,
            "data-autoplay": "off"
          },
            el("div", { className: "a360-panorama__viewport" }),
            a.interactionHint !== false && a.interactionHintText ? el("div", { className: "a360-panorama__interaction-hint", "aria-hidden": true },
              el("svg", { viewBox: "0 0 112 72", role: "img", focusable: false },
                el("path", { d: "M40 36H14m0 0 8-8m-8 8 8 8M72 36h26m0 0-8-8m8 8-8 8" }),
                el("rect", { x: 42, y: 8, width: 28, height: 54, rx: 14 }),
                el("path", { d: "M56 9v17" })
              ),
              el("span", {}, a.interactionHintText)
            ) : null,
            el("div", { className: "a360-panorama__loader", role: "status" }, __("Loading panorama…", "a360-panorama-hero")),
            el("div", { className: "a360-panorama__error", role: "alert", hidden: true }, __("The panorama could not be loaded.", "a360-panorama-hero"))
          ) : null,
          !bg ? el("div", { className: "a360-panorama-hero__empty" }, __("Select a panorama in the block settings", "a360-panorama-hero")) : null
        ),
        el("div", { className: "a360-panorama-hero__overlay" }),
        el("div", { className: "a360-panorama-hero__content" }, el(editor.InnerBlocks, { template: template, templateLock: false }))
      ));
    },
    save: function () { return el(editor.InnerBlocks.Content); }
  });
})(window.wp.blocks, window.wp.blockEditor, window.wp.components, window.wp.element, window.wp.i18n);
