"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);

// src/Tile.ts
var Tile_exports = {};
__export(Tile_exports, {
  TILE_ATTRIBUTES: () => TILE_ATTRIBUTES,
  default: () => Tile
});
module.exports = __toCommonJS(Tile_exports);

// ../slider/dist/esm/effects/tile/tile-slider.js
function applyCss(el, styles) {
  Object.keys(styles).forEach((key) => el.style.setProperty(key, styles[key]));
}
var TILE_CLASS = "bs-tile";
var FRONT_FACE_CLASS = "bs-tile-front";
var BACK_FACE_CLASS = "bs-tile-back";
var FadeTransition = class {
  createTile(tileSettings) {
    const tile = document.createElement("div");
    const front = document.createElement("div");
    const back = document.createElement("div");
    const faces = [front, back];
    tile.classList.add(tileSettings.tileClass);
    applyCss(tile, {
      height: `${tileSettings.height}px`,
      left: `${tileSettings.fromLeft}px`,
      overflow: "hidden",
      position: "absolute",
      top: `${tileSettings.fromTop}px`,
      width: `${tileSettings.width}px`
    });
    faces.forEach((face) => {
      applyCss(face, {
        height: `${tileSettings.boxHeight}px`,
        left: `-${tileSettings.fromLeft}px`,
        position: "absolute",
        top: `-${tileSettings.fromTop}px`,
        transition: "opacity 400ms",
        width: `${tileSettings.boxWidth}px`
      });
    });
    applyCss(back, { opacity: "0" });
    front.classList.add(tileSettings.frontClass);
    tile.appendChild(front);
    back.classList.add(tileSettings.backClass);
    tile.appendChild(back);
    return tile;
  }
  transition(tile, nextFace) {
    const front = tile.querySelector(`.${FRONT_FACE_CLASS}`);
    const back = tile.querySelector(`.${BACK_FACE_CLASS}`);
    applyCss(front, { opacity: nextFace === "front" ? "1" : "0" });
    applyCss(back, { opacity: nextFace === "front" ? "0" : "1" });
  }
  setTileFace(slide, tileFace) {
    const clone = slide.cloneNode(true);
    clone.removeAttribute("style");
    tileFace.replaceChildren(clone);
  }
};
var fade_transition_default = FadeTransition;
var FlipTransition = class {
  createTile(tileSettings) {
    const tileHolder = document.createElement("div");
    const tile = document.createElement("div");
    const front = document.createElement("div");
    const frontFace = document.createElement("div");
    const back = document.createElement("div");
    const backFace = document.createElement("div");
    const faces = [frontFace, backFace];
    applyCss(tileHolder, {
      height: `${tileSettings.height}px`,
      left: `${tileSettings.fromLeft}px`,
      perspective: "300px",
      position: "absolute",
      top: `${tileSettings.fromTop}px`,
      width: `${tileSettings.width}px`,
      "z-index": `${tileSettings.zIndex}`
    });
    tile.classList.add(tileSettings.tileClass);
    applyCss(tile, {
      height: "100%",
      position: "relative",
      "transform-style": "preserve-3d",
      transition: `transform ${tileSettings.speed}ms`,
      width: "100%"
    });
    tileHolder.appendChild(tile);
    faces.forEach(
      (face) => applyCss(face, {
        height: `${tileSettings.boxHeight}px`,
        left: `-${tileSettings.fromLeft}px`,
        position: "absolute",
        top: `-${tileSettings.fromTop}px`,
        width: `${tileSettings.boxWidth}px`
      })
    );
    applyCss(front, {
      "backface-visibility": "hidden",
      inset: "0",
      overflow: "clip",
      position: "absolute"
    });
    applyCss(back, {
      "backface-visibility": "hidden",
      inset: "0",
      overflow: "clip",
      position: "absolute",
      transform: "rotateY(180deg)"
    });
    front.appendChild(frontFace);
    front.classList.add(tileSettings.frontClass);
    tile.appendChild(front);
    back.appendChild(backFace);
    back.classList.add(tileSettings.backClass);
    tile.appendChild(back);
    return tileHolder;
  }
  transition(tile, nextFace) {
    applyCss(tile, {
      transform: `rotateY(${nextFace === "back" ? 180 : 0}deg)`
    });
  }
  setTileFace(slide, tileFace) {
    const clone = slide.cloneNode(true);
    clone.removeAttribute("style");
    tileFace.firstChild.replaceChildren(clone);
  }
};
var flip_transition_default = FlipTransition;
var defaultOptions = {
  tileEffect: "flip",
  rows: 8,
  rowOffset: 50
};
var SLIDE_STYLES = [
  "position",
  "clip",
  "height",
  "width",
  "margin",
  "padding",
  "border"
];
var BOX_STYLES = ["height", "position"];
var TileSlider = class {
  rowCount;
  rowOffset;
  tileEffect;
  _tileWrapper;
  tileTransition;
  grid;
  activeFace;
  rowTimers = [];
  tileTimers = [];
  get tileWrapper() {
    if (this._tileWrapper === void 0) {
      throw new Error("TileWrapper is undefined");
    }
    return this._tileWrapper;
  }
  constructor(options) {
    this.tileEffect = options?.tileEffect || defaultOptions.tileEffect;
    this.rowCount = options?.rows || defaultOptions.rows;
    this.rowOffset = options?.rowOffset || defaultOptions.rowOffset;
    this.activeFace = "front";
    this.tileTransition = this.tileEffect === "fade" ? new fade_transition_default() : new flip_transition_default();
  }
  initialize(el, slides, stateStore, options) {
    const slide = slides[options.startIndex || 0];
    const fragment = document.createDocumentFragment();
    stateStore.storeStyles(el, BOX_STYLES);
    stateStore.storeStyles(slides, SLIDE_STYLES);
    this.grid = this.calculateGrid(el, slides);
    if (this._tileWrapper) {
      this.destroy(el);
    }
    const tileWrapper = document.createElement("div");
    tileWrapper.setAttribute("aria-hidden", "true");
    el.appendChild(tileWrapper);
    this._tileWrapper = tileWrapper;
    if ("fixed absolute relative".indexOf(getComputedStyle(el).position) === -1) {
      applyCss(el, { position: "relative" });
    }
    applyCss(el, {
      height: `${el.offsetHeight}px`
    });
    applyCss(this.tileWrapper, {
      position: "absolute",
      top: "0",
      left: "0",
      width: "100%",
      height: "100%"
    });
    const totalTiles = this.grid.rows * this.grid.cols;
    for (let i = 0; i < this.grid.rows; ++i) {
      const fromTop = i * this.grid.tileHeight;
      for (let j = 0; j < this.grid.cols; ++j) {
        const tile = this.tileTransition.createTile({
          backClass: `${TILE_CLASS}-back`,
          boxWidth: el.offsetWidth,
          boxHeight: el.offsetHeight,
          fromTop,
          fromLeft: j * this.grid.tileWidth,
          frontClass: `${TILE_CLASS}-front`,
          height: this.grid.tileHeight,
          speed: (options.speed - this.rowOffset * (this.grid.rows - 1)) / this.grid.cols,
          tileClass: TILE_CLASS,
          width: this.grid.tileWidth,
          zIndex: totalTiles - (i + j)
        });
        fragment.appendChild(tile);
        this.tileTransition.setTileFace(
          slide,
          tile.querySelector(`.${FRONT_FACE_CLASS}`)
        );
      }
    }
    slides.forEach(
      (s) => applyCss(s, {
        position: "absolute",
        clip: "rect(0 0 0 0)",
        height: "1px",
        width: "1px",
        margin: "-1px",
        padding: "0",
        border: "0"
      })
    );
    this.tileWrapper.appendChild(fragment);
  }
  transition(settings) {
    return new Promise((resolve) => {
      const tiles = this.tileWrapper.querySelectorAll(`.${TILE_CLASS}`);
      const rowInterval = this.rowOffset;
      const tileInterval = (settings.speed - rowInterval * (this.grid.rows - 1)) / this.grid.cols;
      const nextFace = this.activeFace === "front" ? "back" : "front";
      this.rowTimers.length = 0;
      this.tileTimers.length = 0;
      this.tileWrapper.querySelectorAll(
        `.${nextFace === "front" ? FRONT_FACE_CLASS : BACK_FACE_CLASS}`
      ).forEach(
        (tile) => this.tileTransition.setTileFace(
          settings.slides[settings.nextIndex],
          tile
        )
      );
      for (let i = 0; i < this.grid.rows; ++i) {
        let j = i * this.grid.cols;
        let timerIndex = 0;
        const rowEnd = j + this.grid.cols;
        const rowTimeout = i * rowInterval;
        this.rowTimers.push(
          window.setTimeout(() => {
            for (; j < rowEnd; ++j) {
              const tileTimeout = timerIndex * tileInterval;
              const tile = tiles[j];
              this.tileTimers.push(
                window.setTimeout(() => {
                  this.tileTransition.transition(tile, nextFace);
                  if (tile === tiles[tiles.length - 1]) {
                    this.activeFace = nextFace;
                    resolve();
                  }
                }, tileTimeout)
              );
              timerIndex += 1;
            }
          }, rowTimeout)
        );
      }
    });
  }
  destroy(el) {
    el.removeChild(this.tileWrapper);
    delete this._tileWrapper;
    this.rowTimers.forEach(window.clearTimeout);
    this.tileTimers.forEach(window.clearTimeout);
  }
  calculateGrid(el, slides) {
    const height = slides[0].offsetHeight;
    const width = slides[0].offsetWidth;
    const rows = this.rowCount;
    const tileHeight = Math.ceil(height / rows);
    const cols = Math.floor(el.offsetWidth / tileHeight);
    const tileWidth = Math.ceil(width / cols);
    return { cols, rows, tileHeight, tileWidth };
  }
};

// ../slider/dist/esm/box-slider.js
var StateStore = class {
  elementStore;
  constructor() {
    this.elementStore = [];
  }
  storeStyles(elements, styles) {
    this.applyToElements(elements, (el, elementStore) => {
      const computedStyles = getComputedStyle(el);
      styles.forEach(
        (p) => elementStore.styles[p] = computedStyles.getPropertyValue(p)
      );
    });
  }
  storeAttributes(elements, attributes) {
    this.applyToElements(elements, (el, elementStore) => {
      attributes.forEach(
        (attribute) => elementStore.attributes[attribute] = el.getAttribute(attribute)
      );
    });
  }
  revert() {
    this.elementStore.forEach((elementStore) => {
      Object.keys(elementStore.styles).forEach(
        (property) => elementStore.el.style.setProperty(
          property,
          elementStore.styles[property]
        )
      );
      Object.keys(elementStore.attributes).forEach((attribute) => {
        const cachedValue = elementStore.attributes[attribute];
        if (attribute === null || attribute === "") {
          elementStore.el.removeAttribute(attribute);
        } else if (cachedValue !== null) {
          elementStore.el.setAttribute(attribute, cachedValue);
        }
      });
    });
    this.elementStore = [];
  }
  applyToElements(elements, fn) {
    ;
    (Array.isArray(elements) ? elements : [elements]).forEach((el) => {
      let elementStore = this.elementStore.find((s) => s.el === el);
      if (!elementStore) {
        elementStore = { el, styles: {}, attributes: {} };
        this.elementStore.push(elementStore);
      }
      fn(el, elementStore);
    });
  }
};
var boxSliders = [];
var resizeObserver;
if (typeof ResizeObserver !== "undefined") {
  resizeObserver = new ResizeObserver((sliderElements) => {
    sliderElements.forEach(
      (sliderEl) => boxSliders.find((bs) => bs.el === sliderEl.target)?.reset()
    );
  });
}
var responder = {
  add(boxSlider) {
    boxSliders.push(boxSlider);
    resizeObserver?.observe(boxSlider.el);
  },
  remove(boxSlider) {
    resizeObserver?.unobserve(boxSlider.el);
    boxSliders = boxSliders.filter((b) => b !== boxSlider);
  }
};
var createQueue = () => {
  const queue = [];
  const run = () => {
    const fn = queue[0];
    if (fn) {
      fn().then(() => {
        queue.shift();
        run();
      });
    }
  };
  return {
    push(fn) {
      queue.push(fn);
      if (queue.length === 1) {
        run();
      }
    },
    clear() {
      queue.length = 0;
    }
  };
};
var defaultOptions2 = Object.freeze({
  autoScroll: true,
  pauseOnHover: false,
  speed: 800,
  startIndex: 0,
  swipe: true,
  swipeTolerance: 30,
  timeout: 5e3
});
var BoxSlider = class {
  _activeIndex;
  _el;
  _effect;
  _stateStore;
  options;
  slides;
  autoScrollTimer;
  eventListeners;
  elListeners;
  isDestroyed;
  transitionQueue;
  get activeIndex() {
    return this._activeIndex;
  }
  get el() {
    if (this._el === void 0) {
      throw new Error("Slider element is undefined");
    }
    return this._el;
  }
  get length() {
    return this.slides.length;
  }
  getOption(key) {
    return this.options[key];
  }
  get stateStore() {
    if (this._stateStore === void 0) {
      throw new Error(
        "State store is undefined, are you trying to interact with a destroyed slider?"
      );
    }
    return this._stateStore;
  }
  get effect() {
    if (this._effect === void 0) {
      throw new Error(
        "Slide effect is undefined, are you trying to interact with a destroyed slider?"
      );
    }
    return this._effect;
  }
  constructor(el, effect, options) {
    this._el = el;
    this._stateStore = new StateStore();
    this.transitionQueue = createQueue();
    this.slides = [];
    this.eventListeners = {};
    this.elListeners = {};
    this.isDestroyed = false;
    this.options = {
      autoScroll: true,
      speed: 800,
      timeout: 5e3,
      pauseOnHover: false,
      startIndex: 0,
      swipe: true,
      swipeTolerance: 30,
      ...options
    };
    this._activeIndex = this.options.startIndex;
    this.init(effect);
    if (this.slides.length < this.activeIndex) {
      this.destroy();
      throw new Error(
        `Start index option is out of bounds - slides=${this.slides.length} start=${this.activeIndex}`
      );
    }
    this.applyEventListeners();
    responder.add(this);
  }
  reset(options, effect) {
    this.stopAutoScroll();
    this.effect.destroy && this.effect.destroy(this.el);
    this.stateStore.revert();
    this.options = {
      ...this.options,
      ...options
    };
    if (options?.startIndex !== void 0 && !isNaN(options.startIndex)) {
      this._activeIndex = options.startIndex;
    }
    this.init(effect || this.effect);
  }
  next() {
    return this.skipTo(
      this.activeIndex === this.slides.length - 1 ? 0 : this.activeIndex + 1,
      false
    );
  }
  prev() {
    return this.skipTo(
      this.activeIndex === 0 ? this.slides.length - 1 : this.activeIndex - 1
    );
  }
  skipTo(nextIndex, backwards) {
    return new Promise((resolve) => {
      this.transitionQueue.push(async () => {
        await this.transitionTo(
          nextIndex,
          backwards === void 0 ? nextIndex < this.activeIndex : backwards
        );
        resolve();
      });
    });
  }
  pause() {
    this.options.autoScroll = false;
    if (this.autoScrollTimer) {
      this.stopAutoScroll();
      this.emit("pause");
    }
    return this;
  }
  play() {
    this.options.autoScroll = true;
    this.setAutoScroll();
    this.emit("play");
    return this;
  }
  addEventListener(ev, callback) {
    if (!Array.isArray(this.eventListeners[ev])) {
      this.eventListeners[ev] = [];
    }
    this.eventListeners[ev].push(callback);
    return this;
  }
  removeEventListener(ev, callback) {
    const listeners = this.eventListeners[ev]?.filter(
      (cb) => cb !== callback
    );
    this.eventListeners[ev] = listeners;
    return this;
  }
  destroy() {
    this.isDestroyed = true;
    this.stopAutoScroll();
    if (this.effect.destroy) {
      this.effect.destroy(this.el);
    }
    this.stateStore.revert();
    this.transitionQueue.clear();
    responder.remove(this);
    this.emit("destroy");
    this.eventListeners = {};
    Object.keys(this.elListeners).forEach(
      (ev) => this.elListeners[ev].forEach(
        (listener) => this.el.removeEventListener(ev, listener)
      )
    );
    this.elListeners = {};
    delete this._el;
    delete this._stateStore;
    delete this._effect;
    this.slides.length = 0;
  }
  init(effect) {
    this._effect = effect;
    this.slides = this.getSlides();
    this.effect.initialize(this.el, this.slides, this.stateStore, {
      ...this.options,
      startIndex: this.activeIndex
    });
    this.addAriaAttributes();
    if (this.options.autoScroll) {
      this.setAutoScroll();
    }
  }
  addAriaAttributes() {
    this.stateStore.storeAttributes(this.el, ["aria-live"]);
    this.el.setAttribute("aria-live", "polite");
    this.stateStore.storeAttributes(this.slides, ["aria-roledescription"]);
    this.slides.forEach(
      (slide) => slide.setAttribute("aria-roledescription", "slide")
    );
  }
  getSlides() {
    return Array.from(this.el.children).filter(
      (child) => child instanceof HTMLElement
    );
  }
  transitionTo(nextIndex, backwards) {
    return new Promise((resolve, reject) => {
      if (this.isDestroyed || nextIndex === this.activeIndex) {
        return resolve();
      }
      if (nextIndex < 0 || nextIndex >= this.slides.length) {
        return reject(new Error(`${nextIndex} is not a valid slide index`));
      }
      this.stopAutoScroll();
      const settings = {
        el: this.el,
        slides: this.slides,
        speed: this.options.speed,
        currentIndex: this.activeIndex,
        isPrevious: backwards,
        nextIndex
      };
      this._activeIndex = nextIndex;
      this.emit("before", {
        currentIndex: settings.currentIndex,
        nextIndex: settings.nextIndex,
        speed: settings.speed
      });
      this.effect.transition(settings).then(() => {
        if (this.options.autoScroll) {
          this.setAutoScroll();
        }
        this.emit("after");
        resolve();
      });
    });
  }
  stopAutoScroll() {
    window.clearTimeout(this.autoScrollTimer);
  }
  emit(ev, payload) {
    const handlers = this.eventListeners[ev];
    if (ev === "destroy") {
      const destroyHandlers = handlers;
      destroyHandlers?.forEach((cb) => cb());
    } else {
      handlers?.forEach(
        (cb) => cb({
          currentIndex: this.activeIndex,
          speed: this.options.speed,
          ...payload
        })
      );
    }
  }
  setAutoScroll() {
    this.stopAutoScroll();
    window.requestAnimationFrame(() => {
      if (!this._el) {
        return;
      }
      this.el.setAttribute("aria-live", "off");
      this.autoScrollTimer = window.setTimeout(
        () => this.next(),
        this.options.timeout
      );
    });
  }
  addElListener(ev, handler) {
    this.el.addEventListener(ev, handler);
    this.elListeners[ev] = this.elListeners[ev] || [];
    this.elListeners[ev].push(handler);
  }
  applyEventListeners() {
    this.addElListener("pointerenter", () => {
      if (this.options.autoScroll && this.options.pauseOnHover) {
        this.pause();
      }
    });
    this.addElListener("pointerleave", () => {
      if (this.options.autoScroll && this.options.pauseOnHover) {
        this.play();
      }
    });
    if (this.options.swipe) {
      this.addSwipeNavigation();
    }
  }
  addSwipeNavigation() {
    let pointerTraceX = 0;
    this.addElListener("pointerdown", (ev) => {
      pointerTraceX = ev.clientX;
    });
    this.addElListener("pointerup", (ev) => {
      const distanceX = ev.clientX - pointerTraceX;
      if (Math.abs(distanceX) >= this.options.swipeTolerance) {
        if (distanceX > 0) {
          this.prev();
        } else {
          this.next();
        }
        ev.stopPropagation();
      }
    });
  }
};

// src/Slider.ts
function camelize(str) {
  return str.replace(/-./g, (m) => m[1].toUpperCase());
}
function getNumericAttribute(el, attribute, defaultValue) {
  const attributeValue = el.getAttribute(attribute);
  let value = NaN;
  if (attributeValue !== null) {
    value = parseInt(attributeValue, 10);
  }
  return isNaN(value) ? defaultValue : value;
}
function getBbooleanAttribute(el, attribute, defaultValue) {
  if (el.hasAttribute(attribute)) {
    return el.getAttribute(attribute) !== "false";
  }
  return defaultValue;
}
var BOOLEAN_ATTRIBUTES = ["auto-scroll", "pause-on-hover"];
var NUMBER_ATTRIBUTES = [
  "speed",
  "timeout",
  "start-index",
  "swipe",
  "swipe-tolerance"
];
var SLIDER_ATTRIBUTES = [...BOOLEAN_ATTRIBUTES, ...NUMBER_ATTRIBUTES];
var Slider = class extends HTMLElement {
  #slider;
  get slider() {
    return this.#slider;
  }
  get autoScroll() {
    return getBbooleanAttribute(this, "auto-scroll", defaultOptions2.autoScroll);
  }
  get pauseOnHover() {
    return getBbooleanAttribute(
      this,
      "pause-on-hover",
      defaultOptions2.pauseOnHover
    );
  }
  get speed() {
    return getNumericAttribute(this, "speed", defaultOptions2.speed);
  }
  get startIndex() {
    return getNumericAttribute(this, "start-index", defaultOptions2.startIndex);
  }
  get swipe() {
    return getBbooleanAttribute(this, "swipe", defaultOptions2.swipe);
  }
  get swipeTolerance() {
    return getNumericAttribute(
      this,
      "swipe-tolerance",
      defaultOptions2.swipeTolerance
    );
  }
  get timeout() {
    return getNumericAttribute(this, "timeout", defaultOptions2.timeout);
  }
  get options() {
    return {
      autoScroll: this.autoScroll,
      pauseOnHover: this.pauseOnHover,
      speed: this.speed,
      startIndex: this.startIndex,
      swipe: this.swipe,
      swipeTolerance: this.swipeTolerance,
      timeout: this.timeout
    };
  }
  init(effect) {
    const slider = new BoxSlider(this, effect, this.options);
    const events = [
      "play",
      "pause",
      "before",
      "after",
      "destroy"
    ];
    events.forEach(
      (ev) => slider.addEventListener(
        ev,
        (detail) => this.dispatchEvent(new CustomEvent(ev, { detail }))
      )
    );
    this.#slider = slider;
  }
  reset(options, effect) {
    this.slider?.reset(options, effect);
  }
  attributeChangedCallback(name) {
    if (SLIDER_ATTRIBUTES.includes(name)) {
      const propName = camelize(name);
      this.reset({ [propName]: this[propName] });
    }
  }
  disconnectedCallback() {
    this.slider?.destroy();
    this.#slider = void 0;
  }
};

// src/Tile.ts
var TILE_ATTRIBUTES = ["rows", "row-offset", "tile-effect"];
var Tile = class extends Slider {
  static observedAttributes = [...SLIDER_ATTRIBUTES, ...TILE_ATTRIBUTES];
  get rows() {
    return getNumericAttribute(this, "rows", 8);
  }
  get rowOffset() {
    return getNumericAttribute(this, "row-offset", 50);
  }
  get tileEffect() {
    return this.getAttribute("tile-effect") || "fade";
  }
  attributeChangedCallback(name) {
    if (TILE_ATTRIBUTES.includes(name)) {
      const propName = camelize(name);
      this.reset(
        { [propName]: this[propName] },
        new TileSlider({
          rows: this.rows,
          rowOffset: this.rowOffset,
          tileEffect: this.tileEffect
        })
      );
    } else {
      super.attributeChangedCallback(name);
    }
  }
  connectedCallback() {
    this.init(
      new TileSlider({
        rows: this.rows,
        rowOffset: this.rowOffset,
        tileEffect: this.tileEffect
      })
    );
  }
};
if (typeof customElements !== "undefined") {
  customElements.define("bs-tile", Tile);
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  TILE_ATTRIBUTES
});
