(function() {
  var useState  = React.useState;
  var useEffect = React.useEffect;
  var useRef    = React.useRef;

  function ImageLightbox(props) {
    var src = props.src;
    var alt = props.alt || 'Full screen preview';
    var onClose = props.onClose;
    var wrapRef = useRef(null);

    useEffect(function() {
      function onKey(e) {
        if (e.key === 'Escape') onClose && onClose();
      }
      document.addEventListener('keydown', onKey);
      var prev = document.body.style.overflow;
      document.body.style.overflow = 'hidden';
      return function() {
        document.removeEventListener('keydown', onKey);
        document.body.style.overflow = prev;
      };
    }, [onClose]);

    if (!src) return null;

    return React.createElement('div', {
      className: 'cb-lightbox',
      role: 'dialog',
      'aria-modal': 'true',
      'aria-label': alt,
      ref: wrapRef,
      onClick: function(e) {
        if (e.target === wrapRef.current) onClose && onClose();
      },
    },
      React.createElement('button', {
        type: 'button',
        className: 'cb-lightbox-close',
        'aria-label': 'Close',
        onClick: onClose,
        onMouseEnter: function(){ document.body.classList.add('hov'); },
        onMouseLeave: function(){ document.body.classList.remove('hov'); },
      }, '✕'),
      React.createElement('img', {
        className: 'cb-lightbox-img',
        src: src,
        alt: alt,
        onClick: function(e){ e.stopPropagation(); },
      }),
      React.createElement('div', { className: 'cb-lightbox-caption' }, alt)
    );
  }

  /** Clickable image that opens fullscreen lightbox. */
  function ZoomableImage(props) {
    var _open = useState(false);
    var open = _open[0], setOpen = _open[1];
    var src = props.src;
    var alt = props.alt || '';
    var className = props.className || '';
    var style = props.style || null;

    if (!src) return null;

    return React.createElement(React.Fragment, null,
      React.createElement('button', {
        type: 'button',
        className: 'cb-zoomable ' + className,
        style: style,
        onClick: function(){ setOpen(true); },
        onMouseEnter: function(){ document.body.classList.add('hov'); },
        onMouseLeave: function(){ document.body.classList.remove('hov'); },
        'aria-label': (alt ? alt + ' — ' : '') + 'View full screen',
      },
        React.createElement('img', {
          src: src,
          alt: alt,
          className: props.imgClassName || '',
          style: props.imgStyle || { width: '100%', height: '100%', objectFit: 'cover', display: 'block' },
          draggable: false,
        }),
        React.createElement('span', { className: 'cb-zoomable-hint', 'aria-hidden': 'true' }, '⤢')
      ),
      open && React.createElement(ImageLightbox, {
        src: src,
        alt: alt,
        onClose: function(){ setOpen(false); },
      })
    );
  }

  window.ImageLightbox = ImageLightbox;
  window.ZoomableImage = ZoomableImage;
  window.openImageLightbox = function(src, alt) {
    // Imperative helper for non-React call sites
    var root = document.getElementById('cb-lightbox-root');
    if (!root) {
      root = document.createElement('div');
      root.id = 'cb-lightbox-root';
      document.body.appendChild(root);
    }
    function close() {
      if (window.ReactDOM && window.ReactDOM.unmountComponentAtNode) {
        window.ReactDOM.unmountComponentAtNode(root);
      } else {
        root.innerHTML = '';
      }
    }
    if (window.ReactDOM && window.ReactDOM.render) {
      window.ReactDOM.render(
        React.createElement(ImageLightbox, { src: src, alt: alt || '', onClose: close }),
        root
      );
    }
  };
})();
