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 );