1(function () { 2 /** 3 * @typedef {Object} Breakpoint 4 * @property {string} id 5 * @property {string} label 6 * @property {number|undefined} maxWidth 7 * @property {number|undefined} minWidth 8 * @property {number|undefined} defaultPreviewWidth 9 */ 10 11 const is = { 12 arr: function (a) { 13 return Array.isArray(a); 14 }, 15 obj: function (a) { 16 return Object.prototype.toString.call(a).includes("Object"); 17 }, 18 str: function (a) { 19 return typeof a === "string"; 20 }, 21 fnc: function (a) { 22 return typeof a === "function"; 23 }, 24 und: function (a) { 25 return typeof a === "undefined"; 26 }, 27 nil: function (a) { 28 return is.und(a) || a === null; 29 }, 30 }; 31 32 /* 33 * Breakpoints 34 */ 35 36 /** 37 * Return a media query string based on the provided min and max width. 38 * @param {number|null} minWidth 39 * @param {number|null} maxWidth 40 * @returns {string|null} 41 */ 42 function getMediaQueryString(minWidth, maxWidth) { 43 if (minWidth && maxWidth) { 44 return `(min-width: ${minWidth}px) and (max-width: ${maxWidth}px)`; 45 } 46 47 if (maxWidth) { 48 return `(max-width: ${maxWidth}px)`; 49 } 50 51 if (minWidth) { 52 return `(min-width: ${minWidth}px)`; 53 } 54 55 return null; 56 } 57 58 /** 59 * Check whether any breakpoint, excluding desktop, is active. 60 * @returns {boolean} 61 */ 62 function matchAnyMedia() { 63 const { BASE_BREAKPOINT_ID, breakpoints } = window.BreakdanceFrontend.data; 64 65 return breakpoints 66 .filter((b) => b.id !== BASE_BREAKPOINT_ID) 67 .some((b) => matchMedia(b)); 68 } 69 70 /** 71 * Check whether a specific breakpoint is active. 72 * @param {string|Breakpoint} idOrBreakpoint Breakpoint ID or Breakpoint object. 73 * @returns {boolean} 74 */ 75 function matchMedia(idOrBreakpoint) { 76 const { BASE_BREAKPOINT_ID, breakpoints } = window.BreakdanceFrontend.data; 77 const isId = typeof idOrBreakpoint === "string"; 78 const breakpoint = isId 79 ? breakpoints.find((b) => b.id === idOrBreakpoint) 80 : idOrBreakpoint; 81 82 if (!breakpoint) return false; 83 if (breakpoint.id === BASE_BREAKPOINT_ID) return !matchAnyMedia(); 84 85 const { minWidth, maxWidth } = breakpoint; 86 const mediaQuery = getMediaQueryString(minWidth, maxWidth); 87 return window.matchMedia(mediaQuery).matches; 88 } 89 90 /** 91 * Return the current active breakpoint, if none is active return the Desktop breakpoint, which is not a real breakpoint. 92 * @param {string[]|undefined} breakpointIds List of breakpoints to check. 93 * @returns {Breakpoint} 94 */ 95 function getCurrentBreakpoint(breakpointIds) { 96 const { BASE_BREAKPOINT_ID, breakpoints } = window.BreakdanceFrontend.data; 97 98 const activeBreakpoint = breakpoints 99 .filter((b) => { 100 if (!breakpointIds) return true; 101 return breakpointIds.includes(b.id); 102 }) 103 .sort((a, b) => a.maxWidth - b.maxWidth) 104 .find((b) => matchMedia(b)); 105 106 return ( 107 activeBreakpoint || breakpoints.find((b) => b.id === BASE_BREAKPOINT_ID) 108 ); 109 } 110 111 /* 112 * DOM-related utils 113 */ 114 115 /** 116 * Selects an element. Returns null if not found. 117 * @param {string} str 118 * @returns {HTMLElement|null} 119 * @example 120 * selectString('.my-element') 121 * selectString('#my-element') 122 */ 123 function selectString(str) { 124 try { 125 return document.querySelectorAll(str); 126 } catch (e) { 127 return null; 128 } 129 } 130 131 /** 132 * Turn element, string selector or nodeList into an array 133 * @param {HTMLElement|HTMLElement[]|NodeList|String} o 134 * @returns {HTMLElement[]} 135 */ 136 function toArray(o) { 137 if (is.arr(o)) { 138 return o; 139 } 140 if (is.str(o)) { 141 o = selectString(o) || o; 142 } 143 if (o instanceof NodeList || o instanceof HTMLCollection) { 144 return [].slice.call(o); 145 } 146 return [o]; 147 } 148 149 /* 150 * Objects 151 */ 152 153 function cloneObject(obj) { 154 return JSON.parse(JSON.stringify(obj)); 155 } 156 157 /** 158 * Performs a deep merge of `source` into `target`. 159 * Undefined values are not copied to the target object. 160 * @author inspired by [jhildenbiddle](https://stackoverflow.com/a/48218209). 161 */ 162 function mergeObjects(obj1, source) { 163 const target = cloneObject(obj1); 164 165 if (!is.obj(source)) { 166 return target; 167 } 168 169 Object.keys(source).forEach((key) => { 170 const targetValue = target[key]; 171 const sourceValue = source[key]; 172 173 if (is.obj(targetValue) && is.obj(sourceValue)) { 174 target[key] = mergeObjects(Object.assign({}, targetValue), sourceValue); 175 } else if (!is.nil(sourceValue)) { 176 target[key] = sourceValue; 177 } 178 }); 179 180 return target; 181 } 182 183 /* 184 * Event Listeners 185 */ 186 187 function on(eventName, element, callback) { 188 if (!is.fnc(callback)) { 189 callback = element; 190 element = null; 191 } 192 193 if (element) { 194 toArray(element).forEach((el) => { 195 el.addEventListener(eventName, callback); 196 }); 197 } else { 198 window.addEventListener(eventName, callback); 199 } 200 } 201 202 function off(eventName, element, callback) { 203 if (!is.fnc(callback)) { 204 callback = element; 205 element = null; 206 } 207 208 if (element) { 209 toArray(element).forEach((el) => { 210 el.removeEventListener(eventName, callback); 211 }); 212 } else { 213 window.removeEventListener(eventName, callback); 214 } 215 } 216 217 function onResize(callback) { 218 const resizeObserver = new ResizeObserver(callback); 219 resizeObserver.observe(document.body); 220 221 return () => { 222 resizeObserver.disconnect(); 223 }; 224 } 225 226 /* 227 * Function 228 */ 229 230 // Returns a function, that, as long as it continues to be invoked, will not 231 // be triggered. The function will be called after it stops being called for 232 // N milliseconds. If `immediate` is passed, trigger the function on the 233 // leading edge, instead of the trailing. 234 function debounce(callback, wait, immediate) { 235 let timeout; 236 return function () { 237 const context = this, 238 args = arguments; 239 const later = function () { 240 timeout = null;
241 if (!immediate) callback.apply(context, args); 242 }; 243 const callNow = immediate && !timeout; 244 clearTimeout(timeout); 245 timeout = setTimeout(later, wait); 246 if (callNow) callback.apply(context, args); 247 }; 248 } 249 250 function throttle(callback, wait) { 251 let waiting = false; 252 return function () { 253 if (!waiting) { 254 callback.apply(this, arguments); 255 waiting = true; 256 setTimeout(() => { 257 waiting = false; 258 }, wait); 259 } 260 }; 261 } 262 263 function prefersReducedMotion() { 264 return window.matchMedia("(prefers-reduced-motion: reduce)").matches; 265 } 266 267 function makeAjaxRequest(url, options) { 268 return fetch(url, options); 269 } 270 271 /** 272 * Check whether the page is being viewed in the Builder. 273 * @returns {boolean} 274 */ 275 function isBuilder() { 276 try { 277 return !!window.parent.Breakdance; 278 } catch (e) { 279 return false; 280 } 281 } 282 283 document.addEventListener("DOMContentLoaded", () => { 284 if (!document.querySelector("#bde-main")) { 285 document.querySelector(".bde-skip-link")?.remove(); 286 } 287 }); 288 289 if (!window.BreakdanceFrontend) { 290 window.BreakdanceFrontend = {}; 291 } 292 293 window.BreakdanceFrontend.utils = { 294 is,
295 // Breakpoint 296 getCurrentBreakpoint, 297 getMediaQueryString, 298 matchMedia, 299 matchAnyMedia, 300 301 // DOM 302 toArray, 303 // Objects 304 cloneObject, 305 mergeObjects, 306 // Event Listeners 307 on, 308 off, 309 onResize, 310 // Other 311 debounce, 312 throttle, 313 prefersReducedMotion, 314 makeAjaxRequest, 315 isBuilder, 316 }; 317})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.