"use strict";/*
 * ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
 * This devtool is neither made for production nor for readable output files.
 * It uses "eval()" calls to create a separate source file in the browser devtools.
 * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
 * or disable the default devtool with "devtool: false".
 * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
 */ /******/(function(){// webpackBootstrap
/******/var __webpack_modules__={/***/"./node_modules/@glidejs/glide/dist/glide.esm.js":(/*!*******************************************************!*\
  !*** ./node_modules/@glidejs/glide/dist/glide.esm.js ***!
  \*******************************************************/ /***/function node_modulesGlidejsGlideDistGlideEsmJs(__unused_webpack___webpack_module__,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"default\": () => (/* binding */ Glide)\n/* harmony export */ });\n/*!\n * Glide.js v3.6.2\n * (c) 2013-2024 Jędrzej Chałubek (https://github.com/jedrzejchalubek/)\n * Released under the MIT License.\n */\n\nfunction ownKeys(object, enumerableOnly) {\n  var keys = Object.keys(object);\n\n  if (Object.getOwnPropertySymbols) {\n    var symbols = Object.getOwnPropertySymbols(object);\n\n    if (enumerableOnly) {\n      symbols = symbols.filter(function (sym) {\n        return Object.getOwnPropertyDescriptor(object, sym).enumerable;\n      });\n    }\n\n    keys.push.apply(keys, symbols);\n  }\n\n  return keys;\n}\n\nfunction _objectSpread2(target) {\n  for (var i = 1; i < arguments.length; i++) {\n    var source = arguments[i] != null ? arguments[i] : {};\n\n    if (i % 2) {\n      ownKeys(Object(source), true).forEach(function (key) {\n        _defineProperty(target, key, source[key]);\n      });\n    } else if (Object.getOwnPropertyDescriptors) {\n      Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));\n    } else {\n      ownKeys(Object(source)).forEach(function (key) {\n        Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));\n      });\n    }\n  }\n\n  return target;\n}\n\nfunction _typeof(obj) {\n  \"@babel/helpers - typeof\";\n\n  if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") {\n    _typeof = function (obj) {\n      return typeof obj;\n    };\n  } else {\n    _typeof = function (obj) {\n      return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj;\n    };\n  }\n\n  return _typeof(obj);\n}\n\nfunction _classCallCheck(instance, Constructor) {\n  if (!(instance instanceof Constructor)) {\n    throw new TypeError(\"Cannot call a class as a function\");\n  }\n}\n\nfunction _defineProperties(target, props) {\n  for (var i = 0; i < props.length; i++) {\n    var descriptor = props[i];\n    descriptor.enumerable = descriptor.enumerable || false;\n    descriptor.configurable = true;\n    if (\"value\" in descriptor) descriptor.writable = true;\n    Object.defineProperty(target, descriptor.key, descriptor);\n  }\n}\n\nfunction _createClass(Constructor, protoProps, staticProps) {\n  if (protoProps) _defineProperties(Constructor.prototype, protoProps);\n  if (staticProps) _defineProperties(Constructor, staticProps);\n  return Constructor;\n}\n\nfunction _defineProperty(obj, key, value) {\n  if (key in obj) {\n    Object.defineProperty(obj, key, {\n      value: value,\n      enumerable: true,\n      configurable: true,\n      writable: true\n    });\n  } else {\n    obj[key] = value;\n  }\n\n  return obj;\n}\n\nfunction _inherits(subClass, superClass) {\n  if (typeof superClass !== \"function\" && superClass !== null) {\n    throw new TypeError(\"Super expression must either be null or a function\");\n  }\n\n  subClass.prototype = Object.create(superClass && superClass.prototype, {\n    constructor: {\n      value: subClass,\n      writable: true,\n      configurable: true\n    }\n  });\n  if (superClass) _setPrototypeOf(subClass, superClass);\n}\n\nfunction _getPrototypeOf(o) {\n  _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {\n    return o.__proto__ || Object.getPrototypeOf(o);\n  };\n  return _getPrototypeOf(o);\n}\n\nfunction _setPrototypeOf(o, p) {\n  _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {\n    o.__proto__ = p;\n    return o;\n  };\n\n  return _setPrototypeOf(o, p);\n}\n\nfunction _isNativeReflectConstruct() {\n  if (typeof Reflect === \"undefined\" || !Reflect.construct) return false;\n  if (Reflect.construct.sham) return false;\n  if (typeof Proxy === \"function\") return true;\n\n  try {\n    Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));\n    return true;\n  } catch (e) {\n    return false;\n  }\n}\n\nfunction _assertThisInitialized(self) {\n  if (self === void 0) {\n    throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");\n  }\n\n  return self;\n}\n\nfunction _possibleConstructorReturn(self, call) {\n  if (call && (typeof call === \"object\" || typeof call === \"function\")) {\n    return call;\n  } else if (call !== void 0) {\n    throw new TypeError(\"Derived constructors may only return object or undefined\");\n  }\n\n  return _assertThisInitialized(self);\n}\n\nfunction _createSuper(Derived) {\n  var hasNativeReflectConstruct = _isNativeReflectConstruct();\n\n  return function _createSuperInternal() {\n    var Super = _getPrototypeOf(Derived),\n        result;\n\n    if (hasNativeReflectConstruct) {\n      var NewTarget = _getPrototypeOf(this).constructor;\n\n      result = Reflect.construct(Super, arguments, NewTarget);\n    } else {\n      result = Super.apply(this, arguments);\n    }\n\n    return _possibleConstructorReturn(this, result);\n  };\n}\n\nfunction _superPropBase(object, property) {\n  while (!Object.prototype.hasOwnProperty.call(object, property)) {\n    object = _getPrototypeOf(object);\n    if (object === null) break;\n  }\n\n  return object;\n}\n\nfunction _get() {\n  if (typeof Reflect !== \"undefined\" && Reflect.get) {\n    _get = Reflect.get;\n  } else {\n    _get = function _get(target, property, receiver) {\n      var base = _superPropBase(target, property);\n\n      if (!base) return;\n      var desc = Object.getOwnPropertyDescriptor(base, property);\n\n      if (desc.get) {\n        return desc.get.call(arguments.length < 3 ? target : receiver);\n      }\n\n      return desc.value;\n    };\n  }\n\n  return _get.apply(this, arguments);\n}\n\nvar defaults = {\n  /**\n   * Type of the movement.\n   *\n   * Available types:\n   * `slider` - Rewinds slider to the start/end when it reaches the first or last slide.\n   * `carousel` - Changes slides without starting over when it reaches the first or last slide.\n   *\n   * @type {String}\n   */\n  type: 'slider',\n\n  /**\n   * Start at specific slide number defined with zero-based index.\n   *\n   * @type {Number}\n   */\n  startAt: 0,\n\n  /**\n   * A number of slides visible on the single viewport.\n   *\n   * @type {Number}\n   */\n  perView: 1,\n\n  /**\n   * Focus currently active slide at a specified position in the track.\n   *\n   * Available inputs:\n   * `center` - Current slide will be always focused at the center of a track.\n   * `0,1,2,3...` - Current slide will be focused on the specified zero-based index.\n   *\n   * @type {String|Number}\n   */\n  focusAt: 0,\n\n  /**\n   * A size of the gap added between slides.\n   *\n   * @type {Number}\n   */\n  gap: 10,\n\n  /**\n   * Change slides after a specified interval. Use `false` for turning off autoplay.\n   *\n   * @type {Number|Boolean}\n   */\n  autoplay: false,\n\n  /**\n   * Stop autoplay on mouseover event.\n   *\n   * @type {Boolean}\n   */\n  hoverpause: true,\n\n  /**\n   * Allow for changing slides with left and right keyboard arrows.\n   *\n   * @type {Boolean}\n   */\n  keyboard: true,\n\n  /**\n   * Stop running `perView` number of slides from the end. Use this\n   * option if you don't want to have an empty space after\n   * a slider. Works only with `slider` type and a\n   * non-centered `focusAt` setting.\n   *\n   * @type {Boolean}\n   */\n  bound: false,\n\n  /**\n   * Minimal swipe distance needed to change the slide. Use `false` for turning off a swiping.\n   *\n   * @type {Number|Boolean}\n   */\n  swipeThreshold: 80,\n\n  /**\n   * Minimal mouse drag distance needed to change the slide. Use `false` for turning off a dragging.\n   *\n   * @type {Number|Boolean}\n   */\n  dragThreshold: 120,\n\n  /**\n   * A number of slides moved on single swipe.\n   *\n   * Available types:\n   * `` - Moves slider by one slide per swipe\n   * `|` - Moves slider between views per swipe (number of slides defined in `perView` options)\n   *\n   * @type {String}\n   */\n  perSwipe: '',\n\n  /**\n   * Moving distance ratio of the slides on a swiping and dragging.\n   *\n   * @type {Number}\n   */\n  touchRatio: 0.5,\n\n  /**\n   * Angle required to activate slides moving on swiping or dragging.\n   *\n   * @type {Number}\n   */\n  touchAngle: 45,\n\n  /**\n   * Duration of the animation in milliseconds.\n   *\n   * @type {Number}\n   */\n  animationDuration: 400,\n\n  /**\n   * Allows looping the `slider` type. Slider will rewind to the first/last slide when it's at the start/end.\n   *\n   * @type {Boolean}\n   */\n  rewind: true,\n\n  /**\n   * Duration of the rewinding animation of the `slider` type in milliseconds.\n   *\n   * @type {Number}\n   */\n  rewindDuration: 800,\n\n  /**\n   * Easing function for the animation.\n   *\n   * @type {String}\n   */\n  animationTimingFunc: 'cubic-bezier(.165, .840, .440, 1)',\n\n  /**\n   * Wait for the animation to finish until the next user input can be processed\n   *\n   * @type {boolean}\n   */\n  waitForTransition: true,\n\n  /**\n   * Throttle costly events at most once per every wait milliseconds.\n   *\n   * @type {Number}\n   */\n  throttle: 10,\n\n  /**\n   * Moving direction mode.\n   *\n   * Available inputs:\n   * - 'ltr' - left to right movement,\n   * - 'rtl' - right to left movement.\n   *\n   * @type {String}\n   */\n  direction: 'ltr',\n\n  /**\n   * The distance value of the next and previous viewports which\n   * have to peek in the current view. Accepts number and\n   * pixels as a string. Left and right peeking can be\n   * set up separately with a directions object.\n   *\n   * For example:\n   * `100` - Peek 100px on the both sides.\n   * { before: 100, after: 50 }` - Peek 100px on the left side and 50px on the right side.\n   *\n   * @type {Number|String|Object}\n   */\n  peek: 0,\n\n  /**\n   * Defines how many clones of current viewport will be generated.\n   *\n   * @type {Number}\n   */\n  cloningRatio: 1,\n\n  /**\n   * Collection of options applied at specified media breakpoints.\n   * For example: display two slides per view under 800px.\n   * `{\n   *   '800px': {\n   *     perView: 2\n   *   }\n   * }`\n   */\n  breakpoints: {},\n\n  /**\n   * Collection of internally used HTML classes.\n   *\n   * @todo Refactor `slider` and `carousel` properties to single `type: { slider: '', carousel: '' }` object\n   * @type {Object}\n   */\n  classes: {\n    swipeable: 'glide--swipeable',\n    dragging: 'glide--dragging',\n    direction: {\n      ltr: 'glide--ltr',\n      rtl: 'glide--rtl'\n    },\n    type: {\n      slider: 'glide--slider',\n      carousel: 'glide--carousel'\n    },\n    slide: {\n      clone: 'glide__slide--clone',\n      active: 'glide__slide--active'\n    },\n    arrow: {\n      disabled: 'glide__arrow--disabled'\n    },\n    nav: {\n      active: 'glide__bullet--active'\n    }\n  }\n};\n\n/**\n * Outputs warning message to the bowser console.\n *\n * @param  {String} msg\n * @return {Void}\n */\nfunction warn(msg) {\n  console.error(\"[Glide warn]: \".concat(msg));\n}\n\n/**\n * Converts value entered as number\n * or string to integer value.\n *\n * @param {String} value\n * @returns {Number}\n */\nfunction toInt(value) {\n  return parseInt(value);\n}\n/**\n * Converts value entered as number\n * or string to flat value.\n *\n * @param {String} value\n * @returns {Number}\n */\n\nfunction toFloat(value) {\n  return parseFloat(value);\n}\n/**\n * Indicates whether the specified value is a string.\n *\n * @param  {*}   value\n * @return {Boolean}\n */\n\nfunction isString(value) {\n  return typeof value === 'string';\n}\n/**\n * Indicates whether the specified value is an object.\n *\n * @param  {*} value\n * @return {Boolean}\n *\n * @see https://github.com/jashkenas/underscore\n */\n\nfunction isObject(value) {\n  var type = _typeof(value);\n\n  return type === 'function' || type === 'object' && !!value; // eslint-disable-line no-mixed-operators\n}\n/**\n * Indicates whether the specified value is a function.\n *\n * @param  {*} value\n * @return {Boolean}\n */\n\nfunction isFunction(value) {\n  return typeof value === 'function';\n}\n/**\n * Indicates whether the specified value is undefined.\n *\n * @param  {*} value\n * @return {Boolean}\n */\n\nfunction isUndefined(value) {\n  return typeof value === 'undefined';\n}\n/**\n * Indicates whether the specified value is an array.\n *\n * @param  {*} value\n * @return {Boolean}\n */\n\nfunction isArray(value) {\n  return value.constructor === Array;\n}\n\n/**\n * Creates and initializes specified collection of extensions.\n * Each extension receives access to instance of glide and rest of components.\n *\n * @param {Object} glide\n * @param {Object} extensions\n *\n * @returns {Object}\n */\n\nfunction mount(glide, extensions, events) {\n  var components = {};\n\n  for (var name in extensions) {\n    if (isFunction(extensions[name])) {\n      components[name] = extensions[name](glide, components, events);\n    } else {\n      warn('Extension must be a function');\n    }\n  }\n\n  for (var _name in components) {\n    if (isFunction(components[_name].mount)) {\n      components[_name].mount();\n    }\n  }\n\n  return components;\n}\n\n/**\n * Defines getter and setter property on the specified object.\n *\n * @param  {Object} obj         Object where property has to be defined.\n * @param  {String} prop        Name of the defined property.\n * @param  {Object} definition  Get and set definitions for the property.\n * @return {Void}\n */\nfunction define(obj, prop, definition) {\n  Object.defineProperty(obj, prop, definition);\n}\n/**\n * Sorts aphabetically object keys.\n *\n * @param  {Object} obj\n * @return {Object}\n */\n\nfunction sortKeys(obj) {\n  return Object.keys(obj).sort().reduce(function (r, k) {\n    r[k] = obj[k];\n    return r[k], r;\n  }, {});\n}\n/**\n * Merges passed settings object with default options.\n *\n * @param  {Object} defaults\n * @param  {Object} settings\n * @return {Object}\n */\n\nfunction mergeOptions(defaults, settings) {\n  var options = Object.assign({}, defaults, settings); // `Object.assign` do not deeply merge objects, so we\n  // have to do it manually for every nested object\n  // in options. Although it does not look smart,\n  // it's smaller and faster than some fancy\n  // merging deep-merge algorithm script.\n\n  if (settings.hasOwnProperty('classes')) {\n    options.classes = Object.assign({}, defaults.classes, settings.classes);\n    var properties = ['direction', 'type', 'slide', 'arrow', 'nav'];\n    properties.forEach(function (property) {\n      if (settings.classes.hasOwnProperty(property)) {\n        options.classes[property] = _objectSpread2(_objectSpread2({}, defaults.classes[property]), settings.classes[property]);\n      }\n    });\n  }\n\n  if (settings.hasOwnProperty('breakpoints')) {\n    options.breakpoints = Object.assign({}, defaults.breakpoints, settings.breakpoints);\n  }\n\n  return options;\n}\n\nvar EventsBus = /*#__PURE__*/function () {\n  /**\n   * Construct a EventBus instance.\n   *\n   * @param {Object} events\n   */\n  function EventsBus() {\n    var events = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n    _classCallCheck(this, EventsBus);\n\n    this.events = events;\n    this.hop = events.hasOwnProperty;\n  }\n  /**\n   * Adds listener to the specifed event.\n   *\n   * @param {String|Array} event\n   * @param {Function} handler\n   */\n\n\n  _createClass(EventsBus, [{\n    key: \"on\",\n    value: function on(event, handler) {\n      if (isArray(event)) {\n        for (var i = 0; i < event.length; i++) {\n          this.on(event[i], handler);\n        }\n\n        return;\n      } // Create the event's object if not yet created\n\n\n      if (!this.hop.call(this.events, event)) {\n        this.events[event] = [];\n      } // Add the handler to queue\n\n\n      var index = this.events[event].push(handler) - 1; // Provide handle back for removal of event\n\n      return {\n        remove: function remove() {\n          delete this.events[event][index];\n        }\n      };\n    }\n    /**\n     * Runs registered handlers for specified event.\n     *\n     * @param {String|Array} event\n     * @param {Object=} context\n     */\n\n  }, {\n    key: \"emit\",\n    value: function emit(event, context) {\n      if (isArray(event)) {\n        for (var i = 0; i < event.length; i++) {\n          this.emit(event[i], context);\n        }\n\n        return;\n      } // If the event doesn't exist, or there's no handlers in queue, just leave\n\n\n      if (!this.hop.call(this.events, event)) {\n        return;\n      } // Cycle through events queue, fire!\n\n\n      this.events[event].forEach(function (item) {\n        item(context || {});\n      });\n    }\n  }]);\n\n  return EventsBus;\n}();\n\nvar Glide$1 = /*#__PURE__*/function () {\n  /**\r\n   * Construct glide.\r\n   *\r\n   * @param  {String} selector\r\n   * @param  {Object} options\r\n   */\n  function Glide(selector) {\n    var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n\n    _classCallCheck(this, Glide);\n\n    this._c = {};\n    this._t = [];\n    this._e = new EventsBus();\n    this.disabled = false;\n    this.selector = selector;\n    this.settings = mergeOptions(defaults, options);\n    this.index = this.settings.startAt;\n  }\n  /**\r\n   * Initializes glide.\r\n   *\r\n   * @param {Object} extensions Collection of extensions to initialize.\r\n   * @return {Glide}\r\n   */\n\n\n  _createClass(Glide, [{\n    key: \"mount\",\n    value: function mount$1() {\n      var extensions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n      this._e.emit('mount.before');\n\n      if (isObject(extensions)) {\n        this._c = mount(this, extensions, this._e);\n      } else {\n        warn('You need to provide a object on `mount()`');\n      }\n\n      this._e.emit('mount.after');\n\n      return this;\n    }\n    /**\r\n     * Collects an instance `translate` transformers.\r\n     *\r\n     * @param  {Array} transformers Collection of transformers.\r\n     * @return {Void}\r\n     */\n\n  }, {\n    key: \"mutate\",\n    value: function mutate() {\n      var transformers = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];\n\n      if (isArray(transformers)) {\n        this._t = transformers;\n      } else {\n        warn('You need to provide a array on `mutate()`');\n      }\n\n      return this;\n    }\n    /**\r\n     * Updates glide with specified settings.\r\n     *\r\n     * @param {Object} settings\r\n     * @return {Glide}\r\n     */\n\n  }, {\n    key: \"update\",\n    value: function update() {\n      var settings = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n      this.settings = mergeOptions(this.settings, settings);\n\n      if (settings.hasOwnProperty('startAt')) {\n        this.index = settings.startAt;\n      }\n\n      this._e.emit('update');\n\n      return this;\n    }\n    /**\r\n     * Change slide with specified pattern. A pattern must be in the special format:\r\n     * `>` - Move one forward\r\n     * `<` - Move one backward\r\n     * `={i}` - Go to {i} zero-based slide (eq. '=1', will go to second slide)\r\n     * `>>` - Rewinds to end (last slide)\r\n     * `<<` - Rewinds to start (first slide)\r\n     * `|>` - Move one viewport forward\r\n     * `|<` - Move one viewport backward\r\n     *\r\n     * @param {String} pattern\r\n     * @return {Glide}\r\n     */\n\n  }, {\n    key: \"go\",\n    value: function go(pattern) {\n      this._c.Run.make(pattern);\n\n      return this;\n    }\n    /**\r\n     * Move track by specified distance.\r\n     *\r\n     * @param {String} distance\r\n     * @return {Glide}\r\n     */\n\n  }, {\n    key: \"move\",\n    value: function move(distance) {\n      this._c.Transition.disable();\n\n      this._c.Move.make(distance);\n\n      return this;\n    }\n    /**\r\n     * Destroy instance and revert all changes done by this._c.\r\n     *\r\n     * @return {Glide}\r\n     */\n\n  }, {\n    key: \"destroy\",\n    value: function destroy() {\n      this._e.emit('destroy');\n\n      return this;\n    }\n    /**\r\n     * Start instance autoplaying.\r\n     *\r\n     * @param {Boolean|Number} interval Run autoplaying with passed interval regardless of `autoplay` settings\r\n     * @return {Glide}\r\n     */\n\n  }, {\n    key: \"play\",\n    value: function play() {\n      var interval = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;\n\n      if (interval) {\n        this.settings.autoplay = interval;\n      }\n\n      this._e.emit('play');\n\n      return this;\n    }\n    /**\r\n     * Stop instance autoplaying.\r\n     *\r\n     * @return {Glide}\r\n     */\n\n  }, {\n    key: \"pause\",\n    value: function pause() {\n      this._e.emit('pause');\n\n      return this;\n    }\n    /**\r\n     * Sets glide into a idle status.\r\n     *\r\n     * @return {Glide}\r\n     */\n\n  }, {\n    key: \"disable\",\n    value: function disable() {\n      this.disabled = true;\n      return this;\n    }\n    /**\r\n     * Sets glide into a active status.\r\n     *\r\n     * @return {Glide}\r\n     */\n\n  }, {\n    key: \"enable\",\n    value: function enable() {\n      this.disabled = false;\n      return this;\n    }\n    /**\r\n     * Adds cuutom event listener with handler.\r\n     *\r\n     * @param  {String|Array} event\r\n     * @param  {Function} handler\r\n     * @return {Glide}\r\n     */\n\n  }, {\n    key: \"on\",\n    value: function on(event, handler) {\n      this._e.on(event, handler);\n\n      return this;\n    }\n    /**\r\n     * Checks if glide is a precised type.\r\n     *\r\n     * @param  {String} name\r\n     * @return {Boolean}\r\n     */\n\n  }, {\n    key: \"isType\",\n    value: function isType(name) {\n      return this.settings.type === name;\n    }\n    /**\r\n     * Gets value of the core options.\r\n     *\r\n     * @return {Object}\r\n     */\n\n  }, {\n    key: \"settings\",\n    get: function get() {\n      return this._o;\n    }\n    /**\r\n     * Sets value of the core options.\r\n     *\r\n     * @param  {Object} o\r\n     * @return {Void}\r\n     */\n    ,\n    set: function set(o) {\n      if (isObject(o)) {\n        this._o = o;\n      } else {\n        warn('Options must be an `object` instance.');\n      }\n    }\n    /**\r\n     * Gets current index of the slider.\r\n     *\r\n     * @return {Object}\r\n     */\n\n  }, {\n    key: \"index\",\n    get: function get() {\n      return this._i;\n    }\n    /**\r\n     * Sets current index a slider.\r\n     *\r\n     * @return {Object}\r\n     */\n    ,\n    set: function set(i) {\n      this._i = toInt(i);\n    }\n    /**\r\n     * Gets type name of the slider.\r\n     *\r\n     * @return {String}\r\n     */\n\n  }, {\n    key: \"type\",\n    get: function get() {\n      return this.settings.type;\n    }\n    /**\r\n     * Gets value of the idle status.\r\n     *\r\n     * @return {Boolean}\r\n     */\n\n  }, {\n    key: \"disabled\",\n    get: function get() {\n      return this._d;\n    }\n    /**\r\n     * Sets value of the idle status.\r\n     *\r\n     * @return {Boolean}\r\n     */\n    ,\n    set: function set(status) {\n      this._d = !!status;\n    }\n  }]);\n\n  return Glide;\n}();\n\nfunction Run (Glide, Components, Events) {\n  var Run = {\n    /**\n     * Initializes autorunning of the glide.\n     *\n     * @return {Void}\n     */\n    mount: function mount() {\n      this._o = false;\n    },\n\n    /**\n     * Makes glides running based on the passed moving schema.\n     *\n     * @param {String} move\n     */\n    make: function make(move) {\n      var _this = this;\n\n      if (!Glide.disabled) {\n        !Glide.settings.waitForTransition || Glide.disable();\n        this.move = move;\n        Events.emit('run.before', this.move);\n        this.calculate();\n        Events.emit('run', this.move);\n        Components.Transition.after(function () {\n          if (_this.isStart()) {\n            Events.emit('run.start', _this.move);\n          }\n\n          if (_this.isEnd()) {\n            Events.emit('run.end', _this.move);\n          }\n\n          if (_this.isOffset()) {\n            _this._o = false;\n            Events.emit('run.offset', _this.move);\n          }\n\n          Events.emit('run.after', _this.move);\n          Glide.enable();\n        });\n      }\n    },\n\n    /**\n     * Calculates current index based on defined move.\n     *\n     * @return {Number|Undefined}\n     */\n    calculate: function calculate() {\n      var move = this.move,\n          length = this.length;\n      var steps = move.steps,\n          direction = move.direction; // By default assume that size of view is equal to one slide\n\n      var viewSize = 1; // While direction is `=` we want jump to\n      // a specified index described in steps.\n\n      if (direction === '=') {\n        // Check if bound is true, \n        // as we want to avoid whitespaces.\n        if (Glide.settings.bound && toInt(steps) > length) {\n          Glide.index = length;\n          return;\n        }\n\n        Glide.index = steps;\n        return;\n      } // When pattern is equal to `>>` we want\n      // fast forward to the last slide.\n\n\n      if (direction === '>' && steps === '>') {\n        Glide.index = length;\n        return;\n      } // When pattern is equal to `<<` we want\n      // fast forward to the first slide.\n\n\n      if (direction === '<' && steps === '<') {\n        Glide.index = 0;\n        return;\n      } // pagination movement\n\n\n      if (direction === '|') {\n        viewSize = Glide.settings.perView || 1;\n      } // we are moving forward\n\n\n      if (direction === '>' || direction === '|' && steps === '>') {\n        var index = calculateForwardIndex(viewSize);\n\n        if (index > length) {\n          this._o = true;\n        }\n\n        Glide.index = normalizeForwardIndex(index, viewSize);\n        return;\n      } // we are moving backward\n\n\n      if (direction === '<' || direction === '|' && steps === '<') {\n        var _index = calculateBackwardIndex(viewSize);\n\n        if (_index < 0) {\n          this._o = true;\n        }\n\n        Glide.index = normalizeBackwardIndex(_index, viewSize);\n        return;\n      }\n\n      warn(\"Invalid direction pattern [\".concat(direction).concat(steps, \"] has been used\"));\n    },\n\n    /**\n     * Checks if we are on the first slide.\n     *\n     * @return {Boolean}\n     */\n    isStart: function isStart() {\n      return Glide.index <= 0;\n    },\n\n    /**\n     * Checks if we are on the last slide.\n     *\n     * @return {Boolean}\n     */\n    isEnd: function isEnd() {\n      return Glide.index >= this.length;\n    },\n\n    /**\n     * Checks if we are making a offset run.\n     *\n     * @param {String} direction\n     * @return {Boolean}\n     */\n    isOffset: function isOffset() {\n      var direction = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : undefined;\n\n      if (!direction) {\n        return this._o;\n      }\n\n      if (!this._o) {\n        return false;\n      } // did we view to the right?\n\n\n      if (direction === '|>') {\n        return this.move.direction === '|' && this.move.steps === '>';\n      } // did we view to the left?\n\n\n      if (direction === '|<') {\n        return this.move.direction === '|' && this.move.steps === '<';\n      }\n\n      return this.move.direction === direction;\n    },\n\n    /**\n     * Checks if bound mode is active\n     *\n     * @return {Boolean}\n     */\n    isBound: function isBound() {\n      return Glide.isType('slider') && Glide.settings.focusAt !== 'center' && Glide.settings.bound;\n    }\n  };\n  /**\n   * Returns index value to move forward/to the right\n   *\n   * @param viewSize\n   * @returns {Number}\n   */\n\n  function calculateForwardIndex(viewSize) {\n    var index = Glide.index;\n\n    if (Glide.isType('carousel')) {\n      return index + viewSize;\n    }\n\n    return index + (viewSize - index % viewSize);\n  }\n  /**\n   * Normalizes the given forward index based on glide settings, preventing it to exceed certain boundaries\n   *\n   * @param index\n   * @param length\n   * @param viewSize\n   * @returns {Number}\n   */\n\n\n  function normalizeForwardIndex(index, viewSize) {\n    var length = Run.length;\n\n    if (index <= length) {\n      return index;\n    }\n\n    if (Glide.isType('carousel')) {\n      return index - (length + 1);\n    }\n\n    if (Glide.settings.rewind) {\n      // bound does funny things with the length, therefor we have to be certain\n      // that we are on the last possible index value given by bound\n      if (Run.isBound() && !Run.isEnd()) {\n        return length;\n      }\n\n      return 0;\n    }\n\n    if (Run.isBound()) {\n      return length;\n    }\n\n    return Math.floor(length / viewSize) * viewSize;\n  }\n  /**\n   * Calculates index value to move backward/to the left\n   *\n   * @param viewSize\n   * @returns {Number}\n   */\n\n\n  function calculateBackwardIndex(viewSize) {\n    var index = Glide.index;\n\n    if (Glide.isType('carousel')) {\n      return index - viewSize;\n    } // ensure our back navigation results in the same index as a forward navigation\n    // to experience a homogeneous paging\n\n\n    var view = Math.ceil(index / viewSize);\n    return (view - 1) * viewSize;\n  }\n  /**\n   * Normalizes the given backward index based on glide settings, preventing it to exceed certain boundaries\n   *\n   * @param index\n   * @param length\n   * @param viewSize\n   * @returns {*}\n   */\n\n\n  function normalizeBackwardIndex(index, viewSize) {\n    var length = Run.length;\n\n    if (index >= 0) {\n      return index;\n    }\n\n    if (Glide.isType('carousel')) {\n      return index + (length + 1);\n    }\n\n    if (Glide.settings.rewind) {\n      // bound does funny things with the length, therefor we have to be certain\n      // that we are on first possible index value before we to rewind to the length given by bound\n      if (Run.isBound() && Run.isStart()) {\n        return length;\n      }\n\n      return Math.floor(length / viewSize) * viewSize;\n    }\n\n    return 0;\n  }\n\n  define(Run, 'move', {\n    /**\n     * Gets value of the move schema.\n     *\n     * @returns {Object}\n     */\n    get: function get() {\n      return this._m;\n    },\n\n    /**\n     * Sets value of the move schema.\n     *\n     * @returns {Object}\n     */\n    set: function set(value) {\n      var step = value.substr(1);\n      this._m = {\n        direction: value.substr(0, 1),\n        steps: step ? toInt(step) ? toInt(step) : step : 0\n      };\n    }\n  });\n  define(Run, 'length', {\n    /**\n     * Gets value of the running distance based\n     * on zero-indexing number of slides.\n     *\n     * @return {Number}\n     */\n    get: function get() {\n      var settings = Glide.settings;\n      var length = Components.Html.slides.length; // If the `bound` option is active, a maximum running distance should be\n      // reduced by `perView` and `focusAt` settings. Running distance\n      // should end before creating an empty space after instance.\n\n      if (this.isBound()) {\n        return length - 1 - (toInt(settings.perView) - 1) + toInt(settings.focusAt);\n      }\n\n      return length - 1;\n    }\n  });\n  define(Run, 'offset', {\n    /**\n     * Gets status of the offsetting flag.\n     *\n     * @return {Boolean}\n     */\n    get: function get() {\n      return this._o;\n    }\n  });\n  return Run;\n}\n\n/**\n * Returns a current time.\n *\n * @return {Number}\n */\nfunction now() {\n  return new Date().getTime();\n}\n\n/**\n * Returns a function, that, when invoked, will only be triggered\n * at most once during a given window of time.\n *\n * @param {Function} func\n * @param {Number} wait\n * @param {Object=} options\n * @return {Function}\n *\n * @see https://github.com/jashkenas/underscore\n */\n\nfunction throttle(func, wait) {\n  var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n  var timeout, context, args, result;\n  var previous = 0;\n\n  var later = function later() {\n    previous = options.leading === false ? 0 : now();\n    timeout = null;\n    result = func.apply(context, args);\n    if (!timeout) context = args = null;\n  };\n\n  var throttled = function throttled() {\n    var at = now();\n    if (!previous && options.leading === false) previous = at;\n    var remaining = wait - (at - previous);\n    context = this;\n    args = arguments;\n\n    if (remaining <= 0 || remaining > wait) {\n      if (timeout) {\n        clearTimeout(timeout);\n        timeout = null;\n      }\n\n      previous = at;\n      result = func.apply(context, args);\n      if (!timeout) context = args = null;\n    } else if (!timeout && options.trailing !== false) {\n      timeout = setTimeout(later, remaining);\n    }\n\n    return result;\n  };\n\n  throttled.cancel = function () {\n    clearTimeout(timeout);\n    previous = 0;\n    timeout = context = args = null;\n  };\n\n  return throttled;\n}\n\nvar MARGIN_TYPE = {\n  ltr: ['marginLeft', 'marginRight'],\n  rtl: ['marginRight', 'marginLeft']\n};\nfunction Gaps (Glide, Components, Events) {\n  var Gaps = {\n    /**\n     * Applies gaps between slides. First and last\n     * slides do not receive it's edge margins.\n     *\n     * @param {HTMLCollection} slides\n     * @return {Void}\n     */\n    apply: function apply(slides) {\n      for (var i = 0, len = slides.length; i < len; i++) {\n        var style = slides[i].style;\n        var direction = Components.Direction.value;\n\n        if (i !== 0) {\n          style[MARGIN_TYPE[direction][0]] = \"\".concat(this.value / 2, \"px\");\n        } else {\n          style[MARGIN_TYPE[direction][0]] = '';\n        }\n\n        if (i !== slides.length - 1) {\n          style[MARGIN_TYPE[direction][1]] = \"\".concat(this.value / 2, \"px\");\n        } else {\n          style[MARGIN_TYPE[direction][1]] = '';\n        }\n      }\n    },\n\n    /**\n     * Removes gaps from the slides.\n     *\n     * @param {HTMLCollection} slides\n     * @returns {Void}\n    */\n    remove: function remove(slides) {\n      for (var i = 0, len = slides.length; i < len; i++) {\n        var style = slides[i].style;\n        style.marginLeft = '';\n        style.marginRight = '';\n      }\n    }\n  };\n  define(Gaps, 'value', {\n    /**\n     * Gets value of the gap.\n     *\n     * @returns {Number}\n     */\n    get: function get() {\n      return toInt(Glide.settings.gap);\n    }\n  });\n  define(Gaps, 'grow', {\n    /**\n     * Gets additional dimensions value caused by gaps.\n     * Used to increase width of the slides wrapper.\n     *\n     * @returns {Number}\n     */\n    get: function get() {\n      return Gaps.value * Components.Sizes.length;\n    }\n  });\n  define(Gaps, 'reductor', {\n    /**\n     * Gets reduction value caused by gaps.\n     * Used to subtract width of the slides.\n     *\n     * @returns {Number}\n     */\n    get: function get() {\n      var perView = Glide.settings.perView;\n      return Gaps.value * (perView - 1) / perView;\n    }\n  });\n  /**\n   * Apply calculated gaps:\n   * - after building, so slides (including clones) will receive proper margins\n   * - on updating via API, to recalculate gaps with new options\n   */\n\n  Events.on(['build.after', 'update'], throttle(function () {\n    Gaps.apply(Components.Html.wrapper.children);\n  }, 30));\n  /**\n   * Remove gaps:\n   * - on destroying to bring markup to its inital state\n   */\n\n  Events.on('destroy', function () {\n    Gaps.remove(Components.Html.wrapper.children);\n  });\n  return Gaps;\n}\n\n/**\n * Finds siblings nodes of the passed node.\n *\n * @param  {Element} node\n * @return {Array}\n */\nfunction siblings(node) {\n  if (node && node.parentNode) {\n    var n = node.parentNode.firstChild;\n    var matched = [];\n\n    for (; n; n = n.nextSibling) {\n      if (n.nodeType === 1 && n !== node) {\n        matched.push(n);\n      }\n    }\n\n    return matched;\n  }\n\n  return [];\n}\n/**\n * Coerces a NodeList to an Array.\n *\n * @param  {NodeList} nodeList\n * @return {Array}\n */\n\nfunction toArray(nodeList) {\n  return Array.prototype.slice.call(nodeList);\n}\n\nvar TRACK_SELECTOR = '[data-glide-el=\"track\"]';\nfunction Html (Glide, Components, Events) {\n  var Html = {\n    /**\n     * Setup slider HTML nodes.\n     *\n     * @param {Glide} glide\n     */\n    mount: function mount() {\n      this.root = Glide.selector;\n      this.track = this.root.querySelector(TRACK_SELECTOR);\n      this.collectSlides();\n    },\n\n    /**\n     * Collect slides\n     */\n    collectSlides: function collectSlides() {\n      this.slides = toArray(this.wrapper.children).filter(function (slide) {\n        return !slide.classList.contains(Glide.settings.classes.slide.clone);\n      });\n    }\n  };\n  define(Html, 'root', {\n    /**\n     * Gets node of the glide main element.\n     *\n     * @return {Object}\n     */\n    get: function get() {\n      return Html._r;\n    },\n\n    /**\n     * Sets node of the glide main element.\n     *\n     * @return {Object}\n     */\n    set: function set(r) {\n      if (isString(r)) {\n        r = document.querySelector(r);\n      }\n\n      if (r !== null) {\n        Html._r = r;\n      } else {\n        warn('Root element must be a existing Html node');\n      }\n    }\n  });\n  define(Html, 'track', {\n    /**\n     * Gets node of the glide track with slides.\n     *\n     * @return {Object}\n     */\n    get: function get() {\n      return Html._t;\n    },\n\n    /**\n     * Sets node of the glide track with slides.\n     *\n     * @return {Object}\n     */\n    set: function set(t) {\n      Html._t = t;\n    }\n  });\n  define(Html, 'wrapper', {\n    /**\n     * Gets node of the slides wrapper.\n     *\n     * @return {Object}\n     */\n    get: function get() {\n      return Html.track.children[0];\n    }\n  });\n  /**\n   * Add/remove/reorder dynamic slides\n   */\n\n  Events.on('update', function () {\n    Html.collectSlides();\n  });\n  return Html;\n}\n\nfunction Peek (Glide, Components, Events) {\n  var Peek = {\n    /**\n     * Setups how much to peek based on settings.\n     *\n     * @return {Void}\n     */\n    mount: function mount() {\n      this.value = Glide.settings.peek;\n    }\n  };\n  define(Peek, 'value', {\n    /**\n     * Gets value of the peek.\n     *\n     * @returns {Number|Object}\n     */\n    get: function get() {\n      return Peek._v;\n    },\n\n    /**\n     * Sets value of the peek.\n     *\n     * @param {Number|Object} value\n     * @return {Void}\n     */\n    set: function set(value) {\n      if (isObject(value)) {\n        value.before = toInt(value.before);\n        value.after = toInt(value.after);\n      } else {\n        value = toInt(value);\n      }\n\n      Peek._v = value;\n    }\n  });\n  define(Peek, 'reductor', {\n    /**\n     * Gets reduction value caused by peek.\n     *\n     * @returns {Number}\n     */\n    get: function get() {\n      var value = Peek.value;\n      var perView = Glide.settings.perView;\n\n      if (isObject(value)) {\n        return value.before / perView + value.after / perView;\n      }\n\n      return value * 2 / perView;\n    }\n  });\n  /**\n   * Recalculate peeking sizes on:\n   * - when resizing window to update to proper percents\n   */\n\n  Events.on(['resize', 'update'], function () {\n    Peek.mount();\n  });\n  return Peek;\n}\n\nfunction Move (Glide, Components, Events) {\n  var Move = {\n    /**\n     * Constructs move component.\n     *\n     * @returns {Void}\n     */\n    mount: function mount() {\n      this._o = 0;\n    },\n\n    /**\n     * Calculates a movement value based on passed offset and currently active index.\n     *\n     * @param  {Number} offset\n     * @return {Void}\n     */\n    make: function make() {\n      var _this = this;\n\n      var offset = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;\n      this.offset = offset;\n      Events.emit('move', {\n        movement: this.value\n      });\n      Components.Transition.after(function () {\n        Events.emit('move.after', {\n          movement: _this.value\n        });\n      });\n    }\n  };\n  define(Move, 'offset', {\n    /**\n     * Gets an offset value used to modify current translate.\n     *\n     * @return {Object}\n     */\n    get: function get() {\n      return Move._o;\n    },\n\n    /**\n     * Sets an offset value used to modify current translate.\n     *\n     * @return {Object}\n     */\n    set: function set(value) {\n      Move._o = !isUndefined(value) ? toInt(value) : 0;\n    }\n  });\n  define(Move, 'translate', {\n    /**\n     * Gets a raw movement value.\n     *\n     * @return {Number}\n     */\n    get: function get() {\n      return Components.Sizes.slideWidth * Glide.index;\n    }\n  });\n  define(Move, 'value', {\n    /**\n     * Gets an actual movement value corrected by offset.\n     *\n     * @return {Number}\n     */\n    get: function get() {\n      var offset = this.offset;\n      var translate = this.translate;\n\n      if (Components.Direction.is('rtl')) {\n        return translate + offset;\n      }\n\n      return translate - offset;\n    }\n  });\n  /**\n   * Make movement to proper slide on:\n   * - before build, so glide will start at `startAt` index\n   * - on each standard run to move to newly calculated index\n   */\n\n  Events.on(['build.before', 'run'], function () {\n    Move.make();\n  });\n  return Move;\n}\n\nfunction Sizes (Glide, Components, Events) {\n  var Sizes = {\n    /**\n     * Setups dimensions of slides.\n     *\n     * @return {Void}\n     */\n    setupSlides: function setupSlides() {\n      var width = \"\".concat(this.slideWidth, \"px\");\n      var slides = Components.Html.slides;\n\n      for (var i = 0; i < slides.length; i++) {\n        slides[i].style.width = width;\n      }\n    },\n\n    /**\n     * Setups dimensions of slides wrapper.\n     *\n     * @return {Void}\n     */\n    setupWrapper: function setupWrapper() {\n      Components.Html.wrapper.style.width = \"\".concat(this.wrapperSize, \"px\");\n    },\n\n    /**\n     * Removes applied styles from HTML elements.\n     *\n     * @returns {Void}\n     */\n    remove: function remove() {\n      var slides = Components.Html.slides;\n\n      for (var i = 0; i < slides.length; i++) {\n        slides[i].style.width = '';\n      }\n\n      Components.Html.wrapper.style.width = '';\n    }\n  };\n  define(Sizes, 'length', {\n    /**\n     * Gets count number of the slides.\n     *\n     * @return {Number}\n     */\n    get: function get() {\n      return Components.Html.slides.length;\n    }\n  });\n  define(Sizes, 'width', {\n    /**\n     * Gets width value of the slider (visible area).\n     *\n     * @return {Number}\n     */\n    get: function get() {\n      return Components.Html.track.offsetWidth;\n    }\n  });\n  define(Sizes, 'wrapperSize', {\n    /**\n     * Gets size of the slides wrapper.\n     *\n     * @return {Number}\n     */\n    get: function get() {\n      return Sizes.slideWidth * Sizes.length + Components.Gaps.grow + Components.Clones.grow;\n    }\n  });\n  define(Sizes, 'slideWidth', {\n    /**\n     * Gets width value of a single slide.\n     *\n     * @return {Number}\n     */\n    get: function get() {\n      return Sizes.width / Glide.settings.perView - Components.Peek.reductor - Components.Gaps.reductor;\n    }\n  });\n  /**\n   * Apply calculated glide's dimensions:\n   * - before building, so other dimensions (e.g. translate) will be calculated propertly\n   * - when resizing window to recalculate sildes dimensions\n   * - on updating via API, to calculate dimensions based on new options\n   */\n\n  Events.on(['build.before', 'resize', 'update'], function () {\n    Sizes.setupSlides();\n    Sizes.setupWrapper();\n  });\n  /**\n   * Remove calculated glide's dimensions:\n   * - on destoting to bring markup to its inital state\n   */\n\n  Events.on('destroy', function () {\n    Sizes.remove();\n  });\n  return Sizes;\n}\n\nfunction Build (Glide, Components, Events) {\n  var Build = {\n    /**\n     * Init glide building. Adds classes, sets\n     * dimensions and setups initial state.\n     *\n     * @return {Void}\n     */\n    mount: function mount() {\n      Events.emit('build.before');\n      this.typeClass();\n      this.activeClass();\n      Events.emit('build.after');\n    },\n\n    /**\n     * Adds `type` class to the glide element.\n     *\n     * @return {Void}\n     */\n    typeClass: function typeClass() {\n      Components.Html.root.classList.add(Glide.settings.classes.type[Glide.settings.type]);\n    },\n\n    /**\n     * Sets active class to current slide.\n     *\n     * @return {Void}\n     */\n    activeClass: function activeClass() {\n      var classes = Glide.settings.classes;\n      var slide = Components.Html.slides[Glide.index];\n\n      if (slide) {\n        slide.classList.add(classes.slide.active);\n        siblings(slide).forEach(function (sibling) {\n          sibling.classList.remove(classes.slide.active);\n        });\n      }\n    },\n\n    /**\n     * Removes HTML classes applied at building.\n     *\n     * @return {Void}\n     */\n    removeClasses: function removeClasses() {\n      var _Glide$settings$class = Glide.settings.classes,\n          type = _Glide$settings$class.type,\n          slide = _Glide$settings$class.slide;\n      Components.Html.root.classList.remove(type[Glide.settings.type]);\n      Components.Html.slides.forEach(function (sibling) {\n        sibling.classList.remove(slide.active);\n      });\n    }\n  };\n  /**\n   * Clear building classes:\n   * - on destroying to bring HTML to its initial state\n   * - on updating to remove classes before remounting component\n   */\n\n  Events.on(['destroy', 'update'], function () {\n    Build.removeClasses();\n  });\n  /**\n   * Remount component:\n   * - on resizing of the window to calculate new dimensions\n   * - on updating settings via API\n   */\n\n  Events.on(['resize', 'update'], function () {\n    Build.mount();\n  });\n  /**\n   * Swap active class of current slide:\n   * - after each move to the new index\n   */\n\n  Events.on('move.after', function () {\n    Build.activeClass();\n  });\n  return Build;\n}\n\nfunction Clones (Glide, Components, Events) {\n  var Clones = {\n    /**\n     * Create pattern map and collect slides to be cloned.\n     */\n    mount: function mount() {\n      this.items = [];\n\n      if (Glide.isType('carousel')) {\n        this.items = this.collect();\n      }\n    },\n\n    /**\n     * Collect clones with pattern.\n     *\n     * @return {[]}\n     */\n    collect: function collect() {\n      var items = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];\n      var slides = Components.Html.slides;\n      var _Glide$settings = Glide.settings,\n          perView = _Glide$settings.perView,\n          classes = _Glide$settings.classes,\n          cloningRatio = _Glide$settings.cloningRatio;\n\n      if (slides.length > 0) {\n        var peekIncrementer = +!!Glide.settings.peek;\n        var cloneCount = perView + peekIncrementer + Math.round(perView / 2);\n        var append = slides.slice(0, cloneCount).reverse();\n        var prepend = slides.slice(cloneCount * -1);\n\n        for (var r = 0; r < Math.max(cloningRatio, Math.floor(perView / slides.length)); r++) {\n          for (var i = 0; i < append.length; i++) {\n            var clone = append[i].cloneNode(true);\n            clone.classList.add(classes.slide.clone);\n            items.push(clone);\n          }\n\n          for (var _i = 0; _i < prepend.length; _i++) {\n            var _clone = prepend[_i].cloneNode(true);\n\n            _clone.classList.add(classes.slide.clone);\n\n            items.unshift(_clone);\n          }\n        }\n      }\n\n      return items;\n    },\n\n    /**\n     * Append cloned slides with generated pattern.\n     *\n     * @return {Void}\n     */\n    append: function append() {\n      var items = this.items;\n      var _Components$Html = Components.Html,\n          wrapper = _Components$Html.wrapper,\n          slides = _Components$Html.slides;\n      var half = Math.floor(items.length / 2);\n      var prepend = items.slice(0, half).reverse();\n      var append = items.slice(half * -1).reverse();\n      var width = \"\".concat(Components.Sizes.slideWidth, \"px\");\n\n      for (var i = 0; i < append.length; i++) {\n        wrapper.appendChild(append[i]);\n      }\n\n      for (var _i2 = 0; _i2 < prepend.length; _i2++) {\n        wrapper.insertBefore(prepend[_i2], slides[0]);\n      }\n\n      for (var _i3 = 0; _i3 < items.length; _i3++) {\n        items[_i3].style.width = width;\n      }\n    },\n\n    /**\n     * Remove all cloned slides.\n     *\n     * @return {Void}\n     */\n    remove: function remove() {\n      var items = this.items;\n\n      for (var i = 0; i < items.length; i++) {\n        Components.Html.wrapper.removeChild(items[i]);\n      }\n    }\n  };\n  define(Clones, 'grow', {\n    /**\n     * Gets additional dimensions value caused by clones.\n     *\n     * @return {Number}\n     */\n    get: function get() {\n      return (Components.Sizes.slideWidth + Components.Gaps.value) * Clones.items.length;\n    }\n  });\n  /**\n   * Append additional slide's clones:\n   * - while glide's type is `carousel`\n   */\n\n  Events.on('update', function () {\n    Clones.remove();\n    Clones.mount();\n    Clones.append();\n  });\n  /**\n   * Append additional slide's clones:\n   * - while glide's type is `carousel`\n   */\n\n  Events.on('build.before', function () {\n    if (Glide.isType('carousel')) {\n      Clones.append();\n    }\n  });\n  /**\n   * Remove clones HTMLElements:\n   * - on destroying, to bring HTML to its initial state\n   */\n\n  Events.on('destroy', function () {\n    Clones.remove();\n  });\n  return Clones;\n}\n\nvar EventsBinder = /*#__PURE__*/function () {\n  /**\n   * Construct a EventsBinder instance.\n   */\n  function EventsBinder() {\n    var listeners = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n    _classCallCheck(this, EventsBinder);\n\n    this.listeners = listeners;\n  }\n  /**\n   * Adds events listeners to arrows HTML elements.\n   *\n   * @param  {String|Array} events\n   * @param  {Element|Window|Document} el\n   * @param  {Function} closure\n   * @param  {Boolean|Object} capture\n   * @return {Void}\n   */\n\n\n  _createClass(EventsBinder, [{\n    key: \"on\",\n    value: function on(events, el, closure) {\n      var capture = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;\n\n      if (isString(events)) {\n        events = [events];\n      }\n\n      for (var i = 0; i < events.length; i++) {\n        this.listeners[events[i]] = closure;\n        el.addEventListener(events[i], this.listeners[events[i]], capture);\n      }\n    }\n    /**\n     * Removes event listeners from arrows HTML elements.\n     *\n     * @param  {String|Array} events\n     * @param  {Element|Window|Document} el\n     * @param  {Boolean|Object} capture\n     * @return {Void}\n     */\n\n  }, {\n    key: \"off\",\n    value: function off(events, el) {\n      var capture = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;\n\n      if (isString(events)) {\n        events = [events];\n      }\n\n      for (var i = 0; i < events.length; i++) {\n        el.removeEventListener(events[i], this.listeners[events[i]], capture);\n      }\n    }\n    /**\n     * Destroy collected listeners.\n     *\n     * @returns {Void}\n     */\n\n  }, {\n    key: \"destroy\",\n    value: function destroy() {\n      delete this.listeners;\n    }\n  }]);\n\n  return EventsBinder;\n}();\n\nfunction Resize (Glide, Components, Events) {\n  /**\n   * Instance of the binder for DOM Events.\n   *\n   * @type {EventsBinder}\n   */\n  var Binder = new EventsBinder();\n  var Resize = {\n    /**\n     * Initializes window bindings.\n     */\n    mount: function mount() {\n      this.bind();\n    },\n\n    /**\n     * Binds `rezsize` listener to the window.\n     * It's a costly event, so we are debouncing it.\n     *\n     * @return {Void}\n     */\n    bind: function bind() {\n      Binder.on('resize', window, throttle(function () {\n        Events.emit('resize');\n      }, Glide.settings.throttle));\n    },\n\n    /**\n     * Unbinds listeners from the window.\n     *\n     * @return {Void}\n     */\n    unbind: function unbind() {\n      Binder.off('resize', window);\n    }\n  };\n  /**\n   * Remove bindings from window:\n   * - on destroying, to remove added EventListener\n   */\n\n  Events.on('destroy', function () {\n    Resize.unbind();\n    Binder.destroy();\n  });\n  return Resize;\n}\n\nvar VALID_DIRECTIONS = ['ltr', 'rtl'];\nvar FLIPED_MOVEMENTS = {\n  '>': '<',\n  '<': '>',\n  '=': '='\n};\nfunction Direction (Glide, Components, Events) {\n  var Direction = {\n    /**\n     * Setups gap value based on settings.\n     *\n     * @return {Void}\n     */\n    mount: function mount() {\n      this.value = Glide.settings.direction;\n    },\n\n    /**\n     * Resolves pattern based on direction value\n     *\n     * @param {String} pattern\n     * @returns {String}\n     */\n    resolve: function resolve(pattern) {\n      var token = pattern.slice(0, 1);\n\n      if (this.is('rtl')) {\n        return pattern.split(token).join(FLIPED_MOVEMENTS[token]);\n      }\n\n      return pattern;\n    },\n\n    /**\n     * Checks value of direction mode.\n     *\n     * @param {String} direction\n     * @returns {Boolean}\n     */\n    is: function is(direction) {\n      return this.value === direction;\n    },\n\n    /**\n     * Applies direction class to the root HTML element.\n     *\n     * @return {Void}\n     */\n    addClass: function addClass() {\n      Components.Html.root.classList.add(Glide.settings.classes.direction[this.value]);\n    },\n\n    /**\n     * Removes direction class from the root HTML element.\n     *\n     * @return {Void}\n     */\n    removeClass: function removeClass() {\n      Components.Html.root.classList.remove(Glide.settings.classes.direction[this.value]);\n    }\n  };\n  define(Direction, 'value', {\n    /**\n     * Gets value of the direction.\n     *\n     * @returns {Number}\n     */\n    get: function get() {\n      return Direction._v;\n    },\n\n    /**\n     * Sets value of the direction.\n     *\n     * @param {String} value\n     * @return {Void}\n     */\n    set: function set(value) {\n      if (VALID_DIRECTIONS.indexOf(value) > -1) {\n        Direction._v = value;\n      } else {\n        warn('Direction value must be `ltr` or `rtl`');\n      }\n    }\n  });\n  /**\n   * Clear direction class:\n   * - on destroy to bring HTML to its initial state\n   * - on update to remove class before reappling bellow\n   */\n\n  Events.on(['destroy', 'update'], function () {\n    Direction.removeClass();\n  });\n  /**\n   * Remount component:\n   * - on update to reflect changes in direction value\n   */\n\n  Events.on('update', function () {\n    Direction.mount();\n  });\n  /**\n   * Apply direction class:\n   * - before building to apply class for the first time\n   * - on updating to reapply direction class that may changed\n   */\n\n  Events.on(['build.before', 'update'], function () {\n    Direction.addClass();\n  });\n  return Direction;\n}\n\n/**\n * Reflects value of glide movement.\n *\n * @param  {Object} Glide\n * @param  {Object} Components\n * @return {Object}\n */\nfunction Rtl (Glide, Components) {\n  return {\n    /**\n     * Negates the passed translate if glide is in RTL option.\n     *\n     * @param  {Number} translate\n     * @return {Number}\n     */\n    modify: function modify(translate) {\n      if (Components.Direction.is('rtl')) {\n        return -translate;\n      }\n\n      return translate;\n    }\n  };\n}\n\n/**\n * Updates glide movement with a `gap` settings.\n *\n * @param  {Object} Glide\n * @param  {Object} Components\n * @return {Object}\n */\nfunction Gap (Glide, Components) {\n  return {\n    /**\n     * Modifies passed translate value with number in the `gap` settings.\n     *\n     * @param  {Number} translate\n     * @return {Number}\n     */\n    modify: function modify(translate) {\n      var multiplier = Math.floor(translate / Components.Sizes.slideWidth);\n      return translate + Components.Gaps.value * multiplier;\n    }\n  };\n}\n\n/**\n * Updates glide movement with width of additional clones width.\n *\n * @param  {Object} Glide\n * @param  {Object} Components\n * @return {Object}\n */\nfunction Grow (Glide, Components) {\n  return {\n    /**\n     * Adds to the passed translate width of the half of clones.\n     *\n     * @param  {Number} translate\n     * @return {Number}\n     */\n    modify: function modify(translate) {\n      return translate + Components.Clones.grow / 2;\n    }\n  };\n}\n\n/**\n * Updates glide movement with a `peek` settings.\n *\n * @param  {Object} Glide\n * @param  {Object} Components\n * @return {Object}\n */\n\nfunction Peeking (Glide, Components) {\n  return {\n    /**\n     * Modifies passed translate value with a `peek` setting.\n     *\n     * @param  {Number} translate\n     * @return {Number}\n     */\n    modify: function modify(translate) {\n      if (Glide.settings.focusAt >= 0) {\n        var peek = Components.Peek.value;\n\n        if (isObject(peek)) {\n          return translate - peek.before;\n        }\n\n        return translate - peek;\n      }\n\n      return translate;\n    }\n  };\n}\n\n/**\n * Updates glide movement with a `focusAt` settings.\n *\n * @param  {Object} Glide\n * @param  {Object} Components\n * @return {Object}\n */\nfunction Focusing (Glide, Components) {\n  return {\n    /**\n     * Modifies passed translate value with index in the `focusAt` setting.\n     *\n     * @param  {Number} translate\n     * @return {Number}\n     */\n    modify: function modify(translate) {\n      var gap = Components.Gaps.value;\n      var width = Components.Sizes.width;\n      var focusAt = Glide.settings.focusAt;\n      var slideWidth = Components.Sizes.slideWidth;\n\n      if (focusAt === 'center') {\n        return translate - (width / 2 - slideWidth / 2);\n      }\n\n      return translate - slideWidth * focusAt - gap * focusAt;\n    }\n  };\n}\n\n/**\n * Applies diffrent transformers on translate value.\n *\n * @param  {Object} Glide\n * @param  {Object} Components\n * @return {Object}\n */\n\nfunction mutator (Glide, Components, Events) {\n  /**\n   * Merge instance transformers with collection of default transformers.\n   * It's important that the Rtl component be last on the list,\n   * so it reflects all previous transformations.\n   *\n   * @type {Array}\n   */\n  var TRANSFORMERS = [Gap, Grow, Peeking, Focusing].concat(Glide._t, [Rtl]);\n  return {\n    /**\n     * Piplines translate value with registered transformers.\n     *\n     * @param  {Number} translate\n     * @return {Number}\n     */\n    mutate: function mutate(translate) {\n      for (var i = 0; i < TRANSFORMERS.length; i++) {\n        var transformer = TRANSFORMERS[i];\n\n        if (isFunction(transformer) && isFunction(transformer().modify)) {\n          translate = transformer(Glide, Components, Events).modify(translate);\n        } else {\n          warn('Transformer should be a function that returns an object with `modify()` method');\n        }\n      }\n\n      return translate;\n    }\n  };\n}\n\nfunction Translate (Glide, Components, Events) {\n  var Translate = {\n    /**\n     * Sets value of translate on HTML element.\n     *\n     * @param {Number} value\n     * @return {Void}\n     */\n    set: function set(value) {\n      var transform = mutator(Glide, Components).mutate(value);\n      var translate3d = \"translate3d(\".concat(-1 * transform, \"px, 0px, 0px)\");\n      Components.Html.wrapper.style.mozTransform = translate3d; // needed for supported Firefox 10-15\n\n      Components.Html.wrapper.style.webkitTransform = translate3d; // needed for supported Chrome 10-35, Safari 5.1-8, and Opera 15-22\n\n      Components.Html.wrapper.style.transform = translate3d;\n    },\n\n    /**\n     * Removes value of translate from HTML element.\n     *\n     * @return {Void}\n     */\n    remove: function remove() {\n      Components.Html.wrapper.style.transform = '';\n    },\n\n    /**\n     * @return {number}\n     */\n    getStartIndex: function getStartIndex() {\n      var length = Components.Sizes.length;\n      var index = Glide.index;\n      var perView = Glide.settings.perView;\n\n      if (Components.Run.isOffset('>') || Components.Run.isOffset('|>')) {\n        return length + (index - perView);\n      } // \"modulo length\" converts an index that equals length to zero\n\n\n      return (index + perView) % length;\n    },\n\n    /**\n     * @return {number}\n     */\n    getTravelDistance: function getTravelDistance() {\n      var travelDistance = Components.Sizes.slideWidth * Glide.settings.perView;\n\n      if (Components.Run.isOffset('>') || Components.Run.isOffset('|>')) {\n        // reverse travel distance so that we don't have to change subtract operations\n        return travelDistance * -1;\n      }\n\n      return travelDistance;\n    }\n  };\n  /**\n   * Set new translate value:\n   * - on move to reflect index change\n   * - on updating via API to reflect possible changes in options\n   */\n\n  Events.on('move', function (context) {\n    if (!Glide.isType('carousel') || !Components.Run.isOffset()) {\n      return Translate.set(context.movement);\n    }\n\n    Components.Transition.after(function () {\n      Events.emit('translate.jump');\n      Translate.set(Components.Sizes.slideWidth * Glide.index);\n    });\n    var startWidth = Components.Sizes.slideWidth * Components.Translate.getStartIndex();\n    return Translate.set(startWidth - Components.Translate.getTravelDistance());\n  });\n  /**\n   * Remove translate:\n   * - on destroying to bring markup to its inital state\n   */\n\n  Events.on('destroy', function () {\n    Translate.remove();\n  });\n  return Translate;\n}\n\nfunction Transition (Glide, Components, Events) {\n  /**\n   * Holds inactivity status of transition.\n   * When true transition is not applied.\n   *\n   * @type {Boolean}\n   */\n  var disabled = false;\n  var Transition = {\n    /**\n     * Composes string of the CSS transition.\n     *\n     * @param {String} property\n     * @return {String}\n     */\n    compose: function compose(property) {\n      var settings = Glide.settings;\n\n      if (disabled) {\n        return \"\".concat(property, \" 0ms \").concat(settings.animationTimingFunc);\n      }\n\n      return \"\".concat(property, \" \").concat(this.duration, \"ms \").concat(settings.animationTimingFunc);\n    },\n\n    /**\n     * Sets value of transition on HTML element.\n     *\n     * @param {String=} property\n     * @return {Void}\n     */\n    set: function set() {\n      var property = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'transform';\n      Components.Html.wrapper.style.transition = this.compose(property);\n    },\n\n    /**\n     * Removes value of transition from HTML element.\n     *\n     * @return {Void}\n     */\n    remove: function remove() {\n      Components.Html.wrapper.style.transition = '';\n    },\n\n    /**\n     * Runs callback after animation.\n     *\n     * @param  {Function} callback\n     * @return {Void}\n     */\n    after: function after(callback) {\n      setTimeout(function () {\n        callback();\n      }, this.duration);\n    },\n\n    /**\n     * Enable transition.\n     *\n     * @return {Void}\n     */\n    enable: function enable() {\n      disabled = false;\n      this.set();\n    },\n\n    /**\n     * Disable transition.\n     *\n     * @return {Void}\n     */\n    disable: function disable() {\n      disabled = true;\n      this.set();\n    }\n  };\n  define(Transition, 'duration', {\n    /**\n     * Gets duration of the transition based\n     * on currently running animation type.\n     *\n     * @return {Number}\n     */\n    get: function get() {\n      var settings = Glide.settings;\n\n      if (Glide.isType('slider') && Components.Run.offset) {\n        return settings.rewindDuration;\n      }\n\n      return settings.animationDuration;\n    }\n  });\n  /**\n   * Set transition `style` value:\n   * - on each moving, because it may be cleared by offset move\n   */\n\n  Events.on('move', function () {\n    Transition.set();\n  });\n  /**\n   * Disable transition:\n   * - before initial build to avoid transitioning from `0` to `startAt` index\n   * - while resizing window and recalculating dimensions\n   * - on jumping from offset transition at start and end edges in `carousel` type\n   */\n\n  Events.on(['build.before', 'resize', 'translate.jump'], function () {\n    Transition.disable();\n  });\n  /**\n   * Enable transition:\n   * - on each running, because it may be disabled by offset move\n   */\n\n  Events.on('run', function () {\n    Transition.enable();\n  });\n  /**\n   * Remove transition:\n   * - on destroying to bring markup to its inital state\n   */\n\n  Events.on('destroy', function () {\n    Transition.remove();\n  });\n  return Transition;\n}\n\n/**\n * Test via a getter in the options object to see\n * if the passive property is accessed.\n *\n * @see https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md#feature-detection\n */\nvar supportsPassive = false;\n\ntry {\n  var opts = Object.defineProperty({}, 'passive', {\n    get: function get() {\n      supportsPassive = true;\n    }\n  });\n  window.addEventListener('testPassive', null, opts);\n  window.removeEventListener('testPassive', null, opts);\n} catch (e) {}\n\nvar supportsPassive$1 = supportsPassive;\n\nvar START_EVENTS = ['touchstart', 'mousedown'];\nvar MOVE_EVENTS = ['touchmove', 'mousemove'];\nvar END_EVENTS = ['touchend', 'touchcancel', 'mouseup', 'mouseleave'];\nvar MOUSE_EVENTS = ['mousedown', 'mousemove', 'mouseup', 'mouseleave'];\nfunction Swipe (Glide, Components, Events) {\n  /**\n   * Instance of the binder for DOM Events.\n   *\n   * @type {EventsBinder}\n   */\n  var Binder = new EventsBinder();\n  var swipeSin = 0;\n  var swipeStartX = 0;\n  var swipeStartY = 0;\n  var disabled = false;\n  var capture = supportsPassive$1 ? {\n    passive: true\n  } : false;\n  var Swipe = {\n    /**\n     * Initializes swipe bindings.\n     *\n     * @return {Void}\n     */\n    mount: function mount() {\n      this.bindSwipeStart();\n    },\n\n    /**\n     * Handler for `swipestart` event. Calculates entry points of the user's tap.\n     *\n     * @param {Object} event\n     * @return {Void}\n     */\n    start: function start(event) {\n      if (!disabled && !Glide.disabled) {\n        this.disable();\n        var swipe = this.touches(event);\n        swipeSin = null;\n        swipeStartX = toInt(swipe.pageX);\n        swipeStartY = toInt(swipe.pageY);\n        this.bindSwipeMove();\n        this.bindSwipeEnd();\n        Events.emit('swipe.start');\n      }\n    },\n\n    /**\n     * Handler for `swipemove` event. Calculates user's tap angle and distance.\n     *\n     * @param {Object} event\n     */\n    move: function move(event) {\n      if (!Glide.disabled) {\n        var _Glide$settings = Glide.settings,\n            touchAngle = _Glide$settings.touchAngle,\n            touchRatio = _Glide$settings.touchRatio,\n            classes = _Glide$settings.classes;\n        var swipe = this.touches(event);\n        var subExSx = toInt(swipe.pageX) - swipeStartX;\n        var subEySy = toInt(swipe.pageY) - swipeStartY;\n        var powEX = Math.abs(subExSx << 2);\n        var powEY = Math.abs(subEySy << 2);\n        var swipeHypotenuse = Math.sqrt(powEX + powEY);\n        var swipeCathetus = Math.sqrt(powEY);\n        swipeSin = Math.asin(swipeCathetus / swipeHypotenuse);\n\n        if (swipeSin * 180 / Math.PI < touchAngle) {\n          event.stopPropagation();\n          Components.Move.make(subExSx * toFloat(touchRatio));\n          Components.Html.root.classList.add(classes.dragging);\n          Events.emit('swipe.move');\n        } else {\n          return false;\n        }\n      }\n    },\n\n    /**\n     * Handler for `swipeend` event. Finitializes user's tap and decides about glide move.\n     *\n     * @param {Object} event\n     * @return {Void}\n     */\n    end: function end(event) {\n      if (!Glide.disabled) {\n        var _Glide$settings2 = Glide.settings,\n            perSwipe = _Glide$settings2.perSwipe,\n            touchAngle = _Glide$settings2.touchAngle,\n            classes = _Glide$settings2.classes;\n        var swipe = this.touches(event);\n        var threshold = this.threshold(event);\n        var swipeDistance = swipe.pageX - swipeStartX;\n        var swipeDeg = swipeSin * 180 / Math.PI;\n        this.enable();\n\n        if (swipeDistance > threshold && swipeDeg < touchAngle) {\n          Components.Run.make(Components.Direction.resolve(\"\".concat(perSwipe, \"<\")));\n        } else if (swipeDistance < -threshold && swipeDeg < touchAngle) {\n          Components.Run.make(Components.Direction.resolve(\"\".concat(perSwipe, \">\")));\n        } else {\n          // While swipe don't reach distance apply previous transform.\n          Components.Move.make();\n        }\n\n        Components.Html.root.classList.remove(classes.dragging);\n        this.unbindSwipeMove();\n        this.unbindSwipeEnd();\n        Events.emit('swipe.end');\n      }\n    },\n\n    /**\n     * Binds swipe's starting event.\n     *\n     * @return {Void}\n     */\n    bindSwipeStart: function bindSwipeStart() {\n      var _this = this;\n\n      var _Glide$settings3 = Glide.settings,\n          swipeThreshold = _Glide$settings3.swipeThreshold,\n          dragThreshold = _Glide$settings3.dragThreshold;\n\n      if (swipeThreshold) {\n        Binder.on(START_EVENTS[0], Components.Html.wrapper, function (event) {\n          _this.start(event);\n        }, capture);\n      }\n\n      if (dragThreshold) {\n        Binder.on(START_EVENTS[1], Components.Html.wrapper, function (event) {\n          _this.start(event);\n        }, capture);\n      }\n    },\n\n    /**\n     * Unbinds swipe's starting event.\n     *\n     * @return {Void}\n     */\n    unbindSwipeStart: function unbindSwipeStart() {\n      Binder.off(START_EVENTS[0], Components.Html.wrapper, capture);\n      Binder.off(START_EVENTS[1], Components.Html.wrapper, capture);\n    },\n\n    /**\n     * Binds swipe's moving event.\n     *\n     * @return {Void}\n     */\n    bindSwipeMove: function bindSwipeMove() {\n      var _this2 = this;\n\n      Binder.on(MOVE_EVENTS, Components.Html.wrapper, throttle(function (event) {\n        _this2.move(event);\n      }, Glide.settings.throttle), capture);\n    },\n\n    /**\n     * Unbinds swipe's moving event.\n     *\n     * @return {Void}\n     */\n    unbindSwipeMove: function unbindSwipeMove() {\n      Binder.off(MOVE_EVENTS, Components.Html.wrapper, capture);\n    },\n\n    /**\n     * Binds swipe's ending event.\n     *\n     * @return {Void}\n     */\n    bindSwipeEnd: function bindSwipeEnd() {\n      var _this3 = this;\n\n      Binder.on(END_EVENTS, Components.Html.wrapper, function (event) {\n        _this3.end(event);\n      });\n    },\n\n    /**\n     * Unbinds swipe's ending event.\n     *\n     * @return {Void}\n     */\n    unbindSwipeEnd: function unbindSwipeEnd() {\n      Binder.off(END_EVENTS, Components.Html.wrapper);\n    },\n\n    /**\n     * Normalizes event touches points accorting to different types.\n     *\n     * @param {Object} event\n     */\n    touches: function touches(event) {\n      if (MOUSE_EVENTS.indexOf(event.type) > -1) {\n        return event;\n      }\n\n      return event.touches[0] || event.changedTouches[0];\n    },\n\n    /**\n     * Gets value of minimum swipe distance settings based on event type.\n     *\n     * @return {Number}\n     */\n    threshold: function threshold(event) {\n      var settings = Glide.settings;\n\n      if (MOUSE_EVENTS.indexOf(event.type) > -1) {\n        return settings.dragThreshold;\n      }\n\n      return settings.swipeThreshold;\n    },\n\n    /**\n     * Enables swipe event.\n     *\n     * @return {self}\n     */\n    enable: function enable() {\n      disabled = false;\n      Components.Transition.enable();\n      return this;\n    },\n\n    /**\n     * Disables swipe event.\n     *\n     * @return {self}\n     */\n    disable: function disable() {\n      disabled = true;\n      Components.Transition.disable();\n      return this;\n    }\n  };\n  /**\n   * Add component class:\n   * - after initial building\n   */\n\n  Events.on('build.after', function () {\n    Components.Html.root.classList.add(Glide.settings.classes.swipeable);\n  });\n  /**\n   * Remove swiping bindings:\n   * - on destroying, to remove added EventListeners\n   */\n\n  Events.on('destroy', function () {\n    Swipe.unbindSwipeStart();\n    Swipe.unbindSwipeMove();\n    Swipe.unbindSwipeEnd();\n    Binder.destroy();\n  });\n  return Swipe;\n}\n\nfunction Images (Glide, Components, Events) {\n  /**\n   * Instance of the binder for DOM Events.\n   *\n   * @type {EventsBinder}\n   */\n  var Binder = new EventsBinder();\n  var Images = {\n    /**\n     * Binds listener to glide wrapper.\n     *\n     * @return {Void}\n     */\n    mount: function mount() {\n      this.bind();\n    },\n\n    /**\n     * Binds `dragstart` event on wrapper to prevent dragging images.\n     *\n     * @return {Void}\n     */\n    bind: function bind() {\n      Binder.on('dragstart', Components.Html.wrapper, this.dragstart);\n    },\n\n    /**\n     * Unbinds `dragstart` event on wrapper.\n     *\n     * @return {Void}\n     */\n    unbind: function unbind() {\n      Binder.off('dragstart', Components.Html.wrapper);\n    },\n\n    /**\n     * Event handler. Prevents dragging.\n     *\n     * @return {Void}\n     */\n    dragstart: function dragstart(event) {\n      event.preventDefault();\n    }\n  };\n  /**\n   * Remove bindings from images:\n   * - on destroying, to remove added EventListeners\n   */\n\n  Events.on('destroy', function () {\n    Images.unbind();\n    Binder.destroy();\n  });\n  return Images;\n}\n\nfunction Anchors (Glide, Components, Events) {\n  /**\n   * Instance of the binder for DOM Events.\n   *\n   * @type {EventsBinder}\n   */\n  var Binder = new EventsBinder();\n  /**\n   * Holds detaching status of anchors.\n   * Prevents detaching of already detached anchors.\n   *\n   * @private\n   * @type {Boolean}\n   */\n\n  var detached = false;\n  /**\n   * Holds preventing status of anchors.\n   * If `true` redirection after click will be disabled.\n   *\n   * @private\n   * @type {Boolean}\n   */\n\n  var prevented = false;\n  var Anchors = {\n    /**\n     * Setups a initial state of anchors component.\n     *\n     * @returns {Void}\n     */\n    mount: function mount() {\n      /**\n       * Holds collection of anchors elements.\n       *\n       * @private\n       * @type {HTMLCollection}\n       */\n      this._a = Components.Html.wrapper.querySelectorAll('a');\n      this.bind();\n    },\n\n    /**\n     * Binds events to anchors inside a track.\n     *\n     * @return {Void}\n     */\n    bind: function bind() {\n      Binder.on('click', Components.Html.wrapper, this.click);\n    },\n\n    /**\n     * Unbinds events attached to anchors inside a track.\n     *\n     * @return {Void}\n     */\n    unbind: function unbind() {\n      Binder.off('click', Components.Html.wrapper);\n    },\n\n    /**\n     * Handler for click event. Prevents clicks when glide is in `prevent` status.\n     *\n     * @param  {Object} event\n     * @return {Void}\n     */\n    click: function click(event) {\n      if (prevented) {\n        event.stopPropagation();\n        event.preventDefault();\n      }\n    },\n\n    /**\n     * Detaches anchors click event inside glide.\n     *\n     * @return {self}\n     */\n    detach: function detach() {\n      prevented = true;\n\n      if (!detached) {\n        for (var i = 0; i < this.items.length; i++) {\n          this.items[i].draggable = false;\n        }\n\n        detached = true;\n      }\n\n      return this;\n    },\n\n    /**\n     * Attaches anchors click events inside glide.\n     *\n     * @return {self}\n     */\n    attach: function attach() {\n      prevented = false;\n\n      if (detached) {\n        for (var i = 0; i < this.items.length; i++) {\n          this.items[i].draggable = true;\n        }\n\n        detached = false;\n      }\n\n      return this;\n    }\n  };\n  define(Anchors, 'items', {\n    /**\n     * Gets collection of the arrows HTML elements.\n     *\n     * @return {HTMLElement[]}\n     */\n    get: function get() {\n      return Anchors._a;\n    }\n  });\n  /**\n   * Detach anchors inside slides:\n   * - on swiping, so they won't redirect to its `href` attributes\n   */\n\n  Events.on('swipe.move', function () {\n    Anchors.detach();\n  });\n  /**\n   * Attach anchors inside slides:\n   * - after swiping and transitions ends, so they can redirect after click again\n   */\n\n  Events.on('swipe.end', function () {\n    Components.Transition.after(function () {\n      Anchors.attach();\n    });\n  });\n  /**\n   * Unbind anchors inside slides:\n   * - on destroying, to bring anchors to its initial state\n   */\n\n  Events.on('destroy', function () {\n    Anchors.attach();\n    Anchors.unbind();\n    Binder.destroy();\n  });\n  return Anchors;\n}\n\nvar NAV_SELECTOR = '[data-glide-el=\"controls[nav]\"]';\nvar CONTROLS_SELECTOR = '[data-glide-el^=\"controls\"]';\nvar PREVIOUS_CONTROLS_SELECTOR = \"\".concat(CONTROLS_SELECTOR, \" [data-glide-dir*=\\\"<\\\"]\");\nvar NEXT_CONTROLS_SELECTOR = \"\".concat(CONTROLS_SELECTOR, \" [data-glide-dir*=\\\">\\\"]\");\nfunction Controls (Glide, Components, Events) {\n  /**\n   * Instance of the binder for DOM Events.\n   *\n   * @type {EventsBinder}\n   */\n  var Binder = new EventsBinder();\n  var capture = supportsPassive$1 ? {\n    passive: true\n  } : false;\n  var Controls = {\n    /**\n     * Inits arrows. Binds events listeners\n     * to the arrows HTML elements.\n     *\n     * @return {Void}\n     */\n    mount: function mount() {\n      /**\n       * Collection of navigation HTML elements.\n       *\n       * @private\n       * @type {HTMLCollection}\n       */\n      this._n = Components.Html.root.querySelectorAll(NAV_SELECTOR);\n      /**\n       * Collection of controls HTML elements.\n       *\n       * @private\n       * @type {HTMLCollection}\n       */\n\n      this._c = Components.Html.root.querySelectorAll(CONTROLS_SELECTOR);\n      /**\n       * Collection of arrow control HTML elements.\n       *\n       * @private\n       * @type {Object}\n       */\n\n      this._arrowControls = {\n        previous: Components.Html.root.querySelectorAll(PREVIOUS_CONTROLS_SELECTOR),\n        next: Components.Html.root.querySelectorAll(NEXT_CONTROLS_SELECTOR)\n      };\n      this.addBindings();\n    },\n\n    /**\n     * Sets active class to current slide.\n     *\n     * @return {Void}\n     */\n    setActive: function setActive() {\n      for (var i = 0; i < this._n.length; i++) {\n        this.addClass(this._n[i].children);\n      }\n    },\n\n    /**\n     * Removes active class to current slide.\n     *\n     * @return {Void}\n     */\n    removeActive: function removeActive() {\n      for (var i = 0; i < this._n.length; i++) {\n        this.removeClass(this._n[i].children);\n      }\n    },\n\n    /**\n     * Toggles active class on items inside navigation.\n     *\n     * @param  {HTMLElement} controls\n     * @return {Void}\n     */\n    addClass: function addClass(controls) {\n      var settings = Glide.settings;\n      var item = controls[Glide.index];\n\n      if (!item) {\n        return;\n      }\n\n      item.classList.add(settings.classes.nav.active);\n      siblings(item).forEach(function (sibling) {\n        sibling.classList.remove(settings.classes.nav.active);\n      });\n    },\n\n    /**\n     * Removes active class from active control.\n     *\n     * @param  {HTMLElement} controls\n     * @return {Void}\n     */\n    removeClass: function removeClass(controls) {\n      var item = controls[Glide.index];\n      item === null || item === void 0 ? void 0 : item.classList.remove(Glide.settings.classes.nav.active);\n    },\n\n    /**\n     * Calculates, removes or adds `Glide.settings.classes.disabledArrow` class on the control arrows\n     */\n    setArrowState: function setArrowState() {\n      if (Glide.settings.rewind) {\n        return;\n      }\n\n      var next = Controls._arrowControls.next;\n      var previous = Controls._arrowControls.previous;\n      this.resetArrowState(next, previous);\n\n      if (Glide.index === 0) {\n        this.disableArrow(previous);\n      }\n\n      if (Glide.index === Components.Run.length) {\n        this.disableArrow(next);\n      }\n    },\n\n    /**\n     * Removes `Glide.settings.classes.disabledArrow` from given NodeList elements\n     *\n     * @param {NodeList[]} lists\n     */\n    resetArrowState: function resetArrowState() {\n      var settings = Glide.settings;\n\n      for (var _len = arguments.length, lists = new Array(_len), _key = 0; _key < _len; _key++) {\n        lists[_key] = arguments[_key];\n      }\n\n      lists.forEach(function (list) {\n        toArray(list).forEach(function (element) {\n          element.classList.remove(settings.classes.arrow.disabled);\n        });\n      });\n    },\n\n    /**\n     * Adds `Glide.settings.classes.disabledArrow` to given NodeList elements\n     *\n     * @param {NodeList[]} lists\n     */\n    disableArrow: function disableArrow() {\n      var settings = Glide.settings;\n\n      for (var _len2 = arguments.length, lists = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {\n        lists[_key2] = arguments[_key2];\n      }\n\n      lists.forEach(function (list) {\n        toArray(list).forEach(function (element) {\n          element.classList.add(settings.classes.arrow.disabled);\n        });\n      });\n    },\n\n    /**\n     * Adds handles to the each group of controls.\n     *\n     * @return {Void}\n     */\n    addBindings: function addBindings() {\n      for (var i = 0; i < this._c.length; i++) {\n        this.bind(this._c[i].children);\n      }\n    },\n\n    /**\n     * Removes handles from the each group of controls.\n     *\n     * @return {Void}\n     */\n    removeBindings: function removeBindings() {\n      for (var i = 0; i < this._c.length; i++) {\n        this.unbind(this._c[i].children);\n      }\n    },\n\n    /**\n     * Binds events to arrows HTML elements.\n     *\n     * @param {HTMLCollection} elements\n     * @return {Void}\n     */\n    bind: function bind(elements) {\n      for (var i = 0; i < elements.length; i++) {\n        Binder.on('click', elements[i], this.click);\n        Binder.on('touchstart', elements[i], this.click, capture);\n      }\n    },\n\n    /**\n     * Unbinds events binded to the arrows HTML elements.\n     *\n     * @param {HTMLCollection} elements\n     * @return {Void}\n     */\n    unbind: function unbind(elements) {\n      for (var i = 0; i < elements.length; i++) {\n        Binder.off(['click', 'touchstart'], elements[i]);\n      }\n    },\n\n    /**\n     * Handles `click` event on the arrows HTML elements.\n     * Moves slider in direction given via the\n     * `data-glide-dir` attribute.\n     *\n     * @param {Object} event\n     * @return {void}\n     */\n    click: function click(event) {\n      if (!supportsPassive$1 && event.type === 'touchstart') {\n        event.preventDefault();\n      }\n\n      var direction = event.currentTarget.getAttribute('data-glide-dir');\n      Components.Run.make(Components.Direction.resolve(direction));\n    }\n  };\n  define(Controls, 'items', {\n    /**\n     * Gets collection of the controls HTML elements.\n     *\n     * @return {HTMLElement[]}\n     */\n    get: function get() {\n      return Controls._c;\n    }\n  });\n  /**\n   * Swap active class of current navigation item:\n   * - after mounting to set it to initial index\n   * - after each move to the new index\n   */\n\n  Events.on(['mount.after', 'move.after'], function () {\n    Controls.setActive();\n  });\n  /**\n   * Add or remove disabled class of arrow elements\n   */\n\n  Events.on(['mount.after', 'run'], function () {\n    Controls.setArrowState();\n  });\n  /**\n   * Remove bindings and HTML Classes:\n   * - on destroying, to bring markup to its initial state\n   */\n\n  Events.on('destroy', function () {\n    Controls.removeBindings();\n    Controls.removeActive();\n    Binder.destroy();\n  });\n  return Controls;\n}\n\nfunction Keyboard (Glide, Components, Events) {\n  /**\n   * Instance of the binder for DOM Events.\n   *\n   * @type {EventsBinder}\n   */\n  var Binder = new EventsBinder();\n  var Keyboard = {\n    /**\n     * Binds keyboard events on component mount.\n     *\n     * @return {Void}\n     */\n    mount: function mount() {\n      if (Glide.settings.keyboard) {\n        this.bind();\n      }\n    },\n\n    /**\n     * Adds keyboard press events.\n     *\n     * @return {Void}\n     */\n    bind: function bind() {\n      Binder.on('keyup', document, this.press);\n    },\n\n    /**\n     * Removes keyboard press events.\n     *\n     * @return {Void}\n     */\n    unbind: function unbind() {\n      Binder.off('keyup', document);\n    },\n\n    /**\n     * Handles keyboard's arrows press and moving glide foward and backward.\n     *\n     * @param  {Object} event\n     * @return {Void}\n     */\n    press: function press(event) {\n      var perSwipe = Glide.settings.perSwipe;\n      var arrowSymbols = {\n        ArrowRight: '>',\n        ArrowLeft: '<'\n      };\n\n      if (['ArrowRight', 'ArrowLeft'].includes(event.code)) {\n        Components.Run.make(Components.Direction.resolve(\"\".concat(perSwipe).concat(arrowSymbols[event.code])));\n      }\n    }\n  };\n  /**\n   * Remove bindings from keyboard:\n   * - on destroying to remove added events\n   * - on updating to remove events before remounting\n   */\n\n  Events.on(['destroy', 'update'], function () {\n    Keyboard.unbind();\n  });\n  /**\n   * Remount component\n   * - on updating to reflect potential changes in settings\n   */\n\n  Events.on('update', function () {\n    Keyboard.mount();\n  });\n  /**\n   * Destroy binder:\n   * - on destroying to remove listeners\n   */\n\n  Events.on('destroy', function () {\n    Binder.destroy();\n  });\n  return Keyboard;\n}\n\nfunction Autoplay (Glide, Components, Events) {\n  /**\n   * Instance of the binder for DOM Events.\n   *\n   * @type {EventsBinder}\n   */\n  var Binder = new EventsBinder();\n  var Autoplay = {\n    /**\n     * Initializes autoplaying and events.\n     *\n     * @return {Void}\n     */\n    mount: function mount() {\n      this.enable();\n      this.start();\n\n      if (Glide.settings.hoverpause) {\n        this.bind();\n      }\n    },\n\n    /**\n     * Enables autoplaying\n     *\n     * @returns {Void}\n     */\n    enable: function enable() {\n      this._e = true;\n    },\n\n    /**\n     * Disables autoplaying.\n     *\n     * @returns {Void}\n     */\n    disable: function disable() {\n      this._e = false;\n    },\n\n    /**\n     * Starts autoplaying in configured interval.\n     *\n     * @param {Boolean|Number} force Run autoplaying with passed interval regardless of `autoplay` settings\n     * @return {Void}\n     */\n    start: function start() {\n      var _this = this;\n\n      if (!this._e) {\n        return;\n      }\n\n      this.enable();\n\n      if (Glide.settings.autoplay) {\n        if (isUndefined(this._i)) {\n          this._i = setInterval(function () {\n            _this.stop();\n\n            Components.Run.make('>');\n\n            _this.start();\n\n            Events.emit('autoplay');\n          }, this.time);\n        }\n      }\n    },\n\n    /**\n     * Stops autorunning of the glide.\n     *\n     * @return {Void}\n     */\n    stop: function stop() {\n      this._i = clearInterval(this._i);\n    },\n\n    /**\n     * Stops autoplaying while mouse is over glide's area.\n     *\n     * @return {Void}\n     */\n    bind: function bind() {\n      var _this2 = this;\n\n      Binder.on('mouseover', Components.Html.root, function () {\n        if (_this2._e) {\n          _this2.stop();\n        }\n      });\n      Binder.on('mouseout', Components.Html.root, function () {\n        if (_this2._e) {\n          _this2.start();\n        }\n      });\n    },\n\n    /**\n     * Unbind mouseover events.\n     *\n     * @returns {Void}\n     */\n    unbind: function unbind() {\n      Binder.off(['mouseover', 'mouseout'], Components.Html.root);\n    }\n  };\n  define(Autoplay, 'time', {\n    /**\n     * Gets time period value for the autoplay interval. Prioritizes\n     * times in `data-glide-autoplay` attrubutes over options.\n     *\n     * @return {Number}\n     */\n    get: function get() {\n      var autoplay = Components.Html.slides[Glide.index].getAttribute('data-glide-autoplay');\n\n      if (autoplay) {\n        return toInt(autoplay);\n      }\n\n      return toInt(Glide.settings.autoplay);\n    }\n  });\n  /**\n   * Stop autoplaying and unbind events:\n   * - on destroying, to clear defined interval\n   * - on updating via API to reset interval that may changed\n   */\n\n  Events.on(['destroy', 'update'], function () {\n    Autoplay.unbind();\n  });\n  /**\n   * Stop autoplaying:\n   * - before each run, to restart autoplaying\n   * - on pausing via API\n   * - on destroying, to clear defined interval\n   * - while starting a swipe\n   * - on updating via API to reset interval that may changed\n   */\n\n  Events.on(['run.before', 'swipe.start', 'update'], function () {\n    Autoplay.stop();\n  });\n  Events.on(['pause', 'destroy'], function () {\n    Autoplay.disable();\n    Autoplay.stop();\n  });\n  /**\n   * Start autoplaying:\n   * - after each run, to restart autoplaying\n   * - on playing via API\n   * - while ending a swipe\n   */\n\n  Events.on(['run.after', 'swipe.end'], function () {\n    Autoplay.start();\n  });\n  /**\n   * Start autoplaying:\n   * - after each run, to restart autoplaying\n   * - on playing via API\n   * - while ending a swipe\n   */\n\n  Events.on(['play'], function () {\n    Autoplay.enable();\n    Autoplay.start();\n  });\n  /**\n   * Remount autoplaying:\n   * - on updating via API to reset interval that may changed\n   */\n\n  Events.on('update', function () {\n    Autoplay.mount();\n  });\n  /**\n   * Destroy a binder:\n   * - on destroying glide instance to clearup listeners\n   */\n\n  Events.on('destroy', function () {\n    Binder.destroy();\n  });\n  return Autoplay;\n}\n\n/**\n * Sorts keys of breakpoint object so they will be ordered from lower to bigger.\n *\n * @param {Object} points\n * @returns {Object}\n */\n\nfunction sortBreakpoints(points) {\n  if (isObject(points)) {\n    return sortKeys(points);\n  } else {\n    warn(\"Breakpoints option must be an object\");\n  }\n\n  return {};\n}\n\nfunction Breakpoints (Glide, Components, Events) {\n  /**\n   * Instance of the binder for DOM Events.\n   *\n   * @type {EventsBinder}\n   */\n  var Binder = new EventsBinder();\n  /**\n   * Holds reference to settings.\n   *\n   * @type {Object}\n   */\n\n  var settings = Glide.settings;\n  /**\n   * Holds reference to breakpoints object in settings. Sorts breakpoints\n   * from smaller to larger. It is required in order to proper\n   * matching currently active breakpoint settings.\n   *\n   * @type {Object}\n   */\n\n  var points = sortBreakpoints(settings.breakpoints);\n  /**\n   * Cache initial settings before overwritting.\n   *\n   * @type {Object}\n   */\n\n  var defaults = Object.assign({}, settings);\n  var Breakpoints = {\n    /**\n     * Matches settings for currectly matching media breakpoint.\n     *\n     * @param {Object} points\n     * @returns {Object}\n     */\n    match: function match(points) {\n      if (typeof window.matchMedia !== 'undefined') {\n        for (var point in points) {\n          if (points.hasOwnProperty(point)) {\n            if (window.matchMedia(\"(max-width: \".concat(point, \"px)\")).matches) {\n              return points[point];\n            }\n          }\n        }\n      }\n\n      return defaults;\n    }\n  };\n  /**\n   * Overwrite instance settings with currently matching breakpoint settings.\n   * This happens right after component initialization.\n   */\n\n  Object.assign(settings, Breakpoints.match(points));\n  /**\n   * Update glide with settings of matched brekpoint:\n   * - window resize to update slider\n   */\n\n  Binder.on('resize', window, throttle(function () {\n    Glide.settings = mergeOptions(settings, Breakpoints.match(points));\n  }, Glide.settings.throttle));\n  /**\n   * Resort and update default settings:\n   * - on reinit via API, so breakpoint matching will be performed with options\n   */\n\n  Events.on('update', function () {\n    points = sortBreakpoints(points);\n    defaults = Object.assign({}, settings);\n  });\n  /**\n   * Unbind resize listener:\n   * - on destroying, to bring markup to its initial state\n   */\n\n  Events.on('destroy', function () {\n    Binder.off('resize', window);\n  });\n  return Breakpoints;\n}\n\nvar COMPONENTS = {\n  // Required\n  Html: Html,\n  Translate: Translate,\n  Transition: Transition,\n  Direction: Direction,\n  Peek: Peek,\n  Sizes: Sizes,\n  Gaps: Gaps,\n  Move: Move,\n  Clones: Clones,\n  Resize: Resize,\n  Build: Build,\n  Run: Run,\n  // Optional\n  Swipe: Swipe,\n  Images: Images,\n  Anchors: Anchors,\n  Controls: Controls,\n  Keyboard: Keyboard,\n  Autoplay: Autoplay,\n  Breakpoints: Breakpoints\n};\n\nvar Glide = /*#__PURE__*/function (_Core) {\n  _inherits(Glide, _Core);\n\n  var _super = _createSuper(Glide);\n\n  function Glide() {\n    _classCallCheck(this, Glide);\n\n    return _super.apply(this, arguments);\n  }\n\n  _createClass(Glide, [{\n    key: \"mount\",\n    value: function mount() {\n      var extensions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n      return _get(_getPrototypeOf(Glide.prototype), \"mount\", this).call(this, Object.assign({}, COMPONENTS, extensions));\n    }\n  }]);\n\n  return Glide;\n}(Glide$1);\n\n\n\n\n//# sourceURL=webpack://sinn/./node_modules/@glidejs/glide/dist/glide.esm.js?");/***/}),/***/"./node_modules/animejs/lib/anime.es.js":(/*!**********************************************!*\
  !*** ./node_modules/animejs/lib/anime.es.js ***!
  \**********************************************/ /***/function node_modulesAnimejsLibAnimeEsJs(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/*\n * anime.js v3.2.2\n * (c) 2023 Julian Garnier\n * Released under the MIT license\n * animejs.com\n */\n\n// Defaults\n\nvar defaultInstanceSettings = {\n  update: null,\n  begin: null,\n  loopBegin: null,\n  changeBegin: null,\n  change: null,\n  changeComplete: null,\n  loopComplete: null,\n  complete: null,\n  loop: 1,\n  direction: 'normal',\n  autoplay: true,\n  timelineOffset: 0\n};\n\nvar defaultTweenSettings = {\n  duration: 1000,\n  delay: 0,\n  endDelay: 0,\n  easing: 'easeOutElastic(1, .5)',\n  round: 0\n};\n\nvar validTransforms = ['translateX', 'translateY', 'translateZ', 'rotate', 'rotateX', 'rotateY', 'rotateZ', 'scale', 'scaleX', 'scaleY', 'scaleZ', 'skew', 'skewX', 'skewY', 'perspective', 'matrix', 'matrix3d'];\n\n// Caching\n\nvar cache = {\n  CSS: {},\n  springs: {}\n};\n\n// Utils\n\nfunction minMax(val, min, max) {\n  return Math.min(Math.max(val, min), max);\n}\n\nfunction stringContains(str, text) {\n  return str.indexOf(text) > -1;\n}\n\nfunction applyArguments(func, args) {\n  return func.apply(null, args);\n}\n\nvar is = {\n  arr: function (a) { return Array.isArray(a); },\n  obj: function (a) { return stringContains(Object.prototype.toString.call(a), 'Object'); },\n  pth: function (a) { return is.obj(a) && a.hasOwnProperty('totalLength'); },\n  svg: function (a) { return a instanceof SVGElement; },\n  inp: function (a) { return a instanceof HTMLInputElement; },\n  dom: function (a) { return a.nodeType || is.svg(a); },\n  str: function (a) { return typeof a === 'string'; },\n  fnc: function (a) { return typeof a === 'function'; },\n  und: function (a) { return typeof a === 'undefined'; },\n  nil: function (a) { return is.und(a) || a === null; },\n  hex: function (a) { return /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(a); },\n  rgb: function (a) { return /^rgb/.test(a); },\n  hsl: function (a) { return /^hsl/.test(a); },\n  col: function (a) { return (is.hex(a) || is.rgb(a) || is.hsl(a)); },\n  key: function (a) { return !defaultInstanceSettings.hasOwnProperty(a) && !defaultTweenSettings.hasOwnProperty(a) && a !== 'targets' && a !== 'keyframes'; },\n};\n\n// Easings\n\nfunction parseEasingParameters(string) {\n  var match = /\\(([^)]+)\\)/.exec(string);\n  return match ? match[1].split(',').map(function (p) { return parseFloat(p); }) : [];\n}\n\n// Spring solver inspired by Webkit Copyright © 2016 Apple Inc. All rights reserved. https://webkit.org/demos/spring/spring.js\n\nfunction spring(string, duration) {\n\n  var params = parseEasingParameters(string);\n  var mass = minMax(is.und(params[0]) ? 1 : params[0], .1, 100);\n  var stiffness = minMax(is.und(params[1]) ? 100 : params[1], .1, 100);\n  var damping = minMax(is.und(params[2]) ? 10 : params[2], .1, 100);\n  var velocity =  minMax(is.und(params[3]) ? 0 : params[3], .1, 100);\n  var w0 = Math.sqrt(stiffness / mass);\n  var zeta = damping / (2 * Math.sqrt(stiffness * mass));\n  var wd = zeta < 1 ? w0 * Math.sqrt(1 - zeta * zeta) : 0;\n  var a = 1;\n  var b = zeta < 1 ? (zeta * w0 + -velocity) / wd : -velocity + w0;\n\n  function solver(t) {\n    var progress = duration ? (duration * t) / 1000 : t;\n    if (zeta < 1) {\n      progress = Math.exp(-progress * zeta * w0) * (a * Math.cos(wd * progress) + b * Math.sin(wd * progress));\n    } else {\n      progress = (a + b * progress) * Math.exp(-progress * w0);\n    }\n    if (t === 0 || t === 1) { return t; }\n    return 1 - progress;\n  }\n\n  function getDuration() {\n    var cached = cache.springs[string];\n    if (cached) { return cached; }\n    var frame = 1/6;\n    var elapsed = 0;\n    var rest = 0;\n    while(true) {\n      elapsed += frame;\n      if (solver(elapsed) === 1) {\n        rest++;\n        if (rest >= 16) { break; }\n      } else {\n        rest = 0;\n      }\n    }\n    var duration = elapsed * frame * 1000;\n    cache.springs[string] = duration;\n    return duration;\n  }\n\n  return duration ? solver : getDuration;\n\n}\n\n// Basic steps easing implementation https://developer.mozilla.org/fr/docs/Web/CSS/transition-timing-function\n\nfunction steps(steps) {\n  if ( steps === void 0 ) steps = 10;\n\n  return function (t) { return Math.ceil((minMax(t, 0.000001, 1)) * steps) * (1 / steps); };\n}\n\n// BezierEasing https://github.com/gre/bezier-easing\n\nvar bezier = (function () {\n\n  var kSplineTableSize = 11;\n  var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);\n\n  function A(aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1 }\n  function B(aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1 }\n  function C(aA1)      { return 3.0 * aA1 }\n\n  function calcBezier(aT, aA1, aA2) { return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT }\n  function getSlope(aT, aA1, aA2) { return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1) }\n\n  function binarySubdivide(aX, aA, aB, mX1, mX2) {\n    var currentX, currentT, i = 0;\n    do {\n      currentT = aA + (aB - aA) / 2.0;\n      currentX = calcBezier(currentT, mX1, mX2) - aX;\n      if (currentX > 0.0) { aB = currentT; } else { aA = currentT; }\n    } while (Math.abs(currentX) > 0.0000001 && ++i < 10);\n    return currentT;\n  }\n\n  function newtonRaphsonIterate(aX, aGuessT, mX1, mX2) {\n    for (var i = 0; i < 4; ++i) {\n      var currentSlope = getSlope(aGuessT, mX1, mX2);\n      if (currentSlope === 0.0) { return aGuessT; }\n      var currentX = calcBezier(aGuessT, mX1, mX2) - aX;\n      aGuessT -= currentX / currentSlope;\n    }\n    return aGuessT;\n  }\n\n  function bezier(mX1, mY1, mX2, mY2) {\n\n    if (!(0 <= mX1 && mX1 <= 1 && 0 <= mX2 && mX2 <= 1)) { return; }\n    var sampleValues = new Float32Array(kSplineTableSize);\n\n    if (mX1 !== mY1 || mX2 !== mY2) {\n      for (var i = 0; i < kSplineTableSize; ++i) {\n        sampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);\n      }\n    }\n\n    function getTForX(aX) {\n\n      var intervalStart = 0;\n      var currentSample = 1;\n      var lastSample = kSplineTableSize - 1;\n\n      for (; currentSample !== lastSample && sampleValues[currentSample] <= aX; ++currentSample) {\n        intervalStart += kSampleStepSize;\n      }\n\n      --currentSample;\n\n      var dist = (aX - sampleValues[currentSample]) / (sampleValues[currentSample + 1] - sampleValues[currentSample]);\n      var guessForT = intervalStart + dist * kSampleStepSize;\n      var initialSlope = getSlope(guessForT, mX1, mX2);\n\n      if (initialSlope >= 0.001) {\n        return newtonRaphsonIterate(aX, guessForT, mX1, mX2);\n      } else if (initialSlope === 0.0) {\n        return guessForT;\n      } else {\n        return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2);\n      }\n\n    }\n\n    return function (x) {\n      if (mX1 === mY1 && mX2 === mY2) { return x; }\n      if (x === 0 || x === 1) { return x; }\n      return calcBezier(getTForX(x), mY1, mY2);\n    }\n\n  }\n\n  return bezier;\n\n})();\n\nvar penner = (function () {\n\n  // Based on jQuery UI's implemenation of easing equations from Robert Penner (http://www.robertpenner.com/easing)\n\n  var eases = { linear: function () { return function (t) { return t; }; } };\n\n  var functionEasings = {\n    Sine: function () { return function (t) { return 1 - Math.cos(t * Math.PI / 2); }; },\n    Expo: function () { return function (t) { return t ? Math.pow(2, 10 * t - 10) : 0; }; },\n    Circ: function () { return function (t) { return 1 - Math.sqrt(1 - t * t); }; },\n    Back: function () { return function (t) { return t * t * (3 * t - 2); }; },\n    Bounce: function () { return function (t) {\n      var pow2, b = 4;\n      while (t < (( pow2 = Math.pow(2, --b)) - 1) / 11) {}\n      return 1 / Math.pow(4, 3 - b) - 7.5625 * Math.pow(( pow2 * 3 - 2 ) / 22 - t, 2)\n    }; },\n    Elastic: function (amplitude, period) {\n      if ( amplitude === void 0 ) amplitude = 1;\n      if ( period === void 0 ) period = .5;\n\n      var a = minMax(amplitude, 1, 10);\n      var p = minMax(period, .1, 2);\n      return function (t) {\n        return (t === 0 || t === 1) ? t : \n          -a * Math.pow(2, 10 * (t - 1)) * Math.sin((((t - 1) - (p / (Math.PI * 2) * Math.asin(1 / a))) * (Math.PI * 2)) / p);\n      }\n    }\n  };\n\n  var baseEasings = ['Quad', 'Cubic', 'Quart', 'Quint'];\n\n  baseEasings.forEach(function (name, i) {\n    functionEasings[name] = function () { return function (t) { return Math.pow(t, i + 2); }; };\n  });\n\n  Object.keys(functionEasings).forEach(function (name) {\n    var easeIn = functionEasings[name];\n    eases['easeIn' + name] = easeIn;\n    eases['easeOut' + name] = function (a, b) { return function (t) { return 1 - easeIn(a, b)(1 - t); }; };\n    eases['easeInOut' + name] = function (a, b) { return function (t) { return t < 0.5 ? easeIn(a, b)(t * 2) / 2 : \n      1 - easeIn(a, b)(t * -2 + 2) / 2; }; };\n    eases['easeOutIn' + name] = function (a, b) { return function (t) { return t < 0.5 ? (1 - easeIn(a, b)(1 - t * 2)) / 2 : \n      (easeIn(a, b)(t * 2 - 1) + 1) / 2; }; };\n  });\n\n  return eases;\n\n})();\n\nfunction parseEasings(easing, duration) {\n  if (is.fnc(easing)) { return easing; }\n  var name = easing.split('(')[0];\n  var ease = penner[name];\n  var args = parseEasingParameters(easing);\n  switch (name) {\n    case 'spring' : return spring(easing, duration);\n    case 'cubicBezier' : return applyArguments(bezier, args);\n    case 'steps' : return applyArguments(steps, args);\n    default : return applyArguments(ease, args);\n  }\n}\n\n// Strings\n\nfunction selectString(str) {\n  try {\n    var nodes = document.querySelectorAll(str);\n    return nodes;\n  } catch(e) {\n    return;\n  }\n}\n\n// Arrays\n\nfunction filterArray(arr, callback) {\n  var len = arr.length;\n  var thisArg = arguments.length >= 2 ? arguments[1] : void 0;\n  var result = [];\n  for (var i = 0; i < len; i++) {\n    if (i in arr) {\n      var val = arr[i];\n      if (callback.call(thisArg, val, i, arr)) {\n        result.push(val);\n      }\n    }\n  }\n  return result;\n}\n\nfunction flattenArray(arr) {\n  return arr.reduce(function (a, b) { return a.concat(is.arr(b) ? flattenArray(b) : b); }, []);\n}\n\nfunction toArray(o) {\n  if (is.arr(o)) { return o; }\n  if (is.str(o)) { o = selectString(o) || o; }\n  if (o instanceof NodeList || o instanceof HTMLCollection) { return [].slice.call(o); }\n  return [o];\n}\n\nfunction arrayContains(arr, val) {\n  return arr.some(function (a) { return a === val; });\n}\n\n// Objects\n\nfunction cloneObject(o) {\n  var clone = {};\n  for (var p in o) { clone[p] = o[p]; }\n  return clone;\n}\n\nfunction replaceObjectProps(o1, o2) {\n  var o = cloneObject(o1);\n  for (var p in o1) { o[p] = o2.hasOwnProperty(p) ? o2[p] : o1[p]; }\n  return o;\n}\n\nfunction mergeObjects(o1, o2) {\n  var o = cloneObject(o1);\n  for (var p in o2) { o[p] = is.und(o1[p]) ? o2[p] : o1[p]; }\n  return o;\n}\n\n// Colors\n\nfunction rgbToRgba(rgbValue) {\n  var rgb = /rgb\\((\\d+,\\s*[\\d]+,\\s*[\\d]+)\\)/g.exec(rgbValue);\n  return rgb ? (\"rgba(\" + (rgb[1]) + \",1)\") : rgbValue;\n}\n\nfunction hexToRgba(hexValue) {\n  var rgx = /^#?([a-f\\d])([a-f\\d])([a-f\\d])$/i;\n  var hex = hexValue.replace(rgx, function (m, r, g, b) { return r + r + g + g + b + b; } );\n  var rgb = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n  var r = parseInt(rgb[1], 16);\n  var g = parseInt(rgb[2], 16);\n  var b = parseInt(rgb[3], 16);\n  return (\"rgba(\" + r + \",\" + g + \",\" + b + \",1)\");\n}\n\nfunction hslToRgba(hslValue) {\n  var hsl = /hsl\\((\\d+),\\s*([\\d.]+)%,\\s*([\\d.]+)%\\)/g.exec(hslValue) || /hsla\\((\\d+),\\s*([\\d.]+)%,\\s*([\\d.]+)%,\\s*([\\d.]+)\\)/g.exec(hslValue);\n  var h = parseInt(hsl[1], 10) / 360;\n  var s = parseInt(hsl[2], 10) / 100;\n  var l = parseInt(hsl[3], 10) / 100;\n  var a = hsl[4] || 1;\n  function hue2rgb(p, q, t) {\n    if (t < 0) { t += 1; }\n    if (t > 1) { t -= 1; }\n    if (t < 1/6) { return p + (q - p) * 6 * t; }\n    if (t < 1/2) { return q; }\n    if (t < 2/3) { return p + (q - p) * (2/3 - t) * 6; }\n    return p;\n  }\n  var r, g, b;\n  if (s == 0) {\n    r = g = b = l;\n  } else {\n    var q = l < 0.5 ? l * (1 + s) : l + s - l * s;\n    var p = 2 * l - q;\n    r = hue2rgb(p, q, h + 1/3);\n    g = hue2rgb(p, q, h);\n    b = hue2rgb(p, q, h - 1/3);\n  }\n  return (\"rgba(\" + (r * 255) + \",\" + (g * 255) + \",\" + (b * 255) + \",\" + a + \")\");\n}\n\nfunction colorToRgb(val) {\n  if (is.rgb(val)) { return rgbToRgba(val); }\n  if (is.hex(val)) { return hexToRgba(val); }\n  if (is.hsl(val)) { return hslToRgba(val); }\n}\n\n// Units\n\nfunction getUnit(val) {\n  var split = /[+-]?\\d*\\.?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?(%|px|pt|em|rem|in|cm|mm|ex|ch|pc|vw|vh|vmin|vmax|deg|rad|turn)?$/.exec(val);\n  if (split) { return split[1]; }\n}\n\nfunction getTransformUnit(propName) {\n  if (stringContains(propName, 'translate') || propName === 'perspective') { return 'px'; }\n  if (stringContains(propName, 'rotate') || stringContains(propName, 'skew')) { return 'deg'; }\n}\n\n// Values\n\nfunction getFunctionValue(val, animatable) {\n  if (!is.fnc(val)) { return val; }\n  return val(animatable.target, animatable.id, animatable.total);\n}\n\nfunction getAttribute(el, prop) {\n  return el.getAttribute(prop);\n}\n\nfunction convertPxToUnit(el, value, unit) {\n  var valueUnit = getUnit(value);\n  if (arrayContains([unit, 'deg', 'rad', 'turn'], valueUnit)) { return value; }\n  var cached = cache.CSS[value + unit];\n  if (!is.und(cached)) { return cached; }\n  var baseline = 100;\n  var tempEl = document.createElement(el.tagName);\n  var parentEl = (el.parentNode && (el.parentNode !== document)) ? el.parentNode : document.body;\n  parentEl.appendChild(tempEl);\n  tempEl.style.position = 'absolute';\n  tempEl.style.width = baseline + unit;\n  var factor = baseline / tempEl.offsetWidth;\n  parentEl.removeChild(tempEl);\n  var convertedUnit = factor * parseFloat(value);\n  cache.CSS[value + unit] = convertedUnit;\n  return convertedUnit;\n}\n\nfunction getCSSValue(el, prop, unit) {\n  if (prop in el.style) {\n    var uppercasePropName = prop.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();\n    var value = el.style[prop] || getComputedStyle(el).getPropertyValue(uppercasePropName) || '0';\n    return unit ? convertPxToUnit(el, value, unit) : value;\n  }\n}\n\nfunction getAnimationType(el, prop) {\n  if (is.dom(el) && !is.inp(el) && (!is.nil(getAttribute(el, prop)) || (is.svg(el) && el[prop]))) { return 'attribute'; }\n  if (is.dom(el) && arrayContains(validTransforms, prop)) { return 'transform'; }\n  if (is.dom(el) && (prop !== 'transform' && getCSSValue(el, prop))) { return 'css'; }\n  if (el[prop] != null) { return 'object'; }\n}\n\nfunction getElementTransforms(el) {\n  if (!is.dom(el)) { return; }\n  var str = el.style.transform || '';\n  var reg  = /(\\w+)\\(([^)]*)\\)/g;\n  var transforms = new Map();\n  var m; while (m = reg.exec(str)) { transforms.set(m[1], m[2]); }\n  return transforms;\n}\n\nfunction getTransformValue(el, propName, animatable, unit) {\n  var defaultVal = stringContains(propName, 'scale') ? 1 : 0 + getTransformUnit(propName);\n  var value = getElementTransforms(el).get(propName) || defaultVal;\n  if (animatable) {\n    animatable.transforms.list.set(propName, value);\n    animatable.transforms['last'] = propName;\n  }\n  return unit ? convertPxToUnit(el, value, unit) : value;\n}\n\nfunction getOriginalTargetValue(target, propName, unit, animatable) {\n  switch (getAnimationType(target, propName)) {\n    case 'transform': return getTransformValue(target, propName, animatable, unit);\n    case 'css': return getCSSValue(target, propName, unit);\n    case 'attribute': return getAttribute(target, propName);\n    default: return target[propName] || 0;\n  }\n}\n\nfunction getRelativeValue(to, from) {\n  var operator = /^(\\*=|\\+=|-=)/.exec(to);\n  if (!operator) { return to; }\n  var u = getUnit(to) || 0;\n  var x = parseFloat(from);\n  var y = parseFloat(to.replace(operator[0], ''));\n  switch (operator[0][0]) {\n    case '+': return x + y + u;\n    case '-': return x - y + u;\n    case '*': return x * y + u;\n  }\n}\n\nfunction validateValue(val, unit) {\n  if (is.col(val)) { return colorToRgb(val); }\n  if (/\\s/g.test(val)) { return val; }\n  var originalUnit = getUnit(val);\n  var unitLess = originalUnit ? val.substr(0, val.length - originalUnit.length) : val;\n  if (unit) { return unitLess + unit; }\n  return unitLess;\n}\n\n// getTotalLength() equivalent for circle, rect, polyline, polygon and line shapes\n// adapted from https://gist.github.com/SebLambla/3e0550c496c236709744\n\nfunction getDistance(p1, p2) {\n  return Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2));\n}\n\nfunction getCircleLength(el) {\n  return Math.PI * 2 * getAttribute(el, 'r');\n}\n\nfunction getRectLength(el) {\n  return (getAttribute(el, 'width') * 2) + (getAttribute(el, 'height') * 2);\n}\n\nfunction getLineLength(el) {\n  return getDistance(\n    {x: getAttribute(el, 'x1'), y: getAttribute(el, 'y1')}, \n    {x: getAttribute(el, 'x2'), y: getAttribute(el, 'y2')}\n  );\n}\n\nfunction getPolylineLength(el) {\n  var points = el.points;\n  var totalLength = 0;\n  var previousPos;\n  for (var i = 0 ; i < points.numberOfItems; i++) {\n    var currentPos = points.getItem(i);\n    if (i > 0) { totalLength += getDistance(previousPos, currentPos); }\n    previousPos = currentPos;\n  }\n  return totalLength;\n}\n\nfunction getPolygonLength(el) {\n  var points = el.points;\n  return getPolylineLength(el) + getDistance(points.getItem(points.numberOfItems - 1), points.getItem(0));\n}\n\n// Path animation\n\nfunction getTotalLength(el) {\n  if (el.getTotalLength) { return el.getTotalLength(); }\n  switch(el.tagName.toLowerCase()) {\n    case 'circle': return getCircleLength(el);\n    case 'rect': return getRectLength(el);\n    case 'line': return getLineLength(el);\n    case 'polyline': return getPolylineLength(el);\n    case 'polygon': return getPolygonLength(el);\n  }\n}\n\nfunction setDashoffset(el) {\n  var pathLength = getTotalLength(el);\n  el.setAttribute('stroke-dasharray', pathLength);\n  return pathLength;\n}\n\n// Motion path\n\nfunction getParentSvgEl(el) {\n  var parentEl = el.parentNode;\n  while (is.svg(parentEl)) {\n    if (!is.svg(parentEl.parentNode)) { break; }\n    parentEl = parentEl.parentNode;\n  }\n  return parentEl;\n}\n\nfunction getParentSvg(pathEl, svgData) {\n  var svg = svgData || {};\n  var parentSvgEl = svg.el || getParentSvgEl(pathEl);\n  var rect = parentSvgEl.getBoundingClientRect();\n  var viewBoxAttr = getAttribute(parentSvgEl, 'viewBox');\n  var width = rect.width;\n  var height = rect.height;\n  var viewBox = svg.viewBox || (viewBoxAttr ? viewBoxAttr.split(' ') : [0, 0, width, height]);\n  return {\n    el: parentSvgEl,\n    viewBox: viewBox,\n    x: viewBox[0] / 1,\n    y: viewBox[1] / 1,\n    w: width,\n    h: height,\n    vW: viewBox[2],\n    vH: viewBox[3]\n  }\n}\n\nfunction getPath(path, percent) {\n  var pathEl = is.str(path) ? selectString(path)[0] : path;\n  var p = percent || 100;\n  return function(property) {\n    return {\n      property: property,\n      el: pathEl,\n      svg: getParentSvg(pathEl),\n      totalLength: getTotalLength(pathEl) * (p / 100)\n    }\n  }\n}\n\nfunction getPathProgress(path, progress, isPathTargetInsideSVG) {\n  function point(offset) {\n    if ( offset === void 0 ) offset = 0;\n\n    var l = progress + offset >= 1 ? progress + offset : 0;\n    return path.el.getPointAtLength(l);\n  }\n  var svg = getParentSvg(path.el, path.svg);\n  var p = point();\n  var p0 = point(-1);\n  var p1 = point(+1);\n  var scaleX = isPathTargetInsideSVG ? 1 : svg.w / svg.vW;\n  var scaleY = isPathTargetInsideSVG ? 1 : svg.h / svg.vH;\n  switch (path.property) {\n    case 'x': return (p.x - svg.x) * scaleX;\n    case 'y': return (p.y - svg.y) * scaleY;\n    case 'angle': return Math.atan2(p1.y - p0.y, p1.x - p0.x) * 180 / Math.PI;\n  }\n}\n\n// Decompose value\n\nfunction decomposeValue(val, unit) {\n  // const rgx = /-?\\d*\\.?\\d+/g; // handles basic numbers\n  // const rgx = /[+-]?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?/g; // handles exponents notation\n  var rgx = /[+-]?\\d*\\.?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?/g; // handles exponents notation\n  var value = validateValue((is.pth(val) ? val.totalLength : val), unit) + '';\n  return {\n    original: value,\n    numbers: value.match(rgx) ? value.match(rgx).map(Number) : [0],\n    strings: (is.str(val) || unit) ? value.split(rgx) : []\n  }\n}\n\n// Animatables\n\nfunction parseTargets(targets) {\n  var targetsArray = targets ? (flattenArray(is.arr(targets) ? targets.map(toArray) : toArray(targets))) : [];\n  return filterArray(targetsArray, function (item, pos, self) { return self.indexOf(item) === pos; });\n}\n\nfunction getAnimatables(targets) {\n  var parsed = parseTargets(targets);\n  return parsed.map(function (t, i) {\n    return {target: t, id: i, total: parsed.length, transforms: { list: getElementTransforms(t) } };\n  });\n}\n\n// Properties\n\nfunction normalizePropertyTweens(prop, tweenSettings) {\n  var settings = cloneObject(tweenSettings);\n  // Override duration if easing is a spring\n  if (/^spring/.test(settings.easing)) { settings.duration = spring(settings.easing); }\n  if (is.arr(prop)) {\n    var l = prop.length;\n    var isFromTo = (l === 2 && !is.obj(prop[0]));\n    if (!isFromTo) {\n      // Duration divided by the number of tweens\n      if (!is.fnc(tweenSettings.duration)) { settings.duration = tweenSettings.duration / l; }\n    } else {\n      // Transform [from, to] values shorthand to a valid tween value\n      prop = {value: prop};\n    }\n  }\n  var propArray = is.arr(prop) ? prop : [prop];\n  return propArray.map(function (v, i) {\n    var obj = (is.obj(v) && !is.pth(v)) ? v : {value: v};\n    // Default delay value should only be applied to the first tween\n    if (is.und(obj.delay)) { obj.delay = !i ? tweenSettings.delay : 0; }\n    // Default endDelay value should only be applied to the last tween\n    if (is.und(obj.endDelay)) { obj.endDelay = i === propArray.length - 1 ? tweenSettings.endDelay : 0; }\n    return obj;\n  }).map(function (k) { return mergeObjects(k, settings); });\n}\n\n\nfunction flattenKeyframes(keyframes) {\n  var propertyNames = filterArray(flattenArray(keyframes.map(function (key) { return Object.keys(key); })), function (p) { return is.key(p); })\n  .reduce(function (a,b) { if (a.indexOf(b) < 0) { a.push(b); } return a; }, []);\n  var properties = {};\n  var loop = function ( i ) {\n    var propName = propertyNames[i];\n    properties[propName] = keyframes.map(function (key) {\n      var newKey = {};\n      for (var p in key) {\n        if (is.key(p)) {\n          if (p == propName) { newKey.value = key[p]; }\n        } else {\n          newKey[p] = key[p];\n        }\n      }\n      return newKey;\n    });\n  };\n\n  for (var i = 0; i < propertyNames.length; i++) loop( i );\n  return properties;\n}\n\nfunction getProperties(tweenSettings, params) {\n  var properties = [];\n  var keyframes = params.keyframes;\n  if (keyframes) { params = mergeObjects(flattenKeyframes(keyframes), params); }\n  for (var p in params) {\n    if (is.key(p)) {\n      properties.push({\n        name: p,\n        tweens: normalizePropertyTweens(params[p], tweenSettings)\n      });\n    }\n  }\n  return properties;\n}\n\n// Tweens\n\nfunction normalizeTweenValues(tween, animatable) {\n  var t = {};\n  for (var p in tween) {\n    var value = getFunctionValue(tween[p], animatable);\n    if (is.arr(value)) {\n      value = value.map(function (v) { return getFunctionValue(v, animatable); });\n      if (value.length === 1) { value = value[0]; }\n    }\n    t[p] = value;\n  }\n  t.duration = parseFloat(t.duration);\n  t.delay = parseFloat(t.delay);\n  return t;\n}\n\nfunction normalizeTweens(prop, animatable) {\n  var previousTween;\n  return prop.tweens.map(function (t) {\n    var tween = normalizeTweenValues(t, animatable);\n    var tweenValue = tween.value;\n    var to = is.arr(tweenValue) ? tweenValue[1] : tweenValue;\n    var toUnit = getUnit(to);\n    var originalValue = getOriginalTargetValue(animatable.target, prop.name, toUnit, animatable);\n    var previousValue = previousTween ? previousTween.to.original : originalValue;\n    var from = is.arr(tweenValue) ? tweenValue[0] : previousValue;\n    var fromUnit = getUnit(from) || getUnit(originalValue);\n    var unit = toUnit || fromUnit;\n    if (is.und(to)) { to = previousValue; }\n    tween.from = decomposeValue(from, unit);\n    tween.to = decomposeValue(getRelativeValue(to, from), unit);\n    tween.start = previousTween ? previousTween.end : 0;\n    tween.end = tween.start + tween.delay + tween.duration + tween.endDelay;\n    tween.easing = parseEasings(tween.easing, tween.duration);\n    tween.isPath = is.pth(tweenValue);\n    tween.isPathTargetInsideSVG = tween.isPath && is.svg(animatable.target);\n    tween.isColor = is.col(tween.from.original);\n    if (tween.isColor) { tween.round = 1; }\n    previousTween = tween;\n    return tween;\n  });\n}\n\n// Tween progress\n\nvar setProgressValue = {\n  css: function (t, p, v) { return t.style[p] = v; },\n  attribute: function (t, p, v) { return t.setAttribute(p, v); },\n  object: function (t, p, v) { return t[p] = v; },\n  transform: function (t, p, v, transforms, manual) {\n    transforms.list.set(p, v);\n    if (p === transforms.last || manual) {\n      var str = '';\n      transforms.list.forEach(function (value, prop) { str += prop + \"(\" + value + \") \"; });\n      t.style.transform = str;\n    }\n  }\n};\n\n// Set Value helper\n\nfunction setTargetsValue(targets, properties) {\n  var animatables = getAnimatables(targets);\n  animatables.forEach(function (animatable) {\n    for (var property in properties) {\n      var value = getFunctionValue(properties[property], animatable);\n      var target = animatable.target;\n      var valueUnit = getUnit(value);\n      var originalValue = getOriginalTargetValue(target, property, valueUnit, animatable);\n      var unit = valueUnit || getUnit(originalValue);\n      var to = getRelativeValue(validateValue(value, unit), originalValue);\n      var animType = getAnimationType(target, property);\n      setProgressValue[animType](target, property, to, animatable.transforms, true);\n    }\n  });\n}\n\n// Animations\n\nfunction createAnimation(animatable, prop) {\n  var animType = getAnimationType(animatable.target, prop.name);\n  if (animType) {\n    var tweens = normalizeTweens(prop, animatable);\n    var lastTween = tweens[tweens.length - 1];\n    return {\n      type: animType,\n      property: prop.name,\n      animatable: animatable,\n      tweens: tweens,\n      duration: lastTween.end,\n      delay: tweens[0].delay,\n      endDelay: lastTween.endDelay\n    }\n  }\n}\n\nfunction getAnimations(animatables, properties) {\n  return filterArray(flattenArray(animatables.map(function (animatable) {\n    return properties.map(function (prop) {\n      return createAnimation(animatable, prop);\n    });\n  })), function (a) { return !is.und(a); });\n}\n\n// Create Instance\n\nfunction getInstanceTimings(animations, tweenSettings) {\n  var animLength = animations.length;\n  var getTlOffset = function (anim) { return anim.timelineOffset ? anim.timelineOffset : 0; };\n  var timings = {};\n  timings.duration = animLength ? Math.max.apply(Math, animations.map(function (anim) { return getTlOffset(anim) + anim.duration; })) : tweenSettings.duration;\n  timings.delay = animLength ? Math.min.apply(Math, animations.map(function (anim) { return getTlOffset(anim) + anim.delay; })) : tweenSettings.delay;\n  timings.endDelay = animLength ? timings.duration - Math.max.apply(Math, animations.map(function (anim) { return getTlOffset(anim) + anim.duration - anim.endDelay; })) : tweenSettings.endDelay;\n  return timings;\n}\n\nvar instanceID = 0;\n\nfunction createNewInstance(params) {\n  var instanceSettings = replaceObjectProps(defaultInstanceSettings, params);\n  var tweenSettings = replaceObjectProps(defaultTweenSettings, params);\n  var properties = getProperties(tweenSettings, params);\n  var animatables = getAnimatables(params.targets);\n  var animations = getAnimations(animatables, properties);\n  var timings = getInstanceTimings(animations, tweenSettings);\n  var id = instanceID;\n  instanceID++;\n  return mergeObjects(instanceSettings, {\n    id: id,\n    children: [],\n    animatables: animatables,\n    animations: animations,\n    duration: timings.duration,\n    delay: timings.delay,\n    endDelay: timings.endDelay\n  });\n}\n\n// Core\n\nvar activeInstances = [];\n\nvar engine = (function () {\n  var raf;\n\n  function play() {\n    if (!raf && (!isDocumentHidden() || !anime.suspendWhenDocumentHidden) && activeInstances.length > 0) {\n      raf = requestAnimationFrame(step);\n    }\n  }\n  function step(t) {\n    // memo on algorithm issue:\n    // dangerous iteration over mutable `activeInstances`\n    // (that collection may be updated from within callbacks of `tick`-ed animation instances)\n    var activeInstancesLength = activeInstances.length;\n    var i = 0;\n    while (i < activeInstancesLength) {\n      var activeInstance = activeInstances[i];\n      if (!activeInstance.paused) {\n        activeInstance.tick(t);\n        i++;\n      } else {\n        activeInstances.splice(i, 1);\n        activeInstancesLength--;\n      }\n    }\n    raf = i > 0 ? requestAnimationFrame(step) : undefined;\n  }\n\n  function handleVisibilityChange() {\n    if (!anime.suspendWhenDocumentHidden) { return; }\n\n    if (isDocumentHidden()) {\n      // suspend ticks\n      raf = cancelAnimationFrame(raf);\n    } else { // is back to active tab\n      // first adjust animations to consider the time that ticks were suspended\n      activeInstances.forEach(\n        function (instance) { return instance ._onDocumentVisibility(); }\n      );\n      engine();\n    }\n  }\n  if (typeof document !== 'undefined') {\n    document.addEventListener('visibilitychange', handleVisibilityChange);\n  }\n\n  return play;\n})();\n\nfunction isDocumentHidden() {\n  return !!document && document.hidden;\n}\n\n// Public Instance\n\nfunction anime(params) {\n  if ( params === void 0 ) params = {};\n\n\n  var startTime = 0, lastTime = 0, now = 0;\n  var children, childrenLength = 0;\n  var resolve = null;\n\n  function makePromise(instance) {\n    var promise = window.Promise && new Promise(function (_resolve) { return resolve = _resolve; });\n    instance.finished = promise;\n    return promise;\n  }\n\n  var instance = createNewInstance(params);\n  var promise = makePromise(instance);\n\n  function toggleInstanceDirection() {\n    var direction = instance.direction;\n    if (direction !== 'alternate') {\n      instance.direction = direction !== 'normal' ? 'normal' : 'reverse';\n    }\n    instance.reversed = !instance.reversed;\n    children.forEach(function (child) { return child.reversed = instance.reversed; });\n  }\n\n  function adjustTime(time) {\n    return instance.reversed ? instance.duration - time : time;\n  }\n\n  function resetTime() {\n    startTime = 0;\n    lastTime = adjustTime(instance.currentTime) * (1 / anime.speed);\n  }\n\n  function seekChild(time, child) {\n    if (child) { child.seek(time - child.timelineOffset); }\n  }\n\n  function syncInstanceChildren(time) {\n    if (!instance.reversePlayback) {\n      for (var i = 0; i < childrenLength; i++) { seekChild(time, children[i]); }\n    } else {\n      for (var i$1 = childrenLength; i$1--;) { seekChild(time, children[i$1]); }\n    }\n  }\n\n  function setAnimationsProgress(insTime) {\n    var i = 0;\n    var animations = instance.animations;\n    var animationsLength = animations.length;\n    while (i < animationsLength) {\n      var anim = animations[i];\n      var animatable = anim.animatable;\n      var tweens = anim.tweens;\n      var tweenLength = tweens.length - 1;\n      var tween = tweens[tweenLength];\n      // Only check for keyframes if there is more than one tween\n      if (tweenLength) { tween = filterArray(tweens, function (t) { return (insTime < t.end); })[0] || tween; }\n      var elapsed = minMax(insTime - tween.start - tween.delay, 0, tween.duration) / tween.duration;\n      var eased = isNaN(elapsed) ? 1 : tween.easing(elapsed);\n      var strings = tween.to.strings;\n      var round = tween.round;\n      var numbers = [];\n      var toNumbersLength = tween.to.numbers.length;\n      var progress = (void 0);\n      for (var n = 0; n < toNumbersLength; n++) {\n        var value = (void 0);\n        var toNumber = tween.to.numbers[n];\n        var fromNumber = tween.from.numbers[n] || 0;\n        if (!tween.isPath) {\n          value = fromNumber + (eased * (toNumber - fromNumber));\n        } else {\n          value = getPathProgress(tween.value, eased * toNumber, tween.isPathTargetInsideSVG);\n        }\n        if (round) {\n          if (!(tween.isColor && n > 2)) {\n            value = Math.round(value * round) / round;\n          }\n        }\n        numbers.push(value);\n      }\n      // Manual Array.reduce for better performances\n      var stringsLength = strings.length;\n      if (!stringsLength) {\n        progress = numbers[0];\n      } else {\n        progress = strings[0];\n        for (var s = 0; s < stringsLength; s++) {\n          var a = strings[s];\n          var b = strings[s + 1];\n          var n$1 = numbers[s];\n          if (!isNaN(n$1)) {\n            if (!b) {\n              progress += n$1 + ' ';\n            } else {\n              progress += n$1 + b;\n            }\n          }\n        }\n      }\n      setProgressValue[anim.type](animatable.target, anim.property, progress, animatable.transforms);\n      anim.currentValue = progress;\n      i++;\n    }\n  }\n\n  function setCallback(cb) {\n    if (instance[cb] && !instance.passThrough) { instance[cb](instance); }\n  }\n\n  function countIteration() {\n    if (instance.remaining && instance.remaining !== true) {\n      instance.remaining--;\n    }\n  }\n\n  function setInstanceProgress(engineTime) {\n    var insDuration = instance.duration;\n    var insDelay = instance.delay;\n    var insEndDelay = insDuration - instance.endDelay;\n    var insTime = adjustTime(engineTime);\n    instance.progress = minMax((insTime / insDuration) * 100, 0, 100);\n    instance.reversePlayback = insTime < instance.currentTime;\n    if (children) { syncInstanceChildren(insTime); }\n    if (!instance.began && instance.currentTime > 0) {\n      instance.began = true;\n      setCallback('begin');\n    }\n    if (!instance.loopBegan && instance.currentTime > 0) {\n      instance.loopBegan = true;\n      setCallback('loopBegin');\n    }\n    if (insTime <= insDelay && instance.currentTime !== 0) {\n      setAnimationsProgress(0);\n    }\n    if ((insTime >= insEndDelay && instance.currentTime !== insDuration) || !insDuration) {\n      setAnimationsProgress(insDuration);\n    }\n    if (insTime > insDelay && insTime < insEndDelay) {\n      if (!instance.changeBegan) {\n        instance.changeBegan = true;\n        instance.changeCompleted = false;\n        setCallback('changeBegin');\n      }\n      setCallback('change');\n      setAnimationsProgress(insTime);\n    } else {\n      if (instance.changeBegan) {\n        instance.changeCompleted = true;\n        instance.changeBegan = false;\n        setCallback('changeComplete');\n      }\n    }\n    instance.currentTime = minMax(insTime, 0, insDuration);\n    if (instance.began) { setCallback('update'); }\n    if (engineTime >= insDuration) {\n      lastTime = 0;\n      countIteration();\n      if (!instance.remaining) {\n        instance.paused = true;\n        if (!instance.completed) {\n          instance.completed = true;\n          setCallback('loopComplete');\n          setCallback('complete');\n          if (!instance.passThrough && 'Promise' in window) {\n            resolve();\n            promise = makePromise(instance);\n          }\n        }\n      } else {\n        startTime = now;\n        setCallback('loopComplete');\n        instance.loopBegan = false;\n        if (instance.direction === 'alternate') {\n          toggleInstanceDirection();\n        }\n      }\n    }\n  }\n\n  instance.reset = function() {\n    var direction = instance.direction;\n    instance.passThrough = false;\n    instance.currentTime = 0;\n    instance.progress = 0;\n    instance.paused = true;\n    instance.began = false;\n    instance.loopBegan = false;\n    instance.changeBegan = false;\n    instance.completed = false;\n    instance.changeCompleted = false;\n    instance.reversePlayback = false;\n    instance.reversed = direction === 'reverse';\n    instance.remaining = instance.loop;\n    children = instance.children;\n    childrenLength = children.length;\n    for (var i = childrenLength; i--;) { instance.children[i].reset(); }\n    if (instance.reversed && instance.loop !== true || (direction === 'alternate' && instance.loop === 1)) { instance.remaining++; }\n    setAnimationsProgress(instance.reversed ? instance.duration : 0);\n  };\n\n  // internal method (for engine) to adjust animation timings before restoring engine ticks (rAF)\n  instance._onDocumentVisibility = resetTime;\n\n  // Set Value helper\n\n  instance.set = function(targets, properties) {\n    setTargetsValue(targets, properties);\n    return instance;\n  };\n\n  instance.tick = function(t) {\n    now = t;\n    if (!startTime) { startTime = now; }\n    setInstanceProgress((now + (lastTime - startTime)) * anime.speed);\n  };\n\n  instance.seek = function(time) {\n    setInstanceProgress(adjustTime(time));\n  };\n\n  instance.pause = function() {\n    instance.paused = true;\n    resetTime();\n  };\n\n  instance.play = function() {\n    if (!instance.paused) { return; }\n    if (instance.completed) { instance.reset(); }\n    instance.paused = false;\n    activeInstances.push(instance);\n    resetTime();\n    engine();\n  };\n\n  instance.reverse = function() {\n    toggleInstanceDirection();\n    instance.completed = instance.reversed ? false : true;\n    resetTime();\n  };\n\n  instance.restart = function() {\n    instance.reset();\n    instance.play();\n  };\n\n  instance.remove = function(targets) {\n    var targetsArray = parseTargets(targets);\n    removeTargetsFromInstance(targetsArray, instance);\n  };\n\n  instance.reset();\n\n  if (instance.autoplay) { instance.play(); }\n\n  return instance;\n\n}\n\n// Remove targets from animation\n\nfunction removeTargetsFromAnimations(targetsArray, animations) {\n  for (var a = animations.length; a--;) {\n    if (arrayContains(targetsArray, animations[a].animatable.target)) {\n      animations.splice(a, 1);\n    }\n  }\n}\n\nfunction removeTargetsFromInstance(targetsArray, instance) {\n  var animations = instance.animations;\n  var children = instance.children;\n  removeTargetsFromAnimations(targetsArray, animations);\n  for (var c = children.length; c--;) {\n    var child = children[c];\n    var childAnimations = child.animations;\n    removeTargetsFromAnimations(targetsArray, childAnimations);\n    if (!childAnimations.length && !child.children.length) { children.splice(c, 1); }\n  }\n  if (!animations.length && !children.length) { instance.pause(); }\n}\n\nfunction removeTargetsFromActiveInstances(targets) {\n  var targetsArray = parseTargets(targets);\n  for (var i = activeInstances.length; i--;) {\n    var instance = activeInstances[i];\n    removeTargetsFromInstance(targetsArray, instance);\n  }\n}\n\n// Stagger helpers\n\nfunction stagger(val, params) {\n  if ( params === void 0 ) params = {};\n\n  var direction = params.direction || 'normal';\n  var easing = params.easing ? parseEasings(params.easing) : null;\n  var grid = params.grid;\n  var axis = params.axis;\n  var fromIndex = params.from || 0;\n  var fromFirst = fromIndex === 'first';\n  var fromCenter = fromIndex === 'center';\n  var fromLast = fromIndex === 'last';\n  var isRange = is.arr(val);\n  var val1 = isRange ? parseFloat(val[0]) : parseFloat(val);\n  var val2 = isRange ? parseFloat(val[1]) : 0;\n  var unit = getUnit(isRange ? val[1] : val) || 0;\n  var start = params.start || 0 + (isRange ? val1 : 0);\n  var values = [];\n  var maxValue = 0;\n  return function (el, i, t) {\n    if (fromFirst) { fromIndex = 0; }\n    if (fromCenter) { fromIndex = (t - 1) / 2; }\n    if (fromLast) { fromIndex = t - 1; }\n    if (!values.length) {\n      for (var index = 0; index < t; index++) {\n        if (!grid) {\n          values.push(Math.abs(fromIndex - index));\n        } else {\n          var fromX = !fromCenter ? fromIndex%grid[0] : (grid[0]-1)/2;\n          var fromY = !fromCenter ? Math.floor(fromIndex/grid[0]) : (grid[1]-1)/2;\n          var toX = index%grid[0];\n          var toY = Math.floor(index/grid[0]);\n          var distanceX = fromX - toX;\n          var distanceY = fromY - toY;\n          var value = Math.sqrt(distanceX * distanceX + distanceY * distanceY);\n          if (axis === 'x') { value = -distanceX; }\n          if (axis === 'y') { value = -distanceY; }\n          values.push(value);\n        }\n        maxValue = Math.max.apply(Math, values);\n      }\n      if (easing) { values = values.map(function (val) { return easing(val / maxValue) * maxValue; }); }\n      if (direction === 'reverse') { values = values.map(function (val) { return axis ? (val < 0) ? val * -1 : -val : Math.abs(maxValue - val); }); }\n    }\n    var spacing = isRange ? (val2 - val1) / maxValue : val1;\n    return start + (spacing * (Math.round(values[i] * 100) / 100)) + unit;\n  }\n}\n\n// Timeline\n\nfunction timeline(params) {\n  if ( params === void 0 ) params = {};\n\n  var tl = anime(params);\n  tl.duration = 0;\n  tl.add = function(instanceParams, timelineOffset) {\n    var tlIndex = activeInstances.indexOf(tl);\n    var children = tl.children;\n    if (tlIndex > -1) { activeInstances.splice(tlIndex, 1); }\n    function passThrough(ins) { ins.passThrough = true; }\n    for (var i = 0; i < children.length; i++) { passThrough(children[i]); }\n    var insParams = mergeObjects(instanceParams, replaceObjectProps(defaultTweenSettings, params));\n    insParams.targets = insParams.targets || params.targets;\n    var tlDuration = tl.duration;\n    insParams.autoplay = false;\n    insParams.direction = tl.direction;\n    insParams.timelineOffset = is.und(timelineOffset) ? tlDuration : getRelativeValue(timelineOffset, tlDuration);\n    passThrough(tl);\n    tl.seek(insParams.timelineOffset);\n    var ins = anime(insParams);\n    passThrough(ins);\n    children.push(ins);\n    var timings = getInstanceTimings(children, params);\n    tl.delay = timings.delay;\n    tl.endDelay = timings.endDelay;\n    tl.duration = timings.duration;\n    tl.seek(0);\n    tl.reset();\n    if (tl.autoplay) { tl.play(); }\n    return tl;\n  };\n  return tl;\n}\n\nanime.version = '3.2.1';\nanime.speed = 1;\n// TODO:#review: naming, documentation\nanime.suspendWhenDocumentHidden = true;\nanime.running = activeInstances;\nanime.remove = removeTargetsFromActiveInstances;\nanime.get = getOriginalTargetValue;\nanime.set = setTargetsValue;\nanime.convertPx = convertPxToUnit;\nanime.path = getPath;\nanime.setDashoffset = setDashoffset;\nanime.stagger = stagger;\nanime.timeline = timeline;\nanime.easing = parseEasings;\nanime.penner = penner;\nanime.random = function (min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; };\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (anime);\n\n\n//# sourceURL=webpack://sinn/./node_modules/animejs/lib/anime.es.js?");/***/}),/***/"./node_modules/detect-autofill/dist/detect-autofill.js":(/*!**************************************************************!*\
  !*** ./node_modules/detect-autofill/dist/detect-autofill.js ***!
  \**************************************************************/ /***/function node_modulesDetectAutofillDistDetectAutofillJs(){eval("(()=>{var e={454:(e,t,n)=>{\"use strict\";n.d(t,{Z:()=>a});var r=n(645),o=n.n(r)()((function(e){return e[1]}));o.push([e.id,\"INPUT:-webkit-autofill,SELECT:-webkit-autofill,TEXTAREA:-webkit-autofill{animation-name:onautofillstart}INPUT:not(:-webkit-autofill),SELECT:not(:-webkit-autofill),TEXTAREA:not(:-webkit-autofill){animation-name:onautofillcancel}@keyframes onautofillstart{}@keyframes onautofillcancel{}\",\"\"]);const a=o},645:e=>{\"use strict\";e.exports=function(e){var t=[];return t.toString=function(){return this.map((function(t){var n=e(t);return t[2]?\"@media \".concat(t[2],\" {\").concat(n,\"}\"):n})).join(\"\")},t.i=function(e,n,r){\"string\"==typeof e&&(e=[[null,e,\"\"]]);var o={};if(r)for(var a=0;a<this.length;a++){var i=this[a][0];null!=i&&(o[i]=!0)}for(var u=0;u<e.length;u++){var c=[].concat(e[u]);r&&o[c[0]]||(n&&(c[2]?c[2]=\"\".concat(n,\" and \").concat(c[2]):c[2]=n),t.push(c))}},t}},810:()=>{!function(){if(\"undefined\"!=typeof window)try{var e=new window.CustomEvent(\"test\",{cancelable:!0});if(e.preventDefault(),!0!==e.defaultPrevented)throw new Error(\"Could not prevent default\")}catch(e){var t=function(e,t){var n,r;return(t=t||{}).bubbles=!!t.bubbles,t.cancelable=!!t.cancelable,(n=document.createEvent(\"CustomEvent\")).initCustomEvent(e,t.bubbles,t.cancelable,t.detail),r=n.preventDefault,n.preventDefault=function(){r.call(this);try{Object.defineProperty(this,\"defaultPrevented\",{get:function(){return!0}})}catch(e){this.defaultPrevented=!0}},n};t.prototype=window.Event.prototype,window.CustomEvent=t}}()},379:(e,t,n)=>{\"use strict\";var r,o=function(){var e={};return function(t){if(void 0===e[t]){var n=document.querySelector(t);if(window.HTMLIFrameElement&&n instanceof window.HTMLIFrameElement)try{n=n.contentDocument.head}catch(e){n=null}e[t]=n}return e[t]}}(),a=[];function i(e){for(var t=-1,n=0;n<a.length;n++)if(a[n].identifier===e){t=n;break}return t}function u(e,t){for(var n={},r=[],o=0;o<e.length;o++){var u=e[o],c=t.base?u[0]+t.base:u[0],l=n[c]||0,s=\"\".concat(c,\" \").concat(l);n[c]=l+1;var d=i(s),f={css:u[1],media:u[2],sourceMap:u[3]};-1!==d?(a[d].references++,a[d].updater(f)):a.push({identifier:s,updater:m(f,t),references:1}),r.push(s)}return r}function c(e){var t=document.createElement(\"style\"),r=e.attributes||{};if(void 0===r.nonce){var a=n.nc;a&&(r.nonce=a)}if(Object.keys(r).forEach((function(e){t.setAttribute(e,r[e])})),\"function\"==typeof e.insert)e.insert(t);else{var i=o(e.insert||\"head\");if(!i)throw new Error(\"Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.\");i.appendChild(t)}return t}var l,s=(l=[],function(e,t){return l[e]=t,l.filter(Boolean).join(\"\\n\")});function d(e,t,n,r){var o=n?\"\":r.media?\"@media \".concat(r.media,\" {\").concat(r.css,\"}\"):r.css;if(e.styleSheet)e.styleSheet.cssText=s(t,o);else{var a=document.createTextNode(o),i=e.childNodes;i[t]&&e.removeChild(i[t]),i.length?e.insertBefore(a,i[t]):e.appendChild(a)}}function f(e,t,n){var r=n.css,o=n.media,a=n.sourceMap;if(o?e.setAttribute(\"media\",o):e.removeAttribute(\"media\"),a&&\"undefined\"!=typeof btoa&&(r+=\"\\n/*# sourceMappingURL=data:application/json;base64,\".concat(btoa(unescape(encodeURIComponent(JSON.stringify(a)))),\" */\")),e.styleSheet)e.styleSheet.cssText=r;else{for(;e.firstChild;)e.removeChild(e.firstChild);e.appendChild(document.createTextNode(r))}}var v=null,p=0;function m(e,t){var n,r,o;if(t.singleton){var a=p++;n=v||(v=c(t)),r=d.bind(null,n,a,!1),o=d.bind(null,n,a,!0)}else n=c(t),r=f.bind(null,n,t),o=function(){!function(e){if(null===e.parentNode)return!1;e.parentNode.removeChild(e)}(n)};return r(e),function(t){if(t){if(t.css===e.css&&t.media===e.media&&t.sourceMap===e.sourceMap)return;r(e=t)}else o()}}e.exports=function(e,t){(t=t||{}).singleton||\"boolean\"==typeof t.singleton||(t.singleton=(void 0===r&&(r=Boolean(window&&document&&document.all&&!window.atob)),r));var n=u(e=e||[],t);return function(e){if(e=e||[],\"[object Array]\"===Object.prototype.toString.call(e)){for(var r=0;r<n.length;r++){var o=i(n[r]);a[o].references--}for(var c=u(e,t),l=0;l<n.length;l++){var s=i(n[l]);0===a[s].references&&(a[s].updater(),a.splice(s,1))}n=c}}}}},t={};function n(r){var o=t[r];if(void 0!==o)return o.exports;var a=t[r]={id:r,exports:{}};return e[r](a,a.exports,n),a.exports}n.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return n.d(t,{a:t}),t},n.d=(e,t)=>{for(var r in t)n.o(t,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{\"use strict\";var e=n(379),t=n.n(e),r=n(454);function o(e){if(!e.hasAttribute(\"autocompleted\")){e.setAttribute(\"autocompleted\",\"\");var t=new window.CustomEvent(\"onautocomplete\",{bubbles:!0,cancelable:!0,detail:null});e.dispatchEvent(t)||(e.value=\"\")}}function a(e){e.hasAttribute(\"autocompleted\")&&(e.removeAttribute(\"autocompleted\"),e.dispatchEvent(new window.CustomEvent(\"onautocomplete\",{bubbles:!0,cancelable:!1,detail:null})))}t()(r.Z,{insert:\"head\",singleton:!1}),r.Z.locals,n(810),document.addEventListener(\"animationstart\",(function(e){\"onautofillstart\"===e.animationName?o(e.target):a(e.target)}),!0),document.addEventListener(\"input\",(function(e){\"insertReplacementText\"!==e.inputType&&\"data\"in e?a(e.target):o(e.target)}),!0)})()})();\n\n//# sourceURL=webpack://sinn/./node_modules/detect-autofill/dist/detect-autofill.js?");/***/}),/***/"./node_modules/vanilla-lazyload/dist/lazyload.min.js":(/*!************************************************************!*\
  !*** ./node_modules/vanilla-lazyload/dist/lazyload.min.js ***!
  \************************************************************/ /***/function node_modulesVanillaLazyloadDistLazyloadMinJs(module){eval("!function(n,t){ true?module.exports=t():0}(this,(function(){\"use strict\";function n(){return n=Object.assign||function(n){for(var t=1;t<arguments.length;t++){var e=arguments[t];for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(n[i]=e[i])}return n},n.apply(this,arguments)}var t=\"undefined\"!=typeof window,e=t&&!(\"onscroll\"in window)||\"undefined\"!=typeof navigator&&/(gle|ing|ro)bot|crawl|spider/i.test(navigator.userAgent),i=t&&\"IntersectionObserver\"in window,o=t&&\"classList\"in document.createElement(\"p\"),a=t&&window.devicePixelRatio>1,r={elements_selector:\".lazy\",container:e||t?document:null,threshold:300,thresholds:null,data_src:\"src\",data_srcset:\"srcset\",data_sizes:\"sizes\",data_bg:\"bg\",data_bg_hidpi:\"bg-hidpi\",data_bg_multi:\"bg-multi\",data_bg_multi_hidpi:\"bg-multi-hidpi\",data_bg_set:\"bg-set\",data_poster:\"poster\",class_applied:\"applied\",class_loading:\"loading\",class_loaded:\"loaded\",class_error:\"error\",class_entered:\"entered\",class_exited:\"exited\",unobserve_completed:!0,unobserve_entered:!1,cancel_on_exit:!0,callback_enter:null,callback_exit:null,callback_applied:null,callback_loading:null,callback_loaded:null,callback_error:null,callback_finish:null,callback_cancel:null,use_native:!1,restore_on_error:!1},c=function(t){return n({},r,t)},l=function(n,t){var e,i=\"LazyLoad::Initialized\",o=new n(t);try{e=new CustomEvent(i,{detail:{instance:o}})}catch(n){(e=document.createEvent(\"CustomEvent\")).initCustomEvent(i,!1,!1,{instance:o})}window.dispatchEvent(e)},u=\"src\",s=\"srcset\",d=\"sizes\",f=\"poster\",_=\"llOriginalAttrs\",g=\"data\",v=\"loading\",b=\"loaded\",p=\"applied\",m=\"error\",h=\"native\",E=\"data-\",I=\"ll-status\",y=function(n,t){return n.getAttribute(E+t)},k=function(n){return y(n,I)},w=function(n,t){return function(n,t,e){var i=\"data-ll-status\";null!==e?n.setAttribute(i,e):n.removeAttribute(i)}(n,0,t)},A=function(n){return w(n,null)},L=function(n){return null===k(n)},O=function(n){return k(n)===h},x=[v,b,p,m],C=function(n,t,e,i){n&&\"function\"==typeof n&&(void 0===i?void 0===e?n(t):n(t,e):n(t,e,i))},N=function(n,t){\"\"!==t&&(o?n.classList.add(t):n.className+=(n.className?\" \":\"\")+t)},M=function(n,t){\"\"!==t&&(o?n.classList.remove(t):n.className=n.className.replace(new RegExp(\"(^|\\\\s+)\"+t+\"(\\\\s+|$)\"),\" \").replace(/^\\s+/,\"\").replace(/\\s+$/,\"\"))},z=function(n){return n.llTempImage},T=function(n,t){if(t){var e=t._observer;e&&e.unobserve(n)}},R=function(n,t){n&&(n.loadingCount+=t)},G=function(n,t){n&&(n.toLoadCount=t)},j=function(n){for(var t,e=[],i=0;t=n.children[i];i+=1)\"SOURCE\"===t.tagName&&e.push(t);return e},D=function(n,t){var e=n.parentNode;e&&\"PICTURE\"===e.tagName&&j(e).forEach(t)},H=function(n,t){j(n).forEach(t)},V=[u],F=[u,f],B=[u,s,d],J=[g],P=function(n){return!!n[_]},S=function(n){return n[_]},U=function(n){return delete n[_]},$=function(n,t){if(!P(n)){var e={};t.forEach((function(t){e[t]=n.getAttribute(t)})),n[_]=e}},q=function(n,t){if(P(n)){var e=S(n);t.forEach((function(t){!function(n,t,e){e?n.setAttribute(t,e):n.removeAttribute(t)}(n,t,e[t])}))}},K=function(n,t,e){N(n,t.class_applied),w(n,p),e&&(t.unobserve_completed&&T(n,t),C(t.callback_applied,n,e))},Q=function(n,t,e){N(n,t.class_loading),w(n,v),e&&(R(e,1),C(t.callback_loading,n,e))},W=function(n,t,e){e&&n.setAttribute(t,e)},X=function(n,t){W(n,d,y(n,t.data_sizes)),W(n,s,y(n,t.data_srcset)),W(n,u,y(n,t.data_src))},Y={IMG:function(n,t){D(n,(function(n){$(n,B),X(n,t)})),$(n,B),X(n,t)},IFRAME:function(n,t){$(n,V),W(n,u,y(n,t.data_src))},VIDEO:function(n,t){H(n,(function(n){$(n,V),W(n,u,y(n,t.data_src))})),$(n,F),W(n,f,y(n,t.data_poster)),W(n,u,y(n,t.data_src)),n.load()},OBJECT:function(n,t){$(n,J),W(n,g,y(n,t.data_src))}},Z=[\"IMG\",\"IFRAME\",\"VIDEO\",\"OBJECT\"],nn=function(n,t){!t||function(n){return n.loadingCount>0}(t)||function(n){return n.toLoadCount>0}(t)||C(n.callback_finish,t)},tn=function(n,t,e){n.addEventListener(t,e),n.llEvLisnrs[t]=e},en=function(n,t,e){n.removeEventListener(t,e)},on=function(n){return!!n.llEvLisnrs},an=function(n){if(on(n)){var t=n.llEvLisnrs;for(var e in t){var i=t[e];en(n,e,i)}delete n.llEvLisnrs}},rn=function(n,t,e){!function(n){delete n.llTempImage}(n),R(e,-1),function(n){n&&(n.toLoadCount-=1)}(e),M(n,t.class_loading),t.unobserve_completed&&T(n,e)},cn=function(n,t,e){var i=z(n)||n;on(i)||function(n,t,e){on(n)||(n.llEvLisnrs={});var i=\"VIDEO\"===n.tagName?\"loadeddata\":\"load\";tn(n,i,t),tn(n,\"error\",e)}(i,(function(o){!function(n,t,e,i){var o=O(t);rn(t,e,i),N(t,e.class_loaded),w(t,b),C(e.callback_loaded,t,i),o||nn(e,i)}(0,n,t,e),an(i)}),(function(o){!function(n,t,e,i){var o=O(t);rn(t,e,i),N(t,e.class_error),w(t,m),C(e.callback_error,t,i),e.restore_on_error&&q(t,B),o||nn(e,i)}(0,n,t,e),an(i)}))},ln=function(n,t,e){!function(n){return Z.indexOf(n.tagName)>-1}(n)?function(n,t,e){!function(n){n.llTempImage=document.createElement(\"IMG\")}(n),cn(n,t,e),function(n){P(n)||(n[_]={backgroundImage:n.style.backgroundImage})}(n),function(n,t,e){var i=y(n,t.data_bg),o=y(n,t.data_bg_hidpi),r=a&&o?o:i;r&&(n.style.backgroundImage='url(\"'.concat(r,'\")'),z(n).setAttribute(u,r),Q(n,t,e))}(n,t,e),function(n,t,e){var i=y(n,t.data_bg_multi),o=y(n,t.data_bg_multi_hidpi),r=a&&o?o:i;r&&(n.style.backgroundImage=r,K(n,t,e))}(n,t,e),function(n,t,e){var i=y(n,t.data_bg_set);if(i){var o=i.split(\"|\"),a=o.map((function(n){return\"image-set(\".concat(n,\")\")}));n.style.backgroundImage=a.join(),\"\"===n.style.backgroundImage&&(a=o.map((function(n){return\"-webkit-image-set(\".concat(n,\")\")})),n.style.backgroundImage=a.join()),K(n,t,e)}}(n,t,e)}(n,t,e):function(n,t,e){cn(n,t,e),function(n,t,e){var i=Y[n.tagName];i&&(i(n,t),Q(n,t,e))}(n,t,e)}(n,t,e)},un=function(n){n.removeAttribute(u),n.removeAttribute(s),n.removeAttribute(d)},sn=function(n){D(n,(function(n){q(n,B)})),q(n,B)},dn={IMG:sn,IFRAME:function(n){q(n,V)},VIDEO:function(n){H(n,(function(n){q(n,V)})),q(n,F),n.load()},OBJECT:function(n){q(n,J)}},fn=function(n,t){(function(n){var t=dn[n.tagName];t?t(n):function(n){if(P(n)){var t=S(n);n.style.backgroundImage=t.backgroundImage}}(n)})(n),function(n,t){L(n)||O(n)||(M(n,t.class_entered),M(n,t.class_exited),M(n,t.class_applied),M(n,t.class_loading),M(n,t.class_loaded),M(n,t.class_error))}(n,t),A(n),U(n)},_n=[\"IMG\",\"IFRAME\",\"VIDEO\"],gn=function(n){return n.use_native&&\"loading\"in HTMLImageElement.prototype},vn=function(n,t,e){n.forEach((function(n){return function(n){return n.isIntersecting||n.intersectionRatio>0}(n)?function(n,t,e,i){var o=function(n){return x.indexOf(k(n))>=0}(n);w(n,\"entered\"),N(n,e.class_entered),M(n,e.class_exited),function(n,t,e){t.unobserve_entered&&T(n,e)}(n,e,i),C(e.callback_enter,n,t,i),o||ln(n,e,i)}(n.target,n,t,e):function(n,t,e,i){L(n)||(N(n,e.class_exited),function(n,t,e,i){e.cancel_on_exit&&function(n){return k(n)===v}(n)&&\"IMG\"===n.tagName&&(an(n),function(n){D(n,(function(n){un(n)})),un(n)}(n),sn(n),M(n,e.class_loading),R(i,-1),A(n),C(e.callback_cancel,n,t,i))}(n,t,e,i),C(e.callback_exit,n,t,i))}(n.target,n,t,e)}))},bn=function(n){return Array.prototype.slice.call(n)},pn=function(n){return n.container.querySelectorAll(n.elements_selector)},mn=function(n){return function(n){return k(n)===m}(n)},hn=function(n,t){return function(n){return bn(n).filter(L)}(n||pn(t))},En=function(n,e){var o=c(n);this._settings=o,this.loadingCount=0,function(n,t){i&&!gn(n)&&(t._observer=new IntersectionObserver((function(e){vn(e,n,t)}),function(n){return{root:n.container===document?null:n.container,rootMargin:n.thresholds||n.threshold+\"px\"}}(n)))}(o,this),function(n,e){t&&(e._onlineHandler=function(){!function(n,t){var e;(e=pn(n),bn(e).filter(mn)).forEach((function(t){M(t,n.class_error),A(t)})),t.update()}(n,e)},window.addEventListener(\"online\",e._onlineHandler))}(o,this),this.update(e)};return En.prototype={update:function(n){var t,o,a=this._settings,r=hn(n,a);G(this,r.length),!e&&i?gn(a)?function(n,t,e){n.forEach((function(n){-1!==_n.indexOf(n.tagName)&&function(n,t,e){n.setAttribute(\"loading\",\"lazy\"),cn(n,t,e),function(n,t){var e=Y[n.tagName];e&&e(n,t)}(n,t),w(n,h)}(n,t,e)})),G(e,0)}(r,a,this):(o=r,function(n){n.disconnect()}(t=this._observer),function(n,t){t.forEach((function(t){n.observe(t)}))}(t,o)):this.loadAll(r)},destroy:function(){this._observer&&this._observer.disconnect(),t&&window.removeEventListener(\"online\",this._onlineHandler),pn(this._settings).forEach((function(n){U(n)})),delete this._observer,delete this._settings,delete this._onlineHandler,delete this.loadingCount,delete this.toLoadCount},loadAll:function(n){var t=this,e=this._settings;hn(n,e).forEach((function(n){T(n,t),ln(n,e,t)}))},restoreAll:function(){var n=this._settings;pn(n).forEach((function(t){fn(t,n)}))}},En.load=function(n,t){var e=c(t);ln(n,e)},En.resetStatus=function(n){A(n)},t&&function(n,t){if(t)if(t.length)for(var e,i=0;e=t[i];i+=1)l(n,e);else l(n,t)}(En,window.lazyLoadOptions),En}));\n\n\n//# sourceURL=webpack://sinn/./node_modules/vanilla-lazyload/dist/lazyload.min.js?");/***/}),/***/"./source/out/sinn/src/js/app.js":(/*!***************************************!*\
  !*** ./source/out/sinn/src/js/app.js ***!
  \***************************************/ /***/function sourceOutSinnSrcJsAppJs(){eval("var body = document.querySelector('body');\n\n// Stop firing transition on page reload\nsetTimeout(function(){\n  body.classList.remove('js--transition');\n},50);\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/app.js?");/***/}),/***/"./source/out/sinn/src/js/modules/ArticleConfigurator.js":(/*!***************************************************************!*\
  !*** ./source/out/sinn/src/js/modules/ArticleConfigurator.js ***!
  \***************************************************************/ /***/function sourceOutSinnSrcJsModulesArticleConfiguratorJs(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   ArticleConfigurator: () => (/* binding */ ArticleConfigurator),\n/* harmony export */   \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/**\n * This Software is the property of dotfly and is protected\n * by copyright law - it is NOT Freeware.\n *\n * Any unauthorized use of this software without a valid license key\n * is a violation of the license agreement and will be prosecuted by\n * civil and criminal law.\n *\n * @category   Article Configuration State Management\n * @license    http://www.dotfly.de Commercial\n * @link       http://www.dotfly.de\n */\n\n/**\n * Central state management for configurable articles\n */\nclass ArticleConfigurator extends EventTarget {\n    constructor() {\n        super();\n\n        this._state = {};\n        this._locked = false;\n        this._initialState = null;\n        this._standardConfigHash = null;\n    }\n\n    /**\n     * Initialize with article data\n     */\n    initialize(data) {\n        if (!data || typeof data !== 'object') {\n            throw new Error('ArticleConfigurator: Invalid data provided to initialize()');\n        }\n\n        this._state = {\n            id: data.id || '',\n            artnum: data.artnum || '',\n            isWatch: data.isWatch || false,\n            isStrap: data.isStrap || false,\n            isClosure: data.isClosure || false,\n            isSetArticle: data.isSetArticle || false,\n            configuratorImage: data.configuratorImage || '',\n            configHash: data.configHash || '',\n            selectedStrap: data.selectedStrap || {},\n            selectedClosure: data.selectedClosure || {},\n            defaultStrap: data.defaultStrap || {},\n            defaultClosure: data.defaultClosure || {},\n            setItems: data.setItems || {},\n            proalphatitle: data.proalphatitle || '',\n            price: data.price || 0,\n            netPrice: data.netPrice || 0,\n            requiredForWatch: data.requiredForWatch || '',\n            requiredForWatchArtNum: data.requiredForWatchArtNum || '',\n            requiredForWatchProAlphaTitle: data.requiredForWatchProAlphaTitle || '',\n            options: data.options || {}\n        };\n\n        this._standardConfigHash = data.configHash || '';\n        \n        // Check if initialized from wishlist (has configHash and openConfigurator param)\n        const urlParams = new URLSearchParams(window.location.search);\n        const isFromWishlist = urlParams.get('openConfigurator') === '1' && data.configHash;\n\n        if (isFromWishlist) {\n            this._initialState = { ...this._state };\n            this.lock();\n        }\n\n        this.dispatchEvent(new CustomEvent('initialized', {\n            detail: {\n                state: { ...this._state },\n                isFromWishlist\n            }\n        }));\n\n        return this;\n    }\n\n    lock() {\n        this._locked = true;\n        this.dispatchEvent(new CustomEvent('locked'));\n        return this;\n    }\n\n    unlock() {\n        this._locked = false;\n        this.dispatchEvent(new CustomEvent('unlocked'));\n        return this;\n    }\n\n    get isLocked() {\n        return this._locked;\n    }\n\n    get state() {\n        return { ...this._state };\n    }\n\n    get(key) {\n        return this._state[key];\n    }\n\n    // Direct property access\n    get id() { return this._state.id; }\n    get artnum() { return this._state.artnum; }\n    get isWatch() { return this._state.isWatch; }\n    get isStrap() { return this._state.isStrap; }\n    get isClosure() { return this._state.isClosure; }\n    get isSetArticle() { return this._state.isSetArticle; }\n    get configuratorImage() { return this._state.configuratorImage; }\n    get configHash() { return this._state.configHash; }\n    get selectedStrap() { return this._state.selectedStrap; }\n    get selectedClosure() { return this._state.selectedClosure; }\n    get defaultStrap() { return this._state.defaultStrap; }\n    get defaultClosure() { return this._state.defaultClosure; }\n    get setItems() { return this._state.setItems; }\n    get proalphatitle() { return this._state.proalphatitle; }\n    get price() { return this._state.price; }\n    get netPrice() { return this._state.netPrice; }\n    get requiredForWatch() { return this._state.requiredForWatch; }\n    get requiredForWatchArtNum() { return this._state.requiredForWatchArtNum; }\n    get requiredForWatchProAlphaTitle() { return this._state.requiredForWatchProAlphaTitle; }\n    get options() { return this._state.options; }\n\n    // Setters with lock checking\n    set id(value) {\n        if (this._locked) return;\n        this._state.id = value;\n    }\n    set artnum(value) {\n        if (this._locked) return;\n        this._state.artnum = value;\n    }\n    set configHash(value) {\n        this.updateConfigHash(value);\n    }\n    set selectedStrap(value) {\n        this.updateStrap(value);\n    }\n    set selectedClosure(value) {\n        this.updateClosure(value);\n    }\n    set setItems(value) {\n        this.updateSetItems(value);\n    }\n    set price(value) {\n        if (this._locked) return;\n        this._state.price = value;\n    }\n    set requiredForWatch(value) {\n        this.updateRequiredForWatch(value);\n    }\n    set requiredForWatchProAlphaTitle(value) {\n        this._state.requiredForWatchProAlphaTitle = value;\n    }\n    set requiredForWatchArtNum(value) {\n        this._state.requiredForWatchArtNum = value;\n    }\n    set options(value) {\n        this.updateOptions(value);\n    }\n\n    set netPrice(value) {\n        if (this._locked) return;\n        this._state.netPrice = value;\n    }\n\n    updateStrap(strap, forceUpdate = false) {\n        if (this._locked && !forceUpdate) {\n            return this;\n        }\n\n        const oldStrap = { ...this._state.selectedStrap };\n        this._state.selectedStrap = { ...strap };\n\n        this.dispatchEvent(new CustomEvent('strapChanged', {\n            detail: {\n                strap: { ...strap },\n                oldStrap,\n                isLocked: this._locked\n            }\n        }));\n\n        return this;\n    }\n\n    updateClosure(closure, forceUpdate = false) {\n        if (this._locked && !forceUpdate) {\n            return this;\n        }\n\n        const oldClosure = { ...this._state.selectedClosure };\n        this._state.selectedClosure = { ...closure };\n\n        this.dispatchEvent(new CustomEvent('closureChanged', {\n            detail: {\n                closure: { ...closure },\n                oldClosure,\n                isLocked: this._locked\n            }\n        }));\n\n        return this;\n    }\n\n    updateConfigHash(hash, forceUpdate = false) {\n        if (this._locked && !forceUpdate) {\n            return this;\n        }\n\n        const oldHash = this._state.configHash;\n        this._state.configHash = hash;\n\n        this.dispatchEvent(new CustomEvent('configHashChanged', {\n            detail: {\n                hash,\n                oldHash,\n                isLocked: this._locked\n            }\n        }));\n\n        return this;\n    }\n\n    updateVariant(variant, forceUpdate = false) {\n        if (this._locked && !forceUpdate) {\n            return this;\n        }\n\n        const oldData = {\n            id: this._state.id,\n            artnum: this._state.artnum,\n            price: this._state.price,\n            configHash: this._state.configHash\n        };\n\n        this._state.id = variant.id || this._state.id;\n        this._state.artnum = variant.artnum || this._state.artnum;\n        this._state.price = variant.price || this._state.price;\n        this._state.configHash = variant.configHash || this._state.configHash;\n\n        this.dispatchEvent(new CustomEvent('variantChanged', {\n            detail: {\n                variant: { ...variant },\n                oldData,\n                isLocked: this._locked\n            }\n        }));\n\n        return this;\n    }\n\n    updateSetItems(setItems, forceUpdate = false) {\n        if (this._locked && !forceUpdate) {\n            return this;\n        }\n\n        const oldSetItems = { ...this._state.setItems };\n        this._state.setItems = { ...setItems };\n\n        this.dispatchEvent(new CustomEvent('setItemsChanged', {\n            detail: {\n                setItems: { ...setItems },\n                oldsetItems,\n                isLocked: this._locked\n            }\n        }));\n\n        return this;\n    }\n\n    updateRequiredForWatch(requiredForWatch, forceUpdate = false) {\n        if (this._locked && !forceUpdate) {\n            return this;\n        }\n\n        const oldRequiredForWatch = this._state.requiredForWatch;\n        this._state.requiredForWatch = requiredForWatch;\n\n        this.dispatchEvent(new CustomEvent('requiredForWatchChanged', {\n            detail: {\n                requiredForWatch: requiredForWatch,\n                oldRequiredForWatch,\n                isLocked: this._locked\n            }\n        }));\n\n        return this;\n    }\n\n    updateOptions(options, forceUpdate = false) {\n        if (this._locked && !forceUpdate) {\n            return this;\n        }\n\n        const oldOptions = { ...this._state.options };\n        this._state.options = { ...options };\n\n        this.dispatchEvent(new CustomEvent('optionsChanged', {\n            detail: {\n                options: { ...options },\n                oldOptions,\n                isLocked: this._locked\n            }\n        }));\n\n        return this;\n    }\n\n    resetToStandardConfiguration() {\n        // Reset to standard config\n        this._state.selectedStrap = { ...this._state.defaultStrap };\n        this._state.selectedClosure = { ...this._state.defaultClosure };\n        this._state.options = {};\n        this._state.configHash = this._standardConfigHash;\n        \n        // Reset to original article ID and price\n        // Don't use initialState as that might contain wishlist configuration\n        // Instead, get the original product data from page load\n        const originalArticleId = document.querySelector('input[name=\"anid\"]')?.value;\n        if (originalArticleId) {\n            this._state.id = originalArticleId;\n        }\n\n        return this;\n    }\n\n    isOriginalConfiguration() {\n        if (!this._initialState) return true;\n        return this._state.configHash === this._initialState.configHash;\n    }\n\n    getDebugInfo() {\n        return {\n            isLocked: this._locked,\n            hasInitialState: !!this._initialState,\n            isOriginal: this.isOriginalConfiguration(),\n            state: { ...this._state },\n            initialState: this._initialState ? { ...this._initialState } : null\n        };\n    }\n}\n\n// Singleton wrapper\nconst articleConfigurator = (() => {\n    let instance = null;\n\n    return {\n        getInstance() {\n            if (!instance) {\n                instance = new ArticleConfigurator();\n            }\n            return instance;\n        },\n\n        reset() {\n            if (instance) {\n                instance._state = {};\n                instance._locked = false;\n                instance._initialState = null;\n                instance._standardConfigHash = null;\n            }\n            instance = null;\n        },\n\n        resetToStandardConfiguration() {\n            if (instance) {\n                return instance.resetToStandardConfiguration();\n            }\n            return null;\n        }\n    };\n})();\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (articleConfigurator);\n\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/ArticleConfigurator.js?");/***/}),/***/"./source/out/sinn/src/js/modules/SetArticleVariants.js":(/*!**************************************************************!*\
  !*** ./source/out/sinn/src/js/modules/SetArticleVariants.js ***!
  \**************************************************************/ /***/function sourceOutSinnSrcJsModulesSetArticleVariantsJs(){eval("/**\n * Set Article Variants Module\n * Handles variant selection for combinable options in set articles\n * \n * @author SINN Spezialuhren\n * @version 1.0.1\n */\n\nclass SetArticleVariants {\n    constructor() {\n        this.parentId = null;\n        this.checkboxes = null;\n        this.form = null;\n        this.aidInput = null;\n        this.priceElements = null;\n\n        this.init();\n    }\n\n    /**\n     * Initialize the module\n     */\n    init() {\n        if (document.readyState === 'loading') {\n            document.addEventListener('DOMContentLoaded', () => this.setup());\n        } else {\n            this.setup();\n        }\n    }\n\n    /**\n     * Setup the variant selection functionality\n     */\n    setup() {\n        // Get parentId from global variable set in template\n        if (typeof window.setArticleVariantsConfig !== 'undefined' && window.setArticleVariantsConfig.parentId) {\n            this.parentId = window.setArticleVariantsConfig.parentId;\n        } else {\n            console.warn('SetArticleVariants: parentId not found in config');\n            return;\n        }\n\n        // Get checkboxes for variant options\n        this.checkboxes = document.querySelectorAll('.combinable-option');\n\n        // Get form and inputs for variant ID update\n        this.form = document.querySelector('.js-oxProductForm');\n        this.aidInput = this.form ? this.form.querySelector('input[name=\"aid\"]') : null;\n\n        // Get all elements that show the product price\n        this.priceElements = document.querySelectorAll('.js-product-price');\n\n        this.bindEvents();\n    }\n\n    /**\n     * Bind event listeners to checkboxes\n     */\n    bindEvents() {\n        if (this.checkboxes && this.checkboxes.length > 0) {\n            this.checkboxes.forEach((checkbox) => {\n                checkbox.addEventListener('change', () => this.updateVariant());\n            });\n        }\n    }\n\n    /**\n     * Update variant based on selected options\n     */\n    updateVariant() {\n        const selectedOptions = {};\n\n        // Collect selected options\n        this.checkboxes.forEach((checkbox) => {\n            if (checkbox.checked) {\n                selectedOptions[checkbox.name] = 1;\n            }\n        });\n\n        // AJAX call to find matching variant\n        fetch('/widget.php?cl=setarticleoptions&fnc=findVariant', {\n            method: 'POST',\n            headers: {\n                'Content-Type': 'application/json',\n            },\n            body: JSON.stringify({\n                parentId: this.parentId,\n                selectedOptions: selectedOptions\n            })\n        })\n        .then(response => response.json())\n        .then(data => {\n            if (data.success && data.variantId) {\n                // Update form with variant ID\n                if (this.aidInput) this.aidInput.value = data.variantId;\n\n                // Update all price elements with new price\n                if (data.price && this.priceElements) {\n                    this.priceElements.forEach(el => {\n                        el.textContent = data.price + ' €';\n                    });\n                }\n            } else {\n                // Reset to parent ID if no variant found\n                this.resetVariant();\n            }\n        })\n        .catch(error => {\n            console.error('Error finding variant:', error);\n\n            // Reset to parent ID on error\n            this.resetVariant();\n        });\n    }\n\n    /**\n     * Reset variant selection to parent article\n     */\n    resetVariant() {\n        if (this.aidInput) this.aidInput.value = this.parentId;\n\n        // Reset all price elements to original price\n        this.resetPrice();\n    }\n\n    /**\n     * Reset price to original value\n     */\n    resetPrice() {\n        if (this.priceElements && window.setArticleVariantsConfig?.originalPrice) {\n            this.priceElements.forEach(el => {\n                el.textContent = window.setArticleVariantsConfig.originalPrice + ' €';\n            });\n        }\n    }\n}\n\n// Initialize the module\nnew SetArticleVariants();\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/SetArticleVariants.js?");/***/}),/***/"./source/out/sinn/src/js/modules/accordion.js":(/*!*****************************************************!*\
  !*** ./source/out/sinn/src/js/modules/accordion.js ***!
  \*****************************************************/ /***/function sourceOutSinnSrcJsModulesAccordionJs(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   accordion: () => (/* binding */ accordion)\n/* harmony export */ });\n/* harmony import */ var animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! animejs/lib/anime.es.js */ \"./node_modules/animejs/lib/anime.es.js\");\n\n\nconst accordion = () => {\n\tvar accordionItems = document.querySelectorAll('.c-accordion__item');\n\tvar cubicBezier = 'cubicBezier(.40,.05,.20,.90)';\n\tvar accordionContentHeight, accordionBodyHeight, setViewportWidth;\n\n\tif (accordionItems) {\n\t\taccordionItems.forEach((item) => {\n\t\t\tvar accordion   = item;\n\t\t\tvar content     = item.querySelector('.c-accordion__body');\n\t\t\tvar header      = item.querySelector('.c-accordion__header');\n\n\t\t\theader.addEventListener('click', function () {\n\t\t\t\taccordionBodyHeight = item.querySelector('.c-accordion__content').getBoundingClientRect().height;\n\t\t\t\taccordionContentHeight = accordionBodyHeight + 'px';\n\n\t\t\t\taccordion.classList.add('js--pointerevent');\n\n\t\t\t\tif (accordion.classList.contains('js--active')) {\n\t\t\t\t\t(0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])({\n\t\t\t\t\t\ttargets: content,\n\t\t\t\t\t\theight: '0',\n\t\t\t\t\t\tduration: 650,\n\t\t\t\t\t\teasing: cubicBezier,\n\t\t\t\t\t\tcomplete: function () {\n\t\t\t\t\t\t\taccordion.classList.remove('js--active', 'js--pointerevent');\n\t\t\t\t\t\t\taccordion.classList.add('is--closed');\n\t\t\t\t\t\t\taccordion.querySelector('.c-accordion__header').setAttribute('aria-expanded', false);\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t} else {\n\t\t\t\t\taccordion.classList.add('js--active', 'js--pointerevent');\n\n\t\t\t\t\t(0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])({\n\t\t\t\t\t\ttargets: content,\n\t\t\t\t\t\theight: ['0', accordionContentHeight],\n\t\t\t\t\t\tduration: 650,\n\t\t\t\t\t\teasing: cubicBezier,\n\t\t\t\t\t\tcomplete: function () {\n\t\t\t\t\t\t\taccordion.classList.remove('js--pointerevent');\n\t\t\t\t\t\t\taccordion.classList.remove('is--closed');\n\t\t\t\t\t\t\taccordion.querySelector('.c-accordion__header').setAttribute('aria-expanded', true);\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t});\n\n\t\t\twindow.addEventListener('resize', () => {\n\t\t\t\tsetViewportWidth = window.innerWidth;\n\n\t\t\t\taccordionBodyHeight = item.querySelector('.c-accordion__content').getBoundingClientRect().height;\n\t\t\t\taccordionContentHeight = accordionBodyHeight + 'px';\n\n\t\t\t\tif (accordion.classList.contains('js--active') && !accordion.classList.contains('js--pointerevent')) {\n\t\t\t\t\tcontent.style.height = accordionContentHeight;\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n}\n\nconst techAbcExcludedPages = document.querySelector('.is-checkout, .cl-techabcfrontendcontroller');\n\nif (techAbcExcludedPages) {\n\taccordion();\n}\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/accordion.js?");/***/}),/***/"./source/out/sinn/src/js/modules/adressform.js":(/*!******************************************************!*\
  !*** ./source/out/sinn/src/js/modules/adressform.js ***!
  \******************************************************/ /***/function sourceOutSinnSrcJsModulesAdressformJs(){eval("var _oForm = document.getElementById('addressForm');\nvar _oField = document.querySelector('#addressForm .e-form__wrap.text-danger');\n\nif (_oField) {\n\t_oForm.classList.add('is--shown');\n}\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/adressform.js?");/***/}),/***/"./source/out/sinn/src/js/modules/alert.js":(/*!*************************************************!*\
  !*** ./source/out/sinn/src/js/modules/alert.js ***!
  \*************************************************/ /***/function sourceOutSinnSrcJsModulesAlertJs(){eval("var alert = document.querySelector('.js-alert');\nvar alertClose = document.querySelector('.js-alert_close');\n\nif (alert) {\n\n    alertClose.addEventListener('click', (event) => {\n        event.target.closest('.js-alert').classList.add('is--hidden')\n    });\n}\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/alert.js?");/***/}),/***/"./source/out/sinn/src/js/modules/amountCounter.js":(/*!*********************************************************!*\
  !*** ./source/out/sinn/src/js/modules/amountCounter.js ***!
  \*********************************************************/ /***/function sourceOutSinnSrcJsModulesAmountCounterJs(){eval("document.addEventListener('DOMContentLoaded', function() {\n\tconst minusButtons = document.querySelectorAll('.js--btn-count-minus');\n\tconst plusButtons = document.querySelectorAll('.js--btn-count-plus');\n\tconst amountInputs = document.querySelectorAll('.js--btn-count-input');\n\tconst additionalAmountInput = document.getElementById('amountToBasket2');\n    const extrasAmountInput = document.getElementById('hiddenAmount');\n\n\tif (minusButtons.length === plusButtons.length && minusButtons.length === amountInputs.length) {\n\t  for (let i = 0; i < minusButtons.length; i++) {\n\t\tconst minusButton = minusButtons[i];\n\t\tconst plusButton = plusButtons[i];\n\t\tconst amountInput = amountInputs[i];\n\n\t\tconst minValue = parseInt(amountInput.min);\n\t\tconst maxValue = parseInt(amountInput.max);\n\n\t\tminusButton.addEventListener('click', function() {\n\t\t  updateAmount(amountInput, -1, minValue, maxValue);\n\t\t  if (additionalAmountInput) {\n\t\t\tupdateAmount(additionalAmountInput, -1, minValue, maxValue);\n\t\t  }\n\t\t});\n\n\t\tplusButton.addEventListener('click', function() {\n\t\t  updateAmount(amountInput, 1, minValue, maxValue);\n\t\t  if (additionalAmountInput) {\n\t\t\tupdateAmount(additionalAmountInput, 1, minValue, maxValue);\n\t\t  }\n\t\t});\n\t  }\n\t}\n\n\tfunction updateAmount(amountInput, change, minValue, maxValue) {\n\t  let currentValue = parseInt(amountInput.value);\n\t  let newValue = currentValue + change;\n\n\t  if (newValue >= minValue && newValue <= maxValue) {\n\t\tamountInput.value = newValue;\n        extrasAmountInput.value = newValue;\n\t  }\n\t}\n});\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/amountCounter.js?");/***/}),/***/"./source/out/sinn/src/js/modules/animateOffcanvas.js":(/*!************************************************************!*\
  !*** ./source/out/sinn/src/js/modules/animateOffcanvas.js ***!
  \************************************************************/ /***/function sourceOutSinnSrcJsModulesAnimateOffcanvasJs(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   animateOffcanvas: () => (/* binding */ animateOffcanvas)\n/* harmony export */ });\n/**\n * This Software is the property of dotfly and is protected\n * by copyright law - it is NOT Freeware.\n *\n * Any unauthorized use of this software without a valid license key\n * is a violation of the license agreement and will be prosecuted by\n * civil and criminal law.\n *\n * @category\n * @author     Lennart Syre <lennart.syre@dotfly.de>\n * @license    http://www.dotfly.de Commercial\n * @link       http://www.dotfly.de\n */\n\n\nconst animateOffcanvas = function(options={}) {\n    const offCanvas         = document.querySelector(options.offCanvas);\n    const triggers          = document.querySelectorAll(options.triggers);\n    const closeButtons      = document.querySelectorAll(options.closeButtons);\n    const callSelf          = options.callSelf ? options.callSelf : false;\n    const classActive       = 'js--active';\n\n    const resetMobileCanvas = function() {\n        let activeCanvasesMobile = document.querySelectorAll('.c-mobilemenu__item.js--active');\n\n        activeCanvasesMobile.forEach(element => {\n            let canvas = document.querySelector('.' + element.dataset.layer);\n            // animate\n            element.classList.remove(classActive);\n            canvas.classList.remove(classActive);\n\n            // edge case retailer footer\n            const footerTrigger = document.querySelector('a[href=\"#fachhändler\"].js--active');\n            footerTrigger && footerTrigger.classList.remove(classActive);\n\n            // edge case search input focus blur input\n            const searchField = document.querySelector('.c-search.js--active #searchParam');\n            let searchTriggerMobile = document.querySelector('#mobileSearchTrigger');\n            searchTriggerMobile && searchTriggerMobile.classList.remove('is--focused');\n            searchField && searchField.blur();\n\n            // display none after aninmation\n            const transitionEndHandler = function (event) {\n                if (event.target === canvas.firstElementChild) {\n                    canvas.firstElementChild.removeEventListener('transitionend', transitionEndHandler);\n                    canvas.style = 'display: none';\n                }\n            };\n            canvas.firstElementChild.addEventListener('transitionend', transitionEndHandler);\n        });\n    }\n\n    const openOffcanvas = function() {\n        // close mobile offcanvases before opening another\n        resetMobileCanvas();\n\n        // display the canvas\n        offCanvas.style = 'display: block;'\n\n        requestAnimationFrame(() => {\n            // Use a slight delay if needed to ensure everything is fully applied\n            setTimeout(() => {\n                // Trigger scss animation after canvas is displayed\n                offCanvas.classList.add(classActive);\n                triggers && triggers.forEach(item => {\n                    item.classList.add(classActive);\n                });\n            }, 0);\n        });\n    }\n\n    const closeOffcanvas = function() {\n        const offCanvasInner = offCanvas.querySelector('.c-offcanvas__inner');\n        // wait for c-offcanvas__inner transition\n        const transitionEndHandler = function (event) {\n            if (event.target === offCanvasInner) {\n                offCanvasInner.removeEventListener('transitionend', transitionEndHandler);\n                triggers && triggers.forEach(item => {\n                    item.classList.remove(classActive);\n                });\n                offCanvas.style = 'display: none';\n            }\n        };\n        offCanvasInner && offCanvasInner.addEventListener('transitionend', transitionEndHandler);\n        offCanvas.classList.remove(classActive);\n    }\n\n    // register Event listeners\n    closeButtons && closeButtons.forEach(close => {\n        close.addEventListener('click', closeOffcanvas);\n    })\n\n    triggers.forEach(item => {\n        item.addEventListener('click', () => {\n            if (item.classList.contains(classActive)) {\n                closeOffcanvas();\n            } else {\n                openOffcanvas();\n            }\n        });\n    });\n\n    if (callSelf) {\n        openOffcanvas();\n    }\n\n    // Immer geöffnete Offcanvas-Layer mit Möglichkeit zu anderen Layern zu springen\n    const alwaysOpenOffcanvas = function() {\n        const alwaysOpenOffcanvasElements = document.querySelectorAll('.c-offcanvas.js--always-open');\n        const classActive = 'js--active';\n\n        if (alwaysOpenOffcanvasElements.length > 0) {\n            alwaysOpenOffcanvasElements.forEach(element => {\n                element.style.display = 'block'; // Erst sichtbar machen\n\n                requestAnimationFrame(() => {\n                    setTimeout(() => {\n                        element.classList.add(classActive);\n                    }, 0);\n                });\n\n                // Toggle-Funktion für Schließen und Öffnen eines neuen Offcanvas\n                const toggleButton = element.querySelector('.c-offcanvas__toggle');\n                if (toggleButton) {\n                    toggleButton.addEventListener('click', () => {\n                        const targetLayer = toggleButton.dataset.target;\n\n                        element.classList.remove(classActive);\n                        element.addEventListener('transitionend', () => {\n                            element.style.display = 'none';\n\n                            if (targetLayer) {\n                                const newOffcanvas = document.querySelector(`.c-offcanvas[data-layer=\"${targetLayer}\"]`);\n                                if (newOffcanvas) {\n                                    newOffcanvas.style.display = 'block';\n\n                                    requestAnimationFrame(() => {\n                                        setTimeout(() => {\n                                            newOffcanvas.classList.add(classActive);\n                                        }, 0);\n                                    });\n                                }\n                            }\n                        }, { once: true });\n                    });\n                }\n\n                const closeButton = element.querySelector('.c-offcanvas__close');\n                if (closeButton) {\n                    closeButton.addEventListener('click', () => {\n                        element.classList.remove(classActive);\n                        element.addEventListener('transitionend', () => {\n                            closeOffcanvas();\n                        }, { once: true });\n                    });\n                }\n            });\n        }\n    };\n\n\n    document.addEventListener('DOMContentLoaded', alwaysOpenOffcanvas);\n}\n\n\nconst backButtonHandler = function() {\n    const backButtons = document.querySelectorAll('.c-offcanvas__back-button');\n    if (backButtons.length === 0) return;\n\n    const classActive = 'js--active';\n\n    backButtons.forEach(backButton => {\n        backButton.addEventListener('click', () => {\n            const currentOffcanvas = backButton.closest('.c-offcanvas');\n            const targetLayer = backButton.dataset.target;\n\n            if (!targetLayer) return;\n\n            const newOffcanvas = document.querySelector(`.c-offcanvas[data-layer=\"${targetLayer}\"]`);\n            if (!newOffcanvas) return;\n\n            const currentInner = currentOffcanvas.querySelector('.c-offcanvas__inner');\n            const transitionEndHandler = function(event) {\n                if (event.target === currentInner) {\n                    currentInner.removeEventListener('transitionend', transitionEndHandler);\n                    currentOffcanvas.style.display = 'none';\n\n                    newOffcanvas.style.display = 'block';\n                    requestAnimationFrame(() => {\n                        setTimeout(() => {\n                            newOffcanvas.classList.add(classActive);\n                        }, 0);\n                    });\n                }\n            };\n\n            currentInner.addEventListener('transitionend', transitionEndHandler);\n            currentOffcanvas.classList.remove(classActive);\n        });\n    });\n};\n\ndocument.addEventListener('DOMContentLoaded', backButtonHandler);\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/animateOffcanvas.js?");/***/}),/***/"./source/out/sinn/src/js/modules/animation.js":(/*!*****************************************************!*\
  !*** ./source/out/sinn/src/js/modules/animation.js ***!
  \*****************************************************/ /***/function sourceOutSinnSrcJsModulesAnimationJs(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   isKeyboardInput: () => (/* binding */ isKeyboardInput)\n/* harmony export */ });\n/* harmony import */ var _registerOffcanvas__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./registerOffcanvas */ \"./source/out/sinn/src/js/modules/registerOffcanvas.js\");\n/* harmony import */ var _lazyload__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./lazyload */ \"./source/out/sinn/src/js/modules/lazyload.js\");\n/* harmony import */ var _overlay_overlayContentLoader__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./overlay/overlayContentLoader */ \"./source/out/sinn/src/js/modules/overlay/overlayContentLoader.js\");\n/* harmony import */ var _configurator_configurator__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./configurator/configurator */ \"./source/out/sinn/src/js/modules/configurator/configurator.js\");\n/**\n * This Software is the property of dotfly and is protected\n * by copyright law - it is NOT Freeware.\n *\n * Any unauthorized use of this software without a valid license key\n * is a violation of the license agreement and will be prosecuted by\n * civil and criminal law.\n *\n * @category   Manages offCanvas animations\n * @author     Lennart Syre <info@dotfly.de>, Iris Isabell Jirka <iris.jirka@dotfly.de>, Anna Morawe <anna.morawe@dotfly.de>\n * @license    http://www.dotfly.de Commercial\n * @link       http://www.dotfly.de\n */\n\n// Imports\n\n\n\n\n\n// --- Animate Flyout :: Product Search\n(0,_registerOffcanvas__WEBPACK_IMPORTED_MODULE_0__.registerOffcanvas)({\n    offCanvas: '.c-search',\n    triggers: '.c-function.is--search .c-function__label, .c-mobilemenu__item.is--search',\n});\n\n// --- Animate Flyout :: Login\n(0,_registerOffcanvas__WEBPACK_IMPORTED_MODULE_0__.registerOffcanvas)({\n    offCanvas: '.c-login',\n    triggers: '.c-function.is--account .c-function__label, .c-mobilemenu__item.is--account',\n});\n\n// --- Animate Flyout :: Priceinfo\n(0,_registerOffcanvas__WEBPACK_IMPORTED_MODULE_0__.registerOffcanvas)({\n    offCanvas: '.c-priceinfo',\n    triggers: '.c-priceinfo__trigger'\n});\n\n// --- Animate Flyout :: Strap Configurator\ndocument.addEventListener('strapConfiguratorLoaded', () => {\n    (0,_registerOffcanvas__WEBPACK_IMPORTED_MODULE_0__.registerOffcanvas)({\n        offCanvas: '.c-strapconfigurator',\n        triggers: '#selectClasp',\n    }).openOffcanvas(document.querySelector('#selectClasp'));\n});\n\n\n// --- Animate Flyout :: Cart\n(0,_registerOffcanvas__WEBPACK_IMPORTED_MODULE_0__.registerOffcanvas)({\n    offCanvas: '.c-cart',\n    triggers: '.c-function.is--basket .c-function__label, .c-mobilemenu__item.is--cart',\n});\n\nlet openModal = document.querySelector('.c-modal.js--openMinibasket');\nif (openModal) {\n    (0,_registerOffcanvas__WEBPACK_IMPORTED_MODULE_0__.registerOffcanvas)({\n        offCanvas: '.c-cart',\n    }).openOffcanvas(document.querySelector('.c-function.is--basket'));\n}\n\n// --- Animate Flyout :: Refine layer\n(0,_registerOffcanvas__WEBPACK_IMPORTED_MODULE_0__.registerOffcanvas)({\n    offCanvas: '.c-refinelayer',\n    triggers: '.c-refine__action-item .js-show-filter, .c-mobilemenu__item.is--refine',\n});\n// --- Animate Flyout :: Tech ABC\n\n// registerOffcanvas wird im TechABC Modul aufgerufen!!!\n\n// --- Animate Flyout :: Warranty\n(0,_registerOffcanvas__WEBPACK_IMPORTED_MODULE_0__.registerOffcanvas)({\n    offCanvas: '.c-warranty',\n    triggers: '.c-warranty__link',\n});\n\n// --- Animate Flyout :: Basket Question\nvar basketquestionComponent = document.querySelector('#basket-question');\nvar basketquestionTriggers = document.querySelectorAll('#toBasket:not(.is--directlytobasket)');\n\ndocument.addEventListener('basket-questionLoaded', () => { \n    (0,_registerOffcanvas__WEBPACK_IMPORTED_MODULE_0__.registerOffcanvas)({\n        offCanvas: '.c-basketquestion',\n        triggers: '#toBasket:not(.is--directlytobasket)',\n        closeButtons: '.c-basketquestion__close, .c-basketquestion__background, #questionConfigureButton'\n    }).openOffcanvas(document.querySelector('#toBasket:not(.is--directlytobasket)'));\n\n    _lazyload__WEBPACK_IMPORTED_MODULE_1__.lazyContent.update();\n\n    \n    // Handle configurator \n    if (document.querySelector('#configurator').classList.contains('js--fetched')) {\n        //register Configurator Overlay (configurator edge case)\n        (0,_registerOffcanvas__WEBPACK_IMPORTED_MODULE_0__.registerOffcanvas)({\n            offCanvas: '.c-configurator',\n            triggers: '.c-detail__configure-button, .c-detail__sticky-configure--button, .c-basketquestion .is--configuratortrigger',\n            closeButtons: '.c-configurator__closer, .c-configurator__background, .c-configurator__desciption-actions--forward, .c-configurator__options-actions--forward',\n        });\n    } else {\n        // reassign overlay Trigger (configurator edge case)\n        (0,_overlay_overlayContentLoader__WEBPACK_IMPORTED_MODULE_2__.initOverlayContentLoader)(document.querySelector('.c-basketquestion'));\n    }\n    //reassign the eventHandlers for configurator (edge case)\n    (0,_configurator_configurator__WEBPACK_IMPORTED_MODULE_3__.assignEventHandlerTrigger)();\n});\n\nif (basketquestionComponent) {\n    basketquestionTriggers.forEach((item) => {\n        item.addEventListener('click', function (event) {\n            event.stopPropagation();\n            event.preventDefault();\n        });\n    });\n}\n\n// --- Animate Flyout :: Retailer\nconst retailerSelectors = {\n    triggers: '.c-function.is--dealer .c-function__label, a[href=\"#fachhändler\"], .c-mobilemenu__item.is--retailer'\n}\nlet isKeyboardInput = false;\n\ndocument.querySelectorAll(retailerSelectors.triggers).forEach((trigger) => {\n  trigger.addEventListener('keydown', (event) => {\n        if (event.key === 'Enter' || event.keyCode === 13) {\n            isKeyboardInput = true;\n            event.preventDefault();\n            trigger.click();\n        }\n    });\n});\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/animation.js?");/***/}),/***/"./source/out/sinn/src/js/modules/articleConfiguratorInit.js":(/*!*******************************************************************!*\
  !*** ./source/out/sinn/src/js/modules/articleConfiguratorInit.js ***!
  \*******************************************************************/ /***/function sourceOutSinnSrcJsModulesArticleConfiguratorInitJs(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"default\": () => (__WEBPACK_DEFAULT_EXPORT__),\n/* harmony export */   initializeArticleConfigurator: () => (/* binding */ initializeArticleConfigurator),\n/* harmony export */   shouldInitialize: () => (/* binding */ shouldInitialize)\n/* harmony export */ });\n/* harmony import */ var _ArticleConfigurator_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./ArticleConfigurator.js */ \"./source/out/sinn/src/js/modules/ArticleConfigurator.js\");\n/**\n * This Software is the property of dotfly and is protected\n * by copyright law - it is NOT Freeware.\n *\n * Any unauthorized use of this software without a valid license key\n * is a violation of the license agreement and will be prosecuted by\n * civil and criminal law.\n *\n * @category   Article Configuration Initialization\n * @license    http://www.dotfly.de Commercial\n * @link       http://www.dotfly.de\n */\n\n\n\n/**\n * Initialize the articleConfigurator with data from PHP/Smarty template\n * This function should be called once when the page loads with the article data\n */\nfunction initializeArticleConfigurator() {\n    // Get the data that was set by the PHP template\n    const articleInitData = window.articleInitData;\n\n    if (!articleInitData) {\n        console.warn('ArticleConfigurator: No initialization data found');\n        return null;\n    }\n\n    // Get the article object singleton instance\n    const articleObject = _ArticleConfigurator_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"].getInstance();\n\n    // Initialize with the data from PHP\n    articleObject.initialize(articleInitData);\n\n    // Make it available globally\n    window.articleObject = articleObject;\n\n    // Dispatch custom event to notify other modules that articleObject is ready\n    document.dispatchEvent(new CustomEvent('articleObjectReady', {\n        detail: { articleObject }\n    }));\n\n    // Make available in console for debugging\n    window.articleConfiguration = articleObject;\n\n    return articleObject;\n}\n\n/**\n * Check if we are on a detail page and should initialize the configurator\n */\nfunction shouldInitialize() {\n    // Check if we're on a detail page\n    const isDetailPage = document.body.classList.contains('details') ||\n                        document.querySelector('.c-detail') ||\n                        document.querySelector('#productConfigurator') ||\n                        window.location.pathname.includes('/index.php') &&\n                        (window.location.search.includes('cl=details') ||\n                         window.location.search.includes('cl=articledetails'));\n\n    // Check if initialization data is available\n    const hasInitData = window.articleInitData &&\n                       typeof window.articleInitData === 'object' &&\n                       window.articleInitData.id;\n\n    return isDetailPage && hasInitData;\n}\n\n// Auto-initialize when DOM is ready - but only on detail pages with data\ndocument.addEventListener('DOMContentLoaded', () => {\n\n    if (shouldInitialize()) {\n        initializeArticleConfigurator();\n    }\n});\n\n// Export for manual initialization if needed\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (initializeArticleConfigurator);\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/articleConfiguratorInit.js?");/***/}),/***/"./source/out/sinn/src/js/modules/breadcrumb.js":(/*!******************************************************!*\
  !*** ./source/out/sinn/src/js/modules/breadcrumb.js ***!
  \******************************************************/ /***/function sourceOutSinnSrcJsModulesBreadcrumbJs(){eval("var breadcrumb = document.querySelector('.js--breadcrumb');\nvar breadcrumbContainer = document.querySelector('.js--breadcrumb-container');\nvar breadcrumbContainerCMS = document.querySelector('.js--breadcrumb-container-cms');\n\nif(breadcrumb) {\n    // Breadcrumb auf Detailseite\n    if(document.querySelector('body').classList.contains('cl-details') && window.innerWidth >= 1024) {\n        breadcrumbContainer.appendChild(breadcrumb);\n    }\n\n    if(document.querySelector('body').classList.contains('cl-alist') || document.querySelector('body').classList.contains('cl-start')) {\n\n        if(document.querySelector('.cmsContent')) {\n            // Breadcrumb auf Contentseiten\n            if(breadcrumbContainerCMS) {\n                breadcrumbContainerCMS.appendChild(breadcrumb);\n            }\n        } else {\n            // Breadcrumb auf Productliste\n            if(breadcrumbContainer) {\n                breadcrumbContainer.appendChild(breadcrumb);\n            }\n        }\n\n    }\n}\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/breadcrumb.js?");/***/}),/***/"./source/out/sinn/src/js/modules/cart.js":(/*!************************************************!*\
  !*** ./source/out/sinn/src/js/modules/cart.js ***!
  \************************************************/ /***/function sourceOutSinnSrcJsModulesCartJs(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! animejs/lib/anime.es.js */ \"./node_modules/animejs/lib/anime.es.js\");\n/* harmony import */ var _minicartflapper__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./minicartflapper */ \"./source/out/sinn/src/js/modules/minicartflapper.js\");\n\n\n\n$('body').on('click', '.c-minibasket__contents--delete', function () {\n\tvar ajaxTarget \t\t\t= document.getElementById('ajaxTargetMB').value;\n\tvar sessionToken \t\t= document.getElementById('sessionTokenMB').value;\n\tvar minibasketContainer = document.querySelector('.c-minibasket__wrapper');\n\tvar basketCounter \t\t= document.getElementById('basketCounter');\n\tvar cartLoader \t\t\t= document.querySelector('.c-cart__loader');\n\tvar cubicBezier \t\t= 'cubicBezier(.40,.05,.20,.90)';\n\n\tcartLoader.style.display = 'flex';\n\tcartLoader.classList.add('js--active');\n\n\t(0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])({\n\t\ttargets: cartLoader,\n\t\topacity: ['0', '1'],\n\t\tduration: 250,\n\t\teasing: cubicBezier\n\t})\n\n\t$.ajax({\n\t\turl: ajaxTarget + \"cl=basket&fnc=ajaxRemoveArticleFromBasket&stoken=\" + sessionToken,\n\t\tmethod: \"POST\",\n\t\tdata: {basketindex: $(this).data('basketindex')},\n\t\tsuccess: function (ret) {\n\t\t\tminibasketContainer.innerHTML = ret;\n\t\t\tbasketCounter.innerText = document.getElementsByClassName('c-minibasket__item').length;\n\n\t\t\tvar cart = document.querySelector('.c-minibasket__overflow');\n\n\t\t\t(0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])({\n\t\t\t\ttargets: cartLoader,\n\t\t\t\topacity: '0',\n\t\t\t\tduration: 250,\n\t\t\t\teasing: cubicBezier,\n\t\t\t\tcomplete: function () {\n\t\t\t\t\tcartLoader.classList.remove('js--active');\n\t\t\t\t\tcartLoader.style.display = 'none';\n\t\t\t\t}\n\t\t\t})\n\t\t\t;(0,_minicartflapper__WEBPACK_IMPORTED_MODULE_1__.addFlapper)();\n\t\t}\n\t});\n})\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/cart.js?");/***/}),/***/"./source/out/sinn/src/js/modules/catalog.js":(/*!***************************************************!*\
  !*** ./source/out/sinn/src/js/modules/catalog.js ***!
  \***************************************************/ /***/function sourceOutSinnSrcJsModulesCatalogJs(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _wishlist__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./wishlist */ \"./source/out/sinn/src/js/modules/wishlist.js\");\n\n\ndocument.addEventListener('DOMContentLoaded', () => {\n    const languageSelect = document.getElementById('catalogLanguage');\n    if (languageSelect) {\n        languageSelect.addEventListener('change', () => {\n\n            const selectedOption = languageSelect.options[languageSelect.selectedIndex];\n            if (selectedOption) {\n                articleObject.id = selectedOption.value;\n                articleObject.configHash = selectedOption.getAttribute('data-config-hash');\n                (0,_wishlist__WEBPACK_IMPORTED_MODULE_0__.updateWishListButtons)();\n            }\n        })\n    }\n});\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/catalog.js?");/***/}),/***/"./source/out/sinn/src/js/modules/checkSelectedPayment.js":(/*!****************************************************************!*\
  !*** ./source/out/sinn/src/js/modules/checkSelectedPayment.js ***!
  \****************************************************************/ /***/function sourceOutSinnSrcJsModulesCheckSelectedPaymentJs(){eval("function checkSelectedPayment() {\n    const paymentBodyList = document.querySelectorAll('.c-payment__body');\n    paymentBodyList.forEach(paymentBody => {\n        paymentBody.classList.contains('activePayment') ? paymentBody.style.display = '' : paymentBody.style.display = 'none';\n    });\n}\n\ndocument.addEventListener('DOMContentLoaded', () => {\n    checkSelectedPayment();\n});\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/checkSelectedPayment.js?");/***/}),/***/"./source/out/sinn/src/js/modules/checkoutAddressSelection.js":(/*!********************************************************************!*\
  !*** ./source/out/sinn/src/js/modules/checkoutAddressSelection.js ***!
  \********************************************************************/ /***/function sourceOutSinnSrcJsModulesCheckoutAddressSelectionJs(){eval("/* Handles replacing standard radio inputs in the #shippingAddress section with custom button elements.\n Native radio inputs remain hidden for form submission and OXID's JS logic, while buttons improve\n accessibility and keyboard navigation (tabbing/shortcuts). */\ndocument.addEventListener('DOMContentLoaded', function () {\n    var root = document.getElementById('shippingAddress');\n    if (!root) return;\n\n    root.addEventListener('click', function (e) {\n        var btn = e.target.closest('.js-radio-select-btn');\n        if (!btn || !root.contains(btn)) return;\n\n        var radio = root.querySelector(btn.getAttribute('data-radio'));\n        if (!radio) return;\n\n        root.querySelectorAll('input[type=\"radio\"][name=\"' + radio.name + '\"]').forEach(function (r) { r.checked = false; });\n        root.querySelectorAll('.js-radio-select-btn').forEach(function (b) { b.classList.remove('is--active'); });\n\n        radio.checked = true;\n        btn.classList.add('is--active');\n\n        // Trigger OXID\n        radio.dispatchEvent(new Event('change', { bubbles: true }));\n    });\n});\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/checkoutAddressSelection.js?");/***/}),/***/"./source/out/sinn/src/js/modules/configurator/configurator.js":(/*!*********************************************************************!*\
  !*** ./source/out/sinn/src/js/modules/configurator/configurator.js ***!
  \*********************************************************************/ /***/function sourceOutSinnSrcJsModulesConfiguratorConfiguratorJs(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   assignEventHandlerTrigger: () => (/* binding */ assignEventHandlerTrigger),\n/* harmony export */   getConfiguratorBody: () => (/* binding */ getConfiguratorBody),\n/* harmony export */   getConfiguratorComponent: () => (/* binding */ getConfiguratorComponent),\n/* harmony export */   getConfiguratorSlider: () => (/* binding */ getConfiguratorSlider),\n/* harmony export */   getCubicBezier: () => (/* binding */ getCubicBezier),\n/* harmony export */   getForwardButton: () => (/* binding */ getForwardButton),\n/* harmony export */   getOptionSubmitButton: () => (/* binding */ getOptionSubmitButton),\n/* harmony export */   getSubmitButton: () => (/* binding */ getSubmitButton),\n/* harmony export */   getWatchBasePrice: () => (/* binding */ getWatchBasePrice)\n/* harmony export */ });\n/* harmony import */ var _glidejs_glide__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @glidejs/glide */ \"./node_modules/@glidejs/glide/dist/glide.esm.js\");\n/* harmony import */ var _registerOffcanvas__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../registerOffcanvas */ \"./source/out/sinn/src/js/modules/registerOffcanvas.js\");\n/* harmony import */ var _configuratorDropdown__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./configuratorDropdown */ \"./source/out/sinn/src/js/modules/configurator/configuratorDropdown.js\");\n/* harmony import */ var _configuratorUtils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./configuratorUtils */ \"./source/out/sinn/src/js/modules/configurator/configuratorUtils.js\");\n/* harmony import */ var _lazyload__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../lazyload */ \"./source/out/sinn/src/js/modules/lazyload.js\");\n/* harmony import */ var _focusTrap__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../focusTrap */ \"./source/out/sinn/src/js/modules/focusTrap.js\");\n/**\n * This Software is the property of dotfly and is protected\n * by copyright law - it is NOT Freeware.\n *\n * Any unauthorized use of this software without a valid license key\n * is a violation of the license agreement and will be prosecuted by\n * civil and criminal law.\n *\n * @category   Watch configurator\n * @author     Lennart Syre <lennart.syre@dotfly.de>\n * @license    http://www.dotfly.de Commercial\n * @link       http://www.dotfly.de\n */\n\n\n\n\n\n\n\n\n\nconst selectors = {\n    triggers: '.c-detail__configure-button, .c-detail__sticky-configure--button, .c-basketquestion .is--configuratortrigger',\n    closers: '.c-configurator__closer, .c-configurator__background, .c-configurator__desciption-actions--forward, .c-configurator__options-actions--forward'\n}\n\n// Global constants\nconst cubicBezier = 'cubicBezier(.40,.05,.20,.90)';\n\nconst getConfiguratorComponent = () => document.querySelector('#productConfigurator');\nconst getForwardButton = () => document.querySelector('.c-configurator__description-actions--forward');\nconst getOptionSubmitButton = () => document.querySelector('#configuratorCart');\nconst getSubmitButton = () => document.querySelector('#configuratorBasket');\nconst getConfiguratorSlider = () => window.configuratorSlider;\nconst getCubicBezier = () => cubicBezier;\nconst getWatchBasePrice = () => document.querySelector('#productConfigurator').getAttribute('data-base-price');\nconst getConfiguratorBody = () => document.querySelector('.c-configurator__body');\nconst configuratorLoader = document.querySelector('#configuratorLoader');\nvar setViewportWidth;\nvar focusTrapCleanup = null; // Store the cleanup function\nvar firstStepFocusElements;\nvar secondStepFocusElements;\n\n\nconst initializeBacksideImages = function () {\n    let allStrapItems = document.querySelectorAll('.c-configurator__straps-item[data-closings=\"true\"]');\n\n    for (let j = 0; j < allStrapItems.length; j++) {\n        // Get data from input\n        let closureInput = allStrapItems[j].querySelector('.js--claspInfos').value;\n        closureInput = JSON.parse(closureInput);\n\n        // Get <picture>-Element\n        let pictureElement = allStrapItems[j].querySelector('picture.is--backwatch');\n\n        if (pictureElement && closureInput[0]?.image) {\n            // Select first pic from JSON data\n            let newImageUrl = closureInput[0].image;\n\n            // Set new picture\n            (0,_configuratorUtils__WEBPACK_IMPORTED_MODULE_3__.updatePictureElement)(pictureElement, newImageUrl);\n        }\n    }\n};\n\nconst initSlider = function () {\n    setViewportWidth = window.innerWidth;\n\n    // Wait for animation, then mount glide\n    function waitForConfiguratorVisibleAndUpdate() {\n        const el = document.querySelector('.c-configurator');\n        const forwardButton = getForwardButton();\n        const optionSubmitButton = getOptionSubmitButton();\n        const submitButton = getSubmitButton();\n\n        if (el && el.offsetWidth > 0 && el.offsetHeight > 0) {\n            // Overlay is visible -> mount slider\n            window.configuratorSlider.mount();\n            window.configuratorSlider.go('=0');\n            getConfiguratorBody().classList.add('js--active');\n\n            initializeBacksideImages();\n            _lazyload__WEBPACK_IMPORTED_MODULE_4__.lazyContent.update();\n\n            // Change forward button\n            if (forwardButton.classList.contains('is--not-configurable')) {\n                forwardButton.classList.remove('is--active');\n                optionSubmitButton.classList.add('is--active');\n                submitButton.classList.add('is--active');\n            } else {\n                forwardButton.classList.add('is--active');\n                optionSubmitButton.classList.remove('is--active');\n                submitButton.classList.remove('is--active');\n            }\n        } else {\n            setTimeout(waitForConfiguratorVisibleAndUpdate, 50);\n        }\n    }\n    waitForConfiguratorVisibleAndUpdate();\n}\n\n\n/**\n * Register click handlers for configurator triggers\n * When content was already loaded, init the slider\n */\n\nconst assignEventHandlerTrigger = function() {\n    document.querySelectorAll(selectors.triggers).forEach((trigger) => {\n        trigger.addEventListener('click', function (event) {\n\n            if (document.querySelector('#configurator').classList.contains('js--fetched')) {\n                initSlider();\n            } else {\n                configuratorLoader.classList.add('js--active');\n            }\n        });\n    });\n}\n\nassignEventHandlerTrigger();\n\n/**\n * Main event-driven initialization!\n * All DOM variables and slider init happen only after HTML is present\n */\ndocument.addEventListener('configuratorLoaded', async function () {\n    // Import articleConfigurator for unlock logic\n    const { default: articleConfigurator } = await Promise.resolve(/*! import() */).then(__webpack_require__.bind(__webpack_require__, /*! ../ArticleConfigurator.js */ \"./source/out/sinn/src/js/modules/ArticleConfigurator.js\"));\n\n    // General Variables\n    var configuratorForward = document.querySelectorAll('.c-configurator__description-actions--forward, .c-configurator__switch-item.is--options');\n    var optionsItemList = document.querySelectorAll('.c-configurator__options-items .c-configurator__options-item input[type=\"checkbox\"]');\n    var strapTab = document.querySelector('.c-configurator__switch-item.is--wristband');\n    var configuratorBody = getConfiguratorBody();\n    var watchBasePrice = getWatchBasePrice();\n\n    //Action Buttons\n    const submitButton = getSubmitButton();\n\n    // Initialize slider and assign to global scope for event handlers\n    window.configuratorSlider = new _glidejs_glide__WEBPACK_IMPORTED_MODULE_0__[\"default\"]('.js-configuratorslider', {\n        type: 'slider',\n        gap: 0,\n        perView: 5,\n        startAt: 0,\n        focusAt: 'center',\n        animationDuration: 425,\n        animationTimingFunc: 'cubic-bezier(.44,.05,.19,.94)',\n        breakpoints: {\n            1024: { perView: 4 },\n            768: { perView: 3 },\n            640: { perView: 2 }\n        }\n    });\n\n    // Hide loading spinner when content is loaded\n    configuratorLoader.classList.remove('js--active');\n\n    // Animate overlay\n    (0,_registerOffcanvas__WEBPACK_IMPORTED_MODULE_1__.registerOffcanvas)({\n        offCanvas: '.c-configurator',\n        triggers: selectors.triggers,\n        closeButtons: selectors.closers,\n    }).openOffcanvas(document.querySelector('.c-detail__configure-button'));\n\n    // Initialize slider and assign to global scope for event handlers\n    initSlider();\n\n    // Actions before sliding\n    window.configuratorSlider.on('run.before', function () {\n        var activeSlide = document.querySelector('.c-configurator__strap-list .glide__slide--active');\n        var dropdown = document.querySelector('.c-configurator__description-options .js--conf-dropdown');\n        var dropdownMenu = document.querySelector('.c-configurator__description-options .c-configurator__dropdown--menu');\n\n        // Check if dropdown is open\n        if (dropdown.classList.contains('js--active')) {\n            dropdown.classList.remove('js--active');\n        }\n\n        if (activeSlide.classList.contains('js--backwatch')) {\n            (0,_configuratorUtils__WEBPACK_IMPORTED_MODULE_3__.switchView)(activeSlide, 'frontview')\n        }\n    });\n\n    // Actions after sliding\n    window.configuratorSlider.on('run.after', function () {\n        var activeSlide = document.querySelector('.c-configurator__strap-list .glide__slide--active');\n        let activeHiddenInput = activeSlide.querySelector('.js--claspInfos');\n        var descText = document.querySelector('.c-configurator__strap');\n\n        // Get articleConfigurator instance\n        const configurator = articleConfigurator.getInstance();\n\n        // Check if configurator is locked and we reached the target slide\n        if (configurator.isLocked) {\n            const targetStrapId = configurator.get('selectedStrap')?.id;\n            const currentStrapId = activeSlide.querySelector('input[type=\"radio\"]').value;\n\n            // If we reached the target slide from wishlist, unlock after short delay\n            if (targetStrapId === currentStrapId) {\n                setTimeout(() => {\n                    configurator.unlock();\n                }, 300);\n            }\n        }\n\n        // Get data desc\n        if (activeSlide.dataset.desc) {\n            var desc = activeSlide.dataset.desc;\n\n            // Set Desc Text\n            descText.innerHTML = desc;\n        }\n\n        // Build the dropdown with the given data\n        (0,_configuratorDropdown__WEBPACK_IMPORTED_MODULE_2__.buildClaspsDropdown)(activeSlide, activeHiddenInput, watchBasePrice);\n\n        // Check input of active item\n        activeSlide.querySelector('input[type=\"radio\"]').checked = true;\n\n        // Show updated price - check if we have any options selected\n        if (activeSlide.dataset.price) {\n            const checkedOptions = document.querySelectorAll('.configurator-options:checked');\n            if (checkedOptions.length > 0) {\n                // If options are selected, fetch variant data which will update price with all components\n                (0,_configuratorUtils__WEBPACK_IMPORTED_MODULE_3__.fetchVariantData)(watchBasePrice);\n            } else {\n                // No options selected, just update with base + strap + clasp\n                (0,_configuratorUtils__WEBPACK_IMPORTED_MODULE_3__.updatePrice)(watchBasePrice);\n            }\n        }\n\n        // Update articleObject with new strap/closure data\n        (0,_configuratorUtils__WEBPACK_IMPORTED_MODULE_3__.updateArticleObjectAfterConfiguration)();\n\n        // Find out which strap type is active and assign the matching active state in the tab navigation\n        let activeCategory = activeSlide.getAttribute('data-name');\n\n        //reset active states\n        allCategoryItems.forEach(category => {\n            category.classList.remove('js--active');\n        });\n\n        allCategoryItems.forEach(category => {\n\n            if (category.classList.contains('js--' + activeCategory)) {\n                category.classList.add('js--active');\n                (0,_configuratorUtils__WEBPACK_IMPORTED_MODULE_3__.scrollToTab)(category)\n            }\n        });\n    });\n\n\n    // Strap Tab Navigation\n    // Trigger tab navigation when one of the categories is clicked\n    var allCategoryItems = document.querySelectorAll('.c-configurator__category-item');\n    allCategoryItems.forEach(category => {\n        category.addEventListener('click', function(e) {\n            // User interaction - unlock configurator if locked\n            if (e.isTrusted) {\n                const configurator = articleConfigurator.getInstance();\n                if (configurator.isLocked) {\n                    configurator.unlock();\n                }\n            }\n\n            const allSliderItems = document.querySelectorAll('.c-configurator__straps-item');\n            let categoryName = category.getAttribute('data-name');\n            let elFirstSlide = document.querySelectorAll('.c-configurator__straps-item' + '.is--' + categoryName )[0];\n            let strapIndex = [].indexOf.call(allSliderItems, elFirstSlide);\n            // Jump to first matching strap\n            window.configuratorSlider.go('=' + strapIndex);\n            // Update articleObject after category navigation\n            (0,_configuratorUtils__WEBPACK_IMPORTED_MODULE_3__.updateArticleObjectAfterConfiguration)();\n        })\n    });\n\n\n    //switch between front and backview of product\n    var viewTriggers = document.querySelectorAll('.c-configurator__description-options--group > button');\n    viewTriggers.forEach((item) => {\n        item.addEventListener('click', function (trigger) {\n            var activeSlide = document.querySelector('.c-configurator__strap-list .glide__slide--active');\n            var backviewBtn = document.querySelector('.c-configurator__description-options--backview');\n            var frontviewBtn = document.querySelector('.c-configurator__description-options--frontview');\n\n            if (trigger.srcElement.classList.contains('c-configurator__description-options--backview')) {\n                if (activeSlide.querySelector('img.is--backwatch')) {\n                    (0,_configuratorUtils__WEBPACK_IMPORTED_MODULE_3__.switchView)(activeSlide, 'backview');\n                    // Update aria-pressed states\n                    backviewBtn.setAttribute('aria-pressed', 'true');\n                    frontviewBtn.setAttribute('aria-pressed', 'false');\n                }\n            } else if (trigger.srcElement.classList.contains('c-configurator__description-options--frontview')) {\n                if (activeSlide.querySelector('img.is--backwatch')) {\n                    (0,_configuratorUtils__WEBPACK_IMPORTED_MODULE_3__.switchView)(activeSlide, 'frontview');\n                    // Update aria-pressed states\n                    backviewBtn.setAttribute('aria-pressed', 'false');\n                    frontviewBtn.setAttribute('aria-pressed', 'true');\n                }\n            }\n        });\n    });\n\n\n    //Proceed to second Step\n    configuratorForward.forEach((item) => {\n        item.addEventListener('click', function () {\n\n            if (!item.classList.contains('is--not-configurable')) {\n\n                (0,_configuratorUtils__WEBPACK_IMPORTED_MODULE_3__.updateVariantPriceDifference)()\n                ;(0,_configuratorUtils__WEBPACK_IMPORTED_MODULE_3__.updateArticleObjectAfterConfiguration)()\n\n                setViewportWidth = window.innerWidth;\n\n                if (getConfiguratorComponent().classList.contains('js--firststep')) {\n                    var allItemsButActive = document.querySelectorAll('.c-configurator__straps-item:not(.glide__slide--active)');\n                    var dropdown = document.querySelector('.c-configurator__description-options .js--conf-dropdown');\n                    var dropdownMenu = document.querySelector('.c-configurator__description-options .c-configurator__dropdown--menu');\n                    var activeSlide = document.querySelector('.c-configurator__strap-list .glide__slide--active');\n\n\n                    //handle focusable elements - query fresh elements for first step\n                    firstStepFocusElements = getConfiguratorComponent().querySelectorAll('[tabindex=\"0\"], input:not([type=\"hidden\"]), select, textarea');\n\n                    // Elements that should be focusable in second step\n                    secondStepFocusElements = getConfiguratorComponent().querySelectorAll('[tabindex=\"-1\"], .c-configurator__switch-item, .c-configurator__close, #configuratorBasket, .js--conf-dropdown-trigger, .c-configurator__description-options--backview, .c-configurator__description-options--frontview');\n\n                    //accessibility handling\n                    document.querySelector('.c-configurator__options').setAttribute('aria-hidden', 'false');\n\n                    firstStepFocusElements.forEach((element) => {\n                        element.setAttribute('tabindex', '-1');\n                        element.setAttribute('aria-hidden', 'true');\n                    });\n\n                    secondStepFocusElements.forEach((element) => {\n                        if (!element.id.includes('configuratorCart')) {\n                            element.setAttribute('tabindex', '0');\n                            element.setAttribute('aria-hidden', 'false');\n                        }\n                    });\n\n                    //reinitiate focusTrap\n                    setTimeout(() => {\n                        // Clean up previous focus trap\n                        focusTrapCleanup && focusTrapCleanup();\n                        // Create new focus trap and store cleanup function\n                        focusTrapCleanup = (0,_focusTrap__WEBPACK_IMPORTED_MODULE_5__.createFocusTrap)(getConfiguratorComponent().querySelector('.c-configurator__wrap'));\n                    }, 650);\n\n                    // Disable Slider Functionality\n                    window.configuratorSlider.disable();\n\n                    // Set Current Slide Active Radio\n                    activeSlide.querySelector('input[type=\"radio\"]').checked = true;\n\n                    // Add Second Step Class\n                    getConfiguratorComponent().classList.remove('js--firststep');\n                    getConfiguratorComponent().classList.add('js--secondstep');\n\n                    getOptionSubmitButton().classList.add('is--active');\n\n                    // Check If Dropdown Open\n                    if (dropdown.classList.contains('js--active')) {\n                        dropdown.classList.remove('js--active');\n                    }\n\n                    // Handle completion after transition\n                    setTimeout(() => {\n                        allItemsButActive.forEach((item) => {\n                            item.style.visibility = 'hidden';\n                        });\n                        const sliderControls = document.querySelector('.c-configurator__straps-controls');\n                        sliderControls.style.display = 'none';\n\n                        getForwardButton().classList.remove('is--active');\n                        submitButton.classList.add('is--active');\n                    }, 650);\n                }\n            }\n\n        });\n    });\n\n\n    // Return to first step\n    strapTab.addEventListener('click', function () {\n        setViewportWidth = window.innerWidth;\n\n        if (getConfiguratorComponent().classList.contains('js--secondstep')) {\n            var allItemsButActive = document.querySelectorAll('.c-configurator__straps-item:not(.glide__slide--active)');\n            var dropdown = document.querySelector('.c-configurator__description-options .js--conf-dropdown');\n            var dropdownMenu = document.querySelector('.c-configurator__description-options .c-configurator__dropdown--menu');\n\n            window.configuratorSlider.enable();\n\n            // Handle focusable elements - re-query elements to ensure we have the current DOM state\n            // Elements that should be focusable in first step (same as before)\n            firstStepFocusElements = getConfiguratorComponent().querySelectorAll('input:not([type=\"hidden\"]), select, textarea, .c-configurator__category-item, .glide__arrow, .js--conf-dropdown-trigger, .c-configurator__description-options--backview, .c-configurator__description-options--frontview, .c-configurator__description-actions--forward');\n\n            // Elements that should NOT be focusable in first step (second step elements)\n            secondStepFocusElements = getConfiguratorComponent().querySelectorAll('#configuratorBasket, .c-configurator__options-item input[type=\"checkbox\"]');\n\n            // Accessibility handling\n            document.querySelector('.c-configurator__options').setAttribute('aria-hidden', 'true');\n\n            // Set first step elements to be focusable\n            firstStepFocusElements.forEach((element) => {\n                element.setAttribute('tabindex', '0');\n                element.setAttribute('aria-hidden', 'false');\n            });\n\n            // Set second step elements to NOT be focusable\n            secondStepFocusElements.forEach((element) => {\n                if (!element.id.includes('configuratorCart')) {\n                    element.setAttribute('tabindex', '-1');\n                    element.setAttribute('aria-hidden', 'true');\n                }\n            });\n\n            // Reinitiate focusTrap\n            setTimeout(() => {\n                // Clean up previous focus trap\n                focusTrapCleanup && focusTrapCleanup();\n                // Create new focus trap and store cleanup function\n                focusTrapCleanup = (0,_focusTrap__WEBPACK_IMPORTED_MODULE_5__.createFocusTrap)(getConfiguratorComponent().querySelector('.c-configurator__wrap'));\n            }, 1650);\n\n\n            // Check if options checkboxes exist\n            if (optionsItemList) {\n                optionsItemList.forEach((item) => {\n                    item.checked = false\n                });\n\n                watchBasePrice = getWatchBasePrice();\n                (0,_configuratorUtils__WEBPACK_IMPORTED_MODULE_3__.updatePrice)(watchBasePrice);\n            }\n\n            // Check if dropdown open\n            if (dropdown.classList.contains('js--active')) {\n                dropdown.classList.remove('js--active');\n            }\n\n            // Show all items but active - CSS transitions handle this automatically\n            // First, prepare elements for showing\n            allItemsButActive.forEach((item) => {\n                item.style.visibility = null;\n            });\n\n            const sliderControls = document.querySelector('.c-configurator__straps-controls');\n            const bottomBar = document.querySelector('.c-configurator__bottombar');\n\n            sliderControls.style.display = null;\n            bottomBar.style.display = null;\n\n            // Change forward button\n            getForwardButton().classList.add('is--active');\n            getOptionSubmitButton().classList.remove('is--active');\n            submitButton.classList.remove('is--active');\n\n            // Add second step class - this triggers CSS transitions\n            getConfiguratorComponent().classList.add('js--firststep');\n            getConfiguratorComponent().classList.remove('js--secondstep');\n        }\n    });\n\n\n    // Handle added options\n    optionsItemList.forEach((optionCheckbox, i) => {\n        optionCheckbox.addEventListener('change', async (e) => {\n            await (0,_configuratorUtils__WEBPACK_IMPORTED_MODULE_3__.fetchVariantData)(watchBasePrice);\n        });\n    });\n\n    // Buy the watch\n    const submitButtons = document.querySelectorAll('#configuratorCart, #configuratorBasket', '#configuratorForward');\n    submitButtons && submitButtons.forEach(submit => {\n        submit.addEventListener('click', _configuratorUtils__WEBPACK_IMPORTED_MODULE_3__.handleProductSubmit);\n    });\n\n\n    // Add the reset functionality to ALL close buttons defined in selectors.closers\n    document.querySelectorAll(selectors.closers).forEach(closeButton => {\n        // Close configurator - keep existing functionality\n        closeButton.addEventListener('click', async function () {\n            var dropdown = document.querySelector('.c-configurator__description-options .js--conf-dropdown');\n            setViewportWidth = window.innerWidth;\n\n            // Clean up focus trap when closing configurator\n            focusTrapCleanup && focusTrapCleanup();\n            focusTrapCleanup = null;\n\n            getConfiguratorComponent().classList.remove('js--active');\n\n            // Check if options checkboxes exist\n            if (optionsItemList) {\n                optionsItemList.forEach((item) => {\n                    item.checked = false\n                });\n            }\n\n            // Check if dropdown is open\n            if (dropdown.classList.contains('js--active')) {\n                dropdown.classList.remove('js--active');\n            }\n\n            // Reset slider position and clean up\n            if (getConfiguratorComponent().classList.contains('js--firststep')) {\n                setTimeout(function () {\n                    window.configuratorSlider.go('=0');\n                    configuratorBody.classList.remove('js--active');\n                }, 1000)\n            }\n\n            if (getConfiguratorComponent().classList.contains('js--secondstep')) {\n                var allItemsButActive = document.querySelectorAll('.c-configurator__straps-item:not(.glide__slide--active)');\n                setTimeout(function () {\n                    (0,_configuratorUtils__WEBPACK_IMPORTED_MODULE_3__.resetSlider)(allItemsButActive, window.configuratorSlider, getConfiguratorComponent());\n                    configuratorBody.classList.remove('js--active');\n                }, 1000)\n            }\n\n            // Reset articleObject to standard configuration when configurator is closed\n            await (0,_configuratorUtils__WEBPACK_IMPORTED_MODULE_3__.resetArticleObjectToStandard)();\n        });\n    });\n});\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/configurator/configurator.js?");/***/}),/***/"./source/out/sinn/src/js/modules/configurator/configuratorDropdown.js":(/*!*****************************************************************************!*\
  !*** ./source/out/sinn/src/js/modules/configurator/configuratorDropdown.js ***!
  \*****************************************************************************/ /***/function sourceOutSinnSrcJsModulesConfiguratorConfiguratorDropdownJs(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   buildClaspsDropdown: () => (/* binding */ buildClaspsDropdown),\n/* harmony export */   reinitializeDropdown: () => (/* binding */ reinitializeDropdown)\n/* harmony export */ });\n/* harmony import */ var _configuratorUtils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./configuratorUtils */ \"./source/out/sinn/src/js/modules/configurator/configuratorUtils.js\");\n/* harmony import */ var _screenReaderUtils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../screenReaderUtils */ \"./source/out/sinn/src/js/modules/screenReaderUtils.js\");\n/**\n * This Software is the property of dotfly and is protected\n * by copyright law - it is NOT Freeware.\n *\n * Any unauthorized use of this software without a valid license key\n * is a violation of the license agreement and will be prosecuted by\n * civil and criminal law.\n *\n * @category   ...\n * @author     dotfly GmbH <info@dotfly.de>\n * @license    http://www.dotfly.de Commercial\n * @link       http://www.dotfly.de\n */\n\n\n\n\nconst buildClaspsDropdown = async (activeSlide, activeHiddenInput, watchBasePrice) => {\n\tconst dropdown = document.querySelector('.c-configurator__description-options .js--conf-dropdown');\n\tconst dropdownMenu = dropdown.querySelector('.c-configurator__dropdown--menu');\n\tconst dropdownActiveValue = dropdown.querySelector('.js--value');\n\tconst dropdownTrigger = dropdown.querySelector('.js--conf-dropdown-trigger');\n\tconst parseJSON = (activeHiddenInput && activeHiddenInput.value) ? JSON.parse(activeHiddenInput.value) : null;\n\tconst mandatoryClosure = document.querySelector('.js--single-option-text');\n\n\tlet showDropDown = Boolean(parseJSON && parseJSON.length > 1);\n\n\tif (parseJSON && parseJSON.length > 1) {\n\t\tconst itemsHTML = Object.keys(parseJSON)\n\t\t\t.map((key, index) => {\n\t\t\t\tconst { title, id, price, netprice, artnum, configHash, proalphatitle } = parseJSON[key];\n\t\t\t\tconst checked = index === 0 ? 'checked=\"true\"' : '';\n\t\t\t\tconst activeClass = index === 0 ? 'js--active' : '';\n\t\t\t\tconst ariaChecked = index === 0 ? 'true' : 'false';\n\t\t\t\treturn `<li class=\"c-configurator__dropdown--item ${activeClass}\" role=\"none\">\n                  <label role=\"menuitemradio\" aria-checked=\"${ariaChecked}\" tabindex=\"-1\">\n                    <input name=\"closing\" ${checked} type=\"radio\" data-artnum=\"${artnum}\" data-price=\"${price}\" data-netprice=\"${netprice}\" data-config-hash=\"${configHash || ''}\" data-proalpha-title=\"${proalphatitle || ''}\" value=\"${id}\" tabindex=\"-1\">\n                    ${title}\n                  </label>\n                </li>`;\n\t\t\t})\n\t\t\t.join('');\n\n\t\tmandatoryClosure.style.display = 'none';\n\t\tdropdownActiveValue.textContent = parseJSON[0].title;\n\t\tdropdownMenu.innerHTML = itemsHTML;\n\n\t\t// Update ARIA attributes for accessibility\n\t\tdropdownTrigger.setAttribute('aria-expanded', 'false');\n\t\tdropdownMenu.setAttribute('aria-hidden', 'true');\n\t} else {\n\t\tdropdownMenu.innerHTML = '';\n\n\t\tif (parseJSON) {\n\t\t\tconst singleClosureInput = Object.keys(parseJSON)\n\t\t\t\t.map((key, index) => {\n                    // @TODO: refactor this and put it in a function (same code as above)\n\t\t\t\t\tconst { title, id, price, artnum, configHash, proalphatitle } = parseJSON[key];\n\t\t\t\t\tconst checked = index === 0 ? 'checked=\"true\"' : '';\n\t\t\t\t\treturn `<label><input name=\"closing\" ${checked} type=\"radio\" data-artnum=\"${artnum}\" data-price=\"${price}\" data-config-hash=\"${configHash || ''}\" data-proalpha-title=\"${proalphatitle || ''}\" value=\"${id}\">${title}</label>`;\n\t\t\t\t})\n\t\t\t\t.join('');\n\n\t\t\tmandatoryClosure.innerHTML = singleClosureInput;\n\t\t\tmandatoryClosure.style.display = 'inline-block';\n\t\t} else {\n\t\t\t//console.warn('Keine passende Schließe vorhanden.');\n\t\t\tif (mandatoryClosure) {\n\t\t\t\tmandatoryClosure.innerHTML = '';\n\t\t\t\tmandatoryClosure.style.display = 'none';\n\t\t\t}\n\t\t}\n\t}\n\n\tif (showDropDown) {\n\t\tconst element = document.querySelector('.c-configurator__description-options--group');\n\t\tif (element) {\n\t\t\tconst elementWidth = element.getBoundingClientRect().width;\n\n\t\t\tdropdown.classList.add('is--visible');\n\t\t\tdropdown.classList.remove('is--hidden');\n\t\t\tdropdown.style.width = `calc(100% - ${elementWidth}px)`;\n\t\t}\n\t} else {\n\t\tdropdown.classList.add('is--hidden');\n\t\tdropdown.classList.remove('is--visible');\n\t}\n\n\t// Update price and show matching backside image after selecting clasp\n\tdropdown.addEventListener('change', (e) => matchWristbandImage(e, watchBasePrice));\n\n\t// Reinitialize accessible dropdown if it exists\n\tconst existingDropdownInstance = dropdown._accessibleDropdownState;\n\tif (existingDropdownInstance) {\n\t\tupdateMenuItems(dropdown);\n\t}\n}\n\n// Function to reinitialize dropdown after content changes\nconst reinitializeDropdown = () => {\n\tconst dropdown = document.querySelector('.c-configurator__description-options .js--conf-dropdown');\n\tif (dropdown && dropdown._accessibleDropdownState) {\n\t\tupdateMenuItems(dropdown);\n\t}\n};\n\n// Show matching back view when clasp dropdown is changed\nconst matchWristbandImage = (e, watchBasePrice) => {\n\t// Get Active Slider element\n\tlet activeWatchSliderItem = document.querySelector('.c-configurator__straps-item.glide__slide--active');\n\tif (!activeWatchSliderItem) return;\n\n\t// Get ID from Selected Clasp\n\tlet clickedClaspId = e.target.value;\n\n\t// Get JSON Data according to selected band\n\tlet activeImages = JSON.parse(activeWatchSliderItem.querySelector('.js--claspInfos').value);\n\tlet claspMatch = activeImages.find(o => o.id === clickedClaspId);\n\n\tif (!claspMatch) return;\n\n\t// Get <picture>-Element for Backside\n\tlet backPictureElement = activeWatchSliderItem.querySelector('picture.is--backwatch');\n\tif (!backPictureElement) return;\n\n\t// Set new Picture\n\t(0,_configuratorUtils__WEBPACK_IMPORTED_MODULE_0__.updatePictureElement)(backPictureElement, claspMatch.image);\n\n\t// update price - check if we have any options selected\n\tconst checkedOptions = document.querySelectorAll('.configurator-options:checked');\n\tif (checkedOptions.length > 0) {\n\t\t// If options are selected, fetch variant data which will update price with all components\n\t\t(0,_configuratorUtils__WEBPACK_IMPORTED_MODULE_0__.fetchVariantData)(watchBasePrice);\n\t} else {\n\t\t// No options selected, just update with base + strap + clasp\n\t\t(0,_configuratorUtils__WEBPACK_IMPORTED_MODULE_0__.updatePrice)(watchBasePrice);\n\t}\n\t// Update articleObject when closure changes\n\t(0,_configuratorUtils__WEBPACK_IMPORTED_MODULE_0__.updateArticleObjectAfterConfiguration)();\n};\n\n// Dropdown state management\nconst createDropdownState = (dropdownElement) => {\n\treturn {\n\t\tdropdown: dropdownElement,\n\t\ttrigger: dropdownElement.querySelector('.js--conf-dropdown-trigger'),\n\t\tmenu: dropdownElement.querySelector('.c-configurator__dropdown--menu'),\n\t\tvalueDisplay: dropdownElement.querySelector('.js--value'),\n\t\tmenuItems: [],\n\t\tcurrentIndex: -1,\n\t\tisOpen: false,\n\t\tcubicBezier: 'cubicBezier(.40, .05, .20, .90)'\n\t};\n};\n\n// Update menu items array and event listeners\nconst updateMenuItems = (dropdownElement) => {\n\tconst state = dropdownElement._accessibleDropdownState;\n\tif (!state) return;\n\n\tstate.menuItems = Array.from(state.menu.querySelectorAll('.c-configurator__dropdown--item label[role=\"menuitemradio\"]'));\n\tstate.menuItems.forEach((item, index) => {\n\t\titem.setAttribute('tabindex', '-1');\n\t\t// Remove existing listeners to prevent duplicates\n\t\titem.removeEventListener('click', item._clickHandler);\n\t\t// Create new handler and store reference\n\t\titem._clickHandler = (e) => selectItem(state, index, e);\n\t\titem.addEventListener('click', item._clickHandler);\n\t});\n};\n\n// Event handlers\nconst handleTriggerClick = (state, e) => {\n\te.preventDefault();\n\te.stopPropagation();\n\ttoggleDropdown(state);\n};\n\nconst handleTriggerKeydown = (state, e) => {\n\tswitch (e.key) {\n\t\tcase 'Enter':\n\t\tcase ' ':\n\t\tcase 'ArrowDown':\n\t\tcase 'ArrowUp':\n\t\t\te.preventDefault();\n\t\t\topenDropdown(state);\n\t\t\tfocusFirstItem(state);\n\t\t\tbreak;\n\t\tcase 'Escape':\n\t\t\tcloseDropdown(state);\n\t\t\tbreak;\n\t}\n};\n\nconst handleMenuKeydown = (state, e) => {\n\tswitch (e.key) {\n\t\tcase 'ArrowDown':\n\t\t\te.preventDefault();\n\t\t\tfocusNextItem(state);\n\t\t\tbreak;\n\t\tcase 'ArrowUp':\n\t\t\te.preventDefault();\n\t\t\tfocusPreviousItem(state);\n\t\t\tbreak;\n\t\tcase 'Home':\n\t\t\te.preventDefault();\n\t\t\tfocusFirstItem(state);\n\t\t\tbreak;\n\t\tcase 'End':\n\t\t\te.preventDefault();\n\t\t\tfocusLastItem(state);\n\t\t\tbreak;\n\t\tcase 'Enter':\n\t\tcase ' ':\n\t\t\te.preventDefault();\n\t\t\tif (state.currentIndex >= 0) {\n\t\t\t\tselectItem(state, state.currentIndex);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 'Escape':\n\t\t\te.preventDefault();\n\t\t\tcloseDropdown(state);\n\t\t\tstate.trigger.focus();\n\t\t\tbreak;\n\t\tcase 'Tab':\n\t\t\t// Allow tab to close dropdown and move to next element\n\t\t\tcloseDropdown(state);\n\t\t\tbreak;\n\t}\n};\n\nconst handleMenuClick = (state, e) => {\n\tconst clickedItem = e.target.closest('.c-configurator__dropdown--item label[role=\"menuitemradio\"]');\n\tif (clickedItem) {\n\t\tconst index = state.menuItems.indexOf(clickedItem);\n\t\tif (index >= 0) {\n\t\t\tselectItem(state, index, e);\n\t\t}\n\t}\n};\n\nconst handleOutsideClick = (state, e) => {\n\tif (!state.dropdown.contains(e.target) && state.isOpen) {\n\t\tcloseDropdown(state);\n\t}\n};\n\n// Dropdown control functions\nconst toggleDropdown = (state) => {\n\tif (state.isOpen) {\n\t\tcloseDropdown(state);\n\t} else {\n\t\topenDropdown(state);\n\t}\n};\n\nconst openDropdown = (state) => {\n\tif (state.isOpen) return;\n\n\tstate.isOpen = true;\n\tstate.dropdown.classList.add('js--active');\n\tstate.trigger.setAttribute('aria-expanded', 'true');\n\tstate.menu.setAttribute('aria-hidden', 'false');\n\n\t// Find currently selected item\n\tconst activeItem = state.menu.querySelector('.c-configurator__dropdown--item.js--active label[role=\"menuitemradio\"]');\n\tif (activeItem) {\n\t\tstate.currentIndex = state.menuItems.indexOf(activeItem);\n\t}\n\n\t// Announce to screen readers after transition completes\n\tsetTimeout(() => {\n        const message = oWave.i18n.DOT_DROPDOWN_OPENED.replace('%s', state.menuItems.length);\n        (0,_screenReaderUtils__WEBPACK_IMPORTED_MODULE_1__.announceToScreenReader)(message);\n\t}, 300);\n};\n\nconst closeDropdown = (state) => {\n\tif (!state.isOpen) return;\n\n\tstate.isOpen = false;\n\tstate.currentIndex = -1;\n\tstate.trigger.setAttribute('aria-expanded', 'false');\n\tstate.menu.setAttribute('aria-hidden', 'true');\n\n\t// Remove focus from menu items\n\tstate.menuItems.forEach(item => item.setAttribute('tabindex', '-1'));\n\n\t// Remove active class to trigger CSS transition\n\tstate.dropdown.classList.remove('js--active');\n};\n\n// Focus management functions\nconst focusFirstItem = (state) => {\n\tstate.currentIndex = 0;\n\tfocusItem(state);\n};\n\nconst focusLastItem = (state) => {\n\tstate.currentIndex = state.menuItems.length - 1;\n\tfocusItem(state);\n};\n\nconst focusNextItem = (state) => {\n\tstate.currentIndex = (state.currentIndex + 1) % state.menuItems.length;\n\tfocusItem(state);\n};\n\nconst focusPreviousItem = (state) => {\n\tstate.currentIndex = state.currentIndex <= 0 ? state.menuItems.length - 1 : state.currentIndex - 1;\n\tfocusItem(state);\n};\n\nconst focusItem = (state) => {\n\tif (state.currentIndex >= 0 && state.currentIndex < state.menuItems.length) {\n\t\t// Remove tabindex from all items\n\t\tstate.menuItems.forEach(item => item.setAttribute('tabindex', '-1'));\n\n\t\t// Set tabindex and focus on current item\n\t\tconst currentItem = state.menuItems[state.currentIndex];\n\t\tcurrentItem.setAttribute('tabindex', '0');\n\t\tcurrentItem.focus();\n\t}\n};\n\n// Item selection function\nconst selectItem = (state, index, event = null) => {\n\tif (index < 0 || index >= state.menuItems.length) return;\n\n\tconst selectedItem = state.menuItems[index];\n\tconst listItem = selectedItem.closest('.c-configurator__dropdown--item');\n\tconst radioInput = selectedItem.querySelector('input[type=\"radio\"]');\n\tconst text = selectedItem.textContent.trim();\n\n\t// Update visual states\n\tstate.menu.querySelectorAll('.c-configurator__dropdown--item').forEach(item => {\n\t\titem.classList.remove('js--active');\n\t\tconst label = item.querySelector('label[role=\"menuitemradio\"]');\n\t\tif (label) label.setAttribute('aria-checked', 'false');\n\t});\n\n\tlistItem.classList.add('js--active');\n\tselectedItem.setAttribute('aria-checked', 'true');\n\n\t// Update radio input\n\tif (radioInput) {\n\t\tradioInput.checked = true;\n\t\t// Trigger change event for existing functionality\n\t\tradioInput.dispatchEvent(new Event('change', { bubbles: true }));\n\t}\n\n\t// Update display value\n\tstate.valueDisplay.textContent = text;\n\n\t// Handle language dataset if present\n\tif (listItem.dataset.language) {\n\t\tstate.valueDisplay.dataset.language = listItem.dataset.language;\n\t}\n\n\t// Announce selection to screen readers\n    const message = oWave.i18n.DOT_OPTION_SELECTED.replace('%s', text);\n    (0,_screenReaderUtils__WEBPACK_IMPORTED_MODULE_1__.announceToScreenReader)(message);\n\n\t// Close dropdown\n\tcloseDropdown(state);\n\n\t// Return focus to trigger\n\tsetTimeout(() => {\n\t\tstate.trigger.focus();\n\t}, 100);\n};\n\n// Initialize accessible dropdown functionality\nconst initializeAccessibleDropdown = (dropdownElement) => {\n\t// Create state object\n\tconst state = createDropdownState(dropdownElement);\n\n\t// Store state reference on element\n\tdropdownElement._accessibleDropdownState = state;\n\n\t// Set initial ARIA states\n\tstate.trigger.setAttribute('aria-expanded', 'false');\n\tstate.menu.setAttribute('aria-hidden', 'true');\n\n\t// Bind event listeners with state\n\tstate.trigger.addEventListener('click', (e) => handleTriggerClick(state, e));\n\tstate.trigger.addEventListener('keydown', (e) => handleTriggerKeydown(state, e));\n\tstate.menu.addEventListener('keydown', (e) => handleMenuKeydown(state, e));\n\tstate.menu.addEventListener('click', (e) => handleMenuClick(state, e));\n\n\t// Close dropdown when clicking outside\n\tdocument.addEventListener('click', (e) => handleOutsideClick(state, e));\n\n\t// Initialize menu items\n\tupdateMenuItems(dropdownElement);\n};\n\n// Main initialization\ndocument.addEventListener('configuratorLoaded', () => {\n\tconst dropdowns = document.querySelectorAll('.js--conf-dropdown');\n\n\tif (dropdowns.length > 0) {\n\t\tdropdowns.forEach((dropdownElement) => {\n\t\t\t// Initialize language dataset if needed\n\t\t\tconst valueElement = dropdownElement.querySelector('.js--value');\n\t\t\tconst activeItem = dropdownElement.querySelector('.c-configurator__dropdown--item.js--active');\n\n\t\t\tif (valueElement && valueElement.dataset.language && activeItem &&\n\t\t\t\tvalueElement.dataset.language !== activeItem.dataset.language) {\n\t\t\t\tconst activeLanguage = activeItem.dataset.language;\n\t\t\t\tconst activeLanguageText = activeItem.textContent.trim();\n\n\t\t\t\tvalueElement.dataset.language = activeLanguage;\n\t\t\t\tvalueElement.textContent = activeLanguageText;\n\t\t\t}\n\n\t\t\t// Initialize accessible dropdown functionality\n\t\t\tinitializeAccessibleDropdown(dropdownElement);\n\t\t});\n\t}\n});\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/configurator/configuratorDropdown.js?");/***/}),/***/"./source/out/sinn/src/js/modules/configurator/configuratorUtils.js":(/*!**************************************************************************!*\
  !*** ./source/out/sinn/src/js/modules/configurator/configuratorUtils.js ***!
  \**************************************************************************/ /***/function sourceOutSinnSrcJsModulesConfiguratorConfiguratorUtilsJs(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   addConfiguratedArticleToBasket: () => (/* binding */ addConfiguratedArticleToBasket),\n/* harmony export */   fetchVariantData: () => (/* binding */ fetchVariantData),\n/* harmony export */   handleProductSubmit: () => (/* binding */ handleProductSubmit),\n/* harmony export */   resetArticleObjectToStandard: () => (/* binding */ resetArticleObjectToStandard),\n/* harmony export */   resetSlider: () => (/* binding */ resetSlider),\n/* harmony export */   scrollToTab: () => (/* binding */ scrollToTab),\n/* harmony export */   switchView: () => (/* binding */ switchView),\n/* harmony export */   updateArticleObjectAfterConfiguration: () => (/* binding */ updateArticleObjectAfterConfiguration),\n/* harmony export */   updatePictureElement: () => (/* binding */ updatePictureElement),\n/* harmony export */   updatePrice: () => (/* binding */ updatePrice),\n/* harmony export */   updateVariantPriceDifference: () => (/* binding */ updateVariantPriceDifference)\n/* harmony export */ });\n/* harmony import */ var animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! animejs/lib/anime.es.js */ \"./node_modules/animejs/lib/anime.es.js\");\n/* harmony import */ var _minicartflapper__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../minicartflapper */ \"./source/out/sinn/src/js/modules/minicartflapper.js\");\n/* harmony import */ var _registerOffcanvas__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../registerOffcanvas */ \"./source/out/sinn/src/js/modules/registerOffcanvas.js\");\n/* harmony import */ var _screenReaderUtils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../screenReaderUtils */ \"./source/out/sinn/src/js/modules/screenReaderUtils.js\");\n/* harmony import */ var _wishlist_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../wishlist.js */ \"./source/out/sinn/src/js/modules/wishlist.js\");\n/* harmony import */ var _ArticleConfigurator_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../ArticleConfigurator.js */ \"./source/out/sinn/src/js/modules/ArticleConfigurator.js\");\n/* harmony import */ var _configurator__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./configurator */ \"./source/out/sinn/src/js/modules/configurator/configurator.js\");\n/**\n * This Software is the property of dotfly and is protected\n * by copyright law - it is NOT Freeware.\n *\n * Any unauthorized use of this software without a valid license key\n * is a violation of the license agreement and will be prosecuted by\n * civil and criminal law.\n *\n * @category   Configurator Frontend utilities\n * @author     Lennart Syre <lennart.syre@dotfly.de>\n * @license    http://www.dotfly.de Commercial\n * @link       http://www.dotfly.de\n */\n\n\n\n\n\n\n\n\n\nconst scrollToTab = function (tab) {\n    tab.scrollIntoView({\n        behavior: 'smooth',\n        inline: 'center',\n        block: 'nearest'\n    });\n}\n\nconst switchView = function (activeSlide, view) {\n    var frontView = document.querySelector('.c-configurator__description-options--frontview');\n    var backView = document.querySelector('.c-configurator__description-options--backview');\n    var watchBody = document.querySelector('.c-configurator__watch');\n\n    if (view === 'backview') {\n        // Trigger classes\n        frontView.classList.add('js--active');\n        backView.classList.remove('js--active');\n\n        // Active slide classes\n        activeSlide.classList.remove('js--frontwatch');\n        activeSlide.classList.add('js--backwatch');\n\n        // Watch body classes\n        watchBody.classList.remove('js--frontwatch');\n        watchBody.classList.remove('js--active');\n        watchBody.classList.add('js--backwatch');\n        // Set image classes\n        activeSlide.querySelector('img.is--backwatch').classList.add('js--active');\n        activeSlide.querySelector('img.is--frontwatch').classList.remove('js--active');\n    } else if (view === 'frontview') {\n        // Trigger classes\n        frontView.classList.remove('js--active');\n        backView.classList.add('js--active');\n\n        // Active slide classes\n        activeSlide.classList.remove('js--backwatch');\n        activeSlide.classList.add('js--frontwatch');\n\n        // Watch body classes\n        watchBody.classList.remove('js--backwatch');\n        watchBody.classList.add('js--active');\n        watchBody.classList.add('js--frontwatch');\n\n        // set image classes\n        activeSlide.querySelector('img.is--backwatch').classList.remove('js--active')\n        activeSlide.querySelector('img.is--frontwatch').classList.add('js--active');\n    }\n}\n\nconst getOptionsJson = () => {\n    var options = document.querySelectorAll('.configurator-options');\n\n    if (options.length > 0) {\n        var chosenOptions = {};\n\n        for (var i = 0; i < options.length; i++) {\n            if (options[i].checked === true) {\n                chosenOptions[options[i].name] = 1;\n            }\n        }\n        return JSON.stringify(chosenOptions);\n    }\n    return false;\n}\n\n// Helper function to update <source> tags and <img> tags\nconst updatePictureElement = (pictureElement, newImageUrl) => {\n    if (!pictureElement || !newImageUrl) return;\n\n    // Update <source> tags in <picture> element\n    let sources = pictureElement.querySelectorAll('source');\n    sources.forEach(source => {\n        let originalSrcset = source.getAttribute('srcset');\n        if (!originalSrcset) return;\n\n        // Split original srcSet\n        const updatedSrcset = originalSrcset\n            .split(',')\n            .map(entry => {\n                // extract ?-parameter and \"1x\", \"2x\", \"3x\"\n                const sizeInfo = entry.match(/(\\?.*?)\\s(\\d+x)/);\n                if (!sizeInfo) return '';\n\n                // Extract dimensions and scaling\n                const [_, sizeParams, scale] = sizeInfo;\n\n                // Change only URL and keep the other parameters\n                return `${newImageUrl}${sizeParams} ${scale}`;\n            })\n            .join(',');\n\n        // Update srcSet in <source> tag\n        source.setAttribute('srcset', updatedSrcset);\n    });\n\n    // Update fallback <img> tag\n    let imgElement = pictureElement.querySelector('img');\n    if (imgElement) {\n        const fallbackSrc = `${newImageUrl}?width=255&height=400&quality=100`; // Beispiel für die kleinste Größe\n        imgElement.setAttribute('src', fallbackSrc);\n    }\n};\n\nconst fetchVariantData = async (watchBasePrice) => {\n    const url = document.location.origin;\n\n    const chosenOptions = getOptionsJson();\n    // Don't fetch, when no options were chosen\n    if (undefined === chosenOptions || chosenOptions.length <= 2) {\n        // Reset to default\n        watchBasePrice = (0,_configurator__WEBPACK_IMPORTED_MODULE_6__.getWatchBasePrice)();\n        updatePrice(watchBasePrice);\n        return Promise.resolve(false)\n    }\n\n    const strapRadio = document.querySelector('input[name=\"selectedWatch\"]:checked');\n    const selectedStrap = strapRadio?.value;\n    const closureRadio = document.querySelector(\"input[name='closing']:checked\");\n    const selectedClosure = closureRadio?.value;\n\n    const postData = new URLSearchParams({\n        \"lang\": document.oxid.languageId,\n        \"fnc\": \"getVariantArticlePropertiesByOptions\",\n        \"watchId\": document.querySelector('input[name=\"anid\"]').value,\n        \"chosenOptions\": chosenOptions,\n        \"selectedStrap\": selectedStrap,\n        \"selectedClosure\": selectedClosure\n    });\n\n    const response = await fetch(url, {\n        method: 'POST',\n        headers: {\n            'Accept': 'application/json',\n            'Content-Type': 'application/x-www-form-urlencoded'\n        },\n        body: postData\n    });\n    const result = await response.json();\n    const availableVariant = result.availableVariant;\n\n    // Get articleObject instance from articleConfigurator\n    const articleObject = _ArticleConfigurator_js__WEBPACK_IMPORTED_MODULE_5__[\"default\"].getInstance();\n\n    // Always update options in articleObject, regardless of variant availability\n    articleObject.options = JSON.parse(chosenOptions);\n    articleObject.configHash = result.configHash;\n\n    await (0,_wishlist_js__WEBPACK_IMPORTED_MODULE_4__.updateWishListButtons)();\n\n    let watchBaseNetPrice;\n\n    if (availableVariant && availableVariant.oxid) {\n        watchBasePrice = availableVariant.oxprice;\n        watchBaseNetPrice = availableVariant.netprice;\n\n        // Update articleObject with price and article id\n        articleObject.id = availableVariant.oxid;\n        articleObject.artnum = availableVariant.artnum;\n        articleObject.price = watchBasePrice;\n        articleObject.netPrice = watchBaseNetPrice;\n\n        updatePrice(watchBasePrice, watchBaseNetPrice);\n    } else {\n        watchBasePrice = (0,_configurator__WEBPACK_IMPORTED_MODULE_6__.getWatchBasePrice)();\n        console.warn(\"no option available\");\n        updatePrice(watchBasePrice);\n    }\n}\n\nconst updateVariantPriceDifference = async () => {\n    const basePrice = (0,_configurator__WEBPACK_IMPORTED_MODULE_6__.getWatchBasePrice)();\n    const url = document.location.origin;\n    const options = document.querySelectorAll('.configurator-options');\n    let chosenOptions, priceDifference;\n\n    for (let option of options) {\n        chosenOptions = JSON.parse('{\"' + option.name + '\": 1}');\n        let postData = new URLSearchParams({\n            \"lang\": document.oxid.languageId,\n            \"fnc\": \"getVariantArticlePropertiesByOptions\",\n            \"watchId\": document.querySelector('input[name=\"anid\"]').value,\n            \"chosenOptions\": JSON.stringify(chosenOptions)\n        });\n\n        let response = await fetch(url, {\n            method: 'POST',\n            headers: {\n                'Accept': 'application/json',\n                'Content-Type': 'application/x-www-form-urlencoded'\n            },\n            body: postData\n        });\n\n        let result = await response.json();\n        let availableVariant = result.availableVariant;\n\n        priceDifference = availableVariant.oxprice - basePrice;\n        if (Number.isNaN(priceDifference)) {\n            priceDifference = 0;\n        }\n\n        let optionParent = option.parentNode;\n        let optionTextElement = optionParent.querySelector('.e-link');\n\n        // Store original text if not already stored\n        if (!optionTextElement.dataset.originalText) {\n            optionTextElement.dataset.originalText = optionTextElement.innerText;\n        }\n\n        // Update text with original text and price difference\n        optionTextElement.innerText = optionTextElement.dataset.originalText + \" (+\" + priceDifference.toLocaleString('de-DE', { minimumFractionDigits: 2, maximumFractionDigits: 2 }) + \" \" + document.oxid.shopCurrencySign + \")\";\n    }\n}\n\n/**\n * Update the articleObject object after a configuration change.\n * This function gets called whenever the user changes the configuration of an article.\n * It updates the `selectedStrap` and `selectedClosure` properties of the articleObject\n * as well as the `hash` property which is used to identify the configured artile in the wishlist.\n * @async\n */\nconst updateArticleObjectAfterConfiguration = async () => {\n    // Skip updates during reset process\n    if (isResetting) {\n        return;\n    }\n\n    // Get articleObject instance from articleConfigurator\n    const articleObject = _ArticleConfigurator_js__WEBPACK_IMPORTED_MODULE_5__[\"default\"].getInstance();\n\n    const strapRadio = document.querySelector('input[name=\"selectedWatch\"]:checked');\n    const selectedStrap = strapRadio?.value;\n\n    if (selectedStrap) {\n        articleObject.selectedStrap = createStrapObject(strapRadio);\n    }\n\n    const closureRadio = document.querySelector(\"input[name='closing']:checked\");\n    const selectedClosure = closureRadio?.value ?? false;\n\n    if (!selectedClosure) {\n        articleObject.selectedClosure = {};\n    } else {\n        articleObject.selectedClosure = createClosureObject(closureRadio);\n    }\n\n    // Try to get hash from data attributes\n    const currentStrapRadio = document.querySelector(\"input[name='selectedWatch']:checked\");\n    articleObject.configHash = closureRadio?.dataset?.configHash || currentStrapRadio?.dataset?.configHash;\n\n    await updateWishlistButton();\n}\n\n/** Update the wishlist button state based on configHash\n *\n * @returns {Promise<void>}\n */\nconst updateWishlistButton = async () => {\n    // Get articleObject instance from articleConfigurator\n    const articleObject = _ArticleConfigurator_js__WEBPACK_IMPORTED_MODULE_5__[\"default\"].getInstance();\n\n    // Get wishlist button element by id as we have only on in the configurator\n    const wishlistButton = document.getElementById('linkToWishList');\n    if (!wishlistButton) return;\n\n    // Set the config hash as data attribute (even if empty)\n    wishlistButton.setAttribute('data-config-hash', articleObject.configHash);\n\n    // Import checkWishlistStatus from wishlist module\n    try {\n        const { checkWishlistStatus } = await Promise.resolve(/*! import() */).then(__webpack_require__.bind(__webpack_require__, /*! ../wishlist.js */ \"./source/out/sinn/src/js/modules/wishlist.js\"));\n        const isInWishlist = await checkWishlistStatus(articleObject.configHash);\n        if (isInWishlist) {\n            (0,_wishlist_js__WEBPACK_IMPORTED_MODULE_4__.setWishlistButtonOnState)(wishlistButton);\n        } else {\n            (0,_wishlist_js__WEBPACK_IMPORTED_MODULE_4__.setWishlistButtonOffState)(wishlistButton);\n        }\n    } catch (error) {\n        console.warn('Could not update wishlist button:', error);\n    }\n}\n\nconst createStrapObject = (strapRadio) => { // Extract function\n    const strapContainer = strapRadio.closest(\".c-configurator__straps-item\");\n    const proalphatitle = strapContainer.dataset.proalphaTitle;\n    return {\n        \"id\": strapRadio.value,\n        \"artnum\": strapRadio.dataset.artnum,\n        \"title\": strapRadio.dataset.title,\n        \"proalphatitle\": proalphatitle\n    };\n};\n\nconst createClosureObject = (closureRadio) => { // Extract function\n    const closureLabel = closureRadio.closest(\"label\");\n    const title = closureLabel.textContent.replace(/\\s+/g, ' ').trim();\n    return {\n        \"id\": closureRadio.value,\n        \"artnum\": closureRadio.dataset.artnum,\n        \"title\": title,\n        \"proalphatitle\": closureRadio.dataset.proalphaTitle\n    };\n};\n\nconst updatePrice = (watchBasePrice, baseWatchNetPrice = null) => {\n    var priceText = document.querySelectorAll('.c-configurator__description-price--wrap');\n\n    let basePrice = watchBasePrice;\n    if (!baseWatchNetPrice) {\n        baseWatchNetPrice = document.querySelector('#productConfigurator').getAttribute('data-base-netprice');\n    }\n\n    let selectedStrap = document.querySelector('input[name=\"selectedWatch\"]:checked');\n    let strapPrice = null !== selectedStrap ? selectedStrap.parentNode.dataset.price : 0;\n    let strapNetPrice = null !== selectedStrap ? selectedStrap.parentNode.dataset.netprice : 0\n\n    let selectedClosing = document.querySelector(\"input[name='closing']:checked\");\n    let closingPrice = null !== selectedClosing ? selectedClosing.dataset.price : 0;\n    let closingNetPrice = null !== selectedClosing ? selectedClosing.dataset.netprice : 0;\n\n    let newPrice = parseFloat(basePrice) + parseFloat(strapPrice) + parseFloat(closingPrice);\n    let formattedPrice = newPrice.toLocaleString('de-DE', { minimumFractionDigits: 2, maximumFractionDigits: 2 }) + \" \" + document.oxid.shopCurrencySign;\n\n    priceText.forEach(element => {\n        element.innerHTML = formattedPrice;\n    });\n\n    const toNum = v => isNaN(parseFloat(v)) ? 0 : Number(parseFloat(v).toFixed(2));\n    let totalNetPrice = toNum(baseWatchNetPrice) + toNum(strapNetPrice) + toNum(closingNetPrice);\n\n    let ao = _ArticleConfigurator_js__WEBPACK_IMPORTED_MODULE_5__[\"default\"].getInstance();\n\n    // Update articleObject\n    ao.price = newPrice;\n    ao.netPrice = totalNetPrice;\n\n    // Announce price change to screen readers\n    if (window.oWave && window.oWave.i18n && window.oWave.i18n.DOT_PRICE_UPDATED) {\n        const message = window.oWave.i18n.DOT_PRICE_UPDATED.replace('%s', formattedPrice);\n        (0,_screenReaderUtils__WEBPACK_IMPORTED_MODULE_3__.announceToScreenReader)(message);\n    } else {\n        (0,_screenReaderUtils__WEBPACK_IMPORTED_MODULE_3__.announceToScreenReader)(`Price updated to ${formattedPrice}`);\n    }\n}\n\nconst resetSlider = function (allItemsButActive) {\n    const configuratorSlider = (0,_configurator__WEBPACK_IMPORTED_MODULE_6__.getConfiguratorSlider)();\n    const configuratorComponent = (0,_configurator__WEBPACK_IMPORTED_MODULE_6__.getConfiguratorComponent)();\n\n    configuratorSlider.enable();\n    configuratorSlider.go('=0');\n\n    // Reset styles\n    configuratorComponent.classList.remove('js--secondstep');\n    configuratorComponent.classList.add('js--firststep');\n    allItemsButActive.forEach((item) => {\n        item.style.visibility = null;\n        item.style.opacity = 1;\n    });\n    document.querySelector('.c-configurator__options').style = null;\n    document.querySelector('.c-configurator__bottombar').style = null;\n    document.querySelector('.c-configurator__straps-controls').style = null;\n    document.querySelector('.c-configurator__body').style = null;\n    document.querySelector('.c-configurator__footer').style = null;\n}\n\nconst handleProductSubmit = function () {\n    // Necessary data for request\n    var ajaxTarget = document.getElementById('ajaxTarget').value;\n    var sessionToken = document.getElementById('sessionToken').value;\n    var minibasketContainer = document.querySelector('.c-minibasket__wrapper');\n    var basketCounter = document.getElementById('basketCounter');\n\n    var dropdown = document.querySelector('.c-configurator__description-options .js--conf-dropdown');\n    var dropdownMenu = document.querySelector('.c-configurator__description-options .c-configurator__dropdown--menu');\n    var cartComponent = document.querySelector('.c-cart');\n    var cartTriggerMobile = document.querySelector('.c-mobilemenu__item.is--cart');\n    var configuratorLoader = document.querySelector('.c-configurator__loader');\n\n    configuratorLoader.style.display = 'flex';\n    configuratorLoader.classList.add('js--active');\n\n    (0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])({\n        targets: configuratorLoader,\n        opacity: ['0', '1'],\n        duration: 250,\n        easing: (0,_configurator__WEBPACK_IMPORTED_MODULE_6__.getCubicBezier)()\n    })\n\n    let closing;\n    if (document.querySelector(\"input[name='closing']:checked\")) {\n        closing = document.querySelector(\"input[name='closing']:checked\").value ? document.querySelector(\"input[name='closing']:checked\").value : \"\";\n    }\n    let options = getOptionsJson();\n\n    var watchDetails = {\n        watchId: document.querySelector('input[name=\"anid\"]').value,\n        selectedStrap: document.querySelector('input[name=\"selectedWatch\"]:checked').value,\n        selectedClosing: closing,\n        oldId: document.querySelector('input[name=\"oldid\"]').value\n    }\n\n    // Check whether options are selected and add them to \"watchDetails\".\n    if (options.length > 0) {\n        watchDetails.chosenOptions = options\n    }\n\n    // @Todo: move this to the new separate function below addConfiguratedArticleToBasket()\n    // Put watch in cart\n    $.ajax({\n        url: ajaxTarget + \"cl=basket&fnc=addConfiguratedArticleToBasket&stoken=\" + sessionToken,\n        method: \"POST\",\n        data: watchDetails,\n        success: function (ret) {\n            minibasketContainer.innerHTML = ret;\n            basketCounter.innerText = document.getElementsByClassName('c-minibasket__item').length;\n\n            if (dropdown.classList.contains('js--active')) {\n                (0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])({\n                    targets: dropdownMenu,\n                    height: '0',\n                    duration: 650,\n                    easing: cubicBezier,\n                    complete: function () {\n                        dropdown.classList.remove('js--active');\n                        dropdownMenu.style.visibility = 'hidden';\n                        dropdownMenu.style.opacity = '0';\n                    }\n                })\n            }\n\n            if ((0,_configurator__WEBPACK_IMPORTED_MODULE_6__.getConfiguratorComponent)().classList.contains('js--secondstep') || document.querySelector('#configuratorForward').classList.contains('is--not-configurable', 'c-configurator__options-actions--forward')) {\n                var allItemsButActive = document.querySelectorAll('.c-configurator__straps-item:not(.glide__slide--active)');\n\n                // Reset styles after animation\n                setTimeout(() => {\n                    // Configurator finish\n                    configuratorLoader.classList.remove('js--active');\n                    configuratorLoader.style.display = 'none';\n                    configuratorLoader.style.opacity = '0';\n\n                    // Change forward button\n                    (0,_configurator__WEBPACK_IMPORTED_MODULE_6__.getForwardButton)().classList.remove('is--active');\n                    (0,_configurator__WEBPACK_IMPORTED_MODULE_6__.getOptionSubmitButton)().classList.add('is--active');\n\n                    // Add active class to login layer\n                    cartComponent.classList.add('js--active');\n                    cartTriggerMobile.classList.add('js--active');\n\n                    // Open minibasket\n                    let openModal = document.querySelector('.c-modal.js--openMinibasket');\n                    if (openModal) {\n                        (0,_registerOffcanvas__WEBPACK_IMPORTED_MODULE_2__.registerOffcanvas)({\n                            offCanvas: '.c-cart',\n                            closeButtons: '.c-cart__close, .c-cart__background'\n                        }).openOffcanvas(document.querySelector('.c-function.is--basket'));\n                    }\n\n                    resetSlider(allItemsButActive);\n                }, 1000);\n            }\n\n            // Make minibasket flapper function available after ajax call:\n            // INFO: disabled because doesn't work make sense when redirecting afterwards\n            //addFlapper();\n\n            // Redirect to canonical URL\n            const canonicalLink = document.querySelector('link[rel=\"canonical\"]');\n            if (canonicalLink && canonicalLink.href) {\n                window.location.href = canonicalLink.href;\n            }\n        }\n    });\n}\n\nconst addConfiguratedArticleToBasket = (configuration) => {\n    var ajaxTarget = document.getElementById('ajaxTargetMB').value;\n    var sessionToken = document.getElementById('sessionTokenMB').value;\n\n    // Put watch in cart\n    $.ajax({\n        url: ajaxTarget + \"cl=basket&fnc=addConfiguratedArticleToBasket&stoken=\" + sessionToken,\n        method: \"POST\",\n        data: configuration,\n        success: function (ret) {\n            // Make minibasket flapper function available after ajax call:\n            (0,_minicartflapper__WEBPACK_IMPORTED_MODULE_1__.addFlapper)();\n            location.reload();\n        }\n    });\n}\n\n// Flag to prevent updateArticleObjectAfterConfiguration during reset\nlet isResetting = false;\nconst resetArticleObjectToStandard = async () => {\n    try {\n        isResetting = true;\n\n        const resetResult = _ArticleConfigurator_js__WEBPACK_IMPORTED_MODULE_5__[\"default\"].resetToStandardConfiguration();\n\n        if (resetResult) {\n            await (0,_wishlist_js__WEBPACK_IMPORTED_MODULE_4__.updateWishListButtons)();\n        }\n\n        // Small delay before clearing the flag to ensure any pending slider events are processed\n        setTimeout(() => {\n            isResetting = false;\n        }, 1500);\n\n    } catch (error) {\n        console.warn('Error resetting articleObject to standard:', error);\n        isResetting = false;\n    }\n}\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/configurator/configuratorUtils.js?");/***/}),/***/"./source/out/sinn/src/js/modules/contactform.js":(/*!*******************************************************!*\
  !*** ./source/out/sinn/src/js/modules/contactform.js ***!
  \*******************************************************/ /***/function sourceOutSinnSrcJsModulesContactformJs(){eval("var contactform \t\t\t\t= document.querySelector('.c-contactform');\nvar newsletter \t\t\t\t\t= document.querySelector('.c-contactform.is--newsletter');\nlet uploadField \t\t\t\t= document.getElementById('contactFile');\nconst contactRecipientSelect \t= document.getElementById('contactRecipientSelect');\nconst contactSubjectField \t\t= document.getElementById('contactSubject');\nconst contactSubjectSelect \t\t= document.getElementById('contactSubjectSelect');\nconst showForReplacementForm \t= document.querySelectorAll('.show--replacement');\nconst hideForReturnForm \t\t= document.querySelectorAll('.hide--return');\nconst showForReturnForm \t\t= document.querySelectorAll('.show--return');\n\nconst focusFirstElement = (element) => {\n\tsetTimeout(() => {\n\t\tconst firstInput = element.querySelector('input:first-of-type, select:first-of-type');\n\n\t\tif (firstInput) {\n\t\t\tfirstInput.focus();\n\t\t\t//firstInput.select();\n\t\t}\n\t}, 100);\n}\n\nconst handleRecipientField = () => {\n\tif (contactRecipientSelect.value === \"Vertrieb\") {\n\t\tcontactSubjectField.classList.add('is--hidden');\n\t\tcontactSubjectField.setAttribute('aria-hidden', true);\n\n\t\tshowForReturnForm.forEach(element => {\n\t\t\telement.classList.add('is--hidden');\n\t\t\telement.setAttribute('aria-hidden', true);\n\t\t});\n\t\tshowForReplacementForm.forEach(element => {\n\t\t\telement.classList.add('is--hidden');\n\t\t\telement.setAttribute('aria-hidden', true);\n\t\t});\n\t} else if (contactRecipientSelect.value === \"Kundendienst\") {\n\t\tcontactSubjectField.classList.remove('is--hidden');\n\t\tcontactSubjectField.setAttribute('aria-hidden', false);\n\n\t\tfocusFirstElement(contactSubjectField);\n\t}\n}\n\nconst handleSubjectField = () => {\n\n\tif (contactSubjectSelect.value === \"subject_message\") {\n\t\tshowForReplacementForm.forEach(element => {\n\t\t\telement.classList.add('is--hidden');\n\t\t\telement.setAttribute('aria-hidden', true);\n\t\t});\n\n\t\tshowForReturnForm.forEach(element => {\n\t\t\telement.classList.add('is--hidden');\n\t\t\telement.setAttribute('aria-hidden', true);\n\t\t});\n\n\t\thideForReturnForm.forEach((element,index) => {\n\t\t\telement.classList.remove('is--hidden');\n\t\t\telement.setAttribute('aria-hidden', false);\n\n\t\t\tif(index === 0) {\n\t\t\t\tfocusFirstElement(element);\n\t\t\t}\n\t\t});\n\n\t} else if (contactSubjectSelect.value === \"subject_replacement\") {\n\t\tshowForReturnForm.forEach(element => {\n\t\t\telement.classList.add('is--hidden');\n\t\t\telement.setAttribute('aria-hidden', true);\n\t\t});\n\n\t\thideForReturnForm.forEach((element,index) => {\n\t\t\telement.classList.remove('is--hidden');\n\t\t\telement.setAttribute('aria-hidden', false);\n\n\t\t\tif(index === 0) {\n\t\t\t\tfocusFirstElement(element);\n\t\t\t}\n\t\t});\n\n\t\tshowForReplacementForm.forEach((element, index) => {\n\t\t\telement.classList.remove('is--hidden');\n\t\t\telement.setAttribute('aria-hidden', false);\n\n\t\t\tif(index === 0) {\n\t\t\t\tfocusFirstElement(element);\n\t\t\t}\n\t\t});\n\n\t} else if (contactSubjectSelect.value === \"subject_return\") {\n\t\tshowForReplacementForm.forEach(element => {\n\t\t\telement.classList.add('is--hidden');\n\t\t\telement.setAttribute('aria-hidden', true);\n\t\t});\n\n\t\thideForReturnForm.forEach(element => {\n\t\t\telement.classList.add('is--hidden');\n\t\t\telement.setAttribute('aria-hidden', true);\n\t\t});\n\n\t\tshowForReturnForm.forEach((element,index) => {\n\t\t\telement.classList.remove('is--hidden');\n\t\t\telement.setAttribute('aria-hidden', false);\n\n\t\t\tif(index === 0) {\n\t\t\t\tfocusFirstElement(element);\n\t\t\t}\n\t\t});\n\t}\n\n}\n\nconst disableFields = () => {\n\tconst allHiddenFormGroups \t= document.querySelectorAll('.e-form__row.is--hidden input, .e-form__row.is--hidden select');\n\tconst allShownFormGroups \t= document.querySelectorAll('.e-form__row:not(.is--hidden) input, .e-form__row:not(.is--hidden) select');\n\n\tallHiddenFormGroups.forEach(group => {\n\t\tgroup.disabled = true;\n\t});\n\n\tallShownFormGroups.forEach(group => {\n\t\tgroup.disabled = false;\n\t});\n}\n\nif (contactform) {\n\n\tcontactRecipientSelect.addEventListener(\"change\", (e) => {\n\t\thandleRecipientField();\n\t\tdisableFields();\n\t});\n\n\tcontactSubjectSelect.addEventListener(\"change\", (e) => {\n\t\thandleSubjectField();\n\t\tdisableFields();\n\t});\n\n\tcontactform.addEventListener('submit', function (event) {\n\t\tif (newsletter) {\n\t\t\tnewsletter.reset();\n\t\t}\n\t});\n}\n\nif (uploadField) {\n\n\tuploadField.addEventListener(\"change\", (e) => {\n\t\tcheckFileFormat();\n\t});\n\n\tconst checkFileFormat = () => {\n\t\tconst fileTypes = [\"jpg\", \"pdf\", \"rtf\", \"txt\"]\n\t\tconst alert = document.querySelector(\".is--upload\").querySelector(\".e-alert.e-alert__danger\");\n\t\tfor (var i = 0; i < uploadField.files.length; i++) {\n\t\t\tvar extension = uploadField.files[i].name.substr(uploadField.files[i].name.lastIndexOf('.') + 1);\n\t\t\tif (!fileTypes.includes(extension )) {\n\t\t\t\tuploadField.value = \"\";\n\t\t\t\talert.querySelector('p').innerText = oWave.i18n.DOT_WRONG_FILETYPE;\n\t\t\t\talert.style.display = \"block\";\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (uploadField.files[i].size > 5000000) {\n\t\t\t\tuploadField.value = \"\";\n\t\t\t\talert.querySelector('p').innerText = oWave.i18n.DOT_LARGE_FILE;\n\t\t\t\talert.style.display = \"block\";\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\talert.querySelector('p').innerText = \"\";\n\t\talert.style.display = \"none\";\n\t\treturn true;\n\t}\n}\n\n// scroll to contact form at request.success\nwindow.addEventListener('load', function() {\n    const element = document.getElementById('contact-form');\n    if (element) {\n        setTimeout(() => {\n            element.scrollIntoView({ behavior: 'smooth', block: 'start' });\n            const offset = window.headerHeight || 100;\n            window.scrollBy({ top: -offset, behavior: 'smooth' });\n        }, 1000);\n    }\n});\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/contactform.js?");/***/}),/***/"./source/out/sinn/src/js/modules/contentslider.js":(/*!*********************************************************!*\
  !*** ./source/out/sinn/src/js/modules/contentslider.js ***!
  \*********************************************************/ /***/function sourceOutSinnSrcJsModulesContentsliderJs(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _glidejs_glide__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @glidejs/glide */ \"./node_modules/@glidejs/glide/dist/glide.esm.js\");\n/* harmony import */ var animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! animejs/lib/anime.es.js */ \"./node_modules/animejs/lib/anime.es.js\");\n\n\n\ndocument.addEventListener('DOMContentLoaded', () => {\n    const sliders = document.querySelectorAll('.js-contentslider');\n\n    if (sliders.length) {\n        sliders.forEach(initSlider);\n    }\n});\n\nfunction initSlider(slider) {\n    let previousIndex = 0;\n    const sliderInstance = new _glidejs_glide__WEBPACK_IMPORTED_MODULE_0__[\"default\"](slider, {\n        type: 'carousel',\n        gap: 0,\n        animationDuration: 1500,\n        animationTimingFunc: 'cubic-bezier(.44,.05,.19,.94)'\n    });\n\n    sliderInstance.on('run.after', () => animateSlides(slider));\n    sliderInstance.on('run.before', () => resetAnimations(slider));\n\n    sliderInstance.mount();\n}\n\nfunction animateSlides(slider) {\n    (0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"])({\n        targets: slider.querySelectorAll('.glide__slide--active .c-contentslider__slide-headline'),\n        translateY: ['2.5vw', '0'],\n        opacity: [0, 1],\n        delay: animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"].stagger(33),\n        duration: 1500,\n        easing: 'cubicBezier(.40,.05,.20,.90)'\n    });\n    (0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"])({\n        targets: slider.querySelectorAll('.glide__slide--active .c-contentslider__slide-content'),\n        translateY: ['5vw', '0'],\n        opacity: [0, 1],\n        delay: 150,\n        duration: 1500,\n        easing: 'cubicBezier(.40,.05,.20,.90)'\n    });\n    (0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"])({\n        targets: slider.querySelectorAll('.glide__slide--active .c-contentslider__slide-link'),\n        translateY: ['5vw', '0'],\n        opacity: [0, 1],\n        delay: 300,\n        duration: 1500,\n        easing: 'cubicBezier(.40,.05,.20,.90)'\n    });\n}\n\nfunction resetAnimations(slider) {\n    (0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"])({\n        targets: slider.querySelectorAll('.glide__slide--active .c-contentslider__slide-headline'),\n        opacity: [1, 0],\n        translateY: ['0', '-5vw'],\n        duration: 1500,\n        easing: 'cubicBezier(.40,.05,.20,.90)'\n    });\n    (0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"])({\n        targets: slider.querySelectorAll('.glide__slide--active .c-contentslider__slide-content'),\n        opacity: [1, 0],\n        translateY: ['0', '-5vw'],\n        delay: 150,\n        duration: 1500,\n        easing: 'cubicBezier(.40,.05,.20,.90)'\n    });\n    (0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"])({\n        targets: slider.querySelectorAll('.glide__slide--active .c-contentslider__slide-link'),\n        opacity: [1, 0],\n        translateY: ['0', '-5vw'],\n        delay: 300,\n        duration: 1500,\n        easing: 'cubicBezier(.40,.05,.20,.90)'\n    });\n}\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/contentslider.js?");/***/}),/***/"./source/out/sinn/src/js/modules/countryListNotice.js":(/*!*************************************************************!*\
  !*** ./source/out/sinn/src/js/modules/countryListNotice.js ***!
  \*************************************************************/ /***/function sourceOutSinnSrcJsModulesCountryListNoticeJs(){eval("document.addEventListener('DOMContentLoaded', function () {\n    initDealerNotice();\n});\nfunction initDealerNotice() {\n    let dealerLinks = [\n        '/haendlerliste',\n        '/en/haendlerliste',\n        '/fr/haendlerliste',\n    ];\n    let words = [\n        'here.',\n        'Hier',\n        'ici',\n    ];\n    let preparedLinkElements = document.querySelectorAll('.label-notice-link');\n\n    preparedLinkElements.forEach((preparedLinkElement) => {\n        if (dealerLinks[selectedLanguage] && selectedLanguage !== undefined) {\n            preparedLinkElement.style.fontSize = \"smaller\";\n            let preparedHtml = preparedLinkElement.innerHTML;\n\n            words.forEach((word) => {\n                let regex = new RegExp(`(${word})`, 'g');\n                if (preparedHtml.match(regex)) {\n                    let anchor = `<a href=\"${dealerLinks[selectedLanguage]}\" target=\"_blank\" style=\"font-size: inherit; text-decoration: underline; color: inherit;\">${word}</a> `;\n                    preparedHtml = preparedHtml.replace(regex, anchor);\n                }\n            });\n\n            preparedLinkElement.innerHTML = preparedHtml;\n        }\n    });\n}\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/countryListNotice.js?");/***/}),/***/"./source/out/sinn/src/js/modules/datenschutzCBVisibilityControl.js":(/*!**************************************************************************!*\
  !*** ./source/out/sinn/src/js/modules/datenschutzCBVisibilityControl.js ***!
  \**************************************************************************/ /***/function sourceOutSinnSrcJsModulesDatenschutzCBVisibilityControlJs(){eval("document.addEventListener('DOMContentLoaded', function() {\n\n    // Newsletter\n    let btnSubscribe = document.getElementById('newsletterSubscribeOn');\n    let btnUnsubscribe = document.getElementById('newsletterSubscribeOff');\n    let divDatenschutz = document.getElementById('div-datenschutz');\n    let cbDatenschutzNewsletter = document.getElementById('gdproptin_newsletter');\n\n    // Account\n    let selectedOption = document.getElementById('status');\n    let hideOnUnsub = document.querySelectorAll('.hide-on-unsub');\n    let cbDatenschutzAccount = document.getElementById('gdproptin_accountnewsletter');\n\n    function toggleNewsletterDatenschutz() {\n        if (btnUnsubscribe.checked) {\n            divDatenschutz.classList.add('hidden');\n            cbDatenschutzNewsletter.removeAttribute('required');\n        } else {\n            divDatenschutz.classList.remove('hidden');\n            cbDatenschutzNewsletter.setAttribute('required', 'required');\n        }\n    }\n\n    function toggleAccountDatenschutz() {\n        if (selectedOption.value == 0) {\n            modifyVisibility(hideOnUnsub, true);\n            cbDatenschutzAccount.removeAttribute('required');\n        } else {\n            modifyVisibility(hideOnUnsub, false);\n            cbDatenschutzAccount.setAttribute('required', 'required');\n        }\n    }\n\n    function modifyVisibility(elements, visible) {\n        elements.forEach(function(element) {\n            if (visible) {\n                element.classList.add('hidden');\n            } else {\n                element.classList.remove('hidden');\n            }\n        });\n    }\n\n    if (btnSubscribe && btnUnsubscribe) {\n        btnSubscribe.addEventListener('change', toggleNewsletterDatenschutz);\n        btnUnsubscribe.addEventListener('change', toggleNewsletterDatenschutz);\n\n        toggleNewsletterDatenschutz();\n    }\n\n    if (selectedOption) {\n        selectedOption.addEventListener('change', toggleAccountDatenschutz);\n        toggleAccountDatenschutz();\n    }\n});\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/datenschutzCBVisibilityControl.js?");/***/}),/***/"./source/out/sinn/src/js/modules/dropdown.js":(/*!****************************************************!*\
  !*** ./source/out/sinn/src/js/modules/dropdown.js ***!
  \****************************************************/ /***/function sourceOutSinnSrcJsModulesDropdownJs(){eval("/**\n * This Software is the property of dotfly and is protected\n * by copyright law - it is NOT Freeware.\n *\n * Any unauthorized use of this software without a valid license key\n * is a violation of the license agreement and will be prosecuted by\n * civil and criminal law.\n *\n * @category   Einfache Dropdown-Elemente, wie z.B. das Sortieren-Dropdown in Produktlisten\n * @author     Lennart Syre <lennart.syre@dotfly.de, anna.morawe@dotfly.de>\n * @license    http://www.dotfly.de Commercial\n * @link       http://www.dotfly.de\n */\n\ndocument.addEventListener('DOMContentLoaded', function() {\n\tinitializeDropdowns();\n});\n\nfunction initializeDropdowns() {\n\tlet dropdownTriggers = document.querySelectorAll('.js--dropdown-trigger');\n\n\tif (dropdownTriggers.length === 0) {\n\t\treturn; // Keine Dropdowns vorhanden, nichts zu tun\n\t}\n\n\tdropdownTriggers.forEach(function(trigger) {\n\t\ttrigger.addEventListener('click', function(event) {\n\t\t\tevent.stopPropagation();\n\t\t\tlet dropdownContainer = trigger.closest('.e-dropdown');\n\t\t\tdropdownContainer.classList.toggle('js--active');\n\t\t\tcloseOtherDropdowns(dropdownContainer);\n\n\t\t\tif(dropdownContainer.classList.contains('js--active')) {\n\t\t\t\ttrigger.setAttribute('aria-expanded', true);\n\t\t\t\tdocument.body.addEventListener('keydown', closeDropdownESC);\n\t\t\t} else {\n\t\t\t\ttrigger.setAttribute('aria-expanded', false);\n\t\t\t\tdocument.body.removeEventListener('keydown', closeDropdownESC);\n\t\t\t}\n\t\t});\n\t});\n\n\tdocument.addEventListener('click', function() {\n\t\tcloseAllDropdowns();\n\t});\n}\n\nfunction closeAllDropdowns() {\n\tlet dropdownContainers = document.querySelectorAll('.e-dropdown');\n\tdropdownContainers.forEach(function(container) {\n\t\tcontainer.classList.remove('js--active');\n\t\tcontainer.querySelector('.js--dropdown-trigger').setAttribute('aria-expanded', false);\n\t});\n}\n\nfunction closeOtherDropdowns(currentDropdown) {\n\tlet dropdownContainers = document.querySelectorAll('.e-dropdown');\n\tdropdownContainers.forEach(function(container) {\n\t\tif (container !== currentDropdown) {\n\t\t\tcontainer.classList.remove('js--active');\n\t\t\tcontainer.querySelector('.js--dropdown-trigger').setAttribute('aria-expanded', false);\n\t\t}\n\t});\n}\n\nfunction closeDropdownESC(event) {\n\tif (event.key === 'Escape' || event.key === 'Esc' || event.keyCode === 27) {\n\t\tcloseOtherDropdowns();\n\t}\n}\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/dropdown.js?");/***/}),/***/"./source/out/sinn/src/js/modules/etracker.js":(/*!****************************************************!*\
  !*** ./source/out/sinn/src/js/modules/etracker.js ***!
  \****************************************************/ /***/function sourceOutSinnSrcJsModulesEtrackerJs(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _ArticleConfigurator_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./ArticleConfigurator.js */ \"./source/out/sinn/src/js/modules/ArticleConfigurator.js\");\n\nconst ao = _ArticleConfigurator_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"].getInstance();\n\ndocument.addEventListener('DOMContentLoaded', _etrackerOnReady);\n\nfunction _etrackerOnReady() {\n    // E-Commerce events\n    if (document.tracking && !document.tracking.newItemAdded) {\n        trackViewEvent();\n    } else if (document.tracking && document.tracking.newItemAdded) {\n        trackInsertToBasketEvent();\n    }\n    trackOrderEvent();\n\n    // Other tracking events\n    justLoggedIn();\n    trackOtherEvents();\n\n    // HIDE THE ET OVERLAY!!!!\n    function hideEtOverlayCSS() {\n        const css = `\n        #et_debugOverlay {\n            display: none !important;\n            visibility: hidden !important;\n        }\n    `;\n        const style = document.createElement('style');\n        style.innerHTML = css;\n        document.head.appendChild(style);\n    }\n\n    hideEtOverlayCSS();\n    const obs = new MutationObserver(() => {\n        const el = document.getElementById('et_debugOverlay');\n        if (el) el.style.display = 'none';\n    });\n    obs.observe(document.body, { childList: true, subtree: true });\n}\n\n// Ajax call that fetches Et-View Event Object\nfunction trackViewEvent() {\n    // Skip if article is catalog, archived or no available article at all\n    if (typeof ao === \"undefined\" || typeof ao.artnum === \"undefined\" || ao.isCatalog || ao.isArchived) return;\n\n    const category = ao.isWatch || ao.isSetArticle ? 'Uhren' : 'Armbänder & Zubehör';\n    const name = ao.isStrap ? ao.artnum + \" - \" + ao.proalphatitle : ao.proalphatitle;\n\n    // Build product\n    const product = {\n        id: ao.artnum,\n        name: name,\n        price: Number(ao.netPrice).toFixed(2),\n        currency: \"EUR\",\n        category: [category]\n    };\n\n    try {\n        etCommerce.sendEvent('viewProduct', product);\n    } catch (e) {\n        console.error(\"Error sending eTracker event:\", e);\n    }\n}\n\n// Insertt To Basket\nfunction trackInsertToBasketEvent() {\n    const articleFromCookie = JSON.parse(localStorage.getItem(\"lastAddedArticle\"));\n    const lastAddedArticle = articleFromCookie._state;\n    localStorage.removeItem(\"lastAddedArticle\");\n\n    if (!lastAddedArticle) return;\n\n    const category = lastAddedArticle.isWatch || lastAddedArticle.isSetArticle ? 'Uhren' : 'Armbänder & Zubehör';\n    const name = lastAddedArticle.isStrap ? lastAddedArticle.artnum + \" - \" + lastAddedArticle.proalphatitle : lastAddedArticle.proalphatitle;\n    const quantity = articleFromCookie.quantity;\n\n    // Build base product\n    const product = {\n        id: lastAddedArticle.artnum,\n        name: name,\n        price: Number(lastAddedArticle.netPrice).toFixed(2),\n        currency: \"EUR\",\n        category: [category]\n    };\n\n    let variants = {};\n\n    const isWatch = lastAddedArticle.isWatch;\n\n    // Watches\n    if (isWatch) {\n        const isDefault =\n            Object.keys(lastAddedArticle.selectedStrap ?? {}).length === 0 &&\n            Object.keys(lastAddedArticle.selectedClosure ?? {}).length === 0;\n\n        if (isDefault) {\n            variants.var1 = lastAddedArticle.defaultStrap.artnum + \" - \" + lastAddedArticle.defaultStrap.proalphatitle;\n            const defClosure = lastAddedArticle.defaultClosure;\n            const hasClosure = defClosure && Object.keys(defClosure).length > 0;\n\n            variants.var2 = hasClosure\n                ? defClosure.artnum + \" - \" + defClosure.proalphatitle\n                : 'Standardschließe';\n        } else {\n            let var3, var4, var5;\n            let opts = {};\n            if (lastAddedArticle.options) {\n                opts = typeof lastAddedArticle.options === 'string'\n                    ? JSON.parse(lastAddedArticle.options)\n                    : lastAddedArticle.options;\n            }\n\n            if (opts.OptEngWoTag) var3 = 'Englischer Wochentag';\n            if (opts.OptSaphKriGla) var4 = 'Saphirkristallglas';\n            if (opts.OptSaphKriGlaBoden) var5 = 'Saphirkristallglasboden';\n\n            variants.var1 = lastAddedArticle.selectedStrap.artnum + \" - \" + lastAddedArticle.selectedStrap.proalphatitle;\n            variants.var2 = lastAddedArticle.selectedClosure.proalphatitle ?\n                lastAddedArticle.selectedClosure.artnum + \" - \" + lastAddedArticle.selectedClosure.proalphatitle :\n                'Standardschließe';\n\n            if (typeof var3 !== 'undefined') variants.var3 = var3;\n            if (typeof var4 !== 'undefined') variants.var4 = var4;\n            if (typeof var5 !== 'undefined') variants.var5 = var5;\n        }\n\n        // Set Articles\n    } else if (lastAddedArticle.isSetArticle) {\n        variants.var1 = lastAddedArticle.setItems[0].artnum + \" - \" + lastAddedArticle.setItems[0].proalphatitle;\n        variants.var2 = 'Standardschließe';\n        // Straps\n    } else if (lastAddedArticle.isStrap)  {\n        variants.var1 = lastAddedArticle.requiredForWatchProAlphaTitle ?\n            lastAddedArticle.requiredForWatchArtNum + \" - \" + lastAddedArticle.requiredForWatchProAlphaTitle :\n            'Ohne Auswahl';\n\n        variants.var2 = lastAddedArticle.selectedClosure?.proalphatitle ?\n            lastAddedArticle.selectedClosure.artnum + \" - \" + lastAddedArticle.selectedClosure.proalphatitle :\n            'Ohne Auswahl';\n    }\n\n    if (variants && Object.keys(variants).length > 0) {\n        product.variants = variants;\n    }\n\n    try {\n        etCommerce.sendEvent('insertToBasket', product, quantity);\n\n        if (product.variants?.var1 !== undefined && !product.category?.includes(\"Armbänder & Zubehör\")) {\n            _etracker.sendEvent(new et_UserDefinedEvent('Armband', 'Konfigurator', 'Auswahl', product.variants.var1));\n        }\n        if (product.variants?.var2 !== undefined && !product.category?.includes(\"Armbänder & Zubehör\")) {\n            _etracker.sendEvent(new et_UserDefinedEvent('Schließen', 'Konfigurator', 'Auswahl', product.variants.var2));\n        }\n        ['var3', 'var4', 'var5'].forEach(v => {\n            if (product?.variants?.[v] !== undefined) {\n                _etracker.sendEvent(new et_UserDefinedEvent('Optionen', 'Konfigurator', 'Auswahl', product.variants[v]));\n            }\n        });\n    } catch (e) {\n        console.error(\"Sending insertToBasket Event failed!\");\n    }\n\n}\n\n// Writes the last added article in the local storage, so it can be later accessed from the main sending event\nfunction trackInsertToBasketObject() {\n    document.addEventListener(\"click\", e => {\n        const btn = e.target.closest('#configuratorBasket, #toBasket, #toBasket2, #stickyDirect2Basket, .e-btn.is--basket.is--fullwidth, .e-btn--primary.e-btn--icon-left.has--icon-basket.is--fullwidth');\n        if (!btn) return;\n\n        // Skip if hidden/disabled\n        if (btn.getAttribute(\"aria-hidden\") === \"true\" || btn.getClientRects().length === 0) return;\n\n        if (typeof ao !== \"undefined\" && ao !== null) {\n            if ([\"toBasket\", \"toBasket2\", \"stickyDirect2Basket\"].includes(btn.id)) {\n                ao.isDefault = true;\n            } else {\n                ao.isDefault = false;\n            }\n            // Insert quantity detection for classic input\n            const qtyEl = document.getElementById('amountToBasket');\n            let qty = 1;\n            if (qtyEl) {\n                const parsed = parseInt(qtyEl.value, 10);\n                if (!Number.isNaN(parsed) && parsed > 0) qty = parsed;\n            }\n            ao.quantity = qty;\n            const clone = JSON.parse(JSON.stringify(ao));\n            localStorage.setItem(\"lastAddedArticle\", JSON.stringify(clone));\n        }\n    }, true);\n}\n\n// Checks if order placed and sends it\nfunction trackOrderEvent() {\n    try {\n        if (document.tracking && document.tracking.isThankYouPage) {\n            try {\n                const orderEvent = document.tracking.orderEvent;\n                etCommerce.sendEvent('order', orderEvent);\n            } catch (e) {\n                console.error(\"Error sending eTracker event:\", e);\n            }\n        }\n    } catch (e) {\n        console.error(\"Etracker can not be initialised\");\n    }\n}\n\nfunction getCookieValue(a) {\n    const b = document.cookie.match('(^|;)\\\\s*' + a + '\\\\s*=\\\\s*([^;]+)');\n    return b ? b.pop() : '';\n}\n\nfunction justLoggedIn() {\n    const justLoggedInValue = getCookieValue(\"justLoggedIn\");\n    const justLoggedOutValue = getCookieValue(\"justLoggedOut\");\n\n    if (justLoggedInValue == 1) {\n        try {\n            _etracker.sendEvent(new et_AuthenticationSuccessEvent('Login', '',));\n        } catch (e) {\n            console.error(\"Error sending eTracker event:\", e);\n        } finally {\n            document.cookie = \"justLoggedIn=0; max-age=0; path=/;\";\n        }\n    }\n\n    if (justLoggedOutValue == 1) {\n        try {\n            _etracker.sendEvent(new et_AuthenticationLogoutEvent('Logout', '',));\n        } catch (e) {\n            console.error(\"Error sending eTracker event:\", e);\n        } finally {\n            document.cookie = \"justLoggedOut=0; max-age=0; path=/;\";\n        }\n    }\n}\n\nfunction trackAdditionalAlternativesClick() {\n    const links = document.querySelectorAll('.et-dot-show-alternatives');\n    links.forEach(link => {\n        link.addEventListener('click', function () {\n            try {\n                _etracker.sendEvent(new et_UserDefinedEvent('Button Zusätzliche Alternativen', 'Bestellhistorie', 'click', ''));\n            } catch (err) {\n                console.error(\"Error sending eTracker event:\", e);\n            }\n        });\n    });\n}\n\nfunction trackStrapWatchClick() {\n    const selectors = [\n        '.et-dot-strap-watch-selection button',\n        '.et-dot-strap-watch-no-selection button'\n    ];\n\n    document.querySelectorAll(selectors.join(',')).forEach(btn => {\n        btn.addEventListener('click', function () {\n            const li = btn.closest('li');\n\n            try {\n                _etracker.sendEvent(new et_UserDefinedEvent(li.getAttribute('data-name'), \"Armbandkategorieseite\", 'click', ''));\n            } catch (err) {\n                console.error(\"Error sending eTracker event:\", e);\n            }\n        });\n    });\n}\n\nfunction trackClaspWatchClick() {\n    const selectors = [\n        '.et-dot-clasp-watch-selection button',\n        '.et-dot-clasp-watch-no-selection button'\n    ];\n\n    document.querySelectorAll(selectors.join(',')).forEach(btn => {\n        btn.addEventListener('click', function () {\n            const li = btn.closest('li');\n\n            try {\n                _etracker.sendEvent(new et_UserDefinedEvent(li.getAttribute('data-name'), \"Schließenkategorieseite\", 'click', ''));\n            } catch (err) {\n                console.error(\"Error sending eTracker event:\", e);\n            }\n        });\n    });\n}\n\nfunction trackBasketData() {\n    function trackSetArticleWrist() {\n        var elements = document.querySelectorAll('.set-article-wrist-selection:checked');\n\n        if (elements !== null) {\n            for (var i = 0; i < elements.length; i++) {\n                var element = elements[i];\n\n                var articleNum = element.getAttribute('data-article-number');\n                var articleName = element.getAttribute('data-article-name');\n                var wristName = element.getAttribute('data-article-wristname');\n\n                try {\n                    _etracker.sendEvent(new et_UserDefinedEvent('Vormontiertes Band', 'Warenkorb-Übersicht', articleNum + ' - ' + articleName, wristName));\n                } catch (e) {\n                    console.error(\"Error sending eTracker event:\", e);\n                } finally {\n                    continue;\n                }\n            }\n        }\n    }\n\n    function trackWristValues() {\n        var elements = document.querySelectorAll('.wrist-length');\n\n        if (elements !== null) {\n            for (var i = 0; i < elements.length; i++) {\n                var element = elements[i];\n\n                var articleNum = element.getAttribute('data-article-number');\n                var articleName = element.getAttribute('data-article-name');\n                var wristLength = element.getAttribute('value');\n\n                if (parseInt(wristLength) > 0) {\n                    try {\n                        _etracker.sendEvent(new et_UserDefinedEvent('Handgelenkumfang', 'Warenkorb-Übersicht', articleNum + ' - ' + articleName, wristLength + ' mm'));\n                    } catch (e) {\n                        console.error(\"Error sending eTracker event:\", e);\n                    } finally {\n                        continue;\n                    }\n                }\n            }\n        }\n    };\n\n    function trackUserDefinedBasketData() {\n        trackSetArticleWrist();\n        trackWristValues();\n\n        return true;\n    }\n    document.getElementById('SubmitBasket')?.addEventListener('click', trackUserDefinedBasketData);\n}\n\nfunction trackOtherEvents() {\n    // DOM On Content Loaded\n    trackInsertToBasketObject();\n    trackCrossSelling();\n    trackStickyButtons();\n    trackNewsAccordion();\n    trackRegisterEvents();\n    trackBasketData();\n    trackAdditionalAlternativesClick();\n    trackStrapWatchClick();\n    trackClaspWatchClick();\n    trackRetailerHeaderClicks();\n    trackRetailerFooterClicks();\n    trackInsertToWatchlist();\n    trackInsertToBasketFromWishlist();\n\n    // Retailer Loaded\n    document.addEventListener('retailerLoaded', function () {\n        trackRetailerSearchField();\n    });\n\n    // Basket Question Loaded\n    document.addEventListener('basket-questionLoaded', () => {\n        trackQuestionConfigureClick();\n        trackToBasket2Click();\n    });\n\n    // Configurator Loaded\n    document.addEventListener('configuratorLoaded', () => {\n        trackConfiguratorForwardClick();\n    });\n}\n\n// Fires only on article details page\nfunction trackCrossSelling() {\n    const controller = document.tracking?.viewController ?? null;\n\n    if (controller !== null && controller === 'details') {\n\n        const strapsButton = document.querySelector('.et-related-link.e-link.is--inout');\n        if (strapsButton) {\n            strapsButton.addEventListener('click', () => {\n                try {\n                    _etracker.sendEvent(new et_UserDefinedEvent('Cross-Selling', 'Produktdetail', 'Klick auf Button', 'Zusätzliche Armbänder'));\n                } catch (e) {\n                    console.error(\"Error sending eTracker event:\", e);\n                }\n            });\n        }\n\n        const blocks = document.querySelectorAll('.track-related-block');\n        blocks.forEach(el => {\n            el.addEventListener('click', () => {\n                try {\n                    _etracker.sendEvent(new et_UserDefinedEvent('Cross-Selling', 'Produktdetail', 'Klick auf Uhr', el.dataset.productTitle));\n                } catch (e) {\n                    console.error(\"Error sending eTracker event:\", e);\n                }\n            });\n        });\n    }\n\n}\n\nfunction trackStickyButtons() {\n    const stickyDirectToBasket = document.getElementById('stickyDirect2Basket');\n        stickyDirectToBasket?.addEventListener('click', () => {\n            try {\n                _etracker.sendEvent(new et_ClickEvent('In den Warenkorb', 'Sticky Bar'));\n            } catch (e) {\n                console.error(\"Error sending eTracker event:\", e);\n            }\n        });\n\n    const stickyConfBtn = document.getElementById('stickyConfigureButton');\n    stickyConfBtn?.addEventListener('click', () => {\n        try {\n            _etracker.sendEvent(new et_ClickEvent('Uhr konfigurieren', 'Sticky Bar'));\n        } catch (e) {\n            console.error(\"Error sending eTracker event:\", e);\n        }\n    });\n}\n\nfunction trackNewsAccordion() {\n    const dateItems = document.querySelectorAll('.c-accordion__item');\n    dateItems.forEach(dateItem => {\n        dateItem.addEventListener('click', () => {\n            if (dateItem.classList.contains('is--closed')) {\n                const dateItemName = dateItem.querySelector('.c-news__name').innerHTML.trim();\n                try {\n                    _etracker.sendEvent(new et_UserDefinedEvent(dateItemName, 'Veranstaltungen', 'Details anzeigen', ''));\n                } catch (e) {\n                    console.error(\"Error sending eTracker event:\", e);\n                }\n            }\n        });\n    });\n}\n\nfunction trackRegisterEvents() {\n    if (document.tracking?.userRegSuccess) {\n        window.addEventListener('DOMContentLoaded', () => {\n            const targetURLPattern = /\\/index\\.php\\?cl=register&success=1(&|$)/i;\n            if (targetURLPattern.test(window.location.href)) {\n                try {\n                    _etracker.sendEvent(new et_UserDefinedEvent('Standardformular', 'Registrierung', 'Formular abgesendet', 'Formular'));\n                } catch (e) {\n                    console.error(\"Error sending eTracker event:\", e);\n                }\n            }\n        });\n    }\n\n    if (document.tracking?.paymentUserReg) {\n        window.addEventListener('DOMContentLoaded', () => {\n            const targetURLPattern = /\\/index\\.php\\?cl=payment&new_user=1&success=1(&|$)/i;\n            if (targetURLPattern.test(window.location.href)) {\n                try {\n                    _etracker.sendEvent(new et_UserDefinedEvent('Warenkorb', 'Registrierung', 'Formular abgesendet', 'Formular'));\n                } catch (e) {\n                    console.error(\"Error sending eTracker event:\", e);\n                }\n            }\n        });\n    }\n}\n\nfunction trackRetailerHeaderClicks() {\n    const mobileFachhaendler = document.getElementById('mobileFachhaendler');\n    if (mobileFachhaendler) {\n        mobileFachhaendler.addEventListener('click', () => {\n            if (!mobileFachhaendler.classList.contains('js--active')) {\n                try {\n                    _etracker.sendEvent(new et_UserDefinedEvent('Button Fachhändler', 'Fachhändler', 'click', ''));\n                } catch (e) {\n                    console.error(\"Error sending eTracker event:\", e);\n                }\n            }\n        });\n    }\n\n    const headerFachhaendler = document.getElementById('headerFachhaendler');\n    if (headerFachhaendler) {\n        headerFachhaendler.addEventListener('click', () => {\n            try {\n                _etracker.sendEvent(new et_UserDefinedEvent('Button Fachhändler', 'Fachhändler', 'click', ''));\n            } catch (e) {\n                console.error(\"Error sending eTracker event:\", e);\n            }\n        });\n    }\n}\n\nfunction trackRetailerSearchField() {\n    const searchField = document.getElementById('retailerParam');\n    let isFirstInput = true;\n    if (searchField) {\n        searchField.addEventListener('input', () => {\n            if (isFirstInput) {\n                try {\n                    _etracker.sendEvent(new et_UserDefinedEvent('Fachhändler-Suche', 'Fachhändler', 'Interaktion', ''));\n                } catch (e) {\n                    console.error(\"Error sending eTracker event:\", e);\n                } finally {\n                    isFirstInput = false;\n                }\n            }\n        });\n    }\n}\n\nfunction trackRetailerFooterClicks() {\n    const footerFachhaendler = document.getElementById('footerFachhaendler');\n    if (footerFachhaendler) {\n        footerFachhaendler.addEventListener('click', () => {\n            try {\n                _etracker.sendEvent(new et_UserDefinedEvent('Button Fachhändler', 'Fachhändler', 'click', ''));\n            } catch (e) {\n                console.error(\"Error sending eTracker event:\", e);\n            }\n        });\n    }\n}\n\nfunction trackQuestionConfigureClick() {\n    const questionConfBtn = document.getElementById('questionConfigureButton');\n    if (questionConfBtn) {\n        questionConfBtn.addEventListener('click', () => {\n            try {\n                _etracker.sendEvent(new et_ClickEvent('Uhr konfigurieren', 'Nachfrage'));\n            } catch (e) {\n                console.error(\"Error sending eTracker event:\", e);\n            }\n        });\n    }\n}\n\nfunction trackToBasket2Click() {\n    const toBasket2 = document.getElementById('toBasket2');\n    if (toBasket2) {\n        toBasket2.addEventListener('click', () => {\n            try {\n                _etracker.sendEvent(new et_ClickEvent('In den Warenkorb', 'Nachfrage'));\n            } catch (e) {\n                console.error(\"Error sending eTracker event:\", e);\n            }\n        });\n    }\n}\n\nfunction trackConfiguratorForwardClick() {\n    const confForward = document.getElementById('configuratorForward');\n    if (confForward) {\n        confForward.addEventListener('click', function () {\n            try {\n                _etracker.sendEvent(new et_ClickEvent('In den Warenkorb', 'Nach Konfigurator'));\n            } catch (e) {\n                console.error(\"Error sending eTracker event:\", e);\n            }\n        });\n    }\n}\n\nfunction trackInsertToWatchlist() {\n\n    // Productdetail\n    function bindAddToWishlistListeners() {\n        // Add to wishlist selectors\n        const btns = document.querySelectorAll(\n            '.e-link__icon.is--add-to-wishlist:not([disabled]):not([aria-disabled=\"true\"]), ' +\n            '.e-btn--border.is--add-to-wishlist:not([disabled]):not([aria-disabled=\"true\"]), ' +\n            '.e-btn--secondary.e-btn--icon-left.is--add-to-wishlist:not([disabled]):not([aria-disabled=\"true\"]), ' +\n            '.e-link__icon.is--on-wishlist, .e-btn--border.is--on-wishlist, .e-btn--secondary.e-btn--icon-left.is--on-wishlist'\n        );\n\n        btns.forEach(btn => {\n            if (!btn.dataset.trackingBound) {\n                btn.addEventListener('click', e => {\n                    // only fire when it was add-state\n                    if (btn.classList.contains('is--add-to-wishlist')) {\n\n                        if (typeof ao !== \"undefined\") {\n                            const productCategory = (ao.isWatch || ao.isSetArticle) ? 'Uhren' : 'Armbänder & Zubehör';\n                            let var1; let var2; let var3; let var4; let var5;\n\n                            let isConfigurator = btn.href.includes(\"articledetailsconfigurator\") || btn.href.includes(\"configuratorcontroller\");\n\n                            // Configurator\n                            if (isConfigurator) {\n                                // Watches\n                                if (ao.isWatch) {\n                                    var1 = ao.selectedStrap.artnum + \" - \" + ao.selectedStrap.proalphatitle;\n                                    var2 = ao.selectedClosure?.proalphatitle ?\n                                        ao.selectedClosure.artnum + \" - \" + ao.selectedClosure.proalphatitle :\n                                        \"Standardschließe\";\n\n                                    let opts = {};\n                                    if (ao.options) {\n                                        opts = typeof ao.options === 'string'\n                                            ? JSON.parse(ao.options)\n                                            : ao.options;\n                                    }\n\n                                    if (opts.OptEngWoTag)       var3 = 'Englischer Wochentag';\n                                    if (opts.OptSaphKriGla)     var4 = 'Saphirkristallglas';\n                                    if (opts.OptSaphKriGlaBoden) var5 = 'Saphirkristallglasboden';\n                                }\n\n                                // Straps\n                                if (ao.isStrap) {\n                                    const req = (typeof ao.requiredForWatchProAlphaTitle === 'string')\n                                        ? ao.requiredForWatchProAlphaTitle.trim()\n                                        : '';\n                                    var1 = req && ao.requiredForWatch !== 'no_selection' ?\n                                        ao.requiredForWatchArtNum + \" - \" + req : 'Ohne Auswahl';\n\n                                    var2 = '';\n                                    const claspSelect = document.getElementById('claspSelection');\n                                    if (claspSelect) {\n                                        let selectedOption = claspSelect.options[claspSelect.selectedIndex] || null;\n                                        if (!selectedOption) {\n                                            selectedOption = claspSelect.querySelector('option[selected], option:checked');\n                                        }\n                                        if (selectedOption) {\n                                            const rawValue = selectedOption.getAttribute('value');\n                                            const selectedValue = (typeof rawValue === 'string' ? rawValue : selectedOption.value || '').trim();\n                                            const isNoSel = selectedValue === 'no-clasp' || selectedValue === 'no_selection' || selectedValue === 'no-select' || selectedValue === 'no_selection_value';\n                                            if (isNoSel) {\n                                                var2 = 'Ohne Auswahl';\n                                            } else {\n                                                const ptitle = selectedOption.getAttribute('data-proalpha-title') || selectedOption.dataset?.proalphaTitle || '';\n                                                const artnum = selectedOption.getAttribute('data-artnum') || selectedOption.dataset?.artnum || '';\n                                                const title = (ptitle && ptitle.trim()) || (selectedOption.textContent || '').trim();\n                                                var2 = artnum ? `${artnum} - ${title}` : title;\n                                            }\n                                        }\n                                    }\n                                }\n\n                            // Default Configuration\n                            } else {\n                                // Watches\n                                if (ao.isWatch) {\n                                    var1 = ao.defaultStrap.artnum + \" - \" + ao.defaultStrap.proalphatitle;\n                                    var2 = ao.defaultClosure.artnum + \" - \" + ao.defaultClosure.proalphatitle;\n                                }\n\n                                // Set Articles\n                                if (ao.isSetArticle) {\n                                    var1 = ao.setItems[0].artnum + \" - \" + ao.setItems[0].proalphatitle;\n                                }\n\n                                // Straps\n                                if (ao.isStrap) {\n                                    const req = (typeof ao.requiredForWatchProAlphaTitle === 'string')\n                                        ? ao.requiredForWatchProAlphaTitle.trim()\n                                        : '';\n                                    var1 = req && ao.requiredForWatch !== 'no_selection' ?\n                                        ao.requiredForWatchArtNum + \" - \" + req :\n                                        'Ohne Auswahl';\n                                    var2 = \"Ohne Schließe\";\n                                }\n\n                            }\n\n                            // Product assembly\n                            // Fallback: Set && Uhren mit Massivbänder kriegen Standardschließe.\n                            var2 = (typeof var2 === \"string\" ? var2.trim() : \"\");\n                            if ((ao.isWatch || ao.isSetArticle) && !var2) {\n                                var2 = \"Standardschließe\";\n                            }\n\n                            // Build product\n                            let product = {\n                                id: ao.artnum,\n                                name: ao.proalphatitle,\n                                price: Number(ao.netPrice).toFixed(2),\n                                currency: 'EUR',\n                                category: [productCategory, '', '', 'Merkliste'],\n                            };\n\n                            // If strap adjust the name: artnum + proalphatitle\n                            if (ao.isStrap) {\n                                product.name = ao.artnum + \" - \" + ao.proalphatitle;\n                            }\n\n                            if (!ao.isClosure && ao.isWatch || ao.isSetArticle || ao.isStrap) {\n                                product.variants = {\n                                    'var1': var1,\n                                    'var2': var2\n                                }\n                                if (var3 !== undefined) product.variants.var3 = var3;\n                                if (var4 !== undefined) product.variants.var4 = var4;\n                                if (var5 !== undefined) product.variants.var5 = var5;\n                            }\n\n                            try {\n                                if (!product.id || product.id.trim() === '') return;\n                                etCommerce.sendEvent('insertToWatchlist', product, 1);\n                            } catch (e) {\n                                console.error(\"Error sending eTracker event:\", e);\n                            }\n                        }\n                    }\n                });\n                btn.dataset.trackingBound = \"true\";\n            }\n        });\n    }\n\n    bindAddToWishlistListeners();\n    const observer = new MutationObserver(mutations => {\n        mutations.forEach(mutation => {\n            if (mutation.type === 'attributes' && mutation.attributeName === 'class') {\n                if (mutation.target.classList.contains('is--add-to-wishlist')) {\n                    bindAddToWishlistListeners();\n                }\n            }\n            if (mutation.type === 'childList') {\n                bindAddToWishlistListeners();\n            }\n        });\n    });\n    observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['class'] });\n\n    // List-Category\n    function consumeWishlistCookieAndBuildProduct() {\n        const p = readWishlistTracking();\n        if (!p) return null;\n\n        const product = {\n            id: p.id,\n            name: p.title,\n            price: Number(p.netPrice).toFixed(2),\n            currency: 'EUR',\n            category: [p.category || '', '', '', 'Merkliste']\n        };\n\n        const variants = {};\n        if (p.var1) variants.var1 = p.var1;\n        if (p.var2) variants.var2 = p.var2;\n        if (Object.keys(variants).length) product.variants = variants;\n\n        return product;\n    }\n\n    // After clicks on \"add to wishlist\" (list icons), wait for state flip to on-wishlist then read cookie\n    document.body.addEventListener('click', function (evt) {\n        const btn = evt.target.closest('.e-link__icon.is--add-to-wishlist');\n        if (!btn) return;\n\n        let fired = false;\n        function startPollOnce() {\n            if (fired) return;\n            fired = true;\n            let tries = 0;\n            (function poll() {\n                const product = consumeWishlistCookieAndBuildProduct();\n                const ul = btn.closest('ul');\n                if (product && ul && !ul.classList.contains('is--horizontal')) {\n                    try {\n                        if (document.tracking?.viewController === 'details') return;\n                        if (!product.id || product.id.trim() === '') return;\n                        etCommerce.sendEvent('insertToWatchlist', product, 1);\n                    } catch (e) {\n                        console.error(\"Error sending eTracker event:\", e);\n                    }\n                    return;\n                }\n                if (++tries < 25) setTimeout(poll, 120);\n            })();\n        }\n\n        const mo = new MutationObserver((mutations) => {\n            for (const m of mutations) {\n                if (m.type === 'attributes' && m.attributeName === 'class') {\n                    if (btn.classList.contains('is--on-wishlist')) {\n                        mo.disconnect();\n                        startPollOnce();\n                        break;\n                    }\n                }\n            }\n        });\n        mo.observe(btn, { attributes: true, attributeFilter: ['class'] });\n\n        // Fallback: if the class toggled immediately or DOM replaced\n        setTimeout(() => {\n            if (btn.classList.contains('is--on-wishlist')) {\n                try { mo.disconnect(); } catch(_) {}\n                startPollOnce();\n            }\n        }, 50);\n    }, true);\n}\n\nfunction trackInsertToBasketFromWishlist() {\n    const selector = '.js--add-wishlist-item-to-basket';\n\n    function bind() {\n        document.querySelectorAll(selector).forEach(btn => {\n            if (btn.dataset.trackingBound) return;\n\n            btn.addEventListener('click', () => {\n                // Collect hidden inputs from the closest form and send them with the request\n                const form = btn.closest('form');\n                const params = new URLSearchParams();\n\n                function getVal(name) {\n                    if (!form) return '';\n                    const el = form.querySelector(`[name=\"${name}\"]`);\n                    if (!el) return '';\n                    if (el.type === 'checkbox' || el.type === 'radio') return el.checked ? el.value : '';\n                    return (el.value || '').trim();\n                }\n\n                const stoken = getVal('stoken');\n                const anid = getVal('anid');\n                const watchId = getVal('watchId');\n                const selectedStrapId = getVal('selectedStrapId');\n                const selectedClosureId = getVal('selectedClosureId');\n                const requiredForWatch = getVal('persparam[requiredForWatch]');\n                const claspForStrap = getVal('persparam[claspForStrap]');\n                const price = getVal('price');\n\n                // compute aid: prefer watchId when present, otherwise anid\n                const aid = getVal('watchId') || getVal('aid');\n\n                if (stoken) params.append('stoken', stoken);\n                if (aid) params.append('aid', aid);\n                if (requiredForWatch) params.append('persparam[requiredForWatch]', requiredForWatch);\n                if (claspForStrap) params.append('persparam[claspForStrap]', claspForStrap);\n                if (selectedStrapId) params.append('selectedStrapId', selectedStrapId);\n                if (selectedClosureId) params.append('selectedClosureId', selectedClosureId);\n                if (price) params.append('price', price);\n\n                // chosenOptions[] (if present)\n                if (form) {\n                    form.querySelectorAll('[name=\"chosenOptions[]\"]').forEach(el => {\n                        const isChoice = (el.type === 'checkbox' || el.type === 'radio');\n                        const shouldInclude = !isChoice || el.checked;\n                        const v = (el.value || '').trim();\n                        if (shouldInclude && v) params.append('chosenOptions[]', v);\n                    });\n                }\n\n                fetch(`/index.php?cl=trackingajaxcontroller&fnc=getTrackingObjectForWhishlist`, {\n                    method: 'POST',\n                    headers: {\n                        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'\n                    },\n                    body: params.toString()\n                })\n                    .then(r => r.json())\n                    .then(data => {\n                        const product = {\n                            id: data.id,\n                            name: data.title,\n                            currency: 'EUR',\n                            price: Number(data.price).toFixed(2),\n                            category: [data.category, \"\", \"\", \"Merkliste\"],\n                            variants: {}\n                        };\n\n                        const addIfPresent = (key, value) => {\n                            const isString = typeof value === 'string';\n                            const exists = value !== undefined && value !== null;\n                            const notEmpty = isString ? value.trim() !== '' : true;\n                            if (exists && notEmpty) product.variants[key] = value;\n                        };\n\n                        addIfPresent('var1', data.var1);\n                        addIfPresent('var2', data.var2);\n                        addIfPresent('var3', data.var3);\n                        addIfPresent('var4', data.var4);\n                        addIfPresent('var5', data.var5);\n\n                        // If var1 exists and var2 is empty/null/undefined, set var2 to \"Standardschließe\"\n                        if (product.variants?.var1 && !product.variants?.var2) product.variants.var2 = \"Standardschließe\";\n\n                        if (Object.keys(product.variants).length === 0) {\n                            delete product.variants;\n                        }\n\n                        try {\n                            etCommerce.sendEvent('insertToBasket', product, 1);\n\n                            if (product.variants?.var1 !== undefined && !product.category?.includes(\"Armbänder & Zubehör\")) {\n                                _etracker.sendEvent(new et_UserDefinedEvent('Armband', 'Konfigurator', 'Auswahl', product.variants.var1));\n                            }\n                            if (product.variants?.var2 !== undefined && !product.category?.includes(\"Armbänder & Zubehör\")) {\n                                _etracker.sendEvent(new et_UserDefinedEvent('Schließen', 'Konfigurator', 'Auswahl', product.variants.var2));\n                            }\n                            ['var3', 'var4', 'var5'].forEach(v => {\n                                if (product?.variants?.[v] !== undefined) {\n                                    _etracker.sendEvent(new et_UserDefinedEvent('Optionen', 'Konfigurator', 'Auswahl', product.variants[v]));\n                                }\n                            });\n                        } catch (e) {\n                            console.error(\"Sending insertToBasket Event failed!\");\n                        }\n                    })\n                    .catch(e => console.error('Error fetching wishlist insertToBasket object:', e));\n            });\n\n            btn.dataset.trackingBound = 'true';\n        });\n    }\n\n    bind();\n\n    const mo = new MutationObserver(() => bind());\n    mo.observe(document.body, { childList: true, subtree: true });\n}\n\nfunction readCookie(name) {\n    const pairs = document.cookie ? document.cookie.split(';') : [];\n    for (let i = 0; i < pairs.length; i++) {\n        const part = pairs[i].trim();\n        const eqIdx = part.indexOf('=');\n        if (eqIdx === -1) continue;\n        const k = part.substring(0, eqIdx);\n        if (k === name) return part.substring(eqIdx + 1);\n    }\n    return null;\n}\n\nfunction eraseCookie(name) {\n    document.cookie = name + '=; Path=/; Max-Age=0; SameSite=Lax';\n}\n\nfunction readWishlistTracking() {\n    const val = readCookie('wl_last');\n    if (!val) return null;\n    try {\n        const decoded = decodeURIComponent(val);\n        const json = atob(decoded);\n        const payload = JSON.parse(json);\n        eraseCookie('wl_last');\n        return payload;\n    } catch (e) {\n        eraseCookie('wl_last');\n        return null;\n    }\n}\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/etracker.js?");/***/}),/***/"./source/out/sinn/src/js/modules/focusTrap.js":(/*!*****************************************************!*\
  !*** ./source/out/sinn/src/js/modules/focusTrap.js ***!
  \*****************************************************/ /***/function sourceOutSinnSrcJsModulesFocusTrapJs(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   cleanupAllFocusTraps: () => (/* binding */ cleanupAllFocusTraps),\n/* harmony export */   cleanupFocusTrap: () => (/* binding */ cleanupFocusTrap),\n/* harmony export */   createFocusTrap: () => (/* binding */ createFocusTrap)\n/* harmony export */ });\n// -----------------------------------------------------------------------------\n// focusTrap.js\n// Generic focus trap\n// -----------------------------------------------------------------------------\n\n// Global registry to track all active focus traps\nconst activeFocusTraps = new Map();\n\nconst createFocusTrap = function(element) {\n    // Clean up any existing focus trap on this element\n    cleanupFocusTrap(element);\n    \n    const focusableElements = element.querySelectorAll(\n        'button, [href], input:not([type=\"hidden\"]), select, textarea, [tabindex]'\n    );\n\n    const filteredElements = Array.from(focusableElements).filter((element) => {\n        // Filter out elements with tabindex=\"-1\"\n        if (element.hasAttribute('tabindex') && element.getAttribute('tabindex') === '-1') {\n            return false;\n        }\n        \n        let styleElement = window.getComputedStyle(element, null);\n        return styleElement.getPropertyValue(\"display\") !== 'none';\n    });\n\n    const firstFocusable = filteredElements[0];\n    const lastFocusable = filteredElements[filteredElements.length - 1];\n\n    firstFocusable && firstFocusable.focus({ focusVisible: false });\n\n    // Define the keydown handler function so we can remove it later\n    const keydownHandler = function(e) {\n        if (e.key === 'Tab' || e.keyCode === 9) {\n            if (e.shiftKey) { // Shift + Tab\n                if (document.activeElement === firstFocusable) {\n                    e.preventDefault();\n                    lastFocusable && lastFocusable.focus({ focusVisible: true });\n                }\n            } else { // Tab\n                if (document.activeElement === lastFocusable) {\n                    e.preventDefault();\n                    firstFocusable && firstFocusable.focus({ focusVisible: true });\n                }\n            }\n        }\n        //force click on focused element\n        if (e.key === 'Enter' || e.keyCode === 13) {\n            e.target.click();\n        }\n    };\n\n    element.addEventListener('keydown', keydownHandler);\n    \n    // Store the cleanup function in the global registry\n    activeFocusTraps.set(element, keydownHandler);\n\n    // Return cleanup function to remove the event listener\n    return function cleanup() {\n        element.removeEventListener('keydown', keydownHandler);\n        activeFocusTraps.delete(element);\n        //console.log('Focus trap cleaned up.');\n    };\n}\n\n// Function to clean up a specific focus trap\nconst cleanupFocusTrap = function(element) {\n    const existingHandler = activeFocusTraps.get(element);\n    if (existingHandler) {\n        element.removeEventListener('keydown', existingHandler);\n        activeFocusTraps.delete(element);\n        //console.log('Existing focus trap cleaned up.');\n    }\n}\n\n// Function to clean up all focus traps\nconst cleanupAllFocusTraps = function() {\n    activeFocusTraps.forEach((handler, element) => {\n        element.removeEventListener('keydown', handler);\n    });\n    activeFocusTraps.clear();\n    //console.log('All focus traps cleaned up.');\n}\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/focusTrap.js?");/***/}),/***/"./source/out/sinn/src/js/modules/formError.js":(/*!*****************************************************!*\
  !*** ./source/out/sinn/src/js/modules/formError.js ***!
  \*****************************************************/ /***/function sourceOutSinnSrcJsModulesFormErrorJs(){eval("const form = document.querySelector('.js--formvalidate');\nconst submit = document.querySelector('.js--formvalidate-submit') || document.querySelector('.js--formvalidate button[type=\"submit\"]');\nconst errorContent = document.querySelector('.js--formvalidate-error');\n\nif(form) {\n    form.addEventListener('submit', function(e) {\n        e.preventDefault()\n    })\n\n    submit.addEventListener('click', function() {\n        if( form.checkValidity() ) {\n            form.submit();\n        } else {\n            errorContent.style.display = 'block';\n            errorContent.style.visibility = 'visible';\n        }\n    })\n}\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/formError.js?");/***/}),/***/"./source/out/sinn/src/js/modules/formValidation.js":(/*!**********************************************************!*\
  !*** ./source/out/sinn/src/js/modules/formValidation.js ***!
  \**********************************************************/ /***/function sourceOutSinnSrcJsModulesFormValidationJs(){eval("document.addEventListener(\"DOMContentLoaded\", function () {\n    const forms = document.querySelectorAll('.js--dotValidate');\n\n    if (forms) {\n        //console.log('Form validation is active');\n        forms.forEach(function (form) {\n            let firstErrorField = null;\n\n            form.addEventListener('submit', function (event) {\n                const requiredInputs = form.querySelectorAll('.e-form__row:not(.is--hidden) input[required]:not([type=\"checkbox\"])');\n                const requiredTextarea = form.querySelectorAll('.e-form__row:not(.is--hidden) textarea[required]');\n                const requiredCheckbox = form.querySelectorAll('.e-form__row:not(.is--hidden) input[required][type=\"checkbox\"]');\n                const requiredSelect = form.querySelectorAll('.e-form__row:not(.is--hidden) select[required]');\n\n                let isValid = true;\n\n                requiredInputs.forEach(function (field) {\n                    if (!field.value.trim()) {\n                        isValid = false;\n                        markAsError(field);\n                        if (!firstErrorField) {\n                            firstErrorField = field;\n                        }\n                    } else {\n                        markAsValid(field);\n                    }\n                });\n\n                requiredTextarea.forEach(function (textarea) {\n                    if (!textarea.value.trim()) {\n                        isValid = false;\n                        markAsError(textarea);\n                        if (!firstErrorField) {\n                            firstErrorField = textarea;\n                        }\n                    } else {\n                        markAsValid(textarea);\n                    }\n                });\n\n                requiredSelect.forEach(function (select) {\n                    if (select.value.trim() === '') {\n                        isValid = false;\n                        markAsError(select);\n                        if (!firstErrorField) {\n                            firstErrorField = select;\n                        }\n                    } else {\n                        markAsValid(select);\n                    }\n                });\n\n                requiredCheckbox.forEach(function (checkbox) {\n                    if (!checkbox.checked) {\n                        isValid = false;\n                        markAsError(checkbox);\n                        if (!firstErrorField) {\n                            firstErrorField = checkbox;\n                        }\n                    } else {\n                        markAsValid(checkbox);\n                    }\n                });\n\n                if (!isValid && firstErrorField) {\n                    event.preventDefault();\n                    firstErrorField.focus(); // Set focus on the first error field\n                }\n            });\n\n            // Add event listeners to remove error class on input/change\n            const allInputs = form.querySelectorAll('.e-form__row:not(.is--hidden) input, .e-form__row:not(.is--hidden) textarea, .e-form__row:not(.is--hidden) select, .e-form__row:not(.is--hidden) input[type=\"checkbox\"]');\n            allInputs.forEach(function (input) {\n                // Check if the input is a checkbox and has the required attribute\n                if (input.type && input.type.toLowerCase() === 'checkbox' && input.hasAttribute('required')) {\n                    input.addEventListener('change', function () {\n                        validateField(input);\n                    });\n                }\n\n                // Check if the input is a select element and has the required attribute\n                if (input.tagName.toLowerCase() === 'select' && input.hasAttribute('required')) {\n                    input.addEventListener('change', function () {\n                        validateField(input);\n                    });\n                }\n\n                // Add event listener to remove error class when the input is focused (except for checkboxes)\n                if (input.type && input.type.toLowerCase() !== 'checkbox') {\n                    input.addEventListener('focus', function () {\n                        markAsValid(input);\n                    });\n                }\n            });\n        });\n    }\n\n    function markAsError(element) {\n        var parentElement = element.closest('.e-form__wrap');\n        if (parentElement) {\n            parentElement.classList.add('is--error');\n            //parentElement.style.outline = '2px solid red';\n        }\n    }\n\n    function markAsValid(element) {\n        var parentElement = element.closest('.e-form__wrap');\n        if (parentElement) {\n            parentElement.classList.remove('is--error');\n            //parentElement.style.outline = '2px solid green';\n        }\n    }\n\n    function validateField(input) {\n        if (input.type && input.type.toLowerCase() === 'checkbox') {\n            if (input.checked) {\n                markAsValid(input);\n            } else {\n                markAsError(input);\n            }\n        } else if (input.tagName.toLowerCase() === 'select') {\n            if (input.value.trim() === '') {\n                markAsError(input);\n            } else {\n                markAsValid(input);\n            }\n        } else {\n            if (input.value.trim()) {\n                markAsValid(input);\n            } else {\n                markAsError(input);\n            }\n        }\n    }\n});\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/formValidation.js?");/***/}),/***/"./source/out/sinn/src/js/modules/input.js":(/*!*************************************************!*\
  !*** ./source/out/sinn/src/js/modules/input.js ***!
  \*************************************************/ /***/function sourceOutSinnSrcJsModulesInputJs(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var detect_autofill__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! detect-autofill */ \"./node_modules/detect-autofill/dist/detect-autofill.js\");\n/* harmony import */ var detect_autofill__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(detect_autofill__WEBPACK_IMPORTED_MODULE_0__);\n\n\nvar input = document.querySelectorAll('.e-form__wrap.is--input .e-form__input');\nvar filter = document.querySelectorAll('.c-refinelayer__filtergroup-item');\n\nif (filter) {\n\tfilter.forEach((item) => {\n\t\tif (item.querySelector('.c-refinelayer__filtergroup-checkbox').checked == true) {\n\t\t\titem.classList.add('js--active');\n\t\t}\n\n\t\titem.addEventListener('change', (event) => {\n\t\t\tif (!item.classList.contains('js--active')) {\n\t\t\t\tevent.stopPropagation();\n\t\t\t\titem.classList.add('js--active');\n\t\t\t} else {\n\t\t\t\tevent.stopPropagation();\n\t\t\t\titem.classList.remove('js--active');\n\t\t\t}\n\t\t});\n\t});\n}\n\nif (input) {\n\tinput.forEach((item) => {\n\t\tif (item.value.length != 0) {\n\t\t\titem.parentElement.classList.add('js--active');\n\t\t}\n\n\t\titem.addEventListener('onautocomplete', (event) => {\n\t\t\titem.parentElement.classList.add('js--active');\n\t\t});\n\n\t\titem.addEventListener('focusin', (event) => {\n\t\t\tif (event.currentTarget.value.length == 0) {\n\t\t\t\titem.parentElement.classList.add('js--active');\n\t\t\t}\n\t\t});\n\n\t\titem.addEventListener('focusout', (event) => {\n\t\t\tif (event.currentTarget.value.length == 0) {\n\t\t\t\titem.parentElement.classList.remove('js--active');\n\t\t\t}\n\t\t});\n\t});\n}\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/input.js?");/***/}),/***/"./source/out/sinn/src/js/modules/languageModal.js":(/*!*********************************************************!*\
  !*** ./source/out/sinn/src/js/modules/languageModal.js ***!
  \*********************************************************/ /***/function sourceOutSinnSrcJsModulesLanguageModalJs(){eval("// -----------------------------------------------------------------------------\n// languageModal.js\n// Language & country selection modal: wires triggers and AJAX updates.\n// Generic modal mechanics come from modal.js.\n// -----------------------------------------------------------------------------\n\n// Selectors\nconst SELECTORS = {\n    modal: '#languageModal',\n    triggers: '.js--language',\n    languageDropdown: '#selectShopLanguage',\n    countryDropdown: '#selectCountry',\n    csFormLabel: '#languageSelectionHeadline',\n    csCountry: '#csCountry',\n    csLang: '#csLang',\n    csConfirm: '#csConfirm',\n    form: 'form',\n};\n\n// Modal state\nconst langModalState = {\n    modalEl: null,\n    triggerEls: [],\n};\n\n// DOM Elements\nconst getDomElements = () => ({\n    languageDropdown: document.querySelector(SELECTORS.languageDropdown),\n    countryDropdown: document.querySelector(SELECTORS.countryDropdown),\n    csFormLabel: document.querySelector(SELECTORS.csFormLabel),\n    csCountry: document.querySelector(SELECTORS.csCountry),\n    csLang: document.querySelector(SELECTORS.csLang),\n    csConfirm: document.querySelector(SELECTORS.csConfirm),\n});\n\n// Language/Country AJAX wiring\nconst wireLanguageCountryAjax = () => {\n    const {\n        languageDropdown,\n        countryDropdown,\n        csFormLabel,\n        csCountry,\n        csLang,\n        csConfirm,\n    } = getDomElements();\n\n    if (!languageDropdown || !countryDropdown) return;\n\n    const hasOxidGlobals = Boolean(document.oxid && document.oxid.selfLink);\n\n    // Update country list + labels when language changes\n    languageDropdown.addEventListener('change', () => {\n        if (!hasOxidGlobals) return;\n\n        const selectedLangId = languageDropdown.value;\n        const url = `${document.oxid.selfLink}&cl=countryselectionajaxcontroller&fnc=handleLanguageSelectionAjax&lang=${encodeURIComponent(selectedLangId)}`;\n\n        fetch(url, { method: 'GET', headers: { 'X-Requested-With': 'XMLHttpRequest' } })\n        .then((resp) => resp.json())\n        .then((data) => {\n            if (!data || !data.success) return;\n\n            if (csFormLabel) csFormLabel.textContent = data.translations?.csFormLabel ?? '';\n            if (csCountry)   csCountry.textContent   = data.translations?.csCountry ?? '';\n            if (csLang)      csLang.textContent      = data.translations?.csLang ?? '';\n            if (csConfirm)   csConfirm.value         = data.translations?.csConfirm ?? '';\n\n            // Handle different response types based on user login status\n            if (data.usercountry) {\n                // User is logged in - update the fake select link content and label\n                const userCountryLinkEl = document.querySelector('a[aria-labelledby=\"current-country-label\"]');\n                if (userCountryLinkEl) {\n                    userCountryLinkEl.textContent = data.usercountry;\n                }\n                \n                // Update the label text for logged-in users\n                const currentCountryLabelEl = document.querySelector('#current-country-label');\n                if (currentCountryLabelEl && data.translations?.currentCountryLabel) {\n                    currentCountryLabelEl.textContent = data.translations.currentCountryLabel;\n                }\n            } else if (data.countries) {\n                // User is not logged in - populate the country dropdown\n                const countrySelectEl = document.querySelector(SELECTORS.countryDropdown);\n                if (!countrySelectEl) return;\n\n                const fragment = document.createDocumentFragment();\n                (data.countries || []).forEach((country) => {\n                    const optionEl = document.createElement('option');\n                    optionEl.value = country.id;\n                    optionEl.textContent = `${country.oxtitle} (${country.iso})`;\n                    if (String(country.id) === String(document.oxid?.selectedCountryId)) {\n                        optionEl.selected = true;\n                    }\n                    fragment.appendChild(optionEl);\n                });\n                countrySelectEl.replaceChildren(fragment);\n            }\n        })\n        .catch((err) => console.error('Language AJAX error:', err));\n    });\n\n    // Persist selected country server-side\n    countryDropdown.addEventListener('change', () => {\n        if (!hasOxidGlobals) return;\n\n        const selectedCountryId = countryDropdown.value;\n        document.oxid.selectedCountryId = selectedCountryId;\n\n        const url = `${document.oxid.selfLink}&cl=countryselectionajaxcontroller&fnc=handleCountrySelectionAjax&selectCountry=${encodeURIComponent(selectedCountryId)}`;\n\n        fetch(url, { method: 'GET', headers: { 'X-Requested-With': 'XMLHttpRequest' } })\n        .then((resp) => {\n            if (!resp.ok) throw new Error(`HTTP ${resp.status}`);\n        })\n        .catch((err) => console.warn('Could not save selected country:', err));\n    });\n};\n\n// Init\nconst initLanguageModal = () => {\n    // Restore pre-submit scroll position (when coming back from POST)\n    const savedScrollY = sessionStorage.getItem('scrollY');\n    if (savedScrollY) {\n        setTimeout(() => {\n        window.scrollTo(0, Number(savedScrollY));\n        sessionStorage.removeItem('scrollY');\n        }, 0);\n    }\n\n    langModalState.modalEl = document.querySelector(SELECTORS.modal);\n    if (!langModalState.modalEl) return;\n\n    // Wire language/country behavior\n    wireLanguageCountryAjax();\n\n    // Before submit, remember scroll position to restore on return\n    const modalForm = langModalState.modalEl.querySelector(SELECTORS.form);\n    if (modalForm) {\n        modalForm.addEventListener('submit', () => {\n        sessionStorage.setItem('scrollY', String(window.scrollY));\n        });\n    }\n};\n\ndocument.addEventListener('DOMContentLoaded', initLanguageModal);\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/languageModal.js?");/***/}),/***/"./source/out/sinn/src/js/modules/lazyload.js":(/*!****************************************************!*\
  !*** ./source/out/sinn/src/js/modules/lazyload.js ***!
  \****************************************************/ /***/function sourceOutSinnSrcJsModulesLazyloadJs(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   lazyContent: () => (/* binding */ lazyContent)\n/* harmony export */ });\n/* harmony import */ var vanilla_lazyload__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vanilla-lazyload */ \"./node_modules/vanilla-lazyload/dist/lazyload.min.js\");\n/* harmony import */ var vanilla_lazyload__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(vanilla_lazyload__WEBPACK_IMPORTED_MODULE_0__);\n\n\nconst lazyContent = new (vanilla_lazyload__WEBPACK_IMPORTED_MODULE_0___default())({\n\tuse_native: true,\n\telements_selector: '.lazy__load',\n\tclass_loading: 'lazy__load-loading',\n\tclass_loaded: 'lazy__load-loaded'\n});\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/lazyload.js?");/***/}),/***/"./source/out/sinn/src/js/modules/login.js":(/*!*************************************************!*\
  !*** ./source/out/sinn/src/js/modules/login.js ***!
  \*************************************************/ /***/function sourceOutSinnSrcJsModulesLoginJs(){eval("var loginForm = document.querySelector('#login');\n\nif (loginForm) {\n\tloginForm.addEventListener('submit', function (event) {\n\n\t\tevent.preventDefault();\n\n\t\tdocument.getElementById('login-error-box').innerHTML = '';\n\t\tdocument.getElementById('login-error-box').style.display = 'none';\n\n\t\t$.ajax({\n\t\t\tmethod: \"POST\",\n\t\t\turl: document.getElementById('ajaxTargetMB').value + \"cl=user&fnc=ajaxCheckIfUserExists&stoken=\" + document.getElementById('sessionTokenMB').value,\n\t\t\tdata: {\n\t\t\t\tusername: document.querySelector(\"[name='lgn_usr']\").value,\n\t\t\t\tpassword: document.querySelector(\"[name='lgn_pwd']\").value,\n\t\t\t},\n\t\t\tsuccess: function (ret) {\n\t\t\t\tif (ret.length) {\n\t\t\t\t\tdocument.getElementById('login-error-box').style.display = 'block';\n\t\t\t\t\tdocument.getElementById('login-error-box').innerHTML = ret;\n\t\t\t\t} else {\n\t\t\t\t\tloginForm.submit();\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t});\n}\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/login.js?");/***/}),/***/"./source/out/sinn/src/js/modules/miniBasketRenderer.js":(/*!**************************************************************!*\
  !*** ./source/out/sinn/src/js/modules/miniBasketRenderer.js ***!
  \**************************************************************/ /***/function sourceOutSinnSrcJsModulesMiniBasketRendererJs(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _minicartflapper__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./minicartflapper */ \"./source/out/sinn/src/js/modules/minicartflapper.js\");\n\n\ndocument.addEventListener('DOMContentLoaded', function () {\n    const miniBasketBtn = document.getElementById('miniBasketBtn');\n    if (miniBasketBtn) {\n        miniBasketBtn.addEventListener('click', function() {\n            // Recalculate Mini basket\n            fetch('/index.php?cl=minibasketcontroller&fnc=recalculateMiniBasket')\n                .then(response => response.text())\n                .then(data => {\n                    var miniBasketContainer = document.querySelector('.c-minibasket__wrapper');\n                    if (miniBasketContainer) {\n                        miniBasketContainer.innerHTML = data;\n                        (0,_minicartflapper__WEBPACK_IMPORTED_MODULE_0__.addFlapper)();\n                    }\n                })\n                .catch(error => {\n                    console.error('Error recalculating mini basket: ', error);\n                });\n     \n        });       \n    }  \n});    \n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/miniBasketRenderer.js?");/***/}),/***/"./source/out/sinn/src/js/modules/minicartflapper.js":(/*!***********************************************************!*\
  !*** ./source/out/sinn/src/js/modules/minicartflapper.js ***!
  \***********************************************************/ /***/function sourceOutSinnSrcJsModulesMinicartflapperJs(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   addFlapper: () => (/* binding */ addFlapper)\n/* harmony export */ });\n/* harmony import */ var animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! animejs/lib/anime.es.js */ \"./node_modules/animejs/lib/anime.es.js\");\n\n\nconst cubicBezier = 'cubicBezier(.40,.05,.20,.90)';\n\n/**\n * Initialisiert das Flapper-Feature für alle Minibasket-Items\n */\nconst addFlapper = () => {\n    const minibasketItems = document.querySelectorAll('.c-minibasket__item');\n\n    if (!minibasketItems.length) return;\n\n    minibasketItems.forEach(initMinibasketItem);\n};\n\n/**\n * Initialisiert ein einzelnes Minibasket-Item\n * @param {HTMLElement} item - Das Minibasket-Item\n */\nconst initMinibasketItem = (item) => {\n    const content = item.querySelector('.c-minibasket__config');\n    const innerContent = item.querySelector('.c-minibasket__inner');\n    const header = item.querySelector('.js--minibasketflapper');\n\n    if (!header || !innerContent) return;\n\n    header.addEventListener('click', () => toggleMinibasket(item, content, innerContent, header));\n    window.addEventListener('resize', () => adjustHeightOnResize(item, content, innerContent));\n};\n\n/**\n * Toggles die Sichtbarkeit des Minibasket-Contents\n * @param {HTMLElement} minibasket - Das Minibasket-Item\n * @param {HTMLElement} content - Der ausklappbare Content\n * @param {HTMLElement} innerContent - Der innere Content (für die Höhe)\n * @param {HTMLElement} header - Der Header, der als Trigger dient\n */\nconst toggleMinibasket = (minibasket, content, innerContent, header) => {\n    const isActive = minibasket.classList.contains('js--active');\n    const minibasketContentHeight = innerContent.scrollHeight + 'px';\n\n    if (isActive) {\n        collapseContent(minibasket, content, header);\n    } else {\n        expandContent(minibasket, content, header, minibasketContentHeight);\n    }\n};\n\n/**\n * Animiert das Ausklappen des Contents\n * @param {HTMLElement} minibasket - Das Minibasket-Item\n * @param {HTMLElement} content - Der ausklappbare Content\n * @param {HTMLElement} header - Der Header, der als Trigger dient\n * @param {string} height - Die Höhe des ausklappbaren Contents\n */\nconst expandContent = (minibasket, content, header, height) => {\n    minibasket.classList.add('js--active', 'js--pointerevent');\n    header.classList.add('is--open');\n\n    (0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])({\n        targets: content,\n        height: [0, height],\n        duration: 350,\n        easing: cubicBezier\n    });\n};\n\n/**\n * Animiert das Einklappen des Contents\n * @param {HTMLElement} minibasket - Das Minibasket-Item\n * @param {HTMLElement} content - Der ausklappbare Content\n * @param {HTMLElement} header - Der Header, der als Trigger dient\n */\nconst collapseContent = (minibasket, content, header) => {\n    (0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])({\n        targets: content,\n        height: '0',\n        duration: 350,\n        easing: cubicBezier,\n        complete: () => {\n            minibasket.classList.remove('js--active', 'js--pointerevent');\n            header.classList.remove('is--open');\n        }\n    });\n};\n\n/**\n * Passt die Höhe des ausklappbaren Contents bei Fensteränderungen an\n * @param {HTMLElement} minibasket - Das Minibasket-Item\n * @param {HTMLElement} content - Der ausklappbare Content\n * @param {HTMLElement} innerContent - Der innere Content (für die Höhe)\n */\nconst adjustHeightOnResize = (minibasket, content, innerContent) => {\n    if (minibasket.classList.contains('js--active')) {\n        content.style.height = innerContent.scrollHeight + 'px';\n    }\n};\n\naddFlapper();\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/minicartflapper.js?");/***/}),/***/"./source/out/sinn/src/js/modules/modal.js":(/*!*************************************************!*\
  !*** ./source/out/sinn/src/js/modules/modal.js ***!
  \*************************************************/ /***/function sourceOutSinnSrcJsModulesModalJs(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   closeLayer: () => (/* binding */ closeLayer),\n/* harmony export */   openLayer: () => (/* binding */ openLayer)\n/* harmony export */ });\n/* harmony import */ var animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! animejs/lib/anime.es.js */ \"./node_modules/animejs/lib/anime.es.js\");\n/* harmony import */ var _focusTrap__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./focusTrap */ \"./source/out/sinn/src/js/modules/focusTrap.js\");\n// -----------------------------------------------------------------------------\n// modal.js\n// Generic modal controller with animation + focus management\n// -----------------------------------------------------------------------------\n\n\n\n\nconst EASE_STANDARD = 'cubicBezier(.40,.05,.20,.90)';\nconst EASE_OPACITY  = 'easeInOutQuad';\n\nconst DURATION_FAST = 650;\nconst DURATION_BG   = 1000;\n\nconst CLASS_ACTIVE     = 'js--active';\nconst CLASS_NO_POINTER = 'js--pointerevent';\n\n/**\n * Per-layer runtime state stored in a WeakMap\n * {\n *   lastFocusedEl: HTMLElement|null,\n *   trapInitialized: boolean,\n *   escHandler: Function|null,\n *   backdropHandler: Function|null,\n *   isAnimating: boolean,\n *   layerClickHandler: Function|null\n * }\n */\nconst modalStateMap = new WeakMap();\n\nfunction ensureLayerState(layerEl) {\n    if (!modalStateMap.has(layerEl)) {\n        modalStateMap.set(layerEl, {\n            lastFocusedEl: null,\n            trapInitialized: false,\n            escHandler: null,\n            backdropHandler: null,\n            isAnimating: false,\n            layerClickHandler: null,\n        });\n    }\n    return modalStateMap.get(layerEl);\n}\n\n// DOM parts inside a layer we animate or interact with\nfunction getLayerParts(layerEl) {\n    return {\n        bg: layerEl.querySelector('.o-modal__background'),\n        innerBg: layerEl.querySelector('.o-modal__inner-background'),\n        closeBtn: layerEl.querySelector('.o-modal__inner-close'),\n        closeStripes: layerEl.querySelectorAll('.o-modal__inner-close--stripe'),\n        contents: layerEl.querySelectorAll('.o-modal__header, .o-modal__body, .o-modal__footer, .o-modal__contents')\n    };\n}\n\n// Animation\nfunction runAnimation(targets, cfg) {\n    if (!targets) return;\n    const many = NodeList.prototype.isPrototypeOf(targets) || Array.isArray(targets);\n    if (many && !targets.length) return;\n    (0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])({ targets, ...cfg });\n}\n\n// Always initialize focus trap per layer open\nfunction initFocusTrapPerOpen(layerEl) {\n    try { (0,_focusTrap__WEBPACK_IMPORTED_MODULE_1__.createFocusTrap)(layerEl); } catch {}\n}\n\n// Delegate close button clicks on the layer container\nfunction delegateCloseButtonClicks(layerEl) {\n    const state = ensureLayerState(layerEl);\n    if (state.layerClickHandler) return;\n\n    state.layerClickHandler = (ev) => {\n        const btn = ev.target.closest?.('.o-modal__inner-close');\n        if (!btn) return;\n        ev.preventDefault();\n        closeLayer(layerEl);\n    };\n\n    layerEl.addEventListener('click', state.layerClickHandler);\n}\n\nfunction removeCloseButtonDelegation(layerEl) {\n    const state = ensureLayerState(layerEl);\n    if (state.layerClickHandler) {\n        layerEl.removeEventListener('click', state.layerClickHandler);\n        state.layerClickHandler = null;\n    }\n}\n\n// ESC & backdrop\nfunction bindEscClose(layerEl) {\n    const state = ensureLayerState(layerEl);\n    if (state.escHandler || layerEl.getAttribute('data-esc-close') === 'false') return;\n\n    state.escHandler = (ev) => {\n        if (ev.key === 'Escape') {\n            ev.preventDefault();\n            closeLayer(layerEl);\n        }\n    };\n    document.addEventListener('keydown', state.escHandler);\n}\n\nfunction unbindEscClose(layerEl) {\n    const state = ensureLayerState(layerEl);\n    if (!state.escHandler) return;\n    document.removeEventListener('keydown', state.escHandler);\n    state.escHandler = null;\n}\n\nfunction bindBackdropClose(layerEl) {\n    const state = ensureLayerState(layerEl);\n    const { bg } = getLayerParts(layerEl);\n    if (!bg || layerEl.getAttribute('data-backdrop-close') === 'false' || state.backdropHandler) return;\n\n    state.backdropHandler = (ev) => {\n        if (ev.target === bg) closeLayer(layerEl);\n    };\n    bg.addEventListener('click', state.backdropHandler);\n}\n\nfunction unbindBackdropClose(layerEl) {\n    const state = ensureLayerState(layerEl);\n    const { bg } = getLayerParts(layerEl);\n    if (bg && state.backdropHandler) {\n        bg.removeEventListener('click', state.backdropHandler);\n        state.backdropHandler = null;\n    }\n}\n\n// ARIA / visibility\nfunction showLayer(layerEl) {\n    layerEl.style.opacity = '1';\n    layerEl.style.visibility = 'visible';\n    layerEl.classList.add(CLASS_ACTIVE);\n    layerEl.setAttribute('role', 'dialog');\n    layerEl.setAttribute('aria-modal', 'true');\n    layerEl.removeAttribute('aria-hidden');\n}\n\nfunction hideLayer(layerEl) {\n    layerEl.style.opacity = '0';\n    layerEl.style.visibility = 'hidden';\n    layerEl.classList.remove(CLASS_ACTIVE);\n    layerEl.setAttribute('aria-hidden', 'true');\n    layerEl.removeAttribute('aria-modal');\n}\n\n// Open\nfunction openLayer(layerEl, triggerEl) {\n    const { bg, innerBg, closeStripes, contents } = getLayerParts(layerEl);\n    const state = ensureLayerState(layerEl);\n    if (state.isAnimating || layerEl.classList.contains(CLASS_ACTIVE)) return;\n\n    state.isAnimating = true;\n    state.lastFocusedEl = (triggerEl && triggerEl.isConnected) ? triggerEl : (document.activeElement || null);\n\n    // Temporarily block pointer events while opening\n    layerEl.classList.add(CLASS_NO_POINTER);\n\n    // Make visible\n    showLayer(layerEl);\n\n    // Backdrop\n    const backdropCloses = layerEl.getAttribute('data-backdrop-close') !== 'false';\n    if (bg) bg.style.pointerEvents = backdropCloses ? 'auto' : 'none';\n    if (backdropCloses) bindBackdropClose(layerEl); else unbindBackdropClose(layerEl);\n\n    // Focus trap / ESC / delegated close\n    initFocusTrapPerOpen(layerEl);\n    bindEscClose(layerEl);\n    delegateCloseButtonClicks(layerEl);\n\n    // Initial state for content pieces\n    contents.forEach((el) => { if (el) el.style.opacity = '0'; });\n    closeStripes.forEach((el) => { if (el) el.style.opacity = '0'; });\n\n    // Animations\n    runAnimation(bg, { opacity: ['0', '1'], duration: DURATION_BG, easing: EASE_OPACITY });\n\n    runAnimation(innerBg, {\n        scaleY: ['0', '1'],\n        duration: DURATION_FAST,\n        easing: EASE_STANDARD,\n        complete: () => {\n            runAnimation(closeStripes, { opacity: ['0','1'], duration: DURATION_FAST, easing: EASE_OPACITY });\n            runAnimation(contents, {\n                opacity: ['0','1'],\n                duration: DURATION_FAST,\n                easing: EASE_OPACITY,\n                complete: () => {\n                    state.isAnimating = false;\n                    layerEl.classList.remove(CLASS_NO_POINTER);\n                }\n            });\n        }\n    });\n}\n\n// Close\nfunction closeLayer(layerEl) {\n    const { bg, innerBg, closeStripes, contents } = getLayerParts(layerEl);\n    const state = ensureLayerState(layerEl);\n    if (state.isAnimating || !layerEl.classList.contains(CLASS_ACTIVE)) return;\n\n    state.isAnimating = true;\n    layerEl.classList.add(CLASS_NO_POINTER);\n\n    runAnimation(closeStripes, { opacity: ['1','0'], duration: DURATION_FAST, easing: EASE_OPACITY });\n    runAnimation(contents, {\n        opacity: ['1','0'],\n        duration: DURATION_FAST,\n        easing: EASE_OPACITY,\n        complete: () => {\n            runAnimation(innerBg, { scaleY: ['1','0'], duration: DURATION_FAST, easing: EASE_STANDARD });\n        }\n    });\n\n    runAnimation(bg, {\n        opacity: ['1','0'],\n        duration: DURATION_FAST,\n        delay: DURATION_FAST,\n        easing: EASE_OPACITY,\n        complete: () => {\n            unbindBackdropClose(layerEl);\n            if (bg) bg.style.pointerEvents = 'none';\n\n            hideLayer(layerEl);\n            state.isAnimating = false;\n\n            // Focus trap remains, remove ESC + delegation\n            unbindEscClose(layerEl);\n            removeCloseButtonDelegation(layerEl);\n\n            // Restore focus to opener\n            let toRefocus = (state.lastFocusedEl && state.lastFocusedEl.isConnected) ? state.lastFocusedEl : null;\n            state.lastFocusedEl = null;\n\n            if (toRefocus?.focus) {\n                requestAnimationFrame(() => {\n                    try { toRefocus.focus({ preventScroll: true }); } catch {}\n                });\n            }\n        }\n    });\n}\n\n// Triggers\nfunction setupModalTrigger(triggerEl) {\n    triggerEl.addEventListener('click', (ev) => {\n        ev.preventDefault();\n        const selector = triggerEl.getAttribute('data-modal-target');\n        const layerEl = selector ? document.querySelector(selector) : null;\n        if (layerEl) openLayer(layerEl, triggerEl);\n    });\n}\n\ndocument.addEventListener('DOMContentLoaded', () => {\n    document\n    .querySelectorAll('[data-modal-target]')\n    .forEach(setupModalTrigger);\n\n    // Adopt already-visible layers (e.g., server-side active or forced modal)\n    document\n    .querySelectorAll('.o-modal.js--active, .o-modal.is--visible')\n    .forEach((layerEl) => {\n        const { bg } = getLayerParts(layerEl);\n\n        showLayer(layerEl);\n        layerEl.classList.add(CLASS_NO_POINTER);\n\n        const backdropCloses = layerEl.getAttribute('data-backdrop-close') !== 'false';\n        if (bg) bg.style.pointerEvents = backdropCloses ? 'auto' : 'none';\n        if (backdropCloses) bindBackdropClose(layerEl); else unbindBackdropClose(layerEl);\n\n        initFocusTrapPerOpen(layerEl);\n        bindEscClose(layerEl);\n        delegateCloseButtonClicks(layerEl);\n\n        requestAnimationFrame(() => {\n            try { layerEl.focus({ preventScroll: true }); } catch {}\n            layerEl.classList.remove(CLASS_NO_POINTER);\n        });\n    });\n});\n\n\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/modal.js?");/***/}),/***/"./source/out/sinn/src/js/modules/navigationDesktop.js":(/*!*************************************************************!*\
  !*** ./source/out/sinn/src/js/modules/navigationDesktop.js ***!
  \*************************************************************/ /***/function sourceOutSinnSrcJsModulesNavigationDesktopJs(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! animejs/lib/anime.es.js */ \"./node_modules/animejs/lib/anime.es.js\");\n/* harmony import */ var _navigationDesktopImages__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./navigationDesktopImages */ \"./source/out/sinn/src/js/modules/navigationDesktopImages.js\");\n\n\n\n// --- Animate Flyout :: Desktop Menu\nvar logo = document.querySelector('.c-logo');\nvar nav = document.querySelector('.c-navigation');\nconst navBody = document.querySelector('body');\nconst secondLevelScroller = document.querySelectorAll('.c-flyout__scroller');\nvar navItems = document.querySelectorAll('.c-navigation__item.has--child, .c-navigation__burger');\nvar flyoutFirstItems = document.querySelectorAll('.c-flyout__column .c-flyout__menu--item.has--child');\nvar flyoutItems = document.querySelectorAll('.c-mobilenav, .c-search, .c-login, .c-retailer, .c-cart');\nvar cubicBezier = 'cubicBezier(.4, .05, .2, .9)';\nvar mobileMenuItems = document.querySelectorAll('.c-mobilemenu__item');\nvar closeBtn = document.querySelectorAll('.js--flyout-close');\nvar navProgress = document.querySelector('.c-flyout__progress');\n\n\n// Navigate through each navigation item\nconst handleNavFlyout = function (event) {\n    var navItemData = event.currentTarget.getAttribute('data-target');\n    var navItemDataTarget = document.querySelector('.c-flyout[data-flyout=\"' + navItemData + '\"]');\n    var firstFocusLink = navItemDataTarget.querySelector('a');\n    var item = event.currentTarget.parentNode;\n\n    event.preventDefault();\n\n    navItems.forEach(function (item) {\n        item.classList.remove('js--active');\n        item.querySelector('.main-navi-link').setAttribute('aria-expanded', false);\n    });\n\n    item.classList.add('js--active');\n    event.currentTarget.setAttribute('aria-expanded', true);\n    nav.classList.remove('on-second-level');\n\n    // If flyout visible\n    if (navItemDataTarget.style.display === 'block') {\n        event.currentTarget.setAttribute('aria-expanded', false);\n\n        // Animate background\n        (0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])({\n            targets: '.c-navigation .c-flyout__background',\n            opacity: '0',\n            duration: 1000,\n            easing: 'easeInOutQuad',\n            complete: function () {\n                navItemDataTarget.style.display = 'none';\n                nav.classList.remove('js--pointerevent');\n                document.querySelector('.c-navigation .c-flyout__background').style.display = 'none';\n            },\n            begin: function () {\n                nav.classList.add('js--pointerevent');\n                document.querySelector('.c-navigation__item.has--child.js--active, .c-navigation__burger.js--active').classList.remove('js--active');\n            }\n        })\n\n        // Animate progress background\n        ;(0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])({\n            targets: '.c-navigation .c-flyout__progress',\n            width: '0%',\n            duration: 1000,\n            easing: cubicBezier\n        })\n\n        // Animate first level items\n        ;(0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])({\n            targets: '.c-flyout[data-flyout=\"' + navItemData + '\"] .c-flyout__menu--span.first--level',\n            translateY: ['0', '-100%'],\n            delay: animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"].stagger(0,\n                {\n                    start: 0,\n                }\n            ),\n            duration: 650,\n            easing: 'easeInOutQuint'\n        })\n\n        flyoutFirstItems.forEach(function (item) {\n            if (item.classList.contains('js--active')) {\n                // Animate second level items\n                (0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])({\n                    targets: '.c-flyout[data-flyout=\"' + navItemData + '\"] .js--finish .c-flyout__menu--span.second--level',\n                    translateY: ['0', '-100%'],\n                    delay: animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"].stagger(0,\n                        {\n                            start: 0,\n                        }\n                    ),\n                    duration: 650,\n                    easing: 'easeInOutQuint',\n                    complete: function () {\n                        item.classList.remove('js--finish');\n                    }\n                })\n            }\n        });\n\n        // Remove classes\n        nav.classList.remove('js--bg-white');\n        nav.classList.remove('js--triggered');\n        logo.classList.remove('js--black');\n        navBody.classList.remove('no--scroll');\n        navBody.classList.remove('nav--open');\n\n        flyoutFirstItems.forEach(function (item) {\n            item.classList.remove('js--active');\n        });\n    }\n\n        // If flyout is not visible\n        if (navItemDataTarget.style.display !== 'block') {\n            // Show flyout menu\n            navItemDataTarget.style.display = 'block';\n\n            event.currentTarget.setAttribute('aria-expanded', true);\n\n            // Öffnen und Wechseln des Menüs über die Navigationspunkte und das Burger Menü im Header\n            if (document.querySelectorAll('.c-flyout[style*=\"display: block;\"]').length >= 2) {\n\n                // Menü gewechselt (nicht geöffnet!) über einen Header-Navigationspunkt\n\n                // Scrollbar für 2. Ebene ausblenden, wenn das Menü über Header-Navigationspunkte oder das Burgermenü gewechselt wird\n                secondLevelScroller.forEach(function (item) {\n                    item.style.overflowY = 'hidden';\n                });\n                // Animate first level items\n                (0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])({\n                    targets: '.c-navigation__item:not(.js--active) .c-flyout .c-flyout__menu--span.first--level, .c-navigation__burger:not(.js--active) .c-flyout .c-flyout__menu--span.first--level',\n                    translateY: ['0', '-100%'],\n                    delay: animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"].stagger(0, {\n                        start: 0\n                    }),\n                    duration: 750,\n                    easing: cubicBezier,\n                    begin: function () {\n                        nav.classList.add('js--pointerevent');\n                    },\n                    complete: function () {\n                        document.querySelectorAll('.c-navigation__item:not(.js--active) .c-flyout, .c-navigation__burger:not(.js--active) .c-flyout').forEach(function (item) {\n                            item.style.display = 'none';\n                        });\n\n                        // keyboard navigation\n                        if(event.detail === 0) {\n                            firstFocusLink.focus({ focusVisible: true });\n                        }\n                    }\n                });\n\n                // Animate first level items\n                (0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])({\n                    targets: '.c-flyout[data-flyout=\"' + navItemData + '\"] .c-flyout__menu--span.first--level',\n                    translateY: ['100%', '0'],\n                    delay: animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"].stagger(75, {\n                        start: 0\n                    }),\n                    duration: 1000,\n                    easing: cubicBezier,\n                    complete: function () {\n                        nav.classList.remove('js--pointerevent');\n                    }\n                });\n\n                // ...\n                (0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])({\n                    targets: '.c-navigation .c-flyout__progress',\n                    width: '33.33%',\n                    duration: 1000,\n                    easing: cubicBezier,\n                });\n\n                // ???\n                if (document.querySelectorAll('.c-flyout__menu--item.js--active').length >= 1) {\n                    (0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])({\n                        targets: '.c-flyout__menu--item.js--active .c-flyout__menu--span.second--level',\n                        translateY: '-100%',\n                        delay: animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"].stagger(0, {\n                            start: 0\n                        }),\n                        duration: 750,\n                        easing: cubicBezier,\n                        complete: function () {\n                            document.querySelector('.c-flyout__menu--item.js--active .c-flyout__column').style.display = 'none';\n                            document.querySelector('.c-flyout__menu--item.js--active').classList.remove('js--active', 'js--finish');\n                        }\n                    })\n                }\n            } else {\n\n            // Add black state\n            nav.classList.add('js--bg-white');\n            nav.classList.add('js--triggered');\n            navBody.classList.add('no--scroll');\n            navBody.classList.add('nav--open');\n\n            // Animate background\n            (0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])({\n                targets: '.c-navigation .c-flyout__background',\n                opacity: '1',\n                duration: 1000,\n                easing: 'easeInOutQuad',\n                complete: function () {\n                    nav.classList.remove('js--pointerevent');\n                    document.querySelector('.c-navigation .c-flyout__background').classList.remove('js--pointerevent');\n                },\n                begin: function () {\n                    nav.classList.add('js--pointerevent');\n                    document.querySelector('.c-navigation .c-flyout__background').classList.add('js--pointerevent');\n                    document.querySelector('.c-navigation .c-flyout__background').style.display = 'block';\n                }\n            });\n\n            // Animate progress background\n            (0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])({\n                targets: '.c-navigation .c-flyout__progress',\n                width: '33.33%',\n                duration: 1000,\n                easing: cubicBezier\n            })\n\n            // Animate first level items\n            ;(0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])({\n                targets: '.c-flyout[data-flyout=\"' + navItemData + '\"] .c-flyout__menu--span.first--level',\n                translateY: ['100%', '0'],\n                delay: animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"].stagger(75, {\n                    start: 0\n                }),\n                duration: 1000,\n                easing: cubicBezier,\n                complete: function () {\n                    // keyboard navigation\n                    if(event.detail === 0) {\n                        firstFocusLink.focus({ focusVisible: true });\n                    }\n                },\n            });\n        }\n\n        document.body.addEventListener('keydown', closeFlyoutEsc);\n    }\n\n}\n\nconst handleSecondLevel = function(event) {\n    var item = event.currentTarget.parentNode;\n    var flyoutCall = event.currentTarget.parentElement.getAttribute('data-menu');\n    var clickTarget = event.currentTarget.parentElement;\n    var flyoutMenuItems = document.querySelectorAll('.js--active .c-flyout__menu--item:not(.js--finish, .js--active) [data-id=\"' + flyoutCall + '\"] .c-flyout__menu--span.second--level');\n    var flyoutMenuItemsFinish = document.querySelectorAll('.js--active .js--finish .c-flyout__menu--span.second--level');\n    var flyoutFirstItemsActive = document.querySelectorAll('.js--active .c-flyout__column .c-flyout__menu--item.has--child');\n    var firstFocusLink = item.querySelector('.c-flyout__column ul > li > a')\n\n    flyoutFirstItemsActive.forEach(function (item) {\n        item.classList.remove('js--active');\n    });\n\n    flyoutFirstItems.forEach((item) => {\n        item.querySelector('.c-flyout__menu--link').classList.add('js--pointerevent');\n    });\n\n    logo.classList.add('js--black');\n    item.classList.add('js--active');\n    item.classList.add('js--animate');\n\n    // Animate second level items in\n    (0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])({\n        targets: flyoutMenuItems,\n        translateY: ['100%', '0'],\n        delay: animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"].stagger(75, {\n            start: 0\n        }),\n        duration: 1000,\n        easing: cubicBezier,\n        begin: function () {\n            clickTarget.querySelector('.c-flyout__column').style.display = 'block';\n            nav.classList.add('on-second-level');\n        },\n        complete: function () {\n            secondLevelScroller.forEach(function (item) {\n                item.style.overflowY = 'auto';\n            });\n            item.classList.add('js--finish');\n            item.classList.remove('js--animate');\n            flyoutFirstItems.forEach((item) => {\n                item.querySelector('.c-flyout__menu--link').classList.remove('js--pointerevent');\n            });\n        }\n    })\n\n    // Animate second level items out\n    ;(0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])({\n        targets: flyoutMenuItemsFinish,\n        translateY: ['0', '-100%'],\n        delay: animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"].stagger(25, {\n            start: 0\n        }),\n        duration: 750,\n        easing: cubicBezier,\n        begin: function () {\n            secondLevelScroller.forEach(function (item) {\n                item.style.overflowY = 'hidden';\n            });\n            flyoutFirstItemsActive.forEach(function (item) {\n                item.classList.remove('js--finish');\n            });\n        },\n        complete: function () {\n            flyoutFirstItemsActive.forEach(function (item) {\n                if (!item.classList.contains('js--active')) {\n                    item.querySelector('.c-flyout__column').style.display = 'none';\n                }\n            });\n\n            // keyboard navigation\n            if(event.detail === 0) {\n                firstFocusLink.focus({ focusVisible: true });\n            }\n        }\n    })\n\n    // Animate progress background to 66%\n    ;(0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])({\n        targets: '.c-navigation .c-flyout__progress',\n        width: '66.66%',\n        duration: 1000,\n        easing: cubicBezier\n    })\n\n    // Animate progress background to 33%\n    if (clickTarget.classList.contains('js--finish', 'js--active', 'js--animate')) {\n        (0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])({\n            targets: '.c-navigation .c-flyout__progress',\n            width: '33.33%',\n            duration: 1000,\n            easing: cubicBezier,\n            complete: function () {\n                clickTarget.classList.remove('js--finish', 'js--active');\n                clickTarget.querySelector('.c-flyout__column').style.display = 'none';\n                nav.classList.remove('on-second-level');\n            },\n            begin: function () {\n                logo.classList.remove('js--black');\n            }\n        })\n    }\n}\n\nconst closeNavFlyout = function(event) {\n    ;(0,_navigationDesktopImages__WEBPACK_IMPORTED_MODULE_1__.resetImages)();\n\n    var item = event.currentTarget;\n\n    document.querySelector('.main-navi-link').setAttribute('aria-expanded', false);\n\n    // Animate background\n    (0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])({\n        targets: '.c-navigation .c-flyout__background',\n        opacity: '0',\n        duration: 1000,\n        easing: 'easeInOutQuad',\n        complete: function () {\n            document.querySelector('.c-navigation .js--active .c-flyout').style.display = 'none';\n            document.querySelector('.c-navigation .c-flyout__background').style.display = 'none';\n\n            nav.classList.remove('js--pointerevent');\n            item.classList.remove('js--pointerevent');\n\n            document.querySelector('.c-navigation .c-flyout__background').classList.remove('js--pointerevent');\n            document.querySelector('.c-navigation__item.has--child.js--active, .c-navigation__burger.js--active').classList.remove('js--active');\n            document.querySelector('body').classList.remove('nav-open');\n        },\n        begin: function () {\n            navBody.classList.remove('no--scroll');\n            navBody.classList.remove('nav--open');\n            nav.classList.add('js--pointerevent');\n            item.classList.add('js--pointerevent');\n\n            document.querySelector('.c-navigation .c-flyout__background').classList.add('js--pointerevent');\n        }\n    })\n\n    // Animate progress background\n    ;(0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])({\n        targets: '.c-navigation .c-flyout__progress',\n        width: '0%',\n        duration: 1000,\n        easing: cubicBezier\n    })\n\n    // Animate first level items\n    ;(0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])({\n        targets: '.c-navigation__list > li.js--active .c-flyout .c-flyout__menu--span.first--level',\n        translateY: ['0', '-100%'],\n        delay: animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"].stagger(0,\n            {\n                start: 0,\n            }\n        ),\n        duration: 650,\n        easing: 'easeInOutQuint'\n    })\n\n    flyoutFirstItems.forEach(function (item) {\n        if (item.classList.contains('js--active')) {\n            // Animate second level items\n            (0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])({\n                targets: '.c-navigation__list > li.js--active .c-flyout .js--finish .c-flyout__menu--span.second--level',\n                translateY: ['0', '-100%'],\n                delay: animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"].stagger(0, {\n                    start: 0\n                }),\n                duration: 650,\n                easing: 'easeInOutQuint',\n                begin: function () {\n                    secondLevelScroller.forEach(function (item) {\n                        item.style.overflowY = 'hidden';\n                    });\n                },\n                complete: function () {\n                    item.classList.remove('js--finish');\n                    secondLevelScroller.forEach(function (item) {\n                        item.style.overflowY = 'hidden';\n                    });\n                }\n            });\n        }\n    });\n\n    nav.classList.remove('js--bg-white');\n    nav.classList.remove('js--triggered');\n    logo.classList.remove('js--black');\n\n    flyoutFirstItems.forEach(function (item) {\n        item.classList.remove('js--active');\n    });\n\n    document.body.removeEventListener('keydown', closeFlyoutEsc);\n}\n\nconst closeFlyoutEsc = function(event) {\n    if (event.key === 'Escape' || event.key === 'Esc' || event.keyCode === 27) {\n        closeNavFlyout(event);\n    }\n}\n\n\nnavItems.forEach(function (item) {\n    // Listen to click trigger\n    item.children[0].addEventListener('click', handleNavFlyout);\n\n    item.children[0].addEventListener('keydown', function(event) {\n        if (event.key === 'Enter') {\n            event.preventDefault();\n            handleNavFlyout(event);\n        }\n    });\n\n    // Navigate through second level child\n    flyoutFirstItems.forEach(function (item) {\n        item.children[0].addEventListener('click', handleSecondLevel, false);\n\n        item.children[0].addEventListener('keydown', function(event) {\n            if (event.key === 'Enter') {\n                event.preventDefault();\n                handleSecondLevel(event);\n            }\n        }, false);\n    });\n});\n\ncloseBtn.forEach(function (btn) {\n    // Listen to click trigger\n    btn.addEventListener('click', closeNavFlyout);\n});\n\n// Close On Background Click\ndocument.querySelectorAll('.c-flyout .c-flyout__menu--image, .c-flyout__background').forEach((item) => {\n    item.addEventListener('click', closeNavFlyout);\n});\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/navigationDesktop.js?");/***/}),/***/"./source/out/sinn/src/js/modules/navigationDesktopImages.js":(/*!*******************************************************************!*\
  !*** ./source/out/sinn/src/js/modules/navigationDesktopImages.js ***!
  \*******************************************************************/ /***/function sourceOutSinnSrcJsModulesNavigationDesktopImagesJs(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   resetImages: () => (/* binding */ resetImages)\n/* harmony export */ });\n/**\n * This Software is the property of dotfly and is protected\n * by copyright law - it is NOT Freeware.\n *\n * Any unauthorized use of this software without a valid license key\n * is a violation of the license agreement and will be prosecuted by\n * civil and criminal law.\n *\n * @category   Manages menu images on hover\n * @author     dotfly GmbH <info@dotfly.de>\n * @license    http://www.dotfly.de Commercial\n * @link       http://www.dotfly.de\n */\n\nlet activeImage, passiveImage, currentTimeout = null, currentImageUrl = null;\nlet isInitialized = false;\n\nfunction resetImages() {\n\tif (!activeImage || !passiveImage) return;\n\n\tcurrentImageUrl = null;\n\n\tactiveImage.style.opacity = '0';\n\tpassiveImage.style.opacity = '0';\n\n\tactiveImage.style.visibility = 'hidden';\n\tpassiveImage.style.visibility = 'hidden';\n\n\tactiveImage.removeAttribute('src');\n\tpassiveImage.removeAttribute('src');\n\tactiveImage.removeAttribute('alt');\n\tpassiveImage.removeAttribute('alt');\n\n\tif (currentTimeout) {\n\t\tclearTimeout(currentTimeout);\n\t\tcurrentTimeout = null;\n\t}\n}\n\nfunction fadeInImage(imageUrl, altText) {\n\tif (!imageUrl) {\n\t\tresetImages();\n\t\treturn;\n\t}\n\n\tif (currentImageUrl === imageUrl) return;\n\n\tif (currentTimeout) {\n\t\tclearTimeout(currentTimeout);\n\t\tcurrentTimeout = null;\n\t}\n\n\tcurrentImageUrl = imageUrl;\n\n\tpassiveImage.src = imageUrl;\n\tpassiveImage.alt = altText || '';\n\tpassiveImage.style.visibility = 'visible';\n\tpassiveImage.style.opacity = '1';\n\n\tactiveImage.style.opacity = '0';\n\n\tcurrentTimeout = setTimeout(() => {\n\t\tactiveImage.style.visibility = 'hidden';\n\t\t[activeImage, passiveImage] = [passiveImage, activeImage];\n\t}, 500);\n}\n\nfunction handleMouseEnter(event) {\n\tconst el = event.currentTarget.closest('[data-menuimage]');\n\n\tif (el) {\n\t\tconst imageUrl = el.getAttribute('data-menuimage');\n\t\tconst altText = el.getAttribute('data-alt') || '';\n\n\t\tif (imageUrl) {\n\t\t\tfadeInImage(imageUrl, altText);\n\t\t\treturn;\n\t\t}\n\t}\n\n\tresetImages();\n}\n\nfunction initMenuImageFeature(firstTriggerElement) {\n\tconst imageSourceElements = document.querySelectorAll('.c-flyout__menu--link');\n\tconst targetElement = document.querySelector('.js-menu-image');\n\n\tif (!imageSourceElements.length || !targetElement || isInitialized) return;\n\tisInitialized = true;\n\n\t// Erzeuge die beiden gestapelten Bilder\n\tactiveImage = document.createElement('img');\n\tpassiveImage = document.createElement('img');\n\n\tactiveImage.className = 'menu-image menu-image--a';\n\tpassiveImage.className = 'menu-image menu-image--b';\n\n\t[activeImage, passiveImage].forEach(img => {\n\t\timg.setAttribute('loading', 'lazy');\n\t\timg.setAttribute('aria-hidden', 'true');\n\t\timg.style.opacity = '0';\n\t\timg.style.visibility = 'hidden';\n\t\timg.style.transition = 'opacity 0.5s ease';\n\t\timg.style.position = 'absolute';\n\t\timg.style.top = '0';\n\t\timg.style.left = '0';\n\t\timg.style.width = '100%';\n\t\timg.style.height = '100%';\n\t\timg.style.objectFit = 'cover';\n\t\timg.style.pointerEvents = 'none';\n\t});\n\n\ttargetElement.appendChild(activeImage);\n\ttargetElement.appendChild(passiveImage);\n\n\timageSourceElements.forEach(el => {\n\t\tel.removeEventListener('mouseenter', lazyInitializer);\n\t\tel.addEventListener('mouseenter', handleMouseEnter);\n\t});\n\n\tif (firstTriggerElement) {\n\t\thandleMouseEnter({ currentTarget: firstTriggerElement });\n\t}\n}\n\nfunction lazyInitializer(event) {\n\tinitMenuImageFeature(event.currentTarget);\n}\n\nconst imageSourceElements = document.querySelectorAll('.c-flyout__menu--link');\nconst targetElement = document.querySelector('.js-menu-image');\n\nif (imageSourceElements.length && targetElement) {\n\timageSourceElements.forEach(el => {\n\t\tel.addEventListener('mouseenter', lazyInitializer, { once: true });\n\t});\n}\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/navigationDesktopImages.js?");/***/}),/***/"./source/out/sinn/src/js/modules/navigationMobile.js":(/*!************************************************************!*\
  !*** ./source/out/sinn/src/js/modules/navigationMobile.js ***!
  \************************************************************/ /***/function sourceOutSinnSrcJsModulesNavigationMobileJs(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! animejs/lib/anime.es.js */ \"./node_modules/animejs/lib/anime.es.js\");\n/* harmony import */ var _registerOffcanvas__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./registerOffcanvas */ \"./source/out/sinn/src/js/modules/registerOffcanvas.js\");\n\n\n\n// Führt den Code erst aus, wenn der DOM vollständig geladen ist\ndocument.addEventListener('DOMContentLoaded', function () {\n    const mobileNavContainer = document.querySelector('.c-mobilenav');\n\n    // Überprüfen, ob der mobileNavContainer vorhanden ist\n    if (mobileNavContainer) {\n        const mobileNavFirstLevel = document.querySelector('.c-mobilenav__content.first--level');\n        const firstLevelitems = document.querySelectorAll('.c-mobilenav__content.first--level > .c-mobilenav__list > .c-mobilenav__item > .c-mobilenav__item-link');\n        const mobileMenuItems = document.querySelectorAll('.c-mobilemenu__item');\n        const mobileNavItems = document.querySelectorAll('.c-mobilenav__item.has--child > .c-mobilenav__item-link');\n        const backButton = document.querySelectorAll('.c-mobilenav__back');\n        const cubicBezier = 'cubicBezier(.4, .05, .2, .9)';\n\n        // Initialisiert die Offcanvas-Animation für das Haupt-Navigationsmenü\n        (0,_registerOffcanvas__WEBPACK_IMPORTED_MODULE_1__.registerOffcanvas)({\n            offCanvas: '.c-mobilenav',\n            triggers: '.c-mobilemenu__item.is--navigation',\n        });\n\n        // Resettet die mobile Navigation, wenn ein Link außerhalb der Navigation (z.B. Suche oder Warenkorb) angeklickt wird\n        mobileMenuItems.forEach(item => {\n            item.addEventListener('click', () => {\n                !item.classList.contains('is--navigation') && resetMobileNav();\n            });\n        });\n\n        // Funktion zum Zurücksetzen der mobilen Navigation\n        const resetMobileNav = function() {\n            const transitionEndHandler = function () {\n                mobileNavContainer.firstElementChild.removeEventListener('transitionend', transitionEndHandler);\n                document.querySelector('.c-mobilenav__content.first--level').style.transform = null;\n                document.querySelectorAll('.c-mobilenav__content:not(.first--level)').forEach((item) => {\n                    item.style = null;\n                });\n                firstLevelitems.forEach((item) => {\n                    item.style = null;\n                });\n            };\n            mobileNavContainer.firstElementChild.addEventListener('transitionend', transitionEndHandler);\n        }\n\n        // Animiert die Navigation (Verschiebung in X-Richtung)\n        const animateNavigation = (target, translateX, callback) => {\n            ;(0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])({\n                targets: target,\n                translateX: translateX,\n                duration: 1000,\n                easing: cubicBezier,\n                complete: callback,\n            });\n        };\n\n        // Animiert die Navigationselemente (Verschiebung in Y-Richtung) mit optionaler Verzögerung\n        /*const animateItems = (items, translateY, delay = 0) => {\n            anime({\n                targets: items,\n                translateY: translateY,\n                delay: anime.stagger(delay), // Verzögert jedes Element individuell\n                duration: 1000,\n                easing: cubicBezier,\n            });\n        };*/\n\n        // Animationen für die zweite und dritte Navigationsebene\n        mobileNavItems.forEach((item) => {\n            item.addEventListener('click', function (event) {\n                const mobileNavItemData = event.currentTarget.getAttribute('data-href');\n                const mobileNavItemDataTarget = document.querySelector('.c-mobilenav__content[data-target=\"' + mobileNavItemData + '\"]');\n                //const activeItems = mobileNavItemDataTarget.querySelectorAll('.c-mobilenav__item.has--child .c-mobilenav__item-link');\n\n                // Überprüft, ob das Ziel ein Datenattribut besitzt\n                if (mobileNavItemData) {\n                    event.preventDefault();\n\n                    // Verhindert Mehrfachklicks während der Animation\n                    mobileNavFirstLevel.classList.add('js--pointerevent');\n\n                    // Animiert die Navigation nach vorne (zur nächsten Ebene)\n                    animateNavigation(mobileNavFirstLevel, '-=100%', () => {\n                        mobileNavFirstLevel.classList.remove('js--pointerevent');\n                    });\n\n                    // Animiert die Navigationselemente der aktiven Ebene\n                    //animateItems(activeItems, ['100%', '0%'], 20); // Neue Elemente erscheinen von unten\n                    //animateItems(firstLevelitems, ['0', '-100%']); // Aktuelle Elemente verschwinden nach oben\n\n                    // Aktiviert und zeigt den neuen Inhalt an\n                    mobileNavItemDataTarget.style.display = 'block';\n                }\n            });\n        });\n\n        // \"Zurück\"-Button-Animationen\n        backButton.forEach((button) => {\n            button.addEventListener('click', function (event) {\n                const activeContent = button.parentElement;\n                //const activeItems = activeContent.querySelectorAll('.c-mobilenav__item-link');\n\n                event.preventDefault();\n                mobileNavFirstLevel.classList.add('js--pointerevent');\n\n                // Animiert die Navigation zurück (zur vorherigen Ebene)\n                animateNavigation(mobileNavFirstLevel, '+=100%', () => {\n                    activeContent.style.display = null;\n                    mobileNavFirstLevel.classList.remove('js--pointerevent');\n                });\n\n                // Animiert die Navigationselemente zurück\n                //animateItems(activeItems, ['0', '-100%']); // Aktuelle Elemente verschwinden nach unten\n                //animateItems(firstLevelitems, ['100%', '0%'], 75); // Erste Ebene erscheint von oben\n            });\n        });\n    }\n});\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/navigationMobile.js?");/***/}),/***/"./source/out/sinn/src/js/modules/navigationTracking.js":(/*!**************************************************************!*\
  !*** ./source/out/sinn/src/js/modules/navigationTracking.js ***!
  \**************************************************************/ /***/function sourceOutSinnSrcJsModulesNavigationTrackingJs(){eval("// *** Navigation Tracking ***\nvar mainNaviLinks = document.querySelectorAll('.main-navi-link');\nvar fLevelNaviLinks = document.querySelectorAll('.f-level-navi-link');\n\nmainNaviLinks.forEach(function (link) {\n    link.addEventListener('mousedown', function () {\n        let spanTitle = link.getAttribute('data-target');\n        spanTitle === 'Burger' ? spanTitle = 'Menu-Button' : spanTitle;\n\n        if(typeof(_etracker) === 'object') {\n            _etracker.sendEvent(new et_UserDefinedEvent(spanTitle, 'Obernavigation', 'click', ''));\n        } else {\n            // console.log(\"failed\");\n        }\n    });\n});\n\nfLevelNaviLinks.forEach(function (link) {\n    link.addEventListener('mousedown', function () {\n        let spanTitle = link.getAttribute('data-target');\n        let parentElement = link.closest('.c-navigation__item');\n        let parentTitle = parentElement ? parentElement.querySelector('.main-navi-link')?.getAttribute('data-target') : 'Menu-Button';\n\n        if(typeof(_etracker) === 'object') {\n            _etracker.sendEvent(new et_UserDefinedEvent(spanTitle, 'Unternavigation', 'click', parentTitle));\n        } else {\n            // console.log(\"failed\");\n        }\n    });\n});\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/navigationTracking.js?");/***/}),/***/"./source/out/sinn/src/js/modules/optionsCounter.js":(/*!**********************************************************!*\
  !*** ./source/out/sinn/src/js/modules/optionsCounter.js ***!
  \**********************************************************/ /***/function sourceOutSinnSrcJsModulesOptionsCounterJs(){eval("document.addEventListener('DOMContentLoaded', () => {\n\tconst dialog = document.querySelector('#mobileOptionsOffcanvas');\n\tconst openBtn = document.querySelector('.js--open-options');\n\tconst amountEl = document.querySelector('.js--options-amount');\n\tconst checkboxes = dialog?.querySelectorAll('input[type=\"checkbox\"].combinable-option');\n\n\tif (!dialog || !openBtn || !amountEl || !checkboxes.length) return;\n\n\tconst updateSelectedAmount = () => {\n\t\tconst checkedCount = Array.from(checkboxes).filter(cb => cb.checked).length;\n\t\tamountEl.textContent = checkedCount > 0 ? ` (${checkedCount})` : '';\n\t};\n\n\tupdateSelectedAmount();\n\n\tcheckboxes.forEach(cb => {\n\t\tcb.addEventListener('change', updateSelectedAmount);\n\t});\n});\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/optionsCounter.js?");/***/}),/***/"./source/out/sinn/src/js/modules/optionsScroller.js":(/*!***********************************************************!*\
  !*** ./source/out/sinn/src/js/modules/optionsScroller.js ***!
  \***********************************************************/ /***/function sourceOutSinnSrcJsModulesOptionsScrollerJs(){eval("document.addEventListener('DOMContentLoaded', () => {\n\tconst scrollBtn = document.getElementById('chooseOptionsForSet');\n\n\tif (!scrollBtn) return;\n\n\tscrollBtn.addEventListener('click', (e) => {\n\t\te.preventDefault();\n\n\t\twindow.scrollTo({\n\t\t\ttop: 710,\n\t\t\tbehavior: 'smooth'\n\t\t});\n\t});\n});\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/optionsScroller.js?");/***/}),/***/"./source/out/sinn/src/js/modules/optionsdialog.js":(/*!*********************************************************!*\
  !*** ./source/out/sinn/src/js/modules/optionsdialog.js ***!
  \*********************************************************/ /***/function sourceOutSinnSrcJsModulesOptionsdialogJs(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _focusTrap_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./focusTrap.js */ \"./source/out/sinn/src/js/modules/focusTrap.js\");\n\n\ndocument.addEventListener('DOMContentLoaded', () => {\n\tconst openBtn = document.querySelector('.js--open-options');\n\tconst closeBtns = document.querySelectorAll('.js--close-options');\n\tconst dialog = document.querySelector('#mobileOptionsOffcanvas');\n\tconst content = dialog?.querySelector('.c-optionsdialog__content');\n\tconst firstFocusable = dialog?.querySelector('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])');\n\tconst classVisible = 'js--active';\n\tconst classAnimating = 'is--animating';\n\tlet isAnimating = false;\n\tlet animationTimeout;\n\n\tif (!openBtn || !closeBtns.length || !dialog || !content) return;\n\n\tconst openDialog = () => {\n\t\tif (isAnimating) return;\n\t\tisAnimating = true;\n\t\tdialog.removeAttribute('hidden');\n\t\tdialog.style.display = 'block';\n\t\tdialog.classList.add(classAnimating);\n\n\t\trequestAnimationFrame(() => {\n\t\t\tdialog.classList.add(classVisible);\n\t\t});\n\n\t\tdialog.setAttribute('aria-hidden', 'false');\n\t\topenBtn.setAttribute('aria-expanded', 'true');\n\t\tfirstFocusable?.focus();\n\t\t(0,_focusTrap_js__WEBPACK_IMPORTED_MODULE_0__.createFocusTrap)(dialog);\n\t\tdocument.addEventListener('keydown', handleKeydown);\n\n\t\tclearTimeout(animationTimeout);\n\t\tanimationTimeout = setTimeout(() => {\n\t\t\tdialog.classList.remove(classAnimating);\n\t\t\tisAnimating = false;\n\t\t}, 800);\n\t};\n\n\tconst closeDialog = () => {\n\t\tif (isAnimating) return;\n\t\tisAnimating = true;\n\t\tdialog.classList.add(classAnimating);\n\t\tdialog.classList.remove(classVisible);\n\t\tdialog.setAttribute('aria-hidden', 'true');\n\t\topenBtn.setAttribute('aria-expanded', 'false');\n\t\topenBtn.focus();\n\t\tdocument.removeEventListener('keydown', handleKeydown);\n\n\t\tclearTimeout(animationTimeout);\n\t\tanimationTimeout = setTimeout(finishClosing, 800);\n\n\t\tconst onTransitionEnd = (e) => {\n\t\t\tif (e.target === content && e.propertyName === 'transform') {\n\t\t\t\tfinishClosing();\n\t\t\t}\n\t\t};\n\n\t\tcontent.addEventListener('transitionend', onTransitionEnd, { once: true });\n\n\t\tfunction finishClosing() {\n\t\t\tdialog.style.display = 'none';\n\t\t\tdialog.setAttribute('hidden', '');\n\t\t\tdialog.classList.remove(classAnimating);\n\t\t\tisAnimating = false;\n\t\t}\n\t};\n\n\tconst handleKeydown = (e) => {\n\t\tif (e.key === 'Escape' || e.key === 'Esc') {\n\t\t\te.preventDefault();\n\t\t\tcloseDialog();\n\t\t}\n\t};\n\n\topenBtn.addEventListener('click', openDialog);\n\tcloseBtns.forEach(btn => btn.addEventListener('click', closeDialog));\n});\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/optionsdialog.js?");/***/}),/***/"./source/out/sinn/src/js/modules/order.js":(/*!*************************************************!*\
  !*** ./source/out/sinn/src/js/modules/order.js ***!
  \*************************************************/ /***/function sourceOutSinnSrcJsModulesOrderJs(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! animejs/lib/anime.es.js */ \"./node_modules/animejs/lib/anime.es.js\");\n\n\nvar orderItems = document.querySelectorAll('.c-account__order');\nvar cubicBezier = 'cubicBezier(.40,.05,.20,.90)';\nvar contentHeight, bodyHeight, footerHeight, setViewportWidth;\n\nif (orderItems) {\n\torderItems.forEach((item) => {\n\t\tvar order = item;\n\t\tvar content = item.querySelector('.c-account__content');\n\t\tvar header = item.querySelector('.c-account__header');\n\n\t\theader.addEventListener('click', function () {\n\t\t\tbodyHeight = item.querySelector('.c-account__body').getBoundingClientRect().height;\n\t\t\tfooterHeight = item.querySelector('.c-account__footer').getBoundingClientRect().height;\n\t\t\tcontentHeight = (bodyHeight + footerHeight) + 'px';\n\n\t\t\torder.classList.add('js--pointerevent');\n\n\t\t\tif (order.classList.contains('js--active')) {\n\t\t\t\t(0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])({\n\t\t\t\t\ttargets: content,\n\t\t\t\t\theight: '0',\n\t\t\t\t\tduration: 650,\n\t\t\t\t\teasing: cubicBezier,\n\t\t\t\t\tcomplete: function () {\n\t\t\t\t\t\torder.classList.remove('js--active', 'js--pointerevent');\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t} else {\n\t\t\t\torder.classList.add('js--active', 'js--pointerevent');\n\n\t\t\t\t(0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])({\n\t\t\t\t\ttargets: content,\n\t\t\t\t\theight: ['0', contentHeight],\n\t\t\t\t\tduration: 650,\n\t\t\t\t\teasing: cubicBezier,\n\t\t\t\t\tcomplete: function () {\n\t\t\t\t\t\torder.classList.remove('js--pointerevent');\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t}\n\t\t});\n\n\t\twindow.addEventListener('resize', () => {\n\t\t\tsetViewportWidth = window.innerWidth;\n\n\t\t\tbodyHeight = item.querySelector('.c-account__body').getBoundingClientRect().height;\n\t\t\tfooterHeight = item.querySelector('.c-account__footer').getBoundingClientRect().height;\n\t\t\tcontentHeight = (bodyHeight + footerHeight) + 'px';\n\n\t\t\tif (order.classList.contains('js--active') && !order.classList.contains('js--pointerevent')) {\n\t\t\t\tcontent.style.height = contentHeight;\n\t\t\t}\n\t\t});\n\t});\n}\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/order.js?");/***/}),/***/"./source/out/sinn/src/js/modules/overlay/overlayContentLoader.js":(/*!************************************************************************!*\
  !*** ./source/out/sinn/src/js/modules/overlay/overlayContentLoader.js ***!
  \************************************************************************/ /***/function sourceOutSinnSrcJsModulesOverlayOverlayContentLoaderJs(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   initOverlayContentLoader: () => (/* binding */ initOverlayContentLoader),\n/* harmony export */   overlayContentLoader: () => (/* binding */ overlayContentLoader)\n/* harmony export */ });\n/**\n * This Software is the property of dotfly and is protected\n * by copyright law - it is NOT Freeware.\n *\n * Any unauthorized use of this software without a valid license key\n * is a violation of the license agreement and will be prosecuted by\n * civil and criminal law.\n *\n * @category   ...\n * @author     dotfly GmbH <info@dotfly.de>\n * @license    http://www.dotfly.de Commercial\n * @link       http://www.dotfly.de\n */\n\n// usage in template:\n//<button\n//    data-content-trigger (if you want to register the trigger automatically)\n//    data-content-url=\"/fetch-overlay-content\"\n//    data-key=\"key\" (only use when response is an object) (only use when response is an object)\n//    data-target=\"#overlayContainer\"\n//    data-refetch=\"true/false\"\n//    data-payload='{\"key\": \"value\", ...}'\n//    Load Overlay Content\n//</button>\n//<div id=\"overlayContainer\"></div>\n\nconst overlayContentLoader = (triggerElement, targetElement) => {\n    if (!triggerElement || !targetElement) {\n        throw new Error(\"Both triggerElement and targetElement are required.\");\n    }\n\n    const fetchContent = async (url, payload) => {\n        try {\n            const formData = new FormData();\n            if( payload ) {\n                formData.append('payload', payload);\n            }\n            const response = await fetch(url, {\n                method: \"POST\",\n                body: formData\n            });\n            if (!response.ok) {\n                throw new Error(`Failed to fetch content: ${response.statusText}`);\n            }\n            const contentType = response.headers.get(\"content-type\");\n            if (contentType && contentType.includes(\"application/json\")) {\n                return await response.json();\n            } else {\n                return await response.text();\n            }\n        } catch (error) {\n            console.error(\"Error fetching overlay content:\", error);\n            return null;\n        }\n    };\n\n    const insertContent = (html, target) => {\n        const container = target;\n        if (container) {\n            container.innerHTML = html;\n\n            let refetch = triggerElement.getAttribute(\"data-refetch\") ? triggerElement.getAttribute(\"data-refetch\") : 'false';\n            refetch === 'false' && container.classList.add('js--fetched');\n            \n            // dispatch event with custom target to handle offcanvas animation only after fetch\n            const dataLoadedEvent = new CustomEvent(targetElement.id + 'Loaded');\n            document.dispatchEvent(dataLoadedEvent);\n        }\n    };\n\n    const bindTrigger = () => {\n        triggerElement.addEventListener(\"click\", async (event) => {\n            event.preventDefault();\n            const contentUrl = triggerElement.getAttribute(\"data-content-url\");\n            if (!contentUrl) {\n                console.warn(\"Trigger element does not have a 'data-content-url' attribute.\");\n                return;\n            }\n            const payload = triggerElement.getAttribute(\"data-payload\");\n\n            if (!targetElement.classList.contains('js--fetched')) {\n                const contentKey = triggerElement.getAttribute(\"data-key\");\n                const response = await fetchContent(contentUrl, payload);\n                if (typeof response === 'object') {\n                    const htmlContent = response[contentKey];\n                    htmlContent && insertContent(htmlContent, targetElement);\n                } else {\n                    insertContent(response, targetElement);\n                }\n            }          \n        });\n    };\n\n    bindTrigger();\n};\n\n\nconst initOverlayContentLoader = function (obj) {\n    const triggers = obj.querySelectorAll(\"[data-content-trigger]\");\n    triggers.forEach((trigger) => {\n        const targetSelector = trigger.getAttribute(\"data-target\");\n        const targetElement = document.querySelector(targetSelector);\n\n        if (targetElement) {\n            overlayContentLoader(trigger, targetElement);\n        } else {\n            console.warn(`Target element '${targetSelector}' not found.`);\n        }\n    });\n}\n\n//init globally \ndocument.addEventListener(\"DOMContentLoaded\", () => {\n    initOverlayContentLoader(document);\n});\n\n \n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/overlay/overlayContentLoader.js?");/***/}),/***/"./source/out/sinn/src/js/modules/pagination.js":(/*!******************************************************!*\
  !*** ./source/out/sinn/src/js/modules/pagination.js ***!
  \******************************************************/ /***/function sourceOutSinnSrcJsModulesPaginationJs(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   updatePageVisibility: () => (/* binding */ updatePageVisibility)\n/* harmony export */ });\n/**\n * This Software is the property of dotfly and is protected\n * by copyright law - it is NOT Freeware.\n *\n * Any unauthorized use of this software without a valid license key\n * is a violation of the license agreement and will be prosecuted by\n * civil and criminal law.\n *\n * @category   Blendet Punkte aus der Paginierung aus, wenn das Browserfenster nicht breit genug ist\n * @author     Anna Morawe <anna.morawe@dotfly.de>\n * @license    http://www.dotfly.de Commercial\n * @link       http://www.dotfly.de\n */\n\nfunction togglePageDisplay(paginationContainer, show) {\n    const displayStyle = show ? 'block' : 'none';\n    paginationContainer.querySelectorAll('.e-pagination__item:not(.is--prev):not(.is--next):not(.is--active)').forEach(item => {\n        item.style.display = displayStyle;\n    });\n}\n\nfunction handleDotsVisibility(paginationContainer, show) {\n    const displayStyle = show ? 'block' : 'none';\n    paginationContainer.querySelectorAll('.e-pagination__item.is--dots').forEach(dot => {\n        dot.style.display = displayStyle;\n    });\n}\n\nfunction updatePageVisibility() {\n    const windowWidth = window.innerWidth;\n    const isMobileView = windowWidth < 1100;\n    \n    document.querySelectorAll('.e-pagination__inner').forEach(paginationContainer => {\n        handleDotsVisibility(paginationContainer, !isMobileView);\n        togglePageDisplay(paginationContainer, !isMobileView);\n        \n        if (isMobileView) {\n            const activePage = paginationContainer.querySelector('.e-pagination__item.is--active');\n            if (activePage) {\n                const prevSibling = activePage.previousElementSibling;\n                const nextSibling = activePage.nextElementSibling;\n                \n                if (prevSibling && !prevSibling.classList.contains('is--prev') && !prevSibling.classList.contains('is--dots')) {\n                    prevSibling.style.display = 'block';\n                }\n                \n                if (nextSibling && !nextSibling.classList.contains('is--next') && !nextSibling.classList.contains('is--dots')) {\n                    nextSibling.style.display = 'block';\n                }\n            }\n        } else {\n            paginationContainer.querySelectorAll('.e-pagination__item').forEach(item => {\n                item.removeAttribute('style');\n            });\n        }\n    });\n\n    document.querySelectorAll('.e-pagination__inner').forEach(paginationContainer => {\n        paginationContainer.style.opacity = '1';\n    });\n}\n\ndocument.addEventListener(\"DOMContentLoaded\", updatePageVisibility);\nwindow.addEventListener('resize', updatePageVisibility);\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/pagination.js?");/***/}),/***/"./source/out/sinn/src/js/modules/passwordcontrol.js":(/*!***********************************************************!*\
  !*** ./source/out/sinn/src/js/modules/passwordcontrol.js ***!
  \***********************************************************/ /***/function sourceOutSinnSrcJsModulesPasswordcontrolJs(){eval("document.addEventListener('DOMContentLoaded', function () {\n    // List of ID sets\n    const idSets = [\n        { passwordNew: 'passwordNew', passwordNewConfirm: 'passwordNewConfirm', savePass: 'savePass' },\n        { passwordNew: 'password_new', passwordNewConfirm: 'password_new_confirm', savePass: 'savePassForgot' },\n        { passwordNew: 'userPassword', passwordNewConfirm: 'userPasswordConfirm', savePass: 'accUserSaveTop' },\n        { passwordNew: 'userPassword', passwordNewConfirm: 'userPasswordConfirm', savePass: 'userNextStepBottom' }\n    ];\n\n    idSets.forEach(({ passwordNew, passwordNewConfirm, savePass }) => {\n        // Get elements based on IDs\n        const passwordNewField = document.getElementById(passwordNew);\n        const passwordNewConfirmField = document.getElementById(passwordNewConfirm);\n        const passReqMsg = document.getElementById('pass-req-msg');\n        const passConfirmStatus = document.getElementById('pass-confirm-status');\n        const btnSavePass = document.getElementById(savePass);\n\n        // Only proceed if all elements are found\n        if (!passwordNewField || !passwordNewConfirmField || !btnSavePass) return;\n\n        // Requirement Strings and pass booleans\n        const requirements = [\n            {\n                element: document.getElementById('pass-req-length'),\n                check: value => value.length >= 8,\n                pass: false\n            },\n            {\n                element: document.getElementById('pass-req-capital'),\n                check: value => /[A-Z]/.test(value),\n                pass: false\n            },\n            {\n                element: document.getElementById('pass-req-small'),\n                check: value => /[a-z]/.test(value),\n                pass: false\n            },\n            {\n                element: document.getElementById('pass-req-number'),\n                check: value => /\\d/.test(value),\n                pass: false\n            },\n            {\n                element: document.getElementById('pass-req-symbol'),\n                check: value => /[!@#$%^&*(),.?\":{}|<>]/.test(value),\n                pass: false\n            }\n        ];\n\n        // Render changes\n        passwordNewField.addEventListener('input', handlePasswordInput);\n        passwordNewConfirmField.addEventListener('input', handleConfirmPasswordInput);\n\n        // Check Requirements and update\n        function checkRequirement(condition, element) {\n            if (condition) {\n                element.classList.add('hidden');\n            } else {\n                element.classList.remove('hidden');\n            }\n            return condition;\n        }\n\n        function handlePasswordInput() {\n            const value = passwordNewField.value;\n\n            let allConditionsMet = true;\n            requirements.forEach(requirement => {\n                const isMet = checkRequirement(requirement.check(value), requirement.element);\n                requirement.pass = isMet;\n                if (!isMet) {\n                    allConditionsMet = false;\n                }\n            });\n\n            checkPasswordsMatch();\n        }\n\n        function handleConfirmPasswordInput() {\n            checkPasswordsMatch();\n        }\n\n        function checkPasswordsMatch() {\n            const inPassword = passwordNewField.value;\n            const inPasswordConfirm = passwordNewConfirmField.value;\n\n            if (inPasswordConfirm.length > 0) {\n                if (inPassword !== inPasswordConfirm) {\n                    // Show mismatch message & hide save button if passwords don't match if passwords don't match\n                    passConfirmStatus.classList.remove('e-alert__hidden');\n                } else {\n                    passConfirmStatus.classList.add('e-alert__hidden'); // Hide mismatch message if passwords match\n                    // Only show the save button if passwords match and all requirements are met\n                }\n            } else {\n                // If password confirm field is empty, hide confirmation status and save button\n                passConfirmStatus.classList.add('e-alert__hidden');\n            }\n        }\n    });\n});\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/passwordcontrol.js?");/***/}),/***/"./source/out/sinn/src/js/modules/productDetailScrolling.js":(/*!******************************************************************!*\
  !*** ./source/out/sinn/src/js/modules/productDetailScrolling.js ***!
  \******************************************************************/ /***/function sourceOutSinnSrcJsModulesProductDetailScrollingJs(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _glidejs_glide__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @glidejs/glide */ \"./node_modules/@glidejs/glide/dist/glide.esm.js\");\n/**\n * This Software is the property of dotfly and is protected\n * by copyright law - it is NOT Freeware.\n *\n * Any unauthorized use of this software without a valid license key\n * is a violation of the license agreement and will be prosecuted by\n * civil and criminal law.\n *\n * @category   Regelt sämtliche Scroll-Funktionen auf Produktdetailseiten\n * @author     Anna Morawe <anna.morawe@dotfly.de>\n * @license    http://www.dotfly.de Commercial\n * @link       http://www.dotfly.de\n */\n\n\n\nconst productDetailPage = document.querySelector('.cl-details');\n\nfunction isElementNotInViewport(el) {\n\tconst rect = el.getBoundingClientRect();\n\treturn (\n\t\trect.bottom < 0 ||\n\t\trect.right < 0 ||\n\t\trect.top > (window.innerHeight || document.documentElement.clientHeight) ||\n\t\trect.left > (window.innerWidth || document.documentElement.clientWidth)\n\t);\n}\n\nfunction isElementPartiallyInViewport(el) {\n\tconst rect = el.getBoundingClientRect();\n\tconst viewportWidth = window.innerWidth || document.documentElement.clientWidth;\n\tconst viewportHeight = window.innerHeight || document.documentElement.clientHeight;\n\n\treturn (\n\t\trect.bottom > 0 &&\n\t\trect.right > 0 &&\n\t\trect.left < viewportWidth &&\n\t\trect.top < viewportHeight\n\t);\n}\n\nfunction isElementBottomInViewport(el) {\n\tconst rect = el.getBoundingClientRect();\n\tconst windowHeight = window.innerHeight || document.documentElement.clientHeight;\n\n\treturn rect.bottom >= 0 && rect.bottom <= windowHeight;\n}\n\nfunction introProductZoom() {\n\tconst frontViewImage = document.querySelector('.c-detail__images-item[data-anchor=\"frontView\"]');\n\tif (!frontViewImage) return;\n\n    const imageWrap = frontViewImage.querySelector('.c-detail__images-item--wrap');\n    if (!imageWrap) return;\n\n\tif (window.innerWidth >= 1024) {\n\t\tconst imageWrap = frontViewImage.querySelector('.c-detail__images-item--wrap');\n\t\tconst introHeight = frontViewImage.querySelector('.c-detail__images-item--intro').clientHeight;\n\t\tconst wrapHeight = imageWrap.clientHeight;\n\t\tconst wrapRect = imageWrap.getBoundingClientRect();\n\t\tconst wrapValue = wrapRect.y + wrapHeight;\n\t\tconst offsetTop = wrapValue - wrapHeight;\n\t\tconst scaleValue = (offsetTop / (wrapHeight / 2) + 1) * 33.33;\n\n\t\tconst detailFixed = document.querySelector('.c-detail__fixed');\n\t\tconst shouldShowFixed = window.scrollY - introHeight / 1.5 >= 0;\n\n\t\tdetailFixed.classList.toggle('js--visible', shouldShowFixed);\n\n\t\timageWrap.style.width = Math.round(offsetTop) >= 0 ? `${scaleValue}%` : '33.33%';\n\t} else {\n\t\tconst imageWrap = frontViewImage.querySelector('.c-detail__images-item--wrap');\n\t\timageWrap.style.width = 'unset';\n\t}\n}\n\nfunction nightView() {\n\tconst nightViewImage = document.querySelector('.c-detail__images-item[data-anchor=\"nightView\"]');\n\tif (!nightViewImage) return;\n\n\tconst nightviewEl = nightViewImage;\n\tconst nightviewHeight = nightviewEl.clientHeight;\n\tconst currentOffsetY = window.scrollY;\n\tconst nightviewRect = nightviewEl.getBoundingClientRect();\n\tconst nightviewOffsetY = nightviewRect.y + window.scrollY;\n\n\tconst header = document.querySelector('.c-header');\n\tconst body = document.querySelector('body');\n\tconst detail = document.querySelector('.c-detail');\n\tconst darkmodeStatus = document.body.classList.contains('is--darkmode');\n\n\tconst isNightViewFocused = currentOffsetY >= (nightviewOffsetY - nightviewHeight / 2) && currentOffsetY <= (nightviewOffsetY + nightviewHeight / 2);\n\n\tif (window.innerWidth >= 1024) {\n\t\tif (darkmodeStatus == false) {\n\t\t\theader.classList.toggle('is--dark-header', isNightViewFocused);\n\t\t\theader.classList.toggle('is--light-header', !isNightViewFocused);\n\t\t\tbody.classList.toggle('is--nightview', isNightViewFocused);\n\t\t}\n\t}\n}\n\nfunction handleStickyInfos() {\n\tif (window.innerWidth >= 1024) {\n\t\tconst imageContainer = document.querySelector('.c-detail__images');\n\t\tconst fixedInfos = document.querySelector('.c-detail__fixed');\n\t\tconst windowHeight = window.innerHeight;\n\n\t\tif (isElementPartiallyInViewport(imageContainer)) {\n\t\t\tfixedInfos.style.top = '0';\n\n\t\t\tif (isElementBottomInViewport(imageContainer)) {\n\t\t\t\tconst bottomOffset = imageContainer.getBoundingClientRect().bottom - windowHeight;\n\t\t\t\tfixedInfos.style.top = `${bottomOffset}px`;\n\t\t\t}\n\t\t}\n\n\t\tif (isElementNotInViewport(imageContainer)) {\n\t\t\tfixedInfos.classList.remove('js--visible');\n\t\t}\n\t}\n}\n\nfunction handleStickyHeader() {\n\tif (window.innerWidth >= 1024) {\n\t\tconst mainHeader = document.querySelector('.c-header');\n\t\tconst stickyHeader = document.querySelector('.c-detail__sticky');\n\t\tconst allContents = document.querySelectorAll('.c-detail__main');\n\n\t\tif (mainHeader && stickyHeader) {\n\t\t\tconst mainHeaderHeight = mainHeader.clientHeight;\n\t\t\tconst stickyHeaderHeight = stickyHeader.clientHeight;\n\t\t\tconst topWhenStickyVisible = `${mainHeaderHeight}px`;\n\t\t\tconst topWhenStickyHidden = `${mainHeaderHeight - stickyHeaderHeight - 1}px`;\n\n\t\t\tallContents.forEach(item => {\n\t\t\t\tconst isSticky = isElementNotInViewport(item);\n\t\t\t\tstickyHeader.style.top = isSticky ? topWhenStickyVisible : topWhenStickyHidden;\n\t\t\t\tstickyHeader.classList.toggle('js--sticky', isSticky);\n\t\t\t});\n\t\t}\n\t}\n}\n\nfunction setupAnchorLinks() {\n\tif (window.innerWidth >= 1024) {\n\t\tconst anchorContainer = document.querySelector('.c-detail__anchors');\n\t\tif (!anchorContainer) return;\n\n\t\tanchorContainer.addEventListener('click', event => {\n\t\t\tconst clickedItem = event.target.closest('.c-detail__anchors-item');\n\t\t\tif (!clickedItem) return;\n\n\t\t\tevent.preventDefault();\n\n\t\t\tconst anchor = clickedItem.getAttribute('data-target');\n\t\t\tconst targetElement = document.querySelector(`.c-detail__images-item[data-anchor=${anchor}]`);\n\n\t\t\tif (targetElement) {\n\t\t\t\tconst offsetY = targetElement.getBoundingClientRect().top + window.scrollY;\n\t\t\t\twindow.scrollTo({\n\t\t\t\t\ttop: offsetY,\n\t\t\t\t\tbehavior: 'smooth'\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\t}\n}\n\nfunction initializeProductSlider() {\n\tlet detailSlider;\n\n\tconst sliderElement = document.querySelector('.c-detail__images.glide');\n\n\tif (!sliderElement) {\n\t\treturn;\n\t}\n\n\tif (window.innerWidth >= 1024) {\n\t\tif (detailSlider) {\n\t\t\tdetailSlider.disable();\n\t\t}\n\t} else {\n\t\tdetailSlider = new _glidejs_glide__WEBPACK_IMPORTED_MODULE_0__[\"default\"](sliderElement, {\n\t\t\ttype: 'slider',\n\t\t\tgap: 0,\n\t\t\tanimationDuration: 1000,\n\t\t\tanimationTimingFunc: 'cubic-bezier(.44,.05,.19,.94)',\n\t\t\tperView: 2,\n\t\t\tfocusAt: 'center',\n\t\t\tbreakpoints: {\n\t\t\t\t767: {\n\t\t\t\t\tperView: 1\n\t\t\t\t}\n\t\t\t}\n\t\t}).mount();\n\t}\n}\n\n\nlet isScrolling = false;\nlet isResizing = false;\n\nfunction onScroll() {\n\tif (!isScrolling) {\n\t\tisScrolling = true;\n\t\twindow.requestAnimationFrame(() => {\n\t\t\tintroProductZoom();\n\t\t\thandleStickyInfos();\n\t\t\tnightView();\n\t\t\thandleStickyHeader();\n\t\t\tisScrolling = false;\n\t\t});\n\t}\n}\n\nfunction onResize() {\n\tif (!isResizing) {\n\t\tisResizing = true;\n\t\twindow.requestAnimationFrame(() => {\n\t\t\tinitializeProductSlider();\n\t\t\tintroProductZoom();\n\t\t\thandleStickyInfos();\n\t\t\tnightView();\n\t\t\tsetupAnchorLinks();\n\t\t\thandleStickyHeader();\n\t\t\tisResizing = false;\n\t\t});\n\t}\n}\n\nfunction initialSetup() {\n\tinitializeProductSlider();\n\tintroProductZoom();\n\thandleStickyInfos();\n\tnightView();\n\tsetupAnchorLinks();\n\thandleStickyHeader();\n}\n\nif (productDetailPage) {\n\tdocument.addEventListener('DOMContentLoaded', initialSetup);\n\twindow.addEventListener('scroll', onScroll);\n\twindow.innerWidth >= 1024 ? window.addEventListener('resize', onResize) : null;\n}\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/productDetailScrolling.js?");/***/}),/***/"./source/out/sinn/src/js/modules/productFilter/StrapFinder.js":(/*!*********************************************************************!*\
  !*** ./source/out/sinn/src/js/modules/productFilter/StrapFinder.js ***!
  \*********************************************************************/ /***/function sourceOutSinnSrcJsModulesProductFilterStrapFinderJs(){eval("/**\n * StrapFinder widget for handling all form submissions and interactions\n */\nclass StrapFinder {\n    /**\n     * Initialize all StrapFinder forms and their handlers\n     */\n    constructor() {\n        this.resetForm = document.getElementById('resetSelectionForm');\n        this.watchForm = document.getElementById('watchFilter');\n        this.lugWidthForm = document.getElementById('lugWidthFilter');\n        this.init();\n    }\n\n    /**\n     * Initialize event listeners for all forms\n     */\n    init() {\n        this.initResetForm();\n        this.initWatchForm();\n        this.initLugWidthForm();\n    }\n\n    /**\n     * Initialize reset form listeners\n     * Handles checkbox changes for watch and lug width selections\n     */\n    initResetForm() {\n        if (!this.resetForm) {\n            return;\n        }\n\n        // Watch checkbox\n        const watchCheckbox = this.resetForm.querySelector('input[name=\"watchselection\"]');\n        if (watchCheckbox) {\n            watchCheckbox.addEventListener('change', () => this.resetForm.submit());\n        }\n\n        // Lug width checkbox\n        const lugWidthCheckbox = this.resetForm.querySelector('input[name=\"lugwidthselection\"]');\n        if (lugWidthCheckbox) {\n            lugWidthCheckbox.addEventListener('change', () => this.resetForm.submit());\n        }\n\n        // Buckle width checkbox\n        const buckleWidthCheckbox = this.resetForm.querySelector('input[name=\"bucklewidthselection\"]');\n        if (buckleWidthCheckbox) {\n            buckleWidthCheckbox.addEventListener('change', () => this.resetForm.submit());\n        }\n    }\n\n    /**\n     * Initialize watch form listeners\n     * Prevents form submission for offcanvas toggles and handles watch selection\n     */\n    initWatchForm() {\n        if (!this.watchForm) {\n            return;\n        }\n\n        // Prevent form submission for offcanvas toggle buttons\n        const toggleButtons = this.watchForm.querySelectorAll('.c-offcanvas__toggle');\n        toggleButtons.forEach(button => {\n            button.addEventListener('click', (event) => {\n                event.preventDefault();\n            });\n        });\n\n        // Submit form when clicking watch selection buttons\n        const watchButtons = this.watchForm.querySelectorAll('button[name=\"selectedwatch\"]');\n        watchButtons.forEach(button => {\n            button.addEventListener('click', () => this.watchForm.submit());\n        });\n    }\n\n    /**\n     * Initialize lug width form listeners\n     * Handles label clicks and radio button selection\n     */\n    initLugWidthForm() {\n        if (!this.lugWidthForm) {\n            return;\n        }\n\n        // Handle label clicks for radio buttons\n        const labels = this.lugWidthForm.querySelectorAll('.c-attrfilter__label');\n        labels.forEach(label => {\n            label.addEventListener('click', (event) => {\n                const radioId = label.getAttribute('for');\n                const radio = document.getElementById(radioId);\n                \n                if (radio) {\n                    radio.checked = true;\n                    setTimeout(() => {\n                        this.lugWidthForm.submit();\n                    }, 100);\n                }\n            });\n        });\n    }\n}\n\n// Initialize the StrapFinder when DOM is ready\ndocument.addEventListener('DOMContentLoaded', () => {\n    new StrapFinder();\n});\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/productFilter/StrapFinder.js?");/***/}),/***/"./source/out/sinn/src/js/modules/productFilter/activeFilterAttributesCounter.js":(/*!***************************************************************************************!*\
  !*** ./source/out/sinn/src/js/modules/productFilter/activeFilterAttributesCounter.js ***!
  \***************************************************************************************/ /***/function sourceOutSinnSrcJsModulesProductFilterActiveFilterAttributesCounterJs(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"default\": () => (/* binding */ initActiveFilterCounter)\n/* harmony export */ });\n/**\n * This Software is the property of dotfly and is protected\n * by copyright law - it is NOT Freeware.\n *\n * Any unauthorized use of this software without a valid license key\n * is a violation of the license agreement and will be prosecuted by\n * civil and criminal law.\n *\n * @category   Counts active filter attributes\n * @author     Anna Morawe <anna.morawe@dotfly.de>\n * @license    http://www.dotfly.de Commercial\n * @link       http://www.dotfly.de\n */\n\nfunction initActiveFilterCounter() {\n    const checkboxes = document.querySelectorAll('.c-refinelayer__group-fieldset input[type=\"checkbox\"]');\n    const spans = document.querySelectorAll('.js--counter');\n\n    if (checkboxes.length === 0 || spans.length === 0) return;\n\n    const updateCheckedCount = () => {\n        const checkedCount = [...checkboxes].reduce((count, checkbox) => count + checkbox.checked, 0);\n\n        spans.forEach(span => {\n            if (checkedCount > 0) {\n                span.textContent = checkedCount;\n                span.style.display = 'block';\n            } else {\n                span.style.display = 'none';\n            }\n        });\n    };\n\n    checkboxes.forEach(checkbox => checkbox.addEventListener('change', updateCheckedCount));\n    updateCheckedCount();\n}\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/productFilter/activeFilterAttributesCounter.js?");/***/}),/***/"./source/out/sinn/src/js/modules/productFilter/filterAjax.js":(/*!********************************************************************!*\
  !*** ./source/out/sinn/src/js/modules/productFilter/filterAjax.js ***!
  \********************************************************************/ /***/function sourceOutSinnSrcJsModulesProductFilterFilterAjaxJs(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _activeFilterAttributesCounter_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./activeFilterAttributesCounter.js */ \"./source/out/sinn/src/js/modules/productFilter/activeFilterAttributesCounter.js\");\n/**\n * This Software is the property of dotfly and is protected\n * by copyright law - it is NOT Freeware.\n *\n * Any unauthorized use of this software without a valid license key\n * is a violation of the license agreement and will be prosecuted by\n * civil and criminal law.\n *\n * @category   Initializes the filter form with Ajax and updates the number of active filters\n * @author     Anna Morawe <anna.morawe@dotfly.de>\n * @license    http://www.dotfly.de Commercial\n * @link       http://www.dotfly.de\n */\n\n// Zählt aktive Filter und zeigt die Anzahl an\n\n\ndocument.addEventListener('DOMContentLoaded', () => {\n    const liveRegion = document.getElementById('filterLiveRegion');\n\n    // Scrollposition vom vorherigen Filter-Link-Klick wiederherstellen\n    const savedScroll = sessionStorage.getItem('scrollPositionBeforeFilterSubmit');\n    if (savedScroll !== null) {\n        window.scrollTo({ top: parseInt(savedScroll, 10), behavior: 'auto' });\n        sessionStorage.removeItem('scrollPositionBeforeFilterSubmit');\n    }\n\n    // Initialisiere Event-Handling für das Filterformular\n    initFilterFormEvents();\n\n    // Zeige Anzahl aktiver Filter an\n    (0,_activeFilterAttributesCounter_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])();\n\n    // Scrollposition speichern, wenn auf Filter- oder Reset-Links geklickt wird\n    document.addEventListener('click', (event) => {\n        const target = event.target.closest('.c-refinelayer__closebutton, .c-refinelayer__resetbutton');\n        if (target) {\n            sessionStorage.setItem('scrollPositionBeforeFilterSubmit', window.scrollY);\n        }\n    });\n\n    function initFilterFormEvents() {\n        const filterForm = document.getElementById('filterList');\n        if (!filterForm) return;\n\n        let debounceTimeout;\n\n        // Warten, bevor das Formular nach Auswahländerung neu geladen wird\n        filterForm.addEventListener('change', () => {\n            clearTimeout(debounceTimeout);\n\n            debounceTimeout = setTimeout(() => {\n                submitFilterForm(filterForm);\n            }, 5);\n        });\n    }\n\n    function submitFilterForm(form) {\n        const formData = new FormData(form);\n        const actionUrl = form.action;\n\n        // Sende Formulardaten per Ajax an den Server\n        fetch(actionUrl, {\n            method: 'POST',\n            body: formData,\n        })\n            .then(response => response.text())\n            .then(html => handleFilterResponse(html, form))\n            .catch(error => {\n                console.error('Fehler beim Laden der Filterattribute:', error);\n            });\n    }\n\n    function handleFilterResponse(html, oldForm) {\n        const parser = new DOMParser();\n        const newDocument = parser.parseFromString(html, 'text/html');\n        const newForm = newDocument.getElementById('filterList');\n        if (!newForm) return;\n\n        // Merke aktuell fokussiertes Element und Scrollposition\n        const previouslyFocused = document.activeElement;\n        const scrollY = window.scrollY;\n\n        // Ersetze das Filterformular mit aktualisierter Version\n        oldForm.replaceWith(newForm);\n        initFilterFormEvents();\n        (0,_activeFilterAttributesCounter_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])();\n\n        // Stelle Fokus auf vorher fokussierte Checkbox wieder her\n        if (\n            previouslyFocused &&\n            previouslyFocused.name &&\n            previouslyFocused.value\n        ) {\n            const selector = `input[name=\"${previouslyFocused.name}\"][value=\"${previouslyFocused.value}\"]`;\n            const replacement = newForm.querySelector(selector);\n            if (replacement) {\n                replacement.focus();\n            }\n        }\n\n        // Setze Scrollposition auf vorherige Position zurück\n        window.scrollTo({ top: scrollY });\n\n        // Aktualisiere Live-Region für Screenreader\n        if (liveRegion) {\n            const updateText = window.oWave?.i18n?.DOT_FILTER_UPDATED || 'Filterergebnisse wurden aktualisiert.';\n            liveRegion.textContent = updateText;\n        }\n    }\n});\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/productFilter/filterAjax.js?");/***/}),/***/"./source/out/sinn/src/js/modules/productslider.js":(/*!*********************************************************!*\
  !*** ./source/out/sinn/src/js/modules/productslider.js ***!
  \*********************************************************/ /***/function sourceOutSinnSrcJsModulesProductsliderJs(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _glidejs_glide__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @glidejs/glide */ \"./node_modules/@glidejs/glide/dist/glide.esm.js\");\n\n\nif (document.querySelector('.js-productslider')) {\n\tvar productslider = new _glidejs_glide__WEBPACK_IMPORTED_MODULE_0__[\"default\"]('.js-productslider', {\n\t\ttype: 'carousel',\n\t\tperView: 2,\n\t\tanimationDuration: 1000,\n\t\tanimationTimingFunc: 'cubic-bezier(.44,.05,.19,.94)',\n\t\tgap: 0,\n\t\tpeek: {\n\t\t\tbefore: 0,\n\t\t\tafter: 180\n\t\t},\n\t\tbreakpoints: {\n\t\t\t1024: {\n\t\t\t\tperView: 1,\n\t\t\t\tpeek: {\n\t\t\t\t\tbefore: 0,\n\t\t\t\t\tafter: 220\n\t\t\t\t}\n\t\t\t},\n\t\t\t768: {\n\t\t\t\tperView: 1,\n\t\t\t\tpeek: {\n\t\t\t\t\tbefore: 0,\n\t\t\t\t\tafter: 80\n\t\t\t\t}\n\t\t\t},\n\t\t\t400: {\n\t\t\t\tperView: 1,\n\t\t\t\tpeek: {\n\t\t\t\t\tbefore: 0,\n\t\t\t\t\tafter: 80\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t})\n\n\tproductslider.mount()\n}\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/productslider.js?");/***/}),/***/"./source/out/sinn/src/js/modules/register.js":(/*!****************************************************!*\
  !*** ./source/out/sinn/src/js/modules/register.js ***!
  \****************************************************/ /***/function sourceOutSinnSrcJsModulesRegisterJs(){eval("/**\n * This Software is the property of dotfly and is protected\n * by copyright law - it is NOT Freeware.\n *\n * Any unauthorized use of this software without a valid license key\n * is a violation of the license agreement and will be prosecuted by\n * civil and criminal law.\n *\n * @category   Form validation for our fancy registration form\n * @author     Anna Morawe <anna.morawe@dotfly.de>\n * @license    http://www.dotfly.de Commercial\n * @link       http://www.dotfly.de\n */\n\nconst fancyRegistrationForm = document.querySelector('.js--fancyFormErrors');\n\nif (fancyRegistrationForm) {\n\tfancyRegistrationForm.addEventListener('submit', function(event) {\n\n\t\tevent.preventDefault();\n\n\t\tfancyRegistrationForm.querySelector('.c-register__error').innerHTML = '';\n\t\tfancyRegistrationForm.querySelector('.c-register__error').style.display = 'none';\n\n\t\t$.ajax({\n\t\t\tmethod: \"POST\",\n\t\t\turl: document.getElementById('ajaxTargetMB').value + \"cl=user&fnc=validateUserDataForRegister&stoken=\" + document.getElementById('sessionTokenMB').value,\n\t\t\tdata: {\n\t\t\t\tusername: fancyRegistrationForm.querySelector(\"[name='lgn_usr']\").value,\n\t\t\t\tpassword: fancyRegistrationForm.querySelector(\"[name='lgn_pwd']\").value,\n\t\t\t\tcheck_password: fancyRegistrationForm.querySelector(\"[name='lgn_pwd2']\").value\n\t\t\t},\n\t\t\tsuccess: function(ret, data) {\n\t\t\t\tif (ret.length) {\n\t\t\t\t\tfancyRegistrationForm.querySelector('.c-register__error').innerHTML = ret;\n\t\t\t\t\tfancyRegistrationForm.querySelector('.c-register__error').style.display = 'block';\n\t\t\t\t} else {\n\t\t\t\t\tif (!fancyRegistrationForm.querySelector('.is--error')) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t// Tracking\n\t\t\t\t\t\t\t_etracker.sendEvent(new et_UserDefinedEvent('Standardformular', 'Registrierung', 'Formular abgesendet', 'Formular'));\n\t\t\t\t\t\t} finally {\n\t\t\t\t\t\t\t// Submit\n\t\t\t\t\t\t\tfancyRegistrationForm.submit();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t});\n}\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/register.js?");/***/}),/***/"./source/out/sinn/src/js/modules/registerOffcanvas.js":(/*!*************************************************************!*\
  !*** ./source/out/sinn/src/js/modules/registerOffcanvas.js ***!
  \*************************************************************/ /***/function sourceOutSinnSrcJsModulesRegisterOffcanvasJs(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   registerOffcanvas: () => (/* binding */ registerOffcanvas)\n/* harmony export */ });\n/* harmony import */ var _focusTrap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./focusTrap */ \"./source/out/sinn/src/js/modules/focusTrap.js\");\n\n\nfunction getNodeListFromOption(options, optionName, defaultValue) {\n    if (! (optionName in options)) {\n        return defaultValue || false;\n    }\n\n    if (Object.prototype.isPrototypeOf.call(NodeList.prototype, options[optionName])) {\n        return options[optionName];\n    }\n\n    return  document.querySelectorAll(options[optionName]);\n}\n\nconst registerOffcanvas = function(options={}) {\n    const body = document.querySelector('body');\n    const offCanvas = document.querySelector(options.offCanvas);\n    if (!offCanvas) {\n        return;\n    }\n    const triggers = getNodeListFromOption(options, 'triggers');\n    const closeButtons = getNodeListFromOption(\n        options,\n        'closeButtons',\n        offCanvas.querySelectorAll('.c-offcanvas__close, .c-offcanvas__background')\n    );\n    const classActive = 'js--active';\n    let openerTrigger;\n\n\n    const resetMobileCanvas = function() {\n        let activeCanvasesMobile = document.querySelectorAll('.c-mobilemenu__item.js--active');\n\n        activeCanvasesMobile.forEach(element => {\n            let canvas = document.querySelector('.' + element.dataset.layer);\n            //animate\n            element.classList.remove(classActive);\n            canvas.classList.remove(classActive);\n\n            //edge case retailer footer\n            const footerTrigger = document.querySelector('a[href=\"#fachhändler\"].js--active');\n            footerTrigger && footerTrigger.classList.remove(classActive);\n\n            // edge case search input focus blur input\n            const searchField = document.querySelector('.c-search.js--active #searchParam');\n            let searchTriggerMobile = document.querySelector('#mobileSearchTrigger');\n            searchTriggerMobile && searchTriggerMobile.classList.remove('is--focused');\n            searchField && searchField.blur();\n\n            //display none after aninmation\n            const transitionEndHandler = function (event) {\n                if (event.target === canvas.firstElementChild) {\n                    canvas.firstElementChild.removeEventListener('transitionend', transitionEndHandler);\n                    canvas.style = 'display: none';\n                }\n            };\n            canvas.firstElementChild.addEventListener('transitionend', transitionEndHandler);\n        });\n    }\n\n    const openOffcanvas = function(eventTarget) {\n        openerTrigger = eventTarget;\n\n        //close mobile offcanvases before opening another (only on mobile and only if this offcanvas is not already open)\n        const isMobile = window.innerWidth <= 1024 || document.querySelectorAll('.c-mobilemenu__item.js--active').length > 0;\n        const isAlreadyOpen = offCanvas.classList.contains(classActive);\n        if (isMobile && !isAlreadyOpen) {\n            resetMobileCanvas();\n        }\n\n        //display the canvas\n        offCanvas.style = 'display: block;'\n\n        document.body.addEventListener('keydown', closeOffcanvasByEscListener);\n\n        requestAnimationFrame(() => {\n            // Use a slight delay if needed to ensure everything is fully applied\n            setTimeout(() => {\n                // Trigger scss animation after canvas is displayed\n                offCanvas.classList.add(classActive);\n                triggers && triggers.forEach(item => {\n                    item.classList.add(classActive);\n                });\n\n                // Focus on first interactive Element\n                const firstFocusable = offCanvas.querySelector('button, [href], input:not([type=\"hidden\"]), select, textarea, [tabindex]:not([tabindex=\"-1\"])');\n                if (firstFocusable) {\n                    firstFocusable.focus();\n                }\n\n            }, 0);\n        });\n\n        (0,_focusTrap__WEBPACK_IMPORTED_MODULE_0__.createFocusTrap)(offCanvas.querySelector('.c-offcanvas__inner'));\n\n        eventTarget && eventTarget.setAttribute('aria-expanded', true);\n        body.classList.add('no--scroll');\n    }\n\n    const closeOffcanvasListener = function (event) {\n        const offCanvasInner = offCanvas.querySelector('.c-offcanvas__inner');\n\n        // Clean up all focus traps when closing\n        (0,_focusTrap__WEBPACK_IMPORTED_MODULE_0__.cleanupAllFocusTraps)();\n\n        //wait for c-offcanvas__inner transition\n        const canvasClosedListener = function (event) {\n            if (event.target === offCanvasInner) {\n                offCanvasInner.removeEventListener('transitionend', canvasClosedListener);\n                triggers && triggers.forEach(item => {\n                    item.classList.remove(classActive);\n                    item.setAttribute('aria-expanded', false);\n                });\n                offCanvas.style = 'display: none';\n            }\n        };\n\n        offCanvasInner && offCanvasInner.addEventListener('transitionend', canvasClosedListener);\n        offCanvas.classList.remove(classActive);\n        document.body.removeEventListener('keydown', closeOffcanvasByEscListener);\n        body.classList.remove('no--scroll');\n\n        // Wenn Overlay durch Escape geschlossen wird, wird der Focus auf das Trigger-Element zurückgesetzt\n        if (event.detail === 0) {\n            openerTrigger && openerTrigger.focus({ focusVisible: true });\n        }\n    }\n\n    const closeOffcanvasByEscListener = function(event) {\n        if (event.key === 'Escape' || event.key === 'Esc' || event.keyCode === 27) {\n            closeOffcanvasListener(event);\n            // Focus auf das Trigger-Element zurücksetzen\n            openerTrigger && openerTrigger.focus({ focusVisible: true });\n        }\n    }\n\n    closeButtons && closeButtons.forEach(close => {\n        close.addEventListener('click', closeOffcanvasListener);\n    });\n\n    triggers && triggers.forEach(trigger => {\n        trigger.addEventListener('click', (event) => {\n            trigger.classList.contains(classActive)\n                ? closeOffcanvasListener(event)\n                : openOffcanvas(event.currentTarget);\n        });\n\n        // force click on enter\n        trigger.addEventListener('keydown', (event) => {\n            if (event.key === 'Enter' || event.keyCode === 13) {\n                event.preventDefault();\n                trigger.click();\n            }\n        });\n    });\n\n    // Make function openOffcanvas available for method chaining, after calling registerOffcanvas\n    return {\n        openOffcanvas\n    }\n}\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/registerOffcanvas.js?");/***/}),/***/"./source/out/sinn/src/js/modules/removeFromWishlist.js":(/*!**************************************************************!*\
  !*** ./source/out/sinn/src/js/modules/removeFromWishlist.js ***!
  \**************************************************************/ /***/function sourceOutSinnSrcJsModulesRemoveFromWishlistJs(){eval("/**\n * This Software is the property of dotfly and is protected\n * by copyright law - it is NOT Freeware.\n *\n * Any unauthorized use of this software without a valid license key\n * is a violation of the license agreement and will be prosecuted by\n * civil and criminal law.\n *\n * @category   Removes item from wishlist\n * @author     dotfly <info@dotfly.de>\n * @license    http://www.dotfly.de Commercial\n * @link       http://www.dotfly.de\n */\n\ndocument.querySelectorAll('button.removeButton').forEach(function(button) {\n    const formId = button.getAttribute('triggerForm');\n    button.addEventListener('click', function(event) {\n        event.preventDefault();\n        const form = document.getElementById(formId);\n        if (form) {\n            form.submit();\n        }\n    });\n});\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/removeFromWishlist.js?");/***/}),/***/"./source/out/sinn/src/js/modules/retailer.js":(/*!****************************************************!*\
  !*** ./source/out/sinn/src/js/modules/retailer.js ***!
  \****************************************************/ /***/function sourceOutSinnSrcJsModulesRetailerJs(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _retailerMap_GoogleMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./retailerMap/GoogleMap */ \"./source/out/sinn/src/js/modules/retailerMap/GoogleMap.js\");\n/* harmony import */ var _retailerMap_config__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./retailerMap/config */ \"./source/out/sinn/src/js/modules/retailerMap/config.js\");\n/* harmony import */ var _animation__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./animation */ \"./source/out/sinn/src/js/modules/animation.js\");\n/* harmony import */ var _registerOffcanvas__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./registerOffcanvas */ \"./source/out/sinn/src/js/modules/registerOffcanvas.js\");\n\n\n\n\n//init element variables\nlet retailerMap;\nlet retailerResults;\nlet retailerNoResults;\nlet retailerForm;\nlet retailerInput;\nlet retailerSuggestions;\nlet consentBox;\nlet consentButton;\nlet closeButton;\n\nvar retailerBaseURL       = '/widget.php?actcontrol=start&cl=showdealers&searchdealer=';\nvar cubicBezier           = 'cubicBezier(.40,.05,.20,.90)';\n\nconst retailerSelectors = {\n    triggers: '.c-function.is--dealer .c-function__label, a[href=\"#fachhändler\"], .c-mobilemenu__item.is--retailer'\n}\nvar retailerTerm, retailerResultsURL, content, items, resultsItems, languageParam;\nvar isAutoSearch = true;\n\nvar fetchResults = function (event) {\n    if (event) {\n        event.preventDefault();\n        event.stopPropagation();\n\n        if (event.keyCode == 13) {\n            event.preventDefault();\n            return false;\n        }\n        isAutoSearch = false;\n    }\n\n    // Reset \"results\" message at the start of each search\n    retailerResults.style.display = 'none';\n    retailerNoResults.style.display = 'none';\n\n    // Use selectedUserCountry if input is empty\n    retailerTerm = document.querySelector('.c-retailer .c-retailer__row .e-form__input').value || selectedUserCountry;\n    languageParam = '&lang=' + document.querySelector('.c-retailer .c-retailer__row input[name=\"lang\"]').value;\n    retailerResultsURL = (retailerBaseURL + retailerTerm + languageParam);\n\n    fetch(retailerResultsURL)\n        .then(function (response) {\n            return response.json();\n        })\n        .then(function (data) {\n            // Fill Container with items\n            items = (0,_retailerMap_config__WEBPACK_IMPORTED_MODULE_1__.showAllDealers)(data);\n            content = items;\n            retailerResults.innerHTML = content;\n        })\n        .then(function () {\n            resultsItems = document.querySelectorAll('.c-retailer__results .c-retailer__item');\n\n            if (resultsItems.length > 0) {\n                retailerResults.style.display = 'flex';\n                retailerNoResults.style.display = 'none';\n\n                resultsItems.forEach(function (item) {\n                  item.classList.remove('is--hidden');\n                });\n\n            } else if (!isAutoSearch) {\n                retailerResults.style.display = 'none';\n                retailerNoResults.style.display = 'flex';\n            } else if (isAutoSearch) {\n                retailerResults.style.display = 'flex';\n                retailerNoResults.style.display = 'none';\n            }\n\n            //hide consent on keyboard input\n            if (_animation__WEBPACK_IMPORTED_MODULE_2__.isKeyboardInput) {\n                document.cookie = \"gmConsent=false; path=/; secure; samesite; domain=\" + window.location.hostname + \";\"\n                hideConsentLayer();\n                consentBox.style.display = 'flex';\n                consentBox.querySelector('.c-retailer__consent--wrapper').style.display = 'none';\n                consentBox.querySelector('.c-retailer__consent--backdrop').style.display = 'none';\n            }\n\n            //open overlay after fetch\n            (0,_registerOffcanvas__WEBPACK_IMPORTED_MODULE_3__.registerOffcanvas)({\n                offCanvas: '.c-retailer',\n                triggers: retailerSelectors.triggers,\n            }).openOffcanvas(document.querySelector('.c-function.is--dealer'));\n        })\n        .catch(function (err) {\n            retailerResults.style.display = 'none';\n            retailerNoResults.style.display = 'flex';\n\n            (0,_registerOffcanvas__WEBPACK_IMPORTED_MODULE_3__.registerOffcanvas)({\n                offCanvas: '.c-retailer',\n                triggers: retailerSelectors.triggers,\n            }).openOffcanvas(document.querySelector('.c-function.is--dealer'));\n        });\n\n    return false;\n};\n\n// =====================================================================================================\n// Google Maps\n\n// give consent\nconst consent = () => {\n\t// set session cookie\n\tdocument.cookie = \"gmConsent=true; path=/; secure; samesite; domain=\" + window.location.hostname + \";\"\n\thideConsentLayer()\n\tinitMap()\n}\n\n// manages classes depending on consent status\nconst setConsentStateClasses = () => {\n\tconst getCookie = (name) => {\n\t\tconst value = `; ${document.cookie}`;\n\t\tconst parts = value.split(`; ${name}=`);\n\t\tif (parts.length === 2) return parts.pop().split(';').shift();\n\t\treturn null;\n\t};\n\tconst gmConsent = getCookie('gmConsent');\n\n\tif (gmConsent === null) {\n\t\t//console.log('Consent NOT DECIDED YET');\n\t\tretailerMap.classList.add('consent-expected');\n\t\treturn;\n\t}\n\n\tconst mapElement = document.getElementById('map');\n\n\tif (gmConsent === 'true') {\n\t\tmapElement.classList.add('consent-yes');\n\t\tmapElement.classList.remove('consent-no');\n\t\tmapElement.classList.remove('consent-expected');\n\t\t//console.log('Consent YES');\n\t} else if (gmConsent === 'false') {\n\t\tmapElement.classList.add('consent-no');\n\t\tmapElement.classList.remove('consent-yes');\n\t\tmapElement.classList.remove('consent-expected');\n\t\t//console.log('Consent NO');\n\t}\n}\n\n// hide the consent form\nconst hideConsentLayer = () => {\n\tconsentBox.style.display = 'none';\n}\n\n// obeserve, if map is visible\nconst mapObserver = new IntersectionObserver( entries => {\n\tentries.forEach(entry => {\n\t\tif (entry.isIntersecting) {\n\t\t\tinitMap()\n            mapObserver.unobserve(entry.target)\n\t\t}\n\t})\n}, { threshold: 1 })\n\n// initialize the map when consent is given\nconst initMap = () => {\n\tlet mapContainer = document.getElementById('map');\n\tconst gmConsent = document.cookie.includes('gmConsent=true');\n\n\tif (gmConsent && mapContainer) {\n\t\tretailerInput.removeEventListener('keyup', fetchResults, false);\n\t\tretailerForm.removeEventListener('submit', fetchResults, false);\n\n\t\t_retailerMap_GoogleMap__WEBPACK_IMPORTED_MODULE_0__.GoogleMap('#map');\n\t\t_retailerMap_GoogleMap__WEBPACK_IMPORTED_MODULE_0__.initSearch(true);\n\t}\n};\n\nfunction initMapWithCountryFromCookie() {\n    retailerInput.value = selectedUserCountry;\n    fetchResults();\n    retailerInput.value = \"\";\n}\n\ndocument.addEventListener('retailerLoaded', () => {\n    //assign element variables after content is fetched\n    retailerMap = document.querySelector('.c-retailer__map');\n    retailerResults = document.querySelector('.c-retailer .c-retailer__results');\n    retailerNoResults = document.querySelector('.c-retailer__noresults');\n    retailerForm = document.querySelector('.c-retailer__submit');\n    retailerInput = document.querySelector('.c-retailer__submit .e-form__input');\n    retailerSuggestions = document.querySelector('.c-retailer__searchresults--list');\n    consentBox = document.getElementById('consentBox');\n    consentButton = consentBox.querySelector('.consent-button');\n    closeButton = document.querySelector('.c-retailer__close')\n\n    // assing event listeners\n    retailerForm.addEventListener('submit', fetchResults, false);\n    closeButton.addEventListener('click', (e) => {\n        // reset the map and search, if the layer is closed\n        _retailerMap_GoogleMap__WEBPACK_IMPORTED_MODULE_0__.resetToDefault()\n    })\n\n    // Init the search on the first awake with the user country\n    const retailerParam = document.getElementById('retailerParam');\n\n    const observer = new MutationObserver(() => {\n        const isInputEmpty = () => retailerParam.value.trim() === '';\n        const hasResults = () => retailerResults.querySelectorAll('.c-retailer__item').length > 0;\n        const hasSuggestions = () => retailerSuggestions.querySelectorAll('li').length > 0;\n\n        const updateDisplay = () => {\n            if (isInputEmpty()) {\n                // Input is empty: show results, hide \"no results\"\n                toggleDisplay(retailerResults, retailerNoResults, true);\n            } else if (hasResults()) {\n                // Results are available: show results, hide \"no results\"\n                toggleDisplay(retailerResults, retailerNoResults, true);\n            } else if (hasSuggestions()) {\n                // Suggestions exist but no results: hide both\n                toggleDisplay(retailerResults, retailerNoResults, false, false);\n            } else {\n                // No results and no suggestions: show \"no results\"\n                toggleDisplay(retailerResults, retailerNoResults, false, true);\n            }\n        };\n\n        const toggleDisplay = (resultsEl, noResultsEl, showResults, showNoResults = false) => {\n            resultsEl.style.display = showResults ? 'flex' : 'none';\n            noResultsEl.style.display = showNoResults ? 'flex' : 'none';\n        };\n\n        retailerParam.addEventListener('input', () => {\n            if (isInputEmpty()) {\n                // Reset display when input is cleared\n                toggleDisplay(retailerResults, retailerNoResults, true);\n            } else if (!hasSuggestions() || !hasResults()) {\n                // Show \"no results\" if no suggestions or results\n                toggleDisplay(retailerResults, retailerNoResults, false, true);\n            } else {\n                console.log(\"Results are already displayed.\");\n                toggleDisplay(retailerResults, retailerNoResults, true);\n            }\n        });\n\n        updateDisplay();\n    });\n\n    // hide consent form and show map, if cookie is present and true\n    if (document.cookie.includes('gmConsent=true')) {\n        hideConsentLayer();\n        mapObserver.observe(document.getElementById('map'))\n    }\n\n    // show consent form and listen to the consent button\n    setConsentStateClasses();\n\n    if (consentButton) {\n        consentButton.addEventListener('click', (evt) => {\n            consent();\n            setConsentStateClasses();\n        })\n    }\n\n    isAutoSearch = true;\n\n    const rejectButton = consentBox.querySelector('.reject-button');\n    if (rejectButton) {\n        rejectButton.addEventListener('click', (evt) => {\n            document.cookie = \"gmConsent=false; path=/; secure; samesite; domain=\" + window.location.hostname + \";\"\n            //document.getElementById('map').style.display = 'none'\n            setConsentStateClasses();\n            _retailerMap_GoogleMap__WEBPACK_IMPORTED_MODULE_0__.initSearch(false);\n        })\n    }\n\n    observer.observe(retailerSuggestions, { childList: true });\n\n    // Initialize search with the user's country from the cookie\n    initMapWithCountryFromCookie();\n});\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/retailer.js?");/***/}),/***/"./source/out/sinn/src/js/modules/retailerMap/GoogleMap.js":(/*!*****************************************************************!*\
  !*** ./source/out/sinn/src/js/modules/retailerMap/GoogleMap.js ***!
  \*****************************************************************/ /***/function sourceOutSinnSrcJsModulesRetailerMapGoogleMapJs(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   GoogleMap: () => (/* binding */ GoogleMap),\n/* harmony export */   initSearch: () => (/* binding */ initSearch),\n/* harmony export */   resetToDefault: () => (/* binding */ resetToDefault)\n/* harmony export */ });\n/* harmony import */ var _GoogleMapsApi__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./GoogleMapsApi */ \"./source/out/sinn/src/js/modules/retailerMap/GoogleMapsApi.js\");\n/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./config */ \"./source/out/sinn/src/js/modules/retailerMap/config.js\");\n\n\n\nlet searchForm;\nlet searchField;\nlet searchResults;\nlet resultContainer;\nlet dataContainer;\nlet gmapApiKey;\ndocument.addEventListener('retailerLoaded', () => {\n    setGmApiKey();\n});\n\n/**\n * Location Map\n * Main map rendering function that uses our GMaps API class\n * @param {string} el - Google Map selector\n */\nfunction GoogleMap(el) {\n\n    const gmapApi = new _GoogleMapsApi__WEBPACK_IMPORTED_MODULE_0__[\"default\"](gmapApiKey, _config__WEBPACK_IMPORTED_MODULE_1__.config.language)\n    const mapEl = document.querySelector(el)\n\n    // Call map renderer\n    gmapApi.load().then(() => {\n        renderMap(mapEl)\n    })\n}\n\n/**\n * Render Map\n * @param {map obj} mapEl - Google Map\n * @param {obj} data - map data\n */\nfunction renderMap(mapEl) {\n\n    const options = {\n        styles: _config__WEBPACK_IMPORTED_MODULE_1__.mapStyle,\n        zoom: _config__WEBPACK_IMPORTED_MODULE_1__.mapConfig.zoom,\n        disableDefaultUI: _config__WEBPACK_IMPORTED_MODULE_1__.mapConfig.disableDefaultUI,\n        fullscreenControl: _config__WEBPACK_IMPORTED_MODULE_1__.mapConfig.fullscreenControl,\n        zoomControl: _config__WEBPACK_IMPORTED_MODULE_1__.mapConfig.zoomControl\n    }\n\n    window.map = new google.maps.Map(mapEl, options)\n    window.markers = []\n    window.retailers = []\n    window.infowindows = []\n    window.place = {}\n    window.placeIsCountry = false\n\n    // Fetch result JSON\n    fetch(_config__WEBPACK_IMPORTED_MODULE_1__.config.retailerJsonUrl)\n        .then(response => response.json())\n        .then(dealers => {\n            if (!dealers) return;\n\n            dataContainer.style.display = 'none';\n            dataContainer.innerHTML = (0,_config__WEBPACK_IMPORTED_MODULE_1__.showAllDealers)(dealers);\n\n            dealers.forEach(dealer => {\n                let retailerData = {\n                    oxid: dealer.oxid,\n                    lat: dealer.DOTLATITUDE,\n                    lng: dealer.DOTLONGITUDE,\n                    title: dealer.oxtitle,\n                    street: dealer.oxstreet,\n                    zip: dealer.oxzip,\n                    city: dealer.oxcity,\n                    country: dealer.countryTitle,\n                    phone: dealer.oxfon\n                }\n                if (retailerData.lat && retailerData.lng) {\n                    renderMarker(retailerData);\n                    window.retailers.push(retailerData);\n                }\n            });\n        })\n        .catch(err => console.log(err));\n    centerMap()\n}\n\nasync function centerMap() {\n    const coordinates = ( document.oxid.selectedCountry ? await geoCodeInitialCountry(document.oxid.selectedCountry) : _config__WEBPACK_IMPORTED_MODULE_1__.mapConfig.center)\n    window.map.setCenter(\n        new google.maps.LatLng(coordinates.lat, coordinates.lng)\n    )\n}\n\n/**\n * fetch the initial coordinates based on selected country\n * @param country\n * @returns {Promise<*>}\n */\nfunction geoCodeInitialCountry(country) {\n    return fetch(`https://maps.googleapis.com/maps/api/geocode/json?address=${country}&key=${gmapApiKey}`)\n        .then((response) => {\n            return response.json()\n        }).then(jsonData => {\n            return jsonData.results[0].geometry.location\n        })\n        .catch(error => {\n            console.log(error)\n        })\n}\n\n/**\n * Render Marker\n * Renders custom map marker and infowindow\n * @param {object} data\n */\nfunction renderMarker(data) {\n\n    const icon = {\n        url: _config__WEBPACK_IMPORTED_MODULE_1__.mapConfig.iconBase + _config__WEBPACK_IMPORTED_MODULE_1__.mapConfig.icon,\n        scaledSize: new google.maps.Size(_config__WEBPACK_IMPORTED_MODULE_1__.mapConfig.iconDimension, _config__WEBPACK_IMPORTED_MODULE_1__.mapConfig.iconDimension)\n    }\n\n    const tmpl = (0,_config__WEBPACK_IMPORTED_MODULE_1__.infoBoxTpl)(data)\n\n    const marker = new google.maps.Marker({\n        position: new google.maps.LatLng(data.lat, data.lng),\n        map: window.map,\n        icon: icon,\n        title: data.title,\n        content: tmpl,\n        animation: google.maps.Animation.DROP,\n        oxid: data.oxid\n    })\n    window.markers.push(marker)\n    handleMarkerClick(marker)\n}\n\n/**\n * Handle Marker Click\n * @param {marker} marker\n * @param {infowindow} infoWindow\n */\nfunction handleMarkerClick(marker) {\n\n    google.maps.event.addListener(marker, 'click', function () {\n        openInfoWindow(marker)\n    })\n\n    google.maps.event.addListener(window.map, 'click', function (event) {\n        closeAllInfoWindows()\n    })\n\n    let resultItem = document.querySelector('.c-retailer__item[data-id=\"' + marker.oxid + '\"] .c-retailer__item--headline')\n    resultItem.addEventListener('click', function (event) {\n        openInfoWindow(marker)\n    })\n}\n\n/**\n * Close all info windows\n */\nfunction closeAllInfoWindows() {\n\n    window.infowindows.forEach((infowindow) => {\n        infowindow.close(window.map, infowindow)\n    })\n    window.infowindows = []\n\n    window.markers.forEach((marker) => {\n        marker.setIcon({\n            url: _config__WEBPACK_IMPORTED_MODULE_1__.mapConfig.iconBase + _config__WEBPACK_IMPORTED_MODULE_1__.mapConfig.icon,\n            scaledSize: new google.maps.Size(_config__WEBPACK_IMPORTED_MODULE_1__.mapConfig.iconDimension, _config__WEBPACK_IMPORTED_MODULE_1__.mapConfig.iconDimension)\n        })\n    })\n}\n\n/**\n * Open info window\n * @param marker\n */\nfunction openInfoWindow(marker) {\n\n    closeAllInfoWindows()\n\n    let infowindow = new google.maps.InfoWindow({\n        content: marker.content\n    })\n    infowindow.open(window.map, marker)\n    window.infowindows.push(infowindow)\n\n    marker.setIcon({\n        url: _config__WEBPACK_IMPORTED_MODULE_1__.mapConfig.iconBase + _config__WEBPACK_IMPORTED_MODULE_1__.mapConfig.openIcon,\n        scaledSize: new google.maps.Size(_config__WEBPACK_IMPORTED_MODULE_1__.mapConfig.iconDimension, _config__WEBPACK_IMPORTED_MODULE_1__.mapConfig.iconDimension)\n    })\n}\n\n/**\n * Initialize the Search\n */\nfunction initSearch(isConsent) {\n    searchForm = document.getElementById(_config__WEBPACK_IMPORTED_MODULE_1__.config.searchFormId)\n    searchField = searchForm.querySelector('input[type=\"text\"]')\n    searchResults = document.getElementById('searchResults')\n    resultContainer = document.querySelector(_config__WEBPACK_IMPORTED_MODULE_1__.config.retailerResultContainer)\n    dataContainer = document.querySelector(_config__WEBPACK_IMPORTED_MODULE_1__.config.retailerDataContainer)\n    isConsent && searchField.addEventListener('keyup', geoSearch, false)\n    searchForm.addEventListener('submit', (evt) => {\n        evt.preventDefault()\n    }, false)\n}\n\n/**\n * Reset the map and searchform to default state\n */\nfunction resetToDefault() {\n    if (!window.map instanceof Element) {\n        centerMap()\n    }\n    searchResults && (searchResults.innerHTML = '');\n    searchField && (searchField.value = '');\n}\n\n/**\n * Perform the Search\n * @param {Event} evt\n */\nconst geoSearch = (evt) => {\n    if (evt.keyCode == 13) return false\n    evt.preventDefault()\n    let searchParam = searchField.value\n    if (searchParam != \"\") {\n        //logApiActivity(searchParam) // uncomment this line to log API activity\n        const service = new google.maps.places.AutocompleteService()\n        service.getQueryPredictions({input: evt.target.value, language: _config__WEBPACK_IMPORTED_MODULE_1__.config.language}, displaySuggestions)\n    }\n}\n\n/**\n * Display the search results\n * @param {Google Obj} predictions\n * @param {status} status\n */\nconst displaySuggestions = function (predictions, status) {\n    searchResults.innerHTML = ''\n    if (status != google.maps.places.PlacesServiceStatus.OK || !predictions) {\n        console.log(status)\n        return\n    }\n\n    predictions.forEach((prediction) => {\n        const li = document.createElement(\"li\")\n        li.setAttribute('data-place-id', prediction.place_id)\n\n        li.appendChild(document.createTextNode(prediction.description))\n        li.addEventListener('click', selectLocation, false)\n        searchResults.appendChild(li)\n    })\n}\n\n/**\n * Select the location\n * @param {Event} evt\n */\nconst selectLocation = async (evt) => {\n    searchField.value = evt.target.innerText\n    const relocated = await relocateMap(evt.target.dataset.placeId)\n    // ugly workaround ... without timeout, the results of the previous location would be displayed :-(\n    // will try to find a better solution with the refactoring of this\n    window.setTimeout(() => {\n        updateResults()\n    }, 500)\n}\n\n/**\n * Relocate the map to the selected place\n * @param {Place} placeId\n * @returns {boolean}\n */\nconst relocateMap = (placeId) => {\n    let request = {\n        placeId: placeId,\n        fields: ['name', 'geometry']\n    }\n    let serviceDetails = new google.maps.places.PlacesService(map)\n    serviceDetails.getDetails(request, function (place, status) {\n\n        let placeName = place.name\n\n        // quick fix :: exception for USA, because of system names\n        // TODO: refactor to mapping table\n        if (placeName == 'États-Unis') placeName = 'États-Unis d\\'Amérique'\n        if (placeName == 'USA') placeName = 'Vereinigte Staaten von Amerika'\n        if (placeName == 'Hongkong') placeName = 'Hong Kong'\n\n        // exception for metropolitan areas\n        const metros = ['HongKong', 'Hong Kong']\n        let isCountry = false\n        if( metros.find((place) => place === placeName )){\n            isCountry = true\n        }else{\n            // is the searched place a country?\n            isCountry = window.retailers.find(({ country }) => country === placeName);\n        }\n\n        if (status === google.maps.places.PlacesServiceStatus.OK) {\n            if (!place.geometry) {\n                console.log(\"Returned place contains no geometry\")\n                return false\n            }\n\n            let sortedResults = sortRetailersByDistance(place.geometry.location.lat(), place.geometry.location.lng())\n            let latlng = []\n            let bounds = new google.maps.LatLngBounds()\n\n            if (!isCountry) {\n                for (var i = 0; i < _config__WEBPACK_IMPORTED_MODULE_1__.mapConfig.minimumMarkers; i++) {\n                    latlng[i] = new google.maps.LatLng(sortedResults[i].coordinates[0], sortedResults[i].coordinates[1])\n                }\n            }else{\n                // only include retailers from this country\n                for (var i = 0; i < sortedResults.length; i++) {\n                    if (sortedResults[i].country == placeName) {\n                        latlng[i] = new google.maps.LatLng(sortedResults[i].coordinates[0], sortedResults[i].coordinates[1])\n                    }\n                }\n            }\n\n            // current location\n            latlng.push(place.geometry.location)\n\n            // extend view to minimum marker count\n            latlng.forEach(pos => {\n                bounds.extend(pos)\n            })\n\n            window.map.setCenter(bounds.getCenter())\n            window.map.fitBounds(bounds)\n\n            window.place = placeName\n            window.placeIsCountry = (isCountry !== undefined)\n        }\n    })\n\n    return true\n}\n\n/**\n * sort the retailers by distance to selected google place\n * @param lat\n * @param lng\n * @returns {*[]}\n */\nconst sortRetailersByDistance = (lat, lng) => {\n    let sortedlocations = []\n\n    window.retailers.forEach(retailer => {\n        let dis = getDistance([lat, lng], [retailer.lat, retailer.lng])\n\n        sortedlocations.push({\n            coordinates: [retailer.lat, retailer.lng],\n            distance: dis,\n            marker: window.markers.find(marker => marker.oxid === retailer.oxid),\n            country: retailer.country\n        })\n        retailer.distance = dis\n\n    })\n\n    sortedlocations = sortedlocations.sort((a, b) => {\n        return parseFloat(a.distance) - parseFloat(b.distance)\n    })\n\n    return sortedlocations\n}\n\n\n/**\n * calculate distance between two positions\n * @param  array loc1 startpoint\n * @param  array loc2 endpoint\n *\n * @return float\n */\nconst getDistance = (loc1, loc2) => {\n    var radlat1 = Math.PI * loc1[0] / 180\n    var radlat2 = Math.PI * loc2[0] / 180\n    var theta = loc1[1] - loc2[1]\n    var radtheta = Math.PI * theta / 180\n    var dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta)\n\n    dist = Math.acos(dist)\n    dist = dist * 180 / Math.PI\n    dist = dist * 60 * 1.1515\n\n    return dist\n}\n\n/**\n * Update search results, after the map is relocated\n */\nconst updateResults = () => {\n    searchResults.innerHTML = \"\"\n    resultContainer.innerHTML = \"\"\n    let resultElements = []\n    let visibleMarkers = getVisibleMarkers()\n\n    for (var i = 0; i < window.retailers.length; i++) {\n        let retailer = window.retailers[i]\n\n        // if the search was a country only show retailers, that are in this country\n        let showRetailer = false\n        if (!window.placeIsCountry) {\n            if (visibleMarkers.find(vmarker => vmarker.oxid === retailer.oxid)) showRetailer = true\n        }else {\n            if (retailer.country === window.place) showRetailer = true\n        }\n\n        if (showRetailer === true) {\n            let resultElement = dataContainer.querySelector('.c-retailer__item[data-id=\"' + retailer.oxid + '\"]').cloneNode(true)\n\n            if (!window.placeIsCountry) {\n                resultElement.setAttribute('data-dist', retailer.distance)\n\n                let distanceEl = document.createTextNode(' (' + Math.round(retailer.distance * 100) / 100 + ' km)');\n                resultElement.querySelector('.d-name').append(distanceEl)\n            }\n\n            resultElements.push(resultElement)\n        }\n    }\n\n    resultElements\n        .sort(function(a, b) {\n            return (parseFloat(a.dataset.dist) > parseFloat(b.dataset.dist) ? 1 : -1)\n        })\n        .forEach(element => resultContainer.appendChild(element).classList.remove('is--hidden'))\n\n    let spanElement = document.createElement('span')\n    spanElement.classList.add('c-retailer__resultno')\n    spanElement.innerHTML = oWave.i18n.DOTFLY_DEALERFINDER_RESULTS + ' ' + resultElements.length\n    spanElement.setAttribute('data-count', resultElements.length);\n\n    resultContainer.style.display = 'block'\n    resultContainer.insertBefore(spanElement, resultContainer.firstChild)\n\n    openFirstResult()\n}\n\n/**\n * show info window of the first result\n */\nconst openFirstResult = () => {\n    let firstVisibleResult = resultContainer.querySelector('.c-retailer__item:not(.is--hidden)')\n    if (firstVisibleResult) {\n        let newMarker = window.markers.find(marker => marker.oxid === firstVisibleResult.getAttribute('data-id'))\n        openInfoWindow(newMarker)\n    }\n}\n\n/**\n * retrieve visible markers from map\n * @returns {*[]}\n */\nconst getVisibleMarkers = () => {\n    let visibleMarkers = []\n    let bounds = window.map.getBounds()\n\n    for (var i = 0; i < window.markers.length; i++) {\n        var marker = window.markers[i]\n        if (bounds.contains(marker.getPosition()) === true) {\n            visibleMarkers.push(marker)\n        }\n    }\n    return visibleMarkers\n}\n\n/**\n * fetch the api key\n * @returns {Promise<*>}\n */\nasync function fetchGmApiKey() {\n    try {\n        const response = await fetch('/?cl=apicontroller&fnc=getGoogleMapsApiKey')\n        if (!response.ok) {\n            throw new Error('Failed to retrieve API key')\n        }\n        const data = await response.json()\n        return data.apiKey\n    } catch (error) {\n        console.error(error)\n        throw error\n    }\n}\n\n/**\n * set the api key\n * @returns {Promise<*>}\n */\nasync function setGmApiKey() {\n    try {\n        gmapApiKey = await fetchGmApiKey()\n    } catch (error) {\n        console.error(error)\n    }\n}\n\nasync function logApiActivity(searchParam){\n    const response = await fetch('/?cl=apicontroller&fnc=logGoogleApiActivity&searchParam=' + searchParam)\n\n    return true\n}\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/retailerMap/GoogleMap.js?");/***/}),/***/"./source/out/sinn/src/js/modules/retailerMap/GoogleMapsApi.js":(/*!*********************************************************************!*\
  !*** ./source/out/sinn/src/js/modules/retailerMap/GoogleMapsApi.js ***!
  \*********************************************************************/ /***/function sourceOutSinnSrcJsModulesRetailerMapGoogleMapsApiJs(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/**\n * GoogleMapsApi\n * Class to load google maps api with api key\n * and global Callback to init map after resolution of promise.\n * Credits: https://github.com/stephenscaff/google-maps-es6\n *\n * @exports {GoogleMapsApi}\n * @example MapApi = new GoogleMapsApi();\n *          MapApi.load().then(() => {});\n */\nclass GoogleMapsApi {\n\n    /**\n     * Constructor\n     * @property {string} apiKey\n     * @property {string} callbackName\n     */\n    constructor(gApiKey, langIso) {\n\n        // api key for google maps\n        this.apiKey = gApiKey;\n        // language to use\n        this.langIso = langIso;\n\n        // Set global callback\n        if (!window._GoogleMapsApi) {\n            this.callbackName = '_GoogleMapsApi.mapLoaded';\n            window._GoogleMapsApi = this;\n            window._GoogleMapsApi.mapLoaded = this.mapLoaded.bind(this);\n        }\n    }\n\n    /**\n     * Load\n     * Create script element with google maps\n     * api url, containing api key and callback for\n     * map init.\n     * @return {promise}\n     * @this {_GoogleMapsApi}\n     */\n    load() {\n        if (!this.promise) {\n            this.promise = new Promise(resolve => {\n                this.resolve = resolve;\n\n                if (typeof window.google === 'undefined') {\n                    const script = document.createElement('script');\n                    script.src = `//maps.googleapis.com/maps/api/js?key=${this.apiKey}&libraries=places&language=${this.langIso}&callback=${this.callbackName}`;\n                    script.async = true;\n                    document.body.append(script);\n\n                } else {\n                    this.resolve();\n                }\n            });\n        }\n\n        return this.promise;\n    }\n\n    /**\n     * mapLoaded\n     * Global callback for loaded/resolved map instance.\n     * @this {_GoogleMapsApi}\n     *\n     */\n    mapLoaded() {\n\n        if (this.resolve) {\n            this.resolve();\n        }\n    }\n}\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (GoogleMapsApi);\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/retailerMap/GoogleMapsApi.js?");/***/}),/***/"./source/out/sinn/src/js/modules/retailerMap/config.js":(/*!**************************************************************!*\
  !*** ./source/out/sinn/src/js/modules/retailerMap/config.js ***!
  \**************************************************************/ /***/function sourceOutSinnSrcJsModulesRetailerMapConfigJs(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   config: () => (/* binding */ config),\n/* harmony export */   infoBoxTpl: () => (/* binding */ infoBoxTpl),\n/* harmony export */   mapConfig: () => (/* binding */ mapConfig),\n/* harmony export */   mapStyle: () => (/* binding */ mapStyle),\n/* harmony export */   showAllDealers: () => (/* binding */ showAllDealers)\n/* harmony export */ });\nfunction infoBoxTpl(data){\n\tconst searchData = encodeURIComponent(data.street + ', ' + data.zip + ' ' + data.city + ', ' + data.country);\n\treturn '<div class=\"c-retailer__infobox\"><h3 class=\"c-retailer__infobox--headline\">' + data.title + '</h3>' +\n\t\t\t '<p class=\"c-retailer__infobox--address\">' +\n\t\t\tdata.street + '<br>' +\n\t\t\tdata.zip + ' ' + data.city + '<br>' +\n\t\t\tdata.country + '</p>' +\n\t\t\t'<a class=\"c-retailer__infobox--route\" href=\"https://www.google.com/maps/search/' + searchData + '\" target=\"_new\">'+ oWave.i18n.DOT_MAP_ROUTE + '</a><br>' +\n            (data.phone !== '' ? '<a class=\"c-retailer__infobox--phone\" href=\"tel:' + data.phone + '\">'+ oWave.i18n.DOT_MAP_PHONE + '</a>' : '') +\n\t\t\t'</div>';\n}\n\nfunction showAllDealers(data) {\n    return `<div class=\"c-retailer__query\">\n        ${data.map(dealer => `\n        <div class=\"c-retailer__item is--hidden\" data-id=\"${dealer.oxid}\" data-lat=\"${dealer.DOTLATITUDE}\" data-lng=\"${dealer.DOTLONGITUDE}\" data-phone=\"${dealer.oxfon}\">\n            <p class=\"c-retailer__item--headline d-name\">${dealer.oxtitle}</p>\n            <div class=\"c-retailer__item--columns\">\n                <div class=\"c-retailer__item--column\">\n                    <span class=\"c-retailer__item--subline\">${oWave.i18n.DOTFLY_DEALERFINDER_HL_ADDRESS}</span>\n                    <p class=\"c-retailer__item--content d-address\">\n                        <span class=\"d-street\">${dealer.oxstreet} ${dealer.oxstreetnr}</span><br>\n                        <span class=\"d-zip\">${dealer.oxzip}</span> <span class=\"d-city\">${dealer.oxcity}</span><br>\n                        <span class=\"d-country\">${dealer.countryTitle}</span>\n                    </p>\n                </div>\n                ${dealer.oxfon || dealer.dotmail || dealer.dotwebsite ? `\n                <div class=\"c-retailer__item--column\">\n                    <span class=\"c-retailer__item--subline\">${oWave.i18n.DOTFLY_DEALERFINDER_HL_CONTACT}</span>\n                    <p class=\"c-retailer__item--content\">\n                        ${dealer.oxfon ? `<a class=\"c-retailer__item--link\" href=\"tel:${dealer.oxfon}\">${dealer.oxfon}</a><br>` : ''}\n                        ${dealer.dotmail ? `<a class=\"c-retailer__item--link d-mail\" href=\"mailto:${dealer.dotmail}\">${dealer.dotmail}</a><br>` : ''}\n                        ${dealer.dotwebsite ? `<a class=\"c-retailer__item--link d-web\" href=\"https://${dealer.dotwebsite}\" target=\"_blank\">${dealer.dotwebsite}</a>` : ''}\n                    </p>\n                </div>` : ''}\n                <div class=\"c-retailer__item--column\">\n                    <div class=\"c-retailer__item--services\">\n                        ${dealer.services.map(service => `\n                        <span class=\"c-retailer__item--service\">\n                            ${oWave.i18n[service]}\n                        </span>\n                        `).join('')}\n                    </div>\n                </div>\n            </div>\n        </div>\n        `).join('')}\n    </div>`\n}\n\n\nconst config = {\n    retailerJsonUrl: '/widget.php?actcontrol=start&cl=showdealers&showalldealerdatajson=1',\n    retailerItemsUrl: '/widget.php?actcontrol=start&cl=showdealers&showalldealers=1',\n    searchFormId: 'retailerForm',\n    retailerResultContainer: '.c-retailer__results',\n    retailerDataContainer: '.c-retailer__data',\n    language: document.oxid.languageIso\n}\n\nconst mapConfig = {\n    iconBase: '/out/sinn/img/map/',\n    icon: 'location_white.svg',\n    openIcon: 'location_black.svg',\n    iconDimension: 40,\n    center: { lat: 51.163409, lng: 10.447718 }, // center germany by default\n\tzoom: 6,\n\tdisableDefaultUI: true, // Hide all controls and enable only the ones we need\n\tfullscreenControl: true,\n\tzoomControl: true,\n    minimumMarkers: 3,\n    retailerUrl: '/widget.php?actcontrol=start&cl=showdealers&showalldealerdata=1'\n};\n\nconst mapStyle = [\n    {\n        \"elementType\": \"geometry\",\n        \"stylers\": [\n            {\n                \"color\": \"#f5f5f5\"\n            }\n        ]\n    },\n    {\n        \"elementType\": \"labels.icon\",\n        \"stylers\": [\n            {\n                \"visibility\": \"off\"\n            }\n        ]\n    },\n    {\n        \"elementType\": \"labels.text.fill\",\n        \"stylers\": [\n            {\n                \"color\": \"#616161\"\n            }\n        ]\n    },\n    {\n        \"elementType\": \"labels.text.stroke\",\n        \"stylers\": [\n            {\n                \"color\": \"#f5f5f5\"\n            }\n        ]\n    },\n    {\n        \"featureType\": \"administrative.land_parcel\",\n        \"elementType\": \"labels.text.fill\",\n        \"stylers\": [\n            {\n                \"color\": \"#bdbdbd\"\n            }\n        ]\n    },\n    {\n        \"featureType\": \"poi\",\n        \"elementType\": \"geometry\",\n        \"stylers\": [\n            {\n                \"color\": \"#eeeeee\"\n            }\n        ]\n    },\n    {\n        \"featureType\": \"poi\",\n        \"elementType\": \"labels.text.fill\",\n        \"stylers\": [\n            {\n                \"color\": \"#757575\"\n            }\n        ]\n    },\n    {\n        \"featureType\": \"poi.park\",\n        \"elementType\": \"geometry\",\n        \"stylers\": [\n            {\n                \"color\": \"#e5e5e5\"\n            }\n        ]\n    },\n    {\n        \"featureType\": \"poi.park\",\n        \"elementType\": \"labels.text.fill\",\n        \"stylers\": [\n            {\n                \"color\": \"#9e9e9e\"\n            }\n        ]\n    },\n    {\n        \"featureType\": \"road\",\n        \"elementType\": \"geometry\",\n        \"stylers\": [\n            {\n                \"color\": \"#ffffff\"\n            }\n        ]\n    },\n    {\n        \"featureType\": \"road.arterial\",\n        \"elementType\": \"labels.text.fill\",\n        \"stylers\": [\n            {\n                \"color\": \"#757575\"\n            }\n        ]\n    },\n    {\n        \"featureType\": \"road.highway\",\n        \"elementType\": \"geometry\",\n        \"stylers\": [\n            {\n                \"color\": \"#dadada\"\n            }\n        ]\n    },\n    {\n        \"featureType\": \"road.highway\",\n        \"elementType\": \"labels.text.fill\",\n        \"stylers\": [\n            {\n                \"color\": \"#616161\"\n            }\n        ]\n    },\n    {\n        \"featureType\": \"road.local\",\n        \"elementType\": \"labels.text.fill\",\n        \"stylers\": [\n            {\n                \"color\": \"#9e9e9e\"\n            }\n        ]\n    },\n    {\n        \"featureType\": \"transit.line\",\n        \"elementType\": \"geometry\",\n        \"stylers\": [\n            {\n                \"color\": \"#e5e5e5\"\n            }\n        ]\n    },\n    {\n        \"featureType\": \"transit.station\",\n        \"elementType\": \"geometry\",\n        \"stylers\": [\n            {\n                \"color\": \"#eeeeee\"\n            }\n        ]\n    },\n    {\n        \"featureType\": \"water\",\n        \"elementType\": \"geometry\",\n        \"stylers\": [\n            {\n                \"color\": \"#c9c9c9\"\n            }\n        ]\n    },\n    {\n        \"featureType\": \"water\",\n        \"elementType\": \"labels.text.fill\",\n        \"stylers\": [\n            {\n                \"color\": \"#9e9e9e\"\n            }\n        ]\n    }\n];\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/retailerMap/config.js?");/***/}),/***/"./source/out/sinn/src/js/modules/screenReaderUtils.js":(/*!*************************************************************!*\
  !*** ./source/out/sinn/src/js/modules/screenReaderUtils.js ***!
  \*************************************************************/ /***/function sourceOutSinnSrcJsModulesScreenReaderUtilsJs(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   announceAlertToScreenReader: () => (/* binding */ announceAlertToScreenReader),\n/* harmony export */   announceToScreenReader: () => (/* binding */ announceToScreenReader)\n/* harmony export */ });\n/**\n * This Software is the property of dotfly and is protected\n * by copyright law - it is NOT Freeware.\n *\n * Any unauthorized use of this software without a valid license key\n * is a violation of the license agreement and will be prosecuted by\n * civil and criminal law.\n *\n * @category   Configurator Screen Reader Utilities\n * @author     Lennart Syre <lennart.syre@dotfly.de>\n * @license    http://www.dotfly.de Commercial\n * @link       http://www.dotfly.de\n */\n\n/**\n * Announce a message to screen readers using the polite live region\n * @param {string} message - The message to announce\n * @param {string} regionId - The ID of the live region (default: 'configurator-status')\n */\nconst announceToScreenReader = (message, regionId = 'configurator-status') => {\n    const liveRegion = document.getElementById(regionId);\n    if (liveRegion) {\n        // Clear and set new message to ensure announcement\n        liveRegion.textContent = '';\n        setTimeout(() => {\n            liveRegion.textContent = message;\n        }, 100);\n    }\n};\n\n/**\n * Announce an alert to screen readers using the assertive live region\n * @param {string} message - The alert message to announce\n */\nconst announceAlertToScreenReader = (message) => {\n    announceToScreenReader(message, 'configurator-alerts');\n};\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/screenReaderUtils.js?");/***/}),/***/"./source/out/sinn/src/js/modules/search.js":(/*!**************************************************!*\
  !*** ./source/out/sinn/src/js/modules/search.js ***!
  \**************************************************/ /***/function sourceOutSinnSrcJsModulesSearchJs(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! animejs/lib/anime.es.js */ \"./node_modules/animejs/lib/anime.es.js\");\n/* harmony import */ var _lazyload_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./lazyload.js */ \"./source/out/sinn/src/js/modules/lazyload.js\");\n\n\n\n// General Vars\nvar searchComponent \t\t= document.querySelector('.c-search');\nvar searchTabs \t\t\t\t= document.querySelector('.c-search__tabs');\nvar searchProductResults \t= document.querySelector('.c-search__tabs div[data-id=\"search__products\"]');\nvar searchContentResults \t= document.querySelector('.c-search__tabs div[data-id=\"search__pages\"]');\nvar searchProductTab \t\t= document.querySelector('.c-search__tabs-trigger[data-target=\"search__products\"]');\nvar searchContentTab \t\t= document.querySelector('.c-search__tabs-trigger[data-target=\"search__pages\"]');\nvar searchProductCounts \t= document.querySelector('.c-search__products-count');\nvar searchContentCounts \t= document.querySelector('.c-search__contents-count');\nvar searchLoader \t\t\t= document.querySelector('.c-search__loader');\nvar searchNoResults \t\t= document.querySelector('.c-search__noresults');\nvar searchInput \t\t\t= document.querySelector('.c-search__row .e-form__input');\nvar searchTabsTriggers \t\t= document.querySelectorAll('.c-search__tabs-trigger');\nvar searchForm \t\t\t\t= document.querySelector('.c-search__form');\nvar searchFormSubmit \t\t= document.querySelector('.c-search__row--button');\nvar searchSuggestions \t\t= document.querySelectorAll('.c-search__suggestions--span');\nvar cubicBezier \t\t\t= 'cubicBezier(.40,.05,.20,.90)';\n\nlet lang \t\t\t\t\t= searchForm.querySelector('input[name=lang]').value;\n\nvar searchProductURL \t\t= '/livesearch_ajax.php?searchparam=';\nvar searchContentURL \t\t= '/widget.php?lang=' + lang + '&actcontrol=start&cl=contentsearch&searchparam=';\n\nvar suggestionItemClicked,\n\tsearchProductBody,\n\tsearchContentBody,\n\tsearchProductContent,\n\tsearchContentContent,\n\tsearchProductCount,\n\tsearchContentCount,\n\tsearchTerm,\n\tsearchResultsURL,\n\tsearchContentsURL;\n\nif (searchComponent) {\n\tsearchTabsTriggers.forEach((item) => {\n\t\titem.addEventListener('click', function () {\n\t\t\tif (!item.classList.contains('js--active')) {\n\t\t\t\tvar dataTarget = item.dataset.target;\n\t\t\t\tvar dataTargetEl = document.querySelector('.c-search__tabs-content[data-id=\"' + dataTarget + '\"]');\n\t\t\t\tvar dataTargetElNot = document.querySelector('.c-search__tabs-content:not([data-id=\"' + dataTarget + '\"])');\n\n\t\t\t\t// Disable Clicks While Animation\n\t\t\t\tsearchTabs.classList.add('js--pointerevent');\n\n\t\t\t\t// Toggle Active Classes on Triggers\n\t\t\t\tsearchTabsTriggers.forEach((item) => {\n\t\t\t\t\titem.classList.remove('js--active')\n\t\t\t\t});\n\n\t\t\t\t// Toggle Active Classes on Contents\n\t\t\t\tdataTargetEl.classList.add('js--active');\n\n\t\t\t\t(0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])({\n\t\t\t\t\ttargets: dataTargetElNot,\n\t\t\t\t\topacity: ['1', '0'],\n\t\t\t\t\teasing: cubicBezier,\n\t\t\t\t\tduration: 1000,\n\t\t\t\t\tcomplete: function () {\n\t\t\t\t\t\tdataTargetElNot.style.display = 'none';\n\t\t\t\t\t\tdataTargetEl.style.display = 'block';\n\t\t\t\t\t\titem.classList.add('js--active');\n\n\t\t\t\t\t\t(0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])({\n\t\t\t\t\t\t\ttargets: dataTargetEl,\n\t\t\t\t\t\t\topacity: ['0', '1'],\n\t\t\t\t\t\t\teasing: cubicBezier,\n\t\t\t\t\t\t\tduration: 1000,\n\t\t\t\t\t\t\tcomplete: function () {\n\t\t\t\t\t\t\t\tsearchTabs.classList.remove('js--pointerevent');\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\t});\n\n\tsearchSuggestions.forEach((item) => {\n\t\titem.addEventListener('click', function () {\n\t\t\tsuggestionItemClicked = item.innerText;\n\t\t\tsearchInput.value = suggestionItemClicked;\n\t\t\tsearchFormSubmit.click();\n\t\t});\n\t});\n\n\tvar searchResults = function (event) {\n\t\tevent.preventDefault();\n\t\tevent.stopPropagation();\n\n\t\tsearchLoader.style.display = 'flex';\n\t\tsearchLoader.classList.add('js--active');\n\n\t\tsearchInput.disabled = true;\n\t\tsearchFormSubmit.disabled = true;\n\t\tsearchTerm = searchInput.value;\n\t\tsearchResultsURL = (searchProductURL + searchTerm);\n\t\tsearchContentsURL = (searchContentURL + searchTerm);\n\n\t\t(0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])({\n\t\t\ttargets: searchLoader,\n\t\t\topacity: ['0', '1'],\n\t\t\tduration: 250,\n\t\t\teasing: cubicBezier\n\t\t})\n\n\t\t;(0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])({\n\t\t\ttargets: searchTabs,\n\t\t\topacity: '0',\n\t\t\tduration: 250,\n\t\t\teasing: cubicBezier\n\t\t});\n\n\t\t(0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])({\n\t\t\ttargets: searchNoResults,\n\t\t\topacity: '0',\n\t\t\tduration: 250,\n\t\t\teasing: cubicBezier\n\t\t});\n\n\t\tPromise.all([\n\t\t\tfetch(searchResultsURL)\n\t\t\t\t.then(function (response) {\n\t\t\t\t\treturn response.text();\n\t\t\t\t})\n\t\t\t\t.then(function (html) {\n\t\t\t\t\t// Parse HTML content\n\t\t\t\t\tvar parser = new DOMParser();\n\t\t\t\t\tvar results = parser.parseFromString(html, 'text/html');\n\n\t\t\t\t\t// Fill Container with items\n\t\t\t\t\tsearchProductBody = results.querySelector('body');\n\t\t\t\t\tsearchProductCount = searchProductBody.querySelectorAll('.c-search__item').length;\n\t\t\t\t\tsearchProductContent = searchProductBody.innerHTML;\n\n\t\t\t\t\tsearchProductCounts.innerHTML = searchProductCount;\n\t\t\t\t\tsearchProductResults.innerHTML = searchProductContent;\n\n\t\t\t\t\t// LazyLoad Images\n\t\t\t\t\t_lazyload_js__WEBPACK_IMPORTED_MODULE_1__.lazyContent.update();\n\n                    if(typeof(_etracker) === 'object') {\n                        var eTrackerResults = searchProductCount > 0 ? 'Mit Ergebnis' : 'Ohne Ergebnis';\n                        et_areas = decodeURIComponent(et_areas);\n\n                        et_eC_Wrapper(\n                            {\n                                et_et: 'g9gkd9',\n                                et_pagename:'Suchergebnisse',\n                                et_areas: et_areas.substring(0,5) + '/Suche',\n                                cc_ordercurr : '',\n                                cc_ordertype : '',\n                                cc_baskettype : '',\n                                cc_attributes:{etcc_cu:'onsite', etcc_med_onsite:'Interne Suche', etcc_cmp_onsite:eTrackerResults, etcc_st_onsite:searchTerm}\n                            }\n                        );\n                    }\n\t\t\t\t}),\n\t\t\tfetch(searchContentsURL)\n\t\t\t\t.then(function (response) {\n\t\t\t\t\treturn response.text();\n\t\t\t\t})\n\t\t\t\t.then(function (html) {\n\t\t\t\t\t// Parse HTML content\n\t\t\t\t\tvar parser = new DOMParser();\n\t\t\t\t\tvar results = parser.parseFromString(html, 'text/html');\n\n\t\t\t\t\t// Fill Container with items\n\t\t\t\t\tsearchContentBody = results.querySelector('body');\n\t\t\t\t\tsearchContentCount = searchContentBody.querySelectorAll('.c-search__page').length;\n\t\t\t\t\tsearchContentContent = searchContentBody.innerHTML;\n\n\t\t\t\t\tsearchContentCounts.innerHTML = searchContentCount;\n\t\t\t\t\tsearchContentResults.innerHTML = searchContentContent;\n\n\t\t\t\t\t// LazyLoad Images\n\t\t\t\t\t_lazyload_js__WEBPACK_IMPORTED_MODULE_1__.lazyContent.update();\n\t\t\t\t})\n\t\t])\n\t\t\t.then(function () {\n\t\t\t\tif (searchProductCount > 0 || searchContentCount > 0) {\n\t\t\t\t\tif (searchProductCount <= 0 && searchContentCount > 0) {\n\t\t\t\t\t\tsearchProductTab.style.display = 'none';\n\t\t\t\t\t\tsearchProductResults.style.display = 'none';\n\n\t\t\t\t\t\tsearchContentResults.style.display = 'block';\n\t\t\t\t\t\tsearchContentResults.classList.add('js--active');\n\t\t\t\t\t\tsearchProductResults.classList.remove('js--active');\n\n\t\t\t\t\t\tsearchProductTab.classList.remove('js--active');\n\t\t\t\t\t\tsearchContentTab.classList.add('js--active');\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsearchProductTab.style = '';\n\t\t\t\t\t\tsearchProductResults.style = '';\n\n\t\t\t\t\t\tsearchProductTab.classList.add('js--active');\n\t\t\t\t\t\tsearchContentTab.classList.remove('js--active');\n\t\t\t\t\t}\n\n\t\t\t\t\tif (searchContentCount <= 0 && searchProductCount > 0) {\n\t\t\t\t\t\tsearchContentTab.style.display = 'none';\n\t\t\t\t\t\tsearchContentResults.style.display = 'none';\n\n\t\t\t\t\t\tsearchProductResults.style.display = 'block';\n\n\t\t\t\t\t\tsearchProductTab.classList.add('js--active');\n\t\t\t\t\t\tsearchContentTab.classList.remove('js--active');\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsearchContentTab.style = '';\n\t\t\t\t\t\tsearchContentResults.style = '';\n\n\t\t\t\t\t\tsearchProductTab.classList.remove('js--active');\n\t\t\t\t\t\tsearchContentTab.classList.add('js--active');\n\t\t\t\t\t}\n\n\t\t\t\t\tif (searchProductCount > 0 && searchContentCount > 0) {\n\n\t\t\t\t\t\tsearchContentTab.style = '';\n\t\t\t\t\t\tsearchProductTab.style = '';\n\n\t\t\t\t\t\tsearchProductResults.style.display = 'block';\n\t\t\t\t\t\tsearchContentResults.style.display = 'none';\n\n\t\t\t\t\t\tsearchProductTab.classList.add('js--active');\n\t\t\t\t\t\tsearchContentTab.classList.remove('js--active');\n\t\t\t\t\t}\n\n\t\t\t\t\t(0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])({\n\t\t\t\t\t\ttargets: searchLoader,\n\t\t\t\t\t\topacity: ['1', '0'],\n\t\t\t\t\t\tduration: 250,\n\t\t\t\t\t\teasing: cubicBezier,\n\t\t\t\t\t\tcomplete: function () {\n\t\t\t\t\t\t\tsearchLoader.classList.remove('js--active');\n\t\t\t\t\t\t\tsearchTabs.style.display = 'block';\n\t\t\t\t\t\t\tsearchNoResults.style.display = 'none';\n\t\t\t\t\t\t\tsearchLoader.style.display = 'none';\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\n\t\t\t\t\t// Animate Tabs\n\t\t\t\t\t;(0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])({\n\t\t\t\t\t\ttargets: searchTabs,\n\t\t\t\t\t\tdelay: 250,\n\t\t\t\t\t\topacity: ['0', '1'],\n\t\t\t\t\t\tduration: 1000,\n\t\t\t\t\t\teasing: cubicBezier\n\t\t\t\t\t})\n\t\t\t\t} else {\n\t\t\t\t\t(0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])({\n\t\t\t\t\t\ttargets: searchLoader,\n\t\t\t\t\t\topacity: ['1', '0'],\n\t\t\t\t\t\tduration: 250,\n\t\t\t\t\t\teasing: cubicBezier,\n\t\t\t\t\t\tcomplete: function () {\n\t\t\t\t\t\t\tsearchLoader.classList.remove('js--active');\n\t\t\t\t\t\t\tsearchTabs.style.display = 'none';\n\t\t\t\t\t\t\tsearchNoResults.style.display = 'block';\n\t\t\t\t\t\t\tsearchLoader.style.display = 'none';\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\n\t\t\t\t\t// Animate Tabs\n\t\t\t\t\t;(0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])({\n\t\t\t\t\t\ttargets: searchNoResults,\n\t\t\t\t\t\tdelay: 250,\n\t\t\t\t\t\topacity: ['0', '1'],\n\t\t\t\t\t\tduration: 1000,\n\t\t\t\t\t\teasing: cubicBezier\n\t\t\t\t\t})\n\t\t\t\t}\n\n\t\t\t\t// Enable Form Submission\n\t\t\t\tsearchInput.disabled = false;\n\t\t\t\tsearchFormSubmit.disabled = false;\n\t\t\t})\n\t\t\t.catch(function (err) {\n\t\t\t\tconsole.log(err);\n\t\t\t});\n\t}\n\n\tsearchForm.addEventListener('submit', searchResults, false);\n}\n\n// Set focus to desktop search input when opened\nconst searchTriggerDesktop = document.getElementById('searchSidebarTrigger');\nconst searchFocusDesktop = () => {\n\tconst searchField = document.getElementById('searchParam');\n\tsearchField.focus();\n}\nif (searchTriggerDesktop) {\n\tsearchTriggerDesktop.addEventListener('click', (e) => {\n\t\tsearchFocusDesktop();\n\t});\n}\n\n\n// Set focus to mobile search input when opened\nlet searchTriggerMobile = document.querySelector('#mobileSearchTrigger');\nconst searchField = document.getElementById('searchParam');\nconst closeSearch = document.querySelectorAll('.c-search__close, .c-search__background')\nconst searchFocusMobile = () => {\n\tif (!searchTriggerMobile.classList.contains('is--focused')) {\n\t\tsetTimeout(() => {\n\t\t\tsearchField.focus();\n\t\t\tsearchTriggerMobile.classList.add('is--focused');\n\t\t}, 1000);\n\t} else if (searchTriggerMobile.classList.contains('is--focused')) {\n\t\tsearchTriggerMobile.classList.remove('is--focused');\n\t\tsearchField.blur();\n\t}\n}\n\nif (searchTriggerMobile) {\n    searchTriggerMobile.addEventListener('click', (e) => {\n\t\tsearchFocusMobile();\n    });\n}\n\ncloseSearch.forEach((trigger) => {\n\ttrigger.addEventListener('click', () => {\n\t\tsearchTriggerMobile && searchTriggerMobile.classList.remove('is--focused');\n\t\tsearchField && searchField.blur();\n\t})\n});\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/search.js?");/***/}),/***/"./source/out/sinn/src/js/modules/stageslider.js":(/*!*******************************************************!*\
  !*** ./source/out/sinn/src/js/modules/stageslider.js ***!
  \*******************************************************/ /***/function sourceOutSinnSrcJsModulesStagesliderJs(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _glidejs_glide__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @glidejs/glide */ \"./node_modules/@glidejs/glide/dist/glide.esm.js\");\n/* harmony import */ var animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! animejs/lib/anime.es.js */ \"./node_modules/animejs/lib/anime.es.js\");\n\n\n\nvar countSlides = document.querySelectorAll('.js-stageslider .glide__slide');\n\nif (document.querySelector('.js-stageslider')) {\n\n\tlet stageslider;\n\tlet stagesliderPrevI = 0;\n\n\tvar Mutator = function () {\n\t\treturn {\n\t\t\tmodify(translate) {\n\t\t\t\tif (!stageslider) {\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n\n\t\t\t\tconst i = stageslider.index;\n\t\t\t\tconst prevI = stagesliderPrevI;\n\t\t\t\tconst prevItem = 1 + stagesliderPrevI;\n\n\t\t\t\tstagesliderPrevI = i;\n\n\t\t\t\tif (i === prevI) {\n\t\t\t\t\treturn 0;\n\t\t\t\t} else if ((Math.abs(i - prevI) === 1) && i > prevI || (i === 0 && prevI === stageslider._c.Html.slides.length - 1)) {\n\t\t\t\t\tstageslider._c.Html.wrapper.classList.remove('glide__slides--reverse');\n\t\t\t\t} else {\n\t\t\t\t\tstageslider._c.Html.wrapper.classList.add('glide__slides--reverse');\n\t\t\t\t}\n\n\t\t\t\tlet elems = document.querySelectorAll('.c-stageslider .glide__slide:not(.glide__slide--clone)');\n\n\t\t\t\tArray.from(elems).forEach(function (elem) {\n\t\t\t\t\telem.classList.remove('glide__slide--last');\n\t\t\t\t\telems[prevI].classList.add('glide__slide--last')\n\t\t\t\t});\n\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (countSlides.length > 1) {\n\t\tstageslider = new _glidejs_glide__WEBPACK_IMPORTED_MODULE_0__[\"default\"]('.js-stageslider', {\n\t\t\ttype: 'carousel',\n\t\t\thoverpause: false,\n\t\t\tautoplay: 7500,\n\t\t\tgap: 0\n\t\t}).mutate([Mutator]).mount();\n\n\t\tdocument.querySelector('.js-stageslider ul').classList.add('glide--slider__multiple');\n\n\t\tstageslider.on('run.after', function () {\n\t\t\tvar itemsLength = document.querySelectorAll('.c-stageslider .glide__slide--active .c-stageslider__slide-headline--inner').length;\n\n\t\t\t(0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"])({\n\t\t\t\ttargets: document.querySelectorAll('.c-stageslider .glide__slide--active .c-stageslider__slide-headline--inner'),\n\t\t\t\ttranslateY: ['100%', '0'],\n\t\t\t\tdelay: animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"].stagger(100,\n\t\t\t\t\t{\n\t\t\t\t\t\tstart: 300\n\t\t\t\t\t}\n\t\t\t\t),\n\t\t\t\tduration: 1250,\n\t\t\t\teasing: 'cubicBezier(.40,.05,.20,.90)'\n\t\t\t});\n\t\t\t(0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"])({\n\t\t\t\ttargets: document.querySelectorAll('.c-stageslider .glide__slide--active .js-animated-button'),\n\t\t\t\ttranslateY: ['100%', '0'],\n\t\t\t\tdelay: ((itemsLength * 100) + 100),\n\t\t\t\tduration: 1250,\n\t\t\t\teasing: 'cubicBezier(.40,.05,.20,.90)'\n\t\t\t});\n\t\t});\n\n\t\tstageslider.on('run.before', function () {\n\t\t\tvar itemsLength = document.querySelectorAll('.c-stageslider .glide__slide--active .c-stageslider__slide-headline--inner').length;\n\n\t\t\t(0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"])({\n\t\t\t\ttargets: document.querySelectorAll('.c-stageslider .glide__slide--active .c-stageslider__slide-headline--inner'),\n\t\t\t\ttranslateY: ['0', '-100%'],\n\t\t\t\tdelay: animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"].stagger(100,\n\t\t\t\t\t{\n\t\t\t\t\t\tstart: 0,\n\t\t\t\t\t}\n\t\t\t\t),\n\t\t\t\tduration: 1250,\n\t\t\t\teasing: 'cubicBezier(.40,.05,.20,.90)'\n\t\t\t});\n\t\t\t(0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"])({\n\t\t\t\ttargets: document.querySelectorAll('.c-stageslider .glide__slide--active .js-animated-button'),\n\t\t\t\ttranslateY: ['0', '-100%'],\n\t\t\t\tdelay: ((itemsLength * 100) + 100),\n\t\t\t\tduration: 1250,\n\t\t\t\teasing: 'cubicBezier(.40,.05,.20,.90)'\n\t\t\t});\n\t\t});\n\n\t}\n}\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/stageslider.js?");/***/}),/***/"./source/out/sinn/src/js/modules/stickyHeader.js":(/*!********************************************************!*\
  !*** ./source/out/sinn/src/js/modules/stickyHeader.js ***!
  \********************************************************/ /***/function sourceOutSinnSrcJsModulesStickyHeaderJs(){eval("/**\n * This Software is the property of dotfly and is protected\n * by copyright law - it is NOT Freeware.\n *\n * Any unauthorized use of this software without a valid license key\n * is a violation of the license agreement and will be prosecuted by\n * civil and criminal law.\n *\n * @category   Sticky Header\n * @author     Anna Morawe <anna.morawe@dotfly.de>\n * @license    http://www.dotfly.de Commercial\n * @link       http://www.dotfly.de\n */\n\nif (window.innerWidth >= 1024) {\n\tlet sliders = document.querySelectorAll('.c-stageslider, .c-hero');\n\tlet header = document.querySelector('.c-header');\n    let darkmodeStatus = document.body.classList.contains('is--darkmode');\n\tlet headerHeight = header.getBoundingClientRect().height;\n\n\t// Create CSS Variable\n\tdocument.documentElement.style.setProperty('--header-height', headerHeight + 'px');\n\n\tif (sliders.length > 0) {\n\n\t\tfunction checkSliderVisibility() {\n\t\t\tlet anySliderOutOfView = Array.from(sliders).some((item) => {\n\t\t\t\treturn item.getBoundingClientRect().top < 0;\n\t\t\t});\n\n\t\t\tif (anySliderOutOfView) {\n\t\t\t\tif (darkmodeStatus == true) {\n\t\t\t\t\theader.classList.add('is--dark-header');\n\t\t\t\t} else {\n\t\t\t\t\theader.classList.add('is--light-header');\n\t\t\t\t}\n\t\t\t} else if (!anySliderOutOfView && header.classList.contains('is--transparent-header')) {\n\t\t\t\theader.classList.remove('is--dark-header');\n\t\t\t\theader.classList.remove('is--light-header');\n\t\t\t}\n\t\t}\n\n\t\tfunction debounce(func, wait) {\n\t\t\tlet timeout;\n\t\t\treturn function() {\n\t\t\t\tclearTimeout(timeout);\n\t\t\t\ttimeout = setTimeout(() => {\n\t\t\t\t\tfunc();\n\t\t\t\t}, wait);\n\t\t\t};\n\t\t}\n\n\t\tconst debouncedCheckSliderVisibility = debounce(checkSliderVisibility, 100);\n\n\t\twindow.addEventListener('scroll', debouncedCheckSliderVisibility);\n\t}\n}\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/stickyHeader.js?");/***/}),/***/"./source/out/sinn/src/js/modules/strapPurchase/forcedOverlays.js":(/*!************************************************************************!*\
  !*** ./source/out/sinn/src/js/modules/strapPurchase/forcedOverlays.js ***!
  \************************************************************************/ /***/function sourceOutSinnSrcJsModulesStrapPurchaseForcedOverlaysJs(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _focusTrap_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../focusTrap.js */ \"./source/out/sinn/src/js/modules/focusTrap.js\");\n// -----------------------------------------------------------------------------\n// focedOverlays.js\n// Opens offcanvas layer to force users to select a watch\n// -----------------------------------------------------------------------------\n\n\n\nconst classActive = 'js--active';\nconst offcanvasMap = new Map();\n\n// Get the language modal element (by ID or fallback selector)\nfunction getLanguageModalEl() {\n    return document.getElementById('languageModal') || document.querySelector('.o-modal.c-language');\n}\n\n// Check if the language modal is currently open/visible\nfunction isLanguageModalOpen() {\n    const el = getLanguageModalEl();\n    if (!el) return false;\n\n    const visibleByStyle = getComputedStyle(el).visibility === 'visible';\n    return (\n        el.classList.contains('js--active') ||\n        el.getAttribute('aria-modal') === 'true' ||\n        visibleByStyle\n    );\n}\n\n// Run callback once the language modal has been closed\nfunction onLanguageModalClosedOnce(cb) {\n    const el = getLanguageModalEl();\n    if (!el) { cb(); return; }\n    if (!isLanguageModalOpen()) { cb(); return; }\n\n    const obs = new MutationObserver(() => {\n        if (!isLanguageModalOpen()) {\n            obs.disconnect();\n            cb();\n        }\n    });\n    obs.observe(el, { attributes: true, attributeFilter: ['class', 'style', 'aria-modal'] });\n}\n\n// Remove body scroll lock if no offcanvas is open\nfunction updateScrollLock() {\n    const anyStillOpen = document.querySelector(`.c-offcanvas.${classActive}`);\n    if (!anyStillOpen) {\n        document.body.classList.remove('no--scroll');\n    }\n}\n\n// Show an offcanvas and trap focus inside\nfunction showOffcanvas(element) {\n    const trulyOpenWithTrap = () => {\n        element.style.display = 'block';\n        requestAnimationFrame(() => {\n            setTimeout(() => {\n                element.classList.add(classActive);\n                document.body.classList.add('no--scroll');\n                (0,_focusTrap_js__WEBPACK_IMPORTED_MODULE_0__.createFocusTrap)(element);\n            }, 0);\n        });\n    };\n\n    // Delay opening if language modal is active\n    if (isLanguageModalOpen()) {\n        element.setAttribute('inert', '');\n        element.setAttribute('aria-hidden', 'true');\n\n        onLanguageModalClosedOnce(() => {\n            element.removeAttribute('inert');\n            element.removeAttribute('aria-hidden');\n            trulyOpenWithTrap();\n        });\n\n        return;\n    }\n\n    trulyOpenWithTrap();\n}\n\n// Hide an offcanvas and run callback after transition\nfunction hideOffcanvas(element, callback) {\n    element.classList.remove(classActive);\n    element.addEventListener('transitionend', () => {\n        callback();\n        updateScrollLock();\n    }, { once: true });\n}\n\n// Run a handler once after a transitionend event on an element\nfunction addTransitionEndOnce(element, handler) {\n    const wrappedHandler = function (event) {\n        if (event.target === element) {\n            element.removeEventListener('transitionend', wrappedHandler);\n            handler();\n        }\n    };\n    element.addEventListener('transitionend', wrappedHandler);\n}\n\n// Map all offcanvas elements by their data-layer attribute\nfunction mapOffcanvasLayers() {\n    document.querySelectorAll('.c-offcanvas[data-layer]').forEach(el => {\n        offcanvasMap.set(el.dataset.layer, el);\n    });\n}\n\n// Initialize and keep always-open offcanvas layers visible\nfunction initAlwaysOpenOffcanvasLayers() {\n    const elements = document.querySelectorAll('.c-offcanvas.js--always-open');\n    if (elements.length === 0) return;\n\n    elements.forEach(offcanvas => {\n        showOffcanvas(offcanvas);\n        registerOffcanvasEvents(offcanvas);\n    });\n}\n\n// Register toggle/close button events for an offcanvas\nfunction registerOffcanvasEvents(offcanvas) {\n    const toggleButton = offcanvas.querySelector('.c-offcanvas__toggle');\n    if (toggleButton) {\n        toggleButton.addEventListener('click', () => {\n            const targetLayer = toggleButton.dataset.target;\n            hideOffcanvas(offcanvas, () => {\n                offcanvas.style.display = 'none';\n\n                if (targetLayer && offcanvasMap.has(targetLayer)) {\n                    showOffcanvas(offcanvasMap.get(targetLayer));\n                }\n            });\n        });\n    }\n\n    const closeButton = offcanvas.querySelector('.c-offcanvas__close');\n    if (closeButton) {\n        closeButton.addEventListener('click', () => {\n            hideOffcanvas(offcanvas, () => {\n                offcanvas.style.display = 'none';\n            });\n        });\n    }\n}\n\n// Handle \"back\" buttons to switch offcanvas layers\nfunction registerBackButtonEvents() {\n    const backButtons = document.querySelectorAll('.c-offcanvas__back-button');\n    if (backButtons.length === 0) return;\n\n    backButtons.forEach(button => {\n        button.addEventListener('click', () => {\n        const current = button.closest('.c-offcanvas');\n        const targetLayer = button.dataset.target;\n        if (!targetLayer || !offcanvasMap.has(targetLayer)) return;\n\n        const targetOffcanvas = offcanvasMap.get(targetLayer);\n        const inner = current.querySelector('.c-offcanvas__inner');\n\n        addTransitionEndOnce(inner, () => {\n            current.style.display = 'none';\n            showOffcanvas(targetOffcanvas);\n        });\n\n        current.classList.remove(classActive);\n        });\n    });\n}\n\n// Register external triggers that open a specific offcanvas\nfunction registerExternalTriggers() {\n    const triggers = document.querySelectorAll('[data-target]');\n    if (triggers.length === 0) return;\n\n    triggers.forEach(trigger => {\n        trigger.addEventListener('click', () => {\n        const targetLayer = trigger.dataset.target;\n        if (!targetLayer || !offcanvasMap.has(targetLayer)) return;\n\n        const targetOffcanvas = offcanvasMap.get(targetLayer);\n        const openOffcanvas = document.querySelector(`.c-offcanvas.${classActive}`);\n\n        if (openOffcanvas && openOffcanvas !== targetOffcanvas) {\n            hideOffcanvas(openOffcanvas, () => {\n            openOffcanvas.style.display = 'none';\n            showOffcanvas(targetOffcanvas);\n            });\n        } else {\n            showOffcanvas(targetOffcanvas);\n        }\n        });\n    });\n}\n\n// Initialize all offcanvas-related behavior on DOM ready\ndocument.addEventListener('DOMContentLoaded', () => {\n    mapOffcanvasLayers();\n    initAlwaysOpenOffcanvasLayers();\n    registerBackButtonEvents();\n    registerExternalTriggers();\n});\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/strapPurchase/forcedOverlays.js?");/***/}),/***/"./source/out/sinn/src/js/modules/strapPurchase/productCounter.js":(/*!************************************************************************!*\
  !*** ./source/out/sinn/src/js/modules/strapPurchase/productCounter.js ***!
  \************************************************************************/ /***/function sourceOutSinnSrcJsModulesStrapPurchaseProductCounterJs(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"default\": () => (/* binding */ updateUI)\n/* harmony export */ });\n/**\n * This Software is the property of dotfly and is protected\n * by copyright law - it is NOT Freeware.\n *\n * Any unauthorized use of this software without a valid license key\n * is a violation of the license agreement and will be prosecuted by\n * civil and criminal law.\n *\n * @category   Counts items in staps selection\n * @author     Anna Morawe <anna.morawe@dotfly.de>\n * @license    http://www.dotfly.de Commercial\n * @link       http://www.dotfly.de\n */\n\nfunction updateItemCount() {\n    const filterContainers = document.querySelectorAll('.js--filter-container');\n\n    filterContainers.forEach(container => {\n        const countTargets = container.querySelectorAll('.js--count-target');\n        if (!countTargets.length) return;\n\n        const countableList = container.querySelector('.js--count-items');\n        if (!countableList) return;\n\n        const countableItems = countableList.querySelectorAll('li.js--countable:not(.is--hidden)');\n        const itemCount = countableItems.length;\n\n        countTargets.forEach(target => target.textContent = itemCount);\n\n        updateSingularCheck(container, itemCount);\n    });\n}\n\nfunction updateSingularCheck(container, itemCount) {\n    const singularCheckElement = container.querySelector('.js--singular-check');\n    if (!singularCheckElement || !window.oWave?.i18n) return;\n\n    const singularText = window.oWave?.i18n?.DOT_MODEL || \"Modell\";\n    const pluralText = window.oWave?.i18n?.DOT_MODELS || \"Modelle\";\n\n    singularCheckElement.textContent = (itemCount === 1) ? singularText : pluralText;\n}\n\nfunction updateUI() {\n    updateItemCount();\n}\n\ndocument.addEventListener('DOMContentLoaded', updateUI);\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/strapPurchase/productCounter.js?");/***/}),/***/"./source/out/sinn/src/js/modules/strapPurchase/productFilter.js":(/*!***********************************************************************!*\
  !*** ./source/out/sinn/src/js/modules/strapPurchase/productFilter.js ***!
  \***********************************************************************/ /***/function sourceOutSinnSrcJsModulesStrapPurchaseProductFilterJs(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _productCounter_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./productCounter.js */ \"./source/out/sinn/src/js/modules/strapPurchase/productCounter.js\");\n/**\n * This Software is the property of dotfly and is protected\n * by copyright law - it is NOT Freeware.\n *\n * Any unauthorized use of this software without a valid license key\n * is a violation of the license agreement and will be prosecuted by\n * civil and criminal law.\n *\n * @category   Product filter for straps\n * @author     Anna Morawe <anna.morawe@dotfly.de>\n * @license    http://www.dotfly.de Commercial\n * @link       http://www.dotfly.de\n */\n\n\n\ndocument.addEventListener('DOMContentLoaded', () => {\n    const searchInputs = document.querySelectorAll('.js--watch-filter');\n\n    if (!searchInputs.length) return;\n\n    searchInputs.forEach(searchInput => {\n        const parentContainer = searchInput.closest('.js--filter-container');\n        const resultItems = parentContainer\n            ? Array.from(parentContainer.querySelectorAll('.js--countable'))\n            : [];\n\n        function filterProducts(query) {\n            const lowerCaseQuery = query.toLowerCase();\n            let visibleCount = 0;\n\n            resultItems.forEach(item => {\n                const name = getItemName(item);\n                const serial = getItemSerial(item);\n                const matches = name.includes(lowerCaseQuery) || serial.includes(lowerCaseQuery);\n                toggleItemVisibility(item, matches);\n                if (matches) visibleCount++;\n            });\n\n            (0,_productCounter_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])();\n        }\n\n        function getItemName(item) {\n            return item?.dataset.name ? item.dataset.name.toLowerCase() : '';\n        }\n\n        function getItemSerial(item) {\n            return item?.dataset.serial\n                ? item.dataset.serial.toLowerCase().replace(/\\./g, '')\n                : '';\n        }\n\n        function toggleItemVisibility(item, isVisible) {\n            if (!item) return;\n            item.classList.toggle('is--hidden', !isVisible);\n            item.setAttribute('aria-hidden', !isVisible);\n        }\n\n        function handleSearchInput(event) {\n            let query = event.target.value.trim().toLowerCase();\n\n            // normalize query by removing dots\n            query = query.replace(/\\./g, '');\n\n            query.length >= 2 ? filterProducts(query) : resetFilter();\n        }\n\n        function resetFilter() {\n            resultItems.forEach(item => toggleItemVisibility(item, true));\n            (0,_productCounter_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])();\n        }\n\n        function preventFormSubmit(event) {\n            if (event.key === 'Enter') {\n                event.preventDefault();\n            }\n        }\n\n        searchInput.addEventListener('input', handleSearchInput);\n        searchInput.addEventListener('keydown', preventFormSubmit);\n    });\n});\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/strapPurchase/productFilter.js?");/***/}),/***/"./source/out/sinn/src/js/modules/strapPurchase/strapConfigurator.js":(/*!***************************************************************************!*\
  !*** ./source/out/sinn/src/js/modules/strapPurchase/strapConfigurator.js ***!
  \***************************************************************************/ /***/function sourceOutSinnSrcJsModulesStrapPurchaseStrapConfiguratorJs(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _toggleConfiguratorImages__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./toggleConfiguratorImages */ \"./source/out/sinn/src/js/modules/strapPurchase/toggleConfiguratorImages.js\");\n/* harmony import */ var _toggleStrapview__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./toggleStrapview */ \"./source/out/sinn/src/js/modules/strapPurchase/toggleStrapview.js\");\n/* harmony import */ var _wishlist__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../wishlist */ \"./source/out/sinn/src/js/modules/wishlist.js\");\n/* harmony import */ var _ArticleConfigurator__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../ArticleConfigurator */ \"./source/out/sinn/src/js/modules/ArticleConfigurator.js\");\n/**\n * This Software is the property of dotfly and is protected\n * by copyright law - it is NOT Freeware.\n *\n * Any unauthorized use of this software without a valid license key\n * is a violation of the license agreement and will be prosecuted by\n * civil and criminal law.\n *\n * @category   ...\n * @author     dotfly GmbH <info@dotfly.de>\n * @license    http://www.dotfly.de Commercial\n * @link       http://www.dotfly.de\n */\n\n\n\n\n\n\n// Function to fetch watch images data\nconst getWatchImagesData = async (strapId, selectedWatchId) => {\n    if (selectedWatchId === '' || selectedWatchId === 'no_selection' || selectedWatchId === null || strapId === '') return null;\n    try {\n        const response = await fetch(`/index.php?cl=configuratorcontroller&fnc=getWatchImagesData&strid=${encodeURIComponent(strapId)}&wid=${encodeURIComponent(selectedWatchId)}`);\n        if (!response.ok) {\n            throw new Error(`Failed to fetch content: ${response.statusText}`);\n        }\n        return await response.json();\n    } catch (error) {\n        console.error(\"Error fetching watch images data:\", error);\n        return null;\n    }\n}\n\n// Function to switch watch image\nfunction switchWatchImage(strapId, selectedWatchId) {\n    if (selectedWatchId === null || strapId === '') return null;\n    getWatchImagesData(strapId, selectedWatchId).then(imageData => {\n        updateWatchImages(imageData);\n    });\n}\n\n// Function to update watch images in the UI\nfunction updateWatchImages(imageData) {\n    const watchImg = document.querySelector('.js--strapviewToggle-watchimg img');\n    const strapImg = document.querySelector('.js--strapviewToggle-strapimg img');\n    const fallBack = document.querySelector('.js--strapviewToggle-fallback');\n\n    if (watchImg && imageData && imageData.watchImage) {\n        watchImg.src = imageData.watchImage;\n        fallBack.style.display = 'none';\n        watchImg.style.display = 'block';\n    } else {\n        if (watchImg) watchImg.style.display = 'none';\n        if (fallBack) fallBack.style.display = 'flex';\n    }\n    if (strapImg && imageData && imageData.strapImage) {\n        strapImg.src = imageData.strapImage;\n    }\n}\n\ndocument.addEventListener('DOMContentLoaded', () => {\n    // Get singleton instance of articleConfigurator\n    const articleObject = _ArticleConfigurator__WEBPACK_IMPORTED_MODULE_3__[\"default\"].getInstance();\n\n    // Unlock articleObject if it was locked during wishlist initialization\n    if (articleObject.isLocked) {\n        articleObject.unlock();\n    }\n\n    const form = document.querySelector('.js-oxProductForm');\n    const selectedWatch = document.getElementById('requiredForWatch');\n    const selectedClasp = document.getElementById('claspForStrap');\n    const selectClaspButton = document.getElementById('selectClasp');\n    const toBasketButton = document.getElementById('toBasket');\n    const strapViewToggle = document.querySelector('.js--strapviewToggle');\n\n    if( form && selectedWatch ) {\n\n        const strapId = form.querySelector('input[type=\"hidden\"][name=\"aid\"]');\n        if (selectClaspButton) {\n            toggleClaspButton(selectedWatch.value);\n        }\n\n        // if watch is preselected\n        if (selectedWatch.value !== '' && selectedWatch.value !== 'no_selection') {\n            // Auto-fetch clasp on page load when watch is pre-selected\n            if (selectClaspButton) {\n                selectClaspButton.setAttribute(\n                    \"data-payload\",\n                    JSON.stringify({ selectedWatchId: selectedWatch.value })\n                );\n            }\n            // Update Strapimage\n            toggleStrapView(strapId.value, selectedWatch.value);\n\n            // Set initial values in articleObject from the preselected watch\n            const selectedOption = selectedWatch.options[selectedWatch.selectedIndex];\n            if (selectedOption) {\n                articleObject.requiredForWatch = selectedWatch.value;\n                // Only set configHash from watch if no closure is selected yet\n                if (!articleObject.selectedClosure?.id) {\n                    articleObject.configHash = selectedOption.getAttribute('data-config-hash');\n                }\n            }\n        }\n\n        // Force user to select clasp if no watch selected\n        if (selectedWatch.value === 'no_selection' && selectedClasp && selectedClasp.value === '') {\n            if (toBasketButton) {\n                toggleBasketButton(false);\n            }\n            toggleStrapView(strapId.value, selectedWatch.value);\n        }\n\n        // we need a selected watch, before we can select a clasp\n        selectedWatch.addEventListener('change', async (e) => {\n\n            const opt = selectedWatch.options[selectedWatch.selectedIndex];\n            articleObject.requiredForWatchProAlphaTitle = opt?.getAttribute('data-proalpha-title');\n            articleObject.requiredForWatchArtNum = opt?.getAttribute('data-artnum');\n\n            // Check if we have a preselected closure from wishlist\n            const preselectedClosure = articleObject.selectedClosure?.id || null;\n\n            if (selectedClasp) {\n                let selectedClaspData = await getFirstClasp(strapId.value, e.target.value, preselectedClosure);\n                if (selectedClaspData) {\n                    selectedClasp.value = selectedClaspData.id;\n                }\n            }\n\n            // Hide the basket button if user selects 'no-selection'\n            if (toBasketButton) {\n                if (selectedWatch.value === 'no_selection' || (selectedClasp && selectedClasp.value === '')) {\n                    toggleBasketButton(false);\n                } else {\n                    toggleBasketButton(true);\n                }\n            }\n\n            if (selectClaspButton) {\n                selectClaspButton.setAttribute('data-payload', JSON.stringify({\"selectedWatchId\": e.target.value}));\n                toggleClaspButton(e.target.value);\n            }\n\n            articleObject.requiredForWatch = e.target.value;\n            const selectedOption = e.target.selectedOptions[0];\n            articleObject.configHash = selectedOption.getAttribute('data-config-hash');\n\n            // Update wishlist button with new configHash\n            setTimeout(async () => {\n                await (0,_wishlist__WEBPACK_IMPORTED_MODULE_2__.updateWishListButtons)();\n            }, 100);\n\n            toggleStrapView(strapId.value, e.target.value);\n        })\n\n        let claspSelection = null;\n        document.addEventListener('strapConfiguratorLoaded', () => {\n            const claspSelection = document.getElementById('claspSelection');\n            const selectedClasp = document.getElementById('claspForStrap');\n\n            if (claspSelection.value !== '') {\n                toggleBasketButton(true)\n            }\n\n            selectedClasp.addEventListener('input', () => {\n                if (selectedClasp.value !== '') {\n                    toggleBasketButton(true)\n                }\n            });\n\n            registerclaspSelection(claspSelection, selectedClasp);\n            (0,_toggleConfiguratorImages__WEBPACK_IMPORTED_MODULE_0__.registerViewToggle)();\n\n            if (claspSelection && selectedClasp) {\n                // Add the selected clasp input to the basket form if not already present\n                const basketForm = document.querySelector('form[name=\"tobasket\"]');\n                if (basketForm && !basketForm.querySelector('#claspForStrap')) {\n                    const clonedClaspInput = selectedClasp.cloneNode(true);\n                    basketForm.appendChild(clonedClaspInput);\n                }\n                toBasketButton.addEventListener('click', () => {\n                    selectedClasp.value = claspSelection.options[claspSelection.selectedIndex].value;\n                });\n            }\n        });\n    }\n\n    const getFirstClasp = async (strapId, selectedWatchId, preselectedClosure = null) => {\n        if (selectedWatchId === '') return null;\n        try {\n            let url = `/index.php?cl=configuratorcontroller&fnc=getClasp&strid=${encodeURIComponent(strapId)}&wid=${encodeURIComponent(selectedWatchId)}`;\n\n            // Add preselected closure if available (from wishlist)\n            if (preselectedClosure) {\n                url += `&preselectedClosure=${encodeURIComponent(preselectedClosure)}`;\n            }\n\n            const response = await fetch(url);\n            if (!response.ok) {\n                throw new Error(`Failed to fetch content: ${response.statusText}`);\n            }\n            return await response.json();\n        } catch (error) {\n            console.error(\"Error fetching overlay content:\", error);\n            return null;\n        }\n    }\n\n    const registerclaspSelection = (claspSelection, selectedClasp) => {\n        if (!claspSelection || !selectedClasp) return;\n\n        // Determine which element to select initially\n        let firstElement;\n\n        // Priority 1: If selectedClasp already has a value (from hidden input), try to find and select it\n        if (selectedClasp.value !== '') {\n            firstElement = claspSelection.querySelector(`option[value=\"${selectedClasp.value}\"]`);\n            if (firstElement) {\n                claspSelection.value = selectedClasp.value;\n            }\n        }\n\n        // Priority 2: If no valid preselection from hidden input, use first option\n        if (!firstElement && claspSelection.options.length > 0) {\n            firstElement = claspSelection.options[0];\n\n            // Update both selectedClasp and claspSelection with the first element\n            if (firstElement) {\n                selectedClasp.value = firstElement.value;\n                claspSelection.value = firstElement.value;\n            }\n        }\n\n        // Priority 3: Only if somehow no options exist at all, try currently selected\n        if (!firstElement && claspSelection.value !== '') {\n            firstElement = claspSelection.querySelector(`option[value=\"${claspSelection.value}\"]`);\n        }\n\n        // Update articleObject with initial closure selection\n        if (firstElement && firstElement.value) {\n            articleObject.selectedClosure = {\n                id: firstElement.value,\n                title: firstElement.text\n            };\n            // Set initial configHash from selected closure\n            const initialConfigHash = firstElement.getAttribute('data-config-hash');\n            if (initialConfigHash) {\n                articleObject.configHash = initialConfigHash;\n\n                // Update wishlist button with new configHash\n                setTimeout(async () => {\n                    await (0,_wishlist__WEBPACK_IMPORTED_MODULE_2__.updateWishListButtons)();\n                }, 100);\n            }\n        }\n\n        updateProductDetails(firstElement.getAttribute('data-price'), firstElement.getAttribute('data-image'));\n\n        const selectedOption = claspSelection.options[claspSelection.selectedIndex];\n        updateSelectedClosure(selectedOption);\n\n        claspSelection.addEventListener('change', async (e) => {\n            const selectElement = e.target;\n            const selectedOption = selectElement.options[selectElement.selectedIndex];\n\n            selectedClasp.value = selectedOption.value;\n            updateSelectedClosure(selectedOption);\n\n            if (selectedOption.getAttribute('data-config-hash')) {\n                const newHash = selectedOption.getAttribute('data-config-hash');\n\n                if (typeof articleObject.updateConfigHash === 'function') {\n                    articleObject.updateConfigHash(newHash, true); // true = forceUpdate\n                } else {\n                    // Fallback: direct assignment if method doesn't exist\n                    articleObject.configHash = newHash;\n                }\n            } else {\n                console.warn('No data-config-hash attribute found on selected option!');\n            }\n\n            // Update wishlist button's data-config-hash attribute with new configHash\n            const wishlistButtons = document.querySelectorAll('[data-component=\"wishlist-control\"], .is--add-to-wishlist, .is--on-wishlist');\n            wishlistButtons.forEach(button => {\n                button.setAttribute('data-config-hash', articleObject.configHash);\n            });\n\n            updateProductDetails(selectedOption.getAttribute('data-price'), selectedOption.getAttribute('data-image'), selectedOption.getAttribute('data-netprice'));\n            await (0,_wishlist__WEBPACK_IMPORTED_MODULE_2__.updateWishListButtons)();\n        });\n    };\n\n    const updateProductDetails = (price, imageUrl, netPrice = null) => {\n        // Preis aktualisieren\n        const strapConfiguratorPrice = document.getElementById('strapConfiguratorPrice');\n        const basePriceInput = document.querySelector('input[type=\"hidden\"][name=\"basePrice\"]');\n        const basePrice = parseFloat(basePriceInput?.value || 0);\n        const extraPrice = parseFloat(price || 0);\n        const totalPrice = basePrice + extraPrice;\n        const formattedPrice = new Intl.NumberFormat('de-DE', {\n            style: \"decimal\",\n            minimumFractionDigits: 2\n        }).format(totalPrice);\n\n        // Update Article Object\n        strapConfiguratorPrice.textContent = formattedPrice;\n        const ao = _ArticleConfigurator__WEBPACK_IMPORTED_MODULE_3__[\"default\"].getInstance();\n        const safeParse = v => {\n            if (v === null || v === undefined) return 0;\n            return parseFloat(String(v).trim().replace(',', '.')) || 0;\n        };\n\n        ao.netPrice = parseFloat((safeParse(ao.netPrice) + safeParse(netPrice)).toFixed(2));\n\n        // Bild-Container selektieren\n        const pictureWrapper = document.querySelector('.c-strapconfigurator__image.is--strapview');\n        if (!pictureWrapper) return;\n\n        // Hinweislogik\n        const warningClass = 'no-image-warning';\n        const wrapperNoImageClass = 'is--no-image-for-combination';\n        const existingWarning = pictureWrapper.querySelector(`.${warningClass}`);\n        const isMissingImage = imageUrl.includes('/master/product/');\n\n        // Hinweis anzeigen/entfernen und Klasse toggeln\n        if (isMissingImage) {\n            if (!existingWarning) {\n                const warningText = document.createElement('span');\n                warningText.classList.add(warningClass);\n                warningText.textContent = oWave.i18n.DOT_NO_IMAGE_AVAILABLE;\n                pictureWrapper.appendChild(warningText);\n            }\n            pictureWrapper.classList.add(wrapperNoImageClass);\n        } else {\n            if (existingWarning) {\n                existingWarning.remove();\n            }\n            pictureWrapper.classList.remove(wrapperNoImageClass);\n        }\n\n        // Neues Bild erzeugen\n        const newPicture = document.createElement('picture');\n\n        const imageData = {\n            xlarge: {\n                sizes: [\n                    { width: 700, height: 800, res: 1 },\n                    { width: 1400, height: 1600, res: 2 }\n                ],\n                media: \"(min-width: 1600px)\"\n            },\n            large: {\n                sizes: [\n                    { width: 600, height: 700, res: 1 },\n                    { width: 1200, height: 1400, res: 2 }\n                ],\n                media: \"(min-width: 1280px)\"\n            },\n            medium: {\n                sizes: [\n                    { width: 500, height: 600, res: 1 },\n                    { width: 1000, height: 1200, res: 2 }\n                ],\n                media: \"(min-width: 768px)\"\n            },\n            small: {\n                sizes: [\n                    { width: 400, height: 500, res: 1 },\n                    { width: 800, height: 1000, res: 2 }\n                ],\n                media: \"(min-width: 536px)\"\n            }\n        };\n\n        Object.entries(imageData).forEach(([_, config]) => {\n            const source = document.createElement('source');\n            source.media = config.media;\n            source.srcset = config.sizes.map(size => {\n                return `${imageUrl}?width=${size.width}&height=${size.height}&quality=100 ${size.res}x`;\n            }).join(', ');\n            newPicture.appendChild(source);\n        });\n\n        const img = document.createElement('img');\n        img.src = `${imageUrl}?width=660&height=1020&quality=100`;\n        img.alt = document.querySelector('.c-strapconfigurator__buybox > h2')?.textContent || '';\n        img.loading = 'lazy';\n        newPicture.appendChild(img);\n\n        // Bild einfügen (aber Hinweis <span> nicht löschen)\n        while (pictureWrapper.firstChild && !pictureWrapper.firstChild.classList?.contains(warningClass)) {\n            pictureWrapper.removeChild(pictureWrapper.firstChild);\n        }\n        pictureWrapper.insertBefore(newPicture, pictureWrapper.querySelector(`.${warningClass}`) || null);\n    };\n\n\n    // If nothing preselected but firstElement exists, select it\n    function ensureClaspSelection(claspSelection, selectedClasp, firstElement) {\n        if (claspSelection.value === firstElement?.value) {\n            selectedClasp.dispatchEvent(new Event('input'));\n        }\n    }\n\n    // If selectedClasp already has a value, set it on the claspSelection dropdown\n    function updateClaspDropdown(claspSelection, selectedClasp) {\n        // If selectedClasp already has a value, set it on the claspSelection dropdown\n        if (selectedClasp.value !== '') {\n            const existingOption = claspSelection.querySelector(`option[value=\"${selectedClasp.value}\"]`);\n            if (existingOption) {\n                claspSelection.value = selectedClasp.value;\n            }\n        }\n    }\n\n    /**\n     * Toggle visibility of the clasp selection button based on whether a watch is selected.\n     * @param {string} selectedWatch\n     */\n    function toggleClaspButton(selectedWatch) {\n        if (selectClaspButton) {\n            const hasSelectedWatch = selectedWatch !== '';\n            selectClaspButton.classList.toggle('is--hidden', !hasSelectedWatch);\n        }\n    }\n\n    /**\n     * Toggle visibility of the model view toggle button based on whether a watch is selected.\n     * @param {string} strapId - The ID of the strap\n     * @param {string} selectedWatch - The ID of the selected watch\n     */\n    function toggleStrapView(strapId, selectedWatch) {\n        if (strapViewToggle) {\n            const hasSelectedWatch = (selectedWatch !== '' && selectedWatch !== 'no_selection');\n            strapViewToggle.classList.toggle('is--hidden', !hasSelectedWatch);\n            if( hasSelectedWatch ){\n                switchWatchImage(strapId, selectedWatch);\n            } else {\n                (0,_toggleStrapview__WEBPACK_IMPORTED_MODULE_1__.toggleView)('strapview');\n            }\n        }\n    }\n\n    // hide or show basket button\n    function toggleBasketButton(visible) {\n        const selectClaspNotice = document.querySelector('.c-detail__clasp-selection');\n        if (toBasketButton) {\n            if (visible) {\n                toBasketButton.classList.remove('is--hidden');\n                if (selectClaspNotice) selectClaspNotice.classList.add('is--hidden');\n            } else {\n                toBasketButton.classList.add('is--hidden');\n                if (selectClaspNotice) selectClaspNotice.classList.remove('is--hidden');\n            }\n        }\n    }\n\n    function updateSelectedClosure(option) {\n        articleObject.selectedClosure = {\n            id: option.value,\n            artnum: option.getAttribute('data-artnum'),\n            title: option.text,\n            proalphatitle: option.getAttribute('data-proalpha-title'),\n        };\n    }\n\n});\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/strapPurchase/strapConfigurator.js?");/***/}),/***/"./source/out/sinn/src/js/modules/strapPurchase/toggleConfiguratorImages.js":(/*!**********************************************************************************!*\
  !*** ./source/out/sinn/src/js/modules/strapPurchase/toggleConfiguratorImages.js ***!
  \**********************************************************************************/ /***/function sourceOutSinnSrcJsModulesStrapPurchaseToggleConfiguratorImagesJs(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   registerViewToggle: () => (/* binding */ registerViewToggle)\n/* harmony export */ });\n/**\n * This Software is the property of dotfly and is protected\n * by copyright law - it is NOT Freeware.\n *\n * Any unauthorized use of this software without a valid license key\n * is a violation of the license agreement and will be prosecuted by\n * civil and criminal law.\n *\n * @category   Toggles front and back images in strap configurator\n * @author     Anna Morawe <anna.morawe@dotfly.de>\n * @license    http://www.dotfly.de Commercial\n * @link       http://www.dotfly.de\n */\n\nfunction registerViewToggle() {\n    const views = document.querySelectorAll('.c-strapconfigurator__image');\n    const buttons = document.querySelectorAll('.js--strapconfigurator-toggle');\n    const claspSelect = document.getElementById('claspSelection');\n\n    if (views.length === 0 || buttons.length === 0) {\n        return;\n    }\n\n    function toggleView(targetView) {\n        views.forEach(view => {\n            view.classList.toggle('is--visible', view.classList.contains(`is--${targetView}`));\n        });\n\n        buttons.forEach(button => {\n            button.classList.toggle('is--active', button.classList.contains(`is--${targetView}`));\n        });\n    }\n\n    buttons.forEach(button => {\n        button.addEventListener('click', function () {\n            const targetView = this.classList.contains('is--strapview') ? 'strapview' : 'modelview';\n            toggleView(targetView);\n        });\n    });\n\n    if (claspSelect) {\n        claspSelect.addEventListener('change', function () {\n            const modelViewVisible = document.querySelector('.c-strapconfigurator__image.is--modelview')?.classList.contains('is--visible');\n            if (modelViewVisible) {\n                toggleView('strapview');\n            }\n        });\n    }\n}\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/strapPurchase/toggleConfiguratorImages.js?");/***/}),/***/"./source/out/sinn/src/js/modules/strapPurchase/toggleStrapview.js":(/*!*************************************************************************!*\
  !*** ./source/out/sinn/src/js/modules/strapPurchase/toggleStrapview.js ***!
  \*************************************************************************/ /***/function sourceOutSinnSrcJsModulesStrapPurchaseToggleStrapviewJs(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   toggleView: () => (/* binding */ toggleView)\n/* harmony export */ });\n/**\n * This Software is the property of dotfly and is protected\n * by copyright law - it is NOT Freeware.\n *\n * Any unauthorized use of this software without a valid license key\n * is a violation of the license agreement and will be prosecuted by\n * civil and criminal law.\n *\n * @category   Toggles strap and modell view\n * @license    http://www.dotfly.de Commercial\n * @link       http://www.dotfly.de\n */\n\n// Cache DOM elements outside of functions\nconst buttons = document.querySelectorAll('.js--strapviewToggle-btn');\nconst target = document.querySelector('.js--strapviewToggle-target');\nconst galleryBtns_desk = document.querySelector('.c-detail__anchors');\nconst galleryBtns_mobile = document.querySelector('.c-detail__images > .glide__arrows');\n\nfunction registerStrapViewToggle() {\n    if (buttons.length === 0) {\n        return;\n    }\n    buttons.forEach(button => {\n        button.addEventListener('click', function () {\n            const targetView = this.classList.contains('is--strapview') ? 'strapview' : 'modelview';\n            toggleView(targetView);\n        });\n    });\n}\n\nregisterStrapViewToggle();\n\nfunction toggleView(targetView) {\n    if (!target) {\n        return;\n    }\n\n    if(targetView === 'modelview') {\n        target.classList.add('is--active');\n        if( galleryBtns_desk) {\n            galleryBtns_desk.classList.add('is--hidden');\n            galleryBtns_mobile.classList.add('is--hidden');\n        }\n    } else {\n        target.classList.remove('is--active');\n        if( galleryBtns_desk) {\n            galleryBtns_desk.classList.remove('is--hidden');\n            galleryBtns_mobile.classList.remove('is--hidden');\n        }\n    }\n\n    buttons.forEach(button => {\n        button.classList.toggle('is--active', button.classList.contains(`is--${targetView}`));\n    });\n}\n\n\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/strapPurchase/toggleStrapview.js?");/***/}),/***/"./source/out/sinn/src/js/modules/tabcontent.js":(/*!******************************************************!*\
  !*** ./source/out/sinn/src/js/modules/tabcontent.js ***!
  \******************************************************/ /***/function sourceOutSinnSrcJsModulesTabcontentJs(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! animejs/lib/anime.es.js */ \"./node_modules/animejs/lib/anime.es.js\");\n/**\n * This Software is the property of dotfly and is protected\n * by copyright law - it is NOT Freeware.\n *\n * Any unauthorized use of this software without a valid license key\n * is a violation of the license agreement and will be prosecuted by\n * civil and criminal law.\n *\n * @category   Tabs as seen in c-search and c-bandselect\n * @author     Anna Morawe <anna.morawe@dotfly.de>\n * @license    http://www.dotfly.de Commercial\n * @link       http://www.dotfly.de\n */\n\n\n\nconst cubicBezier = 'cubicBezier(.40,.05,.20,.90)';\n\nfunction handleTabClick(event) {\n    const trigger = event.currentTarget;\n    const tabContainer = trigger.closest('.c-tabcontent');\n    const tabTriggers = tabContainer.querySelectorAll('.c-tabcontent__trigger');\n    const tabPanels = tabContainer.querySelectorAll('.c-tabcontent__content');\n\n    if (!trigger.classList.contains('js--active')) {\n        const targetId = trigger.dataset.target;\n        const targetContent = tabContainer.querySelector(`.c-tabcontent__content[data-id=\"${targetId}\"]`);\n        const activeContent = tabContainer.querySelector('.c-tabcontent__content.js--active');\n\n        updateActiveTrigger(tabTriggers, trigger);\n        updateAriaAttributes(tabTriggers, tabPanels, trigger, targetContent);\n        switchTabContent(activeContent, targetContent);\n    }\n}\n\nfunction handleKeydown(event) {\n    const trigger = event.currentTarget;\n    const tabContainer = trigger.closest('.c-tabcontent');\n    const tabTriggers = Array.from(tabContainer.querySelectorAll('.c-tabcontent__trigger'));\n    let index = tabTriggers.indexOf(trigger);\n\n    if (event.key === 'ArrowRight') {\n        index = (index + 1) % tabTriggers.length;\n    } else if (event.key === 'ArrowLeft') {\n        index = (index - 1 + tabTriggers.length) % tabTriggers.length;\n    } else {\n        return;\n    }\n\n    tabTriggers[index].click();\n    tabTriggers[index].focus();\n}\n\nfunction updateActiveTrigger(tabTriggers, activeTrigger) {\n    tabTriggers.forEach(t => t.classList.remove('js--active'));\n    activeTrigger.classList.add('js--active');\n}\n\nfunction updateAriaAttributes(tabTriggers, tabPanels, activeTrigger, activePanel) {\n    tabTriggers.forEach(trigger => {\n        trigger.setAttribute('aria-selected', 'false');\n        trigger.setAttribute('tabindex', '-1');\n    });\n    activeTrigger.setAttribute('aria-selected', 'true');\n    activeTrigger.setAttribute('tabindex', '0');\n\n    tabPanels.forEach(panel => {\n        panel.setAttribute('hidden', 'true');\n    });\n    activePanel.removeAttribute('hidden');\n    activePanel.focus();\n}\n\nfunction switchTabContent(oldContent, newContent) {\n    if (oldContent && oldContent !== newContent) {\n        (0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])({\n            targets: oldContent,\n            opacity: [1, 0],\n            duration: 500,\n            easing: cubicBezier,\n            complete: function () {\n                oldContent.style.display = 'none';\n                oldContent.classList.remove('js--active');\n                newContent.style.display = 'block';\n\n                (0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])({\n                    targets: newContent,\n                    opacity: [0, 1],\n                    duration: 500,\n                    easing: cubicBezier,\n                    complete: function () {\n                        newContent.classList.add('js--active');\n                    }\n                });\n            }\n        });\n    }\n}\n\nfunction initializeTabNavigation() {\n    const tabContainers = document.querySelectorAll('.c-tabcontent');\n    if (!tabContainers.length) return;\n\n    tabContainers.forEach(tabContainer => {\n        const tabTriggers = tabContainer.querySelectorAll('.c-tabcontent__trigger');\n        const tabPanels = tabContainer.querySelectorAll('.c-tabcontent__content');\n\n        tabTriggers.forEach(trigger => {\n            trigger.addEventListener('click', handleTabClick);\n            trigger.addEventListener('keydown', handleKeydown);\n        });\n\n        // Set initial aria attributes\n        tabTriggers.forEach((trigger, index) => {\n            trigger.setAttribute('role', 'tab');\n            trigger.setAttribute('aria-selected', index === 0 ? 'true' : 'false');\n            trigger.setAttribute('tabindex', index === 0 ? '0' : '-1');\n        });\n\n        tabPanels.forEach((panel, index) => {\n            panel.setAttribute('role', 'tabpanel');\n            if (index !== 0) {\n                panel.setAttribute('hidden', 'true');\n            }\n        });\n    });\n}\n\ndocument.addEventListener('DOMContentLoaded', initializeTabNavigation);\n\n\n/*\n\nHTML for Tabs:\n\n<div class=\"c-tabcontent\">\n    <div class=\"c-tabcontent__triggers\" role=\"tablist\">\n        <button class=\"c-tabcontent__trigger js--active\"\n                data-target=\"tabcontent__products\"\n                aria-controls=\"tabcontent__products\"\n                aria-selected=\"true\"\n                role=\"tab\">\n            Überschrift 1\n        </button>\n        <button class=\"c-tabcontent__trigger\"\n                data-target=\"tabcontent__test\"\n                aria-controls=\"tabcontent__test\"\n                aria-selected=\"false\"\n                role=\"tab\">\n            Überschrift 2\n        </button>\n    </div>\n\n    <div class=\"c-tabcontent__contents\">\n        <div class=\"c-tabcontent__content js--active\" data-id=\"tabcontent__products\" id=\"tabcontent__products\" role=\"tabpanel\">\n            Inhalt 1\n        </div>\n\n        <div class=\"c-tabcontent__content\" data-id=\"tabcontent__test\" id=\"tabcontent__test\" role=\"tabpanel\" hidden>\n            Inhalt 2\n        </div>\n    </div>\n</div>\n\n*/\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/tabcontent.js?");/***/}),/***/"./source/out/sinn/src/js/modules/tabs.js":(/*!************************************************!*\
  !*** ./source/out/sinn/src/js/modules/tabs.js ***!
  \************************************************/ /***/function sourceOutSinnSrcJsModulesTabsJs(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! animejs/lib/anime.es.js */ \"./node_modules/animejs/lib/anime.es.js\");\n\n\n/* Klickelement und Contentelement werden über data-attribute verknüpft */\nvar tab = document.querySelectorAll('.js-tab');\n\nvar tabsList;\n\ntab.forEach(function (tabModule) {\n\ttabsList = tabModule.querySelector('.c-tabs__list');\n\ttabModule.querySelectorAll('.js-tab-trigger').forEach(function (item) {\n\n\t\titem.addEventListener('click', function (trigger) {\n\t\t\tvar activeTab = '.js-tab-content[data-tab=\"' + item.dataset.target + '\"]';\n\t\t\tvar activeContent = tabModule.querySelectorAll(activeTab);\n\n\t\t\ttabModule.querySelectorAll('.js-tab-trigger').forEach(function (element){\n\t\t\t\telement.classList.remove('is--active');\n\t\t\t\telement.setAttribute('aria-selected', false);\n\t\t\t});\n\n\t\t\ttabModule.querySelectorAll('.js-tab-content').forEach(element => element.classList.remove('is--active'));\n\n\t\t\tactiveContent.forEach(function (element) {\n\t\t\t\telement.classList.add('is--active');\n\n\t\t\t\tvar test = element.parentElement;\n\t\t\t\tvar test1 = test.parentElement;\n\t\t\t\tvar test2 = test1.querySelector('.c-tabs__content');\n\t\t\t\tvar test3 = test1.parentElement;\n\t\t\t\tvar test4 = test3.querySelector('.c-tabs__img');\n\n\t\t\t\t(0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])({\n\t\t\t\t\ttargets: test2.querySelectorAll('.c-tabs__content-item.is--active'),\n\t\t\t\t\topacity: ['0', '1'],\n\t\t\t\t\tduration: 1000,\n\t\t\t\t\teasing: 'cubicBezier(.40,.05,.20,.90)',\n\t\t\t\t\tbegin: function () {\n\t\t\t\t\t\telement.style.display = 'block';\n\t\t\t\t\t},\n\t\t\t\t\tcomplete: function () {\n\n\t\t\t\t\t\t// focus first link on keyboard navigation\n\t\t\t\t\t\tif(trigger.detail === 0) {\n\t\t\t\t\t\t\tif(element.classList.contains('c-tabs__content-item')) {\n\t\t\t\t\t\t\t\telement.querySelector('a').focus({ focusVisible: true });\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\t(0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])({\n\t\t\t\t\ttargets: test4.querySelectorAll('.c-tabs__img-item.is--active div img'),\n\t\t\t\t\ttranslateY: ['100%', '0'],\n\t\t\t\t\tdelay: animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"].stagger(75,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tstart: 0,\n\t\t\t\t\t\t}\n\t\t\t\t\t),\n\t\t\t\t\tduration: 1000,\n\t\t\t\t\teasing: 'easeInOutCubic',\n\t\t\t\t\tbegin: function () {\n\t\t\t\t\t\ttabsList.classList.add('js--pointerevent');\n\t\t\t\t\t\telement.style.display = 'block';\n\t\t\t\t\t},\n\t\t\t\t\tcomplete: function () {\n\t\t\t\t\t\ttabsList.classList.remove('js--pointerevent');\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\t(0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])({\n\t\t\t\t\ttargets: test2.querySelector('.c-tabs__content-item:not(.is--active)'),\n\t\t\t\t\topacity: ['1', '0'],\n\t\t\t\t\tduration: 750,\n\t\t\t\t\teasing: 'cubicBezier(.40,.05,.20,.90)',\n\t\t\t\t\tcomplete: function () {\n\t\t\t\t\t\ttest2.querySelector('.c-tabs__content-item:not(.is--active)').style.display = 'none';\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\t(0,animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])({\n\t\t\t\t\ttargets: test4.querySelectorAll('.c-tabs__img-item:not(.is--active) div img'),\n\t\t\t\t\ttranslateY: ['0%', '-100%'],\n\t\t\t\t\tdelay: animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"].stagger(75,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tstart: 0,\n\t\t\t\t\t\t}\n\t\t\t\t\t),\n\t\t\t\t\tduration: 1000,\n\t\t\t\t\teasing: 'easeInOutCubic',\n\t\t\t\t\tcomplete: function () {\n\t\t\t\t\t\ttest4.querySelector('.c-tabs__img-item:not(.is--active)').style.display = 'none';\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t});\n\n\t\t\titem.classList.add('is--active');\n\t\t\titem.setAttribute('aria-selected', true);\n\t\t});\n\t});\n\n\tlet rightSideHeight;\n\tlet leftSideHeight;\n\n\ttabModule.querySelectorAll('.c-tabs__img').forEach(function (item) {\n\t\tconst imgs = Array.from(item.querySelectorAll('.c-tabs__img-item'));\n\t\tlet highestImg = 0;\n\n\t\timgs.forEach(function (img) {\n\t\t\tconst imgH = img.getBoundingClientRect().height;\n\t\t\thighestImg = imgH > highestImg ? imgH : highestImg;\n\t\t});\n\n\t\trightSideHeight = highestImg;\n\t});\n\n\ttabModule.querySelectorAll('.c-tabs__wrapper').forEach(function (item) {\n\t\tconst items = Array.from(item.querySelectorAll('.c-tabs__content-item'));\n\t\tconst itemListHeight = item.querySelector('.c-tabs__list').offsetHeight;\n\t\tlet highestItem = 0;\n\n\t\titems.forEach(function (item) {\n\t\t\tconst itemH = item.getBoundingClientRect().height;\n\t\t\thighestItem = itemH > highestItem ? itemH : highestItem;\n\t\t});\n\n\t\tleftSideHeight = highestItem + itemListHeight;\n\t});\n\n\ttabModule.querySelector('.c-tabs__wrapper').style.height = leftSideHeight + 'px';\n\ttabModule.querySelector('.c-tabs__img').style.height = rightSideHeight + 'px';\n\n\twindow.addEventListener('resize', function (event) {\n\t\tlet rightSideHeight;\n\t\tlet leftSideHeight;\n\n\t\ttabModule.querySelectorAll('.c-tabs__img').forEach(function (item) {\n\t\t\tconst imgs = Array.from(item.querySelectorAll('.c-tabs__img-item'));\n\t\t\tlet highestImg = 0;\n\n\t\t\timgs.forEach(function (img) {\n\t\t\t\tconst imgH = img.getBoundingClientRect().height;\n\t\t\t\thighestImg = imgH > highestImg ? imgH : highestImg;\n\t\t\t});\n\n\t\t\trightSideHeight = highestImg;\n\t\t});\n\n\t\ttabModule.querySelectorAll('.c-tabs__wrapper').forEach(function (item) {\n\t\t\tconst items = Array.from(item.querySelectorAll('.c-tabs__content-item'));\n\t\t\tconst itemListHeight = item.querySelector('.c-tabs__list').offsetHeight;\n\t\t\tlet highestItem = 0;\n\n\t\t\titems.forEach(function (item) {\n\t\t\t\tconst itemH = item.getBoundingClientRect().height;\n\t\t\t\thighestItem = itemH > highestItem ? itemH : highestItem;\n\t\t\t});\n\n\t\t\tleftSideHeight = highestItem + itemListHeight;\n\t\t});\n\n\t\ttabModule.querySelector('.c-tabs__wrapper').style.height = leftSideHeight + 'px';\n\t\ttabModule.querySelector('.c-tabs__img').style.height = rightSideHeight + 'px';\n\t});\n});\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/tabs.js?");/***/}),/***/"./source/out/sinn/src/js/modules/techabc.js":(/*!***************************************************!*\
  !*** ./source/out/sinn/src/js/modules/techabc.js ***!
  \***************************************************/ /***/function sourceOutSinnSrcJsModulesTechabcJs(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _accordion__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./accordion */ \"./source/out/sinn/src/js/modules/accordion.js\");\n/* harmony import */ var _timeline__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./timeline */ \"./source/out/sinn/src/js/modules/timeline.js\");\n/* harmony import */ var _registerOffcanvas__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./registerOffcanvas */ \"./source/out/sinn/src/js/modules/registerOffcanvas.js\");\n/* harmony import */ var _glidejs_glide__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @glidejs/glide */ \"./node_modules/@glidejs/glide/dist/glide.esm.js\");\n\n\n\n\n\nconst highlightTerms = () => {\n    const content = document.querySelectorAll('#cDetailBody.js--techabc p, #cDetailBody.js--techabc ul:not(.glide__slides), #cDetailBody.js--techabc .c-accordion__content, .js--techabc .js--techabc-area p');\n\n    content.forEach(element => {\n        element.innerHTML = parseContent(element.innerHTML);\n\t    //console.log(element.innerHTML);\n    })\n\n    ;(0,_accordion__WEBPACK_IMPORTED_MODULE_0__.accordion)();\n\t(0,_timeline__WEBPACK_IMPORTED_MODULE_1__.timeline)();\n\n}\n\nconst parseContent = (content) => {\n\tconst glossaryTerms = document.matchTerms.sort((a, b) => b.name.length - a.name.length);\n\n\tglossaryTerms.forEach(term => {\n\t\tconst searchTerm = term.name.replace(/[-/\\\\^$*+?.()|[\\]{}]/g, '\\\\$&');\n\t\tconst regex = new RegExp(`(?!<a.*?class=\\\\\"c-techabc__link\\\\\">)(?![^<]*?</a>)\\\\b(${searchTerm})\\\\b`, 'gim');\n\t\tcontent = content.replace(regex, match => wrapTermWithLink(match.trim(), term.id));\n\t});\n\treturn content;\n}\n\n\nconst wrapTermWithLink = (name, id) => {\n    return ` <a role=\"button\" class=\"c-techabc__link\" data-id=\"${id}\" aria-expanded=\"false\" aria-controls=\"technikabc\" aria-label=\"${oWave.i18n.DOT_OPEN_OVERLAY}\" tabindex=\"0\">${name}</a>`\n}\n\nconst registerTriggers = () => {\n    const techTriggers = document.querySelectorAll('.c-techabc__link')\n    const techContent = document.querySelector('.c-techabc__content')\n\n    function openAndFillCanvas(event, item) {\n        event.preventDefault();\n\n        const techId = item.getAttribute('data-id');\n        const url = `/index.php?cl=techabcfrontendcontroller&fnc=getTechTerm&id=${techId}`;\n\n        const clickElement = event.currentTarget;\n\n        fetch(url)\n            .then(response => response.json())\n            .then(data => {\n                const title = data.title;\n                const desc = data.parsedContent;\n\n                techContent.innerHTML = `<h3 class=\"c-techabc__headline\">${title}</h3><div class=\"c-techabc__desc\">${desc}</div>`;\n\n                (0,_registerOffcanvas__WEBPACK_IMPORTED_MODULE_2__.registerOffcanvas)({\n                    offCanvas: '.c-techabc',\n                    closeButtons: '.c-techabc__close, .c-techabc__background',\n                    // pass triggers, because of handling state \"area-expanded\"\n                    triggers: techTriggers\n                }).openOffcanvas(clickElement);\n            });\n    }\n\n    techTriggers.forEach(item => {\n        item.addEventListener('click', (event) => { openAndFillCanvas(event, item); });\n        item.addEventListener('keydown', (event) => {\n            if (event.key === \"Enter\") {\n                openAndFillCanvas(event, item);\n            }\n        });\n    });\n}\n\nconst techAbcExcludedPages = document.querySelector('.is-checkout, .cl-techabcfrontendcontroller, .is-techabc-excluded-page')\n\nfunction highlightTermsAndRegisterTriggers() {\n    if (!techAbcExcludedPages) {\n        highlightTerms();\n        //console.log('Terms are highlighted.');\n\n        registerTriggers();\n        //console.log('Triggers are registered.');\n\n    } else {\n        //console.log('This page is excluded from Tech ABC.');\n    }\n}\n\nfunction waitForContentAndExecute() {\n    if (document.readyState === 'complete') {\n        //console.log('readyState is complete');\n        highlightTermsAndRegisterTriggers();\n    } else {\n        window.addEventListener('load', () => {\n            //console.log('event listener load');\n            highlightTermsAndRegisterTriggers();\n        });\n    }\n}\n\ndocument.querySelector('#technikabc') && waitForContentAndExecute();\n\n// *** Index *** //\n\nif (document.querySelector('.js--techabc-index')) {\n    let techAbcIndexSlider = new _glidejs_glide__WEBPACK_IMPORTED_MODULE_3__[\"default\"]('.js--techabc-index .glide', {\n        type: 'slider',\n        bound: true,\n        rewind: false,\n        gap: 0,\n        perView: 26,\n        perSwipe: '|',\n        perTouch: '|',\n        touchRatio: 1,\n        breakpoints: {\n            859: {\n                perView: 13\n            },\n            639: {\n                perView: 5\n            }\n        }\n    })\n\n    techAbcIndexSlider.mount();\n\n    let techAbcIndex= document.querySelector('.js--techabc-index');\n    let techAbcIndexLink= document.querySelectorAll('.js--techabc-index-link');\n    let techAbcIndexTarget= document.querySelectorAll('[data-index-target]');\n\n    let linkHref;\n    let linkTarget;\n    let linkTargetPosition;\n\n    let activeChar;\n    let activeSlide;\n\n    let headerHeight = document.querySelector('.c-header').getBoundingClientRect().height;\n    let scrollSpacing;\n\n    // Check if Header is sticky\n    if (window.getComputedStyle(document.querySelector('.c-logo.is--mobile')).display === \"none\") {\n        headerHeight = document.querySelector('.c-header').getBoundingClientRect().height;\n        scrollSpacing = (techAbcIndex.getBoundingClientRect().height + headerHeight)*-1+'px';\n    } else {\n        scrollSpacing = techAbcIndex.getBoundingClientRect().height *-1+'px';\n        headerHeight = 0;\n    }\n\n    // Scroll to\n    techAbcIndexLink.forEach(function (link){\n\n        //deactivate link without target\n        linkHref = link.getAttribute('href').replace(\"#\", \"\");\n\n        if(!document.getElementById(linkHref)) {\n            link.classList.add('is--inactive');\n        }\n\n        //handle click\n        link.addEventListener('click', function(event) {\n            event.preventDefault();\n\n            linkHref = event.target.getAttribute('href').replace(\"#\", \"\");\n            linkTarget = document.getElementById(linkHref);\n            linkTargetPosition = linkTarget.getBoundingClientRect().top + window.scrollY - headerHeight - techAbcIndex.firstElementChild.getBoundingClientRect().height - 10;\n            activeSlide = event.target.getAttribute('data-index');\n\n            window.scrollTo({\n                top: linkTargetPosition,\n                behavior: 'smooth'\n            });\n\n            setTimeout(function(){\n                techAbcIndexLink.forEach(function(item) {\n                    item.classList.remove('is--active');\n                });\n                link.classList.add('is--active');\n                techAbcIndexSlider.go('=' + activeSlide);\n\n            }, 500);\n        });\n    });\n\n\n    // Intersection Observer\n    let options = {\n        root: null,\n        rootMargin: scrollSpacing+' 0px 0px 0px',\n        threshold: [0],\n    };\n\n    let callback = (entries, observer) => {\n        entries.forEach((entry) => {\n\n            // Element leaves top screen\n            if (!entry.isIntersecting && entry.target.getBoundingClientRect().top < window.innerHeight) {\n                if(entry.target.classList.contains('js--techabc-index')) {\n                    techAbcIndex.classList.add('is--fixed');\n                    techAbcIndex.firstElementChild.style.top = headerHeight+'px';\n                }\n\n                // Handle active Index via scrolling\n                if(entry.target.hasAttribute('data-index-target')) {\n                    techAbcIndexLink.forEach(function (link){\n                        link.classList.remove('is--active');\n                    });\n\n                    activeChar = document.querySelector('a.js--techabc-index-link[href=\"#'+entry.target.getAttribute('id')+'\"]');\n                    activeChar.classList.add('is--active');\n\n                    activeSlide = activeChar.getAttribute('data-index');\n                    techAbcIndexSlider.go('=' + activeSlide);\n                }\n\n            } else {\n                if(entry.target.classList.contains('js--techabc-index')) {\n                    techAbcIndex.classList.remove('is--fixed');\n                    techAbcIndex.firstElementChild.removeAttribute('style');\n                }\n            }\n\n\n            // Scrolling Reverse\n            if(!entry.isIntersecting && entry.target.getBoundingClientRect().top > window.innerHeight && entry.target.getBoundingClientRect().top < window.innerHeight+50) {\n                if(entry.target.hasAttribute('data-index-target')) {\n                    document.querySelector('a.js--techabc-index-link[href=\"#'+entry.target.getAttribute('id')+'\"]').classList.remove('is--active');\n                    activeChar = document.querySelector('a.js--techabc-index-link[href=\"#'+String.fromCharCode(entry.target.getAttribute('id').charCodeAt(0) - 1)+'\"]');\n                    activeChar.classList.add('is--active');\n                    activeSlide = activeChar.getAttribute('data-index');\n                    techAbcIndexSlider.go('=' + activeSlide);\n                }\n            }\n\n        });\n    };\n\n    let observer = new IntersectionObserver(callback, options);\n\n    observer.observe(techAbcIndex);\n\n    techAbcIndexTarget.forEach ( function (el) {\n        observer.observe(el);\n    });\n\n}\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/techabc.js?");/***/}),/***/"./source/out/sinn/src/js/modules/timeline.js":(/*!****************************************************!*\
  !*** ./source/out/sinn/src/js/modules/timeline.js ***!
  \****************************************************/ /***/function sourceOutSinnSrcJsModulesTimelineJs(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   timeline: () => (/* binding */ timeline)\n/* harmony export */ });\n/* harmony import */ var _glidejs_glide__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @glidejs/glide */ \"./node_modules/@glidejs/glide/dist/glide.esm.js\");\n/* harmony import */ var animejs_lib_anime_es_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! animejs/lib/anime.es.js */ \"./node_modules/animejs/lib/anime.es.js\");\n\n\n\nconst timeline = () => {\n\tif (document.querySelector('.js-timeline')) {\n\t\tvar timeline = new _glidejs_glide__WEBPACK_IMPORTED_MODULE_0__[\"default\"]('.js-timeline', {\n\t\t\ttype: 'slider',\n\t\t\tperView: 1,\n\t\t\tgap: 0\n\t\t})\n\n\t\ttimeline.mount();\n\n\t\tvar timelineButtons = new _glidejs_glide__WEBPACK_IMPORTED_MODULE_0__[\"default\"]('.js-timeline-buttons', {\n\t\t\ttype: 'slider',\n\t\t\tperView: 7,\n\t\t\t//bound: true,\n\t\t\trewind: false,\n\t\t\tperSwipe: '|',\n\t\t\tperTouch: '|',\n\t\t\tgap: 0,\n\t\t\tbreakpoints: {\n\t\t\t\t1024: {\n\t\t\t\t\tperView: 5\n\t\t\t\t},\n\t\t\t\t768: {\n\t\t\t\t\tperView: 4\n\t\t\t\t},\n\t\t\t\t500: {\n\t\t\t\t\tperView: 3\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\n\t\tvar timelines = document.querySelectorAll('.c-timeline');\n\n\t\ttimelines.forEach((item) => {\n\t\t\tvar parent = item;\n\t\t\tvar timelineItem = item.querySelectorAll('.js-timelineitem');\n\t\t\tvar mountSlider = timelineItem.length;\n\n\t\t\ttimelineItem.forEach((item, i) => {\n\t\t\t\tvar timelineYear = item.querySelector('.c-timeline__item-text').dataset.year;\n\t\t\t\tvar timelineImg = item.querySelector('.js-timeline-img').dataset.src;\n\n\t\t\t\tvar timelineButton =\n\t\t\t\t\t'<li class=\"glide__slide c-timeline__nav-item\">' +\n\t\t\t\t\t\t'<button class=\"c-timeline__nav-item\" data-glide-dir=\"=' + i + '\">' +\n\t\t\t\t\t\t\t'<span class=\"c-timeline__nav-text\">' + timelineYear + '</span>' +\n\t\t\t\t\t\t\t'<div class=\"c-timeline__nav-img\">' +\n\t\t\t\t\t\t\t\t'<img src=\"' + timelineImg + '\" alt=\"' + timelineYear + '\">' +\n\t\t\t\t\t\t\t'</div>' +\n\t\t\t\t\t\t'</button>' +\n\t\t\t\t\t'</li>';\n\n\t\t\t\tparent.querySelector('.js-timeline-button-container').insertAdjacentHTML('beforeend', timelineButton);\n\n\t\t\t\tif (!--mountSlider) {\n\t\t\t\t\ttimelineButtons.mount();\n\n\t\t\t\t\ttimeline.on('swipe.end', function () {\n\t\t\t\t\t\ttimelineButtons.go('=' + timeline.index);\n\t\t\t\t\t})\n\n\t\t\t\t\ttimelineButtons.on('run', function () {\n\t\t\t\t\t\ttimeline.go('=' + timelineButtons.index);\n\t\t\t\t\t})\n\t\t\t\t}\n\n\t\t\t\tdocument.addEventListener('DOMContentLoaded', function () {\n\t\t\t\t\tvar slideHeight = parent.querySelector('.glide__slide--active').getBoundingClientRect().height;\n\t\t\t\t\tvar glideTrack = parent.querySelector('.glide__track').getBoundingClientRect().height;\n\t\t\t\t\tif (slideHeight != glideTrack) {\n\t\t\t\t\t\tvar newHeight = slideHeight;\n\t\t\t\t\t\tparent.querySelector('.glide__track').style.height = newHeight + \"px\";\n\t\t\t\t\t}\n\t\t\t\t}, false);\n\n\n\t\t\t\ttimeline.on('build.after', function () {\n\t\t\t\t\tvar slideHeight = parent.querySelector('.glide__slide--active').getBoundingClientRect().height;\n\t\t\t\t\tvar glideTrack = parent.querySelector('.glide__track').getBoundingClientRect().height;\n\t\t\t\t\tif (slideHeight != glideTrack) {\n\t\t\t\t\t\tvar newHeight = slideHeight;\n\t\t\t\t\t\tparent.querySelector('.glide__track').style.height = newHeight + \"px\";\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\ttimeline.on('run.after', function () {\n\t\t\t\t\tvar slideHeight = parent.querySelector('.glide__slide--active').getBoundingClientRect().height;\n\t\t\t\t\tvar glideTrack = parent.querySelector('.glide__track').getBoundingClientRect().height;\n\t\t\t\t\tif (slideHeight != glideTrack) {\n\t\t\t\t\t\tvar newHeight = slideHeight;\n\t\t\t\t\t\tparent.querySelector('.glide__track').style.height = newHeight + \"px\";\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t});\n\n\t\t\t// Button navigation\n\t\t\tvar buttonItem = document.querySelectorAll('button.c-timeline__nav-item');\n\n\t\t\tbuttonItem.forEach(function (item){\n\t\t\t\titem.addEventListener('click', function(event) {\n\t\t\t\t\ttimelineButtons.go(item.getAttribute('data-glide-dir'));\n\t\t\t\t\ttimeline.go(item.getAttribute('data-glide-dir'));\n\t\t\t\t});\n\t\t\t});\n\t\t});\n\n\t\t// ====================================================================================\n\t\t// Sticky Buttons Start\n\t\t// ====================================================================================\n\n\t\tlet targetTimeline= document.querySelector('.c-timeline');\n\t\tlet targetTimelineNav= document.querySelector('.c-timeline__sticky');\n\t\t\ttargetTimelineNav.style.height = targetTimelineNav.firstElementChild.getBoundingClientRect().height+'px';\n\t\tlet headerHeight = 0;\n\t\tlet scrollSpacing;\n\n\t\t// Check if Header is sticky\n\t\tif (window.getComputedStyle(document.querySelector('.c-logo.is--mobile')).display === \"none\") {\n\t\t\theaderHeight = document.querySelector('.c-header').getBoundingClientRect().height;\n\t\t\tscrollSpacing = (targetTimelineNav.getBoundingClientRect().height + headerHeight)*-1+'px';\n\t\t} else {\n\t\t\tscrollSpacing = targetTimelineNav.getBoundingClientRect().height *-1+'px';\n\t\t}\n\n\t\tlet options = {\n\t\t\troot: null,\n\t\t\trootMargin: scrollSpacing+' 0px 0px 0px',\n\t\t\tthreshold: [0],\n\t\t};\n\n\t\tlet callback = (entries, observer) => {\n\t\t\tentries.forEach((entry) => {\n\n\t\t\t\t// Navi leaves top screen\n\t\t\t\tif(entry.target.classList.contains('c-timeline__sticky')) {\n\t\t\t\t\tif (!entry.isIntersecting && entry.target.getBoundingClientRect().top < window.innerHeight) {\n\t\t\t\t\t\ttargetTimelineNav.classList.add('is--fixed');\n\t\t\t\t\t\ttargetTimelineNav.firstElementChild.style.top = headerHeight+'px';\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttargetTimelineNav.classList.remove('is--fixed');\n\t\t\t\t\t\ttargetTimelineNav.firstElementChild.removeAttribute('style');\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Timeline leaves Viewport\n\t\t\t\tif(entry.target.classList.contains('c-timeline')) {\n\t\t\t\t\tif (!entry.isIntersecting ) {\n\t\t\t\t\t\ttargetTimelineNav.classList.remove('is--fixed');\n\t\t\t\t\t\ttargetTimelineNav.firstElementChild.removeAttribute('style');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t};\n\n\t\tlet observer = new IntersectionObserver(callback, options);\n\n\t\tobserver.observe(targetTimelineNav);\n\t\tobserver.observe(targetTimeline);\n\n\t\t// Sticky Buttons End\n\n\n\t\t// Browser Resize\n\t\tlet timeOut;\n\t\tfunction handleSize() {\n\t\t\tif (window.getComputedStyle(document.querySelector('.c-logo.is--mobile')).display === \"none\") {\n\t\t\t\theaderHeight = document.querySelector('.c-header').getBoundingClientRect().height;\n\t\t\t\tscrollSpacing = (targetTimelineNav.getBoundingClientRect().height + headerHeight)*-1+'px';\n\t\t\t} else {\n\t\t\t\theaderHeight = 0;\n\t\t\t\tscrollSpacing = targetTimelineNav.getBoundingClientRect().height *-1+'px';\n\t\t\t}\n\t\t\ttargetTimelineNav.firstElementChild.style.top = headerHeight+'px';\n\t\t}\n\n\t\t/*\n\t\twindow.addEventListener('resize', function() {\n\t\t\tclearTimeout(timeOut);\n\t\t\ttimeOut = setTimeout(handleSize, 500);\n\t\t});\n\t\t */\n\n\t}\n}\n\nconst techAbcExcludedPages = document.querySelector('.is-checkout, .cl-techabcfrontendcontroller');\n\nif (techAbcExcludedPages) {\n\ttimeline();\n}\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/timeline.js?");/***/}),/***/"./source/out/sinn/src/js/modules/validateModelSelect.js":(/*!***************************************************************!*\
  !*** ./source/out/sinn/src/js/modules/validateModelSelect.js ***!
  \***************************************************************/ /***/function sourceOutSinnSrcJsModulesValidateModelSelectJs(){eval("/**\n * This Software is the property of dotfly and is protected\n * by copyright law - it is NOT Freeware.\n *\n * Any unauthorized use of this software without a valid license key\n * is a violation of the license agreement and will be prosecuted by\n * civil and criminal law.\n *\n * @category   Checks whether model select is selected on wishlist button click\n * @author     dotfly <info@dotfly.de>\n * @license    http://www.dotfly.de Commercial\n * @link       http://www.dotfly.de\n */\n\ndocument.addEventListener('DOMContentLoaded', () => {\n    const wishListLink = document.querySelector('#linkToWishList');\n    const watchModelSelect = document.querySelector('#requiredForWatch');\n\n    if (!wishListLink || !watchModelSelect) return;\n\n    const wrapper = watchModelSelect.closest('.e-form__wrap');\n    const errorEl = wrapper?.querySelector('#watchmodel-error');\n\n    function isValidSelection() {\n        const value = watchModelSelect.value;\n        return value && value !== 'no_selection';\n    }\n\n    function showError() {\n        wrapper?.classList.add('is--error');\n        watchModelSelect.setAttribute('aria-invalid', 'true');\n        watchModelSelect.setAttribute('aria-describedby', 'watchmodel-error');\n        errorEl?.style && (errorEl.style.display = 'block');\n    }\n\n    function hideError() {\n        wrapper?.classList.remove('is--error');\n        watchModelSelect.removeAttribute('aria-invalid');\n        watchModelSelect.removeAttribute('aria-describedby');\n        errorEl?.style && (errorEl.style.display = 'none');\n    }\n\n    wishListLink.addEventListener('click', (e) => {\n        if (!isValidSelection()) {\n            e.preventDefault();\n            showError();\n        }\n    });\n\n    watchModelSelect.addEventListener('change', () => {\n        if (isValidSelection()) {\n            hideError();\n        }\n    });\n});\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/validateModelSelect.js?");/***/}),/***/"./source/out/sinn/src/js/modules/video.js":(/*!*************************************************!*\
  !*** ./source/out/sinn/src/js/modules/video.js ***!
  \*************************************************/ /***/function sourceOutSinnSrcJsModulesVideoJs(){eval("var videos = document.querySelectorAll('.c-video');\n\nif (videos) {\n\tvideos.forEach((video) => {\n\t\tvar iframe = video.querySelector('iframe');\n\n\t\tvideo.addEventListener('click', function () {\n\t\t\tif (video.classList.contains('is--playing')) {\n\t\t\t\tvideo.classList.remove('is--playing');\n\t\t\t\tiframe.contentWindow.postMessage('{\"event\":\"command\",\"func\":\"pauseVideo\",\"args\":\"\"}', '*');\n\t\t\t} else {\n\t\t\t\tvideo.classList.add('is--playing');\n\t\t\t\tiframe.contentWindow.postMessage('{\"event\":\"command\",\"func\":\"playVideo\",\"args\":\"\"}', '*');\n\t\t\t}\n\t\t});\n\t});\n}\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/video.js?");/***/}),/***/"./source/out/sinn/src/js/modules/wishlist.js":(/*!****************************************************!*\
  !*** ./source/out/sinn/src/js/modules/wishlist.js ***!
  \****************************************************/ /***/function sourceOutSinnSrcJsModulesWishlistJs(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   checkWishlistStatus: () => (/* binding */ checkWishlistStatus),\n/* harmony export */   setWishlistButtonOffState: () => (/* binding */ setWishlistButtonOffState),\n/* harmony export */   setWishlistButtonOnState: () => (/* binding */ setWishlistButtonOnState),\n/* harmony export */   updateWishListButtons: () => (/* binding */ updateWishListButtons)\n/* harmony export */ });\n/* harmony import */ var _configurator_configuratorUtils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./configurator/configuratorUtils */ \"./source/out/sinn/src/js/modules/configurator/configuratorUtils.js\");\n/* harmony import */ var _ArticleConfigurator_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ArticleConfigurator.js */ \"./source/out/sinn/src/js/modules/ArticleConfigurator.js\");\n\n\n\nfunction initializeWishlistLinks() {\n    const wishlistLinks = document.querySelectorAll('.is--add-to-wishlist, .is--on-wishlist');\n    wishlistLinks.forEach(link => {\n        // Prevent duplicate event listeners on dynamically added elements\n        if (!link.hasAttribute('data-initialized')) {\n            link.addEventListener('click', toggleWishlist);\n            link.setAttribute('data-initialized', 'true');\n        }\n    });\n}\n\nfunction observeDOMChanges() {\n    // Watch for dynamically added wishlist links (e.g., AJAX-loaded content)\n    const observer = new MutationObserver((mutations) => {\n        mutations.forEach((mutation) => {\n            if (mutation.addedNodes.length) {\n                initializeWishlistLinks();\n            }\n        });\n    });\n\n    observer.observe(document.body, {\n        childList: true,\n        subtree: true\n    });\n}\n\nfunction addToWishlist(event) {\n    event.preventDefault();\n\n    const clickedElement = event.target.closest('button, a');\n    if (clickedElement && clickedElement.getAttribute('aria-disabled') === 'true') {\n        return false;\n    }\n\n    const ajaxTarget = document.getElementById('ajaxTargetMB').value\n    const sessionToken = document.getElementById('sessionTokenMB').value\n    const clickedLink = event.target.closest('a');\n    const link = clickedLink.getAttribute('href');\n\n    const articleData = {};\n\n    // Use articleObject if available (product detail page), otherwise extract from data attributes or else from URL\n    if (clickedElement.getAttribute('data-config-hash') && clickedElement.getAttribute('data-article-id')) {\n        articleData.articleId = clickedElement.getAttribute('data-article-id');\n        articleData.configHash = clickedElement.getAttribute('data-config-hash');\n        articleData.useDefaults = clickedElement.getAttribute('data-use-defaults');\n    } else if (typeof articleObject !== 'undefined') {\n        articleData.articleId = articleObject.id;\n        articleData.configHash = articleObject.configHash;\n        articleData.isWatch = articleObject.isWatch;\n        articleData.isStrap = articleObject.isStrap;\n        articleData.isClosure = articleObject.isClosure;\n        articleData.isSetArticle = articleObject.isSetArticle;\n        if (articleObject.isWatch || articleObject.isSetArticle) {\n            articleData.strap = articleObject.selectedStrap ? articleObject.selectedStrap : articleObject.defaultStrap;\n            articleData.closure = articleObject.selectedClosure ? articleObject.selectedClosure : articleObject.defaultClosure;\n\n            // Convert options object to JSON string for backend processing\n            if (articleObject.options && typeof articleObject.options === 'object') {\n                articleData.options = JSON.stringify(articleObject.options);\n            } else if (articleObject.options) {\n                articleData.options = articleObject.options; // Already a string\n            }\n            if (articleObject.isSetArticle) {\n                articleData.setItems = articleObject.setItems;\n            }\n        }else if (articleObject.isStrap) {\n            articleData.requiredForWatch = articleObject.requiredForWatch;\n            articleData.lugWidth = articleObject.lugWidth;\n            articleData.closure = articleObject.selectedClosure;\n        }\n    } else {\n        // otherwise extract the article id from link\n        articleData.articleId = link.match(/aid=([^&]+)/)[1];\n    }\n\n    // add article to wishlist\n    $.ajax({\n        url: ajaxTarget + \"cl=alist&fnc=addConfiguredArticleToWishlist&stoken=\" + sessionToken,\n        method: \"POST\",\n        data: articleData,\n        success: function (ret) {\n            if (clickedLink) {\n                setWishlistButtonOnState(clickedLink);\n            }\n        }\n    });\n}\n\nfunction removeFromWishlist(event) {\n    event.preventDefault();\n\n    const clickedLink = event.target.closest('a');\n    if (!clickedLink || clickedLink.getAttribute('aria-disabled') === 'true') return false;\n\n    clickedLink.setAttribute('aria-disabled', 'true');\n\n    const ajaxTarget = document.getElementById('ajaxTargetMB').value;\n    const sessionToken = document.getElementById('sessionTokenMB').value;\n    const configHash = clickedLink.dataset.configHash;\n    const articleData = { configHash: configHash };\n\n    // remove article from wishlist\n    $.ajax({\n        url: ajaxTarget + \"cl=alist&fnc=removeFromWishlist&stoken=\" + sessionToken,\n        method: \"POST\",\n        data: articleData,\n        success: function () {\n            setWishlistButtonOffState(clickedLink);\n        }\n    });\n}\n\nfunction toggleWishlist(event) {\n    const clickedLink = event.target.closest('a');\n\n    if (clickedLink && clickedLink.classList.contains('is--on-wishlist')) {\n        removeFromWishlist(event);\n    } else {\n        addToWishlist(event);\n    }\n}\n\nconst redirectToArticleConfiguration = function (clickedElement) {\n    const redirectUrl = clickedElement.getAttribute('data-href');\n    if (redirectUrl) {\n        const separator = redirectUrl.includes('?') ? '&' : '?';\n        let urlWithParam = redirectUrl + separator + 'openConfigurator=1';\n\n        const configHash = clickedElement.getAttribute('data-config-hash');\n        if (configHash) {\n            // Add context=wishlist to distinguish from other configurator opens\n            urlWithParam += '&configHash=' + configHash + '&context=wishlist';\n        }\n\n        window.location.href = urlWithParam;\n    } else {\n        console.error('No data-href attribute found on clicked element');\n    }\n}\n\n\n/**\n * Sets closure dropdown value and handles complex UI state management.\n * Must run after slider navigation completes and dropdown is rebuilt.\n */\nconst setClosureDropdownValue = function(closureId) {\n    const dropdown = document.querySelector('.c-configurator__description-options .js--conf-dropdown');\n    if (!dropdown) return;\n\n    const closureRadio = dropdown.querySelector(`input[type=\"radio\"][value=\"${closureId}\"]`);\n\n    if (closureRadio) {\n        const label = closureRadio.closest('label');\n        const listItem = closureRadio.closest('.c-configurator__dropdown--item');\n\n        if (label && listItem) {\n            // Ensure this runs after all other DOM handlers to prevent conflicts\n            requestAnimationFrame(() => {\n                dropdown.querySelectorAll('.c-configurator__dropdown--item').forEach(item => {\n                    item.classList.remove('js--active');\n                    const itemLabel = item.querySelector('label[role=\"menuitemradio\"]');\n                    if (itemLabel) {\n                        itemLabel.setAttribute('aria-checked', 'false');\n                    }\n                });\n\n                listItem.classList.add('js--active');\n                label.setAttribute('aria-checked', 'true');\n                closureRadio.checked = true;\n\n                const valueDisplay = dropdown.querySelector('.js--value');\n                if (valueDisplay) {\n                    valueDisplay.textContent = label.textContent.trim();\n                }\n\n                closureRadio.dispatchEvent(new Event('change', { bubbles: true }));\n            });\n        }\n    } else {\n        // Fallback for watches with only one closure option\n        const singleClosure = document.querySelector(`.js--single-option-text input[type=\"radio\"][value=\"${closureId}\"]`);\n        if (singleClosure) {\n            singleClosure.checked = true;\n            singleClosure.dispatchEvent(new Event('change', { bubbles: true }));\n        }\n    }\n};\n\n\nconst checkAndOpenConfigurator = function() {\n    const urlParams = new URLSearchParams(window.location.search);\n    if (urlParams.get('openConfigurator') === '1') {\n        const configHash = urlParams.get('configHash');\n        const context = urlParams.get('context');\n\n        if (typeof articleObject !== 'undefined') {\n            // For watches: open configurator and apply configuration\n            if (articleObject.isWatch) {\n                setTimeout(() => {\n                    const configuratorTrigger = document.querySelector('[data-content-trigger][data-target=\"#configurator\"]');\n                    if (configuratorTrigger) {\n                        configuratorTrigger.click();\n\n                        // Wait for configurator to load before applying configuration\n                        document.addEventListener('configuratorLoaded', async function() {\n                            await applyWatchConfiguration();\n                        }, { once: true });\n\n                    } else {\n                        console.warn('Configurator trigger not found on the page');\n                    }\n                }, 500);\n            // For straps: directly apply configuration without opening configurator\n            } else if (articleObject.isStrap) {\n                applyStrapConfiguration();\n                return;\n            }else{\n                applyWishlistConfiguration()\n            }\n        }\n    }\n}\n\n/**\n * Applies saved wishlist configuration to the configurator.\n * articleObject is populated by backend with wishlist data via $wishlistConfig.\n */\nconst applyWatchConfiguration = async function() {\n    // Import articleConfigurator to get the properly initialized articleObject\n    const { default: articleConfigurator } = await Promise.resolve(/*! import() */).then(__webpack_require__.bind(__webpack_require__, /*! ./ArticleConfigurator.js */ \"./source/out/sinn/src/js/modules/ArticleConfigurator.js\"));\n    const articleObject = articleConfigurator.getInstance();\n\n    if (!articleObject) {\n        return;\n    }\n\n    // The data is already in articleObject from initialization via window.articleInitData\n    // Extract configuration data, checking for non-empty objects\n    const originalStrap = articleObject.selectedStrap && Object.keys(articleObject.selectedStrap).length > 0 ? articleObject.selectedStrap : null;\n    const originalClosure = articleObject.selectedClosure && Object.keys(articleObject.selectedClosure).length > 0 ? articleObject.selectedClosure : null;\n    const originalOptions = articleObject.options && typeof articleObject.options === 'object' && Object.keys(articleObject.options).length > 0 ? articleObject.options : null;\n\n    // Navigate to saved strap\n    if (originalStrap && originalStrap.id && window.configuratorSlider) {\n        const allSliderItems = document.querySelectorAll('.c-configurator__straps-item');\n        const strapElement = document.querySelector(`[data-id=\"${originalStrap.id}\"]`);\n\n        if (strapElement) {\n            let strapIndex = [].indexOf.call(allSliderItems, strapElement);\n            if (strapIndex !== -1) {\n                // Set up closure selection to run after slider completes\n                if (originalClosure && originalClosure.id) {\n                    let closureApplied = false;\n                    const targetStrapId = originalStrap.id;\n                    const onSliderAfter = function() {\n                        // Only apply closure when we're on the correct strap and haven't applied it yet\n                        const activeSlide = document.querySelector('.c-configurator__strap-list .glide__slide--active');\n                        if (!closureApplied && activeSlide && activeSlide.dataset.id === targetStrapId) {\n                            closureApplied = true;\n                            setTimeout(() => {\n                                setClosureDropdownValue(originalClosure.id);\n                            }, 300);\n                        }\n                    };\n\n                    window.configuratorSlider.on('run.after', onSliderAfter);\n                }\n\n                setTimeout(() => {\n                    window.configuratorSlider.go('=' + strapIndex);\n                }, 500);\n            }\n        }\n    }\n\n    // Navigate to options step and restore selections\n    setTimeout(() => {\n        let forwardButton = document.querySelector('.c-configurator__switch-item.is--options');\n        forwardButton.click();\n\n        if (originalOptions && typeof originalOptions === 'object') {\n            // Wait for the second step transition to complete (650ms according to configurator.js)\n            setTimeout(() => {\n                // originalOptions: {\"OptSaphKriGlaBoden\": 1, ...}\n                // Keys are the actual option names used by configurator checkboxes\n                Object.keys(originalOptions).forEach(optionName => {\n                    const checkbox = document.querySelector(`.configurator-options[name=\"${optionName}\"]`);\n                    if (checkbox) {\n                        checkbox.checked = true;\n                    } else {\n                        console.warn(`Checkbox for option ${optionName} not found`);\n                    }\n                });\n            }, 700);\n\n            // Trigger price recalculation after options are set\n            setTimeout(async () => {\n                try {\n                    const module = await Promise.resolve(/*! import() */).then(__webpack_require__.bind(__webpack_require__, /*! ./configurator/configuratorUtils.js */ \"./source/out/sinn/src/js/modules/configurator/configuratorUtils.js\"));\n                    if (module.fetchVariantData) {\n                        const watchBasePrice = document.querySelector('#productConfigurator').getAttribute('data-base-price');\n                        await module.fetchVariantData(watchBasePrice);\n                    }\n                } catch (error) {\n                    // Fallback: trigger change event to recalculate price\n                    const checkedOption = document.querySelector('.configurator-options:checked');\n                    if (checkedOption) {\n                        checkedOption.dispatchEvent(new Event('change', { bubbles: true }));\n                    }\n                }\n            }, 200);\n        }\n    }, 1200);\n};\n\n/**\n * Applies saved wishlist configuration for strap products.\n * Sets the watch and closure selection in form fields and updates wishlist button state.\n * Does NOT open any configurator overlay.\n */\nconst applyStrapConfiguration = async function() {\n    if (typeof articleObject === 'undefined' || !articleObject.isStrap) {\n        return;\n    }\n\n    // Extract configuration data from articleObject\n    const requiredForWatch = articleObject.requiredForWatch || null;\n    const selectedClosure = articleObject.selectedClosure && Object.keys(articleObject.selectedClosure).length > 0 ? articleObject.selectedClosure : null;\n\n    // Set watch selection dropdown if present\n    if (requiredForWatch && requiredForWatch.id) {\n        const watchSelect = document.getElementById('requiredForWatch');\n        if (watchSelect) {\n            watchSelect.value = requiredForWatch.id;\n            // Trigger change event to update any dependent UI\n            watchSelect.dispatchEvent(new Event('change', { bubbles: true }));\n\n            // Update articleObject with selected watch\n            articleObject.requiredForWatch = requiredForWatch.id;\n            articleObject.requiredForWatchProAlphaTitle = requiredForWatch.proalphatitle;\n        }\n    }\n\n    // Wait for UI to update after watch selection\n    await new Promise(resolve => setTimeout(resolve, 500));\n\n    // Set closure selection in hidden input\n    if (selectedClosure && selectedClosure.id) {\n        const closureHiddenInput = document.getElementById('claspForStrap');\n        if (closureHiddenInput) {\n            closureHiddenInput.value = selectedClosure.id;\n            closureHiddenInput.dispatchEvent(new Event('input', { bubbles: true }));\n\n            // IMPORTANT: Also trigger the closure selection in the strap configurator overlay if it's open\n            // Wait for strapConfigurator to be loaded\n            setTimeout(() => {\n                const claspSelection = document.getElementById('claspSelection');\n                if (claspSelection) {\n                    // Set the dropdown to match the hidden input\n                    claspSelection.value = selectedClosure.id;\n                    // Trigger change event to update everything including configHash\n                    claspSelection.dispatchEvent(new Event('change', { bubbles: true }));\n                }\n            }, 1000);\n        }\n\n        // Update articleObject with selected closure\n        articleObject.selectedClosure = selectedClosure;\n    }\n\n    // Ensure configHash is preserved from wishlist\n    // The configHash should already be set from the template, but let's make sure\n    if (articleObject.configHash) {\n        // Update ALL wishlist buttons with correct config hash\n        const wishlistButtons = document.querySelectorAll('[data-component=\"wishlist-control\"]');\n        wishlistButtons.forEach(button => {\n            button.setAttribute('data-config-hash', articleObject.configHash);\n        });\n    }\n\n    // Update wishlist buttons to show correct state\n    setTimeout(async () => {\n        await updateWishListButtons();\n    }, 500);\n};\n\nconst applyWishlistConfiguration = () => {\n    if (typeof articleObject === 'undefined' || articleObject.isStrap || articleObject.isWatch) {\n        return;\n    }\n}\n\ndocument.addEventListener('DOMContentLoaded', function () {\n    initializeWishlistLinks();\n    observeDOMChanges();\n\n    // Wait for articleObject to be ready before checking configurator\n    if (typeof window.articleObject !== 'undefined') {\n        // articleObject already available\n        checkAndOpenConfigurator();\n    } else {\n        // Wait for articleObject to be initialized\n        document.addEventListener('articleObjectReady', function() {\n            checkAndOpenConfigurator();\n        }, { once: true });\n    }\n});\n\nconst backToConfigurationButtonList = document.querySelectorAll('.js--back-to-configuration')\nbackToConfigurationButtonList.forEach(button => {\n    button.addEventListener('click', function (e) {\n        e.preventDefault();\n        redirectToArticleConfiguration(button);\n    });\n});\n\nconst addWishlistItemToBasketButtons = document.querySelectorAll('.js--add-wishlist-item-to-basket')\nif (addWishlistItemToBasketButtons) {\n    addWishlistItemToBasketButtons.forEach(button => {\n        button.addEventListener('click', function (e) {\n            e.preventDefault();\n\n            const form = e.target.closest('form');\n            const getFormValue = (name) => form.querySelector(`input[name=\"${name}\"]`)?.value || '';\n\n            // Early return for simple form submission\n            if (!getFormValue('watchId')) {\n                form.submit();\n                return;\n            }\n\n            // Build configured article data\n            const data = {\n                watchId: getFormValue('watchId'),\n                selectedStrap: getFormValue('selectedStrapId'),\n                selectedClosing: getFormValue('selectedClosureId'),\n                isInWishList: 1\n            };\n\n            // Handle chosen options if present\n            const chosenOptions = Array.from(form.querySelectorAll('input[name=\"chosenOptions\"]:checked'))\n                .reduce((acc, option) => {\n                    acc[option.name] = 1;\n                    return acc;\n                }, {});\n\n            if (Object.keys(chosenOptions).length > 0) {\n                data.chosenOptions = JSON.stringify(chosenOptions);\n            }\n\n            (0,_configurator_configuratorUtils__WEBPACK_IMPORTED_MODULE_0__.addConfiguratedArticleToBasket)(data);\n        });\n    });\n}\n\n\n/**\n * Sets wishlist button to 'on wishlist' state\n * @param {HTMLElement} clickedLink - The button/link element to update\n */\nfunction setWishlistButtonOnState(clickedLink) {\n    clickedLink.classList.remove('is--add-to-wishlist');\n    clickedLink.classList.add('is--on-wishlist');\n\n    const newText = oWave.i18n.DOT_WISHLIST_IS_ON_WISHLIST;\n    const existingSpan = clickedLink.querySelector('span');\n\n    if (existingSpan) {\n        existingSpan.innerText = newText;\n    } else {\n        clickedLink.innerText = newText;\n    }\n}\n\n/**\n * Sets wishlist button to 'not on wishlist' state\n * @param {HTMLElement} clickedLink - The button/link element to update\n */\nfunction setWishlistButtonOffState(clickedLink) {\n    clickedLink.classList.remove('is--on-wishlist');\n    clickedLink.classList.add('is--add-to-wishlist');\n    clickedLink.removeAttribute('aria-disabled');\n\n    const newText = oWave.i18n.DOT_WISHLIST_NOT_ON_WISHLIST;\n    const existingSpan = clickedLink.querySelector('span');\n\n    if (existingSpan) {\n        existingSpan.innerText = newText;\n    } else {\n        clickedLink.innerText = newText;\n    }\n}\n\n/**\n * Updates wishlist button states based on configHash\n * @returns {Promise<void>}\n */\nasync function updateWishListButtons() {\n    const wishlistButtons = document.querySelectorAll('[data-component=\"wishlist-control\"]');\n\n    try {\n        const configHash = _ArticleConfigurator_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getInstance().configHash;\n        const isInWishlist = await checkWishlistStatus(configHash);\n\n        wishlistButtons.forEach(button => {\n            if (isInWishlist) {\n                setWishlistButtonOnState(button);\n            } else {\n                setWishlistButtonOffState(button);\n            }\n        });\n    } catch (error) {\n        console.warn('Error in updateWishListButtons:', error);\n        wishlistButtons.forEach(button => {\n            setWishlistButtonOffState(button);\n        });\n    }\n}\n\n/**\n * Check if article is in wishlist via AJAX\n * @param {string} configHash - The config hash to check\n * @returns {Promise<boolean>} - Promise resolving to wishlist status\n */\nasync function checkWishlistStatus(configHash) {\n    if (!configHash) return false;\n\n    const ajaxTarget = document.getElementById('ajaxTargetMB')?.value;\n    const sessionToken = document.getElementById('sessionTokenMB')?.value;\n\n    if (!ajaxTarget || !sessionToken) {\n        console.warn('Missing AJAX target or session token');\n        return false;\n    }\n\n    try {\n        const response = await $.ajax({\n            url: ajaxTarget + \"cl=alist&fnc=checkWishlistStatus&stoken=\" + sessionToken,\n            method: \"POST\",\n            data: { configHash }\n        });\n\n        return response.isInWishlist || false;\n    } catch (error) {\n        console.error('Error checking wishlist status:', error);\n        return false;\n    }\n}\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/wishlist.js?");/***/}),/***/"./source/out/sinn/src/js/modules/wrists.js":(/*!**************************************************!*\
  !*** ./source/out/sinn/src/js/modules/wrists.js ***!
  \**************************************************/ /***/function sourceOutSinnSrcJsModulesWristsJs(){eval("var input = document.querySelector('input[name=\"wrists\"]');\nvar wrists = document.querySelectorAll('.c-basket__wrist .e-form__input');\nvar trigger = document.querySelector('#orderConfirmAgbBottom');\nvar basketForm = document.getElementById('basket_form');\nvar basketUpdate = document.getElementById('basketUpdate');\nvar wristData = {};\nvar result = [];\n\nif (input) {\n\ttrigger.addEventListener('submit', function (event) {\n\t\tevent.preventDefault();\n\n\t\tresult = [];\n\n\t\twrists.forEach((item) => {\n\t\t\twristData[item.dataset.id] = item.value;\n\t\t});\n\n\t\tinput.value = JSON.stringify(wristData);\n\n\t\ttrigger.submit();\n\t});\n\n\n\t// Prevent Form Submit on Enter -> Trigger Safe Button instead\n\n\tbasketForm.addEventListener ('keydown', function (event) {\n\t\tif (event.key == 'Enter') {\n\t\t\tevent.preventDefault();\n\t\t\tbasketUpdate.click();\n\t\t}\n\t});\n\n}\n\n\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/wrists.js?");/***/}),/***/"./source/out/sinn/src/js/modules/youtubeConsent.js":(/*!**********************************************************!*\
  !*** ./source/out/sinn/src/js/modules/youtubeConsent.js ***!
  \**********************************************************/ /***/function sourceOutSinnSrcJsModulesYoutubeConsentJs(){eval("// -----------------------------------------------------------------------------\n// youtubeConsent.js\n// GDPR solution for YouTube videos\n// -----------------------------------------------------------------------------\n\n// Using the script from dotfly tracking module directly, because we don't need the consent tool\n(function () {\n    let ytIFrames = \tdocument.querySelectorAll('.js-iframe');\n    let ytPlaceholder = document.querySelectorAll('.js-youtube-confirmation');\n\n    function resetFrames() {\n        ytIFrames.forEach( elem => {\n            elem.classList.remove('is--hidden');\n            elem.src = elem.dataset.src;\n        })\n\n        ytPlaceholder.forEach( elem => {\n            !elem.classList.contains('is--hidden');\n            elem.classList.add('is--hidden');\n        })\n    }\n\n    function showVideoElem(videoContainer,  confirmationPanel) {\n        videoContainer.classList.remove('is--hidden');\n\n        //console.log(videoContainer);\n        if (videoContainer.dataset.src && videoContainer.src !== videoContainer.dataset.src) {\n            videoContainer.src = videoContainer.dataset.src;\n        }\n\n        confirmationPanel &&\n        confirmationPanel.classList.contains('js-youtube-confirmation') &&\n        confirmationPanel.classList.add('is--hidden');\n    }\n\n    function registerClickEvents() {\n        document.querySelector('body').addEventListener('click', function (evt) {\n            if (\n                evt.target.classList.contains('js-confirm-once') ||\n                evt.target.classList.contains('js-confirm-always')\n            ) {\n                let videoContainer = document.getElementById(evt.target.dataset.iframeid);\n                if (!videoContainer) {\n                    throw new Error('No video-container available!');\n                }\n                showVideoElem(videoContainer, evt.target.parentNode.parentNode.parentNode.parentElement);\n            }\n        });\n    }\n\n    function showVideos() {\n        ytIFrames.forEach(elem => {\n            let confirmationPanel = elem.nextElementSibling;\n            showVideoElem(elem, confirmationPanel);\n        });\n    }\n\n    (function init() {\n        registerClickEvents();\n    })();\n})();\n\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/modules/youtubeConsent.js?");/***/}),/***/"./source/out/sinn/src/js/tables.js":(/*!******************************************!*\
  !*** ./source/out/sinn/src/js/tables.js ***!
  \******************************************/ /***/function sourceOutSinnSrcJsTablesJs(){eval("// Responsive Tables\n\nif (document.querySelector('.c-text table')) {\n    let wrapper;\n\n    document.querySelectorAll('.c-text table').forEach(function (table){\n        wrapper = document.createElement('div');\n        wrapper.classList.add('c-text__table-responsive');\n\n        // insert wrapper before el in the DOM tree\n        table.parentNode.insertBefore(wrapper, table);\n\n        // move el into wrapper\n        wrapper.appendChild(table);\n    });\n\n}\n\n//# sourceURL=webpack://sinn/./source/out/sinn/src/js/tables.js?");/***/})/******/};/************************************************************************/ /******/ // The module cache
/******/var __webpack_module_cache__={};/******/ /******/ // The require function
/******/function __webpack_require__(moduleId){/******/ // Check if module is in cache
/******/var cachedModule=__webpack_module_cache__[moduleId];/******/if(cachedModule!==undefined){/******/return cachedModule.exports;/******/}/******/ // Create a new module (and put it into the cache)
/******/var module=__webpack_module_cache__[moduleId]={/******/ // no module.id needed
/******/ // no module.loaded needed
/******/exports:{}/******/};/******/ /******/ // Execute the module function
/******/__webpack_modules__[moduleId].call(module.exports,module,module.exports,__webpack_require__);/******/ /******/ // Return the exports of the module
/******/return module.exports;/******/}/******/ /************************************************************************/ /******/ /* webpack/runtime/compat get default export */ /******/(function(){/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/__webpack_require__.n=function(module){/******/var getter=module&&module.__esModule?/******/function(){return module['default'];}:/******/function(){return module;};/******/__webpack_require__.d(getter,{a:getter});/******/return getter;/******/};/******/})();/******/ /******/ /* webpack/runtime/define property getters */ /******/(function(){/******/ // define getter functions for harmony exports
/******/__webpack_require__.d=function(exports,definition){/******/for(var key in definition){/******/if(__webpack_require__.o(definition,key)&&!__webpack_require__.o(exports,key)){/******/Object.defineProperty(exports,key,{enumerable:true,get:definition[key]});/******/}/******/}/******/};/******/})();/******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/(function(){/******/__webpack_require__.o=function(obj,prop){return Object.prototype.hasOwnProperty.call(obj,prop);};/******/})();/******/ /******/ /* webpack/runtime/make namespace object */ /******/(function(){/******/ // define __esModule on exports
/******/__webpack_require__.r=function(exports){/******/if(typeof Symbol!=='undefined'&&Symbol.toStringTag){/******/Object.defineProperty(exports,Symbol.toStringTag,{value:'Module'});/******/}/******/Object.defineProperty(exports,'__esModule',{value:true});/******/};/******/})();/******/ /************************************************************************/ /******/ /******/ // startup
/******/ // Load entry module and return exports
/******/ // This entry module can't be inlined because the eval devtool is used.
/******/__webpack_require__("./source/out/sinn/src/js/app.js");/******/__webpack_require__("./source/out/sinn/src/js/tables.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/ArticleConfigurator.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/SetArticleVariants.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/accordion.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/adressform.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/alert.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/amountCounter.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/animateOffcanvas.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/animation.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/articleConfiguratorInit.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/breadcrumb.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/cart.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/catalog.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/checkSelectedPayment.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/checkoutAddressSelection.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/contactform.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/contentslider.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/countryListNotice.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/datenschutzCBVisibilityControl.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/dropdown.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/etracker.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/focusTrap.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/formError.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/formValidation.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/input.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/languageModal.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/lazyload.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/login.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/miniBasketRenderer.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/minicartflapper.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/modal.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/navigationDesktop.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/navigationDesktopImages.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/navigationMobile.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/navigationTracking.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/optionsCounter.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/optionsScroller.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/optionsdialog.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/order.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/pagination.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/passwordcontrol.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/productDetailScrolling.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/productslider.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/register.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/registerOffcanvas.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/removeFromWishlist.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/retailer.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/screenReaderUtils.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/search.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/stageslider.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/stickyHeader.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/tabcontent.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/tabs.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/techabc.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/timeline.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/validateModelSelect.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/video.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/wishlist.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/wrists.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/youtubeConsent.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/configurator/configurator.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/configurator/configuratorDropdown.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/configurator/configuratorUtils.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/overlay/overlayContentLoader.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/productFilter/StrapFinder.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/productFilter/activeFilterAttributesCounter.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/productFilter/filterAjax.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/retailerMap/GoogleMap.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/retailerMap/GoogleMapsApi.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/retailerMap/config.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/strapPurchase/forcedOverlays.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/strapPurchase/productCounter.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/strapPurchase/productFilter.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/strapPurchase/strapConfigurator.js");/******/__webpack_require__("./source/out/sinn/src/js/modules/strapPurchase/toggleConfiguratorImages.js");/******/var __webpack_exports__=__webpack_require__("./source/out/sinn/src/js/modules/strapPurchase/toggleStrapview.js");/******/ /******/})();