diff --git a/assets/theme.js b/assets/theme.js new file mode 100644 index 0000000..1eb5245 --- /dev/null +++ b/assets/theme.js @@ -0,0 +1,6914 @@ +var __defProp = Object.defineProperty; +var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __publicField = (obj, key, value) => { + __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); + return value; +}; + +// node_modules/ftdomdelegate/main.js +function Delegate(root) { + this.listenerMap = [{}, {}]; + if (root) { + this.root(root); + } + this.handle = Delegate.prototype.handle.bind(this); + this._removedListeners = []; +} +Delegate.prototype.root = function(root) { + const listenerMap = this.listenerMap; + let eventType; + if (this.rootElement) { + for (eventType in listenerMap[1]) { + if (listenerMap[1].hasOwnProperty(eventType)) { + this.rootElement.removeEventListener(eventType, this.handle, true); + } + } + for (eventType in listenerMap[0]) { + if (listenerMap[0].hasOwnProperty(eventType)) { + this.rootElement.removeEventListener(eventType, this.handle, false); + } + } + } + if (!root || !root.addEventListener) { + if (this.rootElement) { + delete this.rootElement; + } + return this; + } + this.rootElement = root; + for (eventType in listenerMap[1]) { + if (listenerMap[1].hasOwnProperty(eventType)) { + this.rootElement.addEventListener(eventType, this.handle, true); + } + } + for (eventType in listenerMap[0]) { + if (listenerMap[0].hasOwnProperty(eventType)) { + this.rootElement.addEventListener(eventType, this.handle, false); + } + } + return this; +}; +Delegate.prototype.captureForType = function(eventType) { + return ["blur", "error", "focus", "load", "resize", "scroll"].indexOf(eventType) !== -1; +}; +Delegate.prototype.on = function(eventType, selector, handler, useCapture) { + let root; + let listenerMap; + let matcher; + let matcherParam; + if (!eventType) { + throw new TypeError("Invalid event type: " + eventType); + } + if (typeof selector === "function") { + useCapture = handler; + handler = selector; + selector = null; + } + if (useCapture === void 0) { + useCapture = this.captureForType(eventType); + } + if (typeof handler !== "function") { + throw new TypeError("Handler must be a type of Function"); + } + root = this.rootElement; + listenerMap = this.listenerMap[useCapture ? 1 : 0]; + if (!listenerMap[eventType]) { + if (root) { + root.addEventListener(eventType, this.handle, useCapture); + } + listenerMap[eventType] = []; + } + if (!selector) { + matcherParam = null; + matcher = matchesRoot.bind(this); + } else if (/^[a-z]+$/i.test(selector)) { + matcherParam = selector; + matcher = matchesTag; + } else if (/^#[a-z0-9\-_]+$/i.test(selector)) { + matcherParam = selector.slice(1); + matcher = matchesId; + } else { + matcherParam = selector; + matcher = Element.prototype.matches; + } + listenerMap[eventType].push({ + selector, + handler, + matcher, + matcherParam + }); + return this; +}; +Delegate.prototype.off = function(eventType, selector, handler, useCapture) { + let i; + let listener; + let listenerMap; + let listenerList; + let singleEventType; + if (typeof selector === "function") { + useCapture = handler; + handler = selector; + selector = null; + } + if (useCapture === void 0) { + this.off(eventType, selector, handler, true); + this.off(eventType, selector, handler, false); + return this; + } + listenerMap = this.listenerMap[useCapture ? 1 : 0]; + if (!eventType) { + for (singleEventType in listenerMap) { + if (listenerMap.hasOwnProperty(singleEventType)) { + this.off(singleEventType, selector, handler); + } + } + return this; + } + listenerList = listenerMap[eventType]; + if (!listenerList || !listenerList.length) { + return this; + } + for (i = listenerList.length - 1; i >= 0; i--) { + listener = listenerList[i]; + if ((!selector || selector === listener.selector) && (!handler || handler === listener.handler)) { + this._removedListeners.push(listener); + listenerList.splice(i, 1); + } + } + if (!listenerList.length) { + delete listenerMap[eventType]; + if (this.rootElement) { + this.rootElement.removeEventListener(eventType, this.handle, useCapture); + } + } + return this; +}; +Delegate.prototype.handle = function(event) { + let i; + let l; + const type = event.type; + let root; + let phase; + let listener; + let returned; + let listenerList = []; + let target; + const eventIgnore = "ftLabsDelegateIgnore"; + if (event[eventIgnore] === true) { + return; + } + target = event.target; + if (target.nodeType === 3) { + target = target.parentNode; + } + if (target.correspondingUseElement) { + target = target.correspondingUseElement; + } + root = this.rootElement; + phase = event.eventPhase || (event.target !== event.currentTarget ? 3 : 2); + switch (phase) { + case 1: + listenerList = this.listenerMap[1][type]; + break; + case 2: + if (this.listenerMap[0] && this.listenerMap[0][type]) { + listenerList = listenerList.concat(this.listenerMap[0][type]); + } + if (this.listenerMap[1] && this.listenerMap[1][type]) { + listenerList = listenerList.concat(this.listenerMap[1][type]); + } + break; + case 3: + listenerList = this.listenerMap[0][type]; + break; + } + let toFire = []; + l = listenerList.length; + while (target && l) { + for (i = 0; i < l; i++) { + listener = listenerList[i]; + if (!listener) { + break; + } + if (target.tagName && ["button", "input", "select", "textarea"].indexOf(target.tagName.toLowerCase()) > -1 && target.hasAttribute("disabled")) { + toFire = []; + } else if (listener.matcher.call(target, listener.matcherParam, target)) { + toFire.push([event, target, listener]); + } + } + if (target === root) { + break; + } + l = listenerList.length; + target = target.parentElement || target.parentNode; + if (target instanceof HTMLDocument) { + break; + } + } + let ret; + for (i = 0; i < toFire.length; i++) { + if (this._removedListeners.indexOf(toFire[i][2]) > -1) { + continue; + } + returned = this.fire.apply(this, toFire[i]); + if (returned === false) { + toFire[i][0][eventIgnore] = true; + toFire[i][0].preventDefault(); + ret = false; + break; + } + } + return ret; +}; +Delegate.prototype.fire = function(event, target, listener) { + return listener.handler.call(target, event, target); +}; +function matchesTag(tagName, element) { + return tagName.toLowerCase() === element.tagName.toLowerCase(); +} +function matchesRoot(selector, element) { + if (this.rootElement === window) { + return ( + // Match the outer document (dispatched from document) + element === document || // The element (dispatched from document.body or document.documentElement) + element === document.documentElement || // Or the window itself (dispatched from window) + element === window + ); + } + return this.rootElement === element; +} +function matchesId(id, element) { + return id === element.id; +} +Delegate.prototype.destroy = function() { + this.off(); + this.root(); +}; +var main_default = Delegate; + +// js/components/input-binding-manager.js +var InputBindingManager = class { + constructor() { + this.delegateElement = new main_default(document.body); + this.delegateElement.on("change", "[data-bind-value]", this._onValueChanged.bind(this)); + } + _onValueChanged(event, target) { + const boundElement = document.getElementById(target.getAttribute("data-bind-value")); + if (boundElement) { + if (target.tagName === "SELECT") { + target = target.options[target.selectedIndex]; + } + boundElement.innerHTML = target.hasAttribute("title") ? target.getAttribute("title") : target.value; + } + } +}; + +// js/helper/event.js +function triggerEvent(element, name, data = {}) { + element.dispatchEvent(new CustomEvent(name, { + bubbles: true, + detail: data + })); +} +function triggerNonBubblingEvent(element, name, data = {}) { + element.dispatchEvent(new CustomEvent(name, { + bubbles: false, + detail: data + })); +} + +// js/custom-element/custom-html-element.js +var CustomHTMLElement = class extends HTMLElement { + constructor() { + super(); + this._hasSectionReloaded = false; + if (Shopify.designMode) { + this.rootDelegate.on("shopify:section:select", (event) => { + const parentSection = this.closest(".shopify-section"); + if (event.target === parentSection && event.detail.load) { + this._hasSectionReloaded = true; + } + }); + } + } + get rootDelegate() { + return this._rootDelegate = this._rootDelegate || new main_default(document.documentElement); + } + get delegate() { + return this._delegate = this._delegate || new main_default(this); + } + showLoadingBar() { + triggerEvent(document.documentElement, "theme:loading:start"); + } + hideLoadingBar() { + triggerEvent(document.documentElement, "theme:loading:end"); + } + untilVisible(intersectionObserverOptions = { rootMargin: "30px 0px", threshold: 0 }) { + const onBecameVisible = () => { + this.classList.add("became-visible"); + this.style.opacity = "1"; + }; + return new Promise((resolve) => { + if (window.IntersectionObserver) { + this.intersectionObserver = new IntersectionObserver((event) => { + if (event[0].isIntersecting) { + this.intersectionObserver.disconnect(); + requestAnimationFrame(() => { + resolve(); + onBecameVisible(); + }); + } + }, intersectionObserverOptions); + this.intersectionObserver.observe(this); + } else { + resolve(); + onBecameVisible(); + } + }); + } + disconnectedCallback() { + this.delegate.destroy(); + this.rootDelegate.destroy(); + this.intersectionObserver?.disconnect(); + delete this._delegate; + delete this._rootDelegate; + } +}; + +// node_modules/tabbable/dist/index.esm.js +var candidateSelectors = ["input:not([inert])", "select:not([inert])", "textarea:not([inert])", "a[href]:not([inert])", "button:not([inert])", "[tabindex]:not(slot):not([inert])", "audio[controls]:not([inert])", "video[controls]:not([inert])", '[contenteditable]:not([contenteditable="false"]):not([inert])', "details>summary:first-of-type:not([inert])", "details:not([inert])"]; +var candidateSelector = /* @__PURE__ */ candidateSelectors.join(","); +var NoElement = typeof Element === "undefined"; +var matches = NoElement ? function() { +} : Element.prototype.matches || Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector; +var getRootNode = !NoElement && Element.prototype.getRootNode ? function(element) { + var _element$getRootNode; + return element === null || element === void 0 ? void 0 : (_element$getRootNode = element.getRootNode) === null || _element$getRootNode === void 0 ? void 0 : _element$getRootNode.call(element); +} : function(element) { + return element === null || element === void 0 ? void 0 : element.ownerDocument; +}; +var isInert = function isInert2(node, lookUp) { + var _node$getAttribute; + if (lookUp === void 0) { + lookUp = true; + } + var inertAtt = node === null || node === void 0 ? void 0 : (_node$getAttribute = node.getAttribute) === null || _node$getAttribute === void 0 ? void 0 : _node$getAttribute.call(node, "inert"); + var inert = inertAtt === "" || inertAtt === "true"; + var result = inert || lookUp && node && isInert2(node.parentNode); + return result; +}; +var isContentEditable = function isContentEditable2(node) { + var _node$getAttribute2; + var attValue = node === null || node === void 0 ? void 0 : (_node$getAttribute2 = node.getAttribute) === null || _node$getAttribute2 === void 0 ? void 0 : _node$getAttribute2.call(node, "contenteditable"); + return attValue === "" || attValue === "true"; +}; +var getCandidates = function getCandidates2(el, includeContainer, filter) { + if (isInert(el)) { + return []; + } + var candidates = Array.prototype.slice.apply(el.querySelectorAll(candidateSelector)); + if (includeContainer && matches.call(el, candidateSelector)) { + candidates.unshift(el); + } + candidates = candidates.filter(filter); + return candidates; +}; +var getCandidatesIteratively = function getCandidatesIteratively2(elements, includeContainer, options) { + var candidates = []; + var elementsToCheck = Array.from(elements); + while (elementsToCheck.length) { + var element = elementsToCheck.shift(); + if (isInert(element, false)) { + continue; + } + if (element.tagName === "SLOT") { + var assigned = element.assignedElements(); + var content = assigned.length ? assigned : element.children; + var nestedCandidates = getCandidatesIteratively2(content, true, options); + if (options.flatten) { + candidates.push.apply(candidates, nestedCandidates); + } else { + candidates.push({ + scopeParent: element, + candidates: nestedCandidates + }); + } + } else { + var validCandidate = matches.call(element, candidateSelector); + if (validCandidate && options.filter(element) && (includeContainer || !elements.includes(element))) { + candidates.push(element); + } + var shadowRoot = element.shadowRoot || // check for an undisclosed shadow + typeof options.getShadowRoot === "function" && options.getShadowRoot(element); + var validShadowRoot = !isInert(shadowRoot, false) && (!options.shadowRootFilter || options.shadowRootFilter(element)); + if (shadowRoot && validShadowRoot) { + var _nestedCandidates = getCandidatesIteratively2(shadowRoot === true ? element.children : shadowRoot.children, true, options); + if (options.flatten) { + candidates.push.apply(candidates, _nestedCandidates); + } else { + candidates.push({ + scopeParent: element, + candidates: _nestedCandidates + }); + } + } else { + elementsToCheck.unshift.apply(elementsToCheck, element.children); + } + } + } + return candidates; +}; +var hasTabIndex = function hasTabIndex2(node) { + return !isNaN(parseInt(node.getAttribute("tabindex"), 10)); +}; +var getTabIndex = function getTabIndex2(node) { + if (!node) { + throw new Error("No node provided"); + } + if (node.tabIndex < 0) { + if ((/^(AUDIO|VIDEO|DETAILS)$/.test(node.tagName) || isContentEditable(node)) && !hasTabIndex(node)) { + return 0; + } + } + return node.tabIndex; +}; +var getSortOrderTabIndex = function getSortOrderTabIndex2(node, isScope) { + var tabIndex = getTabIndex(node); + if (tabIndex < 0 && isScope && !hasTabIndex(node)) { + return 0; + } + return tabIndex; +}; +var sortOrderedTabbables = function sortOrderedTabbables2(a, b) { + return a.tabIndex === b.tabIndex ? a.documentOrder - b.documentOrder : a.tabIndex - b.tabIndex; +}; +var isInput = function isInput2(node) { + return node.tagName === "INPUT"; +}; +var isHiddenInput = function isHiddenInput2(node) { + return isInput(node) && node.type === "hidden"; +}; +var isDetailsWithSummary = function isDetailsWithSummary2(node) { + var r = node.tagName === "DETAILS" && Array.prototype.slice.apply(node.children).some(function(child) { + return child.tagName === "SUMMARY"; + }); + return r; +}; +var getCheckedRadio = function getCheckedRadio2(nodes, form) { + for (var i = 0; i < nodes.length; i++) { + if (nodes[i].checked && nodes[i].form === form) { + return nodes[i]; + } + } +}; +var isTabbableRadio = function isTabbableRadio2(node) { + if (!node.name) { + return true; + } + var radioScope = node.form || getRootNode(node); + var queryRadios = function queryRadios2(name) { + return radioScope.querySelectorAll('input[type="radio"][name="' + name + '"]'); + }; + var radioSet; + if (typeof window !== "undefined" && typeof window.CSS !== "undefined" && typeof window.CSS.escape === "function") { + radioSet = queryRadios(window.CSS.escape(node.name)); + } else { + try { + radioSet = queryRadios(node.name); + } catch (err) { + console.error("Looks like you have a radio button with a name attribute containing invalid CSS selector characters and need the CSS.escape polyfill: %s", err.message); + return false; + } + } + var checked = getCheckedRadio(radioSet, node.form); + return !checked || checked === node; +}; +var isRadio = function isRadio2(node) { + return isInput(node) && node.type === "radio"; +}; +var isNonTabbableRadio = function isNonTabbableRadio2(node) { + return isRadio(node) && !isTabbableRadio(node); +}; +var isNodeAttached = function isNodeAttached2(node) { + var _nodeRoot; + var nodeRoot = node && getRootNode(node); + var nodeRootHost = (_nodeRoot = nodeRoot) === null || _nodeRoot === void 0 ? void 0 : _nodeRoot.host; + var attached = false; + if (nodeRoot && nodeRoot !== node) { + var _nodeRootHost, _nodeRootHost$ownerDo, _node$ownerDocument; + attached = !!((_nodeRootHost = nodeRootHost) !== null && _nodeRootHost !== void 0 && (_nodeRootHost$ownerDo = _nodeRootHost.ownerDocument) !== null && _nodeRootHost$ownerDo !== void 0 && _nodeRootHost$ownerDo.contains(nodeRootHost) || node !== null && node !== void 0 && (_node$ownerDocument = node.ownerDocument) !== null && _node$ownerDocument !== void 0 && _node$ownerDocument.contains(node)); + while (!attached && nodeRootHost) { + var _nodeRoot2, _nodeRootHost2, _nodeRootHost2$ownerD; + nodeRoot = getRootNode(nodeRootHost); + nodeRootHost = (_nodeRoot2 = nodeRoot) === null || _nodeRoot2 === void 0 ? void 0 : _nodeRoot2.host; + attached = !!((_nodeRootHost2 = nodeRootHost) !== null && _nodeRootHost2 !== void 0 && (_nodeRootHost2$ownerD = _nodeRootHost2.ownerDocument) !== null && _nodeRootHost2$ownerD !== void 0 && _nodeRootHost2$ownerD.contains(nodeRootHost)); + } + } + return attached; +}; +var isZeroArea = function isZeroArea2(node) { + var _node$getBoundingClie = node.getBoundingClientRect(), width = _node$getBoundingClie.width, height = _node$getBoundingClie.height; + return width === 0 && height === 0; +}; +var isHidden = function isHidden2(node, _ref) { + var displayCheck = _ref.displayCheck, getShadowRoot = _ref.getShadowRoot; + if (getComputedStyle(node).visibility === "hidden") { + return true; + } + var isDirectSummary = matches.call(node, "details>summary:first-of-type"); + var nodeUnderDetails = isDirectSummary ? node.parentElement : node; + if (matches.call(nodeUnderDetails, "details:not([open]) *")) { + return true; + } + if (!displayCheck || displayCheck === "full" || displayCheck === "legacy-full") { + if (typeof getShadowRoot === "function") { + var originalNode = node; + while (node) { + var parentElement = node.parentElement; + var rootNode = getRootNode(node); + if (parentElement && !parentElement.shadowRoot && getShadowRoot(parentElement) === true) { + return isZeroArea(node); + } else if (node.assignedSlot) { + node = node.assignedSlot; + } else if (!parentElement && rootNode !== node.ownerDocument) { + node = rootNode.host; + } else { + node = parentElement; + } + } + node = originalNode; + } + if (isNodeAttached(node)) { + return !node.getClientRects().length; + } + if (displayCheck !== "legacy-full") { + return true; + } + } else if (displayCheck === "non-zero-area") { + return isZeroArea(node); + } + return false; +}; +var isDisabledFromFieldset = function isDisabledFromFieldset2(node) { + if (/^(INPUT|BUTTON|SELECT|TEXTAREA)$/.test(node.tagName)) { + var parentNode = node.parentElement; + while (parentNode) { + if (parentNode.tagName === "FIELDSET" && parentNode.disabled) { + for (var i = 0; i < parentNode.children.length; i++) { + var child = parentNode.children.item(i); + if (child.tagName === "LEGEND") { + return matches.call(parentNode, "fieldset[disabled] *") ? true : !child.contains(node); + } + } + return true; + } + parentNode = parentNode.parentElement; + } + } + return false; +}; +var isNodeMatchingSelectorFocusable = function isNodeMatchingSelectorFocusable2(options, node) { + if (node.disabled || // we must do an inert look up to filter out any elements inside an inert ancestor + // because we're limited in the type of selectors we can use in JSDom (see related + // note related to `candidateSelectors`) + isInert(node) || isHiddenInput(node) || isHidden(node, options) || // For a details element with a summary, the summary element gets the focus + isDetailsWithSummary(node) || isDisabledFromFieldset(node)) { + return false; + } + return true; +}; +var isNodeMatchingSelectorTabbable = function isNodeMatchingSelectorTabbable2(options, node) { + if (isNonTabbableRadio(node) || getTabIndex(node) < 0 || !isNodeMatchingSelectorFocusable(options, node)) { + return false; + } + return true; +}; +var isValidShadowRootTabbable = function isValidShadowRootTabbable2(shadowHostNode) { + var tabIndex = parseInt(shadowHostNode.getAttribute("tabindex"), 10); + if (isNaN(tabIndex) || tabIndex >= 0) { + return true; + } + return false; +}; +var sortByOrder = function sortByOrder2(candidates) { + var regularTabbables = []; + var orderedTabbables = []; + candidates.forEach(function(item, i) { + var isScope = !!item.scopeParent; + var element = isScope ? item.scopeParent : item; + var candidateTabindex = getSortOrderTabIndex(element, isScope); + var elements = isScope ? sortByOrder2(item.candidates) : element; + if (candidateTabindex === 0) { + isScope ? regularTabbables.push.apply(regularTabbables, elements) : regularTabbables.push(element); + } else { + orderedTabbables.push({ + documentOrder: i, + tabIndex: candidateTabindex, + item, + isScope, + content: elements + }); + } + }); + return orderedTabbables.sort(sortOrderedTabbables).reduce(function(acc, sortable) { + sortable.isScope ? acc.push.apply(acc, sortable.content) : acc.push(sortable.content); + return acc; + }, []).concat(regularTabbables); +}; +var tabbable = function tabbable2(container, options) { + options = options || {}; + var candidates; + if (options.getShadowRoot) { + candidates = getCandidatesIteratively([container], options.includeContainer, { + filter: isNodeMatchingSelectorTabbable.bind(null, options), + flatten: false, + getShadowRoot: options.getShadowRoot, + shadowRootFilter: isValidShadowRootTabbable + }); + } else { + candidates = getCandidates(container, options.includeContainer, isNodeMatchingSelectorTabbable.bind(null, options)); + } + return sortByOrder(candidates); +}; +var focusable = function focusable2(container, options) { + options = options || {}; + var candidates; + if (options.getShadowRoot) { + candidates = getCandidatesIteratively([container], options.includeContainer, { + filter: isNodeMatchingSelectorFocusable.bind(null, options), + flatten: true, + getShadowRoot: options.getShadowRoot + }); + } else { + candidates = getCandidates(container, options.includeContainer, isNodeMatchingSelectorFocusable.bind(null, options)); + } + return candidates; +}; +var isTabbable = function isTabbable2(node, options) { + options = options || {}; + if (!node) { + throw new Error("No node provided"); + } + if (matches.call(node, candidateSelector) === false) { + return false; + } + return isNodeMatchingSelectorTabbable(options, node); +}; +var focusableCandidateSelector = /* @__PURE__ */ candidateSelectors.concat("iframe").join(","); +var isFocusable = function isFocusable2(node, options) { + options = options || {}; + if (!node) { + throw new Error("No node provided"); + } + if (matches.call(node, focusableCandidateSelector) === false) { + return false; + } + return isNodeMatchingSelectorFocusable(options, node); +}; + +// node_modules/focus-trap/dist/focus-trap.esm.js +function ownKeys(e, r) { + var t = Object.keys(e); + if (Object.getOwnPropertySymbols) { + var o = Object.getOwnPropertySymbols(e); + r && (o = o.filter(function(r2) { + return Object.getOwnPropertyDescriptor(e, r2).enumerable; + })), t.push.apply(t, o); + } + return t; +} +function _objectSpread2(e) { + for (var r = 1; r < arguments.length; r++) { + var t = null != arguments[r] ? arguments[r] : {}; + r % 2 ? ownKeys(Object(t), true).forEach(function(r2) { + _defineProperty(e, r2, t[r2]); + }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function(r2) { + Object.defineProperty(e, r2, Object.getOwnPropertyDescriptor(t, r2)); + }); + } + return e; +} +function _defineProperty(obj, key, value) { + key = _toPropertyKey(key); + if (key in obj) { + Object.defineProperty(obj, key, { + value, + enumerable: true, + configurable: true, + writable: true + }); + } else { + obj[key] = value; + } + return obj; +} +function _toPrimitive(input, hint) { + if (typeof input !== "object" || input === null) + return input; + var prim = input[Symbol.toPrimitive]; + if (prim !== void 0) { + var res = prim.call(input, hint || "default"); + if (typeof res !== "object") + return res; + throw new TypeError("@@toPrimitive must return a primitive value."); + } + return (hint === "string" ? String : Number)(input); +} +function _toPropertyKey(arg) { + var key = _toPrimitive(arg, "string"); + return typeof key === "symbol" ? key : String(key); +} +var activeFocusTraps = { + activateTrap: function activateTrap(trapStack, trap) { + if (trapStack.length > 0) { + var activeTrap = trapStack[trapStack.length - 1]; + if (activeTrap !== trap) { + activeTrap.pause(); + } + } + var trapIndex = trapStack.indexOf(trap); + if (trapIndex === -1) { + trapStack.push(trap); + } else { + trapStack.splice(trapIndex, 1); + trapStack.push(trap); + } + }, + deactivateTrap: function deactivateTrap(trapStack, trap) { + var trapIndex = trapStack.indexOf(trap); + if (trapIndex !== -1) { + trapStack.splice(trapIndex, 1); + } + if (trapStack.length > 0) { + trapStack[trapStack.length - 1].unpause(); + } + } +}; +var isSelectableInput = function isSelectableInput2(node) { + return node.tagName && node.tagName.toLowerCase() === "input" && typeof node.select === "function"; +}; +var isEscapeEvent = function isEscapeEvent2(e) { + return (e === null || e === void 0 ? void 0 : e.key) === "Escape" || (e === null || e === void 0 ? void 0 : e.key) === "Esc" || (e === null || e === void 0 ? void 0 : e.keyCode) === 27; +}; +var isTabEvent = function isTabEvent2(e) { + return (e === null || e === void 0 ? void 0 : e.key) === "Tab" || (e === null || e === void 0 ? void 0 : e.keyCode) === 9; +}; +var isKeyForward = function isKeyForward2(e) { + return isTabEvent(e) && !e.shiftKey; +}; +var isKeyBackward = function isKeyBackward2(e) { + return isTabEvent(e) && e.shiftKey; +}; +var delay = function delay2(fn) { + return setTimeout(fn, 0); +}; +var findIndex = function findIndex2(arr, fn) { + var idx = -1; + arr.every(function(value, i) { + if (fn(value)) { + idx = i; + return false; + } + return true; + }); + return idx; +}; +var valueOrHandler = function valueOrHandler2(value) { + for (var _len = arguments.length, params = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + params[_key - 1] = arguments[_key]; + } + return typeof value === "function" ? value.apply(void 0, params) : value; +}; +var getActualTarget = function getActualTarget2(event) { + return event.target.shadowRoot && typeof event.composedPath === "function" ? event.composedPath()[0] : event.target; +}; +var internalTrapStack = []; +var createFocusTrap = function createFocusTrap2(elements, userOptions) { + var doc = (userOptions === null || userOptions === void 0 ? void 0 : userOptions.document) || document; + var trapStack = (userOptions === null || userOptions === void 0 ? void 0 : userOptions.trapStack) || internalTrapStack; + var config = _objectSpread2({ + returnFocusOnDeactivate: true, + escapeDeactivates: true, + delayInitialFocus: true, + isKeyForward, + isKeyBackward + }, userOptions); + var state = { + // containers given to createFocusTrap() + // @type {Array} + containers: [], + // list of objects identifying tabbable nodes in `containers` in the trap + // NOTE: it's possible that a group has no tabbable nodes if nodes get removed while the trap + // is active, but the trap should never get to a state where there isn't at least one group + // with at least one tabbable node in it (that would lead to an error condition that would + // result in an error being thrown) + // @type {Array<{ + // container: HTMLElement, + // tabbableNodes: Array, // empty if none + // focusableNodes: Array, // empty if none + // posTabIndexesFound: boolean, + // firstTabbableNode: HTMLElement|undefined, + // lastTabbableNode: HTMLElement|undefined, + // firstDomTabbableNode: HTMLElement|undefined, + // lastDomTabbableNode: HTMLElement|undefined, + // nextTabbableNode: (node: HTMLElement, forward: boolean) => HTMLElement|undefined + // }>} + containerGroups: [], + // same order/length as `containers` list + // references to objects in `containerGroups`, but only those that actually have + // tabbable nodes in them + // NOTE: same order as `containers` and `containerGroups`, but __not necessarily__ + // the same length + tabbableGroups: [], + nodeFocusedBeforeActivation: null, + mostRecentlyFocusedNode: null, + active: false, + paused: false, + // timer ID for when delayInitialFocus is true and initial focus in this trap + // has been delayed during activation + delayInitialFocusTimer: void 0, + // the most recent KeyboardEvent for the configured nav key (typically [SHIFT+]TAB), if any + recentNavEvent: void 0 + }; + var trap; + var getOption = function getOption2(configOverrideOptions, optionName, configOptionName) { + return configOverrideOptions && configOverrideOptions[optionName] !== void 0 ? configOverrideOptions[optionName] : config[configOptionName || optionName]; + }; + var findContainerIndex = function findContainerIndex2(element, event) { + var composedPath = typeof (event === null || event === void 0 ? void 0 : event.composedPath) === "function" ? event.composedPath() : void 0; + return state.containerGroups.findIndex(function(_ref) { + var container = _ref.container, tabbableNodes = _ref.tabbableNodes; + return container.contains(element) || // fall back to explicit tabbable search which will take into consideration any + // web components if the `tabbableOptions.getShadowRoot` option was used for + // the trap, enabling shadow DOM support in tabbable (`Node.contains()` doesn't + // look inside web components even if open) + (composedPath === null || composedPath === void 0 ? void 0 : composedPath.includes(container)) || tabbableNodes.find(function(node) { + return node === element; + }); + }); + }; + var getNodeForOption = function getNodeForOption2(optionName) { + var optionValue = config[optionName]; + if (typeof optionValue === "function") { + for (var _len2 = arguments.length, params = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { + params[_key2 - 1] = arguments[_key2]; + } + optionValue = optionValue.apply(void 0, params); + } + if (optionValue === true) { + optionValue = void 0; + } + if (!optionValue) { + if (optionValue === void 0 || optionValue === false) { + return optionValue; + } + throw new Error("`".concat(optionName, "` was specified but was not a node, or did not return a node")); + } + var node = optionValue; + if (typeof optionValue === "string") { + node = doc.querySelector(optionValue); + if (!node) { + throw new Error("`".concat(optionName, "` as selector refers to no known node")); + } + } + return node; + }; + var getInitialFocusNode = function getInitialFocusNode2() { + var node = getNodeForOption("initialFocus"); + if (node === false) { + return false; + } + if (node === void 0 || !isFocusable(node, config.tabbableOptions)) { + if (findContainerIndex(doc.activeElement) >= 0) { + node = doc.activeElement; + } else { + var firstTabbableGroup = state.tabbableGroups[0]; + var firstTabbableNode = firstTabbableGroup && firstTabbableGroup.firstTabbableNode; + node = firstTabbableNode || getNodeForOption("fallbackFocus"); + } + } + if (!node) { + throw new Error("Your focus-trap needs to have at least one focusable element"); + } + return node; + }; + var updateTabbableNodes = function updateTabbableNodes2() { + state.containerGroups = state.containers.map(function(container) { + var tabbableNodes = tabbable(container, config.tabbableOptions); + var focusableNodes = focusable(container, config.tabbableOptions); + var firstTabbableNode = tabbableNodes.length > 0 ? tabbableNodes[0] : void 0; + var lastTabbableNode = tabbableNodes.length > 0 ? tabbableNodes[tabbableNodes.length - 1] : void 0; + var firstDomTabbableNode = focusableNodes.find(function(node) { + return isTabbable(node); + }); + var lastDomTabbableNode = focusableNodes.slice().reverse().find(function(node) { + return isTabbable(node); + }); + var posTabIndexesFound = !!tabbableNodes.find(function(node) { + return getTabIndex(node) > 0; + }); + return { + container, + tabbableNodes, + focusableNodes, + /** True if at least one node with positive `tabindex` was found in this container. */ + posTabIndexesFound, + /** First tabbable node in container, __tabindex__ order; `undefined` if none. */ + firstTabbableNode, + /** Last tabbable node in container, __tabindex__ order; `undefined` if none. */ + lastTabbableNode, + // NOTE: DOM order is NOT NECESSARILY "document position" order, but figuring that out + // would require more than just https://developer.mozilla.org/en-US/docs/Web/API/Node/compareDocumentPosition + // because that API doesn't work with Shadow DOM as well as it should (@see + // https://github.com/whatwg/dom/issues/320) and since this first/last is only needed, so far, + // to address an edge case related to positive tabindex support, this seems like a much easier, + // "close enough most of the time" alternative for positive tabindexes which should generally + // be avoided anyway... + /** First tabbable node in container, __DOM__ order; `undefined` if none. */ + firstDomTabbableNode, + /** Last tabbable node in container, __DOM__ order; `undefined` if none. */ + lastDomTabbableNode, + /** + * Finds the __tabbable__ node that follows the given node in the specified direction, + * in this container, if any. + * @param {HTMLElement} node + * @param {boolean} [forward] True if going in forward tab order; false if going + * in reverse. + * @returns {HTMLElement|undefined} The next tabbable node, if any. + */ + nextTabbableNode: function nextTabbableNode(node) { + var forward = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : true; + var nodeIdx = tabbableNodes.indexOf(node); + if (nodeIdx < 0) { + if (forward) { + return focusableNodes.slice(focusableNodes.indexOf(node) + 1).find(function(el) { + return isTabbable(el); + }); + } + return focusableNodes.slice(0, focusableNodes.indexOf(node)).reverse().find(function(el) { + return isTabbable(el); + }); + } + return tabbableNodes[nodeIdx + (forward ? 1 : -1)]; + } + }; + }); + state.tabbableGroups = state.containerGroups.filter(function(group) { + return group.tabbableNodes.length > 0; + }); + if (state.tabbableGroups.length <= 0 && !getNodeForOption("fallbackFocus")) { + throw new Error("Your focus-trap must have at least one container with at least one tabbable node in it at all times"); + } + if (state.containerGroups.find(function(g) { + return g.posTabIndexesFound; + }) && state.containerGroups.length > 1) { + throw new Error("At least one node with a positive tabindex was found in one of your focus-trap's multiple containers. Positive tabindexes are only supported in single-container focus-traps."); + } + }; + var getActiveElement = function getActiveElement2(el) { + var activeElement = el.activeElement; + if (!activeElement) { + return; + } + if (activeElement.shadowRoot && activeElement.shadowRoot.activeElement !== null) { + return getActiveElement2(activeElement.shadowRoot); + } + return activeElement; + }; + var tryFocus = function tryFocus2(node) { + if (node === false) { + return; + } + if (node === getActiveElement(document)) { + return; + } + if (!node || !node.focus) { + tryFocus2(getInitialFocusNode()); + return; + } + node.focus({ + preventScroll: !!config.preventScroll + }); + state.mostRecentlyFocusedNode = node; + if (isSelectableInput(node)) { + node.select(); + } + }; + var getReturnFocusNode = function getReturnFocusNode2(previousActiveElement) { + var node = getNodeForOption("setReturnFocus", previousActiveElement); + return node ? node : node === false ? false : previousActiveElement; + }; + var findNextNavNode = function findNextNavNode2(_ref2) { + var target = _ref2.target, event = _ref2.event, _ref2$isBackward = _ref2.isBackward, isBackward = _ref2$isBackward === void 0 ? false : _ref2$isBackward; + target = target || getActualTarget(event); + updateTabbableNodes(); + var destinationNode = null; + if (state.tabbableGroups.length > 0) { + var containerIndex = findContainerIndex(target, event); + var containerGroup = containerIndex >= 0 ? state.containerGroups[containerIndex] : void 0; + if (containerIndex < 0) { + if (isBackward) { + destinationNode = state.tabbableGroups[state.tabbableGroups.length - 1].lastTabbableNode; + } else { + destinationNode = state.tabbableGroups[0].firstTabbableNode; + } + } else if (isBackward) { + var startOfGroupIndex = findIndex(state.tabbableGroups, function(_ref3) { + var firstTabbableNode = _ref3.firstTabbableNode; + return target === firstTabbableNode; + }); + if (startOfGroupIndex < 0 && (containerGroup.container === target || isFocusable(target, config.tabbableOptions) && !isTabbable(target, config.tabbableOptions) && !containerGroup.nextTabbableNode(target, false))) { + startOfGroupIndex = containerIndex; + } + if (startOfGroupIndex >= 0) { + var destinationGroupIndex = startOfGroupIndex === 0 ? state.tabbableGroups.length - 1 : startOfGroupIndex - 1; + var destinationGroup = state.tabbableGroups[destinationGroupIndex]; + destinationNode = getTabIndex(target) >= 0 ? destinationGroup.lastTabbableNode : destinationGroup.lastDomTabbableNode; + } else if (!isTabEvent(event)) { + destinationNode = containerGroup.nextTabbableNode(target, false); + } + } else { + var lastOfGroupIndex = findIndex(state.tabbableGroups, function(_ref4) { + var lastTabbableNode = _ref4.lastTabbableNode; + return target === lastTabbableNode; + }); + if (lastOfGroupIndex < 0 && (containerGroup.container === target || isFocusable(target, config.tabbableOptions) && !isTabbable(target, config.tabbableOptions) && !containerGroup.nextTabbableNode(target))) { + lastOfGroupIndex = containerIndex; + } + if (lastOfGroupIndex >= 0) { + var _destinationGroupIndex = lastOfGroupIndex === state.tabbableGroups.length - 1 ? 0 : lastOfGroupIndex + 1; + var _destinationGroup = state.tabbableGroups[_destinationGroupIndex]; + destinationNode = getTabIndex(target) >= 0 ? _destinationGroup.firstTabbableNode : _destinationGroup.firstDomTabbableNode; + } else if (!isTabEvent(event)) { + destinationNode = containerGroup.nextTabbableNode(target); + } + } + } else { + destinationNode = getNodeForOption("fallbackFocus"); + } + return destinationNode; + }; + var checkPointerDown = function checkPointerDown2(e) { + var target = getActualTarget(e); + if (findContainerIndex(target, e) >= 0) { + return; + } + if (valueOrHandler(config.clickOutsideDeactivates, e)) { + trap.deactivate({ + // NOTE: by setting `returnFocus: false`, deactivate() will do nothing, + // which will result in the outside click setting focus to the node + // that was clicked (and if not focusable, to "nothing"); by setting + // `returnFocus: true`, we'll attempt to re-focus the node originally-focused + // on activation (or the configured `setReturnFocus` node), whether the + // outside click was on a focusable node or not + returnFocus: config.returnFocusOnDeactivate + }); + return; + } + if (valueOrHandler(config.allowOutsideClick, e)) { + return; + } + e.preventDefault(); + }; + var checkFocusIn = function checkFocusIn2(event) { + var target = getActualTarget(event); + var targetContained = findContainerIndex(target, event) >= 0; + if (targetContained || target instanceof Document) { + if (targetContained) { + state.mostRecentlyFocusedNode = target; + } + } else { + event.stopImmediatePropagation(); + var nextNode; + var navAcrossContainers = true; + if (state.mostRecentlyFocusedNode) { + if (getTabIndex(state.mostRecentlyFocusedNode) > 0) { + var mruContainerIdx = findContainerIndex(state.mostRecentlyFocusedNode); + var tabbableNodes = state.containerGroups[mruContainerIdx].tabbableNodes; + if (tabbableNodes.length > 0) { + var mruTabIdx = tabbableNodes.findIndex(function(node) { + return node === state.mostRecentlyFocusedNode; + }); + if (mruTabIdx >= 0) { + if (config.isKeyForward(state.recentNavEvent)) { + if (mruTabIdx + 1 < tabbableNodes.length) { + nextNode = tabbableNodes[mruTabIdx + 1]; + navAcrossContainers = false; + } + } else { + if (mruTabIdx - 1 >= 0) { + nextNode = tabbableNodes[mruTabIdx - 1]; + navAcrossContainers = false; + } + } + } + } + } else { + if (!state.containerGroups.some(function(g) { + return g.tabbableNodes.some(function(n) { + return getTabIndex(n) > 0; + }); + })) { + navAcrossContainers = false; + } + } + } else { + navAcrossContainers = false; + } + if (navAcrossContainers) { + nextNode = findNextNavNode({ + // move FROM the MRU node, not event-related node (which will be the node that is + // outside the trap causing the focus escape we're trying to fix) + target: state.mostRecentlyFocusedNode, + isBackward: config.isKeyBackward(state.recentNavEvent) + }); + } + if (nextNode) { + tryFocus(nextNode); + } else { + tryFocus(state.mostRecentlyFocusedNode || getInitialFocusNode()); + } + } + state.recentNavEvent = void 0; + }; + var checkKeyNav = function checkKeyNav2(event) { + var isBackward = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : false; + state.recentNavEvent = event; + var destinationNode = findNextNavNode({ + event, + isBackward + }); + if (destinationNode) { + if (isTabEvent(event)) { + event.preventDefault(); + } + tryFocus(destinationNode); + } + }; + var checkKey = function checkKey2(event) { + if (isEscapeEvent(event) && valueOrHandler(config.escapeDeactivates, event) !== false) { + event.preventDefault(); + trap.deactivate(); + return; + } + if (config.isKeyForward(event) || config.isKeyBackward(event)) { + checkKeyNav(event, config.isKeyBackward(event)); + } + }; + var checkClick = function checkClick2(e) { + var target = getActualTarget(e); + if (findContainerIndex(target, e) >= 0) { + return; + } + if (valueOrHandler(config.clickOutsideDeactivates, e)) { + return; + } + if (valueOrHandler(config.allowOutsideClick, e)) { + return; + } + e.preventDefault(); + e.stopImmediatePropagation(); + }; + var addListeners = function addListeners2() { + if (!state.active) { + return; + } + activeFocusTraps.activateTrap(trapStack, trap); + state.delayInitialFocusTimer = config.delayInitialFocus ? delay(function() { + tryFocus(getInitialFocusNode()); + }) : tryFocus(getInitialFocusNode()); + doc.addEventListener("focusin", checkFocusIn, true); + doc.addEventListener("mousedown", checkPointerDown, { + capture: true, + passive: false + }); + doc.addEventListener("touchstart", checkPointerDown, { + capture: true, + passive: false + }); + doc.addEventListener("click", checkClick, { + capture: true, + passive: false + }); + doc.addEventListener("keydown", checkKey, { + capture: true, + passive: false + }); + return trap; + }; + var removeListeners = function removeListeners2() { + if (!state.active) { + return; + } + doc.removeEventListener("focusin", checkFocusIn, true); + doc.removeEventListener("mousedown", checkPointerDown, true); + doc.removeEventListener("touchstart", checkPointerDown, true); + doc.removeEventListener("click", checkClick, true); + doc.removeEventListener("keydown", checkKey, true); + return trap; + }; + var checkDomRemoval = function checkDomRemoval2(mutations) { + var isFocusedNodeRemoved = mutations.some(function(mutation) { + var removedNodes = Array.from(mutation.removedNodes); + return removedNodes.some(function(node) { + return node === state.mostRecentlyFocusedNode; + }); + }); + if (isFocusedNodeRemoved) { + tryFocus(getInitialFocusNode()); + } + }; + var mutationObserver = typeof window !== "undefined" && "MutationObserver" in window ? new MutationObserver(checkDomRemoval) : void 0; + var updateObservedNodes = function updateObservedNodes2() { + if (!mutationObserver) { + return; + } + mutationObserver.disconnect(); + if (state.active && !state.paused) { + state.containers.map(function(container) { + mutationObserver.observe(container, { + subtree: true, + childList: true + }); + }); + } + }; + trap = { + get active() { + return state.active; + }, + get paused() { + return state.paused; + }, + activate: function activate(activateOptions) { + if (state.active) { + return this; + } + var onActivate = getOption(activateOptions, "onActivate"); + var onPostActivate = getOption(activateOptions, "onPostActivate"); + var checkCanFocusTrap = getOption(activateOptions, "checkCanFocusTrap"); + if (!checkCanFocusTrap) { + updateTabbableNodes(); + } + state.active = true; + state.paused = false; + state.nodeFocusedBeforeActivation = doc.activeElement; + onActivate === null || onActivate === void 0 || onActivate(); + var finishActivation = function finishActivation2() { + if (checkCanFocusTrap) { + updateTabbableNodes(); + } + addListeners(); + updateObservedNodes(); + onPostActivate === null || onPostActivate === void 0 || onPostActivate(); + }; + if (checkCanFocusTrap) { + checkCanFocusTrap(state.containers.concat()).then(finishActivation, finishActivation); + return this; + } + finishActivation(); + return this; + }, + deactivate: function deactivate(deactivateOptions) { + if (!state.active) { + return this; + } + var options = _objectSpread2({ + onDeactivate: config.onDeactivate, + onPostDeactivate: config.onPostDeactivate, + checkCanReturnFocus: config.checkCanReturnFocus + }, deactivateOptions); + clearTimeout(state.delayInitialFocusTimer); + state.delayInitialFocusTimer = void 0; + removeListeners(); + state.active = false; + state.paused = false; + updateObservedNodes(); + activeFocusTraps.deactivateTrap(trapStack, trap); + var onDeactivate = getOption(options, "onDeactivate"); + var onPostDeactivate = getOption(options, "onPostDeactivate"); + var checkCanReturnFocus = getOption(options, "checkCanReturnFocus"); + var returnFocus = getOption(options, "returnFocus", "returnFocusOnDeactivate"); + onDeactivate === null || onDeactivate === void 0 || onDeactivate(); + var finishDeactivation = function finishDeactivation2() { + delay(function() { + if (returnFocus) { + tryFocus(getReturnFocusNode(state.nodeFocusedBeforeActivation)); + } + onPostDeactivate === null || onPostDeactivate === void 0 || onPostDeactivate(); + }); + }; + if (returnFocus && checkCanReturnFocus) { + checkCanReturnFocus(getReturnFocusNode(state.nodeFocusedBeforeActivation)).then(finishDeactivation, finishDeactivation); + return this; + } + finishDeactivation(); + return this; + }, + pause: function pause(pauseOptions) { + if (state.paused || !state.active) { + return this; + } + var onPause = getOption(pauseOptions, "onPause"); + var onPostPause = getOption(pauseOptions, "onPostPause"); + state.paused = true; + onPause === null || onPause === void 0 || onPause(); + removeListeners(); + updateObservedNodes(); + onPostPause === null || onPostPause === void 0 || onPostPause(); + return this; + }, + unpause: function unpause(unpauseOptions) { + if (!state.paused || !state.active) { + return this; + } + var onUnpause = getOption(unpauseOptions, "onUnpause"); + var onPostUnpause = getOption(unpauseOptions, "onPostUnpause"); + state.paused = false; + onUnpause === null || onUnpause === void 0 || onUnpause(); + updateTabbableNodes(); + addListeners(); + updateObservedNodes(); + onPostUnpause === null || onPostUnpause === void 0 || onPostUnpause(); + return this; + }, + updateContainerElements: function updateContainerElements(containerElements) { + var elementsAsArray = [].concat(containerElements).filter(Boolean); + state.containers = elementsAsArray.map(function(element) { + return typeof element === "string" ? doc.querySelector(element) : element; + }); + if (state.active) { + updateTabbableNodes(); + } + updateObservedNodes(); + return this; + } + }; + trap.updateContainerElements(elements); + return trap; +}; + +// js/helper/section.js +function filterShopifyEvent(event, domElement, callback) { + let executeCallback = false; + if (event.type.includes("shopify:section")) { + if (domElement.hasAttribute("section") && domElement.getAttribute("section") === event.detail.sectionId) { + executeCallback = true; + } + } else if (event.type.includes("shopify:block") && event.target === domElement) { + executeCallback = true; + } + if (executeCallback) { + callback(event); + } +} + +// js/custom-element/behavior/openable-element.js +var OpenableElement = class extends CustomHTMLElement { + static get observedAttributes() { + return ["open"]; + } + constructor() { + super(); + if (Shopify.designMode) { + this.rootDelegate.on("shopify:section:select", (event) => filterShopifyEvent(event, this, () => this.open = true)); + this.rootDelegate.on("shopify:section:deselect", (event) => filterShopifyEvent(event, this, () => this.open = false)); + } + if (this.hasAttribute("append-body")) { + const existingNode = document.getElementById(this.id); + this.removeAttribute("append-body"); + if (existingNode && existingNode !== this) { + existingNode.replaceWith(this.cloneNode(true)); + this.remove(); + } else { + document.body.appendChild(this); + } + } + } + connectedCallback() { + this.delegate.on("click", ".openable__overlay", () => this.open = false); + this.delegate.on("click", '[data-action="close"]', (event) => { + event.stopPropagation(); + this.open = false; + }); + } + get requiresLoading() { + return this.hasAttribute("href"); + } + get open() { + return this.hasAttribute("open"); + } + set open(value) { + if (value) { + (async () => { + await this._load(); + this.clientWidth; + this.setAttribute("open", ""); + })(); + } else { + this.removeAttribute("open"); + } + } + get shouldTrapFocus() { + return true; + } + get returnFocusOnDeactivate() { + return !this.hasAttribute("return-focus") || this.getAttribute("return-focus") === "true"; + } + get focusTrap() { + return this._focusTrap = this._focusTrap || createFocusTrap(this, { + fallbackFocus: this, + initialFocus: this.hasAttribute("initial-focus-selector") ? this.getAttribute("initial-focus-selector") : void 0, + clickOutsideDeactivates: (event) => !(event.target.hasAttribute("aria-controls") && event.target.getAttribute("aria-controls") === this.id), + allowOutsideClick: (event) => event.target.hasAttribute("aria-controls") && event.target.getAttribute("aria-controls") === this.id, + returnFocusOnDeactivate: this.returnFocusOnDeactivate, + onDeactivate: () => this.open = false, + preventScroll: true + }); + } + attributeChangedCallback(name, oldValue, newValue) { + switch (name) { + case "open": + if (oldValue === null && newValue === "") { + if (this.shouldTrapFocus) { + setTimeout(() => this.focusTrap.activate(), 150); + } + triggerEvent(this, "openable-element:open"); + } else if (newValue === null) { + if (this.shouldTrapFocus) { + this.focusTrap.deactivate(); + } + triggerEvent(this, "openable-element:close"); + } + } + } + async _load() { + if (!this.requiresLoading) { + return; + } + triggerNonBubblingEvent(this, "openable-element:load:start"); + const response = await fetch(this.getAttribute("href")); + const element = document.createElement("div"); + element.innerHTML = await response.text(); + this.innerHTML = element.querySelector(this.tagName.toLowerCase()).innerHTML; + this.removeAttribute("href"); + triggerNonBubblingEvent(this, "openable-element:load:end"); + } +}; +window.customElements.define("openable-element", OpenableElement); + +// js/custom-element/behavior/collapsible-content.js +var CollapsibleContent = class extends OpenableElement { + constructor() { + super(); + this.ignoreNextTransition = this.open; + this.addEventListener("shopify:block:select", () => this.open = true); + this.addEventListener("shopify:block:deselect", () => this.open = false); + } + get animateItems() { + return this.hasAttribute("animate-items"); + } + attributeChangedCallback(name) { + if (this.ignoreNextTransition) { + return this.ignoreNextTransition = false; + } + switch (name) { + case "open": + this.style.overflow = "hidden"; + const keyframes = { + height: ["0px", `${this.scrollHeight}px`], + visibility: ["hidden", "visible"] + }; + if (this.animateItems) { + keyframes["opacity"] = this.open ? [0, 0] : [0, 1]; + } + this.animate(keyframes, { + duration: 500, + direction: this.open ? "normal" : "reverse", + easing: "cubic-bezier(0.75, 0, 0.175, 1)" + }).onfinish = () => { + this.style.overflow = this.open ? "visible" : "hidden"; + }; + if (this.animateItems && this.open) { + this.animate({ + opacity: [0, 1], + transform: ["translateY(10px)", "translateY(0)"] + }, { + duration: 250, + delay: 250, + easing: "cubic-bezier(0.75, 0, 0.175, 1)" + }); + } + triggerEvent(this, this.open ? "openable-element:open" : "openable-element:close"); + } + } +}; +window.customElements.define("collapsible-content", CollapsibleContent); + +// js/custom-element/behavior/confirm-button.js +var ConfirmButton = class extends HTMLButtonElement { + connectedCallback() { + this.addEventListener("click", (event) => { + if (!window.confirm(this.getAttribute("data-message") || "Are you sure you wish to do this?")) { + event.preventDefault(); + } + }); + } +}; +window.customElements.define("confirm-button", ConfirmButton, { extends: "button" }); + +// js/mixin/loader-button.js +var LoaderButtonMixin = { + _prepareButton() { + this.originalContent = this.innerHTML; + this._startTransitionPromise = null; + this.innerHTML = ` + ${this.innerHTML} + + `; + this.textElement = this.firstElementChild; + this.spinnerElement = this.lastElementChild; + window.addEventListener("pagehide", () => this.removeAttribute("aria-busy")); + }, + _startTransition() { + const textAnimation = this.textElement.animate({ + opacity: [1, 0], + transform: ["translateY(0)", "translateY(-10px)"] + }, { + duration: 75, + easing: "ease", + fill: "forwards" + }); + this.spinnerElement.hidden = false; + const spinnerAnimation = this.spinnerElement.animate({ + opacity: [0, 1], + transform: ["translate(-50%, 0%)", "translate(-50%, -50%)"] + }, { + duration: 75, + delay: 75, + easing: "ease", + fill: "forwards" + }); + this._startTransitionPromise = Promise.all([ + new Promise((resolve) => textAnimation.onfinish = () => resolve()), + new Promise((resolve) => spinnerAnimation.onfinish = () => resolve()) + ]); + }, + async _endTransition() { + if (!this._startTransitionPromise) { + return; + } + await this._startTransitionPromise; + this.spinnerElement.animate({ + opacity: [1, 0], + transform: ["translate(-50%, -50%)", "translate(-50%, -100%)"] + }, { + duration: 75, + delay: 100, + easing: "ease", + fill: "forwards" + }).onfinish = () => this.spinnerElement.hidden = true; + this.textElement.animate({ + opacity: [0, 1], + transform: ["translateY(10px)", "translateY(0)"] + }, { + duration: 75, + delay: 175, + easing: "ease", + fill: "forwards" + }); + this._startTransitionPromise = null; + } +}; + +// js/custom-element/behavior/loader-button.js +var LoaderButton = class extends HTMLButtonElement { + static get observedAttributes() { + return ["aria-busy"]; + } + constructor() { + super(); + this.addEventListener("click", (event) => { + if (this.type === "submit" && this.form && this.form.checkValidity() && !this.form.hasAttribute("is")) { + if (/^((?!chrome|android).)*safari/i.test(navigator.userAgent)) { + event.preventDefault(); + this.setAttribute("aria-busy", "true"); + setTimeout(() => this.form.submit(), 250); + } else { + this.setAttribute("aria-busy", "true"); + } + } + }); + } + connectedCallback() { + this._prepareButton(); + } + disconnectedCallback() { + this.innerHTML = this.originalContent; + } + attributeChangedCallback(property, oldValue, newValue) { + if (property === "aria-busy") { + if (newValue === "true") { + this._startTransition(); + } else { + this._endTransition(); + } + } + } +}; +Object.assign(LoaderButton.prototype, LoaderButtonMixin); +window.customElements.define("loader-button", LoaderButton, { extends: "button" }); + +// js/custom-element/behavior/page-pagination.js +var PagePagination = class extends CustomHTMLElement { + connectedCallback() { + if (this.hasAttribute("ajax")) { + this.delegate.on("click", "a", this._onLinkClicked.bind(this)); + } + } + _onLinkClicked(event, target) { + event.preventDefault(); + const url = new URL(window.location.href); + url.searchParams.set("page", target.getAttribute("data-page")); + triggerEvent(this, "pagination:page-changed", { url: url.toString() }); + } +}; +window.customElements.define("page-pagination", PagePagination); + +// js/custom-element/behavior/toggle-button.js +var ToggleButton = class extends HTMLButtonElement { + static get observedAttributes() { + return ["aria-expanded", "aria-busy"]; + } + constructor() { + super(); + if (this.hasAttribute("loader")) { + this._prepareButton(); + } + this.addEventListener("click", this._onButtonClick.bind(this)); + this.rootDelegate = new main_default(document.documentElement); + } + _onButtonClick() { + this.isExpanded = !this.isExpanded; + } + connectedCallback() { + document.addEventListener("openable-element:close", (event) => { + if (this.controlledElement === event.target) { + this.isExpanded = false; + event.stopPropagation(); + } + }); + document.addEventListener("openable-element:open", (event) => { + if (this.controlledElement === event.target) { + this.isExpanded = true; + event.stopPropagation(); + } + }); + this.rootDelegate.on("openable-element:load:start", `#${this.getAttribute("aria-controls")}`, () => { + if (this.classList.contains("button")) { + this.setAttribute("aria-busy", "true"); + } else if (this.offsetParent !== null) { + triggerEvent(document.documentElement, "theme:loading:start"); + } + }, true); + this.rootDelegate.on("openable-element:load:end", `#${this.getAttribute("aria-controls")}`, () => { + if (this.classList.contains("button")) { + this.removeAttribute("aria-busy"); + } else if (this.offsetParent !== null) { + triggerEvent(document.documentElement, "theme:loading:end"); + } + }, true); + } + disconnectedCallback() { + this.rootDelegate.destroy(); + } + get isExpanded() { + return this.getAttribute("aria-expanded") === "true"; + } + set isExpanded(value) { + this.setAttribute("aria-expanded", value ? "true" : "false"); + } + get controlledElement() { + return document.getElementById(this.getAttribute("aria-controls")); + } + attributeChangedCallback(name, oldValue, newValue) { + switch (name) { + case "aria-expanded": + if (oldValue === "false" && newValue === "true") { + this.controlledElement.open = true; + } else if (oldValue === "true" && newValue === "false") { + this.controlledElement.open = false; + } + break; + case "aria-busy": + if (this.hasAttribute("loader")) { + if (newValue === "true") { + this._startTransition(); + } else { + this._endTransition(); + } + } + break; + } + } +}; +Object.assign(ToggleButton.prototype, LoaderButtonMixin); +window.customElements.define("toggle-button", ToggleButton, { extends: "button" }); + +// js/custom-element/behavior/toggle-link.js +var ToggleLink = class extends HTMLAnchorElement { + static get observedAttributes() { + return ["aria-expanded"]; + } + constructor() { + super(); + this.addEventListener("click", (event) => { + event.preventDefault(); + this.isExpanded = !this.isExpanded; + }); + this.rootDelegate = new main_default(document.documentElement); + } + connectedCallback() { + this.rootDelegate.on("openable-element:close", `#${this.getAttribute("aria-controls")}`, (event) => { + if (this.controlledElement === event.target) { + this.isExpanded = false; + } + }, true); + this.rootDelegate.on("openable-element:open", `#${this.getAttribute("aria-controls")}`, (event) => { + if (this.controlledElement === event.target) { + this.isExpanded = true; + } + }, true); + } + disconnectedCallback() { + this.rootDelegate.destroy(); + } + get isExpanded() { + return this.getAttribute("aria-expanded") === "true"; + } + set isExpanded(value) { + this.setAttribute("aria-expanded", value ? "true" : "false"); + } + get controlledElement() { + return document.querySelector(`#${this.getAttribute("aria-controls")}`); + } + attributeChangedCallback(name, oldValue, newValue) { + switch (name) { + case "aria-expanded": + if (oldValue === "false" && newValue === "true") { + this.controlledElement.open = true; + } else if (oldValue === "true" && newValue === "false") { + this.controlledElement.open = false; + } + } + } +}; +window.customElements.define("toggle-link", ToggleLink, { extends: "a" }); + +// js/custom-element/behavior/page-dots.js +var PageDots = class extends CustomHTMLElement { + connectedCallback() { + this.buttons = Array.from(this.querySelectorAll("button")); + this.delegate.on("click", "button", (event, target) => { + this._dispatchEvent(this.buttons.indexOf(target)); + }); + if (this.hasAttribute("animation-timer")) { + this.delegate.on("animationend", (event) => { + if (event.elapsedTime > 0) { + this._dispatchEvent((this.selectedIndex + 1 + this.buttons.length) % this.buttons.length); + } + }); + } + } + get selectedIndex() { + return this.buttons.findIndex((button) => button.getAttribute("aria-current") === "true"); + } + set selectedIndex(selectedIndex) { + this.buttons.forEach((button, index) => button.setAttribute("aria-current", selectedIndex === index ? "true" : "false")); + if (this.hasAttribute("align-selected")) { + const selectedItem = this.buttons[selectedIndex], windowHalfWidth = window.innerWidth / 2, boundingRect = selectedItem.getBoundingClientRect(), scrollableElement = this._findFirstScrollableElement(this.parentElement); + if (scrollableElement) { + scrollableElement.scrollTo({ + behavior: "smooth", + left: scrollableElement.scrollLeft + (boundingRect.left - windowHalfWidth) + boundingRect.width / 2 + }); + } + } + } + _dispatchEvent(index) { + if (index !== this.selectedIndex) { + this.dispatchEvent(new CustomEvent("page-dots:changed", { + bubbles: true, + detail: { + index + } + })); + } + } + _findFirstScrollableElement(item, currentDepth = 0) { + if (item === null || currentDepth > 3) { + return null; + } + return item.scrollWidth > item.clientWidth ? item : this._findFirstScrollableElement(item.parentElement, currentDepth + 1); + } +}; +window.customElements.define("page-dots", PageDots); + +// js/custom-element/behavior/prev-next-buttons.js +var PrevNextButtons = class extends HTMLElement { + connectedCallback() { + this.prevButton = this.querySelector("button:first-of-type"); + this.nextButton = this.querySelector("button:last-of-type"); + this.prevButton.addEventListener("click", () => this.prevButton.dispatchEvent(new CustomEvent("prev-next:prev", { bubbles: true }))); + this.nextButton.addEventListener("click", () => this.nextButton.dispatchEvent(new CustomEvent("prev-next:next", { bubbles: true }))); + } + set isPrevDisabled(value) { + this.prevButton.disabled = value; + } + set isNextDisabled(value) { + this.nextButton.disabled = value; + } +}; +var PrevButton = class extends HTMLButtonElement { + connectedCallback() { + this.addEventListener("click", () => this.dispatchEvent(new CustomEvent("prev-next:prev", { bubbles: true }))); + } +}; +var NextButton = class extends HTMLButtonElement { + connectedCallback() { + this.addEventListener("click", () => this.dispatchEvent(new CustomEvent("prev-next:next", { bubbles: true }))); + } +}; +window.customElements.define("prev-next-buttons", PrevNextButtons); +window.customElements.define("prev-button", PrevButton, { extends: "button" }); +window.customElements.define("next-button", NextButton, { extends: "button" }); + +// js/helper/dimensions.js +function getStickyHeaderOffset() { + const documentStyles = getComputedStyle(document.documentElement); + return parseInt(documentStyles.getPropertyValue("--header-height") || 0) * parseInt(documentStyles.getPropertyValue("--enable-sticky-header") || 0) + parseInt(documentStyles.getPropertyValue("--announcement-bar-height") || 0) * parseInt(documentStyles.getPropertyValue("--enable-sticky-announcement-bar") || 0); +} + +// js/custom-element/behavior/safe-sticky.js +var SafeSticky = class extends HTMLElement { + connectedCallback() { + this.lastKnownY = window.scrollY; + this.currentTop = 0; + this.hasPendingRaf = false; + window.addEventListener("scroll", this._checkPosition.bind(this)); + } + get initialTopOffset() { + return getStickyHeaderOffset() + (parseInt(this.getAttribute("offset")) || 0); + } + _checkPosition() { + if (this.hasPendingRaf) { + return; + } + this.hasPendingRaf = true; + requestAnimationFrame(() => { + let bounds = this.getBoundingClientRect(), maxTop = bounds.top + window.scrollY - this.offsetTop + this.initialTopOffset, minTop = this.clientHeight - window.innerHeight; + if (window.scrollY < this.lastKnownY) { + this.currentTop -= window.scrollY - this.lastKnownY; + } else { + this.currentTop += this.lastKnownY - window.scrollY; + } + this.currentTop = Math.min(Math.max(this.currentTop, -minTop), maxTop, this.initialTopOffset); + this.lastKnownY = window.scrollY; + this.style.top = `${this.currentTop}px`; + this.hasPendingRaf = false; + }); + } +}; +window.customElements.define("safe-sticky", SafeSticky); + +// js/helper/throttle.js +function throttle(callback, delay3 = 15) { + let throttleTimeout = null, storedEvent = null; + const throttledEventHandler = (event) => { + storedEvent = event; + const shouldHandleEvent = !throttleTimeout; + if (shouldHandleEvent) { + callback(storedEvent); + storedEvent = null; + throttleTimeout = setTimeout(() => { + throttleTimeout = null; + if (storedEvent) { + throttledEventHandler(storedEvent); + } + }, delay3); + } + }; + return throttledEventHandler; +} + +// js/custom-element/behavior/scroll-spy.js +var ScrollSpy = class extends HTMLElement { + connectedCallback() { + this._createSvg(); + this.elementsToObserve = Array.from(this.querySelectorAll("a")).map((linkElement) => document.querySelector(linkElement.getAttribute("href"))); + this.navListItems = Array.from(this.querySelectorAll("li")); + this.navItems = this.navListItems.map((listItem) => { + const anchor = listItem.firstElementChild, targetID = anchor && anchor.getAttribute("href").slice(1), target = document.getElementById(targetID); + return { listItem, anchor, target }; + }).filter((item) => item.target); + this.drawPath(); + window.addEventListener("scroll", throttle(this.markVisibleSection.bind(this), 25)); + window.addEventListener("orientationchange", () => { + window.addEventListener("resize", () => { + this.drawPath(); + this.markVisibleSection(); + }, { once: true }); + }); + this.markVisibleSection(); + } + /** + * Dynamically create the SVG element that will be used to "spy" the scroll + */ + _createSvg() { + this.navPath = document.createElementNS("http://www.w3.org/2000/svg", "path"); + const svgElement = document.createElementNS("http://www.w3.org/2000/svg", "svg"); + svgElement.insertAdjacentElement("beforeend", this.navPath); + this.insertAdjacentElement("beforeend", svgElement); + this.lastPathStart = this.lastPathEnd = null; + } + drawPath() { + let path = [], pathIndent; + this.navItems.forEach((item, i) => { + const x = item.anchor.offsetLeft - 5, y = item.anchor.offsetTop, height = item.anchor.offsetHeight; + if (i === 0) { + path.push("M", x, y, "L", x, y + height); + item.pathStart = 0; + } else { + if (pathIndent !== x) { + path.push("L", pathIndent, y); + } + path.push("L", x, y); + this.navPath.setAttribute("d", path.join(" ")); + item.pathStart = this.navPath.getTotalLength() || 0; + path.push("L", x, y + height); + } + pathIndent = x; + this.navPath.setAttribute("d", path.join(" ")); + item.pathEnd = this.navPath.getTotalLength(); + }); + } + syncPath() { + const someElsAreVisible = () => this.querySelectorAll(".is-visible").length > 0, thisElIsVisible = (el) => el.classList.contains("is-visible"), pathLength = this.navPath.getTotalLength(); + let pathStart = pathLength, pathEnd = 0; + this.navItems.forEach((item) => { + if (thisElIsVisible(item.listItem)) { + pathStart = Math.min(item.pathStart, pathStart); + pathEnd = Math.max(item.pathEnd, pathEnd); + } + }); + if (someElsAreVisible() && pathStart < pathEnd) { + if (pathStart !== this.lastPathStart || pathEnd !== this.lastPathEnd) { + const dashArray = `1 ${pathStart} ${pathEnd - pathStart} ${pathLength}`; + this.navPath.style.setProperty("stroke-dashoffset", "1"); + this.navPath.style.setProperty("stroke-dasharray", dashArray); + this.navPath.style.setProperty("opacity", "1"); + } + } else { + this.navPath.style.setProperty("opacity", "0"); + } + this.lastPathStart = pathStart; + this.lastPathEnd = pathEnd; + } + markVisibleSection() { + this.navListItems.forEach((item) => item.classList.remove("is-visible")); + for (const [index, elementToObserve] of this.elementsToObserve.entries()) { + const boundingClientRect = elementToObserve.getBoundingClientRect(); + if (boundingClientRect.top > getStickyHeaderOffset() || index === this.elementsToObserve.length - 1) { + this.querySelector(`a[href="#${elementToObserve.id}"]`).parentElement.classList.add("is-visible"); + break; + } + } + this.syncPath(); + } +}; +window.customElements.define("scroll-spy", ScrollSpy); + +// js/custom-element/behavior/scroll-shadow.js +var template = ` + + + +`; +var Updater = class { + constructor(targetElement) { + this.scheduleUpdate = throttle(() => this.update(targetElement, getComputedStyle(targetElement))); + this.resizeObserver = new ResizeObserver(this.scheduleUpdate.bind(this)); + } + start(element) { + if (this.element) { + this.stop(); + } + if (element) { + element.addEventListener("scroll", this.scheduleUpdate); + this.resizeObserver.observe(element); + this.element = element; + } + } + stop() { + if (!this.element) { + return; + } + this.element.removeEventListener("scroll", this.scheduleUpdate); + this.resizeObserver.unobserve(this.element); + this.element = null; + } + update(targetElement, style) { + if (!this.element) { + return; + } + const maxSize = style.getPropertyValue("--scroll-shadow-size") ? parseInt(style.getPropertyValue("--scroll-shadow-size")) : 0; + const scroll = { + top: Math.max(this.element.scrollTop, 0), + bottom: Math.max(this.element.scrollHeight - this.element.offsetHeight - this.element.scrollTop, 0), + left: Math.max(this.element.scrollLeft, 0), + right: Math.max(this.element.scrollWidth - this.element.offsetWidth - this.element.scrollLeft, 0) + }; + requestAnimationFrame(() => { + for (const position of ["top", "bottom", "left", "right"]) { + targetElement.style.setProperty( + `--${position}`, + `${scroll[position] > maxSize ? maxSize : scroll[position]}px` + ); + } + }); + } +}; +var ScrollShadow = class extends HTMLElement { + constructor() { + super(); + this.attachShadow({ mode: "open" }).innerHTML = template; + this.updater = new Updater(this.shadowRoot.lastElementChild); + } + connectedCallback() { + this.shadowRoot.querySelector("slot").addEventListener("slotchange", () => this.start()); + this.start(); + } + disconnectedCallback() { + this.updater.stop(); + } + start() { + this.updater.start(this.firstElementChild); + } +}; +if ("ResizeObserver" in window) { + window.customElements.define("scroll-shadow", ScrollShadow); +} + +// js/custom-element/behavior/share-toggle-button.js +var ShareToggleButton = class extends ToggleButton { + _onButtonClick() { + if (window.matchMedia(window.themeVariables.breakpoints.phone).matches && navigator.share) { + navigator.share({ + title: this.hasAttribute("share-title") ? this.getAttribute("share-title") : document.title, + url: this.hasAttribute("share-url") ? this.getAttribute("share-url") : window.location.href + }); + } else { + super._onButtonClick(); + } + } +}; +window.customElements.define("share-toggle-button", ShareToggleButton, { extends: "button" }); + +// js/custom-element/ui/carousel.js +var NativeCarousel = class extends CustomHTMLElement { + connectedCallback() { + this.items = Array.from(this.querySelectorAll("native-carousel-item")); + this.pageDotsElements = Array.from(this.querySelectorAll("page-dots")); + this.prevNextButtonsElements = Array.from(this.querySelectorAll("prev-next-buttons")); + if (this.items.length > 1) { + this.addEventListener("prev-next:prev", this.prev.bind(this)); + this.addEventListener("prev-next:next", this.next.bind(this)); + this.addEventListener("page-dots:changed", (event) => this.select(event.detail.index, true)); + if (Shopify.designMode) { + this.addEventListener("shopify:block:select", (event) => this.select(event.target.index, !event.detail.load)); + } + } + const scrollerElement = this.items[0].parentElement; + this.intersectionObserver = new IntersectionObserver(this._onVisibilityChanged.bind(this), { root: scrollerElement, rootMargin: `${scrollerElement.clientHeight}px 0px`, threshold: 0.8 }); + this.items.forEach((item) => this.intersectionObserver.observe(item)); + } + disconnectedCallback() { + super.disconnectedCallback(); + this.intersectionObserver.disconnect(); + } + get selectedIndex() { + return this.items.findIndex((item) => item.selected); + } + prev(shouldAnimate = true) { + this.select(Math.max(this.selectedIndex - 1, 0), shouldAnimate); + } + next(shouldAnimate = true) { + this.select(Math.min(this.selectedIndex + 1, this.items.length - 1), shouldAnimate); + } + select(index, shouldAnimate = true) { + const clampIndex = Math.max(0, Math.min(index, this.items.length)); + const selectedElement = this.items[clampIndex]; + this._adjustNavigationForElement(selectedElement); + if (shouldAnimate) { + this.items.forEach((item) => this.intersectionObserver.unobserve(item)); + setInterval(() => { + this.items.forEach((item) => this.intersectionObserver.observe(item)); + }, 800); + } + this.items.forEach((item, loopIndex) => item.selected = loopIndex === clampIndex); + const direction = window.themeVariables.settings.direction === "ltr" ? 1 : -1; + selectedElement.parentElement.scrollTo({ left: direction * (selectedElement.clientWidth * clampIndex), behavior: shouldAnimate ? "smooth" : "auto" }); + } + _adjustNavigationForElement(selectedElement) { + this.items.forEach((item) => item.selected = selectedElement === item); + this.pageDotsElements.forEach((pageDot) => pageDot.selectedIndex = selectedElement.index); + this.prevNextButtonsElements.forEach((prevNextButton) => { + prevNextButton.isPrevDisabled = selectedElement.index === 0; + prevNextButton.isNextDisabled = selectedElement.index === this.items.length - 1; + }); + } + _onVisibilityChanged(entries) { + for (let entry of entries) { + if (entry.isIntersecting) { + this._adjustNavigationForElement(entry.target); + break; + } + } + } +}; +var NativeCarouselItem = class extends CustomHTMLElement { + static get observedAttributes() { + return ["hidden"]; + } + get index() { + return [...this.parentNode.children].indexOf(this); + } + get selected() { + return !this.hasAttribute("hidden"); + } + set selected(value) { + this.hidden = !value; + } +}; +window.customElements.define("native-carousel-item", NativeCarouselItem); +window.customElements.define("native-carousel", NativeCarousel); + +// js/custom-element/ui/drag-cursor.js +var DragCursor = class extends HTMLElement { + connectedCallback() { + this.scrollableElement = this.parentElement; + this.scrollableElement.addEventListener("mouseenter", this._onMouseEnter.bind(this)); + this.scrollableElement.addEventListener("mousemove", this._onMouseMove.bind(this)); + this.scrollableElement.addEventListener("mouseleave", this._onMouseLeave.bind(this)); + this.innerHTML = ` + + + + + `; + } + _onMouseEnter(event) { + this.removeAttribute("hidden"); + this._positionCursor(event); + } + _onMouseLeave() { + this.setAttribute("hidden", ""); + } + _onMouseMove(event) { + this.toggleAttribute("hidden", event.target.tagName === "BUTTON" || event.target.tagName === "A"); + this._positionCursor(event); + } + _positionCursor(event) { + const elementBoundingRect = this.scrollableElement.getBoundingClientRect(); + const x = event.clientX - elementBoundingRect.x; + const y = event.clientY - elementBoundingRect.y; + this.style.transform = `translate(${x - this.clientWidth / 2}px, ${y - this.clientHeight / 2}px)`; + } +}; +window.customElements.define("drag-cursor", DragCursor); + +// js/custom-element/ui/scrollable-content.js +var ScrollableContent = class extends CustomHTMLElement { + connectedCallback() { + if (this.draggable) { + this._setupDraggability(); + } + this._checkScrollability(); + window.addEventListener("resize", this._checkScrollability.bind(this)); + this.addEventListener("scroll", throttle(this._calculateProgress.bind(this), 15)); + } + get draggable() { + return this.hasAttribute("draggable"); + } + _setupDraggability() { + this.insertAdjacentHTML("afterend", ''); + const mediaQuery = matchMedia("(hover: none)"); + mediaQuery.addListener(this._onMediaChanges.bind(this)); + if (!mediaQuery.matches) { + this._attachDraggableListeners(); + } + } + _attachDraggableListeners() { + this.delegate.on("mousedown", this._onMouseDown.bind(this)); + this.delegate.on("mousemove", this._onMouseMove.bind(this)); + this.delegate.on("mouseup", this._onMouseUp.bind(this)); + } + _removeDraggableListeners() { + this.delegate.off("mousedown"); + this.delegate.off("mousemove"); + this.delegate.off("mouseup"); + } + _checkScrollability() { + this.classList.toggle("is-scrollable", this.scrollWidth > this.offsetWidth); + } + _calculateProgress() { + const scrollLeft = this.scrollLeft * (window.themeVariables.settings.direction === "ltr" ? 1 : -1); + const progress = Math.max(0, Math.min(1, scrollLeft / (this.scrollWidth - this.clientWidth))) * 100; + triggerEvent(this, "scrollable-content:progress", { progress }); + } + _onMediaChanges(event) { + if (!event.matches) { + this._attachDraggableListeners(); + } else { + this._removeDraggableListeners(); + } + } + _onMouseDown(event) { + if (event.target && event.target.nodeName === "IMG") { + event.preventDefault(); + } + this.startX = event.clientX + this.scrollLeft; + this.diffX = 0; + this.drag = true; + } + _onMouseMove(event) { + if (this.drag) { + this.diffX = this.startX - (event.clientX + this.scrollLeft); + this.scrollLeft += this.diffX; + } + } + _onMouseUp() { + this.drag = false; + let start = 1; + let animate = () => { + let step = Math.sinh(start); + if (step <= 0) { + window.cancelAnimationFrame(animate); + } else { + this.scrollLeft += this.diffX * step; + start -= 0.03; + window.requestAnimationFrame(animate); + } + }; + animate(); + } +}; +window.customElements.define("scrollable-content", ScrollableContent); + +// js/custom-element/ui/loading-bar.js +var LoadingBar = class extends CustomHTMLElement { + constructor() { + super(); + this.rootDelegate.on("theme:loading:start", this.show.bind(this)); + this.rootDelegate.on("theme:loading:end", this.hide.bind(this)); + this.delegate.on("transitionend", this._onTransitionEnd.bind(this)); + } + show() { + this.classList.add("is-visible"); + this.style.transform = "scaleX(0.4)"; + } + hide() { + this.style.transform = "scaleX(1)"; + this.classList.add("is-finished"); + } + _onTransitionEnd(event) { + if (event.propertyName === "transform" && this.classList.contains("is-finished")) { + this.classList.remove("is-visible"); + this.classList.remove("is-finished"); + this.style.transform = "scaleX(0)"; + } + } +}; +window.customElements.define("loading-bar", LoadingBar); + +// js/custom-element/ui/split-lines.js +var SplitLines = class extends HTMLElement { + connectedCallback() { + this.originalContent = this.textContent; + this.lastWidth = window.innerWidth; + this.hasBeenSplitted = false; + window.addEventListener("resize", this._onResize.bind(this)); + } + [Symbol.asyncIterator]() { + return { + splitPromise: this.split.bind(this), + index: 0, + async next() { + const lines = await this.splitPromise(); + if (this.index !== lines.length) { + return { done: false, value: lines[this.index++] }; + } else { + return { done: true }; + } + } + }; + } + split(force = false) { + if (this.childElementCount > 0 && !force) { + return Promise.resolve(Array.from(this.children)); + } + this.hasBeenSplitted = true; + return new Promise((resolve) => { + requestAnimationFrame(() => { + this.innerHTML = this.originalContent.replace(/./g, "$&").replace(/\s/g, " "); + const bounds = {}; + Array.from(this.children).forEach((child) => { + const rect = parseInt(child.getBoundingClientRect().top); + bounds[rect] = (bounds[rect] || "") + child.textContent; + }); + this.innerHTML = Object.values(bounds).map( + (item) => `${item.trim()}` + ).join(""); + this.style.opacity = this.hasAttribute("reveal") ? 1 : null; + this.style.visibility = this.hasAttribute("reveal-visibility") ? "visible" : null; + resolve(Array.from(this.children)); + }); + }); + } + async _onResize() { + if (this.lastWidth === window.innerWidth || !this.hasBeenSplitted) { + return; + } + await this.split(true); + this.dispatchEvent(new CustomEvent("split-lines:re-split", { bubbles: true })); + this.lastWidth = window.innerWidth; + } +}; +window.customElements.define("split-lines", SplitLines); + +// js/custom-element/ui/popover.js +var PopoverContent = class extends OpenableElement { + connectedCallback() { + super.connectedCallback(); + this.delegate.on("click", ".popover__overlay", () => this.open = false); + } + attributeChangedCallback(name, oldValue, newValue) { + super.attributeChangedCallback(name, oldValue, newValue); + switch (name) { + case "open": + document.documentElement.classList.toggle("lock-mobile", this.open); + } + } +}; +window.customElements.define("popover-content", PopoverContent); + +// js/custom-element/ui/tabs-nav.js +var TabsNav = class extends HTMLElement { + connectedCallback() { + this.buttons = Array.from(this.querySelectorAll("button[aria-controls]")); + this.scrollerElement = this.querySelector(".tabs-nav__scroller"); + this.buttons.forEach((button) => button.addEventListener("click", () => this.selectButton(button))); + this.addEventListener("shopify:block:select", (event) => this.selectButton(event.target, !event.detail.load)); + this.positionElement = document.createElement("span"); + this.positionElement.classList.add("tabs-nav__position"); + this.buttons[0].parentElement.insertAdjacentElement("afterend", this.positionElement); + window.addEventListener("resize", this._onWindowResized.bind(this)); + this._adjustNavigationPosition(); + if (this.hasArrows) { + this._handleArrows(); + } + } + get hasArrows() { + return this.hasAttribute("arrows"); + } + get selectedTabIndex() { + return this.buttons.findIndex((button) => button.getAttribute("aria-expanded") === "true"); + } + get selectedButton() { + return this.buttons.find((button) => button.getAttribute("aria-expanded") === "true"); + } + selectButton(button, animate = true) { + if (!this.buttons.includes(button) || this.selectedButton === button) { + return; + } + const from = document.getElementById(this.selectedButton.getAttribute("aria-controls")), to = document.getElementById(button.getAttribute("aria-controls")); + if (animate) { + this._transitionContent(from, to); + } else { + from.hidden = true; + to.hidden = false; + } + this.selectedButton.setAttribute("aria-expanded", "false"); + button.setAttribute("aria-expanded", "true"); + triggerEvent(this, "tabs-nav:changed", { button }); + this._adjustNavigationPosition(); + } + addButton(button) { + button.addEventListener("click", () => this.selectButton(button)); + button.setAttribute("aria-expanded", "false"); + this.buttons[this.buttons.length - 1].insertAdjacentElement("afterend", button); + this.buttons.push(button); + this._adjustNavigationPosition(false); + } + _transitionContent(from, to) { + from.animate({ + opacity: [1, 0] + }, { + duration: 250, + easing: "ease" + }).onfinish = () => { + from.hidden = true; + to.hidden = false; + to.animate({ + opacity: [0, 1] + }, { + duration: 250, + easing: "ease" + }); + }; + } + _onWindowResized() { + this._adjustNavigationPosition(); + } + _adjustNavigationPosition(shouldAnimate = true) { + const scale = this.selectedButton.clientWidth / this.positionElement.parentElement.clientWidth, translate = this.selectedButton.offsetLeft / this.positionElement.parentElement.clientWidth / scale, windowHalfWidth = this.scrollerElement.clientWidth / 2; + this.scrollerElement.scrollTo({ + behavior: shouldAnimate ? "smooth" : "auto", + left: this.selectedButton.offsetLeft - windowHalfWidth + this.selectedButton.clientWidth / 2 + }); + if (!shouldAnimate) { + this.positionElement.style.transition = "none"; + } + this.positionElement.style.setProperty("--scale", scale); + this.positionElement.style.setProperty("--translate", `${translate * 100}%`); + this.positionElement.clientWidth; + requestAnimationFrame(() => { + this.positionElement.classList.add("is-initialized"); + this.positionElement.style.transition = null; + }); + } + /** + * When the tabs nav can have lot of tab items (for instance on product page), the custom element can add + * extra arrows to make navigation easier + */ + _handleArrows() { + const arrowsContainer = this.querySelector(".tabs-nav__arrows"); + arrowsContainer.firstElementChild.addEventListener("click", () => { + this.selectButton(this.buttons[Math.max(this.selectedTabIndex - 1, 0)]); + }); + arrowsContainer.lastElementChild.addEventListener("click", () => { + this.selectButton(this.buttons[Math.min(this.selectedTabIndex + 1, this.buttons.length - 1)]); + }); + } +}; +window.customElements.define("tabs-nav", TabsNav); + +// js/helper/library-loader.js +var LibraryLoader = class { + static load(libraryName) { + const STATUS_REQUESTED = "requested", STATUS_LOADED = "loaded"; + const library = this.libraries[libraryName]; + if (!library) { + return; + } + if (library.status === STATUS_REQUESTED) { + return library.promise; + } + if (library.status === STATUS_LOADED) { + return Promise.resolve(); + } + let promise; + if (library.type === "script") { + promise = new Promise((resolve, reject) => { + let tag = document.createElement("script"); + tag.id = library.tagId; + tag.src = library.src; + tag.onerror = reject; + tag.onload = () => { + library.status = STATUS_LOADED; + resolve(); + }; + document.body.appendChild(tag); + }); + } else { + promise = new Promise((resolve, reject) => { + let tag = document.createElement("link"); + tag.id = library.tagId; + tag.href = library.src; + tag.rel = "stylesheet"; + tag.type = "text/css"; + tag.onerror = reject; + tag.onload = () => { + library.status = STATUS_LOADED; + resolve(); + }; + document.body.appendChild(tag); + }); + } + library.promise = promise; + library.status = STATUS_REQUESTED; + return promise; + } +}; +__publicField(LibraryLoader, "libraries", { + flickity: { + tagId: "flickity", + src: window.themeVariables.libs.flickity, + type: "script" + }, + photoswipe: { + tagId: "photoswipe", + src: window.themeVariables.libs.photoswipe, + type: "script" + }, + qrCode: { + tagId: "qrCode", + src: window.themeVariables.libs.qrCode, + type: "script" + }, + modelViewerUiStyles: { + tagId: "shopify-model-viewer-ui-styles", + src: "https://cdn.shopify.com/shopifycloud/model-viewer-ui/assets/v1.0/model-viewer-ui.css", + type: "link" + } +}); + +// js/custom-element/ui/qr-code.js +var QrCode = class extends HTMLElement { + async connectedCallback() { + await LibraryLoader.load("qrCode"); + new window.QRCode(this, { + text: this.getAttribute("identifier"), + width: 200, + height: 200 + }); + } +}; +window.customElements.define("qr-code", QrCode); + +// js/custom-element/ui/country-selector.js +var CountrySelector = class extends HTMLSelectElement { + connectedCallback() { + this.provinceElement = document.getElementById(this.getAttribute("aria-owns")); + this.addEventListener("change", this._updateProvinceVisibility.bind(this)); + if (this.hasAttribute("data-default")) { + for (let i = 0; i !== this.options.length; ++i) { + if (this.options[i].text === this.getAttribute("data-default")) { + this.selectedIndex = i; + break; + } + } + } + this._updateProvinceVisibility(); + const provinceSelectElement = this.provinceElement.tagName === "SELECT" ? this.provinceElement : this.provinceElement.querySelector("select"); + if (provinceSelectElement.hasAttribute("data-default")) { + for (let i = 0; i !== provinceSelectElement.options.length; ++i) { + if (provinceSelectElement.options[i].text === provinceSelectElement.getAttribute("data-default")) { + provinceSelectElement.selectedIndex = i; + break; + } + } + } + } + _updateProvinceVisibility() { + const selectedOption = this.options[this.selectedIndex]; + if (!selectedOption) { + return; + } + let provinces = JSON.parse(selectedOption.getAttribute("data-provinces") || "[]"), provinceSelectElement = this.provinceElement.tagName === "SELECT" ? this.provinceElement : this.provinceElement.querySelector("select"); + provinceSelectElement.innerHTML = ""; + if (provinces.length === 0) { + this.provinceElement.hidden = true; + return; + } + provinces.forEach((data) => { + provinceSelectElement.options.add(new Option(data[1], data[0])); + }); + this.provinceElement.hidden = false; + } +}; +window.customElements.define("country-selector", CountrySelector, { extends: "select" }); + +// js/custom-element/ui/modal.js +var ModalContent = class extends OpenableElement { + connectedCallback() { + super.connectedCallback(); + if (this.appearAfterDelay && !(this.onlyOnce && this.hasAppearedOnce)) { + setTimeout(() => this.open = true, this.apparitionDelay); + } + this.delegate.on("click", ".modal__overlay", () => this.open = false); + } + get appearAfterDelay() { + return this.hasAttribute("apparition-delay"); + } + get apparitionDelay() { + return parseInt(this.getAttribute("apparition-delay") || 0) * 1e3; + } + get onlyOnce() { + return this.hasAttribute("only-once"); + } + get hasAppearedOnce() { + return localStorage.getItem("theme:popup-appeared") !== null; + } + attributeChangedCallback(name, oldValue, newValue) { + super.attributeChangedCallback(name, oldValue, newValue); + switch (name) { + case "open": + document.documentElement.classList.toggle("lock-all", this.open); + if (this.open) { + localStorage.setItem("theme:popup-appeared", true); + } + } + } +}; +window.customElements.define("modal-content", ModalContent); + +// js/custom-element/ui/price-range.js +var PriceRange = class extends HTMLElement { + connectedCallback() { + this.rangeLowerBound = this.querySelector(".price-range__range-group input:first-child"); + this.rangeHigherBound = this.querySelector(".price-range__range-group input:last-child"); + this.textInputLowerBound = this.querySelector(".price-range__input:first-child input"); + this.textInputHigherBound = this.querySelector(".price-range__input:last-child input"); + this.textInputLowerBound.addEventListener("focus", () => this.textInputLowerBound.select()); + this.textInputHigherBound.addEventListener("focus", () => this.textInputHigherBound.select()); + this.textInputLowerBound.addEventListener("change", (event) => { + event.target.value = Math.max(Math.min(parseInt(event.target.value), parseInt(this.textInputHigherBound.value || event.target.max) - 1), event.target.min); + this.rangeLowerBound.value = event.target.value; + this.rangeLowerBound.parentElement.style.setProperty("--range-min", `${parseInt(this.rangeLowerBound.value) / parseInt(this.rangeLowerBound.max) * 100}%`); + }); + this.textInputHigherBound.addEventListener("change", (event) => { + event.target.value = Math.min(Math.max(parseInt(event.target.value), parseInt(this.textInputLowerBound.value || event.target.min) + 1), event.target.max); + this.rangeHigherBound.value = event.target.value; + this.rangeHigherBound.parentElement.style.setProperty("--range-max", `${parseInt(this.rangeHigherBound.value) / parseInt(this.rangeHigherBound.max) * 100}%`); + }); + this.rangeLowerBound.addEventListener("change", (event) => { + this.textInputLowerBound.value = event.target.value; + this.textInputLowerBound.dispatchEvent(new Event("change", { bubbles: true })); + }); + this.rangeHigherBound.addEventListener("change", (event) => { + this.textInputHigherBound.value = event.target.value; + this.textInputHigherBound.dispatchEvent(new Event("change", { bubbles: true })); + }); + this.rangeLowerBound.addEventListener("input", (event) => { + triggerEvent(this, "facet:abort-loading"); + event.target.value = Math.min(parseInt(event.target.value), parseInt(this.textInputHigherBound.value || event.target.max) - 1); + event.target.parentElement.style.setProperty("--range-min", `${parseInt(event.target.value) / parseInt(event.target.max) * 100}%`); + this.textInputLowerBound.value = event.target.value; + }); + this.rangeHigherBound.addEventListener("input", (event) => { + triggerEvent(this, "facet:abort-loading"); + event.target.value = Math.max(parseInt(event.target.value), parseInt(this.textInputLowerBound.value || event.target.min) + 1); + event.target.parentElement.style.setProperty("--range-max", `${parseInt(event.target.value) / parseInt(event.target.max) * 100}%`); + this.textInputHigherBound.value = event.target.value; + }); + } +}; +window.customElements.define("price-range", PriceRange); + +// js/custom-element/ui/link-bar.js +var LinkBar = class extends HTMLElement { + connectedCallback() { + const selectedItem = this.querySelector(".link-bar__link-item--selected"); + if (selectedItem) { + requestAnimationFrame(() => { + selectedItem.style.scrollSnapAlign = "none"; + }); + } + } +}; +window.customElements.define("link-bar", LinkBar); + +// js/helper/media-features.js +var MediaFeatures = class { + static prefersReducedMotion() { + return window.matchMedia("(prefers-reduced-motion: reduce)").matches; + } + static supportsHover() { + return window.matchMedia("(pointer: fine)").matches; + } +}; + +// js/custom-element/ui/flickity-carousel.js +var FlickityCarousel = class extends CustomHTMLElement { + constructor() { + super(); + if (this.childElementCount === 1) { + return; + } + this.addEventListener("flickity:ready", this._preloadNextImage.bind(this)); + this.addEventListener("flickity:slide-changed", this._preloadNextImage.bind(this)); + this._createFlickity(); + } + async disconnectedCallback() { + if (this.flickity) { + const flickityInstance = await this.flickity; + flickityInstance.destroy(); + } + } + get flickityConfig() { + return JSON.parse(this.getAttribute("flickity-config")); + } + get flickityInstance() { + return this.flickity; + } + async next() { + (await this.flickityInstance).next(); + } + async previous() { + (await this.flickityInstance).previous(); + } + async select(indexOrSelector) { + (await this.flickityInstance).selectCell(indexOrSelector); + } + async setDraggable(draggable) { + const flickityInstance = await this.flickity; + flickityInstance.options.draggable = draggable; + flickityInstance.updateDraggable(); + } + async reload() { + const flickityInstance = await this.flickity; + flickityInstance.destroy(); + if (this.flickityConfig["cellSelector"]) { + Array.from(this.children).sort((a, b) => parseInt(a.getAttribute("data-original-position")) > parseInt(b.getAttribute("data-original-position")) ? 1 : -1).forEach((node) => this.appendChild(node)); + } + this._createFlickity(); + } + async _createFlickity() { + this.flickity = new Promise(async (resolve) => { + await LibraryLoader.load("flickity"); + await this.untilVisible({ rootMargin: "400px", threshold: 0 }); + const flickityInstance = new window.ThemeFlickity(this, { ...this.flickityConfig, ...{ + rightToLeft: window.themeVariables.settings.direction === "rtl", + accessibility: MediaFeatures.supportsHover(), + // Flickity cause the carousel to scroll when focused, which is annoying on mobile + on: { + ready: (event) => triggerEvent(this, "flickity:ready", event), + change: (event) => triggerEvent(this, "flickity:slide-changed", event), + settle: (event) => triggerEvent(this, "flickity:slide-settled", event) + } + } }); + resolve(flickityInstance); + }); + if (this.hasAttribute("click-nav")) { + const flickityInstance = await this.flickityInstance; + flickityInstance.on("staticClick", this._onStaticClick.bind(this)); + this.addEventListener("mousemove", this._onMouseMove.bind(this)); + } + } + /** + * If the "click-nav" option is passed, desktop device can switch from one slide to the other + */ + async _onStaticClick(event, pointer, cellElement) { + const flickityInstance = await this.flickityInstance, isVideoOrModelType = flickityInstance.selectedElement.hasAttribute("data-media-type") && ["video", "external_video", "model"].includes(flickityInstance.selectedElement.getAttribute("data-media-type")); + if (!cellElement || isVideoOrModelType || window.matchMedia(window.themeVariables.breakpoints.phone).matches) { + return; + } + const flickityViewport = flickityInstance.viewport, boundingRect = flickityViewport.getBoundingClientRect(), halfEdge = Math.floor(boundingRect.right - boundingRect.width / 2); + if (pointer.clientX > halfEdge) { + flickityInstance.next(); + } else { + flickityInstance.previous(); + } + } + /** + * Add the class "is-hovering-right" or "is-hovering-left" depending on the part we're hovering + */ + async _onMouseMove(event) { + const flickityInstance = await this.flickityInstance, isVideoOrModelType = flickityInstance.selectedElement.hasAttribute("data-media-type") && ["video", "external_video", "model"].includes(flickityInstance.selectedElement.getAttribute("data-media-type")); + this.classList.toggle("is-hovering-right", event.offsetX > this.clientWidth / 2 && !isVideoOrModelType); + this.classList.toggle("is-hovering-left", event.offsetX <= this.clientWidth / 2 && !isVideoOrModelType); + } + /** + * To give a feeling of faster browsing, we always preload the next image once we settle on a slide + */ + async _preloadNextImage() { + const flickityInstance = await this.flickity; + if (flickityInstance.selectedElement.nextElementSibling) { + flickityInstance.selectedElement.nextElementSibling.querySelector("img")?.setAttribute("loading", "eager"); + } + } +}; +window.customElements.define("flickity-carousel", FlickityCarousel); + +// js/helper/dom.js +function getSiblings(element, filter, includeSelf = false) { + let siblings = []; + let currentElement = element; + while (currentElement = currentElement.previousElementSibling) { + if (!filter || currentElement.matches(filter)) { + siblings.push(currentElement); + } + } + if (includeSelf) { + siblings.push(element); + } + currentElement = element; + while (currentElement = currentElement.nextElementSibling) { + if (!filter || currentElement.matches(filter)) { + siblings.push(currentElement); + } + } + return siblings; +} +async function resolveAsyncIterator(target) { + const processedTarget = []; + if (!(target != null && typeof target[Symbol.iterator] === "function")) { + target = [target]; + } + for (const targetItem of target) { + if (typeof targetItem[Symbol.asyncIterator] === "function") { + for await (const awaitTarget of targetItem) { + processedTarget.push(awaitTarget); + } + } else { + processedTarget.push(targetItem); + } + } + return processedTarget; +} + +// js/custom-element/ui/flickity-controls.js +var FlickityControls = class extends CustomHTMLElement { + async connectedCallback() { + this.flickityCarousel.addEventListener("flickity:ready", this._onSlideChanged.bind(this, false)); + this.flickityCarousel.addEventListener("flickity:slide-changed", this._onSlideChanged.bind(this, true)); + this.delegate.on("click", '[data-action="prev"]', () => this.flickityCarousel.previous()); + this.delegate.on("click", '[data-action="next"]', () => this.flickityCarousel.next()); + this.delegate.on("click", '[data-action="select"]', (event, target) => this.flickityCarousel.select(`#${target.getAttribute("aria-controls")}`)); + } + get flickityCarousel() { + return this._flickityCarousel = this._flickityCarousel || document.getElementById(this.getAttribute("controls")); + } + async _onSlideChanged(animate = true) { + let flickityInstance = await this.flickityCarousel.flickityInstance, activeItems = Array.from(this.querySelectorAll(`[aria-controls="${flickityInstance.selectedElement.id}"]`)); + activeItems.forEach((activeItem) => { + activeItem.setAttribute("aria-current", "true"); + getSiblings(activeItem).forEach((sibling) => sibling.removeAttribute("aria-current")); + requestAnimationFrame(() => { + if (activeItem.offsetParent && activeItem.offsetParent !== this) { + const windowHalfHeight = activeItem.offsetParent.clientHeight / 2, windowHalfWidth = activeItem.offsetParent.clientWidth / 2; + activeItem.offsetParent.scrollTo({ + behavior: animate ? "smooth" : "auto", + top: activeItem.offsetTop - windowHalfHeight + activeItem.clientHeight / 2, + left: activeItem.offsetLeft - windowHalfWidth + activeItem.clientWidth / 2 + }); + } + }); + }); + } +}; +window.customElements.define("flickity-controls", FlickityControls); + +// js/custom-element/ui/external-video.js +var ExternalVideo = class extends CustomHTMLElement { + /** + * This must be done in the constructor and not connectedCallback because the element will be re-added + * at run-time by Flickity + */ + constructor() { + super(); + this.hasLoaded = false; + (async () => { + if (this.autoPlay) { + await this.untilVisible({ rootMargin: "300px", threshold: 0 }); + this.play(); + } else { + this.addEventListener("click", this.play.bind(this), { once: true }); + } + })(); + } + get autoPlay() { + return this.hasAttribute("autoplay"); + } + get provider() { + return this.getAttribute("provider"); + } + async play() { + if (!this.hasLoaded) { + await this._setupPlayer(); + } + if (this.provider === "youtube") { + setTimeout(() => { + this.querySelector("iframe").contentWindow.postMessage(JSON.stringify({ event: "command", func: "playVideo", args: "" }), "*"); + }, 150); + } else if (this.provider === "vimeo") { + this.querySelector("iframe").contentWindow.postMessage(JSON.stringify({ method: "play" }), "*"); + } + } + pause() { + if (!this.hasLoaded) { + return; + } + if (this.provider === "youtube") { + this.querySelector("iframe").contentWindow.postMessage(JSON.stringify({ event: "command", func: "pauseVideo", args: "" }), "*"); + } else if (this.provider === "vimeo") { + this.querySelector("iframe").contentWindow.postMessage(JSON.stringify({ method: "pause" }), "*"); + } + } + _setupPlayer() { + if (this._setupPromise) { + return this._setupPromise; + } + return this._setupPromise = new Promise((resolve) => { + const template2 = this.querySelector("template"), node = template2.content.firstElementChild.cloneNode(true); + node.onload = () => { + this.hasLoaded = true; + resolve(); + }; + if (this.autoPlay) { + template2.replaceWith(node); + } else { + this.innerHTML = ""; + this.appendChild(node); + } + }); + } +}; +window.customElements.define("external-video", ExternalVideo); + +// js/helper/product-loader.js +var ProductLoader = class { + static load(productHandle) { + if (!productHandle) { + return; + } + if (this.loadedProducts[productHandle]) { + return this.loadedProducts[productHandle]; + } + this.loadedProducts[productHandle] = new Promise(async (resolve) => { + const response = await fetch(`${window.themeVariables.routes.rootUrlWithoutSlash}/products/${productHandle}.js`); + const responseAsJson = await response.json(); + resolve(responseAsJson); + }); + return this.loadedProducts[productHandle]; + } +}; +__publicField(ProductLoader, "loadedProducts", {}); + +// js/custom-element/ui/model-media.js +var ModelMedia = class extends HTMLElement { + /** + * This must be done in the constructor and not connectedCallback because the element will be re-added + * at run-time by Flickity + */ + constructor() { + super(); + LibraryLoader.load("modelViewerUiStyles"); + window.Shopify.loadFeatures([ + { + name: "shopify-xr", + version: "1.0", + onLoad: this._setupShopifyXr.bind(this) + }, + { + name: "model-viewer-ui", + version: "1.0", + onLoad: () => { + this.modelUi = new window.Shopify.ModelViewerUI(this.firstElementChild, { focusOnPlay: false }); + const modelViewer = this.querySelector("model-viewer"); + modelViewer.addEventListener("shopify_model_viewer_ui_toggle_play", () => { + modelViewer.dispatchEvent(new CustomEvent("model:played", { bubbles: true })); + }); + modelViewer.addEventListener("shopify_model_viewer_ui_toggle_pause", () => { + modelViewer.dispatchEvent(new CustomEvent("model:paused", { bubbles: true })); + }); + } + } + ]); + } + disconnectedCallback() { + this.modelUi?.destroy(); + } + play() { + if (this.modelUi) { + this.modelUi.play(); + } + } + pause() { + if (this.modelUi) { + this.modelUi.pause(); + } + } + async _setupShopifyXr() { + if (!window.ShopifyXR) { + document.addEventListener("shopify_xr_initialized", this._setupShopifyXr.bind(this)); + } else { + const product = await ProductLoader.load(this.getAttribute("product-handle")); + const models = product["media"].filter((media) => media["media_type"] === "model"); + window.ShopifyXR.addModels(models); + window.ShopifyXR.setupXRElements(); + } + } +}; +window.customElements.define("model-media", ModelMedia); + +// js/custom-element/ui/native-video.js +var NativeVideo = class extends HTMLElement { + /** + * This must be done in the constructor and not connectedCallback because the element will be re-added + * at run-time by Flickity + */ + constructor() { + super(); + this.hasLoaded = false; + if (this.autoPlay) { + this.play(); + } else { + this.addEventListener("click", this.play.bind(this), { once: true }); + } + } + get autoPlay() { + return this.hasAttribute("autoplay"); + } + play() { + if (!this.hasLoaded) { + this._replaceContent(); + } + this.querySelector("video").play(); + } + pause() { + if (this.hasLoaded) { + this.querySelector("video").pause(); + } + } + _replaceContent() { + let node = this.querySelector("template"); + if (!node) { + return; + } + node = node.content.firstElementChild.cloneNode(true); + if (!this.hasAttribute("autoplay")) { + this.innerHTML = ""; + } + this.appendChild(node); + this.firstElementChild.addEventListener("play", () => { + this.dispatchEvent(new CustomEvent("video:played", { bubbles: true })); + }); + this.firstElementChild.addEventListener("pause", () => { + this.dispatchEvent(new CustomEvent("video:paused", { bubbles: true })); + }); + this.hasLoaded = true; + } +}; +window.customElements.define("native-video", NativeVideo); + +// js/custom-element/ui/combo-box.js +var ComboBox = class extends OpenableElement { + connectedCallback() { + super.connectedCallback(); + this.options = Array.from(this.querySelectorAll('[role="option"]')); + this.delegate.on("click", '[role="option"]', this._onValueClicked.bind(this)); + this.delegate.on("keydown", '[role="listbox"]', this._onKeyDown.bind(this)); + this.delegate.on("change", "select", this._onValueChanged.bind(this)); + this.delegate.on("click", ".combo-box__overlay", () => this.open = false); + if (this.hasAttribute("fit-toggle")) { + const maxWidth = Math.max(...this.options.map((item) => item.clientWidth)), control = document.querySelector(`[aria-controls="${this.id}"]`); + if (control) { + control.style.setProperty("--largest-option-width", `${maxWidth + 2}px`); + } + } + } + get nativeSelect() { + return this.querySelector("select"); + } + set selectedValue(value) { + this.options.forEach((option) => { + option.setAttribute("aria-selected", option.getAttribute("value") === value ? "true" : "false"); + }); + } + attributeChangedCallback(name, oldValue, newValue) { + super.attributeChangedCallback(name, oldValue, newValue); + switch (name) { + case "open": + if (this.open) { + const boundingRect = this.getBoundingClientRect(); + this.classList.toggle("combo-box--top", boundingRect.top >= window.innerHeight / 2 * 1.5); + setTimeout(() => this.focusTrap.activate(), 150); + } else { + this.focusTrap.deactivate(); + setTimeout(() => this.classList.remove("combo-box--top"), 200); + } + document.documentElement.classList.toggle("lock-mobile", this.open); + } + } + // Called when the option of the custom select is clicked + _onValueClicked(event, target) { + this.selectedValue = target.value; + this.nativeSelect.value = target.value; + this.nativeSelect.dispatchEvent(new Event("change", { bubbles: true })); + this.open = false; + } + // Called when the option of the underlying native select is changed (for instance by external code) + _onValueChanged(event, target) { + Array.from(this.nativeSelect.options).forEach((option) => option.toggleAttribute("selected", target.value === option.value)); + this.selectedValue = target.value; + } + // Improves accessibility with arrow up/down + _onKeyDown(event) { + if (event.key === "ArrowDown" || event.key === "ArrowUp") { + event.preventDefault(); + if (event.key === "ArrowDown") { + document.activeElement.nextElementSibling?.focus(); + } else { + document.activeElement.previousElementSibling?.focus(); + } + } + } +}; +window.customElements.define("combo-box", ComboBox); + +// js/custom-element/ui/quantity-selector.js +var QuantitySelector = class extends CustomHTMLElement { + connectedCallback() { + this.inputElement = this.querySelector("input"); + this.delegate.on("click", "button:first-child", () => this.inputElement.quantity = this.inputElement.quantity - 1); + this.delegate.on("click", "button:last-child", () => this.inputElement.quantity = this.inputElement.quantity + 1); + } +}; +window.customElements.define("quantity-selector", QuantitySelector); + +// js/custom-element/ui/input-number.js +var InputNumber = class extends HTMLInputElement { + connectedCallback() { + this.addEventListener("input", this._onValueInput.bind(this)); + this.addEventListener("change", this._onValueChanged.bind(this)); + this.addEventListener("keydown", this._onKeyDown.bind(this)); + } + get quantity() { + return parseInt(this.value); + } + set quantity(quantity) { + const isNumeric = (typeof quantity === "number" || typeof quantity === "string" && quantity.trim() !== "") && !isNaN(quantity); + if (quantity === "") { + return; + } + if (!isNumeric || quantity < 0) { + quantity = parseInt(quantity) || 1; + } + this.value = Math.max(this.min || 1, Math.min(quantity, this.max || Number.MAX_VALUE)).toString(); + this.size = Math.max(this.value.length + 1, 2); + } + _onValueInput() { + this.quantity = this.value; + } + _onValueChanged() { + if (this.value === "") { + this.quantity = 1; + } + } + _onKeyDown(event) { + event.stopPropagation(); + if (event.key === "ArrowUp") { + this.quantity = this.quantity + 1; + } else if (event.key === "ArrowDown") { + this.quantity = this.quantity - 1; + } + } +}; +window.customElements.define("input-number", InputNumber, { extends: "input" }); + +// js/custom-element/section/announcement-bar/announcement-bar.js +var AnnouncementBar = class extends CustomHTMLElement { + async connectedCallback() { + await customElements.whenDefined("announcement-bar-item"); + this.items = Array.from(this.querySelectorAll("announcement-bar-item")); + this.hasPendingTransition = false; + this.delegate.on("click", '[data-action="prev"]', this.previous.bind(this)); + this.delegate.on("click", '[data-action="next"]', this.next.bind(this)); + if (this.autoPlay) { + this.delegate.on("announcement-bar:content:open", this._pausePlayer.bind(this)); + this.delegate.on("announcement-bar:content:close", this._startPlayer.bind(this)); + } + if (window.ResizeObserver) { + this.resizeObserver = new ResizeObserver(this._updateCustomProperties.bind(this)); + this.resizeObserver.observe(this); + } + if (this.autoPlay) { + this._startPlayer(); + } + if (Shopify.designMode) { + this.delegate.on("shopify:block:select", (event) => this.select(event.target.index, false)); + } + } + get autoPlay() { + return this.hasAttribute("auto-play"); + } + get selectedIndex() { + return this.items.findIndex((item) => item.selected); + } + previous() { + this.select((this.selectedIndex - 1 + this.items.length) % this.items.length); + } + next() { + this.select((this.selectedIndex + 1 + this.items.length) % this.items.length); + } + async select(index, animate = true) { + if (this.selectedIndex === index || this.hasPendingTransition) { + return; + } + if (this.autoPlay) { + this._pausePlayer(); + } + this.hasPendingTransition = true; + await this.items[this.selectedIndex].deselect(animate); + await this.items[index].select(animate); + this.hasPendingTransition = false; + if (this.autoPlay) { + this._startPlayer(); + } + } + _pausePlayer() { + clearInterval(this._interval); + } + _startPlayer() { + clearInterval(this._interval); + this._interval = setInterval(this.next.bind(this), parseInt(this.getAttribute("cycle-speed")) * 1e3); + } + _updateCustomProperties(entries) { + entries.forEach((entry) => { + if (entry.target === this) { + const height = entry.borderBoxSize ? entry.borderBoxSize.length > 0 ? entry.borderBoxSize[0].blockSize : entry.borderBoxSize.blockSize : entry.target.clientHeight; + document.documentElement.style.setProperty("--announcement-bar-height", `${height}px`); + } + }); + } +}; +window.customElements.define("announcement-bar", AnnouncementBar); + +// js/custom-element/section/announcement-bar/item.js +var AnnouncementBarItem = class extends CustomHTMLElement { + connectedCallback() { + if (this.hasContent) { + this.contentElement = this.querySelector(".announcement-bar__content"); + this.delegate.on("click", '[data-action="open-content"]', this.openContent.bind(this)); + this.delegate.on("click", '[data-action="close-content"]', this.closeContent.bind(this)); + if (Shopify.designMode) { + this.addEventListener("shopify:block:select", this.openContent.bind(this)); + this.addEventListener("shopify:block:deselect", this.closeContent.bind(this)); + } + } + } + get index() { + return [...this.parentNode.children].indexOf(this); + } + get hasContent() { + return this.hasAttribute("has-content"); + } + get selected() { + return !this.hasAttribute("hidden"); + } + get focusTrap() { + return this._trapFocus = this._trapFocus || createFocusTrap(this.contentElement.querySelector(".announcement-bar__content-inner"), { + fallbackFocus: this, + clickOutsideDeactivates: (event) => !(event.target.tagName === "BUTTON"), + allowOutsideClick: (event) => event.target.tagName === "BUTTON", + onDeactivate: this.closeContent.bind(this), + preventScroll: true + }); + } + async select(animate = true) { + this.removeAttribute("hidden"); + await new Promise((resolve) => { + this.animate({ + transform: ["translateY(8px)", "translateY(0)"], + opacity: [0, 1] + }, { + duration: animate ? 150 : 0, + easing: "ease-in-out" + }).onfinish = resolve; + }); + } + async deselect(animate = true) { + await this.closeContent(); + await new Promise((resolve) => { + this.animate({ + transform: ["translateY(0)", "translateY(-8px)"], + opacity: [1, 0] + }, { + duration: animate ? 150 : 0, + easing: "ease-in-out" + }).onfinish = resolve; + }); + this.setAttribute("hidden", ""); + } + async openContent() { + if (this.hasContent) { + this.contentElement.addEventListener("transitionend", () => this.focusTrap.activate(), { once: true }); + this.contentElement.removeAttribute("hidden"); + document.documentElement.classList.add("lock-all"); + this.dispatchEvent(new CustomEvent("announcement-bar:content:open", { bubbles: true })); + } + } + async closeContent() { + if (!this.hasContent || this.contentElement.hasAttribute("hidden")) { + return Promise.resolve(); + } + await new Promise((resolve) => { + this.contentElement.addEventListener("transitionend", () => resolve(), { once: true }); + this.contentElement.setAttribute("hidden", ""); + this.focusTrap.deactivate(); + document.documentElement.classList.remove("lock-all"); + this.dispatchEvent(new CustomEvent("announcement-bar:content:close", { bubbles: true })); + }); + } +}; +window.customElements.define("announcement-bar-item", AnnouncementBarItem); + +// js/custom-element/section/search/search-page.js +var SearchPage = class extends HTMLElement { + connectedCallback() { + this.facetToolbar = document.getElementById("mobile-facet-toolbar"); + this.tabsNav = document.getElementById("search-tabs-nav"); + this.tabsNav.addEventListener("tabs-nav:changed", this._onCategoryChanged.bind(this)); + this._completeSearch(); + } + get terms() { + return this.getAttribute("terms"); + } + get completeFor() { + return this.getAttribute("complete-for").split(","); + } + async _completeSearch() { + const promisesList = []; + this.completeFor.forEach((item) => { + promisesList.push(fetch(`${window.themeVariables.routes.searchUrl}?section_id=${this.getAttribute("section-id")}&q=${this.terms}&type=${item}&options[prefix]=last&options[unavailable_products]=${window.themeVariables.settings.searchUnavailableProducts}`)); + }); + const responses = await Promise.all(promisesList); + await Promise.all(responses.map(async (response) => { + const div = document.createElement("div"); + div.innerHTML = await response.text(); + const categoryResultDiv = div.querySelector(".main-search__category-result"), tabNavItem = div.querySelector("#search-tabs-nav .tabs-nav__item"); + if (categoryResultDiv) { + categoryResultDiv.setAttribute("hidden", ""); + this.insertAdjacentElement("beforeend", categoryResultDiv); + this.tabsNav.addButton(tabNavItem); + } + })); + } + _onCategoryChanged(event) { + const button = event.detail.button; + this.facetToolbar.classList.toggle("is-collapsed", button.getAttribute("data-type") !== "product"); + } +}; +window.customElements.define("search-page", SearchPage); + +// js/custom-element/section/footer/cookie-bar.js +var CookieBar = class extends CustomHTMLElement { + connectedCallback() { + if (window.Shopify && window.Shopify.designMode) { + this.rootDelegate.on("shopify:section:select", (event) => filterShopifyEvent(event, this, () => this.open = true)); + this.rootDelegate.on("shopify:section:deselect", (event) => filterShopifyEvent(event, this, () => this.open = false)); + } + this.delegate.on("click", '[data-action~="accept-policy"]', this._acceptPolicy.bind(this)); + this.delegate.on("click", '[data-action~="decline-policy"]', this._declinePolicy.bind(this)); + window.Shopify.loadFeatures([{ + name: "consent-tracking-api", + version: "0.1", + onLoad: this._onCookieBarSetup.bind(this) + }]); + } + set open(value) { + this.toggleAttribute("hidden", !value); + } + _onCookieBarSetup() { + if (window.Shopify.customerPrivacy.shouldShowGDPRBanner()) { + this.open = true; + } + } + _acceptPolicy() { + window.Shopify.customerPrivacy.setTrackingConsent(true, () => this.open = false); + } + _declinePolicy() { + window.Shopify.customerPrivacy.setTrackingConsent(false, () => this.open = false); + } +}; +window.customElements.define("cookie-bar", CookieBar); + +// js/custom-element/section/product-recommendations/product-recommendations.js +var ProductRecommendations = class extends HTMLElement { + async connectedCallback() { + const response = await fetch(`${window.themeVariables.routes.productRecommendationsUrl}?product_id=${this.productId}&limit=${this.recommendationsCount}§ion_id=${this.sectionId}&intent=${this.intent}`); + const div = document.createElement("div"); + div.innerHTML = await response.text(); + const productRecommendationsElement = div.querySelector("product-recommendations"); + if (productRecommendationsElement.hasChildNodes()) { + this.innerHTML = productRecommendationsElement.innerHTML; + } else { + if (this.intent === "complementary") { + this.remove(); + } + } + } + get productId() { + return this.getAttribute("product-id"); + } + get sectionId() { + return this.getAttribute("section-id"); + } + get recommendationsCount() { + return parseInt(this.getAttribute("recommendations-count") || 4); + } + get intent() { + return this.getAttribute("intent"); + } +}; +window.customElements.define("product-recommendations", ProductRecommendations); + +// js/custom-element/section/product-recommendations/recently-viewed-products.js +var RecentlyViewedProducts = class extends HTMLElement { + async connectedCallback() { + if (this.searchQueryString === "") { + return; + } + const response = await fetch(`${window.themeVariables.routes.searchUrl}?type=product&q=${this.searchQueryString}§ion_id=${this.sectionId}`); + const div = document.createElement("div"); + div.innerHTML = await response.text(); + const recentlyViewedProductsElement = div.querySelector("recently-viewed-products"); + if (recentlyViewedProductsElement.hasChildNodes()) { + this.innerHTML = recentlyViewedProductsElement.innerHTML; + } + } + get searchQueryString() { + const items = JSON.parse(localStorage.getItem("theme:recently-viewed-products") || "[]"); + if (this.hasAttribute("exclude-product-id") && items.includes(parseInt(this.getAttribute("exclude-product-id")))) { + items.splice(items.indexOf(parseInt(this.getAttribute("exclude-product-id"))), 1); + } + return items.map((item) => "id:" + item).slice(0, this.productsCount).join(" OR "); + } + get sectionId() { + return this.getAttribute("section-id"); + } + get productsCount() { + return this.getAttribute("products-count") || 4; + } +}; +window.customElements.define("recently-viewed-products", RecentlyViewedProducts); + +// js/helper/image.js +function getSizedMediaUrl(media, size) { + let src = typeof media === "string" ? media : media["preview_image"] ? media["preview_image"]["src"] : media["url"]; + if (size === null) { + return src; + } + if (size === "master") { + return src.replace(/http(s)?:/, ""); + } + const match = src.match(/\.(jpg|jpeg|gif|png|bmp|bitmap|tiff|tif|webp)(\?v=\d+)?$/i); + if (match) { + const prefix = src.split(match[0]); + const suffix = match[0]; + return (prefix[0] + "_" + size + suffix).replace(/http(s)?:/, ""); + } else { + return null; + } +} +function getMediaSrcset(media, sizeList) { + let srcset = [], supportedSizes = typeof media === "string" ? sizeList : getSupportedSizes(media, sizeList); + supportedSizes.forEach((supportedSize) => { + srcset.push(`${getSizedMediaUrl(media, supportedSize + "x")} ${supportedSize}w`); + }); + return srcset.join(","); +} +function getSupportedSizes(media, desiredSizes) { + let supportedSizes = [], mediaWidth = media["preview_image"]["width"]; + desiredSizes.forEach((width) => { + if (mediaWidth >= width) { + supportedSizes.push(width); + } + }); + return supportedSizes; +} +function imageLoaded(image) { + return new Promise((resolve) => { + if (!image || image.tagName !== "IMG" || image.complete) { + resolve(); + } else { + image.onload = () => resolve(); + } + }); +} + +// js/helper/animation.js +var CustomAnimation = class { + constructor(effect) { + this._effect = effect; + this._playState = "idle"; + this._finished = Promise.resolve(); + } + get finished() { + return this._finished; + } + get animationEffects() { + return this._effect instanceof CustomKeyframeEffect ? [this._effect] : this._effect.animationEffects; + } + cancel() { + this.animationEffects.forEach((animationEffect) => animationEffect.cancel()); + } + finish() { + this.animationEffects.forEach((animationEffect) => animationEffect.finish()); + } + play() { + this._playState = "running"; + this._effect.play(); + this._finished = this._effect.finished; + this._finished.then(() => { + this._playState = "finished"; + }, (rejection) => { + this._playState = "idle"; + }); + } +}; +var CustomKeyframeEffect = class { + constructor(target, keyframes, options = {}) { + if (!target) { + return; + } + if ("Animation" in window) { + this._animation = new Animation(new KeyframeEffect(target, keyframes, options)); + } else { + options["fill"] = "forwards"; + this._animation = target.animate(keyframes, options); + this._animation.pause(); + } + this._animation.addEventListener("finish", () => { + target.style.opacity = keyframes.hasOwnProperty("opacity") ? keyframes["opacity"][keyframes["opacity"].length - 1] : null; + target.style.visibility = keyframes.hasOwnProperty("visibility") ? keyframes["visibility"][keyframes["visibility"].length - 1] : null; + }); + } + get finished() { + if (!this._animation) { + return Promise.resolve(); + } + return this._animation.finished ? this._animation.finished : new Promise((resolve) => this._animation.onfinish = resolve); + } + play() { + if (this._animation) { + this._animation.startTime = null; + this._animation.play(); + } + } + cancel() { + if (this._animation) { + this._animation.cancel(); + } + } + finish() { + if (this._animation) { + this._animation.finish(); + } + } +}; +var GroupEffect = class { + constructor(childrenEffects) { + this._childrenEffects = childrenEffects; + this._finished = Promise.resolve(); + } + get finished() { + return this._finished; + } + get animationEffects() { + return this._childrenEffects.flatMap((effect) => { + return effect instanceof CustomKeyframeEffect ? effect : effect.animationEffects; + }); + } +}; +var ParallelEffect = class extends GroupEffect { + play() { + const promises = []; + for (const effect of this._childrenEffects) { + effect.play(); + promises.push(effect.finished); + } + this._finished = Promise.all(promises); + } +}; +var SequenceEffect = class extends GroupEffect { + play() { + this._finished = new Promise(async (resolve, reject) => { + try { + for (const effect of this._childrenEffects) { + effect.play(); + await effect.finished; + } + resolve(); + } catch (exception) { + reject(); + } + }); + } +}; + +// js/custom-element/section/slideshow/slideshow-item.js +var SlideshowItem = class extends HTMLElement { + async connectedCallback() { + this._pendingAnimations = []; + this.addEventListener("split-lines:re-split", (event) => { + Array.from(event.target.children).forEach((line) => line.style.visibility = this.selected ? "visible" : "hidden"); + }); + if (MediaFeatures.prefersReducedMotion()) { + this.setAttribute("reveal-visibility", ""); + Array.from(this.querySelectorAll("[reveal], [reveal-visibility]")).forEach((item) => { + item.removeAttribute("reveal"); + item.removeAttribute("reveal-visibility"); + }); + } + } + get index() { + return [...this.parentNode.children].indexOf(this); + } + get selected() { + return !this.hasAttribute("hidden"); + } + async transitionToLeave(transitionType, shouldAnimate = true) { + if (transitionType !== "reveal") { + this.setAttribute("hidden", ""); + } + this._pendingAnimations.forEach((animation2) => animation2.cancel()); + this._pendingAnimations = []; + let animation = null, textElements = await resolveAsyncIterator(this.querySelectorAll("split-lines, .button-group, .button-wrapper")), imageElements = Array.from(this.querySelectorAll(".slideshow__image-wrapper")); + switch (transitionType) { + case "sweep": + animation = new CustomAnimation(new SequenceEffect([ + new CustomKeyframeEffect(this, { visibility: ["visible", "hidden"] }, { duration: 500 }), + new ParallelEffect(textElements.map((item) => { + return new CustomKeyframeEffect(item, { opacity: [1, 0], visibility: ["visible", "hidden"] }); + })) + ])); + break; + case "fade": + animation = new CustomAnimation(new CustomKeyframeEffect(this, { opacity: [1, 0], visibility: ["visible", "hidden"] }, { duration: 250, easing: "ease-in-out" })); + break; + case "reveal": + animation = new CustomAnimation(new SequenceEffect([ + new ParallelEffect(textElements.reverse().map((item) => { + return new CustomKeyframeEffect(item, { opacity: [1, 0], visibility: ["visible", "hidden"] }, { duration: 250, easing: "ease-in-out" }); + })), + new ParallelEffect(imageElements.map((item) => { + if (!item.classList.contains("slideshow__image-wrapper--secondary")) { + return new CustomKeyframeEffect(item, { visibility: ["visible", "hidden"], clipPath: ["inset(0 0 0 0)", "inset(0 0 100% 0)"] }, { duration: 450, easing: "cubic-bezier(0.99, 0.01, 0.50, 0.94)" }); + } else { + return new CustomKeyframeEffect(item, { visibility: ["visible", "hidden"], clipPath: ["inset(0 0 0 0)", "inset(100% 0 0 0)"] }, { duration: 450, easing: "cubic-bezier(0.99, 0.01, 0.50, 0.94)" }); + } + })) + ])); + break; + } + await this._executeAnimation(animation, shouldAnimate); + if (transitionType === "reveal") { + this.setAttribute("hidden", ""); + } + } + async transitionToEnter(transitionType, shouldAnimate = true, reverseDirection = false) { + this.removeAttribute("hidden"); + await this._untilReady(); + let animation = null, textElements = await resolveAsyncIterator(this.querySelectorAll("split-lines, .button-group, .button-wrapper")), imageElements = Array.from(this.querySelectorAll(".slideshow__image-wrapper")); + switch (transitionType) { + case "sweep": + animation = new CustomAnimation(new SequenceEffect([ + new CustomKeyframeEffect(this, { visibility: ["hidden", "visible"], clipPath: reverseDirection ? ["inset(0 100% 0 0)", "inset(0 0 0 0)"] : ["inset(0 0 0 100%)", "inset(0 0 0 0)"] }, { duration: 500, easing: "cubic-bezier(1, 0, 0, 1)" }), + new ParallelEffect(textElements.map((item, index) => { + return new CustomKeyframeEffect(item, { opacity: [0, 1], visibility: ["hidden", "visible"], clipPath: ["inset(0 0 100% 0)", "inset(0 0 0 0)"], transform: ["translateY(100%)", "translateY(0)"] }, { duration: 450, delay: 100 * index, easing: "cubic-bezier(0.5, 0.06, 0.01, 0.99)" }); + })) + ])); + break; + case "fade": + animation = new CustomAnimation(new CustomKeyframeEffect(this, { opacity: [0, 1], visibility: ["hidden", "visible"] }, { duration: 250, easing: "ease-in-out" })); + break; + case "reveal": + animation = new CustomAnimation(new SequenceEffect([ + new ParallelEffect(imageElements.map((item) => { + if (!item.classList.contains("slideshow__image-wrapper--secondary")) { + return new CustomKeyframeEffect(item, { visibility: ["hidden", "visible"], clipPath: ["inset(0 0 100% 0)", "inset(0 0 0 0)"] }, { duration: 450, delay: 100, easing: "cubic-bezier(0.5, 0.06, 0.01, 0.99)" }); + } else { + return new CustomKeyframeEffect(item, { visibility: ["hidden", "visible"], clipPath: ["inset(100% 0 0 0)", "inset(0 0 0 0)"] }, { duration: 450, delay: 100, easing: "cubic-bezier(0.5, 0.06, 0.01, 0.99)" }); + } + })), + new ParallelEffect(textElements.map((item, index) => { + return new CustomKeyframeEffect(item, { opacity: [0, 1], visibility: ["hidden", "visible"], clipPath: ["inset(0 0 100% 0)", "inset(0 0 0 0)"], transform: ["translateY(100%)", "translateY(0)"] }, { duration: 450, delay: 100 * index, easing: "cubic-bezier(0.5, 0.06, 0.01, 0.99)" }); + })) + ])); + break; + } + return this._executeAnimation(animation, shouldAnimate); + } + async _executeAnimation(animation, shouldAnimate) { + this._pendingAnimations.push(animation); + shouldAnimate ? animation.play() : animation.finish(); + return animation.finished; + } + async _untilReady() { + return Promise.all(this._getVisibleImages().map((image) => imageLoaded(image))); + } + _preloadImages() { + this._getVisibleImages().forEach((image) => { + image.setAttribute("loading", "eager"); + }); + } + _getVisibleImages() { + return Array.from(this.querySelectorAll("img")).filter((image) => { + return getComputedStyle(image.parentElement).display !== "none"; + }); + } +}; +window.customElements.define("slide-show-item", SlideshowItem); + +// js/mixin/vertical-scroll-blocker.js +var VerticalScrollBlockerMixin = { + _blockVerticalScroll(threshold = 18) { + this.addEventListener("touchstart", (event) => { + this.firstTouchClientX = event.touches[0].clientX; + }); + this.addEventListener("touchmove", (event) => { + const touchClientX = event.touches[0].clientX - this.firstTouchClientX; + if (Math.abs(touchClientX) > threshold) { + event.preventDefault(); + } + }, { passive: false }); + } +}; + +// js/custom-element/section/slideshow/slideshow.js +var Slideshow = class extends CustomHTMLElement { + connectedCallback() { + this.items = Array.from(this.querySelectorAll("slide-show-item")); + this.pageDots = this.querySelector("page-dots"); + this.isTransitioning = false; + if (this.items.length > 1) { + if (Shopify.designMode) { + this.addEventListener("shopify:block:deselect", this.startPlayer.bind(this)); + this.addEventListener("shopify:block:select", (event) => { + this.pausePlayer(); + this.intersectionObserver.disconnect(); + if (!(!event.detail.load && event.target.selected)) { + this.select(event.target.index, !event.detail.load); + } + }); + } + this.addEventListener("swiperight", this.previous.bind(this)); + this.addEventListener("swipeleft", this.next.bind(this)); + this.addEventListener("page-dots:changed", (event) => this.select(event.detail.index)); + this._blockVerticalScroll(); + } + this._setupVisibility(); + } + get selectedIndex() { + return this.items.findIndex((item) => item.selected); + } + get transitionType() { + return MediaFeatures.prefersReducedMotion() ? "fade" : this.getAttribute("transition-type"); + } + async _setupVisibility() { + await this.untilVisible(); + await this.items[this.selectedIndex].transitionToEnter(this.transitionType).catch((error) => { + }); + this.startPlayer(); + } + previous() { + this.select((this.selectedIndex - 1 + this.items.length) % this.items.length, true, true); + } + next() { + this.select((this.selectedIndex + 1 + this.items.length) % this.items.length, true, false); + } + async select(index, shouldTransition = true, reverseDirection = false) { + if (this.transitionType === "reveal" && this.isTransitioning) { + return; + } + this.isTransitioning = true; + const previousItem = this.items[this.selectedIndex], newItem = this.items[index]; + this.items[(newItem.index + 1) % this.items.length]._preloadImages(); + if (previousItem && previousItem !== newItem) { + if (this.transitionType !== "reveal") { + previousItem.transitionToLeave(this.transitionType, shouldTransition); + } else { + await previousItem.transitionToLeave(this.transitionType, shouldTransition); + } + } + if (this.pageDots) { + this.pageDots.selectedIndex = newItem.index; + } + await newItem.transitionToEnter(this.transitionType, shouldTransition, reverseDirection).catch((error) => { + }); + this.isTransitioning = false; + } + pausePlayer() { + this.style.setProperty("--section-animation-play-state", "paused"); + } + startPlayer() { + if (this.hasAttribute("auto-play")) { + this.style.setProperty("--section-animation-play-state", "running"); + } + } +}; +Object.assign(Slideshow.prototype, VerticalScrollBlockerMixin); +window.customElements.define("slide-show", Slideshow); + +// js/custom-element/section/image-with-text/image-with-text-item.js +var ImageWithTextItem = class extends HTMLElement { + get index() { + return [...this.parentNode.children].indexOf(this); + } + get selected() { + return !this.hasAttribute("hidden"); + } + get hasAttachedImage() { + return this.hasAttribute("attached-image"); + } + async transitionToEnter(shouldAnimate = true) { + this.removeAttribute("hidden"); + const textWrapper = this.querySelector(".image-with-text__text-wrapper"), headings = await resolveAsyncIterator(this.querySelectorAll(".image-with-text__content split-lines")); + const animation = new CustomAnimation(new SequenceEffect([ + new ParallelEffect(headings.map((item, index) => { + return new CustomKeyframeEffect(item, { + opacity: [0, 0.2, 1], + transform: ["translateY(100%)", "translateY(0)"], + clipPath: ["inset(0 0 100% 0)", "inset(0 0 0 0)"] + }, { + duration: 350, + delay: 120 * index, + easing: "cubic-bezier(0.5, 0.06, 0.01, 0.99)" + }); + })), + new CustomKeyframeEffect(textWrapper, { opacity: [0, 1] }, { duration: 300 }) + ])); + shouldAnimate ? animation.play() : animation.finish(); + return animation.finished; + } + async transitionToLeave(shouldAnimate = true) { + const elements = await resolveAsyncIterator(this.querySelectorAll(".image-with-text__text-wrapper, .image-with-text__content split-lines")); + const animation = new CustomAnimation(new ParallelEffect(elements.map((item) => { + return new CustomKeyframeEffect(item, { opacity: [1, 0] }, { duration: 200 }); + }))); + shouldAnimate ? animation.play() : animation.finish(); + await animation.finished; + this.setAttribute("hidden", ""); + } +}; +window.customElements.define("image-with-text-item", ImageWithTextItem); + +// js/custom-element/section/image-with-text/image-with-text.js +var ImageWithText = class extends CustomHTMLElement { + connectedCallback() { + this.items = Array.from(this.querySelectorAll("image-with-text-item")); + this.imageItems = Array.from(this.querySelectorAll(".image-with-text__image")); + this.pageDots = this.querySelector("page-dots"); + this.hasPendingTransition = false; + if (this.items.length > 1) { + this.addEventListener("page-dots:changed", (event) => this.select(event.detail.index)); + if (Shopify.designMode) { + this.addEventListener("shopify:block:deselect", this.startPlayer.bind(this)); + this.addEventListener("shopify:block:select", (event) => { + this.intersectionObserver.disconnect(); + this.pausePlayer(); + this.select(event.target.index, !event.detail.load); + }); + } + } + this._setupVisibility(); + } + async _setupVisibility() { + await this.untilVisible(); + if (this.hasAttribute("reveal-on-scroll")) { + await this.transitionImage(this.selectedIndex); + this.select(this.selectedIndex); + } + this.startPlayer(); + } + get selectedIndex() { + return this.items.findIndex((item) => item.selected); + } + async select(index, shouldAnimate = true) { + if (this.hasPendingTransition) { + return; + } + this.hasPendingTransition = true; + if (this.items[index].hasAttachedImage || !shouldAnimate) { + await this.transitionImage(index, shouldAnimate); + } + if (this.selectedIndex !== index) { + await this.items[this.selectedIndex].transitionToLeave(shouldAnimate); + } + if (this.pageDots) { + this.pageDots.selectedIndex = index; + } + await this.items[index].transitionToEnter(shouldAnimate); + this.hasPendingTransition = false; + } + async transitionImage(index, shouldAnimate = true) { + const activeImage = this.imageItems.find((item) => !item.hasAttribute("hidden")), nextImage = this.imageItems.find((item) => item.id === this.items[index].getAttribute("attached-image")) || activeImage; + activeImage.setAttribute("hidden", ""); + nextImage.removeAttribute("hidden"); + await imageLoaded(nextImage); + const animation = new CustomAnimation(new CustomKeyframeEffect(nextImage, { + visibility: ["hidden", "visible"], + clipPath: ["inset(0 0 0 100%)", "inset(0 0 0 0)"] + }, { + duration: 600, + easing: "cubic-bezier(1, 0, 0, 1)" + })); + shouldAnimate ? animation.play() : animation.finish(); + } + pausePlayer() { + this.style.setProperty("--section-animation-play-state", "paused"); + } + startPlayer() { + this.style.setProperty("--section-animation-play-state", "running"); + } +}; +window.customElements.define("image-with-text", ImageWithText); + +// js/custom-element/section/testimonials/testimonial-item.js +var TestimonialItem = class extends CustomHTMLElement { + connectedCallback() { + this.addEventListener("split-lines:re-split", (event) => { + Array.from(event.target.children).forEach((line) => line.style.visibility = this.selected ? "visible" : "hidden"); + }); + } + get index() { + return [...this.parentNode.children].indexOf(this); + } + get selected() { + return !this.hasAttribute("hidden"); + } + async transitionToLeave(shouldAnimate = true) { + const textLines = await resolveAsyncIterator(this.querySelectorAll("split-lines, .testimonial__author")), animation = new CustomAnimation(new ParallelEffect(textLines.reverse().map((item, index) => { + return new CustomKeyframeEffect(item, { + visibility: ["visible", "hidden"], + clipPath: ["inset(0 0 0 0)", "inset(0 0 100% 0)"], + transform: ["translateY(0)", "translateY(100%)"] + }, { + duration: 350, + delay: 60 * index, + easing: "cubic-bezier(0.68, 0.00, 0.77, 0.00)" + }); + }))); + shouldAnimate ? animation.play() : animation.finish(); + await animation.finished; + this.setAttribute("hidden", ""); + } + async transitionToEnter(shouldAnimate = true) { + const textLines = await resolveAsyncIterator(this.querySelectorAll("split-lines, .testimonial__author")), animation = new CustomAnimation(new ParallelEffect(textLines.map((item, index) => { + return new CustomKeyframeEffect(item, { + visibility: ["hidden", "visible"], + clipPath: ["inset(0 0 100% 0)", "inset(0 0 0px 0)"], + transform: ["translateY(100%)", "translateY(0)"] + }, { + duration: 550, + delay: 120 * index, + easing: "cubic-bezier(0.23, 1, 0.32, 1)" + }); + }))); + this.removeAttribute("hidden"); + shouldAnimate ? animation.play() : animation.finish(); + return animation.finished; + } +}; +window.customElements.define("testimonial-item", TestimonialItem); + +// js/custom-element/section/testimonials/testimonial-list.js +var TestimonialList = class extends CustomHTMLElement { + connectedCallback() { + this.items = Array.from(this.querySelectorAll("testimonial-item")); + this.pageDots = this.querySelector("page-dots"); + this.hasPendingTransition = false; + if (this.items.length > 1) { + this.addEventListener("swiperight", this.previous.bind(this)); + this.addEventListener("swipeleft", this.next.bind(this)); + this.addEventListener("prev-next:prev", this.previous.bind(this)); + this.addEventListener("prev-next:next", this.next.bind(this)); + this.addEventListener("page-dots:changed", (event) => this.select(event.detail.index)); + if (Shopify.designMode) { + this.addEventListener("shopify:block:select", (event) => { + this.intersectionObserver?.disconnect(); + if (event.detail.load || !event.target.selected) { + this.select(event.target.index, !event.detail.load); + } + }); + } + this._blockVerticalScroll(); + } + if (this.hasAttribute("reveal-on-scroll")) { + this._setupVisibility(); + } + } + get selectedIndex() { + return this.items.findIndex((item) => item.selected); + } + async _setupVisibility() { + await this.untilVisible(); + this.items[this.selectedIndex].transitionToEnter(); + } + previous() { + this.select((this.selectedIndex - 1 + this.items.length) % this.items.length); + } + next() { + this.select((this.selectedIndex + 1 + this.items.length) % this.items.length); + } + async select(index, shouldAnimate = true) { + if (this.hasPendingTransition) { + return; + } + this.hasPendingTransition = true; + await this.items[this.selectedIndex].transitionToLeave(shouldAnimate); + if (this.pageDots) { + this.pageDots.selectedIndex = index; + } + await this.items[index].transitionToEnter(shouldAnimate); + this.hasPendingTransition = false; + } +}; +Object.assign(TestimonialList.prototype, VerticalScrollBlockerMixin); +window.customElements.define("testimonial-list", TestimonialList); + +// js/custom-element/section/shop-the-look/shop-the-look-item.js +var ShopTheLookItem = class extends HTMLElement { + get index() { + return [...this.parentNode.children].indexOf(this); + } + get selected() { + return !this.hasAttribute("hidden"); + } + async transitionToLeave(shouldAnimate = true) { + this.setAttribute("hidden", ""); + const animation = new CustomAnimation(new CustomKeyframeEffect(this, { visibility: ["visible", "hidden"] }, { duration: 500 })); + shouldAnimate ? animation.play() : animation.finish(); + return animation.finished; + } + async transitionToEnter(shouldAnimate = true) { + this.removeAttribute("hidden"); + const dots = Array.from(this.querySelectorAll(".shop-the-look__dot")); + dots.forEach((dot) => dot.style.opacity = 0); + const animation = new CustomAnimation(new SequenceEffect([ + new ParallelEffect(Array.from(this.querySelectorAll(".shop-the-look__image")).map((item) => { + return new CustomKeyframeEffect(item, { opacity: [1, 1] }, { duration: 0 }); + })), + new CustomKeyframeEffect(this, { visibility: ["hidden", "visible"], zIndex: [0, 1], clipPath: ["inset(0 0 0 100%)", "inset(0 0 0 0)"] }, { duration: 500, easing: "cubic-bezier(1, 0, 0, 1)" }), + new ParallelEffect(dots.map((item, index) => { + return new CustomKeyframeEffect(item, { opacity: [0, 1], transform: ["scale(0)", "scale(1)"] }, { duration: 120, delay: 75 * index, easing: "ease-in-out" }); + })) + ])); + shouldAnimate ? animation.play() : animation.finish(); + await animation.finished; + if (window.matchMedia(window.themeVariables.breakpoints.tabletAndUp).matches) { + const firstPopover = this.querySelector(".shop-the-look__product-wrapper .shop-the-look__dot"); + firstPopover?.setAttribute("aria-expanded", "true"); + } + } +}; +window.customElements.define("shop-the-look-item", ShopTheLookItem); + +// js/custom-element/section/shop-the-look/shop-the-look-nav.js +var ShopTheLookNav = class extends CustomHTMLElement { + connectedCallback() { + this.shopTheLook = this.closest("shop-the-look"); + this.inTransition = false; + this.pendingTransition = false; + this.pendingTransitionTo = null; + this.delegate.on("click", '[data-action="prev"]', () => this.shopTheLook.previous()); + this.delegate.on("click", '[data-action="next"]', () => this.shopTheLook.next()); + } + transitionToIndex(selectedIndex, nextIndex, shouldAnimate = true) { + const indexElements = Array.from(this.querySelectorAll(".shop-the-look__counter-page-transition")), currentElement = indexElements[selectedIndex], nextElement = indexElements[nextIndex]; + if (this.inTransition) { + this.pendingTransition = true; + this.pendingTransitionTo = nextIndex; + return; + } + this.inTransition = true; + currentElement.animate({ transform: ["translateY(0)", "translateY(-100%)"] }, { duration: shouldAnimate ? 1e3 : 0, easing: "cubic-bezier(1, 0, 0, 1)" }).onfinish = () => { + currentElement.setAttribute("hidden", ""); + this.inTransition = false; + if (this.pendingTransition && this.pendingTransitionTo !== nextIndex) { + this.pendingTransition = false; + this.transitionToIndex(nextIndex, this.pendingTransitionTo, shouldAnimate); + this.pendingTransitionTo = null; + } + }; + nextElement.removeAttribute("hidden"); + nextElement.animate({ transform: ["translateY(100%)", "translateY(0)"] }, { duration: shouldAnimate ? 1e3 : 0, easing: "cubic-bezier(1, 0, 0, 1)" }); + } +}; +window.customElements.define("shop-the-look-nav", ShopTheLookNav); + +// js/custom-element/section/shop-the-look/shop-the-look.js +var ShopTheLook = class extends CustomHTMLElement { + connectedCallback() { + this.lookItems = Array.from(this.querySelectorAll("shop-the-look-item")); + this.nav = this.querySelector("shop-the-look-nav"); + this.hasPendingTransition = false; + if (this.hasAttribute("reveal-on-scroll")) { + this._setupVisibility(); + } + if (this.lookItems.length > 1 && Shopify.designMode) { + this.addEventListener("shopify:block:select", async (event) => { + this.intersectionObserver.disconnect(); + await this.select(event.target.index, !event.detail.load); + this.nav.animate({ opacity: [0, 1], transform: ["translateY(30px)", "translateY(0)"] }, { duration: 0, fill: "forwards", easing: "ease-in-out" }); + }); + } + } + get selectedIndex() { + return this.lookItems.findIndex((item) => item.selected); + } + async _setupVisibility() { + await this.untilVisible(); + const images = Array.from(this.lookItems[this.selectedIndex].querySelectorAll(".shop-the-look__image")); + for (let image of images) { + if (image.offsetParent !== null) { + await imageLoaded(image); + } + } + await this.lookItems[this.selectedIndex].transitionToEnter(); + if (this.nav) { + this.nav.animate({ opacity: [0, 1], transform: ["translateY(30px)", "translateY(0)"] }, { duration: 150, fill: "forwards", easing: "ease-in-out" }); + } + } + previous() { + this.select((this.selectedIndex - 1 + this.lookItems.length) % this.lookItems.length); + } + next() { + this.select((this.selectedIndex + 1 + this.lookItems.length) % this.lookItems.length); + } + async select(index, animate = true) { + const currentLook = this.lookItems[this.selectedIndex], nextLook = this.lookItems[index]; + if (this.hasPendingTransition) { + return; + } + this.hasPendingTransition = true; + if (currentLook !== nextLook) { + this.nav.transitionToIndex(this.selectedIndex, index, animate); + currentLook.transitionToLeave(); + } + nextLook.transitionToEnter(animate); + this.hasPendingTransition = false; + } +}; +window.customElements.define("shop-the-look", ShopTheLook); + +// js/custom-element/section/collection-list/collection-list.js +var CollectionList = class extends CustomHTMLElement { + async connectedCallback() { + this.items = Array.from(this.querySelectorAll(".list-collections__item")); + if (this.hasAttribute("scrollable")) { + this.scroller = this.querySelector(".list-collections__scroller"); + this.addEventListener("prev-next:prev", this.previous.bind(this)); + this.addEventListener("prev-next:next", this.next.bind(this)); + this.addEventListener("shopify:block:select", (event) => event.target.scrollIntoView({ block: "nearest", inline: "center", behavior: event.detail.load ? "auto" : "smooth" })); + } + if (this.hasAttribute("reveal-on-scroll")) { + this._setupVisibility(); + } + } + async _setupVisibility() { + await this.untilVisible(); + const prefersReducedMotion = MediaFeatures.prefersReducedMotion(); + const animation = new CustomAnimation(new ParallelEffect(this.items.map((item, index) => { + return new SequenceEffect([ + new CustomKeyframeEffect(item.querySelector(".list-collections__item-image"), { + opacity: [0, 1], + transform: [`scale(${prefersReducedMotion ? 1 : 1.1})`, "scale(1)"] + }, { + duration: 250, + delay: prefersReducedMotion ? 0 : 150 * index, + easing: "cubic-bezier(0.65, 0, 0.35, 1)" + }), + new ParallelEffect(Array.from(item.querySelectorAll(".list-collections__item-info [reveal]")).map((textItem, subIndex) => { + return new CustomKeyframeEffect(textItem, { + opacity: [0, 1], + clipPath: [`inset(${prefersReducedMotion ? "0 0 0 0" : "0 0 100% 0"})`, "inset(0 0 0 0)"], + transform: [`translateY(${prefersReducedMotion ? 0 : "100%"})`, "translateY(0)"] + }, { + duration: 200, + delay: prefersReducedMotion ? 0 : 150 * index + 150 * subIndex, + easing: "cubic-bezier(0.5, 0.06, 0.01, 0.99)" + }); + })) + ]); + }))); + this._hasSectionReloaded ? animation.finish() : animation.play(); + } + previous() { + const directionFlip = window.themeVariables.settings.direction === "ltr" ? 1 : -1; + this.scroller.scrollBy({ + left: -this.items[0].clientWidth * directionFlip, + behavior: "smooth" + }); + } + next() { + const directionFlip = window.themeVariables.settings.direction === "ltr" ? 1 : -1; + this.scroller.scrollBy({ + left: this.items[0].clientWidth * directionFlip, + behavior: "smooth" + }); + } +}; +window.customElements.define("collection-list", CollectionList); + +// js/custom-element/section/product-list/product-list.js +var ProductList = class extends CustomHTMLElement { + constructor() { + super(); + this.productListInner = this.querySelector(".product-list__inner"); + this.productItems = Array.from(this.querySelectorAll("product-item")); + } + connectedCallback() { + this.addEventListener("prev-next:prev", this.previous.bind(this)); + this.addEventListener("prev-next:next", this.next.bind(this)); + if (!this.hidden && this.staggerApparition) { + this._staggerProductsApparition(); + } + } + get staggerApparition() { + return this.hasAttribute("stagger-apparition"); + } + get apparitionAnimation() { + return this._animation = this._animation || new CustomAnimation(new ParallelEffect(this.productItems.map((item, index) => { + return new CustomKeyframeEffect(item, { + opacity: [0, 1], + transform: [`translateY(${MediaFeatures.prefersReducedMotion() ? 0 : window.innerWidth < 1e3 ? 35 : 60}px)`, "translateY(0)"] + }, { + duration: 600, + delay: MediaFeatures.prefersReducedMotion() ? 0 : 100 * index - Math.min(3 * index * index, 100 * index), + easing: "ease" + }); + }))); + } + // Move to previous products (if any) + previous(event) { + const directionFlip = window.themeVariables.settings.direction === "ltr" ? 1 : -1, columnGap = parseInt(getComputedStyle(this).getPropertyValue("--product-list-column-gap")); + event.target.nextElementSibling.removeAttribute("disabled"); + event.target.toggleAttribute("disabled", this.productListInner.scrollLeft * directionFlip - (this.productListInner.clientWidth + columnGap) <= 0); + this.productListInner.scrollBy({ left: -(this.productListInner.clientWidth + columnGap) * directionFlip, behavior: "smooth" }); + } + // Move to next products (if any) + next(event) { + const directionFlip = window.themeVariables.settings.direction === "ltr" ? 1 : -1, columnGap = parseInt(getComputedStyle(this).getPropertyValue("--product-list-column-gap")); + event.target.previousElementSibling.removeAttribute("disabled"); + event.target.toggleAttribute("disabled", this.productListInner.scrollLeft * directionFlip + (this.productListInner.clientWidth + columnGap) * 2 >= this.productListInner.scrollWidth); + this.productListInner.scrollBy({ left: (this.productListInner.clientWidth + columnGap) * directionFlip, behavior: "smooth" }); + } + attributeChangedCallback(name) { + if (!this.staggerApparition) { + return; + } + switch (name) { + case "hidden": + if (!this.hidden) { + this.productListInner.scrollLeft = 0; + this.productListInner.parentElement.scrollLeft = 0; + this.querySelector(".prev-next-button--prev")?.setAttribute("disabled", ""); + this.querySelector(".prev-next-button--next")?.removeAttribute("disabled"); + this._staggerProductsApparition(); + } else { + this.apparitionAnimation.finish(); + } + } + } + async _staggerProductsApparition() { + this.productItems.forEach((item) => item.style.opacity = 0); + await this.untilVisible({ threshold: this.clientHeight > 0 ? Math.min(50 / this.clientHeight, 1) : 0 }); + this.apparitionAnimation.play(); + } +}; +__publicField(ProductList, "observedAttributes", ["hidden"]); +window.customElements.define("product-list", ProductList); + +// js/custom-element/section/logo-list/logo-list.js +var LogoList = class extends CustomHTMLElement { + async connectedCallback() { + this.items = Array.from(this.querySelectorAll(".logo-list__item")); + this.logoListScrollable = this.querySelector(".logo-list__list"); + if (this.items.length > 1) { + this.addEventListener("prev-next:prev", this.previous.bind(this)); + this.addEventListener("prev-next:next", this.next.bind(this)); + } + if (this.hasAttribute("reveal-on-scroll")) { + this._setupVisibility(); + } + } + async _setupVisibility() { + await this.untilVisible({ rootMargin: "50px 0px", threshold: 0 }); + const animation = new CustomAnimation(new ParallelEffect(this.items.map((item, index) => { + return new CustomKeyframeEffect(item, { + opacity: [0, 1], + transform: [`translateY(${MediaFeatures.prefersReducedMotion() ? 0 : "30px"})`, "translateY(0)"] + }, { + duration: 300, + delay: MediaFeatures.prefersReducedMotion() ? 0 : 100 * index, + easing: "ease" + }); + }))); + this._hasSectionReloaded ? animation.finish() : animation.play(); + } + previous(event) { + const directionFlip = window.themeVariables.settings.direction === "ltr" ? 1 : -1; + event.target.nextElementSibling.removeAttribute("disabled"); + event.target.toggleAttribute("disabled", this.logoListScrollable.scrollLeft * directionFlip - (this.logoListScrollable.clientWidth + 24) <= 0); + this.logoListScrollable.scrollBy({ left: -(this.logoListScrollable.clientWidth + 24) * directionFlip, behavior: "smooth" }); + } + next(event) { + const directionFlip = window.themeVariables.settings.direction === "ltr" ? 1 : -1; + event.target.previousElementSibling.removeAttribute("disabled"); + event.target.toggleAttribute("disabled", this.logoListScrollable.scrollLeft * directionFlip + (this.logoListScrollable.clientWidth + 24) * 2 >= this.logoListScrollable.scrollWidth); + this.logoListScrollable.scrollBy({ left: (this.logoListScrollable.clientWidth + 24) * directionFlip, behavior: "smooth" }); + } +}; +window.customElements.define("logo-list", LogoList); + +// js/custom-element/section/blog/blog-post-navigation.js +var BlogPostNavigation = class extends HTMLElement { + connectedCallback() { + window.addEventListener("scroll", throttle(this._updateProgressBar.bind(this), 15)); + } + get hasNextArticle() { + return this.hasAttribute("has-next-article"); + } + _updateProgressBar() { + const stickyHeaderOffset = getStickyHeaderOffset(), marginCompensation = window.matchMedia(window.themeVariables.breakpoints.pocket).matches ? 40 : 80, articleNavBoundingBox = this.getBoundingClientRect(), articleMainPartBoundingBox = this.parentElement.getBoundingClientRect(), difference = articleMainPartBoundingBox.bottom - (articleNavBoundingBox.bottom - marginCompensation), progress = Math.max(-1 * (difference / (articleMainPartBoundingBox.height + marginCompensation) - 1), 0); + this.classList.toggle("is-visible", articleMainPartBoundingBox.top < stickyHeaderOffset && articleMainPartBoundingBox.bottom > stickyHeaderOffset + this.clientHeight - marginCompensation); + if (this.hasNextArticle) { + if (progress > 0.8) { + this.classList.add("article__nav--show-next"); + } else { + this.classList.remove("article__nav--show-next"); + } + } + this.style.setProperty("--transform", `${progress}`); + } +}; +window.customElements.define("blog-post-navigation", BlogPostNavigation); + +// js/custom-element/section/multi-column/multi-column.js +var MultiColumn = class extends CustomHTMLElement { + connectedCallback() { + if (!this.hasAttribute("stack")) { + this.multiColumnInner = this.querySelector(".multi-column__inner"); + this.addEventListener("prev-next:prev", this.previous.bind(this)); + this.addEventListener("prev-next:next", this.next.bind(this)); + if (Shopify.designMode) { + this.addEventListener("shopify:block:select", (event) => { + event.target.scrollIntoView({ inline: "center", block: "nearest", behavior: event.detail.load ? "auto" : "smooth" }); + }); + } + } + if (this.hasAttribute("stagger-apparition")) { + this._setupVisibility(); + } + } + async _setupVisibility() { + await this.untilVisible({ threshold: Math.min(50 / this.clientHeight, 1) }); + const prefersReducedMotion = MediaFeatures.prefersReducedMotion(); + const animation = new CustomAnimation(new ParallelEffect(Array.from(this.querySelectorAll(".multi-column__item")).map((item, index) => { + return new CustomKeyframeEffect(item, { + opacity: [0, 1], + transform: [`translateY(${MediaFeatures.prefersReducedMotion() ? 0 : window.innerWidth < 1e3 ? 35 : 60}px)`, "translateY(0)"] + }, { + duration: 600, + delay: prefersReducedMotion ? 0 : 100 * index, + easing: "ease" + }); + }))); + this._hasSectionReloaded ? animation.finish() : animation.play(); + } + // Move to previous products (if any) + previous(event) { + const directionFlip = window.themeVariables.settings.direction === "ltr" ? 1 : -1, columnGap = parseInt(getComputedStyle(this).getPropertyValue("--multi-column-column-gap")); + event.target.nextElementSibling.removeAttribute("disabled"); + event.target.toggleAttribute("disabled", this.multiColumnInner.scrollLeft * directionFlip - (this.multiColumnInner.clientWidth + columnGap) <= 0); + this.multiColumnInner.scrollBy({ left: -(this.multiColumnInner.clientWidth + columnGap) * directionFlip, behavior: "smooth" }); + } + // Move to next products (if any) + next(event) { + const directionFlip = window.themeVariables.settings.direction === "ltr" ? 1 : -1, columnGap = parseInt(getComputedStyle(this).getPropertyValue("--multi-column-column-gap")); + event.target.previousElementSibling.removeAttribute("disabled"); + event.target.toggleAttribute("disabled", this.multiColumnInner.scrollLeft * directionFlip + (this.multiColumnInner.clientWidth + columnGap) * 2 >= this.multiColumnInner.scrollWidth); + this.multiColumnInner.scrollBy({ left: (this.multiColumnInner.clientWidth + columnGap) * directionFlip, behavior: "smooth" }); + } +}; +window.customElements.define("multi-column", MultiColumn); + +// js/custom-element/section/gallery/gallery-list.js +var GalleryList = class extends HTMLElement { + connectedCallback() { + this.listItems = Array.from(this.querySelectorAll("gallery-item")); + this.scrollBarElement = this.querySelector(".gallery__progress-bar"); + this.listWrapperElement = this.querySelector(".gallery__list-wrapper"); + if (this.listItems.length > 1) { + this.addEventListener("scrollable-content:progress", this._updateProgressBar.bind(this)); + this.addEventListener("prev-next:prev", this.previous.bind(this)); + this.addEventListener("prev-next:next", this.next.bind(this)); + if (Shopify.designMode) { + this.addEventListener("shopify:block:select", (event) => this.select(event.target.index, !event.detail.load)); + } + } + } + previous() { + this.select([...this.listItems].reverse().find((item) => item.isOnLeftHalfPartOfScreen).index); + } + next() { + this.select(this.listItems.findIndex((item) => item.isOnRightHalfPartOfScreen)); + } + select(index, animate = true) { + const boundingRect = this.listItems[index].getBoundingClientRect(); + this.listWrapperElement.scrollBy({ + behavior: animate ? "smooth" : "auto", + left: Math.floor(boundingRect.left - window.innerWidth / 2 + boundingRect.width / 2) + }); + } + _updateProgressBar(event) { + this.scrollBarElement?.style.setProperty("--transform", `${event.detail.progress}%`); + } +}; +window.customElements.define("gallery-list", GalleryList); + +// js/custom-element/section/gallery/gallery-item.js +var GalleryItem = class extends HTMLElement { + get index() { + return [...this.parentNode.children].indexOf(this); + } + get isOnRightHalfPartOfScreen() { + if (window.themeVariables.settings.direction === "ltr") { + return this.getBoundingClientRect().left > window.innerWidth / 2; + } else { + return this.getBoundingClientRect().right < window.innerWidth / 2; + } + } + get isOnLeftHalfPartOfScreen() { + if (window.themeVariables.settings.direction === "ltr") { + return this.getBoundingClientRect().right < window.innerWidth / 2; + } else { + return this.getBoundingClientRect().left > window.innerWidth / 2; + } + } +}; +window.customElements.define("gallery-item", GalleryItem); + +// js/custom-element/section/image-with-text-overlay/image-with-text-overlay.js +var ImageWithTextOverlay = class extends CustomHTMLElement { + connectedCallback() { + if (this.hasAttribute("parallax") && !MediaFeatures.prefersReducedMotion()) { + this._hasPendingRaF = false; + this._onScrollListener = this._onScroll.bind(this); + window.addEventListener("scroll", this._onScrollListener); + } + if (this.hasAttribute("reveal-on-scroll")) { + this._setupVisibility(); + } + } + disconnectedCallback() { + super.disconnectedCallback(); + if (this._onScrollListener) { + window.removeEventListener("scroll", this._onScrollListener); + } + } + async _setupVisibility() { + await this.untilVisible(); + const image = this.querySelector(".image-overlay__image"), headings = await resolveAsyncIterator(this.querySelectorAll("split-lines")), prefersReducedMotion = MediaFeatures.prefersReducedMotion(); + await imageLoaded(image); + const innerEffect = [ + new CustomKeyframeEffect(image, { opacity: [0, 1], transform: [`scale(${prefersReducedMotion ? 1 : 1.1})`, "scale(1)"] }, { duration: 500, easing: "cubic-bezier(0.65, 0, 0.35, 1)" }), + new ParallelEffect(headings.map((item, index) => { + return new CustomKeyframeEffect(item, { + opacity: [0, 0.2, 1], + transform: [`translateY(${prefersReducedMotion ? 0 : "100%"})`, "translateY(0)"], + clipPath: [`inset(${prefersReducedMotion ? "0 0 0 0" : "0 0 100% 0"})`, "inset(0 0 0 0)"] + }, { + duration: 300, + delay: prefersReducedMotion ? 0 : 120 * index, + easing: "cubic-bezier(0.5, 0.06, 0.01, 0.99)" + }); + })), + new CustomKeyframeEffect(this.querySelector(".image-overlay__text-container"), { opacity: [0, 1] }, { duration: 300 }) + ]; + const animation = prefersReducedMotion ? new CustomAnimation(new ParallelEffect(innerEffect)) : new CustomAnimation(new SequenceEffect(innerEffect)); + this._hasSectionReloaded ? animation.finish() : animation.play(); + } + _onScroll() { + if (this._hasPendingRaF) { + return; + } + this._hasPendingRaF = true; + requestAnimationFrame(() => { + const boundingRect = this.getBoundingClientRect(), speedFactor = 3, contentElement = this.querySelector(".image-overlay__content-wrapper"), imageElement = this.querySelector(".image-overlay__image"), boundingRectBottom = boundingRect.bottom, boundingRectHeight = boundingRect.height, stickyHeaderOffset = getStickyHeaderOffset(); + if (contentElement) { + contentElement.style.opacity = Math.max(1 - speedFactor * (1 - Math.min(boundingRectBottom / boundingRectHeight, 1)), 0).toString(); + } + if (imageElement) { + imageElement.style.transform = `translateY(${100 - Math.max(1 - (1 - Math.min(boundingRectBottom / (boundingRectHeight + stickyHeaderOffset), 1)), 0) * 100}px)`; + } + this._hasPendingRaF = false; + }); + } +}; +window.customElements.define("image-with-text-overlay", ImageWithTextOverlay); + +// js/custom-element/section/image-with-text-block/image-with-text-block.js +var ImageWithTextBlock = class extends CustomHTMLElement { + async connectedCallback() { + if (this.hasAttribute("reveal-on-scroll")) { + this._setupVisibility(); + } + } + async _setupVisibility() { + await this.untilVisible(); + const images = Array.from(this.querySelectorAll(".image-with-text-block__image[reveal]")), headings = await resolveAsyncIterator(this.querySelectorAll("split-lines")), prefersReducedMotion = MediaFeatures.prefersReducedMotion(); + for (const image of images) { + if (image.offsetParent !== null) { + await imageLoaded(image); + } + } + const innerEffect = [ + new ParallelEffect(images.map((item) => { + return new CustomKeyframeEffect(item, { opacity: [0, 1], transform: [`scale(${prefersReducedMotion ? 1 : 1.1})`, "scale(1)"] }, { duration: 500, easing: "cubic-bezier(0.65, 0, 0.35, 1)" }); + })), + new CustomKeyframeEffect(this.querySelector(".image-with-text-block__content"), { opacity: [0, 1], transform: [`translateY(${prefersReducedMotion ? 0 : "60px"})`, "translateY(0)"] }, { duration: 150, easing: "ease-in-out" }), + new ParallelEffect(headings.map((item, index) => { + return new CustomKeyframeEffect(item, { + opacity: [0, 0.2, 1], + transform: [`translateY(${prefersReducedMotion ? 0 : "100%"})`, "translateY(0)"], + clipPath: [`inset(${prefersReducedMotion ? "0 0 0 0" : "0 0 100% 0"})`, "inset(0 0 0 0)"] + }, { + duration: 300, + delay: prefersReducedMotion ? 0 : 120 * index, + easing: "cubic-bezier(0.5, 0.06, 0.01, 0.99)" + }); + })), + new CustomKeyframeEffect(this.querySelector(".image-with-text-block__text-container"), { opacity: [0, 1] }, { duration: 300 }) + ]; + const animation = prefersReducedMotion ? new CustomAnimation(new ParallelEffect(innerEffect)) : new CustomAnimation(new SequenceEffect(innerEffect)); + this._hasSectionReloaded ? animation.finish() : animation.play(); + } +}; +window.customElements.define("image-with-text-block", ImageWithTextBlock); + +// js/custom-element/section/blog/article-list.js +var ArticleList = class extends CustomHTMLElement { + async connectedCallback() { + this.articleItems = Array.from(this.querySelectorAll(".article-item")); + if (this.staggerApparition) { + await this.untilVisible({ threshold: this.clientHeight > 0 ? Math.min(50 / this.clientHeight, 1) : 0 }); + const animation = new CustomAnimation(new ParallelEffect(this.articleItems.map((item, index) => { + return new CustomKeyframeEffect(item, { + opacity: [0, 1], + transform: [`translateY(${MediaFeatures.prefersReducedMotion() ? 0 : window.innerWidth < 1e3 ? 35 : 60}px)`, "translateY(0)"] + }, { + duration: 600, + delay: MediaFeatures.prefersReducedMotion() ? 0 : 100 * index - Math.min(3 * index * index, 100 * index), + easing: "ease" + }); + }))); + this._hasSectionReloaded ? animation.finish() : animation.play(); + } + } + get staggerApparition() { + return this.hasAttribute("stagger-apparition"); + } +}; +window.customElements.define("article-list", ArticleList); + +// js/custom-element/section/blog/blog-post-header.js +var BlogPostHeader = class extends HTMLElement { + async connectedCallback() { + const image = this.querySelector(".article__image"); + if (MediaFeatures.prefersReducedMotion()) { + image.removeAttribute("reveal"); + } else { + await imageLoaded(image); + image.animate({ opacity: [0, 1], transform: ["scale(1.1)", "scale(1)"] }, { duration: 500, fill: "forwards", easing: "cubic-bezier(0.65, 0, 0.35, 1)" }); + } + } +}; +window.customElements.define("blog-post-header", BlogPostHeader); + +// js/custom-element/section/search/predictive-search-input.js +var PredictiveSearchInput = class extends HTMLInputElement { + connectedCallback() { + this.addEventListener("click", () => document.getElementById(this.getAttribute("aria-controls")).open = true); + } +}; +window.customElements.define("predictive-search-input", PredictiveSearchInput, { extends: "input" }); + +// js/custom-element/ui/drawer.js +var DrawerContent = class extends OpenableElement { + connectedCallback() { + super.connectedCallback(); + if (this.hasAttribute("reverse-breakpoint")) { + this.originalDirection = this.classList.contains("drawer--from-left") ? "left" : "right"; + const matchMedia2 = window.matchMedia(this.getAttribute("reverse-breakpoint")); + matchMedia2.addListener(this._checkReverseOpeningDirection.bind(this)); + this._checkReverseOpeningDirection(matchMedia2); + } + this.delegate.on("click", ".drawer__overlay", () => this.open = false); + } + attributeChangedCallback(name, oldValue, newValue) { + super.attributeChangedCallback(name, oldValue, newValue); + switch (name) { + case "open": + document.documentElement.classList.toggle("lock-all", this.open); + } + } + _checkReverseOpeningDirection(match) { + this.classList.remove("drawer--from-left"); + if (this.originalDirection === "left" && !match.matches || this.originalDirection !== "left" && match.matches) { + this.classList.add("drawer--from-left"); + } + } +}; +window.customElements.define("drawer-content", DrawerContent); + +// js/custom-element/section/search/predictive-search-drawer.js +var PredictiveSearchDrawer = class extends DrawerContent { + connectedCallback() { + super.connectedCallback(); + this.inputElement = this.querySelector('[name="q"]'); + this.drawerContentElement = this.querySelector(".drawer__content"); + this.drawerFooterElement = this.querySelector(".drawer__footer"); + this.loadingStateElement = this.querySelector(".predictive-search__loading-state"); + this.resultsElement = this.querySelector(".predictive-search__results"); + this.menuListElement = this.querySelector(".predictive-search__menu-list"); + this.delegate.on("input", '[name="q"]', this._debounce(this._onSearch.bind(this), 200)); + this.delegate.on("click", '[data-action="reset-search"]', this._startNewSearch.bind(this)); + } + async _onSearch(event, target) { + if (event.key === "Enter") { + return; + } + if (this.abortController) { + this.abortController.abort(); + } + this.drawerContentElement.classList.remove("drawer__content--center"); + this.drawerFooterElement.hidden = true; + if (target.value === "") { + this.loadingStateElement.hidden = true; + this.resultsElement.hidden = true; + this.menuListElement ? this.menuListElement.hidden = false : ""; + } else { + this.drawerContentElement.classList.add("drawer__content--center"); + this.loadingStateElement.hidden = false; + this.resultsElement.hidden = true; + this.menuListElement ? this.menuListElement.hidden = true : ""; + let searchResults = {}; + try { + this.abortController = new AbortController(); + if (this._supportPredictiveApi()) { + searchResults = await this._doPredictiveSearch(target.value); + } else { + searchResults = await this._doLiquidSearch(target.value); + } + } catch (e) { + if (e.name === "AbortError") { + return; + } + } + this.loadingStateElement.hidden = true; + this.resultsElement.hidden = false; + this.menuListElement ? this.menuListElement.hidden = true : ""; + if (searchResults.hasResults) { + this.drawerFooterElement.hidden = false; + this.drawerContentElement.classList.remove("drawer__content--center"); + } + this.resultsElement.innerHTML = searchResults.html; + } + } + async _doPredictiveSearch(term) { + const response = await fetch(`${window.themeVariables.routes.predictiveSearchUrl}?q=${encodeURIComponent(term)}&resources[limit]=10&resources[limit_scope]=each§ion_id=predictive-search`, { + signal: this.abortController.signal + }); + const div = document.createElement("div"); + div.innerHTML = await response.text(); + return { hasResults: div.querySelector(".predictive-search__results-categories") !== null, html: div.firstElementChild.innerHTML }; + } + /* Some languages do not support predictive search API so we fallback to the Liquid search */ + async _doLiquidSearch(term) { + const response = await fetch(`${window.themeVariables.routes.searchUrl}?q=${encodeURIComponent(term)}&resources[limit]=50§ion_id=predictive-search-compatibility`, { + signal: this.abortController.signal + }); + const div = document.createElement("div"); + div.innerHTML = await response.text(); + return { hasResults: div.querySelector(".predictive-search__results-categories") !== null, html: div.firstElementChild.innerHTML }; + } + _startNewSearch() { + this.inputElement.value = ""; + this.inputElement.focus(); + const event = new Event("input", { + bubbles: true, + cancelable: true + }); + this.inputElement.dispatchEvent(event); + } + _supportPredictiveApi() { + const shopifyFeatureRequests = JSON.parse(document.getElementById("shopify-features").innerHTML); + return shopifyFeatureRequests["predictiveSearch"]; + } + /** + * Simple function that allows to debounce + */ + _debounce(fn, delay3) { + let timer = null; + return (...args) => { + clearTimeout(timer); + timer = setTimeout(() => { + fn.apply(this, args); + }, delay3); + }; + } +}; +window.customElements.define("predictive-search-drawer", PredictiveSearchDrawer); + +// js/custom-element/section/timeline/timeline.js +var Timeline = class extends HTMLElement { + connectedCallback() { + this.prevNextButtons = this.querySelector("prev-next-buttons"); + this.pageDots = this.querySelector("page-dots"); + this.scrollBarElement = this.querySelector(".timeline__progress-bar"); + this.listWrapperElement = this.querySelector(".timeline__list-wrapper"); + this.listItemElements = Array.from(this.querySelectorAll(".timeline__item")); + this.isScrolling = false; + if (this.listItemElements.length > 1) { + this.addEventListener("prev-next:prev", this.previous.bind(this)); + this.addEventListener("prev-next:next", this.next.bind(this)); + this.addEventListener("page-dots:changed", (event) => this.select(event.detail.index)); + if (Shopify.designMode) { + this.addEventListener("shopify:block:select", (event) => { + this.select([...event.target.parentNode.children].indexOf(event.target), !event.detail.load); + }); + } + this.itemIntersectionObserver = new IntersectionObserver(this._onItemObserved.bind(this), { threshold: 0.4 }); + const mediaQuery = window.matchMedia(window.themeVariables.breakpoints.pocket); + mediaQuery.addListener(this._onMediaChanged.bind(this)); + this._onMediaChanged(mediaQuery); + } + } + get selectedIndex() { + return this.listItemElements.findIndex((item) => !item.hasAttribute("hidden")); + } + previous() { + this.select(Math.max(0, this.selectedIndex - 1)); + } + next() { + this.select(Math.min(this.selectedIndex + 1, this.listItemElements.length - 1)); + } + select(index, animate = true) { + const listItemElement = this.listItemElements[index], boundingRect = listItemElement.getBoundingClientRect(); + if (animate) { + this.isScrolling = true; + setTimeout(() => this.isScrolling = false, 800); + } + if (window.matchMedia(window.themeVariables.breakpoints.pocket).matches) { + this.listWrapperElement.scrollTo({ + behavior: animate ? "smooth" : "auto", + left: this.listItemElements[0].clientWidth * index + /* Note: the last element does not contain extra margin so we use the first element width */ + }); + } else { + this.listWrapperElement.scrollBy({ + behavior: animate ? "smooth" : "auto", + left: Math.floor(boundingRect.left - window.innerWidth / 2 + boundingRect.width / 2) + }); + } + this._onItemSelected(index); + } + _onItemSelected(index) { + const listItemElement = this.listItemElements[index]; + listItemElement.removeAttribute("hidden", "false"); + getSiblings(listItemElement).forEach((item) => item.setAttribute("hidden", "")); + this.prevNextButtons.isPrevDisabled = index === 0; + this.prevNextButtons.isNextDisabled = index === this.listItemElements.length - 1; + this.pageDots.selectedIndex = index; + this.scrollBarElement?.style.setProperty("--transform", `${100 / (this.listItemElements.length - 1) * index}%`); + } + _onItemObserved(entries) { + if (this.isScrolling) { + return; + } + entries.forEach((entry) => { + if (entry.isIntersecting) { + this._onItemSelected([...entry.target.parentNode.children].indexOf(entry.target)); + } + }); + } + _onMediaChanged(event) { + if (event.matches) { + this.listItemElements.forEach((item) => this.itemIntersectionObserver.observe(item)); + } else { + this.listItemElements.forEach((item) => this.itemIntersectionObserver.unobserve(item)); + } + } +}; +window.customElements.define("time-line", Timeline); + +// js/custom-element/section/press/press-list.js +var PressList = class extends CustomHTMLElement { + connectedCallback() { + this.pressItemsWrapper = this.querySelector(".press-list__wrapper"); + this.pressItems = Array.from(this.querySelectorAll("press-item")); + this.pageDots = this.querySelector("page-dots"); + if (this.pressItems.length > 1) { + if (Shopify.designMode) { + this.addEventListener("shopify:block:select", (event) => { + this.intersectionObserver?.disconnect(); + if (event.detail.load || !event.target.selected) { + this.select(event.target.index, !event.detail.load); + } + }); + } + this.pressItemsWrapper.addEventListener("swiperight", this.previous.bind(this)); + this.pressItemsWrapper.addEventListener("swipeleft", this.next.bind(this)); + this.addEventListener("page-dots:changed", (event) => this.select(event.detail.index)); + this._blockVerticalScroll(); + } + if (this.hasAttribute("reveal-on-scroll")) { + this._setupVisibility(); + } + } + async _setupVisibility() { + await this.untilVisible(); + this.pressItems[this.selectedIndex].transitionToEnter(); + } + get selectedIndex() { + return this.pressItems.findIndex((item) => item.selected); + } + previous() { + this.select((this.selectedIndex - 1 + this.pressItems.length) % this.pressItems.length); + } + next() { + this.select((this.selectedIndex + 1 + this.pressItems.length) % this.pressItems.length); + } + async select(index, shouldAnimate = true) { + const previousItem = this.pressItems[this.selectedIndex], newItem = this.pressItems[index]; + await previousItem.transitionToLeave(shouldAnimate); + this.pageDots.selectedIndex = index; + await newItem.transitionToEnter(shouldAnimate); + } +}; +Object.assign(PressList.prototype, VerticalScrollBlockerMixin); +window.customElements.define("press-list", PressList); + +// js/custom-element/section/press/press-item.js +var PressItem = class extends HTMLElement { + connectedCallback() { + this.addEventListener("split-lines:re-split", (event) => { + Array.from(event.target.children).forEach((line) => line.style.visibility = this.selected ? "visible" : "hidden"); + }); + } + get index() { + return [...this.parentNode.children].indexOf(this); + } + get selected() { + return !this.hasAttribute("hidden"); + } + async transitionToLeave(shouldAnimate = true) { + const textLines = await resolveAsyncIterator(this.querySelectorAll("split-lines")), animation = new CustomAnimation(new ParallelEffect(textLines.reverse().map((item, index) => { + return new CustomKeyframeEffect(item, { + visibility: ["visible", "hidden"], + clipPath: ["inset(0 0 0 0)", "inset(0 0 100% 0)"], + transform: ["translateY(0)", "translateY(100%)"] + }, { + duration: 350, + delay: 60 * index, + easing: "cubic-bezier(0.68, 0.00, 0.77, 0.00)" + }); + }))); + shouldAnimate ? animation.play() : animation.finish(); + await animation.finished; + this.setAttribute("hidden", ""); + } + async transitionToEnter(shouldAnimate = true) { + this.removeAttribute("hidden"); + const textLines = await resolveAsyncIterator(this.querySelectorAll("split-lines, .testimonial__author")), animation = new CustomAnimation(new ParallelEffect(textLines.map((item, index) => { + return new CustomKeyframeEffect(item, { + visibility: ["hidden", "visible"], + clipPath: ["inset(0 0 100% 0)", "inset(0 0 0px 0)"], + transform: ["translateY(100%)", "translateY(0)"] + }, { + duration: 550, + delay: 120 * index, + easing: "cubic-bezier(0.23, 1, 0.32, 1)" + }); + }))); + shouldAnimate ? animation.play() : animation.finish(); + return animation.finished; + } +}; +window.customElements.define("press-item", PressItem); + +// js/custom-element/section/header/desktop-navigation.js +var DesktopNavigation = class extends CustomHTMLElement { + connectedCallback() { + this.openingTimeout = null; + this.currentMegaMenu = null; + this.delegate.on("mouseenter", ".has-dropdown", (event, target) => { + if (event.target === target && event.relatedTarget !== null) { + this.openDropdown(target); + } + }, true); + this.delegate.on("click", ".header__linklist-link[aria-expanded], .nav-dropdown__link[aria-expanded]", (event, target) => { + if (window.matchMedia("(hover: hover)").matches || target.getAttribute("aria-expanded") === "true") { + return; + } + event.preventDefault(); + this.openDropdown(target.parentElement); + }); + this.delegate.on("shopify:block:select", (event) => this.openDropdown(event.target.parentElement)); + this.delegate.on("shopify:block:deselect", (event) => this.closeDropdown(event.target.parentElement)); + } + openDropdown(parentElement) { + const menuItem = parentElement.querySelector("[aria-controls]"), dropdown = parentElement.querySelector(`#${menuItem.getAttribute("aria-controls")}`); + this.currentMegaMenu = dropdown.classList.contains("mega-menu") ? dropdown : null; + let openingTimeout = setTimeout(() => { + if (menuItem.getAttribute("aria-expanded") === "true") { + return; + } + menuItem.setAttribute("aria-expanded", "true"); + dropdown.removeAttribute("hidden"); + if (dropdown.classList.contains("mega-menu") && !MediaFeatures.prefersReducedMotion()) { + const items = Array.from(dropdown.querySelectorAll(".mega-menu__column, .mega-menu__image-push")); + items.forEach((item) => { + item.getAnimations().forEach((animation2) => animation2.cancel()); + item.style.opacity = 0; + }); + const animation = new CustomAnimation(new ParallelEffect(items.map((item, index) => { + return new CustomKeyframeEffect(item, { + opacity: [0, 1], + transform: ["translateY(20px)", "translateY(0)"] + }, { + duration: 250, + delay: 100 + 60 * index, + easing: "cubic-bezier(0.65, 0, 0.35, 1)" + }); + }))); + animation.play(); + } + const leaveListener = (event) => { + if (event.relatedTarget !== null) { + this.closeDropdown(parentElement); + parentElement.removeEventListener("mouseleave", leaveListener); + } + }; + const leaveDocumentListener = () => { + this.closeDropdown(parentElement); + document.documentElement.removeEventListener("mouseleave", leaveDocumentListener); + }; + parentElement.addEventListener("mouseleave", leaveListener); + document.documentElement.addEventListener("mouseleave", leaveDocumentListener); + openingTimeout = null; + this.dispatchEvent(new CustomEvent("desktop-nav:dropdown:open", { bubbles: true })); + }, 100); + parentElement.addEventListener("mouseleave", () => { + if (openingTimeout) { + clearTimeout(openingTimeout); + } + }, { once: true }); + } + closeDropdown(parentElement) { + const menuItem = parentElement.querySelector("[aria-controls]"), dropdown = parentElement.querySelector(`#${menuItem.getAttribute("aria-controls")}`); + requestAnimationFrame(() => { + dropdown.classList.add("is-closing"); + menuItem.setAttribute("aria-expanded", "false"); + setTimeout(() => { + dropdown.setAttribute("hidden", ""); + clearTimeout(this.openingTimeout); + dropdown.classList.remove("is-closing"); + }, dropdown.classList.contains("mega-menu") && this.currentMegaMenu !== dropdown ? 250 : 0); + this.dispatchEvent(new CustomEvent("desktop-nav:dropdown:close", { bubbles: true })); + }); + } +}; +window.customElements.define("desktop-navigation", DesktopNavigation); + +// js/custom-element/section/header/mobile-navigation.js +var MobileNavigation = class extends DrawerContent { + get apparitionAnimation() { + if (this._apparitionAnimation) { + return this._apparitionAnimation; + } + if (!MediaFeatures.prefersReducedMotion()) { + const navItems = Array.from(this.querySelectorAll('.mobile-nav__item[data-level="1"]')), effects = []; + effects.push(new ParallelEffect(navItems.map((item, index) => { + return new CustomKeyframeEffect(item, { + opacity: [0, 1], + transform: ["translateX(-40px)", "translateX(0)"] + }, { + duration: 300, + delay: 300 + 120 * index - Math.min(2 * index * index, 120 * index), + easing: "cubic-bezier(0.25, 1, 0.5, 1)" + }); + }))); + const bottomBar = this.querySelector(".drawer__footer"); + if (bottomBar) { + effects.push(new CustomKeyframeEffect( + bottomBar, + { + opacity: [0, 1], + transform: ["translateY(100%)", "translateY(0)"] + }, + { + duration: 300, + delay: 500 + Math.max(125 * navItems.length - 25 * navItems.length, 25), + easing: "cubic-bezier(0.25, 1, 0.5, 1)" + } + )); + } + return this._apparitionAnimation = new CustomAnimation(new ParallelEffect(effects)); + } + } + attributeChangedCallback(name, oldValue, newValue) { + super.attributeChangedCallback(name, oldValue, newValue); + switch (name) { + case "open": + if (this.open && this.apparitionAnimation) { + Array.from(this.querySelectorAll('.mobile-nav__item[data-level="1"], .drawer__footer')).forEach((item) => item.style.opacity = 0); + this.apparitionAnimation.play(); + } + triggerEvent(this, this.open ? "mobile-nav:open" : "mobile-nav:close"); + } + } +}; +window.customElements.define("mobile-navigation", MobileNavigation); + +// js/custom-element/section/header/store-header.js +var StoreHeader = class extends CustomHTMLElement { + connectedCallback() { + if (window.ResizeObserver) { + this.resizeObserver = new ResizeObserver(this._updateCustomProperties.bind(this)); + this.resizeObserver.observe(this); + this.resizeObserver.observe(this.querySelector(".header__wrapper")); + } + if (this.isTransparent) { + this.isTransparencyDetectionLocked = false; + this.delegate.on("desktop-nav:dropdown:open", () => this.lockTransparency = true); + this.delegate.on("desktop-nav:dropdown:close", () => this.lockTransparency = false); + this.rootDelegate.on("mobile-nav:open", () => this.lockTransparency = true); + this.rootDelegate.on("mobile-nav:close", () => this.lockTransparency = false); + this.delegate.on("mouseenter", this._checkTransparentHeader.bind(this), true); + this.delegate.on("mouseleave", this._checkTransparentHeader.bind(this)); + if (this.isSticky) { + this._checkTransparentHeader(); + this._onWindowScrollListener = throttle(this._checkTransparentHeader.bind(this), 100); + window.addEventListener("scroll", this._onWindowScrollListener); + } + } + } + disconnectedCallback() { + super.disconnectedCallback(); + if (window.ResizeObserver) { + this.resizeObserver.disconnect(); + } + if (this.isTransparent && this.isSticky) { + window.removeEventListener("scroll", this._onWindowScrollListener); + } + } + get isSticky() { + return this.hasAttribute("sticky"); + } + get isTransparent() { + return this.hasAttribute("transparent"); + } + get transparentHeaderThreshold() { + return 25; + } + set lockTransparency(value) { + this.isTransparencyDetectionLocked = value; + this._checkTransparentHeader(); + } + /** + * This method allows to keep in sync various CSS variables that are used to size various elements + */ + _updateCustomProperties(entries) { + entries.forEach((entry) => { + if (entry.target === this) { + const height = entry.borderBoxSize ? entry.borderBoxSize.length > 0 ? entry.borderBoxSize[0].blockSize : entry.borderBoxSize.blockSize : entry.target.clientHeight; + document.documentElement.style.setProperty("--header-height", `${height}px`); + } + if (entry.target.classList.contains("header__wrapper")) { + const heightWithoutNav = entry.borderBoxSize ? entry.borderBoxSize.length > 0 ? entry.borderBoxSize[0].blockSize : entry.borderBoxSize.blockSize : entry.target.clientHeight; + document.documentElement.style.setProperty("--header-height-without-bottom-nav", `${heightWithoutNav}px`); + } + }); + } + _checkTransparentHeader(event) { + if (this.isTransparencyDetectionLocked || window.scrollY > this.transparentHeaderThreshold || event && event.type === "mouseenter") { + this.classList.remove("header--transparent"); + } else { + this.classList.add("header--transparent"); + } + } +}; +window.customElements.define("store-header", StoreHeader); + +// js/custom-element/section/product/gift-card-recipient.js +var GiftCardRecipient = class extends HTMLElement { + connectedCallback() { + const properties = Array.from(this.querySelectorAll('[name*="properties"]')), checkboxPropertyName = "properties[__shopify_send_gift_card_to_recipient]"; + this.recipientCheckbox = properties.find((input) => input.name === checkboxPropertyName); + this.recipientOtherProperties = properties.filter((input) => input.name !== checkboxPropertyName); + this.recipientFieldsContainer = this.querySelector(".gift-card-recipient__fields"); + this.recipientCheckbox?.addEventListener("change", this._synchronizeProperties.bind(this)); + this.offsetProperty = this.querySelector('[name="properties[__shopify_offset]"]'); + if (this.offsetProperty) { + this.offsetProperty.value = (/* @__PURE__ */ new Date()).getTimezoneOffset().toString(); + } + this.recipientSendOnProperty = this.querySelector('[name="properties[Send on]"]'); + const minDate = /* @__PURE__ */ new Date(); + const maxDate = /* @__PURE__ */ new Date(); + maxDate.setDate(minDate.getDate() + 90); + this.recipientSendOnProperty?.setAttribute("min", this._formatDate(minDate)); + this.recipientSendOnProperty?.setAttribute("max", this._formatDate(maxDate)); + this._synchronizeProperties(); + } + _synchronizeProperties() { + this.recipientOtherProperties.forEach((property) => property.disabled = !this.recipientCheckbox.checked); + this.recipientFieldsContainer.classList.toggle("js:hidden", !this.recipientCheckbox.checked); + } + _formatDate(date) { + const offset = date.getTimezoneOffset(); + const offsetDate = new Date(date.getTime() - offset * 60 * 1e3); + return offsetDate.toISOString().split("T")[0]; + } +}; +if (!window.customElements.get("gift-card-recipient")) { + window.customElements.define("gift-card-recipient", GiftCardRecipient); +} + +// js/custom-element/section/product/image-zoom.js +var PhotoSwipeUi = class { + constructor(pswp) { + this.photoSwipeInstance = pswp; + this.delegate = new main_default(this.photoSwipeInstance.scrollWrap); + this.maxSpreadZoom = window.themeVariables.settings.mobileZoomFactor || 2; + this.pswpUi = this.photoSwipeInstance.scrollWrap.querySelector(".pswp__ui"); + this.delegate.on("click", '[data-action="pswp-close"]', this._close.bind(this)); + this.delegate.on("click", '[data-action="pswp-prev"]', this._goToPrev.bind(this)); + this.delegate.on("click", '[data-action="pswp-next"]', this._goToNext.bind(this)); + this.delegate.on("click", '[data-action="pswp-move-to"]', this._moveTo.bind(this)); + this.photoSwipeInstance.listen("close", this._onPswpClosed.bind(this)); + this.photoSwipeInstance.listen("doubleTap", this._onPswpDoubleTap.bind(this)); + this.photoSwipeInstance.listen("beforeChange", this._onPswpBeforeChange.bind(this)); + this.photoSwipeInstance.listen("initialZoomInEnd", this._onPswpInitialZoomInEnd.bind(this)); + this.photoSwipeInstance.listen("initialZoomOut", this._onPswpInitialZoomOut.bind(this)); + this.photoSwipeInstance.listen("parseVerticalMargin", this._onPswpParseVerticalMargin.bind(this)); + this.delegate.on("pswpTap", ".pswp__img", this._onPswpTap.bind(this)); + } + init() { + const prevNextButtons = this.pswpUi.querySelector(".pswp__prev-next-buttons"), dotsNavWrapper = this.pswpUi.querySelector(".pswp__dots-nav-wrapper"); + if (this.photoSwipeInstance.items.length <= 1) { + prevNextButtons.style.display = "none"; + dotsNavWrapper.style.display = "none"; + return; + } + prevNextButtons.style.display = ""; + dotsNavWrapper.style.display = ""; + let dotsNavHtml = ""; + this.photoSwipeInstance.items.forEach((item, index) => { + dotsNavHtml += ` + + `; + }); + dotsNavWrapper.querySelector(".pswp__dots-nav-wrapper .dots-nav").innerHTML = dotsNavHtml; + } + _close() { + this.photoSwipeInstance.close(); + } + _goToPrev() { + this.photoSwipeInstance.prev(); + } + _goToNext() { + this.photoSwipeInstance.next(); + } + _moveTo(event, target) { + this.photoSwipeInstance.goTo([...target.parentNode.children].indexOf(target)); + } + _onPswpClosed() { + this.delegate.off("pswpTap"); + } + _onPswpDoubleTap(point) { + const initialZoomLevel = this.photoSwipeInstance.currItem.initialZoomLevel; + if (this.photoSwipeInstance.getZoomLevel() !== initialZoomLevel) { + this.photoSwipeInstance.zoomTo(initialZoomLevel, point, 333); + } else { + this.photoSwipeInstance.zoomTo(initialZoomLevel < 0.7 ? 1 : this.maxSpreadZoom, point, 333); + } + } + _onPswpTap(event) { + if (event.detail.pointerType === "mouse") { + this.photoSwipeInstance.toggleDesktopZoom(event.detail.releasePoint); + } + } + _onPswpBeforeChange() { + if (this.photoSwipeInstance.items.length <= 1) { + return; + } + const activeDot = this.photoSwipeInstance.scrollWrap.querySelector(`.dots-nav__item:nth-child(${this.photoSwipeInstance.getCurrentIndex() + 1})`); + activeDot.setAttribute("aria-current", "true"); + getSiblings(activeDot).forEach((item) => item.removeAttribute("aria-current")); + } + _onPswpInitialZoomInEnd() { + this.pswpUi?.classList.remove("pswp__ui--hidden"); + } + _onPswpInitialZoomOut() { + this.pswpUi?.classList.add("pswp__ui--hidden"); + } + _onPswpParseVerticalMargin(item) { + item.vGap.bottom = this.photoSwipeInstance.items.length <= 1 || window.matchMedia(window.themeVariables.breakpoints.lapAndUp).matches ? 0 : 60; + } +}; +var ProductImageZoom = class extends OpenableElement { + connectedCallback() { + super.connectedCallback(); + this.mediaElement = this.closest(".product__media"); + this.maxSpreadZoom = window.themeVariables.settings.mobileZoomFactor || 2; + LibraryLoader.load("photoswipe"); + } + disconnectedCallback() { + super.disconnectedCallback(); + this.photoSwipeInstance?.destroy(); + } + async attributeChangedCallback(name, oldValue, newValue) { + super.attributeChangedCallback(name, oldValue, newValue); + switch (name) { + case "open": + if (this.open) { + await LibraryLoader.load("photoswipe"); + this._openPhotoSwipe(); + } + } + } + async _openPhotoSwipe() { + const items = await this._buildItems(); + this.photoSwipeInstance = new window.ThemePhotoSwipe(this, PhotoSwipeUi, items, { + index: items.findIndex((item) => item.selected), + maxSpreadZoom: this.maxSpreadZoom, + loop: false, + allowPanToNext: false, + closeOnScroll: false, + closeOnVerticalDrag: MediaFeatures.supportsHover(), + showHideOpacity: true, + arrowKeys: true, + history: false, + getThumbBoundsFn: () => { + const thumbnail = this.mediaElement.querySelector(".product__media-item.is-selected"), pageYScroll = window.pageYOffset || document.documentElement.scrollTop, rect = thumbnail.getBoundingClientRect(); + return { x: rect.left, y: rect.top + pageYScroll, w: rect.width }; + }, + getDoubleTapZoom: (isMouseClick, item) => { + if (isMouseClick) { + return item.w > item.h ? 1.6 : 1; + } else { + return item.initialZoomLevel < 0.7 ? 1 : 1.33; + } + } + }); + let lastWidth = null; + this.photoSwipeInstance.updateSize = new Proxy(this.photoSwipeInstance.updateSize, { + apply: (target, thisArg, argArray) => { + if (lastWidth !== window.innerWidth) { + target(arguments); + lastWidth = window.innerWidth; + } + } + }); + this.photoSwipeInstance.listen("close", () => { + this.open = false; + }); + this.photoSwipeInstance.init(); + } + async _buildItems() { + const activeImages = Array.from(this.mediaElement.querySelectorAll('.product__media-item[data-media-type="image"]:not(.is-filtered)')), product = await ProductLoader.load(this.getAttribute("product-handle")); + return Promise.resolve(activeImages.map((item) => { + const matchedMedia = product["media"].find((media) => media.id === parseInt(item.getAttribute("data-media-id"))), supportedSizes = getSupportedSizes(matchedMedia, [200, 300, 400, 500, 600, 700, 800, 1e3, 1200, 1400, 1600, 1800, 2e3, 2200, 2400, 2600, 2800, 3e3]), desiredWidth = Math.min(supportedSizes[supportedSizes.length - 1], window.innerWidth); + return { + selected: item.classList.contains("is-selected"), + src: getSizedMediaUrl(matchedMedia, `${Math.ceil(Math.min(desiredWidth * window.devicePixelRatio * this.maxSpreadZoom, 3e3))}x`), + msrc: item.firstElementChild.currentSrc, + originalMedia: matchedMedia, + w: desiredWidth, + h: parseInt(desiredWidth / matchedMedia["aspect_ratio"]) + }; + })); + } +}; +window.customElements.define("product-image-zoom", ProductImageZoom); + +// js/custom-element/section/product/inventory.js +var ProductInventory = class extends HTMLElement { + connectedCallback() { + const scriptTag = this.querySelector("script"); + if (!scriptTag) { + return; + } + this.inventories = JSON.parse(scriptTag.innerHTML); + document.getElementById(this.getAttribute("form-id"))?.addEventListener("variant:changed", this._onVariantChanged.bind(this)); + } + _onVariantChanged(event) { + this.querySelector("span")?.remove(); + if (event.detail.variant && this.inventories[event.detail.variant["id"]] !== "") { + this.hidden = false; + this.insertAdjacentHTML("afterbegin", this.inventories[event.detail.variant["id"]]); + } else { + this.hidden = true; + } + } +}; +window.customElements.define("product-inventory", ProductInventory); + +// js/custom-element/section/product/payment-container.js +var PaymentContainer = class extends HTMLElement { + connectedCallback() { + document.getElementById(this.getAttribute("form-id"))?.addEventListener("variant:changed", this._onVariantChanged.bind(this)); + if (Shopify.designMode && Shopify.PaymentButton) { + Shopify.PaymentButton.init(); + } + } + _onVariantChanged(event) { + this._updateAddToCartButton(event.detail.variant); + this._updateDynamicCheckoutButton(event.detail.variant); + } + _updateAddToCartButton(variant) { + let addToCartButtonElement = this.querySelector("[data-product-add-to-cart-button]"); + if (!addToCartButtonElement) { + return; + } + let addToCartButtonText = ""; + addToCartButtonElement.classList.remove("button--primary", "button--secondary", "button--ternary"); + if (!variant) { + addToCartButtonElement.setAttribute("disabled", "disabled"); + addToCartButtonElement.classList.add("button--ternary"); + addToCartButtonText = window.themeVariables.strings.productFormUnavailable; + } else { + if (variant["available"]) { + addToCartButtonElement.removeAttribute("disabled"); + addToCartButtonElement.classList.add(addToCartButtonElement.hasAttribute("data-use-primary") ? "button--primary" : "button--secondary"); + addToCartButtonText = addToCartButtonElement.getAttribute("data-button-content"); + } else { + addToCartButtonElement.setAttribute("disabled", "disabled"); + addToCartButtonElement.classList.add("button--ternary"); + addToCartButtonText = window.themeVariables.strings.productFormSoldOut; + } + } + if (addToCartButtonElement.getAttribute("is") === "loader-button") { + addToCartButtonElement.firstElementChild.innerHTML = addToCartButtonText; + } else { + addToCartButtonElement.innerHTML = addToCartButtonText; + } + } + _updateDynamicCheckoutButton(variant) { + let paymentButtonElement = this.querySelector(".shopify-payment-button"); + if (!paymentButtonElement) { + return; + } + paymentButtonElement.style.display = !variant || !variant["available"] ? "none" : "block"; + } +}; +window.customElements.define("product-payment-container", PaymentContainer); + +// js/custom-element/section/product/payment-terms.js +var PaymentTerms = class extends CustomHTMLElement { + connectedCallback() { + document.getElementById(this.getAttribute("form-id"))?.addEventListener("variant:changed", this._onVariantChanged.bind(this)); + } + _onVariantChanged(event) { + const variant = event.detail.variant; + if (variant) { + const idElement = this.querySelector('[name="id"]'); + idElement.value = variant["id"]; + idElement.dispatchEvent(new Event("change", { bubbles: true })); + } + } +}; +window.customElements.define("product-payment-terms", PaymentTerms); + +// js/custom-element/section/product/product-form.js +var ProductForm = class extends HTMLFormElement { + connectedCallback() { + this.id.disabled = false; + this.addEventListener("submit", this._onSubmit.bind(this)); + } + async _onSubmit(event) { + event.preventDefault(); + if (!this.checkValidity()) { + this.reportValidity(); + return; + } + const submitButtons = Array.from(this.elements).filter((button) => button.type === "submit"); + submitButtons.forEach((submitButton) => { + submitButton.setAttribute("disabled", "disabled"); + submitButton.setAttribute("aria-busy", "true"); + }); + const productForm = new FormData(this); + productForm.append("sections", ["mini-cart"]); + productForm.delete("option1"); + productForm.delete("option2"); + productForm.delete("option3"); + const response = await fetch(`${window.themeVariables.routes.cartAddUrl}.js`, { + body: productForm, + method: "POST", + headers: { + "X-Requested-With": "XMLHttpRequest" + // This is needed for the endpoint to properly return 422 + } + }); + submitButtons.forEach((submitButton) => { + submitButton.removeAttribute("disabled"); + submitButton.removeAttribute("aria-busy"); + }); + const responseJson = await response.json(); + if (response.ok) { + if (window.themeVariables.settings.cartType === "page" || window.themeVariables.settings.pageType === "cart") { + return window.location.href = `${Shopify.routes.root}cart`; + } + this.dispatchEvent(new CustomEvent("variant:added", { + bubbles: true, + detail: { + variant: responseJson.hasOwnProperty("items") ? responseJson["items"][0] : responseJson + } + })); + fetch(`${window.themeVariables.routes.cartUrl}.js`).then(async (response2) => { + const cartContent = await response2.json(); + document.documentElement.dispatchEvent(new CustomEvent("cart:updated", { + bubbles: true, + detail: { + cart: cartContent + } + })); + cartContent["sections"] = responseJson["sections"]; + document.documentElement.dispatchEvent(new CustomEvent("cart:refresh", { + bubbles: true, + detail: { + cart: cartContent, + openMiniCart: window.themeVariables.settings.cartType === "drawer" && this.closest(".drawer") === null + } + })); + }); + } + this.dispatchEvent(new CustomEvent("cart-notification:show", { + bubbles: true, + cancelable: true, + detail: { + status: response.ok ? "success" : "error", + error: responseJson["description"] || "" + } + })); + } +}; +window.customElements.define("product-form", ProductForm, { extends: "form" }); + +// js/custom-element/section/product/product-media.js +var ProductMedia = class extends CustomHTMLElement { + async connectedCallback() { + this.mainCarousel = this.querySelector("flickity-carousel"); + if (this.hasAttribute("reveal-on-scroll")) { + this._setupVisibility(); + } + if (this.mainCarousel.childElementCount === 1) { + return; + } + this.selectedVariantMediaId = null; + this.viewInSpaceElement = this.querySelector("[data-shopify-model3d-id]"); + this.zoomButton = this.querySelector(".product__zoom-button"); + this.product = await ProductLoader.load(this.getAttribute("product-handle")); + document.getElementById(this.getAttribute("form-id"))?.addEventListener("variant:changed", this._onVariantChanged.bind(this)); + this.mainCarousel.addEventListener("model:played", () => this.mainCarousel.setDraggable(false)); + this.mainCarousel.addEventListener("model:paused", () => this.mainCarousel.setDraggable(true)); + this.mainCarousel.addEventListener("video:played", () => this.mainCarousel.setDraggable(false)); + this.mainCarousel.addEventListener("video:paused", () => this.mainCarousel.setDraggable(true)); + this.mainCarousel.addEventListener("flickity:ready", this._onFlickityReady.bind(this)); + this.mainCarousel.addEventListener("flickity:slide-changed", this._onFlickityChanged.bind(this)); + this.mainCarousel.addEventListener("flickity:slide-settled", this._onFlickitySettled.bind(this)); + this._onFlickityReady(); + } + get thumbnailsPosition() { + return window.matchMedia(window.themeVariables.breakpoints.pocket).matches ? "bottom" : this.getAttribute("thumbnails-position"); + } + async _setupVisibility() { + await this.untilVisible(); + const flickityInstance = await this.mainCarousel.flickityInstance, image = flickityInstance ? flickityInstance.selectedElement.querySelector("img") : this.querySelector(".product__media-image-wrapper img"), prefersReducedMotion = MediaFeatures.prefersReducedMotion(); + await imageLoaded(image); + const animation = new CustomAnimation(new ParallelEffect([ + new CustomKeyframeEffect(image, { opacity: [0, 1], transform: [`scale(${prefersReducedMotion ? 1 : 1.1})`, "scale(1)"] }, { duration: 500, easing: "cubic-bezier(0.65, 0, 0.35, 1)" }), + new ParallelEffect(Array.from(this.querySelectorAll(".product__thumbnail-item:not(.is-filtered)")).map((item, index) => { + return new CustomKeyframeEffect(item, { + opacity: [0, 1], + transform: this.thumbnailsPosition === "left" ? [`translateY(${prefersReducedMotion ? 0 : "40px"})`, "translateY(0)"] : [`translateX(${prefersReducedMotion ? 0 : "50px"})`, "translateX(0)"] + }, { + duration: 250, + delay: prefersReducedMotion ? 0 : 100 * index, + easing: "cubic-bezier(0.75, 0, 0.175, 1)" + }); + })) + ])); + this._hasSectionReloaded ? animation.finish() : animation.play(); + } + async _onVariantChanged(event) { + const variant = event.detail.variant; + const filteredMediaIds = []; + let shouldReload = false; + this.product["media"].forEach((media) => { + let matchMedia2 = variant["featured_media"] && media["id"] === variant["featured_media"]["id"]; + if (media["alt"]?.includes("#")) { + shouldReload = true; + if (!matchMedia2) { + const altParts = media["alt"].split("#"), mediaGroupParts = altParts.pop().split("_"); + this.product["options"].forEach((option) => { + if (option["name"].toLowerCase() === mediaGroupParts[0].toLowerCase()) { + if (variant["options"][option["position"] - 1].toLowerCase() !== mediaGroupParts[1].trim().toLowerCase()) { + filteredMediaIds.push(media["id"]); + } + } + }); + } + } + }); + const currentlyFilteredIds = [...new Set(Array.from(this.querySelectorAll(".is-filtered[data-media-id]")).map((item) => parseInt(item.getAttribute("data-media-id"))))]; + if (currentlyFilteredIds.some((value) => !filteredMediaIds.includes(value))) { + const selectedMediaId = variant["featured_media"] ? variant["featured_media"]["id"] : this.product["media"].map((item) => item.id).filter((item) => !filteredMediaIds.includes(item))[0]; + Array.from(this.querySelectorAll("[data-media-id]")).forEach((item) => { + item.classList.toggle("is-filtered", filteredMediaIds.includes(parseInt(item.getAttribute("data-media-id")))); + item.classList.toggle("is-selected", selectedMediaId === parseInt(item.getAttribute("data-media-id"))); + item.classList.toggle("is-initial-selected", selectedMediaId === parseInt(item.getAttribute("data-media-id"))); + }); + this.mainCarousel.reload(); + } else { + if (!event.detail.variant["featured_media"] || this.selectedVariantMediaId === event.detail.variant["featured_media"]["id"]) { + return; + } + this.mainCarousel.select(`[data-media-id="${event.detail.variant["featured_media"]["id"]}"]`); + } + this.selectedVariantMediaId = event.detail.variant["featured_media"] ? event.detail.variant["featured_media"]["id"] : null; + } + async _onFlickityReady() { + const flickityInstance = await this.mainCarousel.flickityInstance; + if (["video", "external_video"].includes(flickityInstance.selectedElement.getAttribute("data-media-type")) && this.hasAttribute("autoplay-video")) { + flickityInstance.selectedElement.firstElementChild.play(); + } + } + async _onFlickityChanged() { + const flickityInstance = await this.mainCarousel.flickityInstance; + flickityInstance.cells.forEach((item) => { + if (["external_video", "video", "model"].includes(item.element.getAttribute("data-media-type"))) { + item.element.firstElementChild.pause(); + } + }); + } + async _onFlickitySettled() { + const flickityInstance = await this.mainCarousel.flickityInstance, selectedSlide = flickityInstance.selectedElement; + if (this.zoomButton) { + this.zoomButton.hidden = selectedSlide.getAttribute("data-media-type") !== "image"; + } + if (this.viewInSpaceElement) { + this.viewInSpaceElement.setAttribute("data-shopify-model3d-id", this.viewInSpaceElement.getAttribute("data-shopify-model3d-default-id")); + } + switch (selectedSlide.getAttribute("data-media-type")) { + case "model": + this.viewInSpaceElement.setAttribute("data-shopify-model3d-id", selectedSlide.getAttribute("data-media-id")); + selectedSlide.firstElementChild.play(); + break; + case "external_video": + case "video": + if (this.hasAttribute("autoplay-video")) { + selectedSlide.firstElementChild.play(); + } + break; + } + } +}; +window.customElements.define("product-media", ProductMedia); + +// js/helper/currency.js +function formatMoney(cents, format = "") { + if (typeof cents === "string") { + cents = cents.replace(".", ""); + } + const placeholderRegex = /\{\{\s*(\w+)\s*\}\}/, formatString = format || window.themeVariables.settings.moneyFormat; + function defaultTo(value2, defaultValue) { + return value2 == null || value2 !== value2 ? defaultValue : value2; + } + function formatWithDelimiters(number, precision, thousands, decimal) { + precision = defaultTo(precision, 2); + thousands = defaultTo(thousands, ","); + decimal = defaultTo(decimal, "."); + if (isNaN(number) || number == null) { + return 0; + } + number = (number / 100).toFixed(precision); + let parts = number.split("."), dollarsAmount = parts[0].replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1" + thousands), centsAmount = parts[1] ? decimal + parts[1] : ""; + return dollarsAmount + centsAmount; + } + let value = ""; + switch (formatString.match(placeholderRegex)[1]) { + case "amount": + value = formatWithDelimiters(cents, 2); + break; + case "amount_no_decimals": + value = formatWithDelimiters(cents, 0); + break; + case "amount_with_space_separator": + value = formatWithDelimiters(cents, 2, " ", "."); + break; + case "amount_with_comma_separator": + value = formatWithDelimiters(cents, 2, ".", ","); + break; + case "amount_with_apostrophe_separator": + value = formatWithDelimiters(cents, 2, "'", "."); + break; + case "amount_no_decimals_with_comma_separator": + value = formatWithDelimiters(cents, 0, ".", ","); + break; + case "amount_no_decimals_with_space_separator": + value = formatWithDelimiters(cents, 0, " "); + break; + case "amount_no_decimals_with_apostrophe_separator": + value = formatWithDelimiters(cents, 0, "'"); + break; + } + if (formatString.indexOf("with_comma_separator") !== -1) { + return formatString.replace(placeholderRegex, value); + } else { + return formatString.replace(placeholderRegex, value); + } +} + +// js/custom-element/section/product/product-meta.js +var ProductMeta = class extends HTMLElement { + connectedCallback() { + document.getElementById(this.getAttribute("form-id"))?.addEventListener("variant:changed", this._onVariantChanged.bind(this)); + } + get priceClass() { + return this.getAttribute("price-class") || ""; + } + get unitPriceClass() { + return this.getAttribute("unit-price-class") || ""; + } + _onVariantChanged(event) { + this._updateLabels(event.detail.variant); + this._updatePrices(event.detail.variant); + this._updateSku(event.detail.variant); + } + _updateLabels(variant) { + let productLabelList = this.querySelector("[data-product-label-list]"); + if (!productLabelList) { + return; + } + if (!variant) { + productLabelList.innerHTML = ""; + } else { + productLabelList.innerHTML = ""; + if (!variant["available"]) { + productLabelList.innerHTML = `${window.themeVariables.strings.collectionSoldOut}`; + } else if (variant["compare_at_price"] > variant["price"]) { + let savings = ""; + if (window.themeVariables.settings.discountMode === "percentage") { + savings = `${Math.round((variant["compare_at_price"] - variant["price"]) * 100 / variant["compare_at_price"])}%`; + } else { + savings = formatMoney(variant["compare_at_price"] - variant["price"]); + } + productLabelList.innerHTML = `${window.themeVariables.strings.collectionDiscount.replace("@savings@", savings)}`; + } + } + } + _updatePrices(variant) { + let productPrices = this.querySelector("[data-product-price-list]"), currencyFormat = window.themeVariables.settings.currencyCodeEnabled ? window.themeVariables.settings.moneyWithCurrencyFormat : window.themeVariables.settings.moneyFormat; + if (!productPrices) { + return; + } + if (!variant) { + productPrices.style.display = "none"; + } else { + // productPrices.innerHTML = ""; + if (variant["compare_at_price"] > variant["price"]) { + productPrices.querySelector("[data-price-yagi]").textContent = formatMoney(variant["price"], currencyFormat); + productPrices.querySelector("[data-price-yagi]").parentElement.classList.add("price--highlight"); + productPrices.querySelector("[data-compare-at-price-yagi]").textContent = formatMoney(variant["compare_at_price"], currencyFormat); + productPrices.querySelector("[data-compare-at-price-yagi]").parentElement.classList.remove("visually-hidden"); + /* + productPrices.innerHTML += `${window.themeVariables.strings.productSalePrice}${formatMoney(variant["price"], currencyFormat)}`; + productPrices.innerHTML += `${window.themeVariables.strings.productRegularPrice}${formatMoney(variant["compare_at_price"], currencyFormat)}`; + */ + } else { + productPrices.querySelector("[data-price-yagi]").textContent = formatMoney(variant["price"], currencyFormat); + productPrices.querySelector("[data-price-yagi]").parentElement.classList.remove("price--highlight"); + productPrices.querySelector("[data-price-yagi]").parentElement.classList.remove("visually-hidden"); + productPrices.querySelector("[data-compare-at-price-yagi]").textContent = ""; + productPrices.querySelector("[data-compare-at-price-yagi]").parentElement.classList.add("visually-hidden"); + + /* + productPrices.innerHTML += `${window.themeVariables.strings.productSalePrice}${formatMoney(variant["price"], currencyFormat)}`; + productPrices.innerHTML += `${window.themeVariables.strings.productRegularPrice}${formatMoney(variant["compare_at_price"], currencyFormat)}`; + */ + } + if (variant["unit_price_measurement"]) { + let referenceValue = ""; + if (variant["unit_price_measurement"]["reference_value"] !== 1) { + referenceValue = `${variant["unit_price_measurement"]["reference_value"]}`; + } + productPrices.innerHTML += ` +
+
+ ${formatMoney(variant["unit_price"])} + / + ${referenceValue} + ${variant["unit_price_measurement"]["reference_unit"]} +
+
+ `; + } + productPrices.style.display = ""; + } + } + _updateSku(variant) { + let productSku = this.querySelector("[data-product-sku-container]"); + if (!productSku) { + return; + } + let productSkuNumber = productSku.querySelector("[data-product-sku-number]"); + if (!variant || !variant["sku"]) { + productSku.style.display = "none"; + } else { + productSkuNumber.innerHTML = variant["sku"]; + productSku.style.display = ""; + } + } +}; +window.customElements.define("product-meta", ProductMeta); + +// js/custom-element/section/product-list/quick-buy-drawer.js +var QuickBuyDrawer = class extends DrawerContent { + connectedCallback() { + super.connectedCallback(); + this.delegate.on("variant:changed", this._onVariantChanged.bind(this)); + } + async _load() { + await super._load(); + this.imageElement = this.querySelector(".quick-buy-product__image"); + if (window.Shopify && window.Shopify.PaymentButton) { + window.Shopify.PaymentButton.init(); + } + } + _onVariantChanged(event) { + const variant = event.detail.variant; + if (variant) { + Array.from(this.querySelectorAll(`[href*="/products"]`)).forEach((link) => { + const url = new URL(link.href); + url.searchParams.set("variant", variant["id"]); + link.setAttribute("href", url.toString()); + }); + } + if (!this.imageElement || !variant || !variant["featured_media"]) { + return; + } + const featuredMedia = variant["featured_media"]; + if (featuredMedia["alt"]) { + this.imageElement.setAttribute("alt", featuredMedia["alt"]); + } + this.imageElement.setAttribute("width", featuredMedia["preview_image"]["width"]); + this.imageElement.setAttribute("height", featuredMedia["preview_image"]["height"]); + this.imageElement.setAttribute("src", getSizedMediaUrl(featuredMedia, "342x")); + this.imageElement.setAttribute("srcset", getMediaSrcset(featuredMedia, [114, 228, 342])); + } +}; +window.customElements.define("quick-buy-drawer", QuickBuyDrawer); + +// js/custom-element/section/product-list/quick-buy-popover.js +var QuickBuyPopover = class extends PopoverContent { + connectedCallback() { + super.connectedCallback(); + this.delegate.on("variant:changed", this._onVariantChanged.bind(this)); + this.delegate.on("variant:added", () => this.open = false); + } + async _load() { + await super._load(); + this.imageElement = this.querySelector(".quick-buy-product__image"); + } + _onVariantChanged(event) { + const variant = event.detail.variant; + if (variant) { + Array.from(this.querySelectorAll(`[href*="/products"]`)).forEach((link) => { + const url = new URL(link.href); + url.searchParams.set("variant", variant["id"]); + link.setAttribute("href", url.toString()); + }); + } + if (!this.imageElement || !variant || !variant["featured_media"]) { + return; + } + const featuredMedia = variant["featured_media"]; + if (featuredMedia["alt"]) { + this.imageElement.setAttribute("alt", featuredMedia["alt"]); + } + this.imageElement.setAttribute("width", featuredMedia["preview_image"]["width"]); + this.imageElement.setAttribute("height", featuredMedia["preview_image"]["height"]); + this.imageElement.setAttribute("src", getSizedMediaUrl(featuredMedia, "195x")); + this.imageElement.setAttribute("srcset", getMediaSrcset(featuredMedia, [65, 130, 195])); + } +}; +window.customElements.define("quick-buy-popover", QuickBuyPopover); + +// js/custom-element/section/product/store-pickup.js +var StorePickup = class extends HTMLElement { + connectedCallback() { + document.getElementById(this.getAttribute("form-id"))?.addEventListener("variant:changed", this._onVariantChanged.bind(this)); + } + _onVariantChanged(event) { + if (!event.detail.variant) { + this.innerHTML = ""; + } else { + this._renderForVariant(event.detail.variant["id"]); + } + } + async _renderForVariant(id) { + const response = await fetch(`${window.themeVariables.routes.rootUrlWithoutSlash}/variants/${id}?section_id=store-availability`), div = document.createElement("div"); + div.innerHTML = await response.text(); + this.innerHTML = div.firstElementChild.innerHTML.trim(); + } +}; +window.customElements.define("store-pickup", StorePickup); + +// js/custom-element/section/product/variants.js +var ProductVariants = class extends CustomHTMLElement { + async connectedCallback() { + this.masterSelector = document.getElementById(this.getAttribute("form-id")).id; + this.optionSelectors = Array.from(this.querySelectorAll("[data-selector-type]")); + if (!this.masterSelector) { + console.warn(`The variant selector for product with handle ${this.productHandle} is not linked to any product form.`); + return; + } + this.product = await ProductLoader.load(this.productHandle); + this.delegate.on("change", '[name^="option"]', this._onOptionChanged.bind(this)); + this.masterSelector.addEventListener("change", this._onMasterSelectorChanged.bind(this)); + this._updateDisableSelectors(); + this.selectVariant(this.selectedVariant["id"]); + } + get selectedVariant() { + return this._getVariantById(parseInt(this.masterSelector.value)); + } + get productHandle() { + return this.getAttribute("handle"); + } + get hideSoldOutVariants() { + return this.hasAttribute("hide-sold-out-variants"); + } + get updateUrl() { + return this.hasAttribute("update-url"); + } + /** + * Select a new variant by its ID + */ + selectVariant(id) { + if (!this._isVariantSelectable(this._getVariantById(id))) { + id = this._getFirstMatchingAvailableOrSelectableVariant()["id"]; + } + if (this.selectedVariant?.id === id) { + return; + } + this.masterSelector.value = id; + this.masterSelector.dispatchEvent(new Event("change", { bubbles: true })); + if (this.updateUrl && history.replaceState) { + const newUrl = new URL(window.location.href); + if (id) { + newUrl.searchParams.set("variant", id); + } else { + newUrl.searchParams.delete("variant"); + } + window.history.replaceState({ path: newUrl.toString() }, "", newUrl.toString()); + } + this._updateDisableSelectors(); + triggerEvent(this.masterSelector.form, "variant:changed", { variant: this.selectedVariant }); + } + _onOptionChanged() { + this.selectVariant(this._getVariantFromOptions()?.id); + } + _onMasterSelectorChanged() { + const options = this.selectedVariant?.options || []; + options.forEach((value, index) => { + let input = this.querySelector(`input[name="option${index + 1}"][value="${CSS.escape(value)}"], select[name="option${index + 1}"]`), triggerChangeEvent = false; + if (input.tagName === "SELECT") { + triggerChangeEvent = input.value !== value; + input.value = value; + } else if (input.tagName === "INPUT") { + triggerChangeEvent = !input.checked && input.value === value; + input.checked = input.value === value; + } + if (triggerChangeEvent) { + input.dispatchEvent(new Event("change", { bubbles: true })); + } + }); + } + /** + * Get the product variant by its ID + */ + _getVariantById(id) { + return this.product["variants"].find((variant) => variant["id"] === id); + } + /** + * Get the variant based on the options + */ + _getVariantFromOptions() { + const options = this._getSelectedOptionValues(); + return this.product["variants"].find((variant) => { + return variant["options"].every((value, index) => value === options[index]); + }); + } + /** + * Detect if a specific variant is selectable. This is used when the "hide sold out variant" option is enabled, to allow + * to return true only if the variant is actually available + */ + _isVariantSelectable(variant) { + if (!variant) { + return false; + } else { + return variant["available"] || !this.hideSoldOutVariants && !variant["available"]; + } + } + /** + * This method is used internally to select an available or selectable variant, when the current choice does not + * match the requirements. For instance, if sold out variants are configured to be hidden, but that the choices end + * up being a non-valid variant, the theme automatically changes the variant to match the requirements. In the case + * the customer end up on variant combinations that do not exist, it also switches to a valid combination. + * + * The algorithm is as follows: if we have for instance three options "Color", "Size" and "Material", we pop the last + * option (Material) and try to find the first available variant for the given Color and Size. If none is found we + * remove the second option (Size) and try to find the first available variant for the selected color. Finally, if none + * is found we return the first available variant independently of any choice. + */ + _getFirstMatchingAvailableOrSelectableVariant() { + let options = this._getSelectedOptionValues(), matchedVariant = null, slicedCount = 0; + do { + options.pop(); + slicedCount += 1; + matchedVariant = this.product["variants"].find((variant) => { + if (this.hideSoldOutVariants) { + return variant["available"] && variant["options"].slice(0, variant["options"].length - slicedCount).every((value, index) => value === options[index]); + } else { + return variant["options"].slice(0, variant["options"].length - slicedCount).every((value, index) => value === options[index]); + } + }); + } while (!matchedVariant && options.length > 0); + return matchedVariant; + } + _getSelectedOptionValues() { + const options = []; + Array.from(this.querySelectorAll('input[name^="option"]:checked, select[name^="option"]')).forEach((option) => options.push(option.value)); + return options; + } + /** + * We add specific class to sold out variants based on the selectors + */ + _updateDisableSelectors() { + const selectedVariant = this.selectedVariant; + if (!selectedVariant) { + return; + } + this._updateDisableSelectorsForOptionLevel(0, selectedVariant); + } + _updateDisableSelectorsForOptionLevel(level, selectedVariant) { + if (!this.optionSelectors[level]) { + return; + } + const applyClassToSelector = (selector, valueIndex, available, hasAtLeastOneCombination) => { + let selectorType = selector.getAttribute("data-selector-type"), cssSelector = ""; + switch (selectorType) { + case "swatch": + cssSelector = `.color-swatch:nth-child(${valueIndex + 1})`; + break; + case "variant-image": + cssSelector = `.variant-swatch:nth-child(${valueIndex + 1})`; + break; + case "block": + cssSelector = `.block-swatch:nth-child(${valueIndex + 1})`; + break; + case "dropdown": + cssSelector = `.combo-box__option-item:nth-child(${valueIndex + 1})`; + break; + } + selector.querySelector(cssSelector).toggleAttribute("hidden", !hasAtLeastOneCombination); + if (this.hideSoldOutVariants) { + selector.querySelector(cssSelector).toggleAttribute("hidden", !available); + } else { + selector.querySelector(cssSelector).classList.toggle("is-disabled", !available); + } + }; + const hasCombination = (variant, level2, value, selectedVariant2) => { + return Array.from({ length: level2 + 1 }, (_, i) => { + if (i === level2) { + return variant[`option${level2 + 1}`] === value; + } else { + return variant[`option${i + 1}`] === selectedVariant2[`option${i + 1}`]; + } + }).every((condition) => condition); + }; + this.product["options"][level]["values"].forEach((value, valueIndex) => { + const hasAtLeastOneCombination = this.product["variants"].some( + (variant) => hasCombination(variant, level, value, selectedVariant) && variant + ); + const hasAvailableVariant = this.product["variants"].some( + (variant) => hasCombination(variant, level, value, selectedVariant) && variant["available"] + ); + applyClassToSelector(this.optionSelectors[level], valueIndex, hasAvailableVariant, hasAtLeastOneCombination); + this._updateDisableSelectorsForOptionLevel(level + 1, selectedVariant); + }); + } +}; +window.customElements.define("product-variants", ProductVariants); + +// js/custom-element/section/product-list/product-item.js +var ProductItem = class extends CustomHTMLElement { + connectedCallback() { + this.primaryImageList = Array.from(this.querySelectorAll(".product-item__primary-image")); + this.delegate.on("change", ".product-item-meta__swatch-list .color-swatch__radio", this._onColorSwatchChanged.bind(this)); + this.delegate.on("mouseenter", ".product-item-meta__swatch-list .color-swatch__item", this._onColorSwatchHovered.bind(this), true); + } + async _onColorSwatchChanged(event, target) { + Array.from(this.querySelectorAll(`[href*="/products"]`)).forEach((link) => { + let url; + if (link.tagName === "A") { + url = new URL(link.href); + } else { + url = new URL(link.getAttribute("href"), `https://${window.themeVariables.routes.host}`); + } + url.searchParams.set("variant", target.getAttribute("data-variant-id")); + link.setAttribute("href", url.toString()); + }); + if (target.hasAttribute("data-variant-featured-media")) { + const newImage = this.primaryImageList.find((image) => image.getAttribute("data-media-id") === target.getAttribute("data-variant-featured-media")); + newImage.setAttribute("loading", "eager"); + const onImageLoaded = newImage.complete ? Promise.resolve() : new Promise((resolve) => newImage.onload = resolve); + await onImageLoaded; + newImage.removeAttribute("hidden"); + let properties = {}; + if (Array.from(newImage.parentElement.classList).some((item) => ["aspect-ratio--short", "aspect-ratio--tall", "aspect-ratio--square"].includes(item))) { + properties = [ + { clipPath: "polygon(0 0, 0 0, 0 100%, 0% 100%)", transform: "translate(calc(-50% - 20px), -50%)", zIndex: 1, offset: 0 }, + { clipPath: "polygon(0 0, 20% 0, 5% 100%, 0 100%)", transform: "translate(calc(-50% - 20px), -50%)", zIndex: 1, offset: 0.3 }, + { clipPath: "polygon(0 0, 100% 0, 100% 100%, 0 100%)", transform: "translate(-50%, -50%)", zIndex: 1, offset: 1 } + ]; + } else { + properties = [ + { clipPath: "polygon(0 0, 0 0, 0 100%, 0% 100%)", transform: "translateX(-20px)", zIndex: 1, offset: 0 }, + { clipPath: "polygon(0 0, 20% 0, 5% 100%, 0 100%)", transform: "translateX(-20px)", zIndex: 1, offset: 0.3 }, + { clipPath: "polygon(0 0, 100% 0, 100% 100%, 0 100%)", transform: "translateX(0px)", zIndex: 1, offset: 1 } + ]; + } + await newImage.animate(properties, { + duration: 500, + easing: "ease-in-out" + }).finished; + this.primaryImageList.filter((image) => image.classList.contains("product-item__primary-image") && image !== newImage).forEach((image) => image.setAttribute("hidden", "")); + } + } + _onColorSwatchHovered(event, target) { + const input = target.previousElementSibling; + if (input.hasAttribute("data-variant-featured-media")) { + const newImage = this.primaryImageList.find((image) => image.getAttribute("data-media-id") === input.getAttribute("data-variant-featured-media")); + newImage.setAttribute("loading", "eager"); + } + } +}; +window.customElements.define("product-item", ProductItem); + +// js/custom-element/section/product-facet/product-facet.js +var ProductFacet = class extends CustomHTMLElement { + connectedCallback() { + this.delegate.on("pagination:page-changed", this._rerender.bind(this)); + this.delegate.on("facet:criteria-changed", this._rerender.bind(this)); + this.delegate.on("facet:abort-loading", this._abort.bind(this)); + } + async _rerender(event) { + history.replaceState({}, "", event.detail.url); + this._abort(); + this.showLoadingBar(); + const url = new URL(window.location); + url.searchParams.set("section_id", this.getAttribute("section-id")); + try { + this.abortController = new AbortController(); + const response = await fetch(url.toString(), { signal: this.abortController.signal }); + const responseAsText = await response.text(); + const fakeDiv = document.createElement("div"); + fakeDiv.innerHTML = responseAsText; + this.querySelector("#facet-main").innerHTML = fakeDiv.querySelector("#facet-main").innerHTML; + const activeFilterList = Array.from(fakeDiv.querySelectorAll(".product-facet__active-list")), toolbarItem = document.querySelector(".mobile-toolbar__item--filters"); + if (toolbarItem) { + toolbarItem.classList.toggle("has-filters", activeFilterList.length > 0); + } + const filtersTempDiv = fakeDiv.querySelector("#facet-filters"); + if (filtersTempDiv) { + const previousScrollTop = this.querySelector("#facet-filters .drawer__content").scrollTop; + Array.from(this.querySelectorAll("#facet-filters-form .collapsible-toggle[aria-controls]")).forEach((filterToggle) => { + const filtersTempDivToggle = filtersTempDiv.querySelector(`[aria-controls="${filterToggle.getAttribute("aria-controls")}"]`), isExpanded = filterToggle.getAttribute("aria-expanded") === "true"; + if (filtersTempDivToggle) { + filtersTempDivToggle.setAttribute("aria-expanded", isExpanded ? "true" : "false"); + filtersTempDivToggle.nextElementSibling.toggleAttribute("open", isExpanded); + filtersTempDivToggle.nextElementSibling.style.overflow = isExpanded ? "visible" : ""; + } + }); + this.querySelector("#facet-filters").innerHTML = filtersTempDiv.innerHTML; + this.querySelector("#facet-filters .drawer__content").scrollTop = previousScrollTop; + } + const scrollTo = this.querySelector(".product-facet__meta-bar") || this.querySelector(".product-facet__product-list") || this.querySelector(".product-facet__main"); + requestAnimationFrame(() => { + scrollTo.scrollIntoView({ block: "start", behavior: "smooth" }); + }); + this.hideLoadingBar(); + } catch (e) { + if (e.name === "AbortError") { + return; + } + } + } + _abort() { + if (this.abortController) { + this.abortController.abort(); + } + } +}; +window.customElements.define("product-facet", ProductFacet); + +// js/custom-element/section/facet/facet-filters.js +var FacetFilters = class extends DrawerContent { + connectedCallback() { + super.connectedCallback(); + this.delegate.on("change", '[name^="filter."]', this._onFilterChanged.bind(this)); + this.rootDelegate.on("click", '[data-action="clear-filters"]', this._onFiltersCleared.bind(this)); + if (this.alwaysVisible) { + this.matchMedia = window.matchMedia(window.themeVariables.breakpoints.pocket); + this.matchMedia.addListener(this._adjustDrawer.bind(this)); + this._adjustDrawer(this.matchMedia); + } + } + get alwaysVisible() { + return this.hasAttribute("always-visible"); + } + _onFiltersCleared(event, target) { + event.preventDefault(); + triggerEvent(this, "facet:criteria-changed", { url: target.href }); + } + _onFilterChanged() { + const formData = new FormData(this.querySelector("#facet-filters-form")); + const searchParamsAsString = new URLSearchParams(formData).toString(); + triggerEvent(this, "facet:criteria-changed", { url: `${window.location.pathname}?${searchParamsAsString}` }); + } + _adjustDrawer(match) { + this.classList.toggle("drawer", match.matches); + this.classList.toggle("drawer--from-left", match.matches); + } +}; +window.customElements.define("facet-filters", FacetFilters); + +// js/custom-element/section/facet/sort-by-popover.js +var SortByPopover = class extends PopoverContent { + connectedCallback() { + super.connectedCallback(); + this.delegate.on("change", '[name="sort_by"]', this._onSortChanged.bind(this)); + } + _onSortChanged(event, target) { + const currentUrl = new URL(location.href); + currentUrl.searchParams.set("sort_by", target.value); + currentUrl.searchParams.delete("page"); + this.open = false; + this.dispatchEvent(new CustomEvent("facet:criteria-changed", { + bubbles: true, + detail: { + url: currentUrl.toString() + } + })); + } +}; +window.customElements.define("sort-by-popover", SortByPopover); + +// js/custom-element/section/cart/cart-count.js +var CartCount = class extends CustomHTMLElement { + connectedCallback() { + this.rootDelegate.on("cart:updated", (event) => this.innerText = event.detail.cart["item_count"]); + this.rootDelegate.on("cart:refresh", this._updateCartCount.bind(this)); + } + _updateCartCount(event) { + if (event?.detail?.cart) { + this.innerText = event.detail.cart["item_count"]; + } else { + fetch(Shopify.routes.root + "cart.js").then((response) => { + response.json().then((responseAsJson) => { + this.innerText = responseAsJson["item_count"]; + }); + }); + } + } +}; +window.customElements.define("cart-count", CartCount); + +// js/custom-element/section/cart/cart-drawer.js +var CartDrawer = class extends DrawerContent { + connectedCallback() { + super.connectedCallback(); + this.nextReplacementDelay = 0; + this.rootDelegate.on("cart:refresh", this._rerenderCart.bind(this)); + this.addEventListener("variant:added", () => this.nextReplacementDelay = 600); + } + async _rerenderCart(event) { + let cartContent = null, html = ""; + if (event.detail && event.detail["cart"] && event.detail["cart"]["sections"]) { + cartContent = event.detail["cart"]; + html = event.detail["cart"]["sections"]["mini-cart"]; + } else { + const response = await fetch(`${window.themeVariables.routes.cartUrl}?section_id=${this.getAttribute("section")}`); + html = await response.text(); + } + const fakeDiv = document.createElement("div"); + fakeDiv.innerHTML = html; + setTimeout(async () => { + const previousPosition = this.querySelector(".drawer__content").scrollTop; + if (cartContent && cartContent["item_count"] === 0) { + const animation = new CustomAnimation(new ParallelEffect(Array.from(this.querySelectorAll(".drawer__content, .drawer__footer")).map((item) => { + return new CustomKeyframeEffect(item, { opacity: [1, 0] }, { duration: 250, easing: "ease-in" }); + }))); + animation.play(); + await animation.finished; + } + this.innerHTML = fakeDiv.querySelector("cart-drawer").innerHTML; + if (cartContent && cartContent["item_count"] === 0) { + this.querySelector(".drawer__content").animate({ opacity: [0, 1], transform: ["translateY(40px)", "translateY(0)"] }, { duration: 450, easing: "cubic-bezier(0.33, 1, 0.68, 1)" }); + } else { + this.querySelector(".drawer__content").scrollTop = previousPosition; + } + if (event?.detail?.openMiniCart) { + this.clientWidth; + this.open = true; + } + }, event?.detail?.replacementDelay || this.nextReplacementDelay); + this.nextReplacementDelay = 0; + } + async attributeChangedCallback(name, oldValue, newValue) { + super.attributeChangedCallback(name, oldValue, newValue); + switch (name) { + case "open": + if (this.open) { + this.querySelector(".drawer__content").scrollTop = 0; + if (!MediaFeatures.prefersReducedMotion()) { + const lineItems = Array.from(this.querySelectorAll(".line-item")), recommendationsInner = this.querySelector(".mini-cart__recommendations-inner"), bottomBar = this.querySelector(".drawer__footer"), effects = []; + if (recommendationsInner && window.matchMedia(window.themeVariables.breakpoints.pocket).matches) { + lineItems.push(recommendationsInner); + } + lineItems.forEach((item) => item.style.opacity = 0); + recommendationsInner ? recommendationsInner.style.opacity = 0 : null; + bottomBar ? bottomBar.style.opacity = 0 : null; + effects.push(new ParallelEffect(lineItems.map((item, index) => { + return new CustomKeyframeEffect(item, { + opacity: [0, 1], + transform: ["translateX(40px)", "translateX(0)"] + }, { + duration: 400, + delay: 400 + 120 * index - Math.min(2 * index * index, 120 * index), + easing: "cubic-bezier(0.25, 1, 0.5, 1)" + }); + }))); + if (bottomBar) { + effects.push(new CustomKeyframeEffect(bottomBar, { + opacity: [0, 1], + transform: ["translateY(100%)", "translateY(0)"] + }, { + duration: 300, + delay: 400, + easing: "cubic-bezier(0.25, 1, 0.5, 1)" + })); + } + if (recommendationsInner && !window.matchMedia(window.themeVariables.breakpoints.pocket).matches) { + effects.push(new CustomKeyframeEffect(recommendationsInner, { + opacity: [0, 1], + transform: ["translateX(100%)", "translateX(0)"] + }, { + duration: 250, + delay: 400 + Math.max(120 * lineItems.length - 25 * lineItems.length, 25), + easing: "cubic-bezier(0.25, 1, 0.5, 1)" + })); + } + let animation = new CustomAnimation(new ParallelEffect(effects)); + animation.play(); + } + } + } + } +}; +window.customElements.define("cart-drawer", CartDrawer); + +// js/custom-element/section/cart/cart-drawer-recommendations.js +var _CartDrawerRecommendations = class _CartDrawerRecommendations extends HTMLElement { + async connectedCallback() { + if (!_CartDrawerRecommendations.recommendationsCache[this.productId]) { + _CartDrawerRecommendations.recommendationsCache[this.productId] = fetch(`${window.themeVariables.routes.productRecommendationsUrl}?product_id=${this.productId}&limit=10§ion_id=${this.sectionId}`); + } + const response = await _CartDrawerRecommendations.recommendationsCache[this.productId]; + const div = document.createElement("div"); + div.innerHTML = await response.clone().text(); + const productRecommendationsElement = div.querySelector("cart-drawer-recommendations"); + if (productRecommendationsElement && productRecommendationsElement.hasChildNodes()) { + this.innerHTML = productRecommendationsElement.innerHTML; + } else { + this.hidden = true; + } + } + get productId() { + return this.getAttribute("product-id"); + } + get sectionId() { + return this.getAttribute("section-id"); + } +}; +__publicField(_CartDrawerRecommendations, "recommendationsCache", {}); +var CartDrawerRecommendations = _CartDrawerRecommendations; +window.customElements.define("cart-drawer-recommendations", CartDrawerRecommendations); + +// js/custom-element/section/cart/cart-note.js +var CartNote = class extends HTMLTextAreaElement { + connectedCallback() { + this.addEventListener("change", this._onNoteChanged.bind(this)); + } + get ownedToggle() { + return this.hasAttribute("aria-owns") ? document.getElementById(this.getAttribute("aria-owns")) : null; + } + async _onNoteChanged() { + if (this.ownedToggle) { + this.ownedToggle.innerHTML = this.value === "" ? window.themeVariables.strings.cartAddOrderNote : window.themeVariables.strings.cartEditOrderNote; + } + const response = await fetch(`${window.themeVariables.routes.cartUrl}/update.js`, { + body: JSON.stringify({ note: this.value }), + credentials: "same-origin", + method: "POST", + headers: { + "Content-Type": "application/json" + } + }); + const cartContent = await response.json(); + document.documentElement.dispatchEvent(new CustomEvent("cart:updated", { + bubbles: true, + detail: { + cart: cartContent + } + })); + } +}; +window.customElements.define("cart-note", CartNote, { extends: "textarea" }); + +// js/custom-element/section/cart/free-shipping-bar.js +var FreeShippingBar = class extends HTMLElement { + connectedCallback() { + document.documentElement.addEventListener("cart:updated", this._onCartUpdated.bind(this)); + } + get threshold() { + return parseFloat(this.getAttribute("threshold")); + } + _onCartUpdated(event) { + const totalPrice = event.detail["cart"]["items"].filter((item) => item["requires_shipping"]).reduce((sum, item) => sum + item["final_line_price"], 0); + this.style.setProperty("--progress", Math.min(totalPrice / this.threshold, 1)); + } +}; +window.customElements.define("free-shipping-bar", FreeShippingBar); + +// js/custom-element/section/cart/item-quantity.js +var LineItemQuantity = class extends CustomHTMLElement { + connectedCallback() { + this.delegate.on("click", "a", this._onQuantityLinkClicked.bind(this)); + this.delegate.on("change", "input", this._onQuantityChanged.bind(this)); + } + _onQuantityLinkClicked(event, target) { + event.preventDefault(); + this._updateFromLink(target.href); + } + _onQuantityChanged(event, target) { + this._updateFromLink(`${window.themeVariables.routes.cartChangeUrl}?quantity=${target.value}&line=${target.getAttribute("data-line")}`); + } + async _updateFromLink(link) { + if (window.themeVariables.settings.pageType === "cart") { + window.location.href = link; + return; + } + const changeUrl = new URL(link, `https://${window.themeVariables.routes.host}`), searchParams = changeUrl.searchParams, line = searchParams.get("line"), id = searchParams.get("id"), quantity = parseInt(searchParams.get("quantity")); + this.dispatchEvent(new CustomEvent("line-item-quantity:change:start", { bubbles: true, detail: { newLineQuantity: quantity } })); + const response = await fetch(`${window.themeVariables.routes.cartChangeUrl}.js`, { + body: JSON.stringify({ line, id, quantity, sections: ["mini-cart"] }), + credentials: "same-origin", + method: "POST", + headers: { + "Content-Type": "application/json" + } + }); + if (response.ok) { + const cartContent = await response.json(); + this.dispatchEvent(new CustomEvent("line-item-quantity:change:end", { bubbles: true, detail: { cart: cartContent, newLineQuantity: quantity } })); + document.documentElement.dispatchEvent(new CustomEvent("cart:updated", { + bubbles: true, + detail: { + cart: cartContent + } + })); + document.documentElement.dispatchEvent(new CustomEvent("cart:refresh", { + bubbles: true, + detail: { + cart: cartContent, + replacementDelay: quantity === 0 ? 600 : 750 + } + })); + } else { + this.dispatchEvent(new CustomEvent("line-item-quantity:change:end", { bubbles: true })); + } + } +}; +window.customElements.define("line-item-quantity", LineItemQuantity); + +// js/custom-element/section/cart/line-item.js +var LineItem = class extends HTMLElement { + connectedCallback() { + this.lineItemLoader = this.querySelector(".line-item__loader"); + this.addEventListener("line-item-quantity:change:start", this._onQuantityStart.bind(this)); + this.addEventListener("line-item-quantity:change:end", this._onQuantityEnd.bind(this)); + } + _onQuantityStart() { + if (!this.lineItemLoader) { + return; + } + this.lineItemLoader.hidden = false; + this.lineItemLoader.firstElementChild.hidden = false; + this.lineItemLoader.lastElementChild.hidden = true; + } + async _onQuantityEnd(event) { + if (event?.detail?.cart["item_count"] === 0) { + return; + } + if (this.lineItemLoader) { + await this.lineItemLoader.firstElementChild.animate({ opacity: [1, 0], transform: ["translateY(0)", "translateY(-10px)"] }, 75).finished; + this.lineItemLoader.firstElementChild.hidden = true; + if (event?.detail?.newLineQuantity === 0) { + await this.animate({ opacity: [1, 0], height: [`${this.clientHeight}px`, 0] }, { duration: 300, easing: "ease" }).finished; + this.remove(); + } else { + this.lineItemLoader.lastElementChild.hidden = false; + await this.lineItemLoader.lastElementChild.animate({ opacity: [0, 1], transform: ["translateY(10px)", "translateY(0)"] }, { duration: 75, endDelay: 300 }).finished; + this.lineItemLoader.hidden = true; + } + } + } +}; +window.customElements.define("line-item", LineItem); + +// js/custom-element/section/cart/notification.js +var CartNotification = class extends CustomHTMLElement { + connectedCallback() { + this.rootDelegate.on("cart-notification:show", this._onShow.bind(this), !this.hasAttribute("global")); + this.delegate.on("click", '[data-action="close"]', (event) => { + event.stopPropagation(); + this.hidden = true; + }); + this.addEventListener("mouseenter", this.stopTimer.bind(this)); + this.addEventListener("mouseleave", this.startTimer.bind(this)); + window.addEventListener("pagehide", () => this.hidden = true); + } + set hidden(value) { + if (!value) { + this.startTimer(); + } else { + this.stopTimer(); + } + this.toggleAttribute("hidden", value); + } + get isInsideDrawer() { + return this.classList.contains("cart-notification--drawer"); + } + stopTimer() { + clearTimeout(this._timeout); + } + startTimer() { + this._timeout = setTimeout(() => this.hidden = true, 3e3); + } + _onShow(event) { + if (this.isInsideDrawer && !this.closest(".drawer").open) { + return; + } + if (this.hasAttribute("global") && event.detail.status === "success" && window.themeVariables.settings.cartType === "drawer") { + return; + } + event.stopPropagation(); + let closeButtonHtml = ""; + if (!this.isInsideDrawer) { + closeButtonHtml = ` + + `; + } + if (event.detail.status === "success") { + this.classList.remove("cart-notification--error"); + this.innerHTML = ` +
+
+
+ + + + + +
+ ${window.themeVariables.strings.cartItemAdded} + ${window.themeVariables.strings.cartItemAddedShort} + ${window.themeVariables.strings.cartViewCart} +
+ + ${closeButtonHtml} +
+
+
+ `; + } else { + this.classList.add("cart-notification--error"); + this.innerHTML = ` +
+
+
+ + + + + +
+ ${event.detail.error} +
+ + ${closeButtonHtml} +
+
+
+ `; + } + this.clientHeight; + this.hidden = false; + } +}; +window.customElements.define("cart-notification", CartNotification); + +// js/custom-element/section/cart/shipping-estimator.js +var ShippingEstimator = class extends HTMLElement { + connectedCallback() { + this.submitButton = this.querySelector('[type="button"]'); + this.submitButton.addEventListener("click", this._estimateShipping.bind(this)); + } + /** + * @doc https://shopify.dev/docs/themes/ajax-api/reference/cart#generate-shipping-rates + */ + async _estimateShipping() { + const zip = this.querySelector('[name="shipping-estimator[zip]"]').value, country = this.querySelector('[name="shipping-estimator[country]"]').value, province = this.querySelector('[name="shipping-estimator[province]"]').value; + this.submitButton.setAttribute("aria-busy", "true"); + const prepareResponse = await fetch(`${window.themeVariables.routes.cartUrl}/prepare_shipping_rates.json?shipping_address[zip]=${zip}&shipping_address[country]=${country}&shipping_address[province]=${province}`, { method: "POST" }); + if (prepareResponse.ok) { + const shippingRates = await this._getAsyncShippingRates(zip, country, province); + this._formatShippingRates(shippingRates); + } else { + const jsonError = await prepareResponse.json(); + this._formatError(jsonError); + } + this.submitButton.removeAttribute("aria-busy"); + } + async _getAsyncShippingRates(zip, country, province) { + const response = await fetch(`${window.themeVariables.routes.cartUrl}/async_shipping_rates.json?shipping_address[zip]=${zip}&shipping_address[country]=${country}&shipping_address[province]=${province}`); + const responseAsText = await response.text(); + if (responseAsText === "null") { + return this._getAsyncShippingRates(zip, country, province); + } else { + return JSON.parse(responseAsText)["shipping_rates"]; + } + } + _formatShippingRates(shippingRates) { + this.querySelector(".shipping-estimator__results")?.remove(); + let formattedShippingRates = ""; + shippingRates.forEach((shippingRate) => { + formattedShippingRates += `
  • ${shippingRate["presentment_name"]}: ${formatMoney(parseFloat(shippingRate["price"]) * 100)}
  • `; + }); + const html = ` +
    +

    ${shippingRates.length === 0 ? window.themeVariables.strings.shippingEstimatorNoResults : shippingRates.length === 1 ? window.themeVariables.strings.shippingEstimatorOneResult : window.themeVariables.strings.shippingEstimatorMultipleResults}

    + ${formattedShippingRates === "" ? "" : `
      ${formattedShippingRates}
    `} +
    + `; + this.insertAdjacentHTML("beforeend", html); + } + _formatError(errors) { + this.querySelector(".shipping-estimator__results")?.remove(); + let formattedShippingRates = ""; + Object.keys(errors).forEach((errorKey) => { + formattedShippingRates += `
  • ${errorKey} ${errors[errorKey]}
  • `; + }); + const html = ` +
    +

    ${window.themeVariables.strings.shippingEstimatorError}

    +
      ${formattedShippingRates}
    +
    + `; + this.insertAdjacentHTML("beforeend", html); + } +}; +window.customElements.define("shipping-estimator", ShippingEstimator); + +// js/custom-element/section/product/review-link.js +var ReviewLink = class extends HTMLAnchorElement { + constructor() { + super(); + this.addEventListener("click", this._onClick.bind(this)); + } + _onClick() { + const shopifyReviewsElement = document.getElementById("shopify-product-reviews"); + if (!shopifyReviewsElement) { + return; + } + if (window.matchMedia(window.themeVariables.breakpoints.pocket).matches) { + shopifyReviewsElement.closest("collapsible-content").open = true; + } else { + document.querySelector(`[aria-controls="${shopifyReviewsElement.closest(".product-tabs__tab-item-wrapper").id}"]`).click(); + } + } +}; +window.customElements.define("review-link", ReviewLink, { extends: "a" }); + +// js/custom-element/section/product/sticky-form.js +var ProductStickyForm = class extends HTMLElement { + connectedCallback() { + document.getElementById(this.getAttribute("form-id"))?.addEventListener("variant:changed", this._onVariantChanged.bind(this)); + this.imageElement = this.querySelector(".product-sticky-form__image"); + this.priceElement = this.querySelector(".product-sticky-form__price"); + this.unitPriceElement = this.querySelector(".product-sticky-form__unit-price"); + this._setupVisibilityObservers(); + } + disconnectedCallback() { + this.intersectionObserver.disconnect(); + } + set hidden(value) { + this.toggleAttribute("hidden", value); + if (value) { + document.documentElement.style.removeProperty("--cart-notification-offset"); + } else { + document.documentElement.style.setProperty("--cart-notification-offset", `${this.clientHeight}px`); + } + } + _onVariantChanged(event) { + const variant = event.detail.variant, currencyFormat = window.themeVariables.settings.currencyCodeEnabled ? window.themeVariables.settings.moneyWithCurrencyFormat : window.themeVariables.settings.moneyFormat; + if (!variant) { + return; + } + if (this.priceElement) { + this.priceElement.innerHTML = formatMoney(variant["price"], currencyFormat); + } + if (this.unitPriceElement) { + this.unitPriceElement.style.display = variant["unit_price_measurement"] ? "block" : "none"; + if (variant["unit_price_measurement"]) { + let referenceValue = ""; + if (variant["unit_price_measurement"]["reference_value"] !== 1) { + referenceValue = `${variant["unit_price_measurement"]["reference_value"]}`; + } + this.unitPriceElement.innerHTML = ` +
    + ${formatMoney(variant["unit_price"])} + / + ${referenceValue} + ${variant["unit_price_measurement"]["reference_unit"]} +
    + `; + } + } + if (!this.imageElement || !variant || !variant["featured_media"]) { + return; + } + const featuredMedia = variant["featured_media"]; + if (featuredMedia["alt"]) { + this.imageElement.setAttribute("alt", featuredMedia["alt"]); + } + this.imageElement.setAttribute("width", featuredMedia["preview_image"]["width"]); + this.imageElement.setAttribute("height", featuredMedia["preview_image"]["height"]); + this.imageElement.setAttribute("src", getSizedMediaUrl(featuredMedia, "165x")); + this.imageElement.setAttribute("srcset", getMediaSrcset(featuredMedia, [55, 110, 165])); + } + _setupVisibilityObservers() { + const paymentContainerElement = document.getElementById("MainPaymentContainer"), footerElement = document.querySelector(".shopify-section--footer"), stickyHeaderOffset = getStickyHeaderOffset(); + this._isFooterVisible = this._isPaymentContainerPassed = false; + this.intersectionObserver = new IntersectionObserver((entries) => { + entries.forEach((entry) => { + if (entry.target === footerElement) { + this._isFooterVisible = entry.intersectionRatio > 0; + } + if (entry.target === paymentContainerElement) { + const boundingRect = paymentContainerElement.getBoundingClientRect(); + this._isPaymentContainerPassed = entry.intersectionRatio === 0 && boundingRect.top + boundingRect.height <= stickyHeaderOffset; + } + }); + if (window.matchMedia(window.themeVariables.breakpoints.pocket).matches) { + this.hidden = !this._isPaymentContainerPassed || this._isFooterVisible; + } else { + this.hidden = !this._isPaymentContainerPassed; + } + }, { rootMargin: `-${stickyHeaderOffset}px 0px 0px 0px` }); + this.intersectionObserver.observe(paymentContainerElement); + this.intersectionObserver.observe(footerElement); + } +}; +window.customElements.define("product-sticky-form", ProductStickyForm); + +// js/theme.js +(() => { + new InputBindingManager(); +})(); +(() => { + if (Shopify.designMode) { + document.addEventListener("shopify:section:load", () => { + if (window.SPR) { + window.SPR.initDomEls(); + window.SPR.loadProducts(); + } + }); + } + window.SPRCallbacks = { + onFormSuccess: (event, info) => { + document.getElementById(`form_${info.id}`).classList.add("spr-form--success"); + } + }; +})(); +(() => { + let previousClientWidth = window.visualViewport ? window.visualViewport.width : document.documentElement.clientWidth; + let setViewportProperty = () => { + const clientWidth = window.visualViewport ? window.visualViewport.width : document.documentElement.clientWidth, clientHeight = window.visualViewport ? window.visualViewport.height : document.documentElement.clientHeight; + if (clientWidth === previousClientWidth) { + return; + } + requestAnimationFrame(() => { + document.documentElement.style.setProperty("--window-height", clientHeight + "px"); + previousClientWidth = clientWidth; + }); + }; + setViewportProperty(); + if (window.visualViewport) { + window.visualViewport.addEventListener("resize", setViewportProperty); + } else { + window.addEventListener("resize", setViewportProperty); + } +})(); +(() => { + let documentDelegate = new main_default(document.body); + documentDelegate.on("change", 'input:not([type="checkbox"]):not([type="radio"]), textarea', (event, target) => { + target.classList.toggle("is-filled", target.value !== ""); + }); + documentDelegate.on("change", "select", (event, target) => { + target.parentNode.classList.toggle("is-filled", target.value !== ""); + }); +})(); +(() => { + document.querySelectorAll(".rte table").forEach((table) => { + table.outerHTML = '
    ' + table.outerHTML + "
    "; + }); + document.querySelectorAll(".rte iframe").forEach((iframe) => { + if (iframe.src.indexOf("youtube") !== -1 || iframe.src.indexOf("youtu.be") !== -1 || iframe.src.indexOf("vimeo") !== -1) { + iframe.outerHTML = '
    ' + iframe.outerHTML + "
    "; + } + }); +})(); +(() => { + let documentDelegate = new main_default(document.documentElement); + documentDelegate.on("click", "[data-smooth-scroll]", (event, target) => { + const elementToScroll = document.querySelector(target.getAttribute("href")); + if (elementToScroll) { + event.preventDefault(); + elementToScroll.scrollIntoView({ behavior: "smooth", block: "start" }); + } + }); +})(); +(() => { + document.addEventListener("keyup", function(event) { + if (event.key === "Tab") { + document.body.classList.remove("no-focus-outline"); + document.body.classList.add("focus-outline"); + } + }); +})(); +/*! Bundled license information: + +tabbable/dist/index.esm.js: + (*! + * tabbable 6.2.0 + * @license MIT, https://github.com/focus-trap/tabbable/blob/master/LICENSE + *) + +focus-trap/dist/focus-trap.esm.js: + (*! + * focus-trap 7.5.4 + * @license MIT, https://github.com/focus-trap/focus-trap/blob/master/LICENSE + *) +*/ + +/*! + * Isotope PACKAGED v2.1.1 + * Filter & sort magical layouts + * http://isotope.metafizzy.co + */ + +(function(t){function e(){}function i(t){function i(e){e.prototype.option||(e.prototype.option=function(e){t.isPlainObject(e)&&(this.options=t.extend(!0,this.options,e))})}function n(e,i){t.fn[e]=function(n){if("string"==typeof n){for(var s=o.call(arguments,1),a=0,u=this.length;u>a;a++){var p=this[a],h=t.data(p,e);if(h)if(t.isFunction(h[n])&&"_"!==n.charAt(0)){var f=h[n].apply(h,s);if(void 0!==f)return f}else r("no such method '"+n+"' for "+e+" instance");else r("cannot call methods on "+e+" prior to initialization; "+"attempted to call '"+n+"'")}return this}return this.each(function(){var o=t.data(this,e);o?(o.option(n),o._init()):(o=new i(this,n),t.data(this,e,o))})}}if(t){var r="undefined"==typeof console?e:function(t){void 0};return t.bridget=function(t,e){i(e),n(t,e)},t.bridget}}var o=Array.prototype.slice;"function"==typeof define&&define.amd?define("jquery-bridget/jquery.bridget",["jquery"],i):"object"==typeof exports?i(require("jquery")):i(t.jQuery)})(window),function(t){function e(e){var i=t.event;return i.target=i.target||i.srcElement||e,i}var i=document.documentElement,o=function(){};i.addEventListener?o=function(t,e,i){t.addEventListener(e,i,!1)}:i.attachEvent&&(o=function(t,i,o){t[i+o]=o.handleEvent?function(){var i=e(t);o.handleEvent.call(o,i)}:function(){var i=e(t);o.call(t,i)},t.attachEvent("on"+i,t[i+o])});var n=function(){};i.removeEventListener?n=function(t,e,i){t.removeEventListener(e,i,!1)}:i.detachEvent&&(n=function(t,e,i){t.detachEvent("on"+e,t[e+i]);try{delete t[e+i]}catch(o){t[e+i]=void 0}});var r={bind:o,unbind:n};"function"==typeof define&&define.amd?define("eventie/eventie",r):"object"==typeof exports?module.exports=r:t.eventie=r}(this),function(t){function e(t){"function"==typeof t&&(e.isReady?t():s.push(t))}function i(t){var i="readystatechange"===t.type&&"complete"!==r.readyState;e.isReady||i||o()}function o(){e.isReady=!0;for(var t=0,i=s.length;i>t;t++){var o=s[t];o()}}function n(n){return"complete"===r.readyState?o():(n.bind(r,"DOMContentLoaded",i),n.bind(r,"readystatechange",i),n.bind(t,"load",i)),e}var r=t.document,s=[];e.isReady=!1,"function"==typeof define&&define.amd?define("doc-ready/doc-ready",["eventie/eventie"],n):"object"==typeof exports?module.exports=n(require("eventie")):t.docReady=n(t.eventie)}(window),function(){function t(){}function e(t,e){for(var i=t.length;i--;)if(t[i].listener===e)return i;return-1}function i(t){return function(){return this[t].apply(this,arguments)}}var o=t.prototype,n=this,r=n.EventEmitter;o.getListeners=function(t){var e,i,o=this._getEvents();if(t instanceof RegExp){e={};for(i in o)o.hasOwnProperty(i)&&t.test(i)&&(e[i]=o[i])}else e=o[t]||(o[t]=[]);return e},o.flattenListeners=function(t){var e,i=[];for(e=0;t.length>e;e+=1)i.push(t[e].listener);return i},o.getListenersAsObject=function(t){var e,i=this.getListeners(t);return i instanceof Array&&(e={},e[t]=i),e||i},o.addListener=function(t,i){var o,n=this.getListenersAsObject(t),r="object"==typeof i;for(o in n)n.hasOwnProperty(o)&&-1===e(n[o],i)&&n[o].push(r?i:{listener:i,once:!1});return this},o.on=i("addListener"),o.addOnceListener=function(t,e){return this.addListener(t,{listener:e,once:!0})},o.once=i("addOnceListener"),o.defineEvent=function(t){return this.getListeners(t),this},o.defineEvents=function(t){for(var e=0;t.length>e;e+=1)this.defineEvent(t[e]);return this},o.removeListener=function(t,i){var o,n,r=this.getListenersAsObject(t);for(n in r)r.hasOwnProperty(n)&&(o=e(r[n],i),-1!==o&&r[n].splice(o,1));return this},o.off=i("removeListener"),o.addListeners=function(t,e){return this.manipulateListeners(!1,t,e)},o.removeListeners=function(t,e){return this.manipulateListeners(!0,t,e)},o.manipulateListeners=function(t,e,i){var o,n,r=t?this.removeListener:this.addListener,s=t?this.removeListeners:this.addListeners;if("object"!=typeof e||e instanceof RegExp)for(o=i.length;o--;)r.call(this,e,i[o]);else for(o in e)e.hasOwnProperty(o)&&(n=e[o])&&("function"==typeof n?r.call(this,o,n):s.call(this,o,n));return this},o.removeEvent=function(t){var e,i=typeof t,o=this._getEvents();if("string"===i)delete o[t];else if(t instanceof RegExp)for(e in o)o.hasOwnProperty(e)&&t.test(e)&&delete o[e];else delete this._events;return this},o.removeAllListeners=i("removeEvent"),o.emitEvent=function(t,e){var i,o,n,r,s=this.getListenersAsObject(t);for(n in s)if(s.hasOwnProperty(n))for(o=s[n].length;o--;)i=s[n][o],i.once===!0&&this.removeListener(t,i.listener),r=i.listener.apply(this,e||[]),r===this._getOnceReturnValue()&&this.removeListener(t,i.listener);return this},o.trigger=i("emitEvent"),o.emit=function(t){var e=Array.prototype.slice.call(arguments,1);return this.emitEvent(t,e)},o.setOnceReturnValue=function(t){return this._onceReturnValue=t,this},o._getOnceReturnValue=function(){return this.hasOwnProperty("_onceReturnValue")?this._onceReturnValue:!0},o._getEvents=function(){return this._events||(this._events={})},t.noConflict=function(){return n.EventEmitter=r,t},"function"==typeof define&&define.amd?define("eventEmitter/EventEmitter",[],function(){return t}):"object"==typeof module&&module.exports?module.exports=t:n.EventEmitter=t}.call(this),function(t){function e(t){if(t){if("string"==typeof o[t])return t;t=t.charAt(0).toUpperCase()+t.slice(1);for(var e,n=0,r=i.length;r>n;n++)if(e=i[n]+t,"string"==typeof o[e])return e}}var i="Webkit Moz ms Ms O".split(" "),o=document.documentElement.style;"function"==typeof define&&define.amd?define("get-style-property/get-style-property",[],function(){return e}):"object"==typeof exports?module.exports=e:t.getStyleProperty=e}(window),function(t){function e(t){var e=parseFloat(t),i=-1===t.indexOf("%")&&!isNaN(e);return i&&e}function i(){}function o(){for(var t={width:0,height:0,innerWidth:0,innerHeight:0,outerWidth:0,outerHeight:0},e=0,i=s.length;i>e;e++){var o=s[e];t[o]=0}return t}function n(i){function n(){if(!d){d=!0;var o=t.getComputedStyle;if(p=function(){var t=o?function(t){return o(t,null)}:function(t){return t.currentStyle};return function(e){var i=t(e);return i||r("Style returned "+i+". Are you running this code in a hidden iframe on Firefox? "+"See http://bit.ly/getsizebug1"),i}}(),h=i("boxSizing")){var n=document.createElement("div");n.style.width="200px",n.style.padding="1px 2px 3px 4px",n.style.borderStyle="solid",n.style.borderWidth="1px 2px 3px 4px",n.style[h]="border-box";var s=document.body||document.documentElement;s.appendChild(n);var a=p(n);f=200===e(a.width),s.removeChild(n)}}}function a(t){if(n(),"string"==typeof t&&(t=document.querySelector(t)),t&&"object"==typeof t&&t.nodeType){var i=p(t);if("none"===i.display)return o();var r={};r.width=t.offsetWidth,r.height=t.offsetHeight;for(var a=r.isBorderBox=!(!h||!i[h]||"border-box"!==i[h]),d=0,l=s.length;l>d;d++){var c=s[d],y=i[c];y=u(t,y);var m=parseFloat(y);r[c]=isNaN(m)?0:m}var g=r.paddingLeft+r.paddingRight,v=r.paddingTop+r.paddingBottom,_=r.marginLeft+r.marginRight,I=r.marginTop+r.marginBottom,L=r.borderLeftWidth+r.borderRightWidth,z=r.borderTopWidth+r.borderBottomWidth,b=a&&f,x=e(i.width);x!==!1&&(r.width=x+(b?0:g+L));var S=e(i.height);return S!==!1&&(r.height=S+(b?0:v+z)),r.innerWidth=r.width-(g+L),r.innerHeight=r.height-(v+z),r.outerWidth=r.width+_,r.outerHeight=r.height+I,r}}function u(e,i){if(t.getComputedStyle||-1===i.indexOf("%"))return i;var o=e.style,n=o.left,r=e.runtimeStyle,s=r&&r.left;return s&&(r.left=e.currentStyle.left),o.left=i,i=o.pixelLeft,o.left=n,s&&(r.left=s),i}var p,h,f,d=!1;return a}var r="undefined"==typeof console?i:function(t){void 0},s=["paddingLeft","paddingRight","paddingTop","paddingBottom","marginLeft","marginRight","marginTop","marginBottom","borderLeftWidth","borderRightWidth","borderTopWidth","borderBottomWidth"];"function"==typeof define&&define.amd?define("get-size/get-size",["get-style-property/get-style-property"],n):"object"==typeof exports?module.exports=n(require("desandro-get-style-property")):t.getSize=n(t.getStyleProperty)}(window),function(t){function e(t,e){return t[s](e)}function i(t){if(!t.parentNode){var e=document.createDocumentFragment();e.appendChild(t)}}function o(t,e){i(t);for(var o=t.parentNode.querySelectorAll(e),n=0,r=o.length;r>n;n++)if(o[n]===t)return!0;return!1}function n(t,o){return i(t),e(t,o)}var r,s=function(){if(t.matchesSelector)return"matchesSelector";for(var e=["webkit","moz","ms","o"],i=0,o=e.length;o>i;i++){var n=e[i],r=n+"MatchesSelector";if(t[r])return r}}();if(s){var a=document.createElement("div"),u=e(a,"div");r=u?e:n}else r=o;"function"==typeof define&&define.amd?define("matches-selector/matches-selector",[],function(){return r}):"object"==typeof exports?module.exports=r:window.matchesSelector=r}(Element.prototype),function(t){function e(t,e){for(var i in e)t[i]=e[i];return t}function i(t){for(var e in t)return!1;return e=null,!0}function o(t){return t.replace(/([A-Z])/g,function(t){return"-"+t.toLowerCase()})}function n(t,n,r){function a(t,e){t&&(this.element=t,this.layout=e,this.position={x:0,y:0},this._create())}var u=r("transition"),p=r("transform"),h=u&&p,f=!!r("perspective"),d={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"otransitionend",transition:"transitionend"}[u],l=["transform","transition","transitionDuration","transitionProperty"],c=function(){for(var t={},e=0,i=l.length;i>e;e++){var o=l[e],n=r(o);n&&n!==o&&(t[o]=n)}return t}();e(a.prototype,t.prototype),a.prototype._create=function(){this._transn={ingProperties:{},clean:{},onEnd:{}},this.css({position:"absolute"})},a.prototype.handleEvent=function(t){var e="on"+t.type;this[e]&&this[e](t)},a.prototype.getSize=function(){this.size=n(this.element)},a.prototype.css=function(t){var e=this.element.style;for(var i in t){var o=c[i]||i;e[o]=t[i]}},a.prototype.getPosition=function(){var t=s(this.element),e=this.layout.options,i=e.isOriginLeft,o=e.isOriginTop,n=parseInt(t[i?"left":"right"],10),r=parseInt(t[o?"top":"bottom"],10);n=isNaN(n)?0:n,r=isNaN(r)?0:r;var a=this.layout.size;n-=i?a.paddingLeft:a.paddingRight,r-=o?a.paddingTop:a.paddingBottom,this.position.x=n,this.position.y=r},a.prototype.layoutPosition=function(){var t=this.layout.size,e=this.layout.options,i={};e.isOriginLeft?(i.left=this.position.x+t.paddingLeft+"px",i.right=""):(i.right=this.position.x+t.paddingRight+"px",i.left=""),e.isOriginTop?(i.top=this.position.y+t.paddingTop+"px",i.bottom=""):(i.bottom=this.position.y+t.paddingBottom+"px",i.top=""),this.css(i),this.emitEvent("layout",[this])};var y=f?function(t,e){return"translate3d("+t+"px, "+e+"px, 0)"}:function(t,e){return"translate("+t+"px, "+e+"px)"};a.prototype._transitionTo=function(t,e){this.getPosition();var i=this.position.x,o=this.position.y,n=parseInt(t,10),r=parseInt(e,10),s=n===this.position.x&&r===this.position.y;if(this.setPosition(t,e),s&&!this.isTransitioning)return this.layoutPosition(),void 0;var a=t-i,u=e-o,p={},h=this.layout.options;a=h.isOriginLeft?a:-a,u=h.isOriginTop?u:-u,p.transform=y(a,u),this.transition({to:p,onTransitionEnd:{transform:this.layoutPosition},isCleaning:!0})},a.prototype.goTo=function(t,e){this.setPosition(t,e),this.layoutPosition()},a.prototype.moveTo=h?a.prototype._transitionTo:a.prototype.goTo,a.prototype.setPosition=function(t,e){this.position.x=parseInt(t,10),this.position.y=parseInt(e,10)},a.prototype._nonTransition=function(t){this.css(t.to),t.isCleaning&&this._removeStyles(t.to);for(var e in t.onTransitionEnd)t.onTransitionEnd[e].call(this)},a.prototype._transition=function(t){if(!parseFloat(this.layout.options.transitionDuration))return this._nonTransition(t),void 0;var e=this._transn;for(var i in t.onTransitionEnd)e.onEnd[i]=t.onTransitionEnd[i];for(i in t.to)e.ingProperties[i]=!0,t.isCleaning&&(e.clean[i]=!0);if(t.from){this.css(t.from);var o=this.element.offsetHeight;o=null}this.enableTransition(t.to),this.css(t.to),this.isTransitioning=!0};var m=p&&o(p)+",opacity";a.prototype.enableTransition=function(){this.isTransitioning||(this.css({transitionProperty:m,transitionDuration:this.layout.options.transitionDuration}),this.element.addEventListener(d,this,!1))},a.prototype.transition=a.prototype[u?"_transition":"_nonTransition"],a.prototype.onwebkitTransitionEnd=function(t){this.ontransitionend(t)},a.prototype.onotransitionend=function(t){this.ontransitionend(t)};var g={"-webkit-transform":"transform","-moz-transform":"transform","-o-transform":"transform"};a.prototype.ontransitionend=function(t){if(t.target===this.element){var e=this._transn,o=g[t.propertyName]||t.propertyName;if(delete e.ingProperties[o],i(e.ingProperties)&&this.disableTransition(),o in e.clean&&(this.element.style[t.propertyName]="",delete e.clean[o]),o in e.onEnd){var n=e.onEnd[o];n.call(this),delete e.onEnd[o]}this.emitEvent("transitionEnd",[this])}},a.prototype.disableTransition=function(){this.removeTransitionStyles(),this.element.removeEventListener(d,this,!1),this.isTransitioning=!1},a.prototype._removeStyles=function(t){var e={};for(var i in t)e[i]="";this.css(e)};var v={transitionProperty:"",transitionDuration:""};return a.prototype.removeTransitionStyles=function(){this.css(v)},a.prototype.removeElem=function(){this.element.parentNode.removeChild(this.element),this.emitEvent("remove",[this])},a.prototype.remove=function(){if(!u||!parseFloat(this.layout.options.transitionDuration))return this.removeElem(),void 0;var t=this;this.on("transitionEnd",function(){return t.removeElem(),!0}),this.hide()},a.prototype.reveal=function(){delete this.isHidden,this.css({display:""});var t=this.layout.options;this.transition({from:t.hiddenStyle,to:t.visibleStyle,isCleaning:!0})},a.prototype.hide=function(){this.isHidden=!0,this.css({display:""});var t=this.layout.options;this.transition({from:t.visibleStyle,to:t.hiddenStyle,isCleaning:!0,onTransitionEnd:{opacity:function(){this.isHidden&&this.css({display:"none"})}}})},a.prototype.destroy=function(){this.css({position:"",left:"",right:"",top:"",bottom:"",transition:"",transform:""})},a}var r=t.getComputedStyle,s=r?function(t){return r(t,null)}:function(t){return t.currentStyle};"function"==typeof define&&define.amd?define("outlayer/item",["eventEmitter/EventEmitter","get-size/get-size","get-style-property/get-style-property"],n):"object"==typeof exports?module.exports=n(require("wolfy87-eventemitter"),require("get-size"),require("desandro-get-style-property")):(t.Outlayer={},t.Outlayer.Item=n(t.EventEmitter,t.getSize,t.getStyleProperty))}(window),function(t){function e(t,e){for(var i in e)t[i]=e[i];return t}function i(t){return"[object Array]"===f.call(t)}function o(t){var e=[];if(i(t))e=t;else if(t&&"number"==typeof t.length)for(var o=0,n=t.length;n>o;o++)e.push(t[o]);else e.push(t);return e}function n(t,e){var i=l(e,t);-1!==i&&e.splice(i,1)}function r(t){return t.replace(/(.)([A-Z])/g,function(t,e,i){return e+"-"+i}).toLowerCase()}function s(i,s,f,l,c,y){function m(t,i){if("string"==typeof t&&(t=a.querySelector(t)),!t||!d(t))return u&&u.error("Bad "+this.constructor.namespace+" element: "+t),void 0;this.element=t,this.options=e({},this.constructor.defaults),this.option(i);var o=++g;this.element.outlayerGUID=o,v[o]=this,this._create(),this.options.isInitLayout&&this.layout()}var g=0,v={};return m.namespace="outlayer",m.Item=y,m.defaults={containerStyle:{position:"relative"},isInitLayout:!0,isOriginLeft:!0,isOriginTop:!0,isResizeBound:!0,isResizingContainer:!0,transitionDuration:"0.4s",hiddenStyle:{opacity:0,transform:"scale(0.001)"},visibleStyle:{opacity:1,transform:"scale(1)"}},e(m.prototype,f.prototype),m.prototype.option=function(t){e(this.options,t)},m.prototype._create=function(){this.reloadItems(),this.stamps=[],this.stamp(this.options.stamp),e(this.element.style,this.options.containerStyle),this.options.isResizeBound&&this.bindResize()},m.prototype.reloadItems=function(){this.items=this._itemize(this.element.children)},m.prototype._itemize=function(t){for(var e=this._filterFindItemElements(t),i=this.constructor.Item,o=[],n=0,r=e.length;r>n;n++){var s=e[n],a=new i(s,this);o.push(a)}return o},m.prototype._filterFindItemElements=function(t){t=o(t);for(var e=this.options.itemSelector,i=[],n=0,r=t.length;r>n;n++){var s=t[n];if(d(s))if(e){c(s,e)&&i.push(s);for(var a=s.querySelectorAll(e),u=0,p=a.length;p>u;u++)i.push(a[u])}else i.push(s)}return i},m.prototype.getItemElements=function(){for(var t=[],e=0,i=this.items.length;i>e;e++)t.push(this.items[e].element);return t},m.prototype.layout=function(){this._resetLayout(),this._manageStamps();var t=void 0!==this.options.isLayoutInstant?this.options.isLayoutInstant:!this._isLayoutInited;this.layoutItems(this.items,t),this._isLayoutInited=!0},m.prototype._init=m.prototype.layout,m.prototype._resetLayout=function(){this.getSize()},m.prototype.getSize=function(){this.size=l(this.element)},m.prototype._getMeasurement=function(t,e){var i,o=this.options[t];o?("string"==typeof o?i=this.element.querySelector(o):d(o)&&(i=o),this[t]=i?l(i)[e]:o):this[t]=0},m.prototype.layoutItems=function(t,e){t=this._getItemsForLayout(t),this._layoutItems(t,e),this._postLayout()},m.prototype._getItemsForLayout=function(t){for(var e=[],i=0,o=t.length;o>i;i++){var n=t[i];n.isIgnored||e.push(n)}return e},m.prototype._layoutItems=function(t,e){function i(){o.emitEvent("layoutComplete",[o,t])}var o=this;if(!t||!t.length)return i(),void 0;this._itemsOn(t,"layout",i);for(var n=[],r=0,s=t.length;s>r;r++){var a=t[r],u=this._getItemLayoutPosition(a);u.item=a,u.isInstant=e||a.isLayoutInstant,n.push(u)}this._processLayoutQueue(n)},m.prototype._getItemLayoutPosition=function(){return{x:0,y:0}},m.prototype._processLayoutQueue=function(t){for(var e=0,i=t.length;i>e;e++){var o=t[e];this._positionItem(o.item,o.x,o.y,o.isInstant)}},m.prototype._positionItem=function(t,e,i,o){o?t.goTo(e,i):t.moveTo(e,i)},m.prototype._postLayout=function(){this.resizeContainer()},m.prototype.resizeContainer=function(){if(this.options.isResizingContainer){var t=this._getContainerSize();t&&(this._setContainerMeasure(t.width,!0),this._setContainerMeasure(t.height,!1))}},m.prototype._getContainerSize=h,m.prototype._setContainerMeasure=function(t,e){if(void 0!==t){var i=this.size;i.isBorderBox&&(t+=e?i.paddingLeft+i.paddingRight+i.borderLeftWidth+i.borderRightWidth:i.paddingBottom+i.paddingTop+i.borderTopWidth+i.borderBottomWidth),t=Math.max(t,0),this.element.style[e?"width":"height"]=t+"px"}},m.prototype._itemsOn=function(t,e,i){function o(){return n++,n===r&&i.call(s),!0}for(var n=0,r=t.length,s=this,a=0,u=t.length;u>a;a++){var p=t[a];p.on(e,o)}},m.prototype.ignore=function(t){var e=this.getItem(t);e&&(e.isIgnored=!0)},m.prototype.unignore=function(t){var e=this.getItem(t);e&&delete e.isIgnored},m.prototype.stamp=function(t){if(t=this._find(t)){this.stamps=this.stamps.concat(t);for(var e=0,i=t.length;i>e;e++){var o=t[e];this.ignore(o)}}},m.prototype.unstamp=function(t){if(t=this._find(t))for(var e=0,i=t.length;i>e;e++){var o=t[e];n(o,this.stamps),this.unignore(o)}},m.prototype._find=function(t){return t?("string"==typeof t&&(t=this.element.querySelectorAll(t)),t=o(t)):void 0},m.prototype._manageStamps=function(){if(this.stamps&&this.stamps.length){this._getBoundingRect();for(var t=0,e=this.stamps.length;e>t;t++){var i=this.stamps[t];this._manageStamp(i)}}},m.prototype._getBoundingRect=function(){var t=this.element.getBoundingClientRect(),e=this.size;this._boundingRect={left:t.left+e.paddingLeft+e.borderLeftWidth,top:t.top+e.paddingTop+e.borderTopWidth,right:t.right-(e.paddingRight+e.borderRightWidth),bottom:t.bottom-(e.paddingBottom+e.borderBottomWidth)}},m.prototype._manageStamp=h,m.prototype._getElementOffset=function(t){var e=t.getBoundingClientRect(),i=this._boundingRect,o=l(t),n={left:e.left-i.left-o.marginLeft,top:e.top-i.top-o.marginTop,right:i.right-e.right-o.marginRight,bottom:i.bottom-e.bottom-o.marginBottom};return n},m.prototype.handleEvent=function(t){var e="on"+t.type;this[e]&&this[e](t)},m.prototype.bindResize=function(){this.isResizeBound||(i.bind(t,"resize",this),this.isResizeBound=!0)},m.prototype.unbindResize=function(){this.isResizeBound&&i.unbind(t,"resize",this),this.isResizeBound=!1},m.prototype.onresize=function(){function t(){e.resize(),delete e.resizeTimeout}this.resizeTimeout&&clearTimeout(this.resizeTimeout);var e=this;this.resizeTimeout=setTimeout(t,100)},m.prototype.resize=function(){this.isResizeBound&&this.needsResizeLayout()&&this.layout()},m.prototype.needsResizeLayout=function(){var t=l(this.element),e=this.size&&t;return e&&t.innerWidth!==this.size.innerWidth},m.prototype.addItems=function(t){var e=this._itemize(t);return e.length&&(this.items=this.items.concat(e)),e},m.prototype.appended=function(t){var e=this.addItems(t);e.length&&(this.layoutItems(e,!0),this.reveal(e))},m.prototype.prepended=function(t){var e=this._itemize(t);if(e.length){var i=this.items.slice(0);this.items=e.concat(i),this._resetLayout(),this._manageStamps(),this.layoutItems(e,!0),this.reveal(e),this.layoutItems(i)}},m.prototype.reveal=function(t){var e=t&&t.length;if(e)for(var i=0;e>i;i++){var o=t[i];o.reveal()}},m.prototype.hide=function(t){var e=t&&t.length;if(e)for(var i=0;e>i;i++){var o=t[i];o.hide()}},m.prototype.getItem=function(t){for(var e=0,i=this.items.length;i>e;e++){var o=this.items[e];if(o.element===t)return o}},m.prototype.getItems=function(t){if(t&&t.length){for(var e=[],i=0,o=t.length;o>i;i++){var n=t[i],r=this.getItem(n);r&&e.push(r)}return e}},m.prototype.remove=function(t){t=o(t);var e=this.getItems(t);if(e&&e.length){this._itemsOn(e,"remove",function(){this.emitEvent("removeComplete",[this,e])});for(var i=0,r=e.length;r>i;i++){var s=e[i];s.remove(),n(s,this.items)}}},m.prototype.destroy=function(){var t=this.element.style;t.height="",t.position="",t.width="";for(var e=0,i=this.items.length;i>e;e++){var o=this.items[e];o.destroy()}this.unbindResize();var n=this.element.outlayerGUID;delete v[n],delete this.element.outlayerGUID,p&&p.removeData(this.element,this.constructor.namespace)},m.data=function(t){var e=t&&t.outlayerGUID;return e&&v[e]},m.create=function(t,i){function o(){m.apply(this,arguments)}return Object.create?o.prototype=Object.create(m.prototype):e(o.prototype,m.prototype),o.prototype.constructor=o,o.defaults=e({},m.defaults),e(o.defaults,i),o.prototype.settings={},o.namespace=t,o.data=m.data,o.Item=function(){y.apply(this,arguments)},o.Item.prototype=new y,s(function(){for(var e=r(t),i=a.querySelectorAll(".js-"+e),n="data-"+e+"-options",s=0,h=i.length;h>s;s++){var f,d=i[s],l=d.getAttribute(n);try{f=l&&JSON.parse(l)}catch(c){u&&u.error("Error parsing "+n+" on "+d.nodeName.toLowerCase()+(d.id?"#"+d.id:"")+": "+c);continue}var y=new o(d,f);p&&p.data(d,t,y)}}),p&&p.bridget&&p.bridget(t,o),o},m.Item=y,m}var a=t.document,u=t.console,p=t.jQuery,h=function(){},f=Object.prototype.toString,d="function"==typeof HTMLElement||"object"==typeof HTMLElement?function(t){return t instanceof HTMLElement}:function(t){return t&&"object"==typeof t&&1===t.nodeType&&"string"==typeof t.nodeName},l=Array.prototype.indexOf?function(t,e){return t.indexOf(e)}:function(t,e){for(var i=0,o=t.length;o>i;i++)if(t[i]===e)return i;return-1};"function"==typeof define&&define.amd?define("outlayer/outlayer",["eventie/eventie","doc-ready/doc-ready","eventEmitter/EventEmitter","get-size/get-size","matches-selector/matches-selector","./item"],s):"object"==typeof exports?module.exports=s(require("eventie"),require("doc-ready"),require("wolfy87-eventemitter"),require("get-size"),require("desandro-matches-selector"),require("./item")):t.Outlayer=s(t.eventie,t.docReady,t.EventEmitter,t.getSize,t.matchesSelector,t.Outlayer.Item)}(window),function(t){function e(t){function e(){t.Item.apply(this,arguments)}e.prototype=new t.Item,e.prototype._create=function(){this.id=this.layout.itemGUID++,t.Item.prototype._create.call(this),this.sortData={}},e.prototype.updateSortData=function(){if(!this.isIgnored){this.sortData.id=this.id,this.sortData["original-order"]=this.id,this.sortData.random=Math.random();var t=this.layout.options.getSortData,e=this.layout._sorters;for(var i in t){var o=e[i];this.sortData[i]=o(this.element,this)}}};var i=e.prototype.destroy;return e.prototype.destroy=function(){i.apply(this,arguments),this.css({display:""})},e}"function"==typeof define&&define.amd?define("isotope/js/item",["outlayer/outlayer"],e):"object"==typeof exports?module.exports=e(require("outlayer")):(t.Isotope=t.Isotope||{},t.Isotope.Item=e(t.Outlayer))}(window),function(t){function e(t,e){function i(t){this.isotope=t,t&&(this.options=t.options[this.namespace],this.element=t.element,this.items=t.filteredItems,this.size=t.size)}return function(){function t(t){return function(){return e.prototype[t].apply(this.isotope,arguments)}}for(var o=["_resetLayout","_getItemLayoutPosition","_manageStamp","_getContainerSize","_getElementOffset","needsResizeLayout"],n=0,r=o.length;r>n;n++){var s=o[n];i.prototype[s]=t(s)}}(),i.prototype.needsVerticalResizeLayout=function(){var e=t(this.isotope.element),i=this.isotope.size&&e;return i&&e.innerHeight!==this.isotope.size.innerHeight},i.prototype._getMeasurement=function(){this.isotope._getMeasurement.apply(this,arguments)},i.prototype.getColumnWidth=function(){this.getSegmentSize("column","Width")},i.prototype.getRowHeight=function(){this.getSegmentSize("row","Height")},i.prototype.getSegmentSize=function(t,e){var i=t+e,o="outer"+e;if(this._getMeasurement(i,o),!this[i]){var n=this.getFirstItemSize();this[i]=n&&n[o]||this.isotope.size["inner"+e]}},i.prototype.getFirstItemSize=function(){var e=this.isotope.filteredItems[0];return e&&e.element&&t(e.element)},i.prototype.layout=function(){this.isotope.layout.apply(this.isotope,arguments)},i.prototype.getSize=function(){this.isotope.getSize(),this.size=this.isotope.size},i.modes={},i.create=function(t,e){function o(){i.apply(this,arguments)}return o.prototype=new i,e&&(o.options=e),o.prototype.namespace=t,i.modes[t]=o,o},i}"function"==typeof define&&define.amd?define("isotope/js/layout-mode",["get-size/get-size","outlayer/outlayer"],e):"object"==typeof exports?module.exports=e(require("get-size"),require("outlayer")):(t.Isotope=t.Isotope||{},t.Isotope.LayoutMode=e(t.getSize,t.Outlayer))}(window),function(t){function e(t,e){var o=t.create("masonry");return o.prototype._resetLayout=function(){this.getSize(),this._getMeasurement("columnWidth","outerWidth"),this._getMeasurement("gutter","outerWidth"),this.measureColumns();var t=this.cols;for(this.colYs=[];t--;)this.colYs.push(0);this.maxY=0},o.prototype.measureColumns=function(){if(this.getContainerWidth(),!this.columnWidth){var t=this.items[0],i=t&&t.element;this.columnWidth=i&&e(i).outerWidth||this.containerWidth}this.columnWidth+=this.gutter,this.cols=Math.floor((this.containerWidth+this.gutter)/this.columnWidth),this.cols=Math.max(this.cols,1)},o.prototype.getContainerWidth=function(){var t=this.options.isFitWidth?this.element.parentNode:this.element,i=e(t);this.containerWidth=i&&i.innerWidth},o.prototype._getItemLayoutPosition=function(t){t.getSize();var e=t.size.outerWidth%this.columnWidth,o=e&&1>e?"round":"ceil",n=Math[o](t.size.outerWidth/this.columnWidth);n=Math.min(n,this.cols);for(var r=this._getColGroup(n),s=Math.min.apply(Math,r),a=i(r,s),u={x:this.columnWidth*a,y:s},p=s+t.size.outerHeight,h=this.cols+1-r.length,f=0;h>f;f++)this.colYs[a+f]=p;return u},o.prototype._getColGroup=function(t){if(2>t)return this.colYs;for(var e=[],i=this.cols+1-t,o=0;i>o;o++){var n=this.colYs.slice(o,o+t);e[o]=Math.max.apply(Math,n)}return e},o.prototype._manageStamp=function(t){var i=e(t),o=this._getElementOffset(t),n=this.options.isOriginLeft?o.left:o.right,r=n+i.outerWidth,s=Math.floor(n/this.columnWidth);s=Math.max(0,s);var a=Math.floor(r/this.columnWidth);a-=r%this.columnWidth?0:1,a=Math.min(this.cols-1,a);for(var u=(this.options.isOriginTop?o.top:o.bottom)+i.outerHeight,p=s;a>=p;p++)this.colYs[p]=Math.max(u,this.colYs[p])},o.prototype._getContainerSize=function(){this.maxY=Math.max.apply(Math,this.colYs);var t={height:this.maxY};return this.options.isFitWidth&&(t.width=this._getContainerFitWidth()),t},o.prototype._getContainerFitWidth=function(){for(var t=0,e=this.cols;--e&&0===this.colYs[e];)t++;return(this.cols-t)*this.columnWidth-this.gutter},o.prototype.needsResizeLayout=function(){var t=this.containerWidth;return this.getContainerWidth(),t!==this.containerWidth},o}var i=Array.prototype.indexOf?function(t,e){return t.indexOf(e)}:function(t,e){for(var i=0,o=t.length;o>i;i++){var n=t[i];if(n===e)return i}return-1};"function"==typeof define&&define.amd?define("masonry/masonry",["outlayer/outlayer","get-size/get-size"],e):"object"==typeof exports?module.exports=e(require("outlayer"),require("get-size")):t.Masonry=e(t.Outlayer,t.getSize)}(window),function(t){function e(t,e){for(var i in e)t[i]=e[i];return t}function i(t,i){var o=t.create("masonry"),n=o.prototype._getElementOffset,r=o.prototype.layout,s=o.prototype._getMeasurement;e(o.prototype,i.prototype),o.prototype._getElementOffset=n,o.prototype.layout=r,o.prototype._getMeasurement=s;var a=o.prototype.measureColumns;o.prototype.measureColumns=function(){this.items=this.isotope.filteredItems,a.call(this)};var u=o.prototype._manageStamp;return o.prototype._manageStamp=function(){this.options.isOriginLeft=this.isotope.options.isOriginLeft,this.options.isOriginTop=this.isotope.options.isOriginTop,u.apply(this,arguments)},o}"function"==typeof define&&define.amd?define("isotope/js/layout-modes/masonry",["../layout-mode","masonry/masonry"],i):"object"==typeof exports?module.exports=i(require("../layout-mode"),require("masonry-layout")):i(t.Isotope.LayoutMode,t.Masonry)}(window),function(t){function e(t){var e=t.create("fitRows");return e.prototype._resetLayout=function(){this.x=0,this.y=0,this.maxY=0,this._getMeasurement("gutter","outerWidth")},e.prototype._getItemLayoutPosition=function(t){t.getSize();var e=t.size.outerWidth+this.gutter,i=this.isotope.size.innerWidth+this.gutter;0!==this.x&&e+this.x>i&&(this.x=0,this.y=this.maxY);var o={x:this.x,y:this.y};return this.maxY=Math.max(this.maxY,this.y+t.size.outerHeight),this.x+=e,o},e.prototype._getContainerSize=function(){return{height:this.maxY}},e}"function"==typeof define&&define.amd?define("isotope/js/layout-modes/fit-rows",["../layout-mode"],e):"object"==typeof exports?module.exports=e(require("../layout-mode")):e(t.Isotope.LayoutMode)}(window),function(t){function e(t){var e=t.create("vertical",{horizontalAlignment:0});return e.prototype._resetLayout=function(){this.y=0},e.prototype._getItemLayoutPosition=function(t){t.getSize();var e=(this.isotope.size.innerWidth-t.size.outerWidth)*this.options.horizontalAlignment,i=this.y;return this.y+=t.size.outerHeight,{x:e,y:i}},e.prototype._getContainerSize=function(){return{height:this.y}},e}"function"==typeof define&&define.amd?define("isotope/js/layout-modes/vertical",["../layout-mode"],e):"object"==typeof exports?module.exports=e(require("../layout-mode")):e(t.Isotope.LayoutMode)}(window),function(t){function e(t,e){for(var i in e)t[i]=e[i];return t}function i(t){return"[object Array]"===h.call(t)}function o(t){var e=[];if(i(t))e=t;else if(t&&"number"==typeof t.length)for(var o=0,n=t.length;n>o;o++)e.push(t[o]);else e.push(t);return e}function n(t,e){var i=f(e,t);-1!==i&&e.splice(i,1)}function r(t,i,r,u,h){function f(t,e){return function(i,o){for(var n=0,r=t.length;r>n;n++){var s=t[n],a=i.sortData[s],u=o.sortData[s];if(a>u||u>a){var p=void 0!==e[s]?e[s]:e,h=p?1:-1;return(a>u?1:-1)*h}}return 0}}var d=t.create("isotope",{layoutMode:"masonry",isJQueryFiltering:!0,sortAscending:!0});d.Item=u,d.LayoutMode=h,d.prototype._create=function(){this.itemGUID=0,this._sorters={},this._getSorters(),t.prototype._create.call(this),this.modes={},this.filteredItems=this.items,this.sortHistory=["original-order"];for(var e in h.modes)this._initLayoutMode(e)},d.prototype.reloadItems=function(){this.itemGUID=0,t.prototype.reloadItems.call(this)},d.prototype._itemize=function(){for(var e=t.prototype._itemize.apply(this,arguments),i=0,o=e.length;o>i;i++){var n=e[i];n.id=this.itemGUID++}return this._updateItemsSortData(e),e +},d.prototype._initLayoutMode=function(t){var i=h.modes[t],o=this.options[t]||{};this.options[t]=i.options?e(i.options,o):o,this.modes[t]=new i(this)},d.prototype.layout=function(){return!this._isLayoutInited&&this.options.isInitLayout?(this.arrange(),void 0):(this._layout(),void 0)},d.prototype._layout=function(){var t=this._getIsInstant();this._resetLayout(),this._manageStamps(),this.layoutItems(this.filteredItems,t),this._isLayoutInited=!0},d.prototype.arrange=function(t){function e(){o.reveal(i.needReveal),o.hide(i.needHide)}this.option(t),this._getIsInstant();var i=this._filter(this.items);this.filteredItems=i.matches;var o=this;this._isInstant?this._noTransition(e):e(),this._sort(),this._layout()},d.prototype._init=d.prototype.arrange,d.prototype._getIsInstant=function(){var t=void 0!==this.options.isLayoutInstant?this.options.isLayoutInstant:!this._isLayoutInited;return this._isInstant=t,t},d.prototype._filter=function(t){var e=this.options.filter;e=e||"*";for(var i=[],o=[],n=[],r=this._getFilterTest(e),s=0,a=t.length;a>s;s++){var u=t[s];if(!u.isIgnored){var p=r(u);p&&i.push(u),p&&u.isHidden?o.push(u):p||u.isHidden||n.push(u)}}return{matches:i,needReveal:o,needHide:n}},d.prototype._getFilterTest=function(t){return s&&this.options.isJQueryFiltering?function(e){return s(e.element).is(t)}:"function"==typeof t?function(e){return t(e.element)}:function(e){return r(e.element,t)}},d.prototype.updateSortData=function(t){var e;t?(t=o(t),e=this.getItems(t)):e=this.items,this._getSorters(),this._updateItemsSortData(e)},d.prototype._getSorters=function(){var t=this.options.getSortData;for(var e in t){var i=t[e];this._sorters[e]=l(i)}},d.prototype._updateItemsSortData=function(t){for(var e=t&&t.length,i=0;e&&e>i;i++){var o=t[i];o.updateSortData()}};var l=function(){function t(t){if("string"!=typeof t)return t;var i=a(t).split(" "),o=i[0],n=o.match(/^\[(.+)\]$/),r=n&&n[1],s=e(r,o),u=d.sortDataParsers[i[1]];return t=u?function(t){return t&&u(s(t))}:function(t){return t&&s(t)}}function e(t,e){var i;return i=t?function(e){return e.getAttribute(t)}:function(t){var i=t.querySelector(e);return i&&p(i)}}return t}();d.sortDataParsers={parseInt:function(t){return parseInt(t,10)},parseFloat:function(t){return parseFloat(t)}},d.prototype._sort=function(){var t=this.options.sortBy;if(t){var e=[].concat.apply(t,this.sortHistory),i=f(e,this.options.sortAscending);this.filteredItems.sort(i),t!==this.sortHistory[0]&&this.sortHistory.unshift(t)}},d.prototype._mode=function(){var t=this.options.layoutMode,e=this.modes[t];if(!e)throw Error("No layout mode: "+t);return e.options=this.options[t],e},d.prototype._resetLayout=function(){t.prototype._resetLayout.call(this),this._mode()._resetLayout()},d.prototype._getItemLayoutPosition=function(t){return this._mode()._getItemLayoutPosition(t)},d.prototype._manageStamp=function(t){this._mode()._manageStamp(t)},d.prototype._getContainerSize=function(){return this._mode()._getContainerSize()},d.prototype.needsResizeLayout=function(){return this._mode().needsResizeLayout()},d.prototype.appended=function(t){var e=this.addItems(t);if(e.length){var i=this._filterRevealAdded(e);this.filteredItems=this.filteredItems.concat(i)}},d.prototype.prepended=function(t){var e=this._itemize(t);if(e.length){this._resetLayout(),this._manageStamps();var i=this._filterRevealAdded(e);this.layoutItems(this.filteredItems),this.filteredItems=i.concat(this.filteredItems),this.items=e.concat(this.items)}},d.prototype._filterRevealAdded=function(t){var e=this._filter(t);return this.hide(e.needHide),this.reveal(e.matches),this.layoutItems(e.matches,!0),e.matches},d.prototype.insert=function(t){var e=this.addItems(t);if(e.length){var i,o,n=e.length;for(i=0;n>i;i++)o=e[i],this.element.appendChild(o.element);var r=this._filter(e).matches;for(i=0;n>i;i++)e[i].isLayoutInstant=!0;for(this.arrange(),i=0;n>i;i++)delete e[i].isLayoutInstant;this.reveal(r)}};var c=d.prototype.remove;return d.prototype.remove=function(t){t=o(t);var e=this.getItems(t);if(c.call(this,t),e&&e.length)for(var i=0,r=e.length;r>i;i++){var s=e[i];n(s,this.filteredItems)}},d.prototype.shuffle=function(){for(var t=0,e=this.items.length;e>t;t++){var i=this.items[t];i.sortData.random=Math.random()}this.options.sortBy="random",this._sort(),this._layout()},d.prototype._noTransition=function(t){var e=this.options.transitionDuration;this.options.transitionDuration=0;var i=t.call(this);return this.options.transitionDuration=e,i},d.prototype.getFilteredItemElements=function(){for(var t=[],e=0,i=this.filteredItems.length;i>e;e++)t.push(this.filteredItems[e].element);return t},d}var s=t.jQuery,a=String.prototype.trim?function(t){return t.trim()}:function(t){return t.replace(/^\s+|\s+$/g,"")},u=document.documentElement,p=u.textContent?function(t){return t.textContent}:function(t){return t.innerText},h=Object.prototype.toString,f=Array.prototype.indexOf?function(t,e){return t.indexOf(e)}:function(t,e){for(var i=0,o=t.length;o>i;i++)if(t[i]===e)return i;return-1};"function"==typeof define&&define.amd?define(["outlayer/outlayer","get-size/get-size","matches-selector/matches-selector","isotope/js/item","isotope/js/layout-mode","isotope/js/layout-modes/masonry","isotope/js/layout-modes/fit-rows","isotope/js/layout-modes/vertical"],r):"object"==typeof exports?module.exports=r(require("outlayer"),require("get-size"),require("desandro-matches-selector"),require("./item"),require("./layout-mode"),require("./layout-modes/masonry"),require("./layout-modes/fit-rows"),require("./layout-modes/vertical")):t.Isotope=r(t.Outlayer,t.getSize,t.matchesSelector,t.Isotope.Item,t.Isotope.LayoutMode)}(window); +/*! + * fitColumns layout mode for Isotope + * v1.1.1 + * http://isotope.metafizzy.co/layout-modes/fitcolumns.html + */ + +/*jshint browser: true, devel: false, strict: true, undef: true, unused: true */ + +( function( window ) { + +'use strict'; + +function fitColumnsDefinition( LayoutMode ) { + + var FitColumns = LayoutMode.create('fitColumns'); + + FitColumns.prototype._resetLayout = function() { + this.x = 0; + this.y = 0; + this.maxX = 0; + }; + + FitColumns.prototype._getItemLayoutPosition = function( item ) { + item.getSize(); + + // if this element cannot fit in the current row + if ( this.y !== 0 && item.size.outerHeight + this.y > this.isotope.size.innerHeight ) { + this.y = 0; + this.x = this.maxX; + } + + var position = { + x: this.x, + y: this.y + }; + + this.maxX = Math.max( this.maxX, this.x + item.size.outerWidth ); + this.y += item.size.outerHeight; + + return position; + }; + + FitColumns.prototype._getContainerSize = function() { + return { width: this.maxX }; + }; + + FitColumns.prototype.needsResizeLayout = function() { + return this.needsVerticalResizeLayout(); + }; + + return FitColumns; + +} + +if ( typeof define === 'function' && define.amd ) { + // AMD + define( [ + 'isotope/js/layout-mode' + ], + fitColumnsDefinition ); +} else if ( typeof exports === 'object' ) { + // CommonJS + module.exports = fitColumnsDefinition( + require('isotope-layout/js/layout-mode') + ); +} else { + // browser global + fitColumnsDefinition( + window.Isotope.LayoutMode + ); +} + +})( window ); \ No newline at end of file