1<!doctype html> 2<html lang="de"> 3<head > 4 <meta charset="utf-8"/> 5<meta name="title" content="Customer Login | JUST SPICES®"/> 6<meta name="description" content="Just Spices ist Dein Shop für Gewürze, Gewürzmischungen und Zubehör. Ãber 120 Reingewürze, über 50 Gewürzmischungen und reichlich Zubehör bequem online bestellen."/> 7<meta name="robots" content="INDEX,FOLLOW"/> 8<meta name="viewport" content="width=device-width, initial-scale=1"/> 9<title>Customer Login | JUST SPICES®</title> 10<link rel="stylesheet" type="text/css" media="all" href="https://www.justspices.de/static/version1790005904/frontend/Justspices/relaunch/de_DE/Shopgate_WebCheckout/css/default.css" /> 11<link rel="stylesheet" type="text/css" media="all" href="https://www.justspices.de/static/version1790005904/frontend/Justspices/relaunch/de_DE/css/styles.css" /> 12<link rel="stylesheet" type="text/css" media="all" href="https://www.justspices.de/static/version1790005904/frontend/Justspices/relaunch/de_DE/JustSpices_Cms/css/widget/faq.css" /> 13<link rel="stylesheet" type="text/css" media="all" href="https://www.justspices.de/static/version1790005904/frontend/Justspices/relaunch/de_DE/Magento_Customer/css/account-login.css" />
14<script type="text/javascript" src="https://www.justspices.de/static/version1790005904/frontend/Justspices/relaunch/de_DE/JustSpices_Cms/js/lazyload.min.js"></script>
vendor: 1 bytes, line 14
14
15<script type="text/javascript" src="https://www.justspices.de/static/version1790005904/frontend/Justspices/relaunch/de_DE/JustSpices_Cms/js/jquery.min.js"></script>
vendor: 1 bytes, line 15
15
16<script type="text/javascript" src="https://www.justspices.de/static/version1790005904/frontend/Justspices/relaunch/de_DE/JustSpices_Cms/js/vue.min.js"></script>
vendor: 1 bytes, line 16
16
17<script type="text/javascript" src="https://www.justspices.de/static/version1790005904/frontend/Justspices/relaunch/de_DE/JustSpices_Vcheckout/js/vuex.js"></script>
vendor: 1 bytes, line 17
17
18<script type="text/javascript" defer="defer" src="https://www.justspices.de/static/version1790005904/frontend/Justspices/relaunch/de_DE/JustSpices_Cms/js/norequire/messages.min.js"></script>
vendor: 1 bytes, line 18
18
19<script type="text/javascript" defer="defer" src="https://www.justspices.de/static/version1790005904/frontend/Justspices/relaunch/de_DE/JustSpices_Vuecart/js/lib/vue-i18n.js"></script>
vendor: 1 bytes, line 19
19
20<script type="text/javascript" defer="defer" src="https://www.justspices.de/static/version1790005904/frontend/Justspices/relaunch/de_DE/JustSpices_Cms/js/vue-observe-visibility.min.js"></script>
vendor: 1 bytes, line 20
20
21<script type="text/javascript" defer="defer" src="https://www.justspices.de/static/version1790005904/frontend/Justspices/relaunch/de_DE/JustSpices_Cms/js/algoliasearch4.14.2/algoliasearch-lite.umd.js"></script>
vendor: 1 bytes, line 21
21
22<script type="text/javascript" defer="defer" src="https://www.justspices.de/static/version1790005904/frontend/Justspices/relaunch/de_DE/JustSpices_Catalog/js/norequire/catalog-add-to-cart.js"></script>
vendor: 1 bytes, line 22
22
23<script type="text/javascript" defer="defer" src="https://www.justspices.de/static/version1790005904/frontend/Justspices/relaunch/de_DE/JustSpices_Cms/js/norequire/theme.js"></script>
vendor: 1 bytes, line 23
23
24<script type="text/javascript" defer="defer" src="https://www.justspices.de/static/version1790005904/frontend/Justspices/relaunch/de_DE/JustSpices_Cms/js/norequire/faq.js"></script>
24 25<link rel="icon" type="image/x-icon" href="https://www.justspices.de/media/favicon/stores/1/favicon.png" /> 26<link rel="shortcut icon" type="image/x-icon" href="https://www.justspices.de/media/favicon/stores/1/favicon.png" /> 27<!-- OneTrust Cookies Consent Notice start for www.justspices.de -->
28<script src="https://cdn.cookielaw.org/consent/af927ee9-4b28-4d13-960b-e745918ba3b3/otSDKStub.js" type="text/javascript" charset="UTF-8" data-domain-script="af927ee9-4b28-4d13-960b-e745918ba3b3" ></script>
vendor: 2 bytes, line 28
28
29<script type="text/javascript"> 30 function OptanonWrapper() { } 31</script>
31 32<!-- OneTrust Cookies Consent Notice end for www.justspices.de --> 33 34<style> 35 .menu-header-row nav .nav-primary > div div.level0.shop { 36 left: 52.4%; 37 } 38 .menu-header-row nav .nav-primary > div div.level0.recipe { 39 left: 60%; 40 } 41 .menu-header-row nav .nav-primary > div div.level0.blog { 42 left: 90%; 43 transform: translateX(-50%); 44 } 45 .catalog-category-view input[type=search] { 46 border: none; 47 width: 90%; 48 height: 30px; 49 } 50 .catalog-category-view input[type=search]:focus { 51 border: none; 52 } 53 .message-container .shipping-info{ 54 display:none; 55 } 56 .recipe-recipe-view .seo-text h2 strong span{ 57 font-family: "BrandonText-Bold",Verdana,Arial,Helvetica,sans-serif; 58 } 59 60.catalog-category-view .vue-category .instant-search-row .resultbox .results article.article-9063 img, 61.catalog-category-view .vue-category .instant-search-row .resultbox .results article.article-7831 img { 62 aspect-ratio: 0.86923076923077; 63 object-fit: cover; 64} 65 66 #onetrust-consent-sdk { 67 position: relative; 68 } 69 70 #ot-sdk-btn-floating.ot-floating-button { 71 position: absolute!important; 72 } 73 74 @media screen and (max-width: 1200px) { 75 .menu-header-row nav .nav-primary > div div.level0.shop { 76 left:52.3% !important; 77 } 78 .menu-header-row nav .nav-primary > div div.level0.recipe { 79 left: 50.5% !important; 80 } 81 .menu-header-row nav .nav-primary > div div.level0.blog { 82 left:71.5% !important; 83 } 84 85 } 86.old-price.percent-difference{ 87 display:none; 88 } 89 .bundle-price-box .old-price .price-wrapper .price.percent-difference{ 90 display:none; 91 } 92 .bundle-price-box .old-price .price-wrapper .price{ 93 display: inline-block; 94 } 95 96.product-gewuerz-adventskalender .product-info-wrapper .product-info-main-container .info-box.free-incentives, .product-grosser-gewuerz-adventskalender .product-info-wrapper .product-info-main-container .info-box.free-incentives{ 97display:none; 98} 99.good-food-club-section .cash-points { 100 display: none !important; 101} 102</style>
102<script type="text/javascript"> 103 const storeCode = "default"; 104 const baseUrl = "https://www.justspices.de/"; 105 const graphQlUrl = "https://www.justspices.de/graphql"; 106 const restlUrl = "https://www.justspices.de/rest/default/V1"; 107 if(typeof locale === 'undefined'){ 108 const locale = "de_DE"; 109 } 110</script>
110 111<!-- BEGIN SHOPGATE --> 112
113<script type="text/javascript"> 114 var _shopgate = new Object(); 115 _shopgate.shop_number = "21348"; 116 _shopgate.redirect = "default"; 117 _shopgate.is_default_redirect_disabled = true; 118 _shopgate.redirect_to_webapp = true; 119 120 121 122 (function(b,d){var a=("undefined"!==typeof _shopgate?_shopgate:{}).shop_number;if(a){ 123 var c=b.createElement(d);c.async=!/(ip(ad|od|hone)|Android)/i.test(navigator.userAgent);c.src="https://static.shopgate.com/mobile_header/"+a+".js"; 124 a=b.getElementsByTagName(d)[0];a.parentNode.insertBefore(c,a)}} 125 )(document,"script"); 126</script>
126 127<!-- END SHOPGATE -->
127<script type="text/x-magento-init"> 128 { 129 "*": { 130 "Shopgate_WebCheckout/js/init": {"module":"customer","controller":"account","action":"login","env":"production","properties":[],"isSgWebView":false} } 131} 132</script>
132 133<!-- added by Trusted Shops app: Start -->
134<script src="https://integrations.etrusted.com/applications/widget.js/v2" async defer></script>
134 135<!-- End --> 136
137<script> 138 var BASE_URL = 'https://www.justspices.de/'; 139 var THEME_PATH = 'https://www.justspices.de/static/version1790005904/frontend/Justspices/relaunch/de_DE'; 140 var COOKIE_CONFIG = { 141 "expires": null, 142 "path": "\u002F", 143 "domain": ".www.justspices.de", 144 "secure": true, 145 "lifetime": "2592000", 146 "cookie_restriction_enabled": false }; 147 var CURRENT_STORE_CODE = 'default'; 148 var CURRENT_WEBSITE_ID = '1'; 149 150 window.hyva = window.hyva || {} 151 152 window.cookie_consent_groups = window.cookie_consent_groups || {} 153 window.cookie_consent_groups['necessary'] = true; 154 155 window.cookie_consent_config = window.cookie_consent_config || {}; 156 window.cookie_consent_config['necessary'] = [].concat( 157 window.cookie_consent_config['necessary'] || [], 158 [ 159 'user_allowed_save_cookie', 160 'form_key', 161 'mage-messages', 162 'private_content_version', 163 'mage-cache-sessid', 164 'last_visited_store', 165 'section_data_ids' 166 ] 167 ); 168</script>
vendor: 1 bytes, line 168
168
169<script> 170 'use strict'; 171 (function( hyva, undefined ) { 172 173 function lifetimeToExpires(options, defaults) { 174 175 const lifetime = options.lifetime || defaults.lifetime; 176 177 if (lifetime) { 178 const date = new Date; 179 date.setTime(date.getTime() + lifetime * 1000); 180 return date; 181 } 182 183 return null; 184 } 185 186 function generateRandomString() { 187 188 const allowedCharacters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 189 length = 16; 190 191 let formKey = '', 192 charactersLength = allowedCharacters.length; 193 194 for (let i = 0; i < length; i++) { 195 formKey += allowedCharacters[Math.round(Math.random() * (charactersLength - 1))] 196 } 197 198 return formKey; 199 } 200 201 const sessionCookieMarker = {noLifetime: true} 202 203 const cookieTempStorage = {}; 204 205 const internalCookie = { 206 get(name) { 207 const v = document.cookie.match('(^|;) ?' + name + '=([^;]*)(;|$)'); 208 return v ? v[2] : null; 209 }, 210 set(name, value, days, skipSetDomain) { 211 let expires, 212 path, 213 domain, 214 secure, 215 samesite; 216 217 const defaultCookieConfig = { 218 expires: null, 219 path: '/', 220 domain: null, 221 secure: false, 222 lifetime: null, 223 samesite: 'lax' 224 }; 225 226 const cookieConfig = window.COOKIE_CONFIG || {}; 227 228 expires = days && days !== sessionCookieMarker 229 ? lifetimeToExpires({lifetime: 24 * 60 * 60 * days, expires: null}, defaultCookieConfig) 230 : lifetimeToExpires(window.COOKIE_CONFIG, defaultCookieConfig) || defaultCookieConfig.expires; 231 232 path = cookieConfig.path || defaultCookieConfig.path; 233 domain = !skipSetDomain && (cookieConfig.domain || defaultCookieConfig.domain); 234 secure = cookieConfig.secure || defaultCookieConfig.secure; 235 samesite = cookieConfig.samesite || defaultCookieConfig.samesite; 236 237 document.cookie = name + "=" + encodeURIComponent(value) + 238 (expires && days !== sessionCookieMarker ? '; expires=' + expires.toGMTString() : '') + 239 (path ? '; path=' + path : '') + 240 (domain ? '; domain=' + domain : '') + 241 (secure ? '; secure' : '') + 242 (samesite ? '; samesite=' + samesite : 'lax'); 243 }, 244 isWebsiteAllowedToSaveCookie() { 245 const allowedCookies = this.get('user_allowed_save_cookie'); 246 if (allowedCookies) { 247 const allowedWebsites = JSON.parse(unescape(allowedCookies)); 248 249 return allowedWebsites[CURRENT_WEBSITE_ID] === 1; 250 } 251 return false; 252 }, 253 getGroupByCookieName(name) { 254 const cookieConsentConfig = window.cookie_consent_config || {}; 255 let group = null; 256 for (let prop in cookieConsentConfig) { 257 if (!cookieConsentConfig.hasOwnProperty(prop)) continue; 258 if (cookieConsentConfig[prop].includes(name)) { 259 group = prop; 260 break; 261 } 262 } 263 return group; 264 }, 265 isCookieAllowed(name) { 266 const cookieGroup = this.getGroupByCookieName(name); 267 return cookieGroup 268 ? window.cookie_consent_groups[cookieGroup] 269 : this.isWebsiteAllowedToSaveCookie(); 270 }, 271 saveTempStorageCookies() { 272 for (const [name, data] of Object.entries(cookieTempStorage)) { 273 if (this.isCookieAllowed(name)) { 274 this.set(name, data['value'], data['days'], data['skipSetDomain']); 275 delete cookieTempStorage[name]; 276 } 277 } 278 }, 279 remove(name) { 280 let expires, 281 path, 282 domain, 283 secure, 284 samesite; 285 286 const defaultCookieConfig = { 287 expires: null, 288 path: '/', 289 domain: null, 290 secure: false, 291 lifetime: null, 292 samesite: 'lax' 293 }; 294 295 const cookieConfig = window.COOKIE_CONFIG || {}; 296 297 expires = new Date('Jan 01 1970 00:00:01 GMT') 298 path = cookieConfig.path || defaultCookieConfig.path; 299 domain = cookieConfig.domain || defaultCookieConfig.domain; 300 secure = cookieConfig.secure || defaultCookieConfig.secure; 301 samesite = cookieConfig.samesite || defaultCookieConfig.samesite; 302 303 document.cookie = name + "=" + encodeURIComponent('') + 304 (expires ? '; expires=' + expires.toGMTString() : '') + 305 (path ? '; path=' + path : '') + 306 (domain ? '; domain=' + domain : '') + 307 (secure ? '; secure' : '') + 308 (samesite ? '; samesite=' + samesite : 'lax'); 309 } 310 }; 311 312 hyva.getCookie = (name) => { 313 const cookieConfig = window.COOKIE_CONFIG || {}; 314 315 if (cookieConfig.cookie_restriction_enabled && ! internalCookie.isCookieAllowed(name)) { 316 return cookieTempStorage[name] ? cookieTempStorage[name]['value'] : null; 317 } 318 319 return internalCookie.get(name); 320 } 321 322 hyva.setCookie = (name, value, days, skipSetDomain) => { 323 const cookieConfig = window.COOKIE_CONFIG || {}; 324 325 if (cookieConfig.cookie_restriction_enabled && ! internalCookie.isCookieAllowed(name)) { 326 cookieTempStorage[name] = {value, days, skipSetDomain}; 327 return; 328 } 329 return internalCookie.set(name, value, days, skipSetDomain); 330 } 331 332 hyva.removeCookie = (name) => { 333 return internalCookie.remove(name); 334 } 335 336 hyva.setSessionCookie = (name, value, skipSetDomain) => { 337 return hyva.setCookie(name, value, sessionCookieMarker, skipSetDomain) 338 } 339 340 hyva.getBrowserStorage = () => { 341 const browserStorage = window.localStorage || window.sessionStorage; 342 if (!browserStorage) { 343 console.warn('Browser Storage is unavailable'); 344 return false;
345 } 346 try { 347 browserStorage.setItem('storage_test', '1'); 348 browserStorage.removeItem('storage_test'); 349 } catch (error) { 350 console.warn('Browser Storage is not accessible', error); 351 return false; 352 } 353 return browserStorage; 354 } 355 356 hyva.getLocalStorageOfSection = (name) => { 357 const browserStorage = window.localStorage || window.sessionStorage; 358 if (!browserStorage) { 359 console.warn('Browser Storage is unavailable'); 360 return false; 361 } 362 try { 363 browserStorage.setItem('storage_test', 1); 364 browserStorage.removeItem('storage_test'); 365 } catch (error) { 366 console.warn('Browser Storage is not accessible', error); 367 return false; 368 } 369 370 const privateContent = JSON.parse(browserStorage.getItem('mage-cache-storage')); 371 if (!privateContent) { 372 console.warn('PrivateContent is unavailable'); 373 return false; 374 } 375 return privateContent[name]; 376 } 377 378 hyva.postForm = (postParams) => { 379 const form = document.createElement("form"); 380 381 let data = postParams.data; 382 383 if (! postParams.skipUenc && ! data.uenc) { 384 data.uenc = btoa(window.location.href); 385 } 386 form.method = "POST"; 387 form.action = postParams.action; 388 389 Object.keys(postParams.data).map(key => { 390 const field = document.createElement("input"); 391 field.type = 'hidden' 392 field.value = postParams.data[key]; 393 field.name = key; 394 form.appendChild(field); 395 }); 396 397 const form_key = document.createElement("input"); 398 form_key.type = 'hidden'; 399 form_key.value = hyva.getFormKey(); 400 form_key.name="form_key"; 401 form.appendChild(form_key); 402 403 document.body.appendChild(form); 404 405 form.submit(); 406 } 407 408 hyva.getFormKey = function () { 409 let formKey = hyva.getCookie('form_key'); 410 411 if (!formKey) { 412 formKey = generateRandomString(); 413 hyva.setCookie('form_key', formKey); 414 } 415 416 return formKey; 417 } 418 419 hyva.formatPrice = (value, showSign, options = {}) => { 420 const formatter = new Intl.NumberFormat( 421 'de\u002DDE', 422 Object.assign({ 423 style: 'currency', 424 currency: 'EUR', 425 signDisplay: showSign ? 'always' : 'auto' 426 }, options) 427 ); 428 return (typeof Intl.NumberFormat.prototype.formatToParts === 'function') ? 429 formatter.formatToParts(value).map(({type, value}) => { 430 switch (type) { 431 case 'currency': 432 return '\u20AC' || value; 433 case 'minusSign': 434 return '- '; 435 case 'plusSign': 436 return '+ '; 437 default : 438 return value; 439 } 440 }).reduce((string, part) => string + part) : 441 formatter.format(value); 442 } 443 444 const formatStr = function (str, nStart) { 445 const args = Array.from(arguments).slice(2); 446 447 return str.replace(/(%+)([0-9]+)/g, (m, p, n) => { 448 const idx = parseInt(n) - nStart; 449 450 if (args[idx] === null || args[idx] === void 0) { 451 return m; 452 } 453 return p.length % 2 454 ? p.slice(0, -1).replace('%%', '%') + args[idx] 455 : p.replace('%%', '%') + n; 456 }) 457 } 458 459 hyva.str = function (string) { 460 const args = Array.from(arguments); 461 args.splice(1, 0, 1); 462 463 return formatStr.apply(undefined, args); 464 } 465 466 hyva.strf = function () { 467 const args = Array.from(arguments); 468 args.splice(1, 0, 0); 469 470 return formatStr.apply(undefined, args); 471 } 472 473 /** 474 * Take a html string as `content` parameter and 475 * extract an element from the DOM to replace in 476 * the current page under the same selector, 477 * defined by `targetSelector` 478 */ 479 hyva.replaceDomElement = (targetSelector, content) => { 480 // Parse the content and extract the DOM node using the `targetSelector` 481 const parser = new DOMParser(); 482 const doc = parser.parseFromString(content, 'text/html');
483 const contentNode = doc.querySelector(targetSelector); 484 485 // Bail if content can't be found 486 if (!contentNode) { 487 return; 488 } 489 490 hyva.activateScripts(contentNode) 491 492 // Replace the old DOM node with the new content 493 document.querySelector(targetSelector).replaceWith(contentNode); 494 495 // Reload customerSectionData and display cookie-messages if present 496 window.dispatchEvent(new CustomEvent("reload-customer-section-data")); 497 hyva.initMessages(); 498 } 499 500 hyva.activateScripts = (contentNode) => { 501 // Extract all the script tags from the content. 502 // Script tags won't execute when inserted into a dom-element directly, 503 // therefore we need to inject them to the head of the document. 504 const tmpScripts = contentNode.getElementsByTagName('script'); 505 506 if (tmpScripts.length > 0) { 507 // Push all script tags into an array 508 // (to prevent dom manipulation while iterating over dom nodes) 509 const scripts = []; 510 for (let i = 0; i < tmpScripts.length; i++) { 511 scripts.push(tmpScripts[i]); 512 } 513 514 // Iterate over all script tags and duplicate+inject each into the head 515 for (let i = 0; i < scripts.length; i++) { 516 let script = document.createElement('script'); 517 script.innerHTML = scripts[i].innerHTML; 518 519 document.head.appendChild(script); 520 521 // Remove the original (non-executing) node from the content 522 scripts[i].parentNode.removeChild(scripts[i]); 523 } 524 } 525 return contentNode; 526 } 527 528 const replace = {['+']: '-', ['/']: '_', ['=']: ','}; 529 hyva.getUenc = () => btoa(window.location.href).replace(/[+/=]/g, match => replace[match]); 530 531 let currentTrap; 532 533 const focusableElements = (rootElement) => { 534 const selector = 'button, [href], input, select, textarea, details, [tabindex]:not([tabindex="-1"]'; 535 return Array.from(rootElement.querySelectorAll(selector)) 536 .filter(el => { 537 return el.style.display !== 'none' 538 && !el.disabled 539 && el.tabIndex !== -1 540 && (el.offsetWidth || el.offsetHeight || el.getClientRects().length) 541 }) 542 } 543 544 const focusTrap = (e) => { 545 const isTabPressed = e.key === 'Tab' || e.keyCode === 9; 546 if (!isTabPressed) return; 547 548 const focusable = focusableElements(currentTrap) 549 const firstFocusableElement = focusable[0] 550 const lastFocusableElement = focusable[focusable.length - 1] 551 552 e.shiftKey 553 ? document.activeElement === firstFocusableElement && (lastFocusableElement.focus(), e.preventDefault()) 554 : document.activeElement === lastFocusableElement && (firstFocusableElement.focus(), e.preventDefault()) 555 }; 556 557 hyva.releaseFocus = (rootElement) => { 558 if (currentTrap && (!rootElement || rootElement === currentTrap)) { 559 currentTrap.removeEventListener('keydown', focusTrap) 560 currentTrap = null 561 } 562 } 563 hyva.trapFocus = (rootElement) => { 564 if (!rootElement) return; 565 hyva.releaseFocus() 566 currentTrap = rootElement 567 rootElement.addEventListener('keydown', focusTrap) 568 const firstElement = focusableElements(rootElement)[0] 569 firstElement && firstElement.focus() 570 } 571 572 hyva.alpineInitialized = (fn) => window.addEventListener('alpine:initialized', fn, {once: true}) 573 window.addEventListener('user-allowed-save-cookie', () => internalCookie.saveTempStorageCookies()) 574 575 }( window.hyva = window.hyva || {} )); 576</script>
vendor: 1 bytes, line 576
576
577<script> 578 if (!window.IntersectionObserver) { 579 window.IntersectionObserver = function (callback) { 580 this.observe = el => el && callback(this.takeRecords()); 581 this.takeRecords = () => [{isIntersecting: true, intersectionRatio: 1}]; 582 this.disconnect = () => {}; 583 this.unobserve = () => {}; 584 } 585 } 586</script>
vendor: 1 bytes, line 586
586
587<script> 588 const STORE_CODE = 'default'; 589 const locale = "de_DE"; 590</script>
590 591</head> 592<body id="html-body" class="customer-account-login page-layout-1column"> 593<input name="form_key" type="hidden" value="icxHq6W0Magq1fDG" /> 594 <noscript> 595 <section class="message global noscript border-b-2 border-blue-500 bg-blue-50 shadow-none m-0 px-0 rounded-none font-normal"> 596 <div class="container text-center"> 597 <p> 598 <strong>JavaScript scheint in Ihrem Browser deaktiviert zu sein.</strong> 599 <span> 600 Um unsere Website in bester Weise zu erfahren, aktivieren Sie Javascript in Ihrem Browser. </span> 601 </p> 602 </div> 603 </section> 604 </noscript> 605 606
607<script> 608 document.body.addEventListener('touchstart', () => {}, {passive: true}) 609</script>
609 610
611<script> 612 'use strict'; 613 (function(hyva) { 614 const formValidationRules = { 615 required(value, options, field, context) { 616 const el = field.element.type === 'hidden' ? createTextInputFrom(field.element) : field.element, 617 msg = 'Vervollst\u00E4ndige\u0020bitte\u0020die\u0020notwendigen\u0020Angaben.'; 618 619 if (el.type === 'radio' || el.type === 'checkbox') { 620 return (value === undefined || value.length === 0) ? msg : true; 621 } 622 623 el.setAttribute('required', ''); 624 el.checkValidity(); 625 626 return el.validity.valueMissing ? msg : true; 627 }, 628 maxlength(value, options, field, context) { 629 const n = Number(options) 630 if (value.length > n) { 631 return n === 1 632 ? hyva.strf('Please\u0020enter\u0020no\u0020more\u0020than\u00201\u0020character.') 633 : hyva.strf('Bitte\u0020nicht\u0020mehr\u0020als\u0020\u00250\u0020Zeichen.', options) 634 } 635 return true; 636 }, 637 minlength(value, options, field, context) { 638 const n = Number(options) 639 if (value.length > 0 && value.length < n) { 640 return n === 1 641 ? hyva.strf('Bitte\u0020mindestens\u00201\u0020Zeichen\u0020eingeben.') 642 : hyva.strf('Bitte\u0020mindestens\u0020\u00250\u0020Zeichen\u0020eingeben.', options) 643 } 644 return true; 645 }, 646 max(value, options, field, context) { 647 field.element.setAttribute('max', options); 648 field.element.checkValidity(); 649 if (field.element.validity.rangeOverflow) { 650 return hyva.strf('Please\u0020enter\u0020a\u0020value\u0020less\u0020than\u0020or\u0020equal\u0020to\u0020\u0022\u00250\u0022.', options); 651 } 652 return true; 653 }, 654 min(value, options, field, context) { 655 field.element.setAttribute('min', options); 656 field.element.checkValidity(); 657 if (field.element.validity.rangeUnderflow) { 658 return hyva.strf('Please\u0020enter\u0020a\u0020value\u0020greater\u0020than\u0020or\u0020equal\u0020to\u0020\u0022\u00250\u0022.', options); 659 } 660 return true; 661 }, 662 step(value, options, field, context) { 663 field.element.setAttribute('step', options); 664 field.element.checkValidity(); 665 if (field.element.validity.stepMismatch) { 666 const val = Number(value); 667 const step = Number(options); 668 const msg = 'Please\u0020enter\u0020a\u0020valid\u0020value.\u0020The\u0020two\u0020nearest\u0020valid\u0020values\u0020are\u0020\u0022\u00250\u0022\u0020and\u0020\u0022\u00251\u0022.'; 669 return hyva.strf(msg, Math.floor(val / step) * step, Math.ceil(val / step) * step); 670 } 671 return true; 672 }, 673 pattern(value, options, field, context) { 674 field.element.setAttribute('pattern', options); 675 field.element.checkValidity(); 676 if (field.element.validity.patternMismatch) { 677 return field.element.title 678 ? hyva.strf('Bitte\u0020korrigere\u0020das\u0020Format\u003A\u0020\u00250.', field.element.title) 679 : 'Please\u0020match\u0020the\u0020requested\u0020format.' 680 } 681 return true; 682 }, 683 email(value, options, field, context) { 684 const rule = /^([a-z0-9,!\#\$%&'\*\+\/=\?\^_`\{\|\}~-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z0-9,!\#\$%&'\*\+\/=\?\^_`\{\|\}~-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*@([a-z0-9-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z0-9-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*\.(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]){2,})$/i; 685 if (value.length > 0 && !rule.test(value)) { 686 return 'Bitte\u0020geben\u0020Sie\u0020eine\u0020g\u
68600FCltige\u0020E\u002DMail\u002DAdresse\u0020an.'; 687 } 688 return true; 689 }, 690 password(value, options, field, context) { 691 const rule = /^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,}$/; 692 if (value.length > 0 && !rule.test(value)) { 693 return 'Please\u0020provide\u0020at\u0020least\u0020one\u0020upper\u0020case,\u0020one\u0020lower\u0020case,\u0020one\u0020digit\u0020and\u0020one\u0020special\u0020character\u0020\u0028\u0023\u003F\u0021\u0040\u0024\u0025\u005E\u0026\u002A\u002D\u0029'; 694 } 695 return true; 696 }, 697 equalTo(value, options, field, context) { 698 const dependencyField = context.fields[options].element; 699 if (value !== dependencyField.value) { 700 const dependencyFieldName = 701 dependencyField.label || 702 dependencyField.title || 703 (dependencyField.labels && dependencyField.labels[0] && dependencyField.labels[0].innerText) || 704 dependencyField.name; 705 return hyva.strf('Das\u0020Feld\u0020muss\u0020identisch\u0020sein\u0020mit\u0020\u0022\u00250\u0022.', dependencyFieldName); 706 } 707 return true; 708 } 709 }; 710 711 function raceSome(promises, pred) { 712 return new Promise((resolve, reject) => { 713 714 if (promises.length === 0) { 715 return resolve(); 716 } 717 718 let settled = false, nDone = 0; 719 720 const resolveIf = v => { 721 if (!settled && (pred(v) || ++nDone === promises.length)) { 722 settled = true; 723 resolve(v); 724 } 725 return v; 726 } 727 728 promises.map(promise => { 729 promise.then(resolveIf).catch(reason => { 730 settled = true; 731 reject(reason) 732 }); 733 return promise; 734 }); 735 }); 736 } 737 738 const INPUT_ATTRIBUTE_RULES = {min: 'min', max: 'max', required: 'required', minlength: 'minlength', maxlength: 'maxlength', step: 'step', pattern: 'pattern'} 739 const INPUT_TYPE_RULES = {email: 'email'} 740 741 function getRules(element) { 742 let rules = {}; 743 Object.keys(INPUT_ATTRIBUTE_RULES).forEach(attrName => { 744 if (element.hasAttribute(attrName)) { 745 rules[INPUT_ATTRIBUTE_RULES[attrName]] = element.getAttribute(attrName); 746 } 747 }) 748 if (INPUT_TYPE_RULES[element.type]) { 749 rules[INPUT_TYPE_RULES[element.type]] = true; 750 } 751 752 if (element.dataset.validate) { 753 try { 754 Object.assign(rules, JSON.parse(element.dataset.validate)); 755 } catch (error) { 756 console.error('Validator error. Cannot parse data-validate attribute of element:\n', element); 757 } 758 } 759 760 return rules; 761 } 762 763 function isInvalidRuleResult(ruleState) { 764 return typeof ruleState === 'string' || !ruleState || (ruleState.type && ruleState.content); 765 } 766 767 async function runValidateFn(rule, options, value, field) { 768 return formValidationRules[rule](value, options, field, this); 769 } 770 771 function generateId() { 772 let id; 773 do { 774 id = `${this.idPrefix}-${++this.idSeq}`; 775 } while (document.getElementById(id)); 776 return id; 777 } 778 779 function isVisible(element) { 780 const el = element.type !== 'hidden' ? element : (element.parentElement || {}); 781 return !!(el.offsetWidth || el.offsetHeight || el.getClientRects().length) 782 } 783 784 function elementWillValidate(element) { 785 return (element.willValidate || element.type === 'hidden') 786 && element.tagName !== 'BUTTON' 787 && element.disabled === false 788 && !(element.tagName === 'INPUT' && element.type === 'submit') 789 && (element.hasAttribute('data-validate-hidden') || isVisible(element)) 790 } 791 792 function createMessageContainer(el, fieldWrapperClassName) { 793 if (! el.parentElement) { 794 return; 795 } 796 const refocus = document.activeElement === el; 797 const wrapper = document.createElement('div'); 798 wrapper.classList.add.apply(wrapper.classList, fieldWrapperClassName.split(' ')); 799 el.parentElement.insertBefore(wrapper, el); 800 wrapper.appendChild(el); 801 refocus && document.activeElement !== el && el.focus(); 802 return wrapper; 803 } 804 805 function containerNotFound(selector, el) { 806 const msg = `Cannot find message container element ${selector} of ${el.name}`; 807 console.error(msg, el); 808 throw msg; 809 } 810 811 function createTextInputFrom(el) { 812 const text = document.createElement('INPUT'); 813 text.type = 'text'; 814 text.value = el.value; 815 return text; 816 } 817 818 function classNamesToSelector(classNames) { 819 return classNames.split(' ') 820 .filter(className => className.length > 0) 821 .map(className => `.${className}`) 822 .join('') 823 } 824 825 function hasMessagesWrapper(field, messagesWrapperClassName) { 826 return this.getMessageContainer(field).querySelector(classNamesToSelector(messagesWrapperClassName)); 827 } 828
829 function getMessagesWrapper(field, messagesWrapperClassName) { 830 if (hasMessagesWrapper.call(this, field, messagesWrapperClassName)) { 831 return this.getMessageContainer(field).querySelector(classNamesToSelector(messagesWrapperClassName)); 832 } 833 834 const msgWrapper = document.createElement('ul'); 835 const msgId = generateId.call(this); 836 msgWrapper.id = msgId; 837 field.element.setAttribute('aria-errormessage', msgId); 838 field.element.setAttribute('aria-describedby', msgId); 839 msgWrapper.classList.add.apply(msgWrapper.classList, messagesWrapperClassName.split(' ')); 840 if (field.validateOnChange) { 841 msgWrapper.setAttribute('aria-live', 'polite'); 842 } 843 this.getMessageContainer(field).appendChild(msgWrapper); 844 845 return msgWrapper; 846 } 847 848 function getCheckedValues(field) { 849 const name = field.element.name.replace(/([\\"])/g, '\\$1'); 850 const elements = field.element.form.querySelectorAll('input[name="' + name + '"]:checked'); 851 return Array.from(elements).map(el => el.value); 852 } 853 854 function escapeHtml(s) { 855 const div = document.createElement('div') 856 div.innerText = s; 857 return div.innerHTML; 858 } 859 860 861 function formValidation(formElement, options) { 862 // Disable browser default validation 863 if (formElement.tagName === 'FORM') { 864 formElement.setAttribute('novalidate', ''); 865 } else { 866 console.error('formValidation can be initialized only on FORM element', formElement); 867 return; 868 } 869 870 options = Object.assign({ 871 fieldWrapperClassName: 'field field-reserved', 872 messagesWrapperClassName: 'messages', 873 validClassName: 'field-success', 874 invalidClassName: 'field-error', 875 pageMessagesWrapperSelector: null, 876 scrollToFirstError: true, 877 }, options || {}); 878 879 return { 880 state: { 881 valid: false, 882 }, 883 fields: {}, 884 idSeq: 0, 885 idPrefix: formElement.id || 'vld-msg', 886 setupFields(elements) { 887 this.fields = {}; 888 Array.from(elements).forEach(element => { 889 if (elementWillValidate(element)) { 890 this.setupField(element); 891 } 892 }); 893 }, 894 setupField(element) { 895 if (! element) return; 896 const onChange = !!element.dataset.onChange; 897 if (elementWillValidate(element)) { 898 const rules = getRules(element); 899 if (Object.keys(rules).length > 0) { 900 if (this.fields[element.name]) { 901 Object.assign(this.fields[element.name].rules, rules); 902 } else { 903 this.fields[element.name] = { 904 element, 905 rules: rules, 906 validateOnChange: onChange, 907 state: { 908 valid: null, 909 rules: {} 910 } 911 } 912 } 913 } 914 } else { 915 console.error('Element will not validate', element); 916 } 917 }, 918 onSubmit(event) { 919 if (event.target.tagName === 'FORM') { 920 event.preventDefault(); 921 922 this.validate() 923 .then(() => event.target.submit()) 924 .catch(invalidElements => {}); 925 } 926 }, 927 onChange(event) {
928 event.target.dataset.onChange = 'true'; 929 if (!Object.keys(this.fields).length) { 930 this.setupFields(formElement.elements); 931 } 932 if (!Object.keys(this.fields).includes(event.target.name)) { 933 this.setupField(event.target); 934 } 935 const field = this.fields[event.target.name]; 936 937 this.validateField(field); 938 field && field.element.removeAttribute('data-on-change') 939 }, 940 validateSafe() { 941 return new Promise(resolve => this.validate().then(() => resolve(true)).catch(() => {})) 942 }, 943 validate() { 944 if (!Object.keys(this.fields).length || !Object.keys(this.fields).length !== formElement.elements.length) { 945 this.setupFields(formElement.elements); 946 } 947 return new Promise(async (resolve, reject) => { 948 if (formElement.elements) { 949 await raceSome(this.validateFields(), result => result !== true) 950 const invalidFields = Object.values(this.fields).filter(field => !field.state.valid); 951 this.state.valid = invalidFields.length === 0; 952 if (this.state.valid) { 953 resolve(); 954 } else { 955 if (options.scrollToFirstError && invalidFields.length > 0) { 956 invalidFields[0].element.focus() 957 invalidFields[0].element.select && invalidFields[0].element.select(); 958 } 959 reject(invalidFields.map(field => field.element)); 960 } 961 } 962 }); 963 }, 964 validateFields() { 965 const fields = Object.values(this.fields); 966 967 fields.forEach(field => { 968 this.getMessageContainer(field).classList.remove(options.validClassName, options.invalidClassName) 969 }); 970 return fields.map(field => this.validateField(field)) 971 }, 972 validateField(field) { 973 if (! field || ! elementWillValidate(field.element)) { 974 return new Promise(resolve => resolve(true)) 975 } 976 977 let value; 978 if (field.element.type === 'checkbox') { 979 value = getCheckedValues(field); 980 } else if (field.element.type === 'radio') { 981 value = getCheckedValues(field)[0] || undefined; 982 } else if (field.element.tagName === 'SELECT' && field.element.multiple) { 983 value = Array.from(field.element.selectedOptions).map(opt => opt.value); 984 } else { 985 value = field.element.value; 986 } 987 988 const rules = field.rules || {}; 989 990 field.state.valid = true; 991 this.showFieldState(field); 992 993 994 const fieldValidations = Object.keys(rules).filter(rule => formValidationRules[rule]).map(async rule => { 995 return runValidateFn.call(this, rule, rules[rule], value, field).then(result => { 996 field.state.rules[rule] = result; 997 return result; 998 }) 999 }); 1000 1001 return new Promise(resolve => { 1002 Promise.all(fieldValidations).then(results => { 1003 field.state.valid = !elementWillValidate(field.element) || rules.length === 0 || !results.some(isInvalidRuleResult)
1004 this.showFieldState(field); 1005 resolve(field.state.valid); 1006 }) 1007 }); 1008 }, 1009 getMessagesByField(field) { 1010 const messages = []; 1011 const invalidRules = Object.keys(field.state.rules).filter(rule => isInvalidRuleResult(field.state.rules[rule])); 1012 1013 field.rules && Object.keys(field.rules).forEach((rule) => { 1014 if (invalidRules.includes(rule)) { 1015 const customMessage = field.element.getAttribute('data-msg-' + rule); 1016 const message = customMessage ? customMessage : field.state.rules[rule]; 1017 const ruleOptions = JSON.parse(JSON.stringify(field.rules[rule])); 1018 1019 if (typeof message === 'undefined' || message === null || (typeof message !== 'string' && ! message.type)) { 1020 messages.push(hyva.strf('Validation rule "%0" failed.', rule)); 1021 } else if (Array.isArray(ruleOptions)) { 1022 ruleOptions.unshift(message.type ? message.content : message); 1023 const content = hyva.strf.apply(null, ruleOptions); 1024 messages.push(message.type ? {type: message.type, content} : content); 1025 } else { 1026 const content = hyva.strf(message.type ? message.content : message, ruleOptions) 1027 messages.push(message.type ? {type: message.type, content} : content); 1028 } 1029 } 1030 }); 1031 return messages; 1032 }, 1033 /** @deprecated */ 1034 getFieldWrapper(field) { 1035 return this.getMessageContainer(field) 1036 }, 1037 getMessageContainer(field) { 1038 let container; 1039 const pageSelector = field.element.getAttribute('data-validation-container') || options.pageMessagesContainerSelector; 1040 if (pageSelector) { 1041 container = document.querySelector(pageSelector) 1042 || containerNotFound(pageSelector, field.element) 1043 } else { 1044 const containerSelector = classNamesToSelector(options.fieldWrapperClassName); 1045 container = field.element.closest(containerSelector) 1046 || createMessageContainer(field.element, options.fieldWrapperClassName) 1047 || containerNotFound(containerSelector, field.element); 1048 } 1049 1050 return container; 1051 }, 1052 showFieldState(field) { 1053 const container = this.getMessageContainer(field), 1054 hasErrorMessages = hasMessagesWrapper.call(this, field, options.messagesWrapperClassName), 1055 messages = this.getMessagesByField(field).map(m => { 1056 return m.type !== 'html' ? escapeHtml(m.type ? m.content : m) : m.content; 1057 }); 1058 container.classList.toggle(options.validClassName, field.state.valid && ! hasErrorMessages); 1059 container.classList.toggle(options.invalidClassName, !field.state.valid || hasErrorMessages); 1060 this.createHtmlErrorMessage(field, messages); 1061 1062 if (field.state.valid) { 1063 field.element.removeAttribute('aria-invalid'); 1064 } else { 1065 field.element.setAttribute('aria-invalid', 'true'); 1066 if (! document.activeElement) { 1067 field.element.focus(); 1068 } 1069 } 1070 }, 1071 removeMessages(field, messagesClass) { 1072 if (! hasMessagesWrapper.call(this, field, messagesClass || options.messagesWrapperClassName)) { 1073 return; 1074 } 1075 1076 const msgWrapper = getMessagesWrapper.call(this, field, messagesClass || options.messagesWrapperClassName); 1077 const messages = msgWrapper.querySelectorAll(`[data-msg-field='${field.element.name}']`);
1078 Array.from(messages).forEach(msg => msg.remove()); 1079 if (msgWrapper && msgWrapper.childElementCount === 0) { 1080 field.element.removeAttribute('aria-errormessage'); 1081 field.element.removeAttribute('aria-describedby'); 1082 msgWrapper.remove(); 1083 } 1084 }, 1085 createErrorMessage(field, messages) { 1086 const htmlMessages = (Array.isArray(messages) ? messages : [messages]).map(escapeHtml) 1087 this.createHtmlErrorMessage(field, htmlMessages); 1088 }, 1089 createHtmlErrorMessage(field, messages) { 1090 this.removeMessages(field, options.messagesWrapperClassName); 1091 field.element.removeAttribute('aria-errormessage'); 1092 field.element.removeAttribute('aria-describedby'); 1093 1094 if (!field.state.valid) { 1095 const msgWrapper = this.addHtmlMessages(field, options.messagesWrapperClassName, messages); 1096 field.element.setAttribute('aria-errormessage', msgWrapper.id); 1097 field.element.setAttribute('aria-describedby', msgWrapper.id); 1098 } 1099 }, 1100 /** @deprecated */ 1101 createMessage(field, message) { 1102 return this.addMessages(field, options.messagesWrapperClassName, message); 1103 }, 1104 addMessages(field, messagesClass, messages) { 1105 const htmlMessages = (Array.isArray(messages) ? messages : [messages]).map(escapeHtml) 1106 return this.addHtmlMessages(field, messagesClass, htmlMessages); 1107 }, 1108 addHtmlMessages(field, messagesClass, htmlMessages) { 1109 const msgWrapper = getMessagesWrapper.call(this, field, messagesClass); 1110 1111 (Array.isArray(htmlMessages) ? htmlMessages : [htmlMessages]).forEach((htmlMessage) => { 1112 const li = document.createElement('li'); 1113 li.innerHTML = htmlMessage; 1114 li.setAttribute('data-msg-field', field.element.name); 1115 msgWrapper.appendChild(li); 1116 }); 1117 1118 return msgWrapper; 1119 }, 1120 setField(name, value) { 1121 this.fields[name].element.value = value; 1122 this.fields[name].element.dispatchEvent((new Event('input'))); 1123 this.validateField(this.fields[name]); 1124 } 1125 } 1126 } 1127 1128 hyva.formValidation = formValidation; 1129 hyva.formValidation.rules = formValidationRules; 1130 hyva.formValidation.setInputAttributeRuleName = (attrName, ruleName) => INPUT_ATTRIBUTE_RULES[attrName] = ruleName || attrName; 1131 hyva.formValidation.setInputTypeRuleName = (typeName, ruleName) => INPUT_TYPE_RULES[typeName] = ruleName || typeName; 1132 hyva.formValidation.addRule = (name, validator) => formValidationRules[name] = validator; 1133 }(window.hyva = window.hyva || {})); 1134</script>
1134 1135 1136<div class="page-wrapper"><header class="page-header"><div class="black-week-coupon-code-banner" data-content-type="html" data-appearance="default" data-element="main" data-decoded="true"><style> 1137.quick-buy { 1138 display: none !important; 1139} 1140</style></div><div id="downgrade-date-container" style="background-color: #FF6D0F"></div>
1141<script> 1142 const nextDowngradeDayCacheStorage = JSON.parse(window.localStorage.getItem('mage-cache-storage')); 1143 const daysToNextDowngrade = nextDowngradeDayCacheStorage.customer.gfc_next_downgrade_days; 1144 1145 if (daysToNextDowngrade) { 1146 const downgradeMessageTemplate = "In %1 Tagen verlierst Du Cash & Level Points und wirst somit zurückgestuft. Shoppe jetzt, um Deine Points zu behalten."; 1147 const downgradeMessage = downgradeMessageTemplate.replace('%1', daysToNextDowngrade); 1148 1149 document.getElementById('downgrade-date-container').innerHTML = ` 1150 <div class="next-downgrade-warning-header"> 1151 <div class="text-main-white text-left laptop:text-center py-1 px-3 flex items-center justify-center tablet:gap-x-8 z-20 relative overflow-x-auto whitespace-nowrap"> 1152 <p class="fs-14"> 1153 ${downgradeMessage} 1154 <a href="https://www.justspices.de/goodfoodclub#faq"><u class="fs-14">Mehr erfahren</u></a> 1155 </p> 1156 </div> 1157 </div> 1158 `; 1159 const benefitAnnouncement = document.getElementById("scroll-container"); 1160 const couponCodeAnnouncement = document.getElementById("couponBanner"); 1161 if (benefitAnnouncement) { 1162 benefitAnnouncement.remove(); 1163 } 1164 if (couponCodeAnnouncement) { 1165 couponCodeAnnouncement.remove(); 1166 } 1167 } 1168</script>
1168 1169<a class="action skip sr-only focus:not-sr-only focus:absolute focus:z-40 focus:bg-white 1170 contentarea" 1171 href="#contentarea"> 1172 <span> 1173 Zum Inhalt springen </span> 1174</a>
1175<script> 1176 function initHeader () { 1177 return { 1178 slideOutAnimation: false, 1179 searchOpen: false, 1180 cart: {}, 1181 customer : {}, 1182 isCartOpen: false, 1183 isCustomerMenuOpen : false, 1184 getData(data) { 1185 if (data.cart) { this.cart = data.cart } 1186 if (data.customer) { this.customer = data.customer} 1187 }, 1188 getGfcIcon() { 1189 if(this.customer.gfc_level) { 1190 let level = this.customer.gfc_level; 1191 return level.replace(/\s+/g, '_').toLowerCase(); 1192 } 1193 return '' 1194 }, 1195 isCartEmpty() { 1196 return !this.cart.summary_count 1197 }, 1198 visibleCartItemsCount(summary_count) { 1199 let cartItems = this.cart.items; 1200 if (cartItems.length > 0) { 1201 let hiddenQtyCount = cartItems 1202 .filter(item => item.hide_for_customer === true || item.message === '\nFREE!') 1203 .reduce((acc, item) => acc + item.qty, 0) 1204 return summary_count - hiddenQtyCount 1205 } 1206 return summary_count 1207 }, 1208 toggleCart(event) { 1209 if (event.detail && event.detail.isOpen !== undefined) { 1210 this.isCartOpen = event.detail.isOpen 1211 if (!this.isCartOpen && this.$refs && this.$refs.cartButton) { 1212 this.$refs.cartButton.focus() 1213 } 1214 } else { 1215 this.isCartOpen = true 1216 } 1217 }, 1218 toggleCustomerNav(event) { 1219 if (event.detail && event.detail.isOpen !== undefined) { 1220 this.isCustomerMenuOpen = event.detail.isOpen 1221 } else { 1222 this.isCustomerMenuOpen = true 1223 } 1224 }, 1225 slideOut() { 1226 this.slideOutAnimation = true 1227 setTimeout(() => { 1228 this.slideOutAnimation = false 1229 this.searchOpen = false 1230 }, 350); 1231 }, 1232 toggleMobileSearchBar() { 1233 if(this.searchOpen === true){ 1234 document.body.classList.add('searchbar-open'); 1235 }else { 1236 document.body.classList.remove('searchbar-open'); 1237 } 1238 }, 1239 closeMobileSearchBar() { 1240 document.body.classList.remove('searchbar-open'); 1241 } 1242 } 1243 } 1244 function initCompareHeader() { 1245 return { 1246 compareProducts: null, 1247 itemCount: 0, 1248 receiveCompareData(data) { 1249 if (data['compare-products']) { 1250 this.compareProducts = data['compare-products']; 1251 this.itemCount = this.compareProducts.count; 1252 } 1253 } 1254 } 1255 } 1256</script>
1256 1257 1258<div id="header" 1259 class="bg-main-creme w-full relative" 1260 x-data="initHeader()" 1261 @private-content-loaded.window="getData(event.detail.data)" 1262 > 1263 <div class="container flex items-center justify-between py-1 laptop:py-2"> 1264 1265 <div class="header-left flex items-center justify-between gap-4 order-1 laptop:order-2"> 1266 1267 <nav 1268 x-data="initMenuMobile_6abf8ffc4212a()" 1269 @load.window="setActiveMenu($root)" 1270 @keydown.window.escape="closeMenu()" 1271 class="z-20 laptop:hidden toggle-nav" 1272 aria-label="Site navigation" 1273 role="navigation" 1274> 1275 <!-- mobile --> 1276 <button 1277 x-ref="mobileMenuTrigger" 1278 @click="!open ? openMenu() : closeMenu()" 1279 type="button" 1280 aria-label="Open menu" 1281 aria-haspopup="menu" 1282 :aria-expanded="open" 1283 id="mobile-toggle" 1284 > 1285 <div> 1286 <i class="fal fa-bars text-4"></i> 1287 </div> 1288 </button> 1289 <div 1290 x-ref="mobileMenuNavLinks" 1291 class="nav-links invisible" 1292 :class="{ 'open': open, 'invisible': !open }" 1293 :aria-hidden="open ? 'false' : 'true'" 1294 role="dialog" 1295 aria-modal="true" 1296 @click="closeMenu()" 1297 > 1298 1299 1300 <div class="navigation-wrapper"> 1301 <div class="close-button" @click="closeMenu()"> 1302 <i class="fal fa-times"></i> 1303 </div> 1304 <div class="navigation-container" @click.stop> 1305 <span class="go-to-previous"> 1306 1307 </span> 1308 <div data-content-type="html" data-appearance="default" data-element="main" data-decoded="true"><style> 1309 .navigation nav > div > ul#abtest-v1{ 1310 display:none; 1311 } 1312 #header nav div ul#abtest-v1{ 1313 display:none; 1314 } 1315 .submenu-dropdown > .container > div:has(+ ul.abtest) { 1316 gap: 15rem; 1317 } 1318 .submenu-dropdown>.container>div>ul.abtest { 1319 display: flex; 1320 flex-direction: row; 1321 gap: 8.8rem; 1322 max-width: fit-content; 1323 margin-top: 0; 1324} 1325 .submenu-dropdown>.container>div>ul.abtest a{ 1326 font-family: BrandonText-Regular, sans-serif; 1327 1328 } 1329 .navigation-wrapper .navigation-container ul.abtest{ 1330 gap: 1.5rem; 1331 } 1332 .navigation-wrapper .navigation-container ul.abtest a{ 1333 font-family: BrandonText-Regular, sans-serif; 1334 font-size: 1.6rem; 1335 } 1336 .navigation-wrapper .navigation-container ul.abtest span{ 1337 font-size: 1.6rem; 1338 } 1339 .navigation-wrapper .navigation-container ul>li ul.abtest>li ul>li>a{ 1340 background-color: unset; 1341 } 1342 .submenu-dropdown>.container>div>ul.abtest a.font-bold{ 1343 font-family: BrandonText-Bold, sans-serif; 1344 position: inherit; 1345 cursor: default; 1346 } 1347 .submenu-dropdown>.container>div>ul.abtest li{ 1348 padding: 0 0 10px 0px; 1349 } 1350 .abtest-img-hover{ 1351 cursor:pointer; 1352 max-width: 365px; 1353 margin-left: auto; 1354 margin-right: auto; 1355 margin-top: 0; 1356 } 1357 1358 .navigation-wrapper .navigation-container ul.abtest-v1 a i.position-relative{ 1359 position : relative; 1360 } 1361 .navigation-wrapper .navigation-container ul.abtest-v1 span.bold{ 1362 font-family: BrandonText-Bold,sans-serif; 1363 } 1364 .navigation-wrapper .navigation-container ul.abtest-v1 > li ul > li ul > li > a{ 1365 background-color: inherit; 1366 padding: .8rem 0; 1367 } 1368 1369</style></div><div data-content-type="html" data-appearance="default" data-element="main" data-decoded="true"><ul id="first-layer" class="abtest-original"> 1370 <li> 1371 <a data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:parent"> 1372 <picture> 1373 1374 <source type="image/webp" 1375 srcset="https://www.justspices.de/media/opti_image/webp/wysiwyg/relaunch-2024/navigation/nav-gewuerze.webp"> 1376 1377 <source type="image/png" 1378 srcset="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/nav-gewuerze.png"> 1379 1380 <img src="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/nav-gewuerze.png" class="laptop:hidden first-layer
1380-image" alt="Gewürze" /> </picture> 1381 1382 1383 Gewürze 1384 </a> 1385 <ul> 1386 <li onlyDesktop><span>Gewürze</span></li> 1387 <li onlyDesktop> 1388 <a href="https://www.justspices.de/alle-produkte.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:AlleProdukte">Alle Produkte</a> 1389 </li> 1390 <li> 1391 <a href="https://www.justspices.de/gewuerzmischungen.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:Gewurzmischungen">Alle Gewürzmischungen</a> 1392 </li> 1393 <li> 1394 <a href="https://www.justspices.de/bestseller.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:Bestseller">Bestseller</a> 1395 </li> 1396 1397 <li rightContainer> 1398 <a onlyMobile>Nach Kategorie</a> 1399 <ul onlyMobile> 1400 <li> 1401 <a href="https://www.justspices.de/gewuerzmischungen/suppen-und-eintoepfe.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:SuppenEintöpfe"> 1402 <img data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/cat-image-suppen-eintopf.svg" width="64" height="64" class="lozad" /> 1403 <span>Suppen & Eintöpfe</span> 1404 </a> 1405 </li> 1406 <li> 1407 <a href="https://www.justspices.de/gewuerzmischungen/fruehstueck.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:Fruhstuck"> 1408 <img data-src="https://www.justspices.de/media/wysiwyg/navigation/fruehstueck.svg" width="64" height="64" class="lozad" /> 1409 <span>Frühstück</span> 1410 </a> 1411 </li> 1412 <li> 1413 <a href="https://www.justspices.de/gewuerzmischungen/backen-und-suesses.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:BackenSusses"> 1414 <img data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/suesses.svg" width="64" height="64" class="lozad" /> 1415 <span>Backen & Süsses</span> 1416 </a> 1417 </li> 1418 <li> 1419 <a href="https://www.justspices.de/gewuerzmischungen/dips-und-aufstriche.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:AufstricheDips"> 1420 <img data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/dips.svg" width="64" height="64" class="lozad" /> 1421 <span>Aufstriche & Dips</span> 1422 </a> 1423 </li> 1424 <li> 1425 <a href="https://www.justspices.de/gewuerzmischungen/italienisch.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:Italienisch"> 1426 <img data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/italienisch.svg" width="64" height="64" class="lozad" /> 1427 <span>Italienisch</span> 1428 </a> 1429 </li> 1430 <li> 1431 <a href="https://www.justspices.de/gewuerzmischungen/kartoffeln.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:Kartoffeln"> 1432 <img data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/kartoffeln.svg" width="64" height="64" class="lozad" /> 1433 <span>Kartoffeln</span> 1434 </a> 1435 </li> 1436 <li> 1437 <a href="https://www.justspices.de/gewuerzmischungen/airfryer.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:Heissluftfritteuse"> 1438 <img data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/heissluftfritteuse.svg" width="64" height="64" class="lozad" />
1439 <span>Airfryer</span> 1440 </a> 1441 </li> 1442 <li> 1443 <a href="https://www.justspices.de/asiatische-gewuerzmischungen" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:Asiatisch"> 1444 <img data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/asiatisch.svg" width="64" height="64" class="lozad" /> 1445 <span>Asiatisch</span> 1446 </a> 1447 </li> 1448 </ul> 1449 <ul onlyDesktop> 1450 <li><span>Nach Anwendung</span></li> 1451 <li> 1452 <a href="https://www.justspices.de/gewuerzmischungen/salat-und-dressing.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:SalatDressing"> 1453 <span><i class="fa-light fa-salad pr-1"></i> Salat & Dressing</span> 1454 </a> 1455 </li> 1456 <li> 1457 <a href="https://www.justspices.de/gewuerzmischungen/fruehstueck.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:Fruhstuck"> 1458 1459 <span><i class="fa-light fa-croissant pr-1"></i> Frühstück</span> 1460 </a> 1461 </li> 1462 <li> 1463 <a href="https://www.justspices.de/gewuerzmischungen/backen-und-suesses.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:BackenSusses"> 1464 1465 <span><i class="fa-light fa-cupcake pr-1"></i> Backen & Süsses</span> 1466 </a> 1467 </li> 1468 1469 <li> 1470 <a href="https://www.justspices.de/gewuerzmischungen/grillen.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:MarinierenGrillen"> 1471 1472 <span><i class="fa-light fa-meat pr-1"></i> Marinieren & Grillen</span> 1473 </a> 1474 </li> 1475 <li> 1476 <a href="https://www.justspices.de/gewuerzmischungen/eis-joghurt-und-getraenke.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:EisJoghurtGetränke"> 1477 1478 <span><i class="fa-light fa-ice-cream pr-1"></i> Eis, Joghurt & Getränke</span> 1479 </a> 1480 </li> 1481 <li> 1482 <a href="https://www.justspices.de/gewuerzmischungen/dips-und-aufstriche.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:AufstricheDips"> 1483 1484 <span><i class="fa-light fa-avocado pr-1"></i> Aufstriche & Dips</span> 1485 </a> 1486 </li> 1487 </ul> 1488 <ul onlyDesktop> 1489 <li><span>Nach Küche</span></li> 1490 <li> 1491 <a href="https://www.justspices.de/gewuerzmischungen/indisch.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:Indisch"> 1492 1493 <span>Indisch</span> 1494 </a> 1495 </li> 1496 <li> 1497 <a href="https://www.justspices.de/gewuerzmischungen/italienisch.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:Italienisch"> 1498 1499 <span>Italienisch</span> 1500 </a> 1501 </li> 1502 <li> 1503 <a href="https://www.justspices.de/gewuerzmischungen/mexikanisch.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:Mexikanisch"> 1504
1505 <span>Mexikanisch</span> 1506 </a> 1507 </li> 1508 1509 <li> 1510 <a href="https://www.justspices.de/gewuerzmischungen/griechisch.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:Griechisch"> 1511 1512 <span>Griechisch</span> 1513 </a> 1514 </li> 1515 <li> 1516 <a href="https://www.justspices.de/gewuerzmischungen/orientalisch.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:Orientalisch"> 1517 1518 <span>Orientalisch</span> 1519 </a> 1520 </li> 1521 <li> 1522 <a href="https://www.justspices.de/gewuerzmischungen/asiatisch.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:Asiatisch"> 1523 1524 <span>Asiatisch</span> 1525 </a> 1526 </li> 1527 </ul> 1528 <ul onlyDesktop> 1529 <li><span>Passend zu</span></li> 1530 <li> 1531 <a href="https://www.justspices.de/gewuerzmischungen/kartoffeln.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:Kartoffeln"> 1532 1533 <span>Kartoffeln</span> 1534 </a> 1535 </li> 1536 <li> 1537 <a href="https://www.justspices.de/gewuerzmischungen/fleisch.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:Fleisch"> 1538 1539 <span>Fleisch</span> 1540 </a> 1541 </li> 1542 <li> 1543 <a href="https://www.justspices.de/gewuerzmischungen/gemuese.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:Gemüse"> 1544 1545 <span>Gemüse</span> 1546 </a> 1547 </li> 1548 1549 <li> 1550 <a href="https://www.justspices.de/gewuerzmischungen/pasta.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:Pasta"> 1551 1552 <span>Pasta</span> 1553 </a> 1554 </li> 1555 <li> 1556 <a href="https://www.justspices.de/gewuerzmischungen/fisch.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:Fisch"> 1557 1558 <span>Fisch</span> 1559 </a> 1560 </li> 1561 1562 </ul> 1563 <ul onlyDesktop> 1564 <li imageContainer> 1565 <a href="https://www.justspices.de/bestseller/fruehling.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:Bild"> 1566 <picture> 1567 1568 <source type="image/webp" 1569 srcset="https://www.justspices.de/media/opti_image/webp/wysiwyg/relaunch-2024/navigation/image-fruehlings-bestseller.webp"> 1570 1571 <source type="image/png" 1572 srcset="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/image-fruehlings-bestseller.png"> 1573 1574 <img class="abtest-img-hover" src="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/image-fruehlings-bestseller.png" alt="Gewürze" /> </picture> 1575 1576 1577 </a> 1578 </li> 1579 </ul> 1580 </li> 1581 1582 1583 </ul> 1584 </li> 1585 1586 <li> 1587 <a data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:parent"> 1588 <picture> 1589 1590 <source type="image/webp" 1591 srcset="https://www.justspices.de/media/opti_image/webp/wysiwyg/relaunch-2024/navigation/rezepte_mobile.webp"> 1592 1593 <source type="image/png" 1594 srcset="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/rezepte_mobile.png"> 1595 1596 <img src="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/rezepte_mobile.png" class="laptop:hidden first-layer
1596-image" alt="Rezepte" /> </picture> 1597 1598 1599 Rezepte & Co 1600 </a> 1601 <ul> 1602 <li onlyDesktop><span>Rezepte</span></li> 1603 <li> 1604 <a href="https://www.justspices.de/rezepte" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:Ubersicht">Ãbersicht</a> 1605 </li> 1606 <li> 1607 <a href="https://www.justspices.de/alle-rezepte" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:AlleRezepte">Alle Rezepte</a> 1608 </li> 1609 <li onlyDesktop> 1610 <a href="https://www.justspices.de/rezeptsammlungen/beliebte-rezepte" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:BeliebteRezepte">Beliebte Rezepte</a> 1611 </li> 1612 <li> 1613 <a href="https://www.justspices.de/rezeptsammlungen" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:Rezeptsammlungen">Rezeptsammlungen</a> 1614 </li> 1615 <li onlyMobile> 1616 <a>Nach Kategorie</a> 1617 <ul> 1618 <li> 1619 <a href="https://www.justspices.de/rezeptsammlungen/beliebte-rezepte" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:BeliebteRezepte"> 1620 <img data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/beliebt.svg" width="64" height="64" class="lozad" /> 1621 <span>Beliebte Rezepte</span> 1622 </a> 1623 </li> 1624 <li> 1625 <a href="https://www.justspices.de/rezeptsammlungen/vegetarische-rezepte" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:Vegetarisch"> 1626 <img data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/vegetarisch.svg" width="64" height="64" class="lozad" /> 1627 <span>Vegetarisch</span> 1628 </a> 1629 </li> 1630 <li> 1631 <a href="https://www.justspices.de/rezeptsammlungen/low-carb-rezepte" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:LowCarb"> 1632 <img data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/low-carb.svg" width="64" height="64" class="lozad" /> 1633 <span>Low Carb</span> 1634 </a> 1635 </li> 1636 <li> 1637 <a href="https://www.justspices.de/rezeptsammlungen/fleisch-rezepte" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:Fleisch"> 1638 <img data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/fleisch.svg" width="64" height="64" class="lozad" /> 1639 <span>Fleisch</span> 1640 </a> 1641 </li> 1642 <li> 1643 <a href="https://www.justspices.de/rezeptsammlungen/top30pasta-rezepte" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:Pasta"> 1644 <img data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/pasta.svg" width="64" height="64" class="lozad" /> 1645 <span>Pasta</span> 1646 </a> 1647 </li> 1648 <li> 1649 <a href="https://www.justspices.de/rezeptsammlungen/vegane-rezepte" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:Vegan"> 1650 <img data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/vegan.svg" width="64" height="64" class="lozad" />
1651 <span>Vegan</span> 1652 </a> 1653 </li> 1654 <li> 1655 <a href="https://www.justspices.de/rezeptsammlungen/kartoffel-rezepte" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:Kartoffeln"> 1656 <img data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/kartoffeln.svg" width="64" height="64" class="lozad" /> 1657 <span>Kartoffeln</span> 1658 </a> 1659 </li> 1660 <li> 1661 <a href="https://www.justspices.de/rezeptsammlungen/gemuese-rezepte" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:Gemuse"> 1662 <img data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/gemuese.svg" width="64" height="64" class="lozad" /> 1663 <span>Gemüse</span> 1664 </a> 1665 </li> 1666 </ul> 1667 </li> 1668 <li> 1669 <a href="https://www.justspices.de/waskocheichheute" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:Waskocheichheute">Was koche ich heute?</a> 1670 </li> 1671 <li> 1672 <a href="https://www.justspices.de/blog" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:Blog">Blog</a> 1673 </li> 1674 <li rightContainer onlyDesktop> 1675 <ul> 1676 <li><span>Nach Ernährung</span></li> 1677 <li> 1678 <a href="https://www.justspices.de/rezeptsammlungen/vegetarische-rezepte" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:Vegetarisch"> 1679 <span><i class="fa-light fa-leaf pr-1"></i> Vegetarisch</span> 1680 </a> 1681 </li> 1682 <li> 1683 <a href="https://www.justspices.de/rezeptsammlungen/vegane-rezepte" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:Vegan"> 1684 <span><i class="fa-light fa-v pr-1"></i> Vegan</span> 1685 </a> 1686 </li> 1687 <li> 1688 <a href="https://www.justspices.de/rezeptsammlungen/low-carb-rezepte" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:LowCarb"> 1689 1690 <span><i class="fa-light fa-bread-loaf pr-1"></i> Low Carb</span> 1691 </a> 1692 </li> 1693 1694 <li> 1695 <a href="https://www.justspices.de/rezeptsammlungen/kalorienarme-rezepte" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:Kalorienarm"> 1696 <span><i class="fa-light fa-tomato pr-1"></i> Kalorienarm</span> 1697 </a> 1698 </li> 1699 </ul> 1700 <ul> 1701 <li><span>Nach Menüart</span></li> 1702 <li> 1703 <a href="https://www.justspices.de/alle-rezepte?refine=menu%3AFr%C3%BChst%C3%BCck" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:Frühstück"> 1704 1705 <span>Frühstück</span> 1706 </a> 1707 </li> 1708 <li> 1709 <a href="https://www.justspices.de/rezeptsammlungen/mittagessen-rezepte" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:Mittagessen"> 1710 1711 <span>Mittagessen</span> 1712 </a> 1713 </li> 1714 <li> 1715 <a href="https://www.justspices.de/alle-rezepte?refine=menu%3ASnacks" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:Snacks"> 1716
1717 <span>Snacks</span> 1718 </a> 1719 </li> 1720 1721 <li> 1722 <a href="https://www.justspices.de/alle-rezepte?refine=menu%3AAbendessen" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:Abendessen"> 1723 1724 <span>Abendessen</span> 1725 </a> 1726 </li> 1727 <li> 1728 <a href="https://www.justspices.de/alle-rezepte?refine=menu%3ADessert" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:Dessert"> 1729 1730 <span>Dessert</span> 1731 </a> 1732 </li> 1733 </ul> 1734 <ul> 1735 <li><span>Nach Trends</span></li> 1736 <li> 1737 <a href="https://www.justspices.de/rezeptsammlungen/schnelle-rezepte" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:Schnelles"> 1738 1739 <span>Schnelles</span> 1740 </a> 1741 </li> 1742 <li> 1743 <a href="https://www.justspices.de/rezeptsammlungen/airfryer-rezepte" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:Airfryer"> 1744 1745 <span>Airfryer</span> 1746 </a> 1747 </li> 1748 <li> 1749 <a href="https://www.justspices.de/rezeptsammlungen/fingerfood-rezepte" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:Fingerfood"> 1750 1751 <span>Fingerfood</span> 1752 </a> 1753 </li> 1754 1755 <li> 1756 <a href="https://www.justspices.de/rezeptsammlungen/gnocchi-rezepte" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:Gnocchi"> 1757 1758 <span>Gnocchi</span> 1759 </a> 1760 </li> 1761 </ul> 1762 <ul onlyDesktop> 1763 <li imageContainer> 1764 <a href="https://www.justspices.de/rezeptsammlungen/airfryer-rezepte"> 1765 <picture> 1766 1767 <source type="image/webp" 1768 srcset="https://www.justspices.de/media/opti_image/webp/wysiwyg/relaunch-2024/navigation/rezepte-tab.webp"> 1769 1770 <source type="image/png" 1771 srcset="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/rezepte-tab.png"> 1772 1773 <img class="abtest-img-hover" src="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/rezepte-tab.png" alt="Airfryer Rezepte" /> </picture> 1774 1775 1776 </a> 1777 </li> 1778 </ul> 1779 </li> 1780 </ul> 1781 </li> 1782 1783 1784 <li> 1785 <a href="https://www.justspices.de/storefinder" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Storefinder:parent"> 1786 <picture> 1787 1788 <source type="image/webp" 1789 srcset="https://www.justspices.de/media/opti_image/webp/wysiwyg/relaunch-2024/navigation/nav-storefinder.webp"> 1790 1791 <source type="image/png" 1792 srcset="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/nav-storefinder.png"> 1793 1794 <img src="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/nav-storefinder.png" class="laptop:hidden first-layer-image" alt="Storefinder" /> </picture> 1795 1796 1797 Storefinder 1798 </a> 1799 </li> 1800 1801 <li> 1802 <a href="https://www.justspices.de/about" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="UeberUns:parent"> 1803 <picture> 1804 1805 <source type="image/webp" 1806 srcset="https://www.justspices.de/media/opti_image/webp/wysiwyg/relaunch-2024/navigation/neu_mobile.webp"> 1807 1808 <source type="image/png" 1809 srcset="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/neu_mobile.png"> 1810 1811 <img src="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/neu_mobile.png" class="laptop:hidden first-layer
1811-image" alt="Ãber Uns" /> </picture> 1812 1813 1814 Ãber Uns 1815 </a> 1816 </li> 1817 1818</ul></div> </div> 1819 </div> 1820 </div> 1821</nav>
1822<script> 1823 'use strict'; 1824 1825 const initMenuMobile_6abf8ffc4212a = () => { 1826 return { 1827 mobilePanelActiveId: null, 1828 open: false, 1829 goBackButton : document.querySelector('.go-to-previous'), 1830 slideOutLeft(item, removeHiddenClass = true) { 1831 item.classList.add('slide-out-left'); 1832 item.addEventListener('animationend', function() { 1833 item.classList.remove('slide-out-left'); 1834 if (removeHiddenClass) { 1835 item.classList.add('hidden-important'); 1836 } else { 1837 item.style.display = 'none'; 1838 } 1839 }, { once: true }); 1840 }, 1841 slideOutRight(item, removeHiddenClass = true) { 1842 item.classList.add('slide-out-right'); 1843 item.addEventListener('animationend', function() { 1844 item.classList.remove('slide-out-right'); 1845 if (removeHiddenClass) { 1846 item.classList.add('hidden-important'); 1847 } else { 1848 item.style.display = 'none'; 1849 } 1850 }, { once: true }); 1851 }, 1852 slideInLeft(item, className = 'flex') { 1853 item.classList.remove('hidden-important'); 1854 item.style.display = className; 1855 item.classList.add('slide-in-left'); 1856 item.addEventListener('animationend', function() { 1857 item.classList.remove('slide-in-left'); 1858 }, { once: true }); 1859 }, 1860 slideInRight(item, className = 'flex') { 1861 item.classList.remove('hidden-important'); 1862 item.style.display = className; 1863 item.classList.add('slide-in-right'); 1864 item.addEventListener('animationend', function() { 1865 item.classList.remove('slide-in-right'); 1866 }, { once: true }); 1867 },
1868 setActiveMenu(menuNode) { 1869 // Remove desktop-only elements from mobile navigation 1870 menuNode.querySelectorAll('[onlyDesktop]').forEach(el => el.remove()); 1871 1872 Array.from(menuNode.querySelectorAll('a')).filter(link => { 1873 return link 1874 }).map(item => { 1875 if (item.nextElementSibling && item.nextElementSibling.tagName.toLowerCase() === 'ul') { 1876 1877 item.classList.add('has-subcategory'); 1878 item.insertAdjacentHTML('beforeend', '<i class="fal fa-arrow-right"></i>'); 1879 item.addEventListener('click', () => { 1880 1881 let parentLi = item.closest('li'), 1882 parentList = parentLi.parentElement, 1883 allLi = parentList.querySelectorAll(':scope > li'); 1884 1885 1886 let clickedItems = document.querySelectorAll('.navigation-container .clicked') 1887 clickedItems.forEach(function(clickedItem) { 1888 clickedItem.classList.remove('clicked'); 1889 }); 1890 item.classList.add('clicked') 1891 1892 1893 // item.classList.add('hidden-important'); 1894 this.slideOutLeft(item) 1895 allLi.forEach((li) => { 1896 if (li !== parentLi) { 1897 this.slideOutLeft(li) 1898 } 1899 }); 1900 1901 item.addEventListener('animationend', () => { 1902 this.slideInRight(item.nextElementSibling) 1903 }, { once: true }); 1904 1905 this.goBackButton.innerHTML = '<i class="fas fa-chevron-left"></i>' + item.innerText; 1906 this.goBackButton.classList.add('add-margin') 1907 }) 1908 1909 } 1910 }); 1911 this.goBackButton.addEventListener('click',() => { 1912 let clickedItem = document.querySelector('.navigation-container .clicked'), 1913 parentLi = clickedItem.closest('li'), 1914 parentList = parentLi.parentElement, 1915 allLi = parentList.querySelectorAll(':scope > li'), 1916 parentUl = clickedItem.closest('ul'); 1917 1918 this.slideOutRight(clickedItem.nextElementSibling) 1919 clickedItem.nextElementSibling.addEventListener('animationend', () => { 1920 this.slideInLeft(clickedItem) 1921 allLi.forEach((li) => { 1922 this.slideInLeft(li) 1923 }); 1924 }, { once: true }); 1925 1926 this.goBackButton.innerHTML = '' 1927 1928 clickedItem.classList.remove('clicked'); 1929 1930 let prevAElement = parentUl.previousElementSibling; 1931 if (prevAElement && prevAElement.matches('a.has-subcategory')) { 1932 prevAElement.classList.add('clicked') 1933 this.goBackButton.innerHTML = '<i class="fas fa-chevron-left"></i>' + prevAElement.innerText; 1934 this.goBackButton.classList.add('mb-2') 1935 } 1936 1937 if (this.goBackButton.innerHTML === '') { 1938 this.goBackButton.classList.remove('mb-2') 1939 } 1940 }) 1941 }, 1942 openMenu() { 1943 this.open = true 1944 document.body.style.overflow = 'hidden'; 1945 if (lazyLoadInstance !== 'undefined') { 1946 lazyLoadInstance.update(); 1947 } 1948 }, 1949 closeMenu() { 1950 document.body.style.overflow = ''; 1951 this.open = false 1952 this.mobilePanelActiveId = null 1953 } 1954 } 1955 } 1956</script>
1956 1957 1958 <button 1959 id="menu-search-icon" 1960 class="laptop:hidden" 1961 @click.prevent=" 1962 searchOpen = !searchOpen; 1963 $dispatch('search-open'); 1964 window.setTimeout(function() { $refs.mobileSearchInput.focus() },0); 1965 toggleMobileSearchBar(); 1966 1967 " 1968 aria-label="Toggle search form" 1969 aria-haspopup="true" 1970 :aria-expanded="searchOpen" 1971 x-ref="searchButton" 1972 > 1973 <i class="fal fa-search text-4"></i> 1974 </button> 1975 </div> 1976 1977 <div class="header-center order-2 laptop:order-1 laptop:flex laptop:gap-4"> 1978 <a href="https://www.justspices.de/" class="logo" title="Just Spices" 1979 aria-label="store logo"> 1980 <picture> 1981 <source srcset="https://www.justspices.de/static/version1790005904/frontend/Justspices/relaunch/de_DE/images/logo.svg" type="image/svg+xml"> 1982 <img class="logo" src="https://www.justspices.de/static/version1790005904/frontend/Justspices/relaunch/de_DE/images/logo.png" alt="Just Spices Logo" width="60" height="60" /> 1983 </picture> 1984</a> 1985 1986 <div x-data="initMenuDesktop_6abf8ffc6ec6e()" 1987 class="z-20 navigation hidden laptop:flex" 1988> 1989 <!-- desktop --> 1990 <div x-ref="nav-desktop" 1991 @load.window="setActiveMenu($root)" 1992 class="hidden laptop:block"> 1993 <nav 1994 aria-label="Main menu" 1995 > 1996 <div data-content-type="html" data-appearance="default" data-element="main" data-decoded="true"><style> 1997 .navigation nav > div > ul#abtest-v1{ 1998 display:none; 1999 } 2000 #header nav div ul#abtest-v1{ 2001 display:none; 2002 } 2003 .submenu-dropdown > .container > div:has(+ ul.abtest) { 2004 gap: 15rem; 2005 } 2006 .submenu-dropdown>.container>div>ul.abtest { 2007 display: flex; 2008 flex-direction: row; 2009 gap: 8.8rem; 2010 max-width: fit-content; 2011 margin-top: 0; 2012} 2013 .submenu-dropdown>.container>div>ul.abtest a{ 2014 font-family: BrandonText-Regular, sans-serif; 2015 2016 } 2017 .navigation-wrapper .navigation-container ul.abtest{ 2018 gap: 1.5rem; 2019 } 2020 .navigation-wrapper .navigation-container ul.abtest a{ 2021 font-family: BrandonText-Regular, sans-serif; 2022 font-size: 1.6rem; 2023 } 2024 .navigation-wrapper .navigation-container ul.abtest span{ 2025 font-size: 1.6rem; 2026 } 2027 .navigation-wrapper .navigation-container ul>li ul.abtest>li ul>li>a{ 2028 background-color: unset; 2029 } 2030 .submenu-dropdown>.container>div>ul.abtest a.font-bold{ 2031 font-family: BrandonText-Bold, sans-serif; 2032 position: inherit; 2033 cursor: default; 2034 } 2035 .submenu-dropdown>.container>div>ul.abtest li{ 2036 padding: 0 0 10px 0px; 2037 } 2038 .abtest-img-hover{ 2039 cursor:pointer; 2040 max-width: 365px; 2041 margin-left: auto; 2042 margin-right: auto; 2043 margin-top: 0; 2044 } 2045 2046 .navigation-wrapper .navigation-container ul.abtest-v1 a i.position-relative{ 2047 position : relative; 2048 } 2049 .navigation-wrapper .navigation-container ul.abtest-v1 span.bold{ 2050 font-family: BrandonText-Bold,sans-serif; 2051 } 2052 .navigation-wrapper .navigation-container ul.abtest-v1 > li ul > li ul > li > a{ 2053 background-color: inherit; 2054 padding: .8rem 0; 2055 } 2056 2057</style></div><div data-content-type="html" data-appearance="default" data-element="main" data-decoded="true"><ul id="first-layer" class="abtest-original"> 2058 <li> 2059 <a data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:parent"> 2060 <picture> 2061 2062 <source type="image/webp" 2063 srcset="https://www.justspices.de/media/opti_image/webp/wysiwyg/relaunch-2024/navigation/nav-gewuerze.webp"> 2064 2065 <source type="image/png" 2066 srcset="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/nav-gewuerze.png"> 2067 2068 <img src="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/nav-gewuerze.png" class="laptop:hidden first-layer
2068-image" alt="Gewürze" /> </picture> 2069 2070 2071 Gewürze 2072 </a> 2073 <ul> 2074 <li onlyDesktop><span>Gewürze</span></li> 2075 <li onlyDesktop> 2076 <a href="https://www.justspices.de/alle-produkte.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:AlleProdukte">Alle Produkte</a> 2077 </li> 2078 <li> 2079 <a href="https://www.justspices.de/gewuerzmischungen.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:Gewurzmischungen">Alle Gewürzmischungen</a> 2080 </li> 2081 <li> 2082 <a href="https://www.justspices.de/bestseller.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:Bestseller">Bestseller</a> 2083 </li> 2084 2085 <li rightContainer> 2086 <a onlyMobile>Nach Kategorie</a> 2087 <ul onlyMobile> 2088 <li> 2089 <a href="https://www.justspices.de/gewuerzmischungen/suppen-und-eintoepfe.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:SuppenEintöpfe"> 2090 <img data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/cat-image-suppen-eintopf.svg" width="64" height="64" class="lozad" /> 2091 <span>Suppen & Eintöpfe</span> 2092 </a> 2093 </li> 2094 <li> 2095 <a href="https://www.justspices.de/gewuerzmischungen/fruehstueck.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:Fruhstuck"> 2096 <img data-src="https://www.justspices.de/media/wysiwyg/navigation/fruehstueck.svg" width="64" height="64" class="lozad" /> 2097 <span>Frühstück</span> 2098 </a> 2099 </li> 2100 <li> 2101 <a href="https://www.justspices.de/gewuerzmischungen/backen-und-suesses.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:BackenSusses"> 2102 <img data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/suesses.svg" width="64" height="64" class="lozad" /> 2103 <span>Backen & Süsses</span> 2104 </a> 2105 </li> 2106 <li> 2107 <a href="https://www.justspices.de/gewuerzmischungen/dips-und-aufstriche.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:AufstricheDips"> 2108 <img data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/dips.svg" width="64" height="64" class="lozad" /> 2109 <span>Aufstriche & Dips</span> 2110 </a> 2111 </li> 2112 <li> 2113 <a href="https://www.justspices.de/gewuerzmischungen/italienisch.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:Italienisch"> 2114 <img data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/italienisch.svg" width="64" height="64" class="lozad" /> 2115 <span>Italienisch</span> 2116 </a> 2117 </li> 2118 <li> 2119 <a href="https://www.justspices.de/gewuerzmischungen/kartoffeln.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:Kartoffeln"> 2120 <img data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/kartoffeln.svg" width="64" height="64" class="lozad" /> 2121 <span>Kartoffeln</span> 2122 </a> 2123 </li> 2124 <li> 2125 <a href="https://www.justspices.de/gewuerzmischungen/airfryer.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:Heissluftfritteuse"> 2126 <img data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/heissluftfritteuse.svg" width="64" height="64" class="lozad" />
2127 <span>Airfryer</span> 2128 </a> 2129 </li> 2130 <li> 2131 <a href="https://www.justspices.de/asiatische-gewuerzmischungen" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:Asiatisch"> 2132 <img data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/asiatisch.svg" width="64" height="64" class="lozad" /> 2133 <span>Asiatisch</span> 2134 </a> 2135 </li> 2136 </ul> 2137 <ul onlyDesktop> 2138 <li><span>Nach Anwendung</span></li> 2139 <li> 2140 <a href="https://www.justspices.de/gewuerzmischungen/salat-und-dressing.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:SalatDressing"> 2141 <span><i class="fa-light fa-salad pr-1"></i> Salat & Dressing</span> 2142 </a> 2143 </li> 2144 <li> 2145 <a href="https://www.justspices.de/gewuerzmischungen/fruehstueck.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:Fruhstuck"> 2146 2147 <span><i class="fa-light fa-croissant pr-1"></i> Frühstück</span> 2148 </a> 2149 </li> 2150 <li> 2151 <a href="https://www.justspices.de/gewuerzmischungen/backen-und-suesses.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:BackenSusses"> 2152 2153 <span><i class="fa-light fa-cupcake pr-1"></i> Backen & Süsses</span> 2154 </a> 2155 </li> 2156 2157 <li> 2158 <a href="https://www.justspices.de/gewuerzmischungen/grillen.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:MarinierenGrillen"> 2159 2160 <span><i class="fa-light fa-meat pr-1"></i> Marinieren & Grillen</span> 2161 </a> 2162 </li> 2163 <li> 2164 <a href="https://www.justspices.de/gewuerzmischungen/eis-joghurt-und-getraenke.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:EisJoghurtGetränke"> 2165 2166 <span><i class="fa-light fa-ice-cream pr-1"></i> Eis, Joghurt & Getränke</span> 2167 </a> 2168 </li> 2169 <li> 2170 <a href="https://www.justspices.de/gewuerzmischungen/dips-und-aufstriche.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:AufstricheDips"> 2171 2172 <span><i class="fa-light fa-avocado pr-1"></i> Aufstriche & Dips</span> 2173 </a> 2174 </li> 2175 </ul> 2176 <ul onlyDesktop> 2177 <li><span>Nach Küche</span></li> 2178 <li> 2179 <a href="https://www.justspices.de/gewuerzmischungen/indisch.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:Indisch"> 2180 2181 <span>Indisch</span> 2182 </a> 2183 </li> 2184 <li> 2185 <a href="https://www.justspices.de/gewuerzmischungen/italienisch.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:Italienisch"> 2186 2187 <span>Italienisch</span> 2188 </a> 2189 </li> 2190 <li> 2191 <a href="https://www.justspices.de/gewuerzmischungen/mexikanisch.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:Mexikanisch"> 2192
2193 <span>Mexikanisch</span> 2194 </a> 2195 </li> 2196 2197 <li> 2198 <a href="https://www.justspices.de/gewuerzmischungen/griechisch.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:Griechisch"> 2199 2200 <span>Griechisch</span> 2201 </a> 2202 </li> 2203 <li> 2204 <a href="https://www.justspices.de/gewuerzmischungen/orientalisch.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:Orientalisch"> 2205 2206 <span>Orientalisch</span> 2207 </a> 2208 </li> 2209 <li> 2210 <a href="https://www.justspices.de/gewuerzmischungen/asiatisch.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:Asiatisch"> 2211 2212 <span>Asiatisch</span> 2213 </a> 2214 </li> 2215 </ul> 2216 <ul onlyDesktop> 2217 <li><span>Passend zu</span></li> 2218 <li> 2219 <a href="https://www.justspices.de/gewuerzmischungen/kartoffeln.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:Kartoffeln"> 2220 2221 <span>Kartoffeln</span> 2222 </a> 2223 </li> 2224 <li> 2225 <a href="https://www.justspices.de/gewuerzmischungen/fleisch.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:Fleisch"> 2226 2227 <span>Fleisch</span> 2228 </a> 2229 </li> 2230 <li> 2231 <a href="https://www.justspices.de/gewuerzmischungen/gemuese.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:Gemüse"> 2232 2233 <span>Gemüse</span> 2234 </a> 2235 </li> 2236 2237 <li> 2238 <a href="https://www.justspices.de/gewuerzmischungen/pasta.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:Pasta"> 2239 2240 <span>Pasta</span> 2241 </a> 2242 </li> 2243 <li> 2244 <a href="https://www.justspices.de/gewuerzmischungen/fisch.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:Fisch"> 2245 2246 <span>Fisch</span> 2247 </a> 2248 </li> 2249 2250 </ul> 2251 <ul onlyDesktop> 2252 <li imageContainer> 2253 <a href="https://www.justspices.de/bestseller/fruehling.html" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Gewuerze:Bild"> 2254 <picture> 2255 2256 <source type="image/webp" 2257 srcset="https://www.justspices.de/media/opti_image/webp/wysiwyg/relaunch-2024/navigation/image-fruehlings-bestseller.webp"> 2258 2259 <source type="image/png" 2260 srcset="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/image-fruehlings-bestseller.png"> 2261 2262 <img class="abtest-img-hover" src="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/image-fruehlings-bestseller.png" alt="Gewürze" /> </picture> 2263 2264 2265 </a> 2266 </li> 2267 </ul> 2268 </li> 2269 2270 2271 </ul> 2272 </li> 2273 2274 <li> 2275 <a data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:parent"> 2276 <picture> 2277 2278 <source type="image/webp" 2279 srcset="https://www.justspices.de/media/opti_image/webp/wysiwyg/relaunch-2024/navigation/rezepte_mobile.webp"> 2280 2281 <source type="image/png" 2282 srcset="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/rezepte_mobile.png"> 2283 2284 <img src="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/rezepte_mobile.png" class="laptop:hidden first-layer
2284-image" alt="Rezepte" /> </picture> 2285 2286 2287 Rezepte & Co 2288 </a> 2289 <ul> 2290 <li onlyDesktop><span>Rezepte</span></li> 2291 <li> 2292 <a href="https://www.justspices.de/rezepte" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:Ubersicht">Ãbersicht</a> 2293 </li> 2294 <li> 2295 <a href="https://www.justspices.de/alle-rezepte" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:AlleRezepte">Alle Rezepte</a> 2296 </li> 2297 <li onlyDesktop> 2298 <a href="https://www.justspices.de/rezeptsammlungen/beliebte-rezepte" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:BeliebteRezepte">Beliebte Rezepte</a> 2299 </li> 2300 <li> 2301 <a href="https://www.justspices.de/rezeptsammlungen" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:Rezeptsammlungen">Rezeptsammlungen</a> 2302 </li> 2303 <li onlyMobile> 2304 <a>Nach Kategorie</a> 2305 <ul> 2306 <li> 2307 <a href="https://www.justspices.de/rezeptsammlungen/beliebte-rezepte" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:BeliebteRezepte"> 2308 <img data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/beliebt.svg" width="64" height="64" class="lozad" /> 2309 <span>Beliebte Rezepte</span> 2310 </a> 2311 </li> 2312 <li> 2313 <a href="https://www.justspices.de/rezeptsammlungen/vegetarische-rezepte" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:Vegetarisch"> 2314 <img data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/vegetarisch.svg" width="64" height="64" class="lozad" /> 2315 <span>Vegetarisch</span> 2316 </a> 2317 </li> 2318 <li> 2319 <a href="https://www.justspices.de/rezeptsammlungen/low-carb-rezepte" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:LowCarb"> 2320 <img data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/low-carb.svg" width="64" height="64" class="lozad" /> 2321 <span>Low Carb</span> 2322 </a> 2323 </li> 2324 <li> 2325 <a href="https://www.justspices.de/rezeptsammlungen/fleisch-rezepte" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:Fleisch"> 2326 <img data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/fleisch.svg" width="64" height="64" class="lozad" /> 2327 <span>Fleisch</span> 2328 </a> 2329 </li> 2330 <li> 2331 <a href="https://www.justspices.de/rezeptsammlungen/top30pasta-rezepte" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:Pasta"> 2332 <img data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/pasta.svg" width="64" height="64" class="lozad" /> 2333 <span>Pasta</span> 2334 </a> 2335 </li> 2336 <li> 2337 <a href="https://www.justspices.de/rezeptsammlungen/vegane-rezepte" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:Vegan"> 2338 <img data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/vegan.svg" width="64" height="64" class="lozad" />
2339 <span>Vegan</span> 2340 </a> 2341 </li> 2342 <li> 2343 <a href="https://www.justspices.de/rezeptsammlungen/kartoffel-rezepte" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:Kartoffeln"> 2344 <img data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/kartoffeln.svg" width="64" height="64" class="lozad" /> 2345 <span>Kartoffeln</span> 2346 </a> 2347 </li> 2348 <li> 2349 <a href="https://www.justspices.de/rezeptsammlungen/gemuese-rezepte" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:Gemuse"> 2350 <img data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/gemuese.svg" width="64" height="64" class="lozad" /> 2351 <span>Gemüse</span> 2352 </a> 2353 </li> 2354 </ul> 2355 </li> 2356 <li> 2357 <a href="https://www.justspices.de/waskocheichheute" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:Waskocheichheute">Was koche ich heute?</a> 2358 </li> 2359 <li> 2360 <a href="https://www.justspices.de/blog" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:Blog">Blog</a> 2361 </li> 2362 <li rightContainer onlyDesktop> 2363 <ul> 2364 <li><span>Nach Ernährung</span></li> 2365 <li> 2366 <a href="https://www.justspices.de/rezeptsammlungen/vegetarische-rezepte" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:Vegetarisch"> 2367 <span><i class="fa-light fa-leaf pr-1"></i> Vegetarisch</span> 2368 </a> 2369 </li> 2370 <li> 2371 <a href="https://www.justspices.de/rezeptsammlungen/vegane-rezepte" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:Vegan"> 2372 <span><i class="fa-light fa-v pr-1"></i> Vegan</span> 2373 </a> 2374 </li> 2375 <li> 2376 <a href="https://www.justspices.de/rezeptsammlungen/low-carb-rezepte" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:LowCarb"> 2377 2378 <span><i class="fa-light fa-bread-loaf pr-1"></i> Low Carb</span> 2379 </a> 2380 </li> 2381 2382 <li> 2383 <a href="https://www.justspices.de/rezeptsammlungen/kalorienarme-rezepte" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:Kalorienarm"> 2384 <span><i class="fa-light fa-tomato pr-1"></i> Kalorienarm</span> 2385 </a> 2386 </li> 2387 </ul> 2388 <ul> 2389 <li><span>Nach Menüart</span></li> 2390 <li> 2391 <a href="https://www.justspices.de/alle-rezepte?refine=menu%3AFr%C3%BChst%C3%BCck" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:Frühstück"> 2392 2393 <span>Frühstück</span> 2394 </a> 2395 </li> 2396 <li> 2397 <a href="https://www.justspices.de/rezeptsammlungen/mittagessen-rezepte" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:Mittagessen"> 2398 2399 <span>Mittagessen</span> 2400 </a> 2401 </li> 2402 <li> 2403 <a href="https://www.justspices.de/alle-rezepte?refine=menu%3ASnacks" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:Snacks"> 2404
2405 <span>Snacks</span> 2406 </a> 2407 </li> 2408 2409 <li> 2410 <a href="https://www.justspices.de/alle-rezepte?refine=menu%3AAbendessen" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:Abendessen"> 2411 2412 <span>Abendessen</span> 2413 </a> 2414 </li> 2415 <li> 2416 <a href="https://www.justspices.de/alle-rezepte?refine=menu%3ADessert" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:Dessert"> 2417 2418 <span>Dessert</span> 2419 </a> 2420 </li> 2421 </ul> 2422 <ul> 2423 <li><span>Nach Trends</span></li> 2424 <li> 2425 <a href="https://www.justspices.de/rezeptsammlungen/schnelle-rezepte" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:Schnelles"> 2426 2427 <span>Schnelles</span> 2428 </a> 2429 </li> 2430 <li> 2431 <a href="https://www.justspices.de/rezeptsammlungen/airfryer-rezepte" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:Airfryer"> 2432 2433 <span>Airfryer</span> 2434 </a> 2435 </li> 2436 <li> 2437 <a href="https://www.justspices.de/rezeptsammlungen/fingerfood-rezepte" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:Fingerfood"> 2438 2439 <span>Fingerfood</span> 2440 </a> 2441 </li> 2442 2443 <li> 2444 <a href="https://www.justspices.de/rezeptsammlungen/gnocchi-rezepte" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="RezepteCo:Gnocchi"> 2445 2446 <span>Gnocchi</span> 2447 </a> 2448 </li> 2449 </ul> 2450 <ul onlyDesktop> 2451 <li imageContainer> 2452 <a href="https://www.justspices.de/rezeptsammlungen/airfryer-rezepte"> 2453 <picture> 2454 2455 <source type="image/webp" 2456 srcset="https://www.justspices.de/media/opti_image/webp/wysiwyg/relaunch-2024/navigation/rezepte-tab.webp"> 2457 2458 <source type="image/png" 2459 srcset="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/rezepte-tab.png"> 2460 2461 <img class="abtest-img-hover" src="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/rezepte-tab.png" alt="Airfryer Rezepte" /> </picture> 2462 2463 2464 </a> 2465 </li> 2466 </ul> 2467 </li> 2468 </ul> 2469 </li> 2470 2471 2472 <li> 2473 <a href="https://www.justspices.de/storefinder" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="Storefinder:parent"> 2474 <picture> 2475 2476 <source type="image/webp" 2477 srcset="https://www.justspices.de/media/opti_image/webp/wysiwyg/relaunch-2024/navigation/nav-storefinder.webp"> 2478 2479 <source type="image/png" 2480 srcset="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/nav-storefinder.png"> 2481 2482 <img src="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/nav-storefinder.png" class="laptop:hidden first-layer-image" alt="Storefinder" /> </picture> 2483 2484 2485 Storefinder 2486 </a> 2487 </li> 2488 2489 <li> 2490 <a href="https://www.justspices.de/about" data-event="ev" data-ga4event="Main Menu" data-category="Navigation" data-action="Click" data-label="UeberUns:parent"> 2491 <picture> 2492 2493 <source type="image/webp" 2494 srcset="https://www.justspices.de/media/opti_image/webp/wysiwyg/relaunch-2024/navigation/neu_mobile.webp"> 2495 2496 <source type="image/png" 2497 srcset="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/neu_mobile.png"> 2498 2499 <img src="https://www.justspices.de/media/wysiwyg/relaunch-2024/navigation/neu_mobile.png" class="laptop:hidden first-layer
2499-image" alt="Ãber Uns" /> </picture> 2500 2501 2502 Ãber Uns 2503 </a> 2504 </li> 2505 2506</ul></div> </nav> 2507 </div> 2508</div>
2509<script> 2510 'use strict'; 2511 2512 const initMenuDesktop_6abf8ffc6ec6e = () => { 2513 return { 2514 originalHeaderColor: '', 2515 2516 init() { 2517 this.setOriginalHeaderColor(); 2518 }, 2519 2520 setOriginalHeaderColor() { 2521 const root = document.documentElement; 2522 const mainHeaderColor = getComputedStyle(root).getPropertyValue('--header-main-color').trim(); 2523 if (mainHeaderColor) { 2524 this.originalHeaderColor = mainHeaderColor || '#FCFAEE'; 2525 } else { 2526 this.originalHeaderColor = '#FCFAEE'; 2527 } 2528 }, 2529 2530 setHeaderColor(color) { 2531 const header = document.querySelector('#header'); 2532 if (header) { 2533 header.style.setProperty('--header-main-color', color); 2534 } 2535 }, 2536 2537 slideOutTop(item) { 2538 item.classList.add('slide-out-top'); 2539 item.addEventListener('animationend', function() { 2540 item.classList.remove('slide-out-top'); 2541 item.classList.add('hidden') 2542 }, { once: true }); 2543 }, 2544 slideInTop(item) { 2545 item.classList.remove('hidden'); 2546 item.classList.add('slide-in-top'); 2547 item.addEventListener('animationend', function() { 2548 item.classList.remove('slide-in-top'); 2549 }, { once: true }); 2550 }, 2551 showOverlay(submenu,navItems) { 2552 const existingOverlay = document.querySelector('.nav-overlay') 2553 2554 if (existingOverlay) { 2555 existingOverlay.remove() 2556 } 2557 2558 const overlay = document.createElement('div') 2559 overlay.classList.add('nav-overlay') 2560 document.body.appendChild(overlay) 2561 2562 overlay.addEventListener('click', () => { 2563 this.slideOutTop(submenu) 2564 submenu.classList.remove('open') 2565 navItems.forEach(item => { 2566 if (item.hasAttribute('can-close')) { 2567 item.removeAttribute('can-close') 2568 item.classList.remove('open') 2569 } 2570 }); 2571 overlay.remove() 2572 this.setHeaderColor(this.originalHeaderColor); 2573 }); 2574 }, 2575 hideOverlay() { 2576 const existingOverlay = document.querySelector('.nav-overlay') 2577 if (existingOverlay) { 2578 existingOverlay.remove() 2579 this.setHeaderColor(this.originalHeaderColor); 2580 } 2581 },
2582 setActiveMenu(menuNode) { 2583 // Remove mobile-only elements from desktop navigation 2584 menuNode.querySelectorAll('[onlyMobile]').forEach(el => el.remove()); 2585 2586 let header = document.querySelector('#header'), 2587 nav = document.querySelector('.navigation nav'), 2588 firstLevelNavItems = nav.querySelectorAll(':scope > div > ul > li > a'), 2589 subMenu = nav.querySelectorAll(':scope > div > ul > li > ul'); 2590 2591 const dropDownMenu = document.createElement('div'); 2592 dropDownMenu.classList.add('submenu-dropdown'); 2593 dropDownMenu.classList.add('hidden'); 2594 2595 const container = document.createElement('div'); 2596 container.classList.add('container'); 2597 dropDownMenu.appendChild(container); 2598 2599 header.insertAdjacentElement('afterend', dropDownMenu) 2600 2601 let activeSubMenu = null; 2602 2603 firstLevelNavItems.forEach((navItem) => { 2604 const navItemSubMenu = navItem.nextElementSibling; 2605 const menu = document.createElement('div') 2606 2607 if (navItemSubMenu) { 2608 const navItemRightItem = navItemSubMenu.querySelector('[rightcontainer]') 2609 const navItemImageItem = navItemSubMenu.querySelector('[imagecontainer]') 2610 2611 const rightContainerWrapper = document.createElement('div') 2612 rightContainerWrapper.classList.add('right-container') 2613 rightContainerWrapper.appendChild(navItemRightItem) 2614 if(navItemImageItem) { 2615 rightContainerWrapper.appendChild(navItemImageItem) 2616 } 2617 2618 2619 menu.appendChild(navItemSubMenu) 2620 menu.appendChild(rightContainerWrapper) 2621 2622 } 2623 2624 navItem.addEventListener('click', (event) => { 2625 if (navItemSubMenu) { 2626 event.preventDefault(); 2627 2628 const isOpen = navItem.hasAttribute('can-close'); 2629 2630 if (isOpen) { 2631 this.slideOutTop(dropDownMenu); 2632 this.hideOverlay(); 2633 dropDownMenu.classList.remove('open'); 2634 navItem.removeAttribute('can-close'); 2635 activeSubMenu = null; 2636 navItem.classList.remove('open'); 2637 } else { 2638 2639 firstLevelNavItems.forEach(item => { 2640 if (item !== navItem && item.hasAttribute('can-close')) { 2641 item.removeAttribute('can-close'); 2642 item.classList.remove('open') 2643 } 2644 }); 2645 2646 navItem.setAttribute('can-close', 'true'); 2647 navItem.classList.add('open') 2648 2649 if (!dropDownMenu.classList.contains('open')) { 2650 this.slideInTop(dropDownMenu); 2651 dropDownMenu.classList.add('open'); 2652 this.showOverlay(dropDownMenu, firstLevelNavItems); 2653 } 2654 2655 if (activeSubMenu && activeSubMenu !== menu) { 2656 menu.classList.add('hidden') 2657 } 2658 2659 this.setHeaderColor('#FCFAEE'); 2660 container.innerHTML = ''; 2661 container.appendChild(menu); 2662 menu.classList.remove('hidden'); 2663 2664 activeSubMenu = menu; 2665 2666 if (lazyLoadInstance !== 'undefined') {
2667 lazyLoadInstance.update(); 2668 } 2669 } 2670 } 2671 }); 2672 }); 2673 }, 2674 } 2675 } 2676</script>
2676 2677 </div> 2678 2679 <div class="header-right flex items-center justify-between gap-4 order-3"> 2680 2681 2682 <div class="vue-searchbar hidden laptop:block relative" id="vue-search"> 2683 <div class="ais-InstantSearch"> 2684 <div class="ais-SearchBox"> 2685 <div class="search-box position-relative"> 2686 <i class="fal fa-search font fs-16 black"></i> 2687 <input type="search" 2688 class="fs-14 lh-20" 2689 v-model="query" 2690 v-on:keyup.enter="window.location.href = baseUrl + 'catalogsearch/result/?q=' + query" 2691 placeholder="Suche" 2692 /> 2693 <i 2694 class="fal fa-times font fs-20 lh-20 black vue-search-reset" 2695 v-if="query.length > 0" 2696 @click="removeQuery" 2697 > 2698 </i> 2699 </div> 2700 </div> 2701 <div class="algolia-result-container search-results slide-in-right-slow" v-show="visible" v-bind:class="slideOutAnimation ? 'slide-out-right-slow' : ''" style="display: none;"> 2702 <div class="algolia-background"> 2703 <div class="algolia-result-nav"> 2704 <span v-bind:class="resultTabToggle === 'products' ? 'active' : ''" @click="toggleResultNav('products')">Produkte</span> 2705 <span v-bind:class="resultTabToggle === 'recipes' ? 'active' : ''" @click="toggleResultNav('recipes')">Rezepte</span> 2706 <span v-bind:class="resultTabToggle === 'blog' ? 'active' : ''" @click="toggleResultNav('blog')">Artikel</span> 2707 </div> 2708 <div class="result-list"> 2709 <div v-show="resultTabToggle === 'products'" class=""> 2710 <div class="ais-Hits" v-if="products.length > 0"> 2711 <div class="hit-result" v-for="(product,index) in products" v-if="product" v-bind:key="product.objectID"> 2712 <a class="" @click="redirectTo('product',product,index)" 2713 data-event="ev" data-ga4event="search_custom" data-category="product" 2714 data-action="click" v-bind:data-label="product.name"> 2715 <div class="hit-item-image"> 2716 <img v-bind:src="product.thumbnail_url_webp ?? product.image_url" class="lozad" style="width: 90px" width="90" height="90" v-bind:alt="product.name" v-bind:title="product.name" /> 2717 </div> 2718 <div class="hit-item-info"> 2719 <strong class="fs-14 lh-20">{{product.name}}</strong> 2720 <div class="prices" v-if="!isCreateYourOwn(product)"> 2721 <template v-if="product.type_id === 'bundle'"> 2722 <template v-if="product.price.EUR.default_max_formated"> 2723 <span class="fs-14 lh-20 bundle">{{product.price.EUR.default_max_formated}}</span> 2724 </template> 2725 <template v-else> 2726 <span class="fs-14 lh-20 bundle">{{product.price.EUR.default_formated}}</span> 2727 </template> 2728 </template> 2729 <template v-else> 2730 <span class="fs-14 lh-20">{{product.price.EUR.default_formated}}</span> 2731 <template v-if="product.price.EUR.default_original_formated"> 2732 <s class="fs-14 lh-20 text-main-red line-through old-price ml-1">{{product.price.EUR.default_original_formated}}</s> 2733 </template> 2734 </template> 2735 </div> 2736 </div> 2737 </a> 2738 </div> 2739 <div class="hits-header w-full">
2740 <span class="fs-14 lh-20"> 2741 {{productCount}} Ergebnisse </span> 2742 <div class="flex justify-center items-center gap-1"> 2743 <a class="fs-14 lh-20" 2744 v-bind:href="baseUrl + 'catalogsearch/result/?q=' + query" data-event="ev" 2745 data-ga4event="search_custom" data-category="product_all" 2746 data-action="click"> 2747 Alle anzeigen </a> 2748 <i class="fa-regular fa-arrow-right font fs-21 lh-28"></i> 2749 </div> 2750 </div> 2751 </div> 2752 2753 <div class="col-12 no-results" v-if="products.length === 0"> 2754 <p class="font text-s mb-2">Kein Ergebnis. Versuche es mit einem anderen Suchbegriff oder sieh Dir unsere Empfehlungen an.</p> 2755 <div class="inspiration"> 2756 <div data-content-type="html" data-appearance="default" data-element="main" data-decoded="true"><p class="font-recoleta text-m mb-2">Top Kategorien</p> 2757<div class="top-categories"> 2758 <a class="img-fluid category-icon" data-event="ev" data-ga4event="select_category" data-category="search" data-action="click" data-label="Bestseller" 2759 href="https://www.justspices.de/bestseller.html"> 2760 <img src="https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_products_bestseller.svg" alt="Produktkategorie Bestseller" /> 2761 <span>Bestseller</span> 2762 </a> 2763 <a class="img-fluid category-icon" data-event="ev" data-ga4event="select_category" data-category="search" data-action="click" data-label="Neuheiten" 2764 href="https://www.justspices.de/neuheiten.html"> 2765 <img src="https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_products_neuheiten.svg" alt="Produktkategorie Neuheiten" /> 2766 <span>Neuheiten</span> 2767 </a> 2768 <a class="img-fluid category-icon" data-event="ev" data-ga4event="select_category" data-category="search" data-action="click" data-label="Geschenkideen" 2769 href="https://www.justspices.de/geschenkideen.html"> 2770 <picture> 2771 2772 <source type="image/webp" 2773 srcset="https://www.justspices.de/media/opti_image/webp/wysiwyg/relaunch-2024/search/search_inspiration_products_gifts.webp"> 2774 2775 <source type="image/png" 2776 srcset="https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_products_gifts.png"> 2777 2778 <img src="https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_products_gifts.png" alt="Produktkategorie Geschenkideen" /> </picture> 2779 2780 2781 <span>Geschenke</span> 2782 </a> 2783</div> 2784<p class="font-recoleta text-m mb-2">Beliebte Produkte</p> 2785<div class="popular-products"> 2786 <a class="img-fluid product" data-event="ev" data-ga4event="select_product_recommendation" data-category="search" data-action="click" data-label="Avocado Topping" 2787 href="https://www.justspices.de/avocado-topping.html"> 2788 <picture> 2789 2790 <source type="image/webp" 2791 srcset="https://www.justspices.de/media/opti_image/webp/wysiwyg/relaunch-2024/search/search_inspiration_products_avocado_topping-2.webp"> 2792 2793 <source type="image/png" 2794 srcset="https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_products_avocado_topping-2.png"> 2795 2796 <img src="https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_products_avocado_topping-2.png" alt="Avocado Topping" /> </picture> 2797 2798 2799 <div class="product-info"> 2800 <p class="product-name">Avocado Topping</p> 2801 <p class="product-price">5,99 â¬</p> 2802 </div> 2803 </a> 2804 <a class="img-fluid product" data-event="ev" data-ga4event="select_product_recommendation" data-category="search" data-action="click" data-label="Ofengemüse Gewuerzmix" 2805 href="https://www.justspices.de/ofengemuese-gewuerzmix.html"> 2806 <picture> 2807 2808 <source type="image/webp" 2809 srcset="https://www.justspices.de/media/opti_image/webp/wysiwyg/relaunch-2024/search/search_inspiration_products_ofengemuese_gewuerzmix.webp"> 2810 2811 <source type="image/png" 2812 srcset="https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_products_ofengemuese_gewuerzmix.png"> 2813 2814 <img src="https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_products_ofengemuese_gewuerzmix.png" alt="Ofengemüse Gewürzmix" /> </picture> 2815 2816 2817 <div class="product-info"> 2818 <p class="product-name">Ofengemüse Gewürzmix</p> 2819 <p class="product-price">4,99 â¬</p> 2820 </div> 2821 </a> 2822 <a class="img-fluid product" data-event="ev" data-ga4event="select_product_recommendation" data-category="search" data-action="click" data-label="Haehnchen Allrounder" 2823 href="https://www.justspices.de/haehnchen-allrounder.html"> 2824 <picture> 2825 2826 <source type="image/webp" 2827 srcset="https://www.justspices.de/media/opti_image/webp/wysiwyg/relaunch-2024/search/search_inspiration_products_haehnchen_allrounder.webp"> 2828 2829 <source type="image/png" 2830 srcset="https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_products_haehnchen_allrounder.png"> 2831 2832 <img src="https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_products_haehnchen_allrounder.png" alt="Hähnchen Allrounder" /> </picture> 2833 2834 2835 <div class="product-info"> 2836 <p class="product-name">Hähnchen Allrounder</p> 2837 <p class="product-price">4,99 â¬</p> 2838 </div> 2839 </a> 2840 <a class="img-fluid product" data-event="ev" data-ga4event="select_product_recommendation" data-category="search" data-action="click" data-label="Aglio e Olio Gewuerzmix" 2841 href="https://www.justspices.de/aglio-e-olio-gewuerz.html"> 2842 <picture> 2843 2844 <source type="image/webp" 2845 srcset="https://www.justspices.de/media/opti_image/webp/wysiwyg/relaunch-2024/search/search_inspiration_products_aglio_e_olio_gewuerzmix.webp"> 2846 2847 <source type="image/png" 2848 srcset="https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_products_aglio_e_olio_gewuerzmix.png"> 2849 2850 <img src="https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_products_aglio_e_olio_gewuerzmix.png" alt="Aglio e Olio Gewürzmix" /> </picture> 2851 2852 2853 <div class="product-info"> 2854 <p class="product-name">Aglio e Olio Gewürzmix</p> 2855 <p class="product-price">5,49 â¬</p> 2856 </div> 2857 </a> 2858</div></div> </div> 2859 </div> 2860 </div> 2861 <div v-show="resultTabToggle === 'recipes'" class=""> 2862 <div class="ais-Hits recipe-hits" v-if="recipes.length > 0"> 2863 <div v-for="(recipe,index) in recipes" v-if="recipe && index < 7 " v-bind:key="recipe.objectID" class="hit-result recipe"> 2864 <a class="" @click="redirectTo('recipe',recipe,index)" 2865 data-event="ev" data-ga4event="search_custom" data-category="recipe" 2866 data-action="click" v-bind:data-label="recipe.title"> 2867 <div class="hit-item-image"> 2868 <img v-bind:src="recipe.image_url" class="lozad" width="150" height="150" v-bind:alt="recipe.image_alt" v-bind:title="recipe.title" /> 2869 </div> 2870 <div class="hit-item-info"> 2871 <strong class="fs-14 lh-20 title">{{recipe.title}}</strong> 2872 </div> 2873 </a> 2874 </div> 2875 <div class="hits-header w-full">
2876 <span class="fs-14 lh-20"> 2877 {{recipeCount}} Ergebnisse </span> 2878 <div class="flex justify-center items-center gap-1"> 2879 <a class="fs-14 lh-20" 2880 v-bind:href="baseUrl + 'catalogsearch/result/?tab=recipes&q=' + query" data-event="ev" 2881 data-ga4event="search_custom" data-category="recipes_all" 2882 data-action="click"> 2883 Alle anzeigen </a> 2884 <i class="fa-regular fa-arrow-right font fs-21 lh-28"></i> 2885 </div> 2886 </div> 2887 </div> 2888 <div class="col-12 no-results" v-if="recipes.length === 0"> 2889 <p class="font text-s mb-2">Kein Ergebnis. Versuche es mit einem anderen Suchbegriff oder sieh Dir unsere Empfehlungen an.</p> 2890 <div class="inspiration"> 2891 <div data-content-type="html" data-appearance="default" data-element="main" data-decoded="true"><p class="font-recoleta text-m mb-2">Top Rezeptsammlungen</p> 2892<div class="top-categories"> 2893 <a class="img-fluid category-icon" data-event="ev" data-ga4event="select_recipe_category" data-category="search" data-action="click" data-label="Beliebte Rezepte" 2894 href="https://www.justspices.de/rezeptsammlungen/beliebte-rezepte"> 2895 <img class="lozad" data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_products_bestseller.svg" alt="Beliebte Rezepte" /> 2896 <span>Beliebt</span> 2897 </a> 2898 <a class="img-fluid category-icon" data-event="ev" data-ga4event="select_recipe_category" data-category="search" data-action="click" data-label="Heissluftfritteuse Rezepte" 2899 href="https://www.justspices.de/rezeptsammlungen/heissluftfritteuse-rezepte"> 2900 <img class="lozad" data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_recipes_salat.svg" alt="Heissluftfritteuse Rezepte" /> 2901 <span>Fritteuse</span> 2902 </a> 2903 <a class="img-fluid category-icon" data-event="ev" data-ga4event="select_recipe_category" data-category="search" data-action="click" data-label="Grill Rezepte" 2904 href="https://www.justspices.de/rezeptsammlungen/grill-rezepte"> 2905 <img class="lozad" data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_products_bbq.svg" alt="Grill Rezepte" /> 2906 <span>Grill Rezepte</span> 2907 </a> 2908</div> 2909<p class="font-recoleta text-m mb-2">Beliebte Rezepte</p> 2910<div class="popular-recipes"> 2911 <a class="img-fluid recipe" data-event="ev" data-ga4event="select_recipe_recommendation" data-category="search" data-action="click" data-label="SüÃkartoffel Bowl aus der HeiÃluftfritteuse" 2912 href="https://www.justspices.de/rezepte/suesskartoffel-bowl-heissluftfritteuse.html"> 2913 <picture> 2914 2915 <source type="image/webp" data-srcset=" 2916 https://www.justspices.de/media/opti_image/webp/wysiwyg/relaunch-2024/search/search_inspiration_recipes_sweetpotatoebowl-2.webp"> 2917 2918 <source type="image/png" 2919 data-srcset=" 2920 https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_recipes_sweetpotatoebowl-2.png"> 2921 2922 <img class="lozad" data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_recipes_sweetpotatoebowl-2.png" alt="SüÃkartoffel Bowl aus der HeiÃluftfritteuse" /> </picture> 2923 2924 2925 <p class="recipe-name">SüÃkartoffel Bowl aus der HeiÃluftfritteuse</p> 2926 </a> 2927 <a class="img-fluid recipe" data-event="ev" data-ga4event="select_recipe_recommendation" data-category="search" data-action="click" data-label="Mexikanische Wraps" 2928 href="https://www.justspices.de/rezepte/mexikanische-wraps.html"> 2929 <picture> 2930 2931 <source type="image/webp" data-srcset=" 2932 https://www.justspices.de/media/opti_image/webp/wysiwyg/relaunch-2024/search/search_inspiration_recipes_mexikanische_wraps.webp"> 2933 2934 <source type="image/png" 2935 data-srcset=" 2936 https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_recipes_mexikanische_wraps.png"> 2937 2938 <img class="lozad" data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_recipes_mexikanische_wraps.png" alt="Mexikanische Wraps" /> </picture> 2939 2940 2941 <p class="recipe-name">Mexikanische Wraps</p> 2942 </a> 2943 <a class="img-fluid recipe" data-event="ev" data-ga4event="select_recipe_recommendation" data-category="search" data-action="click" data-label="Saftiger Joghurt Kuchen" 2944 href="https://www.justspices.de/rezepte/saftiger-joghurtkuchen.html"> 2945 <picture> 2946 2947 <source type="image/webp" data-srcset=" 2948 https://www.justspices.de/media/opti_image/webp/wysiwyg/relaunch-2024/search/search_inspiration_recipes_s
2948aftiger_joghurtkuchen.webp"> 2949 2950 <source type="image/png" 2951 data-srcset=" 2952 https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_recipes_saftiger_joghurtkuchen.png"> 2953 2954 <img class="lozad" data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_recipes_saftiger_joghurtkuchen.png" alt="Saftiger Joghurt Kuchen" /> </picture> 2955 2956 2957 <p class="recipe-name">Saftiger Joghurt Kuchen</p> 2958 </a> 2959 <a class="img-fluid recipe" data-event="ev" data-ga4event="select_recipe_recommendation" data-category="search" data-action="click" data-label="One Pot Pasta" 2960 href="https://www.justspices.de/rezepte/tomate-mozzarella-one-pot-pasta.html"> 2961 <picture> 2962 2963 <source type="image/webp" data-srcset=" 2964 https://www.justspices.de/media/opti_image/webp/wysiwyg/relaunch-2024/search/search_inspiration_recipes_one_pot_pasta.webp"> 2965 2966 <source type="image/png" 2967 data-srcset=" 2968 https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_recipes_one_pot_pasta.png"> 2969 2970 <img class="lozad" data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_recipes_one_pot_pasta.png" alt="One Pot Pasta" /> </picture> 2971 2972 2973 <p class="recipe-name">One Pot Pasta</p> 2974 </a> 2975</div></div> </div> 2976 </div> 2977 </div> 2978 <div v-show="resultTabToggle === 'blog'" class=""> 2979 <div class="ais-Hits blog-hits" v-if="blog.length > 0"> 2980 <div v-for="(post,index) in blog" v-if="post && index < 6 " v-bind:key="post.objectID" class="hit-result blog"> 2981 <a v-bind:href="post.url" class="" 2982 data-event="ev" data-ga4event="search_custom" data-category="blog" 2983 data-action="click" v-bind:data-label="post.title"> 2984 <div class="hit-item-image"> 2985 <img v-bind:src="post.image_url_crop_webp ?? post.image_url_crop" width="78" height="78" 2986 v-bind:alt="post.title" v-bind:title="post.title" 2987 class="lozad"> 2988 2989 </div> 2990 <div class="hit-item-info"> 2991 <strong class="fs-14 lh-20 title">{{post.title}}</strong> 2992 </div> 2993 </a> 2994 </div> 2995 <div class="hits-header w-full"> 2996 <span class="fs-14 lh-20"> 2997 {{blogCount}} Ergebnisse </span> 2998 <div class="flex justify-center items-center gap-1"> 2999 <a class="fs-14 lh-20" 3000 v-bind:href="baseUrl + 'catalogsearch/result/?tab=blog&q=' + query" data-event="ev" 3001 data-ga4event="search_custom" data-category="blog_all" 3002 data-action="click"> 3003 Alle anzeigen </a> 3004 <i class="fa-regular fa-arrow-right font fs-21 lh-28"></i> 3005 </div> 3006 </div> 3007 </div> 3008 <div class="col-12 no-results" v-if="blog.length === 0"> 3009 <p class="font text-s mb-2">Kein Ergebnis. Versuche es mit einem anderen Suchbegriff oder sieh Dir unsere Empfehlungen an.</p> 3010 <div class="inspiration"> 3011 <div data-content-type="html" data-appearance="default" data-element="main" data-decoded="true"><p class="font-recoleta text-m mb-2">Top Blog Kategorien</p> 3012<div class="top-categories"> 3013 <a class="img-fluid category-icon" data-event="ev" data-ga4event="select_blog_category" data-category="search" data-action="click" data-label="1x1 des Kochens" 3014 href="https://www.justspices.de/blog/1x1-des-kochens"> 3015 <img class="lozad" data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_blog_einmaleins_kochen.svg" alt="1x1 des Kochens" />
3016 <span>1x1 des Kochens</span> 3017 </a> 3018 <a class="img-fluid category-icon" data-event="ev" data-ga4event="select_blog_category" data-category="search" data-action="click" data-label="1x1 der Gewürze" 3019 href="https://www.justspices.de/blog/1x1-der-gewuerze"> 3020 <img class="lozad" data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_blog_einmaleins_gewuerze.svg" alt="1x1 der Gewürze" /> 3021 <span>1x1 der Gewürze</span> 3022 </a> 3023 <a class="img-fluid category-icon" data-event="ev" data-ga4event="select_blog_category" data-category="search" data-action="click" data-label="HeiÃe Themen" 3024 href="https://www.justspices.de/blog/heisse-themen"> 3025 <img class="lozad" data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_products_fritteuse.svg" alt="HeiÃe Themen" /> 3026 <span>HeiÃe Themen</span> 3027 </a> 3028</div> 3029<p class="font-recoleta text-m mb-2">Beliebte Blogartikel</p> 3030<div class="popular-blogposts"> 3031 <a class="img-fluid blogpost" data-event="ev" data-ga4event="select_blog_recommendation" data-category="search" data-action="click" data-label="Bulgur richtig kochen" 3032 href="https://www.justspices.de/blog/1x1-des-kochens/richtig-kochen/bulgur-kochen"> 3033 <picture> 3034 3035 <source type="image/webp" data-srcset=" 3036 https://www.justspices.de/media/opti_image/webp/wysiwyg/relaunch-2024/search/search_inspiration_blog_bulgur_kochen.webp"> 3037 3038 <source type="image/png" 3039 data-srcset=" 3040 https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_blog_bulgur_kochen.png"> 3041 3042 <img class="lozad" data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_blog_bulgur_kochen.png" alt="Bulgur richtig kochen" /> </picture> 3043 3044 3045 <p class="recipe-name">Bulgur richtig kochen</p> 3046 </a> 3047 <a class="img-fluid blogpost" data-event="ev" data-ga4event="select_blog_recommendation" data-category="search" data-action="click" data-label="Brokkoli richtig kochen" 3048 href="https://www.justspices.de/blog/1x1-des-kochens/richtig-kochen/brokkoli-kochen"> 3049 <picture> 3050 3051 <source type="image/webp" data-srcset=" 3052 https://www.justspices.de/media/opti_image/webp/wysiwyg/relaunch-2024/search/search_inspiration_blog_brokkoli_kochen.webp"> 3053 3054 <source type="image/png" 3055 data-srcset=" 3056 https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_blog_brokkoli_kochen.png"> 3057 3058 <img class="lozad" data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_blog_brokkoli_kochen.png" alt="Brokkoli richtig kochen" /> </picture> 3059 3060 3061 <p class="recipe-name">Brokkoli richtig kochen</p> 3062 </a> 3063 <a class="img-fluid blogpost" data-event="ev" data-ga4event="select_blog_recommendation" data-category="search" data-action="click" data-label="Was passt zu Kartoffelsalat?" 3064 href="https://www.justspices.de/blog/1x1-des-kochens/was-passt-zu/was-passt-zu-kartoffelsalat"> 3065 <picture> 3066 3067 <source type="image/webp" data-srcset=" 3068 https://www.justspices.de/media/opti_image/webp/wysiwyg/relaunch-2024/search/search_inspiration_blog_kartoffelsalat.webp"> 3069 3070 <source type="image/png" 3071 data-srcset=" 3072 https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_blog_kartoffelsalat.png"> 3073 3074 <img class="lozad" data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_blog_kartoffelsalat.png" alt="Was passt zu Kartoffelsalat?" /> </picture> 3075 3076 3077 <p class="recipe-name">Was passt zu Kartoffelsalat?</p> 3078 </a> 3079 <a class="img-fluid blogpost" data-event="ev" data-ga4event="select_blog_recommendation" data-category="search" data-action="click" data-label="Garnelen richtig würzen" 3080 href="https://www.justspices.de/blog/1x1-des-kochens/garnelen-wuerzen"> 3081 <picture> 3082 3083 <source type="image/webp" data-srcset=" 3084 https://www.justspices.de/media/opti_image/webp/wysiwyg/relaunch-2024/search/search_inspiration_blog_garnelen.webp"> 3085 3086 <source type="image/png" 3087 data-srcset=" 3088 https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_blog_garnelen.png"> 3089 3090 <img class="lozad" data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_blog_garnelen.png" alt="Garnelen richtig würzen" /> </picture> 3091 3092 3093 <p class="recipe-name">Garnelen richtig würzen</p> 3094 </a> 3095</div></div> </div> 3096 </div> 3097 </div> 3098 </div> 3099 </div> 3100 </div> 3101 </div> 3102</div>
3103<script type="module"> 3104 window.addEventListener('DOMContentLoaded', function() { 3105 3106 const algoliaClient = algoliasearch( 3107 'PCZYM1QRDW', 3108 '7d6e133d365a91ddf242dd6fbd396721', 3109 ); 3110 3111 const searchClient = { 3112 ...algoliaClient, 3113 search(requests) { 3114 if (requests.every(({ params }) => params.query === "")) { 3115 return Promise.resolve({ 3116 results: requests.map(() => ({ 3117 hits: [], 3118 nbHits: 0, 3119 nbPages: 0, 3120 page: 0, 3121 processingTimeMS: 0, 3122 hitsPerPage: 0, 3123 exhaustiveNbHits: false, 3124 query: '', 3125 params: '', 3126 })), 3127 }); 3128 } 3129 3130 return algoliaClient.search(requests); 3131 }, 3132 }; 3133 3134 let loggedInUserToken = hyva.getCookie('aa-search'); 3135 let userToken = null; 3136 if (loggedInUserToken && loggedInUserToken !== '') { 3137 userToken = loggedInUserToken; 3138 } else { 3139 let savedAnonCookie = hyva.getCookie('_ALGOLIA'); 3140 if (savedAnonCookie && savedAnonCookie !== "" && savedAnonCookie.indexOf("anonymous-") === 0) { 3141 userToken = savedAnonCookie; 3142 } else { 3143 let newAnonCookie = "anonymous-" + generateAnonCookieValue(); 3144 hyva.setCookie('_ALGOLIA', newAnonCookie) 3145 userToken = newAnonCookie; 3146 } 3147 } 3148 3149 function generateAnonCookieValue() { 3150 return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (e) { 3151 var t = 16 * Math.random() | 0; 3152 return ("x" === e ? t : 3 & t | 8).toString(16) 3153 }) 3154 } 3155 3156 new Vue({ 3157 el: "#vue-search", 3158 data() { 3159 return { 3160 // middlewares: [insightsMiddleware], 3161 currentQuery: '', 3162 client : algoliaClient, 3163 visible : false, 3164 slideOutAnimation : false, 3165 products: [], 3166 productCount : 0, 3167 productQueryId : '', 3168 recipes : [], 3169 recipeCount : 0, 3170 recipeQueryId : '', 3171 blog:[], 3172 blogCount:0, 3173 blogQueryId : '', 3174 topPosition : '', 3175 scrollPosition: window.scrollY, 3176 resultTabToggle : 'products' 3177 } 3178 }, 3179 created() { 3180 this.topPosition = $('.page-header').outerHeight() 3181 }, 3182 mounted() { 3183 let resultContainer = document.querySelector('.algolia-result-container') 3184 if (resultContainer) { 3185 if (resultContainer.classList.contains('hidden') ) { 3186 resultContainer.classList.remove('hidden') 3187 } 3188 } 3189 3190 if ($('body').hasClass('catalog-product-view')) { 3191 let productId = $('#product_addtocart_form').find('input[name="product"]').val(); 3192 if (productId) { 3193 window.dataLayer = window.dataLayer || []; 3194 dataLayer.push({ 3195 "algoliaUserToken": userToken, 3196 "index": 'magento2_prod_default_products', 3197 "event": 'PDP Hit Viewed', 3198 "objectIDs": [productId], 3199 }) 3200 } 3201 } 3202 3203 $(document).click((event) => { 3204 if (!$(event.target).closest('.algolia-result-container').length && !$(event.target).closest('#header').length) { 3205 if (this.visible) { 3206 this.slideOutAnimation = true 3207 setTimeout(() => { 3208 this.slideOutAnimation = false 3209 this.visible = false;
3210 this.removeQuery(); 3211 document.querySelector('.page-header .black-overlay').classList.add('hidden'); 3212 }, 350); 3213 } 3214 } 3215 }); 3216 3217 if(document.querySelector('body').classList.contains('recipes-algolia-listview') 3218 || document.querySelector('body').classList.contains('recipe-recipe-view') 3219 || window.location.pathname.includes('rezeptsammlung') 3220 ){ 3221 this.toggleResultNav('recipes') 3222 } 3223 3224 if(document.querySelector('body').classList.contains('blog-page')){ 3225 this.toggleResultNav('blog') 3226 } 3227 }, 3228 computed: { 3229 3230 query: { 3231 get() { 3232 return this.currentQuery 3233 }, 3234 set(value) { 3235 this.currentQuery = value 3236 if(value !== ""){ 3237 document.querySelector('.page-header .black-overlay').classList.remove('hidden'); 3238 this.visible = true 3239 }else{ 3240 this.slideOutAnimation = true 3241 setTimeout(() => { 3242 this.slideOutAnimation = false 3243 this.visible = false; 3244 document.querySelector('.page-header .black-overlay').classList.add('hidden'); 3245 }, 350); 3246 } 3247 this.fetchResults() 3248 } 3249 }, 3250 3251 }, 3252 methods : { 3253 isCreateYourOwn: function(item) { 3254 if((Array.isArray(item.sku) && item.sku.some(element => element.includes("CYOG"))) 3255 || (Array.isArray(item.sku) && item.sku.some(element => element.includes("CYOB")))){ 3256 return true; 3257 } 3258 return false; 3259 }, 3260 toggleResultNav : function (activeTab) { 3261 this.resultTabToggle = activeTab 3262 }, 3263 3264 redirectTo : function(indexName, hit, index) { 3265 let algoliaIndex = { 3266 product : 'magento2_prod_default_products', 3267 recipe : 'magento2_prod_default_recipes', 3268 blog : 'magento2_prod_default_blog' 3269 } 3270 3271 if (algoliaIndex[indexName] !== undefined) { 3272 window.dataLayer = window.dataLayer || []; 3273 dataLayer.push({ 3274 "algoliaUserToken": userToken, 3275 "event": 'Autocomplete Hit Clicked', 3276 "index": algoliaIndex[indexName], 3277 "eventType": 'click', 3278 "queryID": this[indexName + 'QueryId'], 3279 "objectIDs": [hit.objectID], 3280 "positions": [index + 1] 3281 }) 3282 3283 } 3284 3285 window.location.href = hit.url 3286 }, 3287 3288 removeQuery : function() { 3289 this.query = '' 3290 }, 3291 3292 fetchResults : function() { 3293 const queries = [{ 3294 indexName: 'magento2_prod_default_products', 3295 query: this.query, 3296 params: { 3297 hitsPerPage: 6 3298 }, 3299 filters: 'visibility_search=1', 3300 clickAnalytics: true 3301 }, { 3302 indexName: 'magento2_prod_default_recipes', 3303 query: this.query, 3304 params: { 3305 hitsPerPage: 6, 3306 }, 3307 clickAnalytics: true 3308 }, { 3309 indexName: 'magento2_prod_default_blog', 3310 query: this.query, 3311 params: { 3312 hitsPerPage: 6, 3313 }, 3314 clickAnalytics: true 3315 }] 3316 3317 this.client.multipleQueries(queries).then(({ results }) => { 3318 if (results.length > 0) { 3319 this.products = results[0]?.hits
3320 this.productCount = results[0]?.nbHits 3321 this.productQueryId = results[0]?.queryID 3322 3323 this.recipes = results[1]?.hits 3324 this.recipeCount = results[1]?.nbHits 3325 this.recipeQueryId = results[1]?.queryID 3326 3327 this.blog = results[2]?.hits 3328 this.blogCount = results[2]?.nbHits 3329 this.blogQueryId = results[2]?.queryID 3330 } 3331 }); 3332 }, 3333 3334 get_scroll_position : function() { 3335 window.addEventListener('scroll', () => { 3336 this.scrollPosition = window.scrollY; 3337 }); 3338 return this.scrollPosition 3339 }, 3340 3341 formattedPrice : (price) => { 3342 let countryCode = locale !== undefined ? locale : 'de_DE', 3343 currencyCode = { 3344 'de-DE' : 'EUR', 3345 'en-GB' : 'GBP', 3346 'es-ES' : 'EUR', 3347 'en-US' : 'USD' 3348 } 3349 3350 if (countryCode.includes('_')) { 3351 countryCode = countryCode.replace('_','-') 3352 } 3353 3354 return new Intl.NumberFormat(countryCode, { style: 'currency', currency: currencyCode[countryCode] }).format(price); 3355 }, 3356 } 3357 }); 3358 }) 3359</script>
3359 3360 3361 <a class="customer-account-icon" 3362 @click="() => { 3363 if (typeof customer.customerId !== 'undefined') { 3364 if (window.innerWidth <= 1199) { 3365 $dispatch('toggle-customer-nav', { isOpen: true }) 3366 } else { 3367 window.location.href = 'https://www.justspices.de/customer/account' 3368 } 3369 } else { 3370 window.location.href = 'https://www.justspices.de/customer/account/login' 3371 } 3372 }" 3373 @toggle-customer-nav.window="toggleCustomerNav($event)" 3374 > 3375 <i class="fal fa-user text-4"></i> 3376 <template x-if="typeof customer.customerId !== 'undefined'"> 3377 <span class="gfc-bubble" :class="getGfcIcon()"></span> 3378 </template> 3379 </a> 3380 3381 <button 3382 id="menu-cart-icon" 3383 class="relative inline-block rounded p-1 outline-offset-2" 3384 x-ref="cartButton" 3385 :aria-disabled="isCartEmpty()" 3386 :aria-label="` 3387 Toggle minicart, 3388 ${isCartEmpty() 3389 ? 'Cart is empty' 3390 : cart.summary_count > 1 3391 ? hyva.str('%1 Artikel', cart.summary_count) 3392 : hyva.str('%1 item', cart.summary_count) 3393 }`" 3394 @click.prevent.stop="() => { 3395 $dispatch('toggle-cart', { isOpen: true }) 3396 }" 3397 @toggle-cart.window="toggleCart($event)" 3398 :aria-expanded="isCartOpen" 3399 aria-haspopup="dialog" 3400 > 3401 <i class="fal fa-bag-shopping text-4"></i> 3402 <span 3403 x-text="cart.summary_count ? visibleCartItemsCount(cart.summary_count) : 0" 3404 x-cloak 3405 class="absolute cart-icon-badge m-0 rounded-full bg-main-black text-main-white w-2 h-2 fs-11 inline-flex justify-center items-center right-0" 3406 aria-hidden="true" 3407 ></span> 3408 </button> 3409 3410 3411 </div> 3412 </div> 3413 3414 <!--Search--> 3415 <div class="absolute z-30 w-full search-mobile" 3416 id="search-content" 3417 :class="slideOutAnimation ? 'slide-out-left-slow' : 'slide-in-left-slow'" 3418 x-cloak x-show="searchOpen" 3419 @click.outside="searchOpen = false" 3420 @keydown.escape=" 3421 searchOpen = false; 3422 $refs.searchButton.focus(); 3423 " 3424 style="display: none" 3425 > 3426 <div id="vue-search-mobile" class="vue-searchbar"> 3427 <div class="vue-search-popup d-block"> 3428 <div class="ais-InstantSearch search-results"> 3429 <div class="ais-SearchBox"> 3430 <div class="search-box position-relative"> 3431 <i class="fal fa-arrow-left font fs-20 lh-20 vue-search-close" x-on:click="slideOut(); closeMobileSearchBar();"></i> 3432 <input 3433 x-ref="mobileSearchInput" 3434 type="search" 3435 class="font fs-16" 3436 id="vue-search-input" 3437 v-model="query" 3438 v-on:keyup.enter="window.location.href = baseUrl + 'catalogsearch/result/?q=' + query" 3439 placeholder="Suche" 3440 tabindex="-1" 3441 /> 3442 <i 3443 class="fal fa-times font fs-20 lh-20 black vue-search-reset" 3444 v-if="query.length > 0" 3445 @click="deleteQuery();" 3446 > 3447 </i> 3448 </div> 3449 </div> 3450 <div class="algolia-result-nav"> 3451 <span @click="toggleResults('products')" v-bind:class="tabs.products ? 'active' : ''">Produkte</span>
3452 <span @click="toggleResults('recipes')" v-bind:class="tabs.recipes ? 'active' : ''">Rezepte</span> 3453 <span @click="toggleResults('blog')" v-bind:class="tabs.blog ? 'active' : ''">Artikel</span> 3454 </div> 3455 <div class="result-container" v-if="query.length > 0"> 3456 <div class="col-12 px-0 products" v-show="tabs.products"> 3457 <div class="ais-hits"> 3458 <div class="ais-Hits" v-if="products.length > 0"> 3459 <div class="hit-result" v-for="(product,index) in products" v-if="product" v-bind:key="product.objectID"> 3460 <a class="" @click="redirectTo('product',product,index)" 3461 data-event="ev" data-ga4event="search_custom" data-category="product" 3462 data-action="click" v-bind:data-label="product.name"> 3463 <div class="hit-item-image"> 3464 <img v-bind:src="product.thumbnail_url_webp ?? product.image_url" class="lozad" style="width: 90px" width="78" height="78" v-bind:alt="product.name" v-bind:title="product.name" /> 3465 </div> 3466 <div class="hit-item-info"> 3467 <strong class="text-s title">{{product.name}}</strong> 3468 <div class="prices" v-if="!isCreateYourOwn(product)"> 3469 <template v-if="product.type_id === 'bundle'"> 3470 <template v-if="product.price.EUR.default_max_formated"> 3471 <span class="fs-14 lh-20 bundle">{{product.price.EUR.default_max_formated}}</span> 3472 </template> 3473 <template v-else> 3474 <span class="fs-14 lh-20 bundle">{{product.price.EUR.default_formated}}</span> 3475 </template> 3476 </template> 3477 <template v-else> 3478 <span class="fs-14 lh-20">{{product.price.EUR.default_formated}}</span> 3479 <template v-if="product.price.EUR.default_original_formated"> 3480 <s class="fs-14 lh-20 text-main-red line-through old-price ml-1">{{product.price.EUR.default_original_formated}}</s> 3481 </template> 3482 </template> 3483 </div> 3484 </div> 3485 </a> 3486 </div> 3487 <div class="hits-header w-full"> 3488 <span class="fs-14 lh-20"> 3489 {{productCount}} Ergebnisse </span> 3490 <div class="flex justify-center items-center gap-1"> 3491 <a class="fs-14 lh-20" 3492 v-bind:href="baseUrl + 'catalogsearch/result/?q=' + query" data-event="ev" 3493 data-ga4event="search_custom" data-category="product_all" 3494 data-action="click"> 3495 Alle anzeigen </a> 3496 <i class="fa-regular fa-arrow-right font fs-21 lh-28"></i> 3497 </div> 3498 </div> 3499 </div> 3500 <div class="col-12 no-results" v-if="products.length === 0"> 3501 <p class="font text-s mb-2">Kein Ergebnis. Versuche es mit einem anderen Suchbegriff oder sieh Dir unsere Empfehlungen an.</p> 3502 <div class="inspiration"> 3503 <div data-content-type="html" data-appearance="default" data-element="main" data-decoded="true"><p class="font-recoleta text-m mb-2">Top Kategorien</p> 3504<div class="top-categories"> 3505 <a class="img-fluid category-icon" data-event="ev" data-ga4event="select_category" data-category="search" data-action="click" data-label="Bestseller" 3506 href="https://www.justspices.de/bestseller.html"> 3507 <img src="https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_products_bestseller.svg" alt="Produktk
3507ategorie Bestseller" /> 3508 <span>Bestseller</span> 3509 </a> 3510 <a class="img-fluid category-icon" data-event="ev" data-ga4event="select_category" data-category="search" data-action="click" data-label="Neuheiten" 3511 href="https://www.justspices.de/neuheiten.html"> 3512 <img src="https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_products_neuheiten.svg" alt="Produktkategorie Neuheiten" /> 3513 <span>Neuheiten</span> 3514 </a> 3515 <a class="img-fluid category-icon" data-event="ev" data-ga4event="select_category" data-category="search" data-action="click" data-label="Geschenkideen" 3516 href="https://www.justspices.de/geschenkideen.html"> 3517 <picture> 3518 3519 <source type="image/webp" 3520 srcset="https://www.justspices.de/media/opti_image/webp/wysiwyg/relaunch-2024/search/search_inspiration_products_gifts.webp"> 3521 3522 <source type="image/png" 3523 srcset="https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_products_gifts.png"> 3524 3525 <img src="https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_products_gifts.png" alt="Produktkategorie Geschenkideen" /> </picture> 3526 3527 3528 <span>Geschenke</span> 3529 </a> 3530</div> 3531<p class="font-recoleta text-m mb-2">Beliebte Produkte</p> 3532<div class="popular-products"> 3533 <a class="img-fluid product" data-event="ev" data-ga4event="select_product_recommendation" data-category="search" data-action="click" data-label="Avocado Topping" 3534 href="https://www.justspices.de/avocado-topping.html"> 3535 <picture> 3536 3537 <source type="image/webp" 3538 srcset="https://www.justspices.de/media/opti_image/webp/wysiwyg/relaunch-2024/search/search_inspiration_products_avocado_topping-2.webp"> 3539 3540 <source type="image/png" 3541 srcset="https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_products_avocado_topping-2.png"> 3542 3543 <img src="https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_products_avocado_topping-2.png" alt="Avocado Topping" /> </picture> 3544 3545 3546 <div class="product-info"> 3547 <p class="product-name">Avocado Topping</p> 3548 <p class="product-price">5,99 â¬</p> 3549 </div> 3550 </a> 3551 <a class="img-fluid product" data-event="ev" data-ga4event="select_product_recommendation" data-category="search" data-action="click" data-label="Ofengemüse Gewuerzmix" 3552 href="https://www.justspices.de/ofengemuese-gewuerzmix.html"> 3553 <picture> 3554 3555 <source type="image/webp" 3556 srcset="https://www.justspices.de/media/opti_image/webp/wysiwyg/relaunch-2024/search/search_inspiration_products_ofengemuese_gewuerzmix.webp"> 3557 3558 <source type="image/png" 3559 srcset="https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_products_ofengemuese_gewuerzmix.png"> 3560 3561 <img src="https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_products_ofengemuese_gewuerzmix.png" alt="Ofengemüse Gewürzmix" /> </picture> 3562 3563 3564 <div class="product-info"> 3565 <p class="product-name">Ofengemüse Gewürzmix</p> 3566 <p class="product-price">4,99 â¬</p> 3567 </div> 3568 </a> 3569 <a class="img-fluid product" data-event="ev" data-ga4event="select_product_recommendation" data-category="search" data-action="click" data-label="Haehnchen Allrounder" 3570 href="https://www.justspices.de/haehnchen-allrounder.html"> 3571 <picture> 3572 3573 <source type="image/webp" 3574 srcset="https://www.justspices.de/media/opti_image/webp/wysiwyg/relaunch-2024/search/search_inspiration_products_haehnchen_allrounder.webp"> 3575 3576 <source type="image/png" 3577 srcset="https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_products_haehnchen_allrounder.png"> 3578 3579 <img src="https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_products_haehnchen_allrounder.png" alt="Hähnchen Allrounder" /> </picture> 3580 3581 3582 <div class="product-info"> 3583 <p class="product-name">Hähnchen Allrounder</p> 3584 <p class="product-price">4,99 â¬</p> 3585 </div> 3586 </a> 3587 <a class="img-fluid product" data-event="ev" data-ga4event="select_product_recommendation" data-category="search" data-action="click" data-label="Aglio e Olio Gewuerzmix" 3588 href="https://www.justspices.de/aglio-e-olio-gewuerz.html"> 3589 <picture> 3590 3591 <source type="image/webp" 3592 srcset="https://www.justspices.de/media/opti_image/webp/wysiwyg/relaunch-2024/search/search_inspiration_products_aglio_e_olio_gewuerzmix.webp"> 3593 3594 <source type="image/png" 3595 srcset="https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_products_aglio_e_olio_gewuerzmix.png"> 3596 3597 <img src="https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_products_aglio_e_olio_gewuerzmix.png" alt="Aglio e Olio Gewürzmix" /> </picture> 3598 3599 3600 <div class="product-info"> 3601 <p class="product-name">Aglio e Olio Gewürzmix</p> 3602 <p class="product-price">5,49 â¬</p> 3603 </div> 3604 </a> 3605</div></div> </div> 3606 </div> 3607 </div> 3608 </div> 3609 <div class="col-12 px-0 recipes" v-show="tabs.recipes"> 3610 <div class="ais-Hits recipe-hits"> 3611 <div class="ais-Hits" v-if="recipes.length > 0"> 3612 <div v-for="(recipe,index) in recipes" v-if="recipe && index < 5 " v-bind:key="recipe.objectID" class="hit-result recipe"> 3613 <a class="" @click="redirectTo('recipe',recipe,index)" 3614 data-event="ev" data-ga4event="search_custom" data-category="recipe" 3615 data-action="click" v-bind:data-label="recipe.title"> 3616 <div class="hit-item-image"> 3617 <img v-bind:src="recipe.image_url" class="lozad" width="78" height="78" v-bind:alt="recipe.image_alt" v-bind:title="recipe.title" /> 3618 </div> 3619 <div class="hit-item-info"> 3620 <strong class="text-s title">{{recipe.title}}</strong> 3621 </div> 3622 </a> 3623 </div> 3624 <div class="hits-header w-full">
3625 <span class="fs-14 lh-20"> 3626 {{recipeCount}} Ergebnisse </span> 3627 <div class="flex justify-center items-center gap-1"> 3628 <a class="fs-14 lh-20" 3629 v-bind:href="baseUrl + 'catalogsearch/result/?tab=recipes&q=' + query" data-event="ev" 3630 data-ga4event="search_custom" data-category="recipes_all" 3631 data-action="click"> 3632 Alle anzeigen </a> 3633 <i class="fa-regular fa-arrow-right font fs-21 lh-28"></i> 3634 </div> 3635 </div> 3636 </div> 3637 <div class="col-12 no-results" v-if="recipes.length === 0"> 3638 <p class="font text-s mb-2">Kein Ergebnis. Versuche es mit einem anderen Suchbegriff oder sieh Dir unsere Empfehlungen an.</p> 3639 <div class="inspiration"> 3640 <div data-content-type="html" data-appearance="default" data-element="main" data-decoded="true"><p class="font-recoleta text-m mb-2">Top Rezeptsammlungen</p> 3641<div class="top-categories"> 3642 <a class="img-fluid category-icon" data-event="ev" data-ga4event="select_recipe_category" data-category="search" data-action="click" data-label="Beliebte Rezepte" 3643 href="https://www.justspices.de/rezeptsammlungen/beliebte-rezepte"> 3644 <img class="lozad" data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_products_bestseller.svg" alt="Beliebte Rezepte" /> 3645 <span>Beliebt</span> 3646 </a> 3647 <a class="img-fluid category-icon" data-event="ev" data-ga4event="select_recipe_category" data-category="search" data-action="click" data-label="Heissluftfritteuse Rezepte" 3648 href="https://www.justspices.de/rezeptsammlungen/heissluftfritteuse-rezepte"> 3649 <img class="lozad" data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_recipes_salat.svg" alt="Heissluftfritteuse Rezepte" /> 3650 <span>Fritteuse</span> 3651 </a> 3652 <a class="img-fluid category-icon" data-event="ev" data-ga4event="select_recipe_category" data-category="search" data-action="click" data-label="Grill Rezepte" 3653 href="https://www.justspices.de/rezeptsammlungen/grill-rezepte"> 3654 <img class="lozad" data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_products_bbq.svg" alt="Grill Rezepte" /> 3655 <span>Grill Rezepte</span> 3656 </a> 3657</div> 3658<p class="font-recoleta text-m mb-2">Beliebte Rezepte</p> 3659<div class="popular-recipes"> 3660 <a class="img-fluid recipe" data-event="ev" data-ga4event="select_recipe_recommendation" data-category="search" data-action="click" data-label="SüÃkartoffel Bowl aus der HeiÃluftfritteuse" 3661 href="https://www.justspices.de/rezepte/suesskartoffel-bowl-heissluftfritteuse.html"> 3662 <picture> 3663 3664 <source type="image/webp" data-srcset=" 3665 https://www.justspices.de/media/opti_image/webp/wysiwyg/relaunch-2024/search/search_inspiration_recipes_sweetpotatoebowl-2.webp"> 3666 3667 <source type="image/png" 3668 data-srcset=" 3669 https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_recipes_sweetpotatoebowl-2.png"> 3670 3671 <img class="lozad" data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_recipes_sweetpotatoebowl-2.png" alt="SüÃkartoffel Bowl aus der HeiÃluftfritteuse" /> </picture> 3672 3673 3674 <p class="recipe-name">SüÃkartoffel Bowl aus der HeiÃluftfritteuse</p> 3675 </a> 3676 <a class="img-fluid recipe" data-event="ev" data-ga4event="select_recipe_recommendation" data-category="search" data-action="click" data-label="Mexikanische Wraps" 3677 href="https://www.justspices.de/rezepte/mexikanische-wraps.html"> 3678 <picture> 3679 3680 <source type="image/webp" data-srcset=" 3681 https://www.justspices.de/media/opti_image/webp/wysiwyg/relaunch-2024/search/search_inspiration_recipes_mexikanische_wraps.webp"> 3682 3683 <source type="image/png" 3684 data-srcset=" 3685 https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_recipes_mexikanische_wraps.png"> 3686 3687 <img class="lozad" data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_recipes_mexikanische_wraps.png" alt="Mexikanische Wraps" /> </picture> 3688 3689 3690 <p class="recipe-name">Mexikanische Wraps</p> 3691 </a> 3692 <a class="img-fluid recipe" data-event="ev" data-ga4event="select_recipe_recommendation" data-category="search" data-action="click" data-label="Saftiger Joghurt Kuchen" 3693 href="https://www.justspices.de/rezepte/saftiger-joghurtkuchen.html"> 3694 <picture> 3695 3696 <source type="image/webp" data-srcset=" 3697 https://www.justspices.de/media/opti_image/webp/wysiwyg/relaunch-2024/search/search_inspiration_recipes_s
3697aftiger_joghurtkuchen.webp"> 3698 3699 <source type="image/png" 3700 data-srcset=" 3701 https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_recipes_saftiger_joghurtkuchen.png"> 3702 3703 <img class="lozad" data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_recipes_saftiger_joghurtkuchen.png" alt="Saftiger Joghurt Kuchen" /> </picture> 3704 3705 3706 <p class="recipe-name">Saftiger Joghurt Kuchen</p> 3707 </a> 3708 <a class="img-fluid recipe" data-event="ev" data-ga4event="select_recipe_recommendation" data-category="search" data-action="click" data-label="One Pot Pasta" 3709 href="https://www.justspices.de/rezepte/tomate-mozzarella-one-pot-pasta.html"> 3710 <picture> 3711 3712 <source type="image/webp" data-srcset=" 3713 https://www.justspices.de/media/opti_image/webp/wysiwyg/relaunch-2024/search/search_inspiration_recipes_one_pot_pasta.webp"> 3714 3715 <source type="image/png" 3716 data-srcset=" 3717 https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_recipes_one_pot_pasta.png"> 3718 3719 <img class="lozad" data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_recipes_one_pot_pasta.png" alt="One Pot Pasta" /> </picture> 3720 3721 3722 <p class="recipe-name">One Pot Pasta</p> 3723 </a> 3724</div></div> </div> 3725 </div> 3726 </div> 3727 </div> 3728 <div class="col-12 px-0 blog" v-show="tabs.blog"> 3729 <div class="ais-Hits blog-hits"> 3730 <div class="ais-Hits" v-if="blog.length > 0"> 3731 <div v-for="(post,index) in blog" v-if="post && index < 5 " v-bind:key="post.objectID" class="hit-result blog"> 3732 <a v-bind:href="post.url" class="" 3733 data-event="ev" data-ga4event="search_custom" data-category="blog" 3734 data-action="click" v-bind:data-label="post.title"> 3735 <div class="hit-item-image"> 3736 <img v-bind:src="post.image_url_crop_webp ?? post.image_url_crop" width="78" height="78" 3737 v-bind:alt="post.title" v-bind:title="post.title" 3738 class="lozad"> 3739 3740 </div> 3741 <div class="hit-item-info"> 3742 <strong class="text-s title">{{post.title}}</strong> 3743 </div> 3744 </a> 3745 </div> 3746 <div class="hits-header w-full"> 3747 <span class="fs-14 lh-20"> 3748 {{blogCount}} Ergebnisse </span> 3749 <div class="flex justify-center items-center gap-1"> 3750 <a class="fs-14 lh-20" 3751 v-bind:href="baseUrl + 'catalogsearch/result/?tab=blog&q=' + query" data-event="ev" 3752 data-ga4event="search_custom" data-category="blog_all" 3753 data-action="click"> 3754 Alle anzeigen </a> 3755 <i class="fa-regular fa-arrow-right font fs-21 lh-28"></i> 3756 </div> 3757 </div> 3758 </div> 3759 <div class="col-12 no-results" v-if="blog.length === 0"> 3760 <p class="font text-s mb-2">Kein Ergebnis. Versuche es mit einem anderen Suchbegriff oder sieh Dir unsere Empfehlungen an.</p> 3761 <div class="inspiration"> 3762 <div data-content-type="html" data-appearance="default" data-element="main" data-decoded="true"><p class="font-recoleta text-m mb-2">Top Blog Kategorien</p> 3763<div class="top-categories"> 3764 <a class="img-fluid category-icon" data-event="ev" data-ga4event="select_blog_category" data-category="search" data-action="click" data-label="1x1 des Kochens" 3765 href="https://www.justspices.de/blog/1x1-des-kochens"> 3766 <img class="lozad" data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_blog_einmaleins_kochen.svg" alt="1x1 des Kochens" />
3767 <span>1x1 des Kochens</span> 3768 </a> 3769 <a class="img-fluid category-icon" data-event="ev" data-ga4event="select_blog_category" data-category="search" data-action="click" data-label="1x1 der Gewürze" 3770 href="https://www.justspices.de/blog/1x1-der-gewuerze"> 3771 <img class="lozad" data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_blog_einmaleins_gewuerze.svg" alt="1x1 der Gewürze" /> 3772 <span>1x1 der Gewürze</span> 3773 </a> 3774 <a class="img-fluid category-icon" data-event="ev" data-ga4event="select_blog_category" data-category="search" data-action="click" data-label="HeiÃe Themen" 3775 href="https://www.justspices.de/blog/heisse-themen"> 3776 <img class="lozad" data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_products_fritteuse.svg" alt="HeiÃe Themen" /> 3777 <span>HeiÃe Themen</span> 3778 </a> 3779</div> 3780<p class="font-recoleta text-m mb-2">Beliebte Blogartikel</p> 3781<div class="popular-blogposts"> 3782 <a class="img-fluid blogpost" data-event="ev" data-ga4event="select_blog_recommendation" data-category="search" data-action="click" data-label="Bulgur richtig kochen" 3783 href="https://www.justspices.de/blog/1x1-des-kochens/richtig-kochen/bulgur-kochen"> 3784 <picture> 3785 3786 <source type="image/webp" data-srcset=" 3787 https://www.justspices.de/media/opti_image/webp/wysiwyg/relaunch-2024/search/search_inspiration_blog_bulgur_kochen.webp"> 3788 3789 <source type="image/png" 3790 data-srcset=" 3791 https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_blog_bulgur_kochen.png"> 3792 3793 <img class="lozad" data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_blog_bulgur_kochen.png" alt="Bulgur richtig kochen" /> </picture> 3794 3795 3796 <p class="recipe-name">Bulgur richtig kochen</p> 3797 </a> 3798 <a class="img-fluid blogpost" data-event="ev" data-ga4event="select_blog_recommendation" data-category="search" data-action="click" data-label="Brokkoli richtig kochen" 3799 href="https://www.justspices.de/blog/1x1-des-kochens/richtig-kochen/brokkoli-kochen"> 3800 <picture> 3801 3802 <source type="image/webp" data-srcset=" 3803 https://www.justspices.de/media/opti_image/webp/wysiwyg/relaunch-2024/search/search_inspiration_blog_brokkoli_kochen.webp"> 3804 3805 <source type="image/png" 3806 data-srcset=" 3807 https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_blog_brokkoli_kochen.png"> 3808 3809 <img class="lozad" data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_blog_brokkoli_kochen.png" alt="Brokkoli richtig kochen" /> </picture> 3810 3811 3812 <p class="recipe-name">Brokkoli richtig kochen</p> 3813 </a> 3814 <a class="img-fluid blogpost" data-event="ev" data-ga4event="select_blog_recommendation" data-category="search" data-action="click" data-label="Was passt zu Kartoffelsalat?" 3815 href="https://www.justspices.de/blog/1x1-des-kochens/was-passt-zu/was-passt-zu-kartoffelsalat"> 3816 <picture> 3817 3818 <source type="image/webp" data-srcset=" 3819 https://www.justspices.de/media/opti_image/webp/wysiwyg/relaunch-2024/search/search_inspiration_blog_kartoffelsalat.webp"> 3820 3821 <source type="image/png" 3822 data-srcset=" 3823 https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_blog_kartoffelsalat.png"> 3824 3825 <img class="lozad" data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_blog_kartoffelsalat.png" alt="Was passt zu Kartoffelsalat?" /> </picture> 3826 3827 3828 <p class="recipe-name">Was passt zu Kartoffelsalat?</p> 3829 </a> 3830 <a class="img-fluid blogpost" data-event="ev" data-ga4event="select_blog_recommendation" data-category="search" data-action="click" data-label="Garnelen richtig würzen" 3831 href="https://www.justspices.de/blog/1x1-des-kochens/garnelen-wuerzen"> 3832 <picture> 3833 3834 <source type="image/webp" data-srcset=" 3835 https://www.justspices.de/media/opti_image/webp/wysiwyg/relaunch-2024/search/search_inspiration_blog_garnelen.webp"> 3836 3837 <source type="image/png" 3838 data-srcset=" 3839 https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_blog_garnelen.png"> 3840 3841 <img class="lozad" data-src="https://www.justspices.de/media/wysiwyg/relaunch-2024/search/search_inspiration_blog_garnelen.png" alt="Garnelen richtig würzen" /> </picture> 3842 3843 3844 <p class="recipe-name">Garnelen richtig würzen</p> 3845 </a> 3846</div></div> </div> 3847 </div> 3848 </div> 3849 </div> 3850 </div> 3851 </div> 3852 </div> 3853</div> 3854 3855
3856<script type="module"> 3857 window.addEventListener('DOMContentLoaded',function () { 3858 3859 const algoliaClient = algoliasearch( 3860 'PCZYM1QRDW', 3861 '7d6e133d365a91ddf242dd6fbd396721', 3862 ); 3863 3864 const searchClient = { 3865 ...algoliaClient, 3866 search(requests) { 3867 if (requests.every(({ params }) => params.query === "")) { 3868 return Promise.resolve({ 3869 results: requests.map(() => ({ 3870 hits: [], 3871 nbHits: 0, 3872 nbPages: 0, 3873 page: 0, 3874 processingTimeMS: 0, 3875 hitsPerPage: 0, 3876 exhaustiveNbHits: false, 3877 query: '', 3878 params: '', 3879 })), 3880 }); 3881 } 3882 3883 return algoliaClient.search(requests); 3884 }, 3885 }; 3886 3887 let loggedInUserToken = hyva.getCookie('aa-search'); 3888 let userToken = null; 3889 if (loggedInUserToken && loggedInUserToken !== '') { 3890 userToken = loggedInUserToken; 3891 } else { 3892 let savedAnonCookie = hyva.getCookie('_ALGOLIA'); 3893 if (savedAnonCookie && savedAnonCookie !== "" && savedAnonCookie.indexOf("anonymous-") === 0) { 3894 userToken = savedAnonCookie; 3895 } else { 3896 let newAnonCookie = "anonymous-" + generateAnonCookieValue(); 3897 hyva.setCookie('_ALGOLIA', newAnonCookie) 3898 userToken = newAnonCookie; 3899 } 3900 } 3901 3902 function generateAnonCookieValue() { 3903 return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (e) { 3904 var t = 16 * Math.random() | 0; 3905 return ("x" === e ? t : 3 & t | 8).toString(16) 3906 }) 3907 } 3908 3909 new Vue({ 3910 el: "#vue-search-mobile", 3911 data() { 3912 return { 3913 searchClient, 3914 currentQuery:'', 3915 tabs : { 3916 products : true, 3917 recipes : false, 3918 blog: false, 3919 }, 3920 client : algoliaClient, 3921 products: [], 3922 productCount : 0, 3923 recipes : [], 3924 recipeCount : 0, 3925 blog:[], 3926 blogCount:0, 3927 } 3928 }, 3929 created() { 3930 3931 }, 3932 mounted() { 3933 if(document.querySelector('body').classList.contains('recipes-algolia-listview') 3934 || document.querySelector('body').classList.contains('recipe-recipe-view') 3935 || window.location.pathname.includes('rezeptsammlung') 3936 ){ 3937 this.toggleResults('recipes') 3938 } 3939 3940 if(document.querySelector('body').classList.contains('blog-page')){ 3941 this.toggleResults('blog') 3942 } 3943 }, 3944 computed: { 3945 3946 query: { 3947 get() { 3948 return this.currentQuery 3949 }, 3950 set(value) { 3951 this.currentQuery = value 3952 this.fetchResults() 3953 } 3954 }, 3955 3956 }, 3957 methods : { 3958 isCreateYourOwn: function(item) { 3959 if((Array.isArray(item.sku) && item.sku.some(element => element.includes("CYOG"))) 3960 || (Array.isArray(item.sku) && item.sku.some(element => element.includes("CYOB")))){ 3961 return true; 3962 } 3963 return false; 3964 }, 3965 toggleResults : function (activeTab) { 3966 this.tabs.products = false 3967 this.tabs.recipes = false 3968 this.tabs.blog = false 3969 this.tabs[activeTab] = true 3970 }, 3971 3972 fetchResults : function() { 3973 const queries = [{ 3974 indexName: 'magento2_prod_default_products', 3975 query: this.query, 3976 params: { 3977 hitsPerPage: 5 3978 }, 3979 filters: 'visibility_search=1', 3980 }, { 3981 indexName: 'magento2_prod_default_recipes', 3982 query: this.query, 3983 params: { 3984 hitsPerPage: 5, 3985 } 3986 },{ 3987 indexName: 'magento2_prod_default_blog', 3988 query: this.query, 3989 params: { 3990 hitsPerPage: 5, 3991 } 3992 }] 3993 3994 this.client.multipleQueries(queries).then(({ results }) => { 3995 if (results.length > 0) { 3996 this.products = results[0]?.hits
3997 this.productCount = results[0]?.nbHits 3998 3999 this.recipes = results[1]?.hits 4000 this.recipeCount = results[1]?.nbHits 4001 4002 this.blog = results[2]?.hits 4003 this.blogCount = results[2]?.nbHits 4004 } 4005 }); 4006 }, 4007 4008 redirectTo : function(indexName, hit, index) { 4009 let algoliaIndex = { 4010 product : 'magento2_prod_default_products', 4011 recipe : 'magento2_prod_default_recipes', 4012 blog : 'magento2_prod_default_blog' 4013 } 4014 4015 if (algoliaIndex[indexName] !== undefined) { 4016 window.dataLayer = window.dataLayer || []; 4017 dataLayer.push({ 4018 "algoliaUserToken": userToken, 4019 "event": 'Autocomplete Hit Clicked', 4020 "index": algoliaIndex[indexName], 4021 "eventType": 'click', 4022 "queryID": this[indexName + 'QueryId'], 4023 "objectIDs": [hit.objectID], 4024 "positions": [index + 1] 4025 }) 4026 4027 } 4028 4029 window.location.href = hit.url 4030 }, 4031 4032 closePopup : function () { 4033 4034 }, 4035 4036 deleteQuery() { 4037 this.currentQuery = '' 4038 } 4039 4040 } 4041 }); 4042 }) 4043 4044</script>
4044 4045 </div> 4046 4047 <!--Cart Drawer--> 4048
4048<script> 4049 function initCartDrawer() { 4050 4051 window.addEventListener('load',() => { 4052 const params = new URLSearchParams(window.location.search); 4053 4054 if (params.has('show-cart')) { 4055 window.dispatchEvent(new CustomEvent('toggle-cart', {detail: {isOpen: true}})); 4056 window.dispatchEvent(new CustomEvent('cart-drawer-toggled', {detail: {isOpen: true}})); 4057 } 4058 4059 let cartDrawer = document.querySelector('#cart-drawer') 4060 cartDrawer.classList.remove('hidden') 4061 }) 4062 4063 return { 4064 open: false, 4065 isLoading: false, 4066 cart: {}, 4067 maxItemsToDisplay: 10, 4068 itemsCount: 0, 4069 getData(data) { 4070 if (data.cart) { 4071 this.cart = data.cart; 4072 this.itemsCount = data.cart.items && data.cart.items.length || 0; 4073 this.setCartItems(); 4074 } 4075 this.isLoading = false; 4076 }, 4077 cartItems: [], 4078 getItemCountTitle() { 4079 return hyva.strf('\u00250\u0020of\u0020\u00251\u0020products\u0020in\u0020cart\u0020displayed', this.maxItemsToDisplay, this.itemsCount) 4080 }, 4081 setCartItems() { 4082 this.cartItems = this.cart.items && this.cart.items.sort((a, b) => b.item_id - a.item_id) || []; 4083 4084 if (this.maxItemsToDisplay > 0) { 4085 this.cartItems = this.cartItems.slice(0, parseInt(this.maxItemsToDisplay, 10)); 4086 } 4087 }, 4088 deleteItemFromCart(itemId) { 4089 this.isLoading = true; 4090 4091 const formKey = hyva.getFormKey(); 4092 const postUrl = BASE_URL + 'checkout/sidebar/removeItem/'; 4093 4094 fetch(postUrl, { 4095 "headers": { 4096 "content-type": "application/x-www-form-urlencoded; charset=UTF-8", 4097 }, 4098 "body": "form_key=" + formKey + "&item_id=" + itemId, 4099 "method": "POST", 4100 "mode": "cors", 4101 "credentials": "include" 4102 }).then(response => { 4103 if (response.redirected) { 4104 window.location.href = response.url; 4105 } else if (response.ok) { 4106 return response.json(); 4107 } else { 4108 window.dispatchMessages && window.dispatchMessages([{ 4109 type: 'warning', 4110 text: 'Could\u0020not\u0020remove\u0020item\u0020from\u0020quote.' 4111 }]); 4112 this.isLoading = false; 4113 } 4114 }).then(result => { 4115 window.dispatchMessages && window.dispatchMessages([{ 4116 type: result.success ? 'success' : 'error', 4117 text: result.success 4118 ? 'Sie\u0020haben\u0020den\u0020Artikel\u0020entfernt.' 4119 : result.error_message 4120 }], result.success ? 5000 : 0) 4121 window.dispatchEvent(new CustomEvent('reload-customer-section-data')); 4122 }); 4123 }, 4124 scrollLock(use = true) { 4125 document.body.style.overflow = use ? "hidden" : ""; 4126 }, 4127 toggleCartDrawer(event) { 4128 if (event.detail && event.detail.isOpen !== undefined) { 4129 if (event.detail.isOpen) { 4130 this.openCartDrawer(); 4131 } else { 4132 this.open = false; 4133 this.scrollLock(false); 4134 this.$refs && this.$refs.cartDialogContent && hyva.releaseFocus(this.$refs.cartDialogContent); 4135 } 4136 } else { 4137 this.openCartDrawer() 4138 } 4139 window.dispatchEvent(new CustomEvent('cart-drawer-toggled', { detail: {isOpen: this.open}})); 4140 }, 4141 openCartDrawer() { 4142 this.open = true; 4143 this.scrollLock(true); 4144 this.$nextTick(() => { 4145 this.$refs && this.$refs.cartDialogContent && hyva.trapFocus(this.$refs.cartDialogContent) 4146 }) 4147 }, 4148 closeCartDrawer() { 4149 this.$dispatch('toggle-cart', { isOpen: false }) 4150 }, 4151 getSectionDataExtraActions() { 4152 if (!this.cart.extra_actions) { 4153 return ''; 4154 } 4155 4156 const contentNode = document.createElement('div'); 4157 contentNode.innerHTML = this.cart.extra_actions; 4158 4159 hyva.activateScripts(contentNode); 4160 4161 return contentNode.innerHTML; 4162 } 4163 } 4164 } 4165</script>
4165 4166<section x-cloak 4167 x-show="cart" 4168 id="cart-drawer" 4169 x-data="initCartDrawer()" 4170 @private-content-loaded.window="getData($event.detail.data)" 4171 @toggle-cart.window="toggleCartDrawer($event)" 4172 @keydown.escape="closeCartDrawer" 4173 class="hidden" 4174> 4175 <div role="dialog" 4176 aria-labelledby="cart-drawer-title" 4177 aria-modal="true" 4178 :aria-hidden="!open" 4179 class="fixed inset-y-0 right-0 z-30 flex max-w-full"> 4180 <div class="backdrop" 4181 x-show="open" 4182 x-transition:enter="ease-in-out duration-500" 4183 x-transition:enter-start="opacity-0" 4184 x-transition:enter-end="opacity-100" 4185 x-transition:leave="ease-in-out duration-500" 4186 x-transition:leave-start="opacity-100" 4187 x-transition:leave-end="opacity-0" 4188 role="button" 4189 @click="closeCartDrawer" 4190 aria-label="Close minicart"></div> 4191 <div class="relative w-screen vue-minicart-drawer-content shadow-2xl" 4192 x-show="open" 4193 x-transition:enter="transform transition ease-in-out duration-500 tablet:duration-700" 4194 x-transition:enter-start="translate-x-full" 4195 x-transition:enter-end="translate-x-0" 4196 x-transition:leave="transform transition ease-in-out duration-500 tablet:duration-700" 4197 x-transition:leave-start="translate-x-0" 4198 x-transition:leave-end="translate-x-full" 4199 x-ref="cartDialogContent" 4200 role="region" 4201 :tabindex="open ? 0 : -1" 4202 aria-label="Mein Warenkorb" 4203 > 4204 <div class="flex flex-col h-full max-h-screen bg-white shadow-xl"> 4205 4206<div id="slide-in-cart"> 4207 <cart-modal 4208 v-bind:besteller="bestsellerUrl" 4209 ></cart-modal> 4210</div> 4211 4212 4213
4214<script id="cart_store"> 4215 const cart = { 4216 namespaced: true, 4217 state: () => ({ 4218 cartId : mage_cache_storage.cart?.cartId ?? null, 4219 shippingThreshold : '39', 4220 shippingMethod : [], 4221 totals : {}, 4222 shippingInformation : {}, 4223 _keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", 4224 baseUrl: "https://www.justspices.de/", 4225 atcErrorUrl : "", 4226 cartIsEmpty : false, 4227 loyaltyShippingThreshold : { 4228 silver : '30', 4229 gold : '25' 4230 }, 4231 storedCart : {}, 4232 incentiveInformation: [], 4233 forceIncentivePopupOpen: false, 4234 selectedFreeGiftInCart: false 4235 }), 4236 mutations: { 4237 4238 updateStoredCart(state, cart) { 4239 state.storedCart = cart 4240 }, 4241 4242 updateShippingMethod(state, method) { 4243 state.shippingMethod = method 4244 }, 4245 4246 updateTotals(state, totals) { 4247 state.totals = totals 4248 }, 4249 4250 updateShippingInformation(state, information) { 4251 state.shippingInformation = information 4252 }, 4253 4254 updateAtcErrorUrl(state,url) { 4255 state.atcErrorUrl = url 4256 }, 4257 4258 updateCartId(state,id) { 4259 state.cartId = id 4260 }, 4261 4262 updateCartIsEmpty(state, bool) { 4263 state.cartIsEmpty = bool 4264 }, 4265 4266 updateShippingThreshold(state,threshold) { 4267 state.shippingThreshold = threshold 4268 }, 4269 4270 updateIncentiveInformation(state,incentiveInformation) { 4271 state.incentiveInformation = incentiveInformation 4272 }, 4273 4274 updateForceIncentivePopupOpen(state,forceIncentivePopupOpen) { 4275 state.forceIncentivePopupOpen = forceIncentivePopupOpen 4276 }, 4277 4278 updateSelectedFreeGiftInCart(state,selectedFreeGiftInCart) { 4279 state.selectedFreeGiftInCart = selectedFreeGiftInCart 4280 } 4281 4282 }, 4283 actions : { 4284 4285 4286 calculateShippingThreshold({state, commit, dispatch, rootState}) { 4287 if (rootState.customer.customerId != null) { 4288 if (rootState.customer.customerLoyaltyRank === 'Gold') { 4289 commit('updateShippingThreshold',state.loyaltyShippingThreshold.gold) 4290 return true 4291 } else if (rootState.customer.customerLoyaltyRank === 'Silber' || 4292 rootState.customer.customerLoyaltyRank === 'Silver' ) { 4293 commit('updateShippingThreshold',state.loyaltyShippingThreshold.silver) 4294 return true 4295 } 4296 } 4297 }, 4298 4299 /** 4300 * @param dispatch 4301 * @param request // {cartId,token} 4302 */ 4303 async getTotals({dispatch},request) { 4304 if (request.token) { 4305 // logged in 4306 await dispatch('apiRequest', { 4307 commit : 'cart/updateTotals', 4308 endpoint : `carts/mine/totals`, 4309 type : 'GET', 4310 header : {headers: { Authorization: `Bearer ${request.token}`}}, 4311 },{ root: true }) 4312 } else { 4313 await dispatch('apiRequest', { 4314 commit : `cart/updateTotals`, 4315 endpoint : `guest-carts/${request.cartId}/totals`, 4316 type : 'GET', 4317 },{ root: true }) 4318 } 4319 }, 4320 4321 4322 /** 4323 * @param dispatch 4324 * @param request // {cartId,token,data} 4325 */ 4326 async getEstimatedShippingMethod({dispatch},request) { 4327 if (request.token) { 4328 // logged in 4329 await dispatch('apiRequest', { 4330 commit : 'cart/updateShippingMethod',
4331 endpoint : `carts/mine/estimate-shipping-methods`, 4332 type : 'POST', 4333 header : {headers: { Authorization: `Bearer ${request.token}`}}, 4334 data : JSON.stringify(request.data) 4335 },{ root: true }) 4336 } else { 4337 await dispatch('apiRequest', { 4338 commit : `cart/updateShippingMethod`, 4339 endpoint : `guest-carts/${request.cartId}/estimate-shipping-methods`, 4340 type : 'POST', 4341 data : JSON.stringify(request.data) 4342 },{ root: true }) 4343 } 4344 }, 4345 4346 4347 /** 4348 * @param dispatch 4349 * @param request // {cartId,token,data} 4350 */ 4351 async setShippingInformation({dispatch},request) { 4352 if (request.token) { 4353 // logged in 4354 await dispatch('apiRequest', { 4355 commit : 'cart/updateShippingInformation', 4356 endpoint : `carts/mine/shipping-information`, 4357 type : 'POST', 4358 header : {headers: { Authorization: `Bearer ${request.token}`}}, 4359 data : JSON.stringify(request.data) 4360 },{ root: true }) 4361 } else { 4362 await dispatch('apiRequest', { 4363 commit : `cart/updateShippingInformation`, 4364 endpoint : `guest-carts/${request.cartId}/shipping-information`, 4365 type : 'POST', 4366 data : JSON.stringify(request.data) 4367 },{ root: true }) 4368 } 4369 }, 4370 4371 4372 /** 4373 * @param dispatch 4374 * @param request // {cartId,token,data} 4375 */ 4376 async addToCart({dispatch},request) { 4377 await dispatch('controllerRequest', { 4378 action : request.action, 4379 form : request.form, 4380 addToCart : true, 4381 },{ root: true }) 4382 }, 4383 4384 4385 /** 4386 * @param dispatch 4387 * @param request // {cartId,token,data} 4388 */ 4389 async removeItemFromCart({dispatch},request) { 4390 if (request.token) { 4391 // logged in 4392 await dispatch('apiRequest', { 4393 endpoint: `carts/mine/items/${request.itemId}`, 4394 type: 'DELETE', 4395 header: {headers: {Authorization: `Bearer ${request.token}`}}, 4396 reloadLocalStorage : true 4397 }, {root: true}) 4398 } else { 4399 await dispatch('apiRequest', { 4400 endpoint: `guest-carts/${request.cartId}/items/${request.itemId}`, 4401 type: 'DELETE', 4402 reloadLocalStorage : true 4403 }, {root: true}) 4404 } 4405 }, 4406 4407 4408 4409 /** 4410 * @param dispatch 4411 * @param request // {cartId,token,data} 4412 */ 4413 async updateCartItem({dispatch},request) { 4414 if (request.token) { 4415 // logged in 4416 await dispatch('apiRequest', { 4417 endpoint : `carts/mine/items/${request.itemId}`, 4418 errorMessage : true, 4419 type : 'PUT', 4420 header : {headers: { Authorization: `Bearer ${request.token}`}}, 4421 data : JSON.stringify(request.data), 4422 reloadLocalStorage : true 4423 },{ root: true }) 4424 } else { 4425 await dispatch('apiRequest', { 4426 endpoint : `guest-carts/${request.cartId}/items/${request.itemId}`, 4427 errorMessage : true, 4428 type : 'PUT', 4429 data : JSON.stringify(request.data), 4430 reloadLocalStorage : true 4431 },{ root: true }) 4432 } 4433 }, 4434 4435 }, 4436 getters : { 4437 4438 createAddToCartUrl : (state,getters) => (productId) => { 4439 const currentLocationUENC = encodeURIComponent( 4440 getters.encodeUenc(state.baseUrl), 4441 ) 4442 return state.baseUrl + 4443 "checkout/cart/add/uenc/" + 4444 currentLocationUENC + 4445 "/product/" + 4446 productId 4447 }, 4448 4449 encodeUenc: () => (value) => { 4450 const regex = /=/gi 4451 return btoa(value).replace(regex, ",") 4452 }, 4453 4454 mageEncode: (state, getters) => (input) => { 4455 return getters.encode(input).replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, ','); 4456 }, 4457 4458 encode: (state,getters) => (input) => { 4459 let output = ""; 4460 let chr1, chr2, chr3, enc1, enc2, enc3, enc4; 4461 let i = 0; 4462 4463 if( typeof window.btoa === "function" ){ 4464 return window.btoa(input); 4465 } 4466 4467 input = getters._utf8_encode(input); 4468 4469 while (i < input.length) { 4470 4471 chr1 = input.charCodeAt(i++); 4472 chr2 = input.charCodeAt(i++); 4473 chr3 = input.charCodeAt(i++); 4474 4475 enc1 = chr1 >> 2; 4476 enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); 4477 enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); 4478 enc4 = chr3 & 63; 4479 4480 if (isNaN(chr2)) { 4481 enc3 = enc4 = 64; 4482 } else if (isNaN(chr3)) { 4483 enc4 = 64; 4484 } 4485 output = output + 4486 state._keyStr.charAt(enc1) + state._keyStr.charAt(enc2) + 4487 state._keyStr.charAt(enc3) + state._keyStr.charAt(enc4); 4488 } 4489 4490 return output; 4491 }, 4492 4493 _utf8_encode : () => (string) => {
4494 string = string.replace(/\r\n/g,"\n"); 4495 let utftext = ""; 4496 4497 for (let n = 0; n < string.length; n++) { 4498 4499 let c = string.charCodeAt(n); 4500 4501 if (c < 128) { 4502 utftext += String.fromCharCode(c); 4503 } 4504 else if((c > 127) && (c < 2048)) { 4505 utftext += String.fromCharCode((c >> 6) | 192); 4506 utftext += String.fromCharCode((c & 63) | 128); 4507 } 4508 else { 4509 utftext += String.fromCharCode((c >> 12) | 224); 4510 utftext += String.fromCharCode(((c >> 6) & 63) | 128); 4511 utftext += String.fromCharCode((c & 63) | 128); 4512 } 4513 } 4514 return utftext; 4515 }, 4516 4517 cartItemsAreSalable : (state, getters, rootState) => { 4518 let cartItems = rootState.quote.items.filter(item => item && item.is_salable === false) 4519 return cartItems.length === 0 4520 }, 4521 4522 4523 getCartItemPayload : () => (qty,cartId) => { 4524 return { 4525 "cartItem": { 4526 "qty": qty, 4527 "quote_id": cartId, 4528 } 4529 } 4530 }, 4531 4532 4533 addToCartItemPayload : (state, getters, rootState) => (cartId) => { 4534 if (rootState.product === undefined) return false 4535 let payload = { 4536 "cartItem" : { 4537 "qty": 1, 4538 "quote_id": cartId, 4539 "sku" : rootState.product.sku 4540 } 4541 } 4542 4543 if (rootState.product.type_id === "configurable") { 4544 payload["cartItem"]["product_option"] = { 4545 "extension_attributes" : { 4546 "configurable_item_options" : [{ 4547 "option_id" : rootState.product.extension_attributes.configurable_product_options[0].attribute_id, 4548 "option_value" : rootState.product.extension_attributes.configurable_product_options[0].values[0].value_index, 4549 }] 4550 } 4551 } 4552 } 4553 4554 if (rootState.product.type_id === "bundle") { 4555 payload["cartItem"]["product_option"] = { 4556 "extension_attributes" : { 4557 "bundle_options" : getters.getBundleOptions() 4558 } 4559 } 4560 } 4561 4562 return payload 4563 }, 4564 4565 4566 getBundleOptions : (state, getters, rootState)=> () => { 4567 let options = rootState.product.extension_attributes.bundle_product_options[0].product_links ?? [], 4568 response = [] 4569 for (let option of options) { 4570 response.push({ 4571 "option_id": option.option_id, 4572 "option_qty": option.qty, 4573 "option_selections": [option.id] 4574 }) 4575 } 4576 return response 4577 }, 4578 4579 4580 } 4581 } 4582</script>
4582 4583
4584<script id="customer_store"> 4585 const customer = { 4586 namespaced: true, 4587 state: () => ({ 4588 customerIdentifier : mage_cache_storage.customer?.customerId ?? null, 4589 customerId : mage_cache_storage.customer?.signin_token ?? null, 4590 4591 customerLoyaltyRank : mage_cache_storage.customer?.customerTier ?? null, 4592 4593 customerGroup : "0", 4594 4595 default_address : { 4596 region_id : null, 4597 country_id : 'DE', 4598 }, 4599 4600 shipping_address : { 4601 firstname : null, 4602 lastname : null, 4603 email : null, 4604 country_id : null, 4605 region_id : null, 4606 city : null, 4607 postcode : null, 4608 street : null, 4609 hnr : null, 4610 telephone : null 4611 }, 4612 4613 loginErrors : { 4614 errors : false, 4615 message : '' 4616 } 4617 }), 4618 mutations: { 4619 4620 updateCustomerId : (state,customerId) => { 4621 state.customerId = customerId 4622 }, 4623 4624 updateCustomerIdentifier : (state,customerIdentifier) => { 4625 state.customerIdentifier = customerIdentifier 4626 }, 4627 4628 updateLoginErrors : (state,error) => { 4629 state.loginErrors = error 4630 }, 4631 4632 updateCustomerGroup : (state, group) => { 4633 state.customerGroup = group 4634 } 4635 4636 }, 4637 actions : { 4638 4639 /** 4640 * @param commit 4641 * @param dispatch 4642 * @param request // {url,data,errorComponent} 4643 */ 4644 async login({commit,dispatch},request) { 4645 await dispatch('controllerRequest', { 4646 url : request.url, 4647 data : request.data, 4648 errorComponent : { 4649 commit : 'customer/updateLoginErrors', 4650 active : true 4651 } 4652 },{ root: true }) 4653 .then(async () => { 4654 window.dispatchEvent(new CustomEvent("reload-private-content", { 4655 detail: { 4656 section: ['cart','customer'] 4657 } 4658 })); 4659 localStorageHelper.initFormKey() 4660 commit('updateFormKey',localStorageHelper.getFormKey(),{root:true}) 4661 }) 4662 }, 4663 4664 }, 4665 } 4666</script>
4666 4667
4668<script id="store"> 4669 4670 const mage_cache_storage = JSON.parse(window.localStorage.getItem('mage-cache-storage')) ?? {} 4671 if(typeof locale === 'undefined'){ 4672 const locale = "de_DE"; 4673 } 4674 4675 Vue.use(Vuex); 4676 const store = new Vuex.Store({ 4677 modules: { 4678 cart : cart, 4679 customer : customer, 4680 }, 4681 state: { 4682 restUrl : "https://www.justspices.de/rest/default/V1", 4683 localStorage : mage_cache_storage, 4684 formKey : hyva.getCookie('form_key'), 4685 quote : {}, 4686 product : {}, 4687 errors : { 4688 permanent : "", 4689 temporary : [] 4690 }, 4691 hasReservedOrderId : false 4692 }, 4693 mutations: { 4694 async updateQuote(state, quote) { 4695 state.quote = quote 4696 4697 if ('reserved_order_id' in quote) { 4698 this.commit('updateReservedOrderId', true) 4699 } else { 4700 this.commit('updateReservedOrderId', false) 4701 } 4702 4703 4704 // check if quote contains only valid items 4705 let invalidCartItems = state.quote.items.filter((item) => { 4706 return item.extension_attributes?.is_salable === false 4707 }) 4708 if (invalidCartItems.length === 0) { 4709 this.commit('removePermanentError') 4710 } 4711 4712 // check if cart is emtpy 4713 state.quote.items.length === 0 ? 4714 this.commit('cart/updateCartIsEmpty', true) : 4715 this.commit('cart/updateCartIsEmpty', false) 4716 4717 if(state.quote.extension_attributes?.has_error === true && state.quote.extension_attributes?.messages){ 4718 let cartItemsWithError = state.quote.items.filter((item) => { 4719 return item.extension_attributes?.has_error === true 4720 }) 4721 4722 let cartItemNamesWithError = [] 4723 for (let cartItemWithError of cartItemsWithError ) { 4724 cartItemNamesWithError.push(cartItemWithError.name) 4725 } 4726 4727 for (let message of state.quote.extension_attributes?.messages ) { 4728 this.commit('updateErrors',{ 4729 status : "permanent", 4730 error : message + ' Bitte entferne folgende Produkte: ' + cartItemNamesWithError.toString() 4731 }) 4732 } 4733 } 4734 }, 4735 4736 updateReservedOrderId(state,status) { 4737 state.hasReservedOrderId = status 4738 }, 4739 4740 4741 async updateProduct(state,product) { 4742 state.product = product 4743 }, 4744 4745 async updateErrors(state,error) { 4746 if (error.status === "permanent") { 4747 state.errors.permanent = error.error 4748 } 4749 if (error.status === "temporary") { 4750 state.errors.temporary.push(error) 4751 this.commit('removeTemporaryErrors',error) 4752 window.scrollTo(0,0) 4753 } 4754 }, 4755 4756 async removeTemporaryErrors(state,error) { 4757 setTimeout(() => { 4758 state.errors.temporary = state.errors.temporary.filter(function(item) { 4759 return item.message !== error.message 4760 }) 4761 },3000) 4762 }, 4763 4764 async removePermanentError(state) { 4765 state.errors.permanent = "" 4766 }, 4767 4768 async updateLocalStorage(state,localstorage) { 4769 state.localStorage = localstorage 4770 }, 4771 4772 updateFormKey(state, formkey) { 4773 state.formKey = formkey 4774 } 4775 4776 }, 4777 actions: { 4778 4779 async apiRequest({state, commit},payload = { 4780 commit : '', 4781 loadingCommit : '', 4782 errorMessage : false, 4783 endpoint : ``, 4784 type : 'GET', 4785 header : {}, 4786 data : {},
4787 cartEmptyCheck : false, 4788 reloadLocalStorage : false 4789 }) { 4790 let request = { 4791 url : `${state.restUrl}/${payload.endpoint}`, 4792 contentType: "application/json;charset=utf-8", 4793 dataType: "json" , 4794 type: payload.type, 4795 header : payload.header, 4796 data : payload.data 4797 } 4798 if (payload.loadingCommit) commit(payload.loadingCommit,true) 4799 return new Promise((resolve, reject) => { 4800 try { 4801 $.ajax(request).done((response) => { 4802 if (response && payload.commit) { 4803 commit(payload.commit,response) 4804 } 4805 if (payload.loadingCommit) commit(payload.loadingCommit,false) 4806 4807 // Event auslösen, um den Mini-Cart-Counter zu aktualisieren 4808 if (payload.reloadLocalStorage) { 4809 hyva.setCookie('mage-cache-sessid', '', -1, true); 4810 window.dispatchEvent(new CustomEvent("reload-customer-section-data")); 4811 } 4812 4813 resolve() 4814 }).fail((xhr, textStatus, error) => { 4815 if (payload.errorCommit && payload.errorCommit.commit !== '') { 4816 commit(payload.errorCommit.commit,payload.errorCommit.status) 4817 } 4818 if (payload.loadingCommit) commit(payload.loadingCommit,false) 4819 if (payload.errorMessage === true) { 4820 commit('updateErrors',{ 4821 status: "temporary", 4822 message: xhr.responseJSON?.message 4823 }) 4824 reject(xhr.responseJSON?.message) 4825 } 4826 if (payload.cartEmptyCheck === true) { 4827 commit('cart/updateCartIsEmpty',true) 4828 } 4829 }) 4830 } catch (error) { 4831 console.log(error) 4832 } 4833 }) 4834 }, 4835 4836 4837 4838 async controllerRequest({state, commit},payload = { 4839 commit : '', 4840 loadingCommit : '', 4841 reloadSection : '', 4842 errorMessage : false, 4843 form : [], 4844 addToCart : false, 4845 data : {}, 4846 url : '', 4847 errorComponent : { 4848 commit : '', 4849 active : false 4850 }, 4851 reloadLocalStorage : false 4852 }) { 4853 return new Promise((resolve, reject) => { 4854 try { 4855 4856 let formData = payload.form ? new FormData(payload.form) : payload.data, 4857 request = { 4858 url: payload.url ? payload.url : payload.action + '/response_variant/' + 'false', 4859 data: formData, 4860 type: 'POST', 4861 dataType: 'json', 4862 cache: false, 4863 contentType: false, 4864 processData: false, 4865 } 4866 $.ajax(request).done((response) => { 4867 if(payload.addToCart && response.backUrl) { 4868 commit('cart/updateAtcErrorUrl', response.backUrl) 4869 } else if (payload.addToCart) { 4870 commit('cart/updateAtcErrorUrl', "") 4871 } 4872 if (payload.loadingCommit) commit(payload.loadingCommit,false) 4873 if (payload.errorComponent && payload.errorComponent.active) { 4874 commit(payload.errorComponent.commit,response) 4875 } 4876 4877 // Event auslösen, um den Mini-Cart-Counter zu aktualisieren 4878 if (payload.reloadLocalStorage) { 4879 hyva.setCookie('mage-cache-sessid', '', -1, true); 4880 window.dispatchEvent(new CustomEvent("reload-customer-section-data")); 4881 } 4882 4883 resolve() 4884 }).fail((xhr, textStatus, error) => { 4885 if (payload.errorMessage === true) { 4886 this.$store.commit('updateErrors',{ 4887 status : "temporary", 4888 error : xhr.responseJSON?.message 4889 }) 4890 reject(xhr.responseJSON?.message) 4891 } 4892 }) 4893 } catch (error) { 4894 console.log(error) 4895 } 4896 }) 4897 }, 4898 4899 4900 /** 4901 * @param dispatch 4902 * @param request // {cartId,token} 4903 */ 4904 async getQuote({dispatch},request) { 4905 if (request.token) { 4906 // customer cart 4907 await dispatch('apiRequest', { 4908 commit : 'updateQuote',
4909 endpoint : `carts/mine`, 4910 type : 'GET', 4911 header : {headers: { Authorization: `Bearer ${request.token}`}}, 4912 cartEmptyCheck : true, 4913 },{ root: true }) 4914 } else { 4915 // guest cart 4916 await dispatch('apiRequest', { 4917 commit : `updateQuote`, 4918 endpoint : `guest-carts/${request.cartId}`, 4919 type : 'GET', 4920 cartEmptyCheck : true, 4921 },{ root: true }) 4922 } 4923 }, 4924 4925 4926 /** 4927 * @param dispatch 4928 * @param request // {cartId,token} 4929 */ 4930 async getProduct({dispatch},request) { 4931 await dispatch('apiRequest', { 4932 commit : 'updateProduct', 4933 endpoint : `products/id/${request.id}`, 4934 header : {headers: { Authorization: `Bearer ${request.token}`}}, 4935 type : 'GET', 4936 },{ root: true }) 4937 }, 4938 4939 }, 4940 getters: { 4941 4942 formattedPrice : (state) => (price) => { 4943 let countryCode = locale !== undefined ? locale : 'de_DE', 4944 currencyCode = { 4945 'de-DE' : 'EUR', 4946 'en-GB' : 'GBP', 4947 'es-ES' : 'EUR', 4948 'en-US' : 'USD' 4949 } 4950 4951 if (countryCode.includes('_')) { 4952 countryCode = countryCode.replace('_','-') 4953 } 4954 4955 return new Intl.NumberFormat(countryCode, { style: 'currency', currency: currencyCode[countryCode] }).format(price); 4956 }, 4957 4958 htmldecode : (state) => (input) => { 4959 let doc = new DOMParser().parseFromString(input, "text/html"); 4960 return doc.documentElement.textContent; 4961 }, 4962 4963 } 4964 }); 4965</script>
4965 4966 4967
4968<script type="text/x-template" id="cart-modal"> 4969 <div class="modal block v-slide-cart-modal"> 4970 <div class="v-modal-content" @click.stop> 4971 <div class="v-modal-header" :class="isScrollable ? 'scrollable' : ''"> 4972 <div class="v-modal-headline relative"> 4973 <span class="v-close" x-on:click="closeCartDrawer"> 4974 <i class="fal fa-times"></i> 4975 </span> 4976 <p class="font-recoleta fs-24 lh-30">Dein Warenkorb</p> 4977 </div> 4978 </div> 4979 <div ref="modalCartItems" class="v-modal-cart-items" :class="isScrollable ? 'scrollable' : ''"> 4980 <div class="v-modal-incentives"> 4981 <incentives></incentives> 4982 </div> 4983 4984 <gift-selection v-for="(incentiveSelectionRule,key) of incentiveSelectionRules" 4985 :data="incentiveSelectionRule" :rule="key"></gift-selection> 4986 4987 <cart-items v-if="countStoredArticles > 0"></cart-items> 4988 <div class="algolia-reco-container" v-if="countStoredArticles > 0"> 4989 <algolia-recommendations></algolia-recommendations> 4990 </div> 4991 <gfc-totals></gfc-totals> 4992 </div> 4993 <div class="v-modal-totals" :class="[countStoredArticles > 0 ? '' : 'hidden']"> 4994 <totals :is-scrolled="isScrolled"></totals> 4995 </div> 4996 <div v-if="countStoredArticles === 0" class="flex justify-center items-center flex-col text-center cart-empty-container"> 4997 <span class="font-bold fs-18 lh-26">Dein Warenkorb ist leer</span> 4998 <a class="cart-empty font-bold fs-16 lh-24" :href="bestsellerUrl"> 4999 Jetzt Shoppen </a> 5000 </div> 5001 </div> 5002 </div> 5003</script>
5003 5004 5005<!--COMPONENTS-->
5006<script type="text/x-template" id="incentives"> 5007 <div class="incentives box" :class="mode" v-if="incentives.length > 0 && !cartContainsOnlyExcludedUrls"> 5008 <div class="box-content p-2" v-if="mode === 'all'"> 5009 <div class="progress-container"> 5010 <div class="milestones flex relative mb-1"> 5011 <div class="progressbar"></div> 5012 <div class="progress-fill" :style="{ 'width' : filledprogress + '%' }"></div> 5013 5014 <div class="milestone text-center relative" :class="isIncentiveActive(index)" v-for="(incentive, index) in incentives" :key="incentive.name"> 5015 <div class="milestone-label fs-12 lh-16 mb-0.5"> {{strippedLabel(incentive.name)}}</div> 5016 <div class="circle"> 5017 <svg v-if="incentive.icon.includes('can-icon')" xmlns="http://www.w3.org/2000/svg" width="15" height="21" viewBox="0 0 15 21" fill="none"> 5018 <ellipse cx="7.53222" cy="3.70365" rx="6.53222" ry="2.70365" stroke="white"/> 5019 <path d="M14.0644 17.698C14.0644 19.1912 11.1399 20.4017 7.53222 20.4017C3.92458 20.4017 1 19.1912 1 17.698" stroke="white"/> 5020 <path d="M1 3.86407L1 17.8595" stroke="white"/> 5021 <path d="M14.0645 3.86407L14.0645 17.8595" stroke="white"/> 5022 </svg> 5023 <img v-else-if="incentive.icon.includes('https')" :src="incentive.icon"/> 5024 <i class="fal" :class="incentive.icon" v-else></i> 5025 </div> 5026 <div class="threshold">{{formattedPrice(incentive.price)}}</div> 5027 </div> 5028 </div> 5029 <span class="next-incentive black font fs-12 lh-14" v-if="currentIncentive.priceToNext"><strong>{{formattedPrice(currentIncentive.priceToNext.toFixed(2))}}</strong> bis zum {{strippedLabel(currentIncentive.nextIncentiveName)}}</span> 5030 5031 </div> 5032 </div> 5033 <div class="box-content pb-0" v-if="mode === 'single'"> 5034 <div class="progress"> 5035 <div class="progress-bar" role="progressbar" :style="{ 'width' : progress + '%' }" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100"></div> 5036 </div> 5037 <div class="cart-current-incentive" style="min-height:20px"> 5038 <span class="next-incentives-price" v-if="shippingThreshold"> 5039 <i class="fal" :class="currentIncentive.icon"></i> 5040 </span> 5041 <span class="next-incentive black font fs-14 lh-14" v-if="shippingThreshold" v-html="currentIncentive.nextIncentiveName"></span> 5042 </div> 5043 </div> 5044 </div> 5045</script>
5045 5046
5047<script> 5048 Vue.component("incentives", { 5049 data: function () { 5050 return { 5051 mode: 'all', 5052 incentives: [], 5053 excludedSkus : ["geschenkgutschein","JS11004105","JS11004106","JSB11004156","JS11005239","JSB0047300"], 5054 activeIncentiveNumber: 0 5055 } 5056 }, 5057 created() { 5058 if (typeof this.incentives === 'object') { 5059 let incentiveArray = []; 5060 if (Object.keys(this.incentives).length > 0 ) { 5061 5062 if (this.$store.state.localStorage.customer?.gfc_level !== 'Taste Master') { 5063 incentiveArray.push({ 5064 icon : "fa-truck", 5065 name : "Kostenloser Versand", 5066 price : this.$store.state.cart.shippingThreshold ?? 39 5067 }) 5068 } 5069 5070 const objectArray = Object.entries(this.incentives); 5071 objectArray.forEach(([key, value]) => { 5072 incentiveArray.push(value) 5073 }); 5074 5075 incentiveArray.sort((a, b) => this.currencyToNumber(a.price) > this.currencyToNumber(b.price) ? 1 : -1) 5076 5077 this.incentives = incentiveArray; 5078 } 5079 }else{ 5080 if (this.incentives.length > 0 ) { 5081 if (this.$store.state.localStorage.customer?.gfc_level !== 'Taste Master') { 5082 this.incentives.push({ 5083 icon: "fa-truck", 5084 name: "Kostenloser Versand", 5085 price: this.$store.state.cart.shippingThreshold ?? 39 5086 }) 5087 } 5088 this.incentives = this.incentives.sort((a, b) => this.currencyToNumber(a.price) > this.currencyToNumber(b.price) ? 1 : -1) 5089 } 5090 } 5091 5092 }, 5093 computed: { 5094 subtotalWithoutExcludedSkus : function() { 5095 let cartItems = this.$store.state.cart.storedCart.items ?? [], 5096 subtotal = this.$store.state.cart.storedCart.subtotalAmount ??0 5097 5098 if (cartItems.length > 0) { 5099 5100 5101 let matchingItems = cartItems.filter(item => { 5102 if ( item && item.product_sku && this.excludedSkus.indexOf(item.product_sku) >= 0 ) { 5103 return item 5104 } 5105 }) 5106 5107 if (matchingItems.length > 0) { 5108 for (let item of matchingItems) { 5109 subtotal = subtotal - parseFloat(item.product_price_value * item.qty ?? "0").toFixed(2) 5110 } 5111 } 5112 5113 } 5114 return subtotal 5115 }, 5116 5117 shippingThreshold : function() { 5118 return this.$store.state.cart.shippingThreshold ?? 39 5119 }, 5120 5121 currentIncentive: function () { 5122 let i = 1 5123 let currentSubtotals = this.subtotalWithoutExcludedSkus 5124 let incentiveName = ''; 5125 5126 for (let incentive of this.incentives) { 5127 5128 incentiveName = incentive.name; 5129 5130 if (incentiveName === "Kostenloser Versand") { 5131 incentive.price = this.$store.state.cart.shippingThreshold 5132 } 5133 5134 if (currentSubtotals < parseFloat(incentive.price)) { 5135 return { 5136 priceToNext: parseFloat(incentive.price) - currentSubtotals, 5137 price: incentive.price, 5138 nextIncentiveName: incentiveName === "Kostenloser Versand" ? 5139 this.$i18n.t("incentives.free_shipping", { 5140 price: this.$store.getters['formattedPrice'](parseFloat(incentive.price) - currentSubtotals), 5141 incentive: incentiveName 5142 }) : 5143 this.$i18n.t("incentives.free_spice", { 5144 price: this.$store.getters['formattedPrice'](parseFloat(incentive.price) - currentSubtotals), 5145 incentive: incentiveName 5146 }), 5147 icon: incentive.icon, 5148 name: incentiveName 5149 } 5150 } 5151 i++ 5152 } 5153 return { 5154 priceToNext: '', 5155 price: '', 5156 nextIncentiveName: 'Glückwunsch! Du hast Dir kostenlosen Versand und alle Geschenke gesichert!', 5157 icon: 'fa-gift', 5158 name : incentiveName 5159 } 5160 }, 5161 5162 filledprogress: function () { 5163 if (!this.subtotalWithoutExcludedSkus || this.incentives.length === 0) return 0; 5164 5165 let subtotal = this.subtotalWithoutExcludedSkus; 5166 5167 let iconPositions = [ 5168 {start: 10, end: 24}, 5169 {start: 44, end: 57}, 5170 {start: 78, end: 100} 5171 ]; 5172 5173 if (this.incentives.length === 4) { 5174 iconPositions = [ 5175 {start: 7, end: 19}, 5176 {start: 32, end: 44}, 5177 {start: 57, end: 69}, 5178 {start: 82, end: 100} 5179 ]; 5180 } 5181 // Find the current active incentive based on the subtotal. 5182 let currentIncentiveIndex = -1; 5183 for (let i = 0; i < this.incentives.length; i++) { 5184 if (subtotal < parseFloat(this.incentives[i].price)) { 5185 currentIncentiveIndex = i; 5186 break; 5187 } 5188 } 5189 5190 // Handle the case where the subtotal is past the last incentive. 5191 if (currentIncentiveIndex === -1) { 5192 this.activeIncentiveNumber = this.incentives.length; 5193 return 100; 5194 } 5195 5196 // Set the active incentive number. 5197 this.activeIncentiveNumber = currentIncentiveIndex; 5198 5199 // Calculate progress for the first segment (before the first icon). 5200 if (currentIncentiveIndex === 0) { 5201 const iconStart = iconPositions[0].start; 5202 const incentivePrice = parseFloat(this.incentives[0].price); 5203 return ((subtotal / incentivePrice) * iconStart).toFixed(0); 5204 } 5205 5206 // Calculate progress for any subsequent segment. 5207 const previousIncentivePrice = parseFloat(this.incentives[currentIncentiveIndex - 1].price); 5208 const currentIncentivePrice = parseFloat(this.incentives[currentIncentiveIndex].price); 5209 5210 const priceDifference = currentIncentivePrice - previousIncentivePrice; 5211 5212 const previousIconEnd = iconPositions[currentIncentiveIndex - 1].end; 5213 const currentIconStart = iconPositions[currentIncentiveIndex].start; 5214 const widthDifference = currentIconStart - previousIconEnd; 5215 5216 const priceAboveLastStep = subtotal - previousIncentivePrice; 5217 const widthInStep = (priceAboveLastStep / priceDifference) * widthDifference; 5218 5219 return (widthInStep + previousIconEnd).toFixed(0); 5220 }, 5221 5222 progress : function () { 5223 if (!this.subtotalWithoutExcludedSkus) return 0 5224 5225 let countIncentives = this.incentives.length, 5226 progress = 0 5227 5228 if (this.currentIncentive.priceToNext * countIncentives > 100) { 5229 progress = (((100 - (this.currentIncentive.priceToNext * countIncentives)) / 10) + countIncentives).toFixed(0) 5230 } else { 5231 progress = (100 - (this.currentIncentive.priceToNext * countIncentives)).toFixed(0) 5232 } 5233 return progress 5234 }, 5235 5236 cartContainsOnlyExcludedUrls : function() { 5237 let cartItems = this.$store.state.cart.storedCart.items ?? [] 5238 if(cartItems.length > 0 && this.excludedSkus.length > 0) { 5239 let matchingItems = cartItems.filter(item => { 5240 if ( this.excludedSkus.indexOf(item.product_sku) >= 0 ) { 5241 return item 5242 } 5243 }) 5244 return matchingItems.length === cartItems.length 5245 } 5246 return false 5247 }, 5248 5249 5250 }, 5251 methods: { 5252 isIncentiveActive: function (index) { 5253 return (this.activeIncentiveNumber === index+1 || this.activeIncentiveNumber > index+1) ? 'active' : '' 5254 },
5255 strippedLabel: function (input) { 5256 let regex = /(<([^>]+)>)/ig; 5257 let nohtmlinput = input.replace(regex, ""); 5258 if(nohtmlinput.includes('Gratis Produkt')) { 5259 return "Gratis Produkt"; 5260 } 5261 if(nohtmlinput.includes('gratis Versand')) { 5262 return "Kostenloser Versand"; 5263 } 5264 let regex2 = /bis zum\s+(.*)/; 5265 let match = input.match(regex2) 5266 if (match) { 5267 return match[1]; 5268 } 5269 5270 return nohtmlinput 5271 }, 5272 currencyToNumber : function (currency) { 5273 if (typeof currency === 'string') { 5274 return Number(currency.replace(/[^0-9.-]+/g,"")) 5275 } 5276 }, 5277 formattedPrice : (price) => { 5278 if(price.includes('.')){ 5279 price = price.replace('.', ','); 5280 } 5281 if(price.includes('â¬')){ 5282 return price; 5283 } 5284 return price + 'â¬'; 5285 } 5286 5287 }, 5288 template: "#incentives", 5289 }); 5290</script>
5290 5291
5292<script type="text/x-template" id="gift-selection"> 5293 <div class="select-free-gift-message mb-3" :data-rule-id="rule"> 5294 <div class="image cursor-pointer" @click="toggleIncentivesModal"> 5295 <img src="https://www.justspices.de//media/wysiwyg/relaunch-2024/cart/gift.svg" alt="Justspices" width="110" height="110"> 5296 </div> 5297 <div class="content cursor-pointer" @click="toggleIncentivesModal"> 5298 <div class="product-item-name font-bold fs-18 lh-26">Wähle dein Gratisgeschenk</div> 5299 <div class="row absolute right-1 bottom-1"> 5300 <button class="button-small w-auto green">Auswählen</button> 5301 </div> 5302 </div> 5303 <div class="select-incentive-popup bg-main-creme rounded-25 p-2 fixed z-30" :class="!showPopup ? 'hidden' : ''"> 5304 <i @click="toggleIncentivesModal" class="cursor-pointer fa-light fa-xmark fs-24 absolute right-2 top-2 z-10"></i> 5305 <div class="relative flex flex-wrap"> 5306 <p class="font-recoleta text-l mb-5 w-full">Geschenk auswählen</p> 5307 <div class="items w-full"> 5308 <div class="incentive-selection-item mb-3 last:mb-0 cursor-pointer" v-for="incentiveSelectionProduct in incentiveSelectionProducts" @click="addIncentiveToCart(incentiveSelectionProduct.product_id)"> 5309 <div class="image"> 5310 <img :src="baseUrl + 'media/catalog/product/' + incentiveSelectionProduct.thumbnail" :alt="incentiveSelectionProduct.name" width="110" height="110"> 5311 </div> 5312 <div class="content"> 5313 <p class="font-bold fs-18 lh-26">{{incentiveSelectionProduct.name}}</p> 5314 <div class="row flex justify-between"> 5315 <p class="fs-15 desktop:fs-18 lh-26">0,00 ⬠<span class="old-price font-bold fs-15 desktop:fs-18 lh-26 text-main-red line-through">{{formattedPrice(incentiveSelectionProduct.old_price)}}</span></p> 5316 <button class="button green w-auto p-2">Auswählen</button> 5317 </div> 5318 </div> 5319 </div> 5320 </div> 5321 <button class="button secondary mt-5 close" @click="toggleIncentivesModal">SchlieÃen</button> 5322 </div> 5323 </div> 5324 <div class="incentive-black-overlay" :class="!showPopup ? 'hidden' : 'active'" @click="toggleIncentivesModal"></div> 5325 </div> 5326</script>
5326 5327
5328<script> 5329 Vue.component("gift-selection", { 5330 props : { 5331 data : Object, 5332 rule : String 5333 }, 5334 data: function () { 5335 return { 5336 popupOpen : false, 5337 } 5338 }, 5339 created() { 5340 5341 5342 }, 5343 computed: { 5344 showPopup: function () { 5345 if(this.popupOpen === true) { 5346 return true 5347 } 5348 5349 if(this.$store.state.cart.forceIncentivePopupOpen === true) { 5350 this.$store.commit('cart/updateForceIncentivePopupOpen', false) 5351 return true 5352 } 5353 5354 return false 5355 }, 5356 incentiveSelectionProducts : function () { 5357 let incentiveInformation = this.$store.state.cart.incentiveInformation; 5358 if(incentiveInformation && incentiveInformation.triggered_products[this.rule]) { 5359 return incentiveInformation.triggered_products[this.rule].sku 5360 } 5361 return []; 5362 } 5363 }, 5364 methods: { 5365 formattedPrice : function (price) { 5366 let countryCode = locale !== undefined ? locale : 'de_DE', 5367 currencyCode = { 5368 'de-DE' : 'EUR', 5369 'en-GB' : 'GBP', 5370 'es-ES' : 'EUR', 5371 'en-US' : 'USD' 5372 } 5373 5374 if (countryCode.includes('_')) { 5375 countryCode = countryCode.replace('_','-') 5376 } 5377 5378 return new Intl.NumberFormat(countryCode, { style: 'currency', currency: currencyCode[countryCode] }).format(price); 5379 }, 5380 toggleIncentivesModal: function() { 5381 if(this.popupOpen === true) { 5382 this.popupOpen = false 5383 } else { 5384 this.popupOpen = true 5385 } 5386 }, 5387 addIncentiveToCart : function (productId) { 5388 let currentUrl = window.location.href; 5389 let base64currentUrl = btoa(currentUrl); 5390 5391 let request = { 5392 url: baseUrl + 'amasty_promo/cart/add/', 5393 data: { 5394 "uenc": btoa(currentUrl), 5395 "isPromoItems": true, 5396 "product_id": productId, 5397 "form_key": this.$store.state.formKey 5398 }, 5399 type: 'POST' 5400 }; 5401 5402 $.ajax(request).done((response) => { 5403 this.toggleIncentivesModal() 5404 window.dispatchEvent(new CustomEvent("reload-private-content", { 5405 detail: { 5406 section: ['cart'] 5407 } 5408 })); 5409 }) 5410 }, 5411 5412 }, 5413 template: "#gift-selection", 5414 }); 5415</script>
5415 5416 5417
5418<script type="text/x-template" id="cart-items"> 5419 <div class="box" id="v-cart-items-container"> 5420 <cart-article 5421 v-for="article of storedArticles" 5422 :article="article" 5423 ></cart-article> 5424 </div> 5425</script>
5425 5426 5427<!--COMPONENTS-->
5428<script type="text/x-template" id="cart-article"> 5429 <div ref="cartItemContainers" class="cart-item-container" v-if="!hideForCustomer" :class="isPromo ? 'promo' : ''"> 5430 <article class="cart-items" v-if="!isPromo"> 5431 <div class="cart-item-image-container"> 5432 <div class="cart-item-cell image"> 5433 <a 5434 class="product-item-photo" 5435 :href="article.product_url" 5436 :title="article.product_name" v-if="article.is_visible_in_site_visibility" 5437 > 5438 <img 5439 class="vue-lozad" 5440 width="110" 5441 height="110" 5442 :alt="article.product_name" 5443 :data-src="article.product_image?.src" 5444 /> 5445 </a> 5446 <img 5447 width="110" 5448 height="110" 5449 :alt="article.product_name" 5450 :src="article.product_image?.src" 5451 loading="lazy" 5452 v-else 5453 /> 5454 </div> 5455 </div> 5456 <div class="cart-item-info-container"> 5457 <div class="cart-item-name flex justify-between"> 5458 <div class="product-item-name"> 5459 <a :href="article.product_url" v-if="article.is_visible_in_site_visibility"> 5460 {{$store.getters["htmldecode"](article.product_name)}} 5461 </a> 5462 <span v-else>{{$store.getters["htmldecode"](article.product_name)}}</span> 5463 </div> 5464 <div class="remove-item-from-cart"> 5465 <i class="fa-light fa-trash fs-18 cursor-pointer" @click="removeItemFromCart" :class="{ 'hidden': loading === 'remove-cart' }"></i> 5466 <div class="spinner" :class="{ 'hidden': loading !== 'remove-cart' }" width="16" height="16" style="width: 18px;"> 5467 <svg aria-hidden="true" focusable="false" role="presentation" class="loading-spinner" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg"> 5468 <circle class="path" fill="none" stroke-width="6" cx="33" cy="33" r="30"></circle> 5469 </svg> 5470 </div> 5471 </div> 5472 </div> 5473 <div class="cart-item-content" v-show="content !== ''"> 5474 <p class="fs-14 lh-18 underline" @click="showContent = !showContent" v-text="article.product_type == 'configurable' ? 'Zutaten anzeigen' : 'Inhalt anzeigen'"></p> 5475 <span v-if="showContent" class="ingredients-popup"> 5476 <span class="pr-3 block" v-html="content"> 5477 </span> 5478 <div class="ingredient-close-button" @click="showContent = !showContent"> 5479 <i class="fal fa-times"></i> 5480 </div> 5481 </span> 5482 </div> 5483 <div class="flex flex-row justify-between items-center cart-item-infos"> 5484 <div class="cart-item-price-container"> 5485 <div class="price-including-tax text-left" v-if="item && item.is_salable"> 5486 <span class="cart-price"> 5487 <span class="price fs-18 lh-26 font-regular">{{$store.getters["formattedPrice"](item.row_price_incl_tax)}}</span> 5488 <span class="old-price fs-18 lh-26 font-regular" v-if="item.base_price_incl_tax < item.price && !isBundle">{{$store.getters["formattedPrice"](item.price)}}</span> 5489 </span> 5490 </div> 5491 <span class="fs-18 lh-26 font-regular text-left" v-else-if="item && item.is_salable === false"> 5492 Nicht auf Lager </span> 5493 <div class="spinner" v-else width="16" height="16"> 5494 <svg aria-hidden="true" focusable="false" role="presentation" class="loading-spinner" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg"> 5495 <circle class="path" fill="none" stroke-width="6" cx="33" cy="33" r="30"></circle> 5496 </svg> 5497 </div>
5498 <span class="fs-12 price-per-weight text-main-grey-dark block" v-if="article.weight"> 5499 <span class="price fs-12 lh-18"> 5500 <span class="fs-12 lh-18">{{formattedWeight(article.weight)}}g</span> 5501 <span class="fs-12 lh-18" v-if="!hideWeightPrice">({{formattedCalculatedWeightPrice(article)}}/kg)</span> 5502 </span> 5503 </span> 5504 <span class="fs-12 price-per-weight text-main-grey-dark block" v-else-if="article.weight_price && !hideWeightPrice"> 5505 <span class="price fs-12 lh-18"> 5506 <span class="fs-12 lh-18">{{formattedWeight(article.weight)}}g</span> 5507 <span class="fs-12 lh-18" v-if="!hideWeightPrice">({{$store.getters["formattedPrice"](article.weight_price)}}/kg)</span> 5508 </span> 5509 </span> 5510 </div> 5511 <div class="cart-item-qty-container"> 5512 <div class="field qty"> 5513 <div class="control qty"> 5514 <button 5515 type="button" 5516 class="minusQty" 5517 @click="updateCartItem(!item.is_salable ? 0 : article.qty-1)" 5518 > 5519 <svg :class="{ 'hidden': loading === 'qty-minus' }" width="11" height="3" viewBox="0 0 11 3" fill="none" xmlns="http://www.w3.org/2000/svg"> 5520 <path d="M10.5625 0.875H0.9375C0.809896 0.875 0.700521 0.920573 0.609375 1.01172C0.536458 1.08464 0.5 1.1849 0.5 1.3125V2.1875C0.5 2.3151 0.536458 2.42448 0.609375 2.51562C0.700521 2.58854 0.809896 2.625 0.9375 2.625H10.5625C10.6901 2.625 10.7904 2.58854 10.8633 2.51562C10.9544 2.42448 11 2.3151 11 2.1875V1.3125C11 1.1849 10.9544 1.08464 10.8633 1.01172C10.7904 0.920573 10.6901 0.875 10.5625 0.875Z" 5521 fill="black"></path> 5522 </svg> 5523 <div class="spinner" :class="{ 'hidden': loading !== 'qty-minus' }" width="16" height="16"> 5524 <svg aria-hidden="true" focusable="false" role="presentation" class="loading-spinner" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg"> 5525 <circle class="path" fill="none" stroke-width="6" cx="33" cy="33" r="30"></circle> 5526 </svg> 5527 </div> 5528 </button> 5529 <input 5530 id="" 5531 name="" 5532 type="number" 5533 title="Menge" 5534 class="input-text qty" 5535 :value="article.qty" 5536 v-model="article.qty" 5537 @change="updateCartItem(article.qty)" 5538 :disabled="!item.is_salable" 5539 readonly 5540 > 5541 <button 5542 type="button" 5543 class="addQty" 5544 :class="{ 'loading': loading === 'qty-plus' }" 5545 @click="updateCartItem(article.qty+1)" 5546 :disabled="!item.is_salable" 5547 > 5548 <svg :class="{ 'hidden': loading === 'qty-plus' }
5548" width="11" height="11" viewBox="0 0 11 11" fill="none" xmlns="http://www.w3.org/2000/svg"> 5549 <path d="M10.5625 4.875H6.625V0.9375C6.625 0.809896 6.57943 0.709635 6.48828 0.636719C6.41536 0.545573 6.3151 0.5 6.1875 0.5H5.3125C5.1849 0.5 5.07552 0.545573 4.98438 0.636719C4.91146 0.709635 4.875 0.809896 4.875 0.9375V4.875H0.9375C0.809896 4.875 0.700521 4.92057 0.609375 5.01172C0.536458 5.08464 0.5 5.1849 0.5 5.3125V6.1875C0.5 6.3151 0.536458 6.42448 0.609375 6.51562C0.700521 6.58854 0.809896 6.625 0.9375 6.625H4.875V10.5625C4.875 10.6901 4.91146 10.7995 4.98438 10.8906C5.07552 10.9635 5.1849 11 5.3125 11H6.1875C6.3151 11 6.41536 10.9635 6.48828 10.8906C6.57943 10.7995 6.625 10.6901 6.625 10.5625V6.625H10.5625C10.6901 6.625 10.7904 6.58854 10.8633 6.51562C10.9544 6.42448 11 6.3151 11 6.1875V5.3125C11 5.1849 10.9544 5.08464 10.8633 5.01172C10.7904 4.92057 10.6901 4.875 10.5625 4.875Z" 5550 fill="black"></path> 5551 </svg> 5552 <div class="spinner" :class="{ 'hidden': loading !== 'qty-plus' }" width="16" height="16"> 5553 <svg aria-hidden="true" focusable="false" role="presentation" class="loading-spinner" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg"> 5554 <circle class="path" fill="none" stroke-width="6" cx="33" cy="33" r="30"></circle> 5555 </svg> 5556 </div> 5557 </button> 5558 </div> 5559 </div> 5560 </div> 5561 </div> 5562 </div> 5563 </article> 5564 <article class="cart-items promo" v-else> 5565 <div class="cart-item-image-container"> 5566 <div class="cart-item-cell image"> 5567 <a 5568 class="product-item-photo" 5569 :href="article.product_url" 5570 :title="article.product_name" v-if="article.is_visible_in_site_visibility" 5571 > 5572 <img 5573 class="vue-lozad" 5574 width="110" 5575 height="110" 5576 :alt="article.product_name" 5577 :data-src="article.product_image?.src" 5578 /> 5579 </a> 5580 <img 5581 width="110" 5582 height="110" 5583 :alt="article.name" 5584 :src="article.product_image?.src" 5585 loading="lazy" 5586 v-else 5587 /> 5588 </div> 5589 </div> 5590 <div class="cart-item-info-container"> 5591 <div class="cart-item-name"> 5592 <div class="product-item-name"> 5593 <a :href="article.product_url" v-if="article.is_visible_in_site_visibility"> 5594 {{formattedIncentiveProduct($store.getters["htmldecode"](article.product_name))}} 5595 </a> 5596 <span v-else>{{formattedIncentiveProduct($store.getters["htmldecode"](article.product_name))}}</span> 5597 <div class="interferer gift"> 5598 Geschenk </div> 5599 </div> 5600 </div> 5601 <div class="flex flex-row justify-between items-center"> 5602 <div class="cart-item-price-container"> 5603 <span class="cart-price" v-if="item && item.is_salable"> 5604 <span class="price fs-18 lh-26 font-regular">{{$store.getters["formattedPrice"](item.row_price_incl_tax)}}</span> 5605 <span class="old-price fs-18 lh-26 font-regular" v-if="item.base_price_incl_tax < item.price && !isBundle">{{$store.getters["formattedPrice"](item.price)}}</span> 5606 </span> 5607 </div> 5608 <div class="cart-item-action absolute right-1 bottom-0" v-if="this.$store.state.cart.selectedFreeGiftInCart"> 5609 <button class="button-small w-auto secondary px-2" @click="changeIncentive">Tauschen</button> 5610 </div> 5611 </div> 5612 </div> 5613 </article> 5614 </div> 5615</script>
5615 5616
5617<script> 5618 Vue.component("cart-article", { 5619 props : { 5620 article : Object 5621 }, 5622 created() { 5623 if ( this.item.is_salable === false ) { 5624 this.$store.commit('updateErrors',{ 5625 status : "permanent", 5626 error : "Your shopping cart contains unavailable products" 5627 }) 5628 } 5629 }, 5630 mounted() { 5631 lazyLoadInstance.update() 5632 }, 5633 computed: { 5634 5635 quoteItem : function () { 5636 let cartItems = this.$store.state.quote.items ?? [] 5637 let item = cartItems.filter(item => { 5638 return item.item_id === parseInt(this.article.item_id) 5639 }) 5640 5641 return item.length > 0 ? item[0] : {} 5642 }, 5643 5644 isPromo : function () { 5645 return this.article.message === '\nFREE!' 5646 }, 5647 5648 isBundle : function () { 5649 return this.quoteItem?.product_type === 'bundle' || false 5650 }, 5651 5652 item : function () { 5653 return this.quoteItem?.extension_attributes ?? {} 5654 }, 5655 5656 hideForCustomer : function() { 5657 return this.article.hide_for_customer ?? false 5658 }, 5659 5660 hideWeightPrice : function() { 5661 return this.article.hide_weight_price ?? false 5662 }, 5663 5664 content : function() { 5665 return this.item.content ?? '' 5666 } 5667 5668 }, 5669 data: function () { 5670 return { 5671 isActive:false, 5672 customerLoginUrl:'https://www.justspices.de/customer/account/login/referer/aHR0cHM6Ly93d3cuanVzdHNwaWNlcy5kZS9jdXN0b21lci9hY2NvdW50L2luZGV4Lw~~/', 5673 placeholder : '', 5674 loading : '', 5675 showContent : false 5676 } 5677 }, 5678 methods: { 5679 changeIncentive : function () { 5680 this.removeItemFromCart().then(() => { 5681 this.$store.commit('cart/updateForceIncentivePopupOpen', true) 5682 }) 5683 }, 5684 formattedIncentiveProduct : function (productName) { 5685 if(productName) { 5686 return productName.replace('FREE - ',''); 5687 } 5688 return productName; 5689 }, 5690 formattedWeight : function(price) { 5691 return parseFloat(price).toFixed(0) ?? 0 5692 }, 5693 5694 formattedCalculatedWeightPrice : function (item) { 5695 let finalPrice = parseFloat(item.product_price_value).toFixed(2) ?? 0; 5696 let weight = item.weight > 0 ? item.weight : 1; 5697 let calculatedPrice = (finalPrice / weight) * 1000; 5698 5699 return this.$store.getters["formattedPrice"](calculatedPrice); 5700 }, 5701 5702 removeItemFromCart : async function() { 5703 this.loading = 'remove-cart'; 5704 await this.$store.dispatch('cart/removeItemFromCart', { 5705 cartId : this.$store.state.cart.cartId, 5706 token : this.$store.state.customer.customerId, 5707 itemId : this.article.item_id 5708 }).then(() => { 5709 this.loading = ''; 5710 lazyLoadInstance.restoreAll() 5711 lazyLoadInstance.update() 5712 }); 5713 }, 5714 5715 updateCartItem : function(qty = this.article.qty) { 5716 if(qty < this.article.qty) { 5717 this.loading = 'qty-minus'; 5718 }else{ 5719 this.loading = 'qty-plus'; 5720 } 5721 if (qty == 0) { 5722 this.$store.dispatch('cart/removeItemFromCart', { 5723 cartId : this.$store.state.cart.cartId, 5724 token : this.$store.state.customer.customerId, 5725 itemId : this.article.item_id 5726 }).then(() => { 5727 this.loading = ''; 5728 lazyLoadInstance.restoreAll()
5729 lazyLoadInstance.update() 5730 }); 5731 } else { 5732 this.$store.dispatch('cart/updateCartItem', { 5733 cartId : this.$store.state.cart.cartId, 5734 token : this.$store.state.customer.customerId, 5735 itemId : this.article.item_id, 5736 data : this.getCartItemPayload(qty) 5737 }).then(() => { 5738 this.loading = ''; 5739 }).catch(error => { 5740 console.error('An error occurred:', error); 5741 this.loading = ''; 5742 }); 5743 } 5744 }, 5745 5746 getCartItemPayload : function(qty) { 5747 return this.$store.getters["cart/getCartItemPayload"](qty,this.$store.state.cart.cartId) 5748 }, 5749 5750 }, 5751 template: "#cart-article", 5752 }); 5753</script>
5753 5754
5755<script> 5756 Vue.component("cart-items", { 5757 data: function () { 5758 return { 5759 5760 } 5761 }, 5762 created() { 5763 if (typeof lazyLoadVueInstance !== "undefined") { 5764 lazyLoadVueInstance.update() 5765 } 5766 }, 5767 computed: { 5768 5769 articles : function () { 5770 return this.$store.state.quote.items ?? [] 5771 }, 5772 5773 storedArticles : function () { 5774 return this.$store.state.cart.storedCart.items ?? [] 5775 } 5776 5777 }, 5778 methods: { 5779 5780 }, 5781 watch : { 5782 articles: function (newValue, oldValue) { 5783 if (typeof lazyLoadVueInstance !== "undefined") { 5784 lazyLoadVueInstance.restoreAll() 5785 lazyLoadVueInstance.update() 5786 } 5787 } 5788 }, 5789 template: "#cart-items", 5790 }); 5791</script>
5791 5792 5793
5794<script type="text/x-template" id="gfc-totals"> 5795 <div class="gfc-totals mb-1 rounded-10 p-1 border-solid black-border mt-3" v-if="cashPoints || levelPoints"> 5796 <p class="fs-14 lh-18 mb-1" v-if="isLoggedIn">Du sicherst Dir:</p> 5797 <p class="fs-14 lh-18 mb-1" v-else>Würdest Du Dir angemeldet sichern:</p> 5798 <div class="points flex"> 5799 <div class="cash-points flex mr-1" v-if="cashPoints"> 5800 <img class="mr-0.5" src="https://www.justspices.de/media/wysiwyg/relaunch-2024/gfc/cash-points.svg" width="16" height="16"> 5801 <p class="fs-14 lh-18"><span class="fs-14 lh-18">{{cashPoints}}</span> <span class="fs-14 lh-18 underline cursor-pointer" onclick="openCashPointsPopup()">Cash Points</span></p> 5802 </div> 5803 <div class="level-points flex" v-if="levelPoints"> 5804 <picture> 5805 5806 <source type="image/webp" 5807 srcset="https://www.justspices.de/media/opti_image/webp/wysiwyg/relaunch-2024/gfc/level-points.webp"> 5808 5809 <source type="image/png" 5810 srcset="https://www.justspices.de/media/wysiwyg/relaunch-2024/gfc/level-points.png"> 5811 5812 <img class="mr-0.5" src="https://www.justspices.de/media/wysiwyg/relaunch-2024/gfc/level-points.png" width="16" height="16"> </picture> 5813 5814 5815 <p class="fs-14 lh-18"><span class="fs-14 lh-18">{{levelPoints}}</span> <span class="fs-14 lh-18 underline cursor-pointer" onclick="openLevelPointsPopup()">Level Points</span></p> 5816 </div> 5817 </div> 5818 </div> 5819 </script>
5819 5820
5821<script> 5822 Vue.component("gfc-totals", { 5823 data: function () { 5824 return { 5825 } 5826 }, 5827 created() { 5828 5829 }, 5830 computed: { 5831 cartGrandTotal : function() { 5832 return this.$store.state.cart.totals.grand_total ?? 0 5833 }, 5834 isLoggedIn : function() { 5835 return this.$store.state.customer.customerIdentifier !== null 5836 }, 5837 cashPoints : function() { 5838 if (this.$store.state.cart.totals?.total_segments) { 5839 let rewardsTotal = this.$store.state.cart.totals.total_segments.filter(e => e && e.code === 'rewards-total' ) 5840 if(rewardsTotal.length > 0 && rewardsTotal[0].value){ 5841 return rewardsTotal.length > 0 ? rewardsTotal[0].value : 0 5842 } 5843 5844 let rewardsPossible = this.$store.state.cart.totals.total_segments.filter(e => e && e.code === 'rewards-possible' ) 5845 if(rewardsPossible.length > 0 && rewardsPossible[0].value){ 5846 return rewardsPossible.length > 0 ? rewardsPossible[0].value : 0 5847 } 5848 } 5849 return null; 5850 }, 5851 5852 levelPoints : function() { 5853 return Math.ceil(this.cartGrandTotal) * 5 5854 }, 5855 5856 }, 5857 template: "#gfc-totals", 5858 }); 5859</script>
5859 5860
5860<script> 5861 function openCashPointsPopup() { 5862 jQuery(`body`).css(`overflow-y`, `hidden`); 5863 jQuery('.cashpoints-popup').show(); 5864 if(jQuery('.gfc-overlay').length === 0){ 5865 jQuery('.page-header .black-overlay').clone().addClass('gfc-overlay').insertAfter(".levelpoints-popup"); 5866 5867 jQuery('.gfc-overlay').click((event) => { 5868 if(event.target.classList.contains('black-overlay') && jQuery('.cashpoints-popup').is(":visible")){ 5869 closeCashPointsPopup(); 5870 } 5871 5872 if(event.target.classList.contains('black-overlay') && jQuery('.levelpoints-popup').is(":visible")){ 5873 closeLevelPointsPopup(); 5874 } 5875 }); 5876 } 5877 jQuery('.gfc-overlay').addClass(`active`); 5878 jQuery('.gfc-overlay').removeClass(`hidden`); 5879 } 5880 function closeCashPointsPopup() { 5881 jQuery(`body`).css(`overflow-y`, ``); 5882 jQuery('.cashpoints-popup').hide(); 5883 jQuery('.gfc-overlay').removeClass(`active`); 5884 jQuery('.gfc-overlay').addClass(`hidden`); 5885 } 5886 5887 function openLevelPointsPopup() { 5888 jQuery(`body`).css(`overflow-y`, `hidden`); 5889 jQuery('.levelpoints-popup').show(); 5890 if(jQuery('.gfc-overlay').length === 0){ 5891 jQuery('.page-header .black-overlay').clone().addClass('gfc-overlay').insertAfter(".levelpoints-popup"); 5892 5893 jQuery('.gfc-overlay').click((event) => { 5894 if(event.target.classList.contains('black-overlay') && jQuery('.cashpoints-popup').is(":visible")){ 5895 closeCashPointsPopup(); 5896 } 5897 5898 if(event.target.classList.contains('black-overlay') && jQuery('.levelpoints-popup').is(":visible")){ 5899 closeLevelPointsPopup(); 5900 } 5901 }); 5902 } 5903 jQuery('.gfc-overlay').addClass(`active`); 5904 jQuery('.gfc-overlay').removeClass(`hidden`); 5905 } 5906 function closeLevelPointsPopup() { 5907 jQuery(`body`).css(`overflow-y`, ``); 5908 jQuery('.levelpoints-popup').hide(); 5909 jQuery('.gfc-overlay').removeClass(`active`); 5910 jQuery('.gfc-overlay').addClass(`hidden`); 5911 } 5912 </script>
5912 5913
5914<script type="text/x-template" id="totals"> 5915 <div class="cart-summary" :class="countArticles === 0 ? 'visibility-hidden' : ''"> 5916 <div class="cart-totals"> 5917 <div class="flex justify-between items-center mb-1"> 5918 <div> 5919 <strong class="fs-18 lh-26">Zwischensumme</strong> 5920 <span class="fs-14 lh-18">inkl. MwSt.</span> 5921 </div> 5922 <div> 5923 <strong class="price fs-18 lh-26">{{formattedSubtotal}}</strong> 5924 </div> 5925 </div> 5926 <div class="flex justify-between items-center"> 5927 <div> 5928 <span class="fs-16 lh-24">Versand</span> <i class="fa-light fa-circle-info cursor-pointer" @click="toggleShippingPopup"></i> 5929 </div> 5930 <div class="info-popup bg-main-white rounded-25 p-3 absolute bottom-5 hidden" ref="shippingInfoPopup"> 5931 <i class="fa-light fa-xmark absolute top-2 right-2 fs-24 cursor-pointer" @click="toggleShippingPopup"></i> 5932 <div data-content-type="html" data-appearance="default" data-element="main" data-decoded="true"><strong>Die aktuelle Lieferzeit beträgt 3-5 Werktage</strong><br /> 5933<strong>Deutschland:</strong> 5,90â¬, ab 39⬠versandkostenfrei<br /> 5934 <strong>Ãsterreich:</strong> 5,90â¬, ab 49⬠versandkostenfrei<br /> 5935 <strong>Ãbrige EU-Länder, Schweiz und Monaco:</strong> 9,90â¬, ab 49⬠noch 5,90⬠und ab 99⬠versandkostenfrei</div> </div> 5936 <div> 5937 <span class="price fs-14 lh-24 text-right">{{shippingText}}</span> 5938 </div> 5939 </div> 5940 </div> 5941 <div> 5942 <button :disabled="!cartIsValid && cartEmpty" 5943 @click="checkoutLoading = true; trackButton();" 5944 onclick="window.location='https://www.justspices.de/vcheckout/'" 5945 class="button w-full green"> 5946 <span :class="{ 'hidden': checkoutLoading === true }">Sicher zum Checkout</span> 5947 <svg class="spinner" :class="{ 'hidden': checkoutLoading === false }" width="16" height="16" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg"> 5948 <circle class="path" fill="none" stroke-width="6" cx="33" cy="33" r="30"></circle> 5949 </svg> 5950 </button> 5951 </div> 5952 </div> 5953</script>
5953 5954
5955<script> 5956 Vue.component("totals", { 5957 data: function () { 5958 return { 5959 amazonConfig : {"region":"de","code":"amazon_payment_v2","vault_code":"amazon_payment_v2_vault","is_method_available":true,"is_pay_only":true,"is_lwa_enabled":false,"is_guest_checkout_enabled":true,"has_restricted_products":false,"is_multicurrency_enabled":false}, 5960 amazonPayButton: null, 5961 amazonConfigStorage: null, 5962 isAmazonEnabled : true, 5963 checkoutLoading : false 5964 } 5965 }, 5966 created() { 5967 5968 }, 5969 computed: { 5970 cartEmpty : function () { 5971 return this.$store.state.cart.cartIsEmpty || !this.$store.state.cart.cartId 5972 }, 5973 5974 countArticles : function () { 5975 return this.$store.state.cart.storedCart.summary_count ?? 0 5976 }, 5977 5978 cartIsValid : function() { 5979 return this.$store.state.errors.permanent === '' 5980 }, 5981 5982 cartSubtotal : function() { 5983 return this.$store.state.cart.storedCart.subtotalAmount ?? 0 5984 }, 5985 cartGrandTotal : function() { 5986 return this.$store.state.cart.totals.grand_total ?? 0 5987 }, 5988 formattedSubtotal : function() { 5989 return this.$store.getters['formattedPrice'](this.cartSubtotal ?? 0) 5990 }, 5991 5992 carrierTitle : function () { 5993 return 0 in this.$store.state.cart.shippingMethod ? 5994 this.$store.state.cart.shippingMethod[0].carrier_title : 5995 '' 5996 }, 5997 5998 carrierCode : function () { 5999 return 0 in this.$store.state.cart.shippingMethod ? 6000 this.$store.state.cart.shippingMethod[0].carrier_code : 6001 '' 6002 }, 6003 6004 methodCode : function () { 6005 return 0 in this.$store.state.cart.shippingMethod ? 6006 this.$store.state.cart.shippingMethod[0].method_code : 6007 '' 6008 }, 6009 6010 shippingCosts : function () { 6011 if(this.$store.state.quote.extension_attributes?.shipping_assignments.length > 0 && this.$store.state.quote.extension_attributes.shipping_assignments[0].shipping.method) { 6012 return this.$store.state.cart.totals.shipping_incl_tax 6013 } 6014 6015 return null; 6016 }, 6017 6018 formattedShippingCosts : function() { 6019 return this.$store.getters['formattedPrice'](this.shippingCosts ?? 0) 6020 }, 6021 6022 activeGiftCards : function() { 6023 if (this.$store.state.cart.totals?.total_segments) { 6024 let giftCards = this.$store.state.cart.totals.total_segments.filter(e => e && e.code === 'giftcardaccount' ) 6025 return giftCards.length > 0 && giftCards[0].extension_attributes ? 6026 JSON.parse(giftCards[0].extension_attributes?.gift_cards) : 6027 [] 6028 } 6029 }, 6030 6031 acceptedDiscountCode : function() { 6032 return this.$store.state.cart.totals.coupon_code ? this.$store.state.cart.totals.coupon_code : '' 6033 }, 6034 6035 acceptedDiscount : function() { 6036 return this.$store.state.cart.totals.discount_amount !== 0 ? this.$store.state.cart.totals.discount_amount : 0 6037 }, 6038 6039 shippingThreshold : function() { 6040 return this.$store.state.cart.shippingThreshold 6041 }, 6042 6043 freeShippingAt : function () { 6044 return this.$i18n.t("incentives.free_shipping_at",{ 6045 price : this.shippingThreshold 6046 }) ?? '' 6047 }, 6048 6049 shippingText : function () { 6050 if(this.shippingCosts !== null) { 6051 return this.formattedShippingCosts 6052 } 6053 return this.cartSubtotal < this.shippingThreshold ? 6054 "Berechnet im Checkout" : 6055 "Gratis" 6056 } 6057 6058 }, 6059 methods : { 6060 toggleShippingPopup: function() { 6061 let popup = this.$refs['shippingInfoPopup']; 6062 popup.classList.toggle('hidden'); 6063 }, 6064 trackButton: function() { 6065 dataLayer.push({ 6066 'event': 'ga4Event', 6067 'eventName': 'dytest', 6068 'eventCategory': 'cartmodal', 6069 'eventAction': 'click', 6070 'eventLabel': 'Go to checkout' 6071 }); 6072 }, 6073 initializeAmazon:async function() { 6074 if(this.cartSubtotal.toFixed(2) > 0){ 6075 const storageKey = 'amzn-checkout-session-config'; 6076 let browserStorage = hyva.getBrowserStorage(); 6077 let amazonConfigStorage = JSON.parse(browserStorage.getItem(storageKey)) 6078 6079 let cartId = this.$store.state.cart.cartId; 6080 if((amazonConfigStorage && amazonConfigStorage.cart_id !== cartId) || !amazonConfigStorage) { 6081 await fetch(`${BASE_URL}amazon_pay/checkout/config?omit_payloads=true`, { 6082 method: 'GET', 6083 headers: { 6084 'Content-Type': 'application/json', 6085 'X-Requested-With': 'XMLHttpRequest' 6086 } 6087 }) 6088 .then(response => response.json()) 6089 .then( 6090 config => { 6091 if (config) { 6092 const newStorageData = { 6093 cart_id: cartId, 6094 config: config 6095 }; 6096 6097 browserStorage.setItem(storageKey, JSON.stringify(newStorageData)); 6098 this.amazonConfigStorage = JSON.parse(browserStorage.getItem(storageKey)) 6099 } 6100 } 6101 ); 6102 } else { 6103 this.amazonConfigStorage = amazonConfigStorage; 6104 } 6105 6106 var customer = this.$store.state.customer, 6107 canCheckoutWithAmazon = false, 6108 isGuestCheckoutEnabled = this.amazonConfig.is_guest_checkout_enabled, 6109 isLwaEnabled = this.amazonConfig.is_lwa_enabled; 6110 6111 // to use Amazon Pay: customer needs to be logged in, or guest checkout allowed, or Amazon Sign-in enabled 6112 if (customer.customerId || isGuestCheckoutEnabled || isLwaEnabled) { 6113 canCheckoutWithAmazon = true; 6114 } 6115 6116 if (this.isAmazonEnabled && canCheckoutWithAmazon && this.amazonConfigStorage) { 6117 this.drawAmazonButton(); 6118 } else { 6119 if ((customer.customerId || isGuestCheckoutEnabled || isLwaEnabled) && this.amazonConfigStorage) { 6120 this.drawAmazonButton(); 6121 } 6122 } 6123 } 6124 }, 6125 drawAmazonButton : function() { 6126 if(this.amazonConfigStorage.config) { 6127 let buttonContainer = $('#PayWithAmazon-Cart'); 6128 6129 let buttonRoot = $('<div></div>'); 6130 buttonContainer.empty().append(buttonRoot); 6131 6132 let buttonConfig = { 6133 merchantId: this.amazonConfigStorage.config.merchant_id, 6134 publicKeyId: this.amazonConfigStorage.config.public_key_id, 6135 ledgerCurrency: this.amazonConfigStorage.config.currency, 6136 sandbox: this.amazonConfigStorage.config.sandbox, 6137 checkoutLanguage: this.amazonConfigStorage.config.language, 6138 productType: 'PayAndShip', 6139 placement: 'Cart', 6140 buttonColor: this.amazonConfigStorage.config.button_color, 6141 createCheckoutSessionConfig: { 6142 payloadJSON: this.amazonConfigStorage.config.checkout_payload, 6143 signature: this.amazonConfigStorage.config.checkout_signature, 6144 publicKeyId: this.amazonConfigStorage.config.public_key_id, 6145 }, 6146 estimatedOrderAmount: this.getEstimatedAmountForAmazon() 6147 } 6148 buttonRoot.empty().attr('id', 'ui-id-2') 6149 this.amazonPayButton = amazon.Pay.renderButton('#ui-id-2', buttonConfig); 6150 $('#minicart-amazon-pay-button').show(); 6151 } 6152 }, 6153 getEstimatedAmountForAmazon: function() { 6154 let subtotal = this.cartSubtotal.toFixed(2); 6155 let currencyCode = this.amazonConfigStorage.config.currency; 6156 6157 if (currencyCode === 'JPY') { 6158 subtotal = parseFloat(subtotal).toFixed(0); 6159 } 6160 6161 return { 6162 amount: subtotal, 6163 currencyCode: currencyCode 6164 }; 6165 }, 6166 getEstimatedShippingAddress : function() { 6167 if (this.$store.state.customer.customerId && this.$store.state.quote.customer?.addresses.length > 0) { 6168 return { 6169 "address" : { 6170 "country_id" : this.$store.state.quote.customer.addresses[0].country_id ?? this.$store.state.customer.default_address.country_id , 6171 "city" : this.$store.state.quote.customer.addresses[0].city ?? null, 6172 "email" : this.$store.state.quote.customer.email ?? null, 6173 "firstname" : this.$store.state.quote.customer.addresses[0].firstname ?? null, 6174 "lastname" : this.$store.state.quote.customer.addresses[0].lastname ?? null, 6175 "postcode" : this.$store.state.quote.customer.addresses[0].postcode ?? null, 6176 "region_id" : this.$store.state.quote.customer.addresses[0].region_id ?? this.$store.state.customer.default_address.region_id , 6177 "street" : [ 6178 this.$store.state.quote.customer.addresses[0].street[0] ?? null, 6179 this.$store.state.quote.customer.addresses[0].street[1] ?? null 6180 ] 6181 } 6182 } 6183 } 6184 6185 let countryId = this.$store.state.customer.default_address.country_id 6186 return { 6187 "address" : { 6188 "country_id" : countryId, 6189 } 6190 } 6191 }, 6192 6193 getShippingInformation : function() { 6194 let countryId = this.$store.state.customer.default_address.country_id 6195 6196 return { 6197 "addressInformation" : { 6198 "shipping_address" : { 6199 "country_id" : countryId 6200 }, 6201 "shipping_method_code" : this.methodCode, 6202 "shipping_carrier_code" : this.carrierCode 6203 } 6204 } 6205 }, 6206 6207 }, 6208 template: "#totals", 6209 }); 6210</script>
6210 6211<style> 6212 #svg-left-arrow-animation { 6213 pointer-events : all 6214 } 6215 6216 .button_left:hover #svg-left-arrow-animation #svg-left-arrow-animation-animation-line, 6217 #svg-left-arrow-animation:hover #svg-left-arrow-animation-animation-line { 6218 animation-name : svg-left-arrow-animation-animation-line_c_o, svg-left-arrow-animation-animation-line_s_do; 6219 animation-duration : .8s; 6220 animation-fill-mode : forwards; 6221 animation-timing-function : linear; 6222 animation-direction : normal; 6223 animation-iteration-count : 1 6224 } 6225 6226 @keyframes svg-left-arrow-animation-animation-line_c_o { 6227 0%, 37.5% { 6228 opacity : 0 6229 } 6230 100%, 62.5% { 6231 opacity : 1 6232 } 6233 } 6234 6235 @keyframes svg-left-arrow-animation-animation-line_s_do { 6236 0%, 25% { 6237 stroke-dashoffset : 380 6238 } 6239 100%, 62.5% { 6240 stroke-dashoffset : 0 6241 } 6242 } 6243 6244 .button_left:hover #svg-left-arrow-animation #svg-left-arrow-animation-arrow, 6245 #svg-left-arrow-animation:hover #svg-left-arrow-animation-arrow { 6246 animation : .8s linear forwards svg-left-arrow-animation-arrow__to 6247 } 6248 6249 @keyframes svg-left-arrow-animation-arrow__to { 6250 0% { 6251 transform : translate(200.75688px, 181.997249px) 6252 } 6253 100%, 37.5% { 6254 transform : translate(100.954757px, 181.997249px) 6255 } 6256 } 6257 6258 .button_right:hover #svg-right-arrow-animation #svg-right-arrow-animation-animation-line, 6259 #svg-right-arrow-animation:hover #svg-right-arrow-animation-animation-line { 6260 animation-name : svg-right-arrow-animation-animation-line_c_o, svg-right-arrow-animation-animation-line_s_do; 6261 animation-duration : .8s; 6262 animation-fill-mode : forwards; 6263 animation-timing-function : linear; 6264 animation-direction : normal; 6265 animation-iteration-count : 1 6266 } 6267 6268 @keyframes svg-right-arrow-animation-animation-line_c_o { 6269 0%, 37.5% { 6270 opacity : 0 6271 } 6272 100%, 62.5% { 6273 opacity : 1 6274 } 6275 } 6276 6277 @keyframes svg-right-arrow-animation-animation-line_s_do { 6278 0%, 25% { 6279 stroke-dashoffset : 380 6280 } 6281 100%, 62.5% { 6282 stroke-dashoffset : 0 6283 } 6284 } 6285 6286 .button_right:hover #svg-right-arrow-animation #svg-right-arrow-animation-arrow, 6287 #svg-right-arrow-animation:hover #svg-right-arrow-animation-arrow { 6288 animation : .8s linear forwards svg-right-arrow-animation-arrow__to 6289 } 6290 6291 @keyframes svg-right-arrow-animation-arrow__to { 6292 0% { 6293 transform : translate(233.234697px, 182.5px) 6294 } 6295 100%, 37.5% { 6296 transform : translate(333.03682px, 182.5px) 6297 } 6298 } 6299</style>
6300<script type="text/x-template" id="algolia-recommendations"> 6301 <div class="recos algolia relative"> 6302 <div class="algolia-sentinel" v-observe-visibility="{ callback: (isVisible, entry) => visibilityChanged(isVisible, entry) }" /> 6303 <div class="algolia recommendations-container" v-if="products.length > 0"> 6304 <p class="font-recoleta mb-1">Im Trend: Schnell sichern</p> 6305 <div class="box-content"> 6306 <div role="region" aria-label="Produkt Empfehlungen Slider"> 6307 <div class="controls"> 6308 <button class="button_left" ref="js-reco-arrow-left" aria-label="Vorheriges Element"> 6309 <svg aria-hidden="true" id="svg-left-arrow-animation" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="-10 -13 460 390" shape-rendering="geometricPrecision" text-rendering="geometricPrecision"> 6310 <line id="svg-left-arrow-animation-animation-line" x1="400" y1="182" x2="20" y2="182" transform="matrix(-.955605 0 0 1.005502 435.573342-1.004115)" opacity="0" fill="none" stroke="#000" stroke-width="60" stroke-linecap="round" stroke-miterlimit="1" stroke-dashoffset="380" stroke-dasharray="380"/><g id="svg-left-arrow-animation-arrow" transform="translate(200.75688,181.997249)"><polyline points="255.6,345 413.1,182.6 255.6,20" transform="scale(-1,1) translate(-334.350006,-182.5)" fill="none" stroke="#000" stroke-width="60" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/></g> 6311 </svg> 6312 </button> 6313 <button class="button_right" ref="js-reco-arrow-right" aria-label="Nächstes Element"> 6314 <svg aria-hidden="true" id="svg-right-arrow-animation" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="-10 -13 455 390" shape-rendering="geometricPrecision" text-rendering="geometricPrecision"> 6315 <line id="svg-right-arrow-animation-animation-line" x1="400" y1="182" x2="20" y2="182" transform="matrix(.955605 0 0 1.005502 0.8879-1.004115)" opacity="0" fill="none" stroke="#000" stroke-width="60" stroke-linecap="round" stroke-miterlimit="1" stroke-dashoffset="380" stroke-dasharray="380"/><g id="svg-right-arrow-animation-arrow" transform="translate(233.234697,182.5)"><polyline points="255.6,345 413.1,182.6 255.6,20" transform="translate(-334.350006,-182.5)" fill="none" stroke="#000" stroke-width="60" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/></g> 6316 </svg> 6317 </button> 6318 </div> 6319 <div class="javascript-reco-slider" ref="js-reco-slider" role="group" aria-roledescription="carousel" aria-label="Produktempfehlungen"> 6320 <div v-for="(reco,index) in products" :key="index" v-if="reco.price.EUR.default > 0" class="reco-item" ref="js-reco-slider-children" :aria-label="'Produktempfehlung ' + (index + 1) + ' von ' + products.length"> 6321 <div class="cart-item-image-container"> 6322 <a :href="reco.url" 6323 @click="trackClick(reco.name)"> 6324 <img class="lozad" 6325 :data-src="reco.image_url" 6326 :placeholder="placeholder" /> 6327 </a> 6328 </div> 6329 <div class="cart-item-info-container"> 6330 <span class="block mb-1"> 6331 <a :href="reco.url" class="fs-16 lh-24 font-bold product-name text-left">{{ reco.name }}</a> 6332 </span> 6333 <div class="price-container"> 6334 <div v-if="!isCreateYourOwn(reco)" class="price-container text-left"> 6335 <div class="price-box price-final_price font fs-16 lh-24"> 6336 <template v-if="reco.price.EUR.default_max_formated">
6337 <span>{{reco.price.EUR.default_max_formated}}</span> 6338 <template v-if="reco.type_id === 'bundle'"> 6339 <p class="old-price text-main-red fs-12 lh-16 bundle-old-price" 6340 v-if="reco.price.EUR.regular_price_max != reco.price.EUR.default_max && reco.price.EUR.regular_price_max_formated"> 6341 Summe der <br class="tablet:hidden">Einzelpreise {{ reco.price.EUR.regular_price_max_formated }}<span class="old-price percent-difference"> (-{{ calculatePriceDifference(reco) }}%)</span></p> 6342 </template> 6343 <template v-else> 6344 <s v-if="reco.price.EUR.regular_price_max_formated && reco.type_id != 'giftcard' && reco.price.EUR.regular_price_max_formated">{{reco.price.EUR.regular_price_max_formated}}</s> 6345 </template> 6346 </template> 6347 <template v-else> 6348 <span>{{reco.price.EUR.default_formated}}</span> 6349 <template v-if="reco.type_id === 'bundle'"> 6350 <p class="old-price text-main-red fs-12 lh-16 bundle-old-price" v-if="reco.price.EUR.default_original_formated && reco.price.EUR.default_original_formated">Summe der <br class="tablet:hidden">Einzelpreise {{reco.price.EUR.default_original_formated}}</p> 6351 </template> 6352 <template v-else> 6353 <s v-if="reco.price.EUR.default_original_formated && reco.type_id != 'giftcard' && reco.price.EUR.default_original_formated">{{reco.price.EUR.default_original_formated}}</s> 6354 </template> 6355 </template> 6356 </div> 6357 <div class="weight-price"> 6358 <span v-if="reco.weight && reco.weight > 0" class="fs-12 price-per-weight text-main-grey-dark block">{{reco.weight}}g ({{formattedCalculatedWeightPrice(reco)}}/kg)</span> 6359 <span v-else-if="reco.weight_price" class="fs-12 price-per-weight text-main-grey-dark block">{{$store.getters["formattedPrice"](reco.weight_price)}}/kg</span> 6360 </div> 6361 </div> 6362 <div class="add-to-cart-button-container"> 6363 <reco-add-to-cart 6364 :type="reco.type_id" 6365 :url="reco.url" 6366 :sku="reco.sku" 6367 :id="reco.objectID" 6368 v-if="reco && reco.is_saleable === 1 && !isCustomizable(reco)" 6369 ></reco-add-to-cart> 6370 <a :href="reco.url" 6371 @click="trackClick(reco.name)"> 6372 <div v-if="reco && isCustomizable(reco)" class="quick-buy quick-buy flex items-center justify-center"> 6373 <i class="fa-light fa-magnifying-glass fs-24 lh-28"></i> 6374 </div> 6375 </a> 6376 </div> 6377 </div> 6378 </div> 6379 </div> 6380 </div> 6381 </div> 6382 </div> 6383 </div> 6384 </div> 6385</script>
6385 6386 6387
6388<script> 6389 Vue.component("algolia-recommendations", { 6390 data: function () { 6391 return { 6392 placeholder : '', 6393 generatedSlider : false, 6394 recommendations : null 6395 } 6396 }, 6397 updated() { 6398 if(this.generatedSlider === false){ 6399 window.dispatchEvent(new Event('algolia-reco-products-changed')); 6400 lazyLoadInstance.update() 6401 this.slideCarousel() 6402 } 6403 }, 6404 computed: { 6405 6406 products : function() { 6407 if(this.recommendations && this.recommendations.length > 0) { 6408 window.dispatchEvent(new Event('algolia-reco-products-changed')); 6409 } 6410 return this.recommendations ?? [] 6411 }, 6412 6413 quoteIds : function() { 6414 let ids = []; 6415 let cartItems = this.$store.state.quote.items ?? [] 6416 for (let item of cartItems) { 6417 ids.push(item.extension_attributes.js_product_id); 6418 6419 } 6420 6421 return ids; 6422 }, 6423 6424 visibleQuoteIds : function() { 6425 let ids = []; 6426 let cartItems = this.$store.state.quote.items ?? [] 6427 for (let item of cartItems) { 6428 if(item.extension_attributes.is_visible_in_site_visibility === true) { 6429 ids.push(item.extension_attributes.js_product_id); 6430 } 6431 } 6432 6433 return ids; 6434 }, 6435 6436 }, 6437 methods : { 6438 calculatePriceDifference(reco) { 6439 const defaultPrice = parseFloat(reco.price.EUR.default_max) || 0; 6440 const regularPrice = parseFloat(reco.price.EUR.regular_price_max) || 0; 6441 6442 if (regularPrice === 0) return 0; 6443 const difference = ((regularPrice - defaultPrice) / regularPrice) * 100; 6444 return Math.ceil(difference); 6445 }, 6446 isCustomizable: function(item) { 6447 if(item.name.includes('personalisierbar') 6448 || item.name.includes('Personalisierbar') 6449 || item.sku === 'JSB11004156' 6450 || item.type_id === 'giftcard' 6451 || (Array.isArray(item.sku) && item.sku.some(element => element.includes("CYOG"))) 6452 || (Array.isArray(item.sku) && item.sku.some(element => element.includes("CYOB")))){ 6453 return true; 6454 } 6455 return false; 6456 }, 6457 isCreateYourOwn: function(item) { 6458 if((Array.isArray(item.sku) && item.sku.some(element => element.includes("CYOG"))) 6459 || (Array.isArray(item.sku) && item.sku.some(element => element.includes("CYOB")))){ 6460 return true; 6461 } 6462 return false; 6463 }, 6464 formattedCalculatedWeightPrice : function (item) { 6465 let finalPrice = 0; 6466 let weight = item.weight; 6467 if(item.type_id === 'bundle') { 6468 if(item.price.EUR.default_max) { 6469 finalPrice = item.price.EUR.default_max; 6470 }else { 6471 finalPrice = item.price.EUR.default 6472 } 6473 }else { 6474 finalPrice = item.price.EUR.default 6475 } 6476 6477 let calculatedPrice = (finalPrice / weight) * 1000; 6478 6479 return this.$store.getters["formattedPrice"](calculatedPrice); 6480 }, 6481 formattedWeight : function(price) { 6482 return parseFloat(price).toFixed(0) ?? 0 6483 }, 6484 visibilityChanged(isVisible) { 6485 if(isVisible && this.recommendations === null){ 6486 this.getRecommendations(); 6487 } 6488 }, 6489 slideCarousel() { 6490 let recoContainer = this.$refs["js-reco-slider"]; 6491 if (recoContainer) { 6492 let carouselItems = this.$refs["js-reco-slider-children"]; 6493 if (carouselItems.length > 0) { 6494 const buttonLeft = this.$refs['js-reco-arrow-left']; 6495 const buttonRight = this.$refs['js-reco-arrow-right']; 6496 const itemWidth = carouselItems[0].offsetWidth; 6497 const containerWidth = recoContainer.offsetWidth; 6498 const maxScroll = recoContainer.scrollWidth - containerWidth; 6499 let currentPosition = 0; 6500 6501 buttonLeft.addEventListener('click', () => { 6502 if (currentPosition > 0) { 6503 currentPosition -= itemWidth; 6504 currentPosition = Math.max(currentPosition, 0); // Ensure position is not negative 6505 this.scrollToPosition(currentPosition); 6506 updateButtonVisibility(); 6507 } 6508 }); 6509 6510 buttonRight.addEventListener('click', () => { 6511 if (currentPosition < maxScroll) { 6512 currentPosition += itemWidth; 6513 currentPosition = Math.min(currentPosition, maxScroll); // Ensure position does not exceed maxScroll 6514 this.scrollToPosition(currentPosition); 6515 updateButtonVisibility(); 6516 } 6517 }); 6518 6519 function updateButtonVisibility() { 6520 if (currentPosition === 0) { 6521 buttonLeft.style.display = 'none'; 6522 } else { 6523 buttonLeft.style.display = 'block'; 6524 } 6525 6526 if (currentPosition >= maxScroll) { 6527 buttonRight.style.display = 'none'; 6528 } else { 6529 buttonRight.style.display = 'block'; 6530 } 6531 } 6532 6533 this.generatedSlider = true; 6534 updateButtonVisibility(); // Initial button visibility 6535 } 6536 } 6537 }, 6538 scrollToPosition: function(position) { 6539 let recoContainer = this.$refs["js-reco-slider"] 6540 recoContainer.scrollTo({ 6541 left: position, 6542 behavior: 'smooth' 6543 }); 6544 }, 6545 trackClick: function(name){ 6546 window.dataLayer = window.dataLayer || []; 6547 dataLayer.push({ 6548 'event': 'ga4Event', 6549 'eventName': 'recommendation', 6550 'eventAction': 'click', 6551 'eventLabel': name 6552 }); 6553 }, 6554 6555 getRecommendations : async function () { 6556 this.recommendations = []; 6557 const ajaxUrl = "https://www.justspices.de/jsalgolia/reco/get"; 6558 $.ajax({ 6559 url: ajaxUrl, 6560 data: { 6561 "form_key" : hyva.getCookie('form_key'), 6562 "cart_ids" : this.visibleQuoteIds, 6563 "reco_model" : 'trending-items', 6564 }, 6565 type: "GET" 6566 }).done((data) => { 6567 this.recommendations = data;
6568 lazyLoadInstance.update() 6569 }); 6570 }, 6571 6572 sortByKey : function (array, key) { 6573 return array.sort(function(a, b) { 6574 var x = a[key]; var y = b[key]; 6575 return ((x < y) ? 1 : ((x > y) ? -1 : 0)); 6576 }); 6577 }, 6578 6579 }, 6580 template: "#algolia-recommendations", 6581 }); 6582</script>
6582 6583
6584<script type="text/x-template" id="reco-add-to-cart"> 6585 <div class="actions-primary" v-if="type === 'giftcard'"> 6586 <div 6587 @click="window.location=url" 6588 class="quick-buy"> 6589 <i class="fal fa-bag-shopping"></i> 6590 </div> 6591 </div> 6592 <div class="action-btn add-to-cart" title="In den Warenkorb" v-else> 6593 <form 6594 class="reco" 6595 data-role="tocart-form" 6596 method="post" 6597 :action="$store.getters['cart/createAddToCartUrl'](id)" 6598 ref="form" 6599 > 6600 <input type="hidden" name="product" :value="id"> 6601 <input type="hidden" name="uenc" :value="$store.getters['cart/mageEncode']($store.getters['cart/createAddToCartUrl'](id))"> 6602 <input type="hidden" name="currency" class="curreny-symbol" value="EUR"> 6603 <input name="form_key" type="hidden" :value="$store.state.formKey"> 6604 <button class="quick action tocart primary"> 6605 <i class="fa-light fa-bag-shopping"></i> 6606 <div class="spinner hidden"> 6607 <svg aria-hidden="true" focusable="false" role="presentation" class="loading-spinner" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg"> 6608 <circle class="path" fill="none" stroke-width="6" cx="33" cy="33" r="30" style="stroke:white;"></circle> 6609 </svg> 6610 </div> 6611 </button> 6612 </form> 6613 </div> 6614</script>
6614 6615 6616
6617<script> 6618 Vue.component("reco-add-to-cart", { 6619 props: { 6620 type: String, 6621 url: String, 6622 sku: String, 6623 id : Number, 6624 }, 6625 data: function () { 6626 return { 6627 status : 'INACTIVE' 6628 } 6629 }, 6630 mounted() { 6631 if(jQuery('[data-role=tocart-form]').length > 0){ 6632 jQuery('[data-role=tocart-form]').each(function(index) { 6633 bindSubmitAndButton(jQuery(this)); 6634 }); 6635 } 6636 }, 6637 computed: { 6638 buttonAnimationClass : function() { 6639 let url = this.splitUrl(this.url) 6640 // if (this.$store.state.cart.atcErrorUrl.indexOf(url) !== -1) { 6641 // this.status = 'ERROR' 6642 // return 'fal fa-times' 6643 // } 6644 if (this.status === 'SUCCESS') { 6645 return 'fal fa-check' 6646 } 6647 if (this.status === 'LOADING') { 6648 return 'hidden' 6649 } 6650 6651 this.status = 'INACTIVE' 6652 return 'fal fa-bag-shopping' 6653 }, 6654 6655 6656 6657 }, 6658 methods : { 6659 6660 splitUrl : function(url) { 6661 const lastIndex = url.lastIndexOf('/'); 6662 return url.slice(lastIndex + 1); 6663 }, 6664 6665 }, 6666 template: "#reco-add-to-cart", 6667 }); 6668</script>
6668 6669 6670
6671<script> 6672 jQuery(document).ready(function ($) { 6673 Vue.component("cart-modal", { 6674 props: { 6675 visible : Boolean, 6676 besteller : String 6677 }, 6678 data: function () { 6679 return { 6680 storage : {}, 6681 isScrolled: false, 6682 lastScrollTop: 0, 6683 } 6684 }, 6685 computed: { 6686 incentiveSelectionRules : function () { 6687 let incentiveInformation = this.$store.state.cart.incentiveInformation; 6688 if(incentiveInformation && incentiveInformation.triggered_products && Object.keys(incentiveInformation.triggered_products).length > 0) { 6689 this.$store.commit('cart/updateSelectedFreeGiftInCart', true) 6690 return incentiveInformation.triggered_products 6691 } 6692 return []; 6693 }, 6694 6695 isScrollable: function() { 6696 return this.countStoredArticles >= 2 || window.innerHeight < 800 6697 }, 6698 6699 countArticles : function () { 6700 return this.$store.state.quote.items ? this.$store.state.quote.items.length : 0 6701 }, 6702 6703 countStoredArticles : function () { 6704 return this.$store.state.cart.storedCart.summary_count ?? 0 6705 }, 6706 6707 shippingInformationFilled : function() { 6708 return Object.entries(this.$store.state.cart.shippingInformation).length > 0 6709 }, 6710 6711 bestsellerUrl : function() { 6712 return this.besteller 6713 }, 6714 6715 }, 6716 template: "#cart-modal", 6717 }); 6718 }) 6719 6720</script>
6720 6721 6722<style> 6723 .slide-fade-enter-active { 6724 transition: all 0.3s ease-out; 6725 } 6726 6727 .slide-fade-leave-active { 6728 transition: all 0.3s ease-out; 6729 } 6730 6731 .slide-fade-enter-from, 6732 .slide-fade-leave-to { 6733 transform: translateY(100%); 6734 opacity: 0; 6735 } 6736</style> 6737 6738 6739
6740<script> 6741 6742 const lazyLoadVueInstance = new LazyLoad({ 6743 elements_selector: ".vue-lozad", 6744 }); 6745 6746 jQuery(document).ready(function ($) { 6747 6748 const messages = { 6749 de_DE : { 6750 incentives: { 6751 free_shipping: '<strong>{price}</strong> bis zum gratis Versand', 6752 free_spice: '<span class="price">{price}</span> bis zum {incentive}', 6753 free_achived_incentive: '{incentive} erreicht', 6754 free_achived_shipping_incentive: '{incentive} erreicht', 6755 free_shipping_at : 'kostenlos ab {price}â¬' 6756 }, 6757 loyalty : { 6758 rank : 'Du bist Rang {rank}' 6759 } 6760 }, 6761 en_GB : { 6762 incentives: { 6763 free_shipping: '$6.99 shipping <strong>OR</strong> spend {price} more to get <strong>Free Shipping</strong>', 6764 free_spice: '<span class="price">{price}</span> until you get a <b>{incentive}</b>', 6765 free_achived_incentive: '{incentive} achieved', 6766 free_achived_shipping_incentive: '{incentive} achieved!', 6767 free_shipping_at : 'free of charge above £{price}' 6768 }, 6769 loyalty : { 6770 rank : 'You are {rank} Tier' 6771 } 6772 }, 6773 en_US : { 6774 incentives: { 6775 free_shipping: '$6.99 shipping <strong>OR</strong> spend {price} more to get <strong>Free Shipping</strong>', 6776 free_spice: '<span class="price">{price}</span> until you get a <b>{incentive}</b>', 6777 free_achived_incentive: '{incentive} achieved', 6778 free_achived_shipping_incentive: '{incentive} achieved!', 6779 free_shipping_at : 'free of charge above £{price}' 6780 }, 6781 loyalty : { 6782 rank : 'You are {rank} Tier' 6783 } 6784 }, 6785 es_ES : { 6786 incentives: { 6787 free_shipping: '{price} hasta el envÃo gratuito', 6788 free_spice: 'Faltan <span class="price">{price}</span> para un {incentive}', 6789 free_achived_incentive: '{incentive}', 6790 free_achived_shipping_incentive: '¡Tienes gastos de envÃo gratis!', 6791 free_shipping_at : 'gratuito desde {price} â¬' 6792 }, 6793 } 6794 } 6795 6796 const i18n = new VueI18n({ 6797 locale: locale, // set locale 6798 messages, // set locale messages 6799 }) 6800 6801 minicartVue = new Vue({ 6802 i18n, 6803 el: '#slide-in-cart', 6804 store : store, 6805 data() { 6806 return { 6807 visible : false, 6808 mouseIsOver : false, 6809 loaded : true, 6810 storage : JSON.parse(window.localStorage.getItem('mage-cache-storage')), 6811 token : '', 6812 form_key : '', 6813 cart_id : '', 6814 config : { 6815 baseUrl : "https://www.justspices.de/", 6816 locale : '', 6817 shippingThreshold : "39" 6818 }, 6819 cart : { 6820 qty : 0, 6821 subtotals : 0, 6822 subtotalAmount : 0, 6823 items : [], 6824 shippingCosts : '' 6825 }, 6826 bestsellerUrl : "https://www.justspices.de/bestseller-gewuerze.html", 6827 cartOpen : false 6828 } 6829 }, 6830 created() { 6831 window.addEventListener('cart-drawer-toggled', (event) => { 6832 this.cartOpen = event.detail.isOpen 6833 if( this.cartOpen ) { 6834 this.storage = JSON.parse(window.localStorage.getItem('mage-cache-storage')) 6835 if(this.storage) { 6836 this.$store.commit('cart/updateCartId', this.storage.cart?.cartId ?? null) 6837 this.$store.commit('cart/updateStoredCart', this.storage.cart ?? {}) 6838 6839 this.form_key = hyva.getCookie('form_key') 6840 this.$store.commit('customer/updateCustomerIdentifier',this.storage?.customer?.customerId ?? null) 6841 this.$store.commit('customer/updateCustomerId',this.storage?.customer?.
6841signin_token ?? null) 6842 if (this.storage.cart && this.storage.cart.cartId !== '') { 6843 this.loadQuote() 6844 } 6845 6846 this.viewCartDataLayer() 6847 this.loadPromoInformation() 6848 } 6849 } 6850 }) 6851 6852 window.addEventListener('private-content-loaded', (event) => { 6853 if( this.cartOpen ) { 6854 this.storage = event.detail !== null ? event.detail.data : JSON.parse(window.localStorage.getItem('mage-cache-storage')) 6855 this.$store.commit('cart/updateCartId', this.storage.cart?.cartId ?? null) 6856 this.$store.commit('cart/updateStoredCart', this.storage.cart) 6857 6858 this.form_key = hyva.getCookie('form_key') 6859 this.$store.commit('customer/updateCustomerIdentifier',this.storage?.customer?.customerId ?? null) 6860 this.$store.commit('customer/updateCustomerId',this.storage?.customer?.signin_token ?? null) 6861 6862 if (this.storage?.cart) { 6863 this.loadQuote() 6864 } 6865 6866 this.viewCartDataLayer() 6867 this.loadPromoInformation() 6868 } 6869 }) 6870 }, 6871 computed: { 6872 6873 6874 }, 6875 methods : { 6876 loadPromoInformation : function () { 6877 let currentUrl = window.location.href; 6878 let base64currentUrl = btoa(currentUrl); 6879 6880 let request = { 6881 url: this.config.baseUrl + 'amasty_promo/popup/reload/', 6882 data: { 6883 "uenc": btoa(currentUrl) 6884 }, 6885 type: 'GET' 6886 }; 6887 6888 $.ajax(request).done((response) => { 6889 this.$store.commit('cart/updateIncentiveInformation', response.products) 6890 }) 6891 }, 6892 loadQuote : async function() { 6893 let formKey = hyva.getCookie('form_key') 6894 if(formKey) { 6895 this.$store.state.formKey = formKey 6896 } 6897 6898 await this.$store.dispatch('getQuote', { 6899 cartId : this.$store.state.cart.cartId, 6900 token : this.$store.state.customer.customerId 6901 }) 6902 6903 await this.$store.dispatch('cart/getTotals', { 6904 cartId : this.$store.state.cart.cartId, 6905 token : this.$store.state.customer.customerId 6906 }) 6907 }, 6908 6909 viewCartDataLayer : async function() { 6910 window.dataLayer = window.dataLayer || []; 6911 let products = []; 6912 this.storage.cart?.items.forEach(item => { 6913 products.push({ 6914 'name': item.product_name, 6915 'id': item.product_sku, 6916 'price': item.product_price_value, 6917 'brand': 'Just Spices', 6918 'quantity': item.qty 6919 }); 6920 }); 6921 6922 dataLayer.push({ 6923 "pageType": "basket", 6924 'event': 'view_cart', 6925 'eventAction': 'Checkout', 6926 'eventLabel': 'Step 1', 6927 'ecommerce': { 6928 'checkout': { 6929 'actionField': {'step': 1}, 6930 'totals': this.storage.cart.subtotalAmount, 6931 'num_items': this.storage.cart.qty, 6932 'products': products 6933 } 6934 } 6935 }); 6936 }, 6937 6938 getEstimatedShippingAddress : function() { 6939 if (this.$store.state.customer.customerId && this.$store.state.quote.customer?.addresses.length > 0) { 6940 return { 6941 "address" : { 6942 "country_id" : this.$store.state.quote.customer.addresses[0].country_id ?? this.$store.state.customer.default_address.country_id , 6943 "city" : this.$store.state.quote.customer.addresses[0].city ?? null, 6944 "email" : this.$store.state.quote.customer.email ?? null, 6945 "firstname" : this.$store.state.quote.customer.addresses[0].firstname ?? null, 6946 "lastname" : this.$store.state.quote.customer.addresses[0].lastname ?? null, 6947 "postcode" : this.$store.state.quote.customer.addresses[0].postcode ?? null, 6948 "region_id" : this.$store.state.quote.customer.addresses[0].region_id ?? this.$store.state.customer.default_address.region_id , 6949 "street" : [ 6950 this.$store.state.quote.customer.addresses[0].street[0] ?? null, 6951 this.$store.state.quote.customer.addresses[0].street[1] ?? null 6952 ] 6953 } 6954 } 6955 } 6956 6957 let countryId = this.$store.state.customer.default_address.country_id 6958 return { 6959 "address" : { 6960 "country_id" : countryId, 6961 } 6962 } 6963 }, 6964 6965 trackClick: function() { 6966 dataLayer.push({ 6967 'event': 'ga4Event', 6968 'eventName': 'dytest', 6969 'eventCategory': 'cartmodal', 6970 'eventAction': 'click', 6971 'eventLabel': 'Open' 6972 }); 6973 }, 6974 6975 setVisible : function () { 6976 setTimeout(() => { 6977 if (this.visible) { 6978 this.visible = false 6979 } 6980 }, 300) 6981 }, 6982 6983 } 6984 6985 }); 6986 }) 6987</script>
6987 6988 </div> 6989 </div> 6990 </div> 6991 6992</section> 6993 6994 <!--Authentication Pop-Up--> 6995 6996 <!-- Customer Account Drawer --> 6997
6997<script> 6998 'use strict'; 6999 7000 const initCustomerAccountMenuMobile = () => { 7001 return { 7002 mobilePanelActiveId: null, 7003 open: false, 7004 openMenu() { 7005 this.open = true 7006 document.body.style.overflow = 'hidden'; 7007 }, 7008 closeMenu() { 7009 document.body.style.overflow = ''; 7010 this.open = false 7011 this.mobilePanelActiveId = null 7012 } 7013 } 7014 } 7015</script>
7015 7016<nav 7017 x-data="initCustomerAccountMenuMobile()" 7018 @keydown.window.escape="closeMenu()" 7019 class="z-20 laptop:hidden toggle-nav" 7020 aria-label="Customer Account navigation" 7021 role="navigation" 7022 @toggle-customer-nav.window="openMenu($event)" 7023> 7024 <div 7025 x-ref="mobileCustomerAccountLinks" 7026 class="nav-links invisible" 7027 :class="{ 'open': open, 'invisible': !open }" 7028 :aria-hidden="open ? 'false' : 'true'" 7029 role="dialog" 7030 aria-modal="true" 7031 @click="closeMenu()" 7032 > 7033 <div class="navigation-wrapper customer-account"> 7034 <div class="close-button" @click="closeMenu()"> 7035 <i class="fal fa-times"></i> 7036 </div> 7037 <div class="navigation-container" @click.stop> 7038 <ul class="nav items"> 7039<li class="nav item "> 7040 <i class="fal fa-hat-chef"></i> 7041 <a data-role="collapsible" href="https://www.justspices.de/customer/account/">Good Food Club</a> 7042 </li> 7043 7044<li class="nav item "> 7045 <i class="fal fa-box-heart"></i> 7046 <a data-role="collapsible" href="https://www.justspices.de/sales/order/history/">Deine Bestellungen</a> 7047 </li> 7048 7049<li class="nav item "> 7050 <i class="fal fa-star"></i> 7051 <a data-role="collapsible" href="https://www.justspices.de/customeraccountproductrating/index/">Produktbewertungen</a> 7052 </li> 7053 7054<li class="nav item "> 7055 <i class="fal fa-user-edit"></i> 7056 <a data-role="collapsible" href="https://www.justspices.de/customer/account/edit/">Kontoinformation</a> 7057 </li> 7058 7059<li class="nav item "> 7060 <i class="fal fa-map-marker-alt"></i> 7061 <a data-role="collapsible" href="https://www.justspices.de/customer/address/">Deine Adressen</a> 7062 </li> 7063 7064<li class="nav item "> 7065 <i class="fal fa-heart"></i> 7066 <a data-role="collapsible" href="https://www.justspices.de/recipes/account/savedrecipes/">Gespeicherte Rezepte</a> 7067 </li> 7068 7069<li class="nav item logout"> 7070 <a class="button secondary" href="https://www.justspices.de/customer/account/logout/">Abmelden</a> 7071 </li> 7072</ul> </div> 7073 </div> 7074 </div> 7075</nav> 7076</div> 7077<div class="black-overlay hidden"></div> 7078</header><div id="js_autocoupon" class="jsmodal"> 7079 <div class="modal-body-content" data-role="content"> 7080 </div> 7081</div> 7082 7083
7083<script type="text/javascript"> 7084 const autoCouponCookieValue = hyva.getCookie('AutoCoupon'); 7085 7086 if (typeof autoCouponCookieValue !== "undefined" && autoCouponCookieValue !== null) { 7087 const message = autoCouponCookieValue === 'success' 7088 ? 'Der Gutschein wurde Dir direkt in Deinen Warenkorb zugefügt. Wir wünschen Dir viel Spaà beim Shoppen!' 7089 : 'Der Gutschein ist leider abgelaufen'; 7090 7091 hyva.removeCookie('AutoCoupon'); 7092 7093 var popup = jQuery('#js_autocoupon .modal-body-content'); 7094 popup.html(message); 7095 7096 jQuery('#js_autocoupon').show(); 7097 jQuery('#js_autocoupon').addClass('show'); 7098 setTimeout(function () { 7099 jQuery('#js_autocoupon').hide(); 7100 jQuery('#js_autocoupon').removeClass('show'); 7101 }, 5000); 7102 } 7103 </script>
7103 7104<link rel="stylesheet" type="text/css" media="all" href="https://www.justspices.de/static/version1790005904/frontend/Justspices/relaunch/de_DE/JustSpices_Cms/css/modals.css"> 7105<main id="maincontent" class="page-main"><div id="contentarea" tabindex="-1"></div> 7106<div class="page messages">
7106<script> 7107 function initMessages() { 7108 "use strict"; 7109 return { 7110 messages: window.mageMessages || [], 7111 isEmpty() { 7112 return this.messages.reduce( 7113 function (isEmpty, message) { 7114 return isEmpty && message === undefined 7115 }, true 7116 ) 7117 }, 7118 removeMessage(messageIndex, interacted = false) { 7119 if(interacted) { 7120 let messageType = this.messages[messageIndex].type; 7121 window.hyva.setCookie('closedMessage_' + messageType, true); 7122 } 7123 this.messages[messageIndex] = undefined; 7124 }, 7125 addMessages(messages, hideAfter) { 7126 messages.map((message) => { 7127 this.messages = this.messages.concat(message); 7128 if (hideAfter === undefined && message.type === 'success' && window.defaultSuccessMessageTimeout) { 7129 hideAfter = window.defaultSuccessMessageTimeout; 7130 } 7131 if (hideAfter) { 7132 this.setHideTimeOut(this.messages.length -1, hideAfter); 7133 } 7134 }); 7135 }, 7136 setHideTimeOut(messageIndex, hideAfter) { 7137 setTimeout((messageIndex) => { 7138 this.removeMessage(messageIndex); 7139 }, hideAfter, messageIndex); 7140 }, 7141 eventListeners: { 7142 ['@messages-loaded.window'](event) { 7143 this.addMessages(event.detail.messages, event.detail.hideAfter) 7144 }, 7145 ['@private-content-loaded.window'](event) { 7146 const data = event.detail.data; 7147 if ( 7148 data.messages && 7149 data.messages.messages && 7150 data.messages.messages.length 7151 ) { 7152 this.addMessages(data.messages.messages); 7153 } 7154 }, 7155 ['@clear-messages.window']() { 7156 this.messages = []; 7157 } 7158 } 7159 } 7160 } 7161</script>
7161 7162<section id="messages" 7163 x-data="initMessages()" 7164 x-bind="eventListeners" 7165 aria-live="assertive" 7166 role="alert" 7167> 7168 <template x-if="!isEmpty()"> 7169 <div class="w-full"> 7170 <div class="messages"> 7171 <template x-for="(message, index) in messages" :key="index"> 7172 <div class="slide-in-right"> 7173 <template x-if="message"> 7174 <div class="message" :class="message.type" 7175 :ui-id="'message-' + message.type" 7176 > 7177 <i class="fal" :class="message.type"></i> 7178 <span x-html="message.text"></span> 7179 <button 7180 type="button" 7181 class="text-gray-600 hover:text-black" 7182 aria-label="Close message" 7183 @click.prevent="removeMessage(index, true)" 7184 > 7185 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="stroke-current" width="18" height="18" aria-hidden="true"> 7186 <path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"/> 7187</svg> 7188 </button> 7189 </div> 7190 </template> 7191 </div> 7192 </template> 7193 </div> 7194 </div> 7195 </template> 7196</section> 7197</div><div class="columns"><div class="column main"> 7198
7198<script> 7199 if (window.require) { 7200 require(['jquery', 'domReady!'], function($){ 7201 if ($('.mfblogunveil').length) { 7202 require(['Magefan_Blog/js/lib/mfblogunveil'], function(){ 7203 $('.mfblogunveil').mfblogunveil(); 7204 }); 7205 } 7206 }); 7207 } else { 7208 /* e.g. hyva theme */ 7209 document.addEventListener("DOMContentLoaded", function(){ 7210 var items = document.getElementsByClassName('mfblogunveil'); 7211 var el, url; 7212 if (items.length) { 7213 for (var i=0; i<items.length;i++) { 7214 el = items[i]; 7215 url = el.getAttribute('data-original'); 7216 if (!url) { 7217 continue; 7218 } 7219 if ('IMG' == el.tagName) { 7220 el.src = url; 7221 } else { 7222 el.style.backgroundImage = "url('" + url + "')"; 7223 } 7224 } 7225 } 7226 }); 7227 } 7228 </script>
7228 7229 7230<div id="customer-login-container" class="container"><div class="img-container hidden laptop:block laptop:mt-8"> 7231 <picture> 7232 7233 <source type="image/webp" 7234 srcset="https://www.justspices.de/media/opti_image/webp/wysiwyg/relaunch-2024/customer/image-good-food-club.webp"> 7235 7236 <source type="image/png" 7237 srcset="https://www.justspices.de/media/wysiwyg/relaunch-2024/customer/image-good-food-club.png"> 7238 7239 <img src="https://www.justspices.de/media/wysiwyg/relaunch-2024/customer/image-good-food-club.png" 7240 alt="Welcome to the Good Food Club." /> </picture> 7241 7242 7243</div> 7244<div class="login-register-container mt-5 laptop:mt-8"> 7245 <h1 class="fs-48 lh-50 font-recoleta text-center"> 7246 Willkommen im Good Food Club. </h1> 7247 <p class="pt-1 text-center fs-16 lh-24">Schön, dass Du da bist! In Deinem Konto ist alles Wichtige: Ãbersicht der Cash & Level Points, Rabatte & mehr.</p> 7248 <div class="button-container flex align-center justify-center gap-x-1 pt-4"> 7249 <a x-on:click="showRegisterForm()" x-init="showLoginForm()" class="button secondary fs-14 lh-20 content-center register-button"> 7250 Jetzt registrieren </a> 7251 <a x-on:click="showLoginForm()" x-init="showLoginForm()" class="button primary fs-14 lh-20 content-center login-button"> 7252 Jetzt einloggen </a> 7253 </div> 7254 <div class="login-form-container form-container flex align-center justify-center box-border pt-3"> 7255 <div aria-labelledby="block-customer-login-heading" class="block-customer-login-heading"> 7256 <form class="form form-login" 7257 action="https://www.justspices.de/customer/account/loginPost/referer/aHR0cHM6Ly93d3cuanVzdHNwaWNlcy5kZS9jdXN0b21lci9hY2NvdW50L2luZGV4Lw~~/" 7258 method="post" 7259 x-data="initCustomerLoginForm()" 7260 @submit.prevent="submitForm()" 7261 id="customer-login-form"> 7262 <input name="form_key" type="hidden" value="icxHq6W0Magq1fDG" /> <div class="floating-label mb-2 field field-reserved"> 7263 <input name="login[username]" 7264 class="input-text form-control email" 7265 required 7266 value="" 7267 autocomplete="off" 7268 id="email" 7269 type="email" 7270 @blur="onChange" 7271 title="E-Mail" 7272 placeholder=" " 7273 /> 7274 <label class="label inline" for="email">E-Mail</label> 7275 </div> 7276 7277 <div class="floating-label field field-reserved"> 7278 <input name="login[password]" 7279 class="input-text form-control password" 7280 required 7281 type="password" 7282 autocomplete="off" 7283 id="pass" 7284 placeholder=" " 7285 title="Passwort" 7286 /> 7287 <label for="pass" class="label inline">Passwort</label> 7288 </div> 7289 <div class="mt-2 captcha"> 7290 <div id="grecaptcha-container-Customerlogin" class="g-recaptcha"></div>
7291<script> 7292 'use strict'; 7293 7294 (() => { 7295 const containerId = 'grecaptcha\u002Dcontainer\u002DCustomerlogin'; 7296 const initRecaptcha = () => { 7297 grecaptchaV2LoadCallbacks.push(() => { 7298 window.grecaptchaInstanceCustomerlogin = window.grecaptcha.render(containerId, { 7299 sitekey: '6LdDkiYqAAAAAF6nRRfJ1Jy3maxsM3Igx1xMV7k6', 7300 callback: 'googleRecaptchaCallbackCustomerlogin', 7301 size: 'invisible', 7302 badge: 'inline', 7303 }); 7304 }); 7305 }; 7306 7307 // Dynamically rendered forms (eg. via Alpine or Magewire) are rendered post DOMContentLoaded event trigger 7308 if (document.readyState !== 'loading') { 7309 // Wait for 'nextTick' for alpine/magewire to finish re-rendering markup 7310 setTimeout(() => { 7311 initRecaptcha(); 7312 forceLoadRecaptchaScript(document.getElementById(containerId).closest('form')); 7313 }); 7314 } else { 7315 document.addEventListener('DOMContentLoaded', initRecaptcha); 7316 } 7317 })(); 7318</script>
7318 7319 </div> 7320 <div class="pt-2"> 7321 <button type="submit" class="btn btn-primary button primary disabled:opacity-75 w-full" name="send" 7322 disabled data-recaptcha-btn > 7323 Einloggen </button> 7324 </div> 7325 <a class="underline text-secondary pt-2 block text-center fs-14 lh-20" href="https://www.justspices.de/customer/account/forgotpassword/"> 7326 Passwort vergessen? </a> 7327 <div> 7328 <template x-if="displayErrorMessage"> 7329 <p class="text-red flex items-center"> 7330 <template x-for="errorMessage in errorMessages"> 7331 <span x-html="errorMessage"></span> 7332 </template> 7333 </p> 7334 </template> 7335 </div> 7336 </form> 7337 </div> 7338
7338<script> 7339 function initCustomerLoginForm() { 7340 return { 7341 errors: 0, 7342 hasCaptchaToken: 0, 7343 showPassword: false, 7344 displayErrorMessage: false, 7345 errorMessages: [], 7346 setErrorMessages(messages) { 7347 this.errorMessages = [messages] 7348 this.displayErrorMessage = this.errorMessages.length 7349 }, 7350 submitForm() { 7351 // do not rename $form, the variable is the expected name in the recaptcha output 7352 const $form = document.querySelector('#customer-login-form'); 7353 if (!this.hasCaptchaToken) { 7354 window.googleRecaptchaCallbackCustomerlogin = (token) => { 7355 this.hasCaptchaToken = token.length > 0; 7356 this.errors = this.hasCaptchaToken ? 0 : 1; 7357 if (! this.errors) { 7358 (this.submitForm || $form.submit).call(this); 7359 } else { 7360 const error = 'ReCaptcha\u0020validation\u0020failed,\u0020please\u0020try\u0020again'; 7361 if (this.setErrorMessages) { 7362 this.setErrorMessages([error]) 7363 this.displayErrorMessage = true; 7364 } else { 7365 window.dispatchMessages && window.dispatchMessages([{type: "error", text: error}], 5000); 7366 } 7367 } 7368 } 7369 7370 this.errors = 1; 7371 grecaptcha.execute(window.grecaptchaInstanceCustomerlogin); 7372 } 7373 7374 7375 if (this.errors === 0) { 7376 window.dataLayer = window.dataLayer || []; 7377 dataLayer.push({ 7378 "event": "login", 7379 "customer_email": document.querySelector('#email').value 7380 }); 7381 $form.submit(); 7382 } 7383 } 7384 } 7385 } 7386 </script>
7386 7387 </div> 7388 <div class="register-form-container form-container flex align-center justify-center box-border pt-3 hidden"> 7389 <div aria-labelledby="block-customer-login-heading" class="block-customer-login-heading"> 7390 <form class="form create account form-create-account" 7391 action="https://www.justspices.de/customer/account/createpost/" 7392 x-data="Object.assign(hyva.formValidation($el), initForm())" 7393 id="accountcreate" 7394 @submit.prevent="submitForm()" 7395 method="post" id="form-validate" enctype="multipart/form-data" autocomplete="off" 7396 > 7397 <input name="form_key" type="hidden" value="icxHq6W0Magq1fDG" /> <div class=""> 7398 <input type="hidden" name="success_url" value=""> 7399 <input type="hidden" name="error_url" value=""> 7400 <div class="floating-label mb-2 field field-reserved"> 7401 <input type="text" id="firstname" 7402 name="firstname" 7403 value="" 7404 title="Vorname" 7405 placeholder=" " 7406 @blur="onChange" 7407 class="input-text form-control 7408 required-entry" 7409 required> 7410 <label class="label inline" for="firstname"> 7411 Vorname* 7412 </label> 7413</div> 7414<div class="floating-label mb-2 field field-reserved"> 7415 <input type="text" id="lastname" 7416 name="lastname" 7417 value="" 7418 title="Nachname" 7419 placeholder=" " 7420 @blur="onChange" 7421 class="input-text form-control 7422 required-entry" 7423 required> 7424 <label class="label inline" for="lastname"> 7425 Nachname* 7426 </label> 7427</div> 7428 <div class="floating-label mb-2 field field-reserved"> 7429 <input 7430 type="email" 7431 name="email" 7432 autocomplete="email" 7433 id="email_address" 7434 required 7435 value="" 7436 title="E-Mail" 7437 placeholder=" " 7438 class="input-text form-control email" 7439 @blur="onChange" 7440 /> 7441 <label for="email_address" class="label inline">E-Mail</label> 7442 </div> 7443 <div class="floating-label mb-2 field field-reserved"> 7444 <input 7445 type="password" 7446 id="password" 7447 name="password" 7448 title="Passwort" 7449 minlength="8" 7450 class="input-text form-control password" 7451 required 7452 placeholder=" " 7453 data-validate='{"password-strength": {"minCharacterSets": 3}}' 7454 @blur="onChange" 7455 autocomplete="off" 7456 > 7457 <label for="password" class="label">Passwort</label> 7458 </div> 7459 <div class="floating-label mb-2 field field-reserved"> 7460 <input 7461 type="password" 7462 name="password_confirmation" 7463 title="Passwort bestätigen" 7464 id="password-confirmation" 7465 data-validate='{"equalTo": "password"}' 7466 @blur="onChange" 7467 required 7468 placeholder=" " 7469 class="input-text form-control password" 7470 autocomplete="off" 7471 > 7472 <label for="password-confirmation" class="label">Passwort bestätigen</label> 7473 7474 </div> 7475 </div> 7476 <div class="mt-2 captcha mb-2"> 7477 <div id="grecaptcha-container-Customercreate" class="g-recaptcha"></div>
7478<script> 7479 'use strict'; 7480 7481 (() => { 7482 const containerId = 'grecaptcha\u002Dcontainer\u002DCustomercreate'; 7483 const initRecaptcha = () => { 7484 grecaptchaV2LoadCallbacks.push(() => { 7485 window.grecaptchaInstanceCustomercreate = window.grecaptcha.render(containerId, { 7486 sitekey: '6LdDkiYqAAAAAF6nRRfJ1Jy3maxsM3Igx1xMV7k6', 7487 callback: 'googleRecaptchaCallbackCustomercreate', 7488 size: 'invisible', 7489 badge: 'inline', 7490 }); 7491 }); 7492 }; 7493 7494 // Dynamically rendered forms (eg. via Alpine or Magewire) are rendered post DOMContentLoaded event trigger 7495 if (document.readyState !== 'loading') { 7496 // Wait for 'nextTick' for alpine/magewire to finish re-rendering markup 7497 setTimeout(() => { 7498 initRecaptcha(); 7499 forceLoadRecaptchaScript(document.getElementById(containerId).closest('form')); 7500 }); 7501 } else { 7502 document.addEventListener('DOMContentLoaded', initRecaptcha); 7503 } 7504 })(); 7505</script>
7505 7506 </div> 7507 <div class="actions-toolbar"> 7508 <button type="submit" class="btn btn-primary button primary disabled:opacity-75 w-full" 7509 title="Ein Konto erstellen" 7510 disabled data-recaptcha-btn> 7511 Ein Konto erstellen </button> 7512 </div> 7513 <p class="font black fs-11 lh-16 pt-2"> 7514 Mit Deiner Anmeldung akzeptierst Du die <a href="https://www.justspices.de/agb" 7515 class="underline fs-11 lh-16" 7516 title="AGB">AGB</a> von Just Spices und bestätigst, dass Du die <a href="https://www.justspices.de/datenschutz" class="underline fs-11 lh-16" 7517 title="Datenschutzrichtlinien">Datenschutzrichtlinien</a> sowie den Hinweis zum personalisierten E-Mail-Marketing zur Kenntnis genommen hast. </p> 7518 </form> 7519 </div> 7520
7520<script> 7521 function initForm() { 7522 return { 7523 errors: 0, 7524 hasCaptchaToken: 0, 7525 showPassword: false, 7526 showPasswordConfirm: false, 7527 submitForm() { 7528 this.validate() 7529 .then(() => { 7530 // Do not rename $form, the variable is expected to be declared in the recaptcha output 7531 const $form = document.querySelector('#accountcreate'); 7532 if (!this.hasCaptchaToken) { 7533 window.googleRecaptchaCallbackCustomercreate = (token) => { 7534 this.hasCaptchaToken = token.length > 0; 7535 this.errors = this.hasCaptchaToken ? 0 : 1; 7536 if (! this.errors) { 7537 (this.submitForm || $form.submit).call(this); 7538 } else { 7539 const error = 'ReCaptcha\u0020validation\u0020failed,\u0020please\u0020try\u0020again'; 7540 if (this.setErrorMessages) { 7541 this.setErrorMessages([error]) 7542 this.displayErrorMessage = true; 7543 } else { 7544 window.dispatchMessages && window.dispatchMessages([{type: "error", text: error}], 5000); 7545 } 7546 } 7547 } 7548 7549 this.errors = 1; 7550 grecaptcha.execute(window.grecaptchaInstanceCustomercreate); 7551 } 7552 7553 7554 if (this.errors === 0) { 7555 window.dataLayer = window.dataLayer || []; 7556 dataLayer.push({ 7557 "event": "customer_registration", 7558 "customer_email": document.querySelector('#email_address').value 7559 }); 7560 $form.submit(); 7561 } 7562 }) 7563 .catch((invalid) => { 7564 if (invalid.length > 0) { 7565 invalid[0].focus(); 7566 } 7567 }); 7568 } 7569 } 7570 } 7571 </script>
7571 7572</div> 7573 <div class="amsl-login-page"> <div class="social-login-wrapper flex align-center justify-center box-border pt-3 with-labels" 7574 x-data="AmSocialLogin()" 7575 x-init="initializeSocialLogin()" 7576 > 7577 <div class="social-login -labeled-buttons"> 7578 <template x-if="socialErrorMessage"> 7579 <p class="amsl-error -social message error mb-4" x-text="socialErrorMessage"></p> 7580 </template> 7581 <div class="amsl-buttons flex gap-x-3 justify-center" > 7582 <div class="amsl-button-wrapper 7583 with-label"> 7584 <a class="amsl-button -google -rectangular hover-scale" 7585 x-on:click="socialLoginClick($event)" 7586 href="https://www.justspices.de/amsociallogin/social/login/?type=google" 7587 title="Sign in with Google" 7588 role="link" 7589 > 7590 <span class="amsl-social-icon pointer-events-none hover-scale" 7591 role="img" 7592 aria-label="Sign in with Google" 7593 > 7594 </span> 7595 </a> 7596 </div> 7597 <div class="amsl-button-wrapper 7598 with-label"> 7599 <a class="amsl-button -facebook -rectangular hover-scale" 7600 x-on:click="socialLoginClick($event)" 7601 href="https://www.justspices.de/amsociallogin/social/login/?type=facebook" 7602 title="Sign in with Facebook" 7603 role="link" 7604 > 7605 <span class="amsl-social-icon pointer-events-none hover-scale" 7606 role="img" 7607 aria-label="Sign in with Facebook" 7608 > 7609 </span> 7610 </a> 7611 </div> 7612 <div class="amsl-button-wrapper 7613 with-label"> 7614 <a class="amsl-button -apple -rectangular hover-scale" 7615 x-on:click="socialLoginClick($event)" 7616 href="https://www.justspices.de/amsociallogin/social/login/?type=apple" 7617 title="Sign in with Apple" 7618 role="link" 7619 > 7620 <span class="amsl-social-icon pointer-events-none hover-scale" 7621 role="img" 7622 aria-label="Sign in with Apple" 7623 > 7624 </span> 7625 </a> 7626 </div> 7627 </div> 7628 </div> 7629 </div> 7630
7630<script> 7631 function AmSocialLogin() { 7632 return { 7633 socialErrorMessage: '', 7634 isPopupEnabled: '', 7635 7636 initializeSocialLogin() { 7637 this.initContentUpdaters(); 7638 }, 7639 7640 socialLoginClick(event) { 7641 if (this.messageEventListener) { 7642 window.removeEventListener('message', this.messageEventListener); 7643 } 7644 this.messageEventListener = this.onMessageEvent.bind(this); 7645 window.addEventListener('message', this.messageEventListener); 7646 if (this.isPopupEnabled) { 7647 window.open( 7648 event.currentTarget.href + '&isAjax=true', 7649 event.currentTarget.title, 7650 this.getPopupParams() 7651 ); 7652 } else { 7653 window.location.assign(event.currentTarget.href); 7654 } 7655 event.stopPropagation(); 7656 event.preventDefault(); 7657 7658 return false; 7659 }, 7660 7661 onSocialResponse(data) { 7662 const isSuccessfulResult = data.result === 1; 7663 7664 if (isSuccessfulResult) { 7665 window.dispatchEvent( 7666 new CustomEvent( 7667 'amsl-popup-show-notification', 7668 { 7669 detail: data.messages 7670 } 7671 ) 7672 ); 7673 this.processRedirect(); 7674 } else { 7675 this.socialErrorMessage = data.messages.pop(); 7676 setTimeout(() => { 7677 this.socialErrorMessage = ''; 7678 }, 5000); 7679 7680 if (data?.redirect_data?.redirectWithError) { 7681 this.processRedirect(); 7682 } 7683 } 7684 }, 7685 7686 onMessageEvent(event) { 7687 if (event.data['redirect_data']) { 7688 this.onSocialResponse(event.data); 7689 } 7690 }, 7691 7692 getPopupParams(w, h, l, t) { 7693 let screenX = typeof window.screenX !== 'undefined' ? window.screenX : window.screenLeft, 7694 screenY = typeof window.screenY !== 'undefined' ? window.screenY : window.screenTop, 7695 outerWidth = typeof window.outerWidth !== 'undefined' 7696 ? window.outerWidth 7697 : document.body.clientWidth, 7698 outerHeight = typeof window.outerHeight !== 'undefined' 7699 ? window.outerHeight 7700 : (document.body.clientHeight - 22), 7701 width = w ? w : 500, 7702 height = h ? h : 420, 7703 left = l ? l : parseInt(screenX + ((outerWidth - width) / 2), 10), 7704 top = t ? t : parseInt(screenY + ((outerHeight - height) / 2.5), 10); 7705 7706 return ( 7707 'width=' + width + 7708 ',height=' + height + 7709 ',left=' + left + 7710 ',top=' + top 7711 ); 7712 }, 7713 7714 ...AmAuthPopupRedirect(), 7715 ...AmAuthPopupReloadContent() 7716 } 7717 } 7718</script>
7718 7719</div></div>
7720<script type="text/javascript"> 7721 document.addEventListener('DOMContentLoaded', function () { 7722 if (document.body.classList.contains('is-sg-app')) { 7723 showRegisterForm(); 7724 document.querySelector('.button-container')?.classList.add('hidden'); 7725 } 7726 }); 7727 function showLoginForm() { 7728 document.querySelector('.login-form-container').classList.remove('hidden'); 7729 document.querySelector('.register-form-container').classList.add('hidden'); 7730 document.querySelector('a.login-button').classList.remove('secondary'); 7731 document.querySelector('a.login-button').classList.add('primary'); 7732 document.querySelector('a.register-button').classList.add('secondary'); 7733 document.querySelector('a.register-button').classList.remove('primary'); 7734 if (window.grecaptcha) grecaptcha.reset(); 7735 } 7736 7737 function showRegisterForm() { 7738 document.querySelector('.login-form-container').classList.add('hidden'); 7739 document.querySelector('.register-form-container').classList.remove('hidden'); 7740 document.querySelector('a.login-button').classList.add('secondary'); 7741 document.querySelector('a.login-button').classList.remove('primary'); 7742 document.querySelector('a.register-button').classList.remove('secondary'); 7743 document.querySelector('a.register-button').classList.add('primary'); 7744 if (window.grecaptcha) grecaptcha.reset(); 7745 } 7746 7747 7748</script>
7748 7749</div><div data-content-type="html" data-appearance="default" data-element="main" data-decoded="true"><style> 7750 .level-system-inner .cash-points > picture, 7751 .level-system-inner .level-points > picture, 7752 .level-system-inner .cash-points > img, 7753 .level-system-inner .level-points > img{ 7754 width: 62px; 7755 flex-shrink: 0; 7756 } 7757 7758 .level-point-benefit > picture, 7759 .level-point-benefit > img { 7760 flex-shrink: 0; 7761 } 7762 7763 .customer-account-login .link-to-landingpage { 7764 display: inline-flex !important; 7765 } 7766</style></div><div data-content-type="html" data-appearance="default" data-element="main" data-decoded="true"><div class="level-system container relative mb-8"> 7767 <div class="w-full flex flex-col justify-center items-center gap-5"> 7768 <p class="font-recoleta fs-32 lh-40">Cash? Level? Was? Wir erklärenâs.</p> 7769 <div class="flex justify-between flex-col laptop:flex-row items-center gap-5 level-system-inner"> 7770 <div class="flex justify-start items-start gap-2 bg-main-white px-2 py-3 max-tablet:flex-wrap cash-points"> 7771 <img src="https://www.justspices.de/media/wysiwyg/relaunch-2024/gfc/cash-points.svg" alt="Cash Points" /> 7772 <div class="flex flex-col gap-4 justify-start items-start"> 7773 <div> 7774 <p class="font-bold fs-18 lh-26 mb-1">Cash Points</p> 7775 <p class="font-regular fs-18 lh-26"> 7776 Cash Points sind die <strong class="fs-18 lh-26">Währung im Good Food Club</strong>, die Du beim Einkaufen sammelst und gegen Rabatt für künftige Einkäufe tauschen kannst. 7777 </p> 7778 </div> 7779 <div> 7780 <p class="font-bold fs-18 lh-26 mb-1">So sammelst Du Cash Points:</p> 7781 <p class="font-regular fs-18 lh-26 mb-1"> 7782 Du bekommst bei jedem Online-Einkauf Deine Cash Points. 7783 </p> 7784 <div class="flex justify-start items-center gap-1"> 7785 <img src="https://www.justspices.de/media/wysiwyg/relaunch-2024/gfc/cash-points.svg" alt="1 ⬠Einkaufswert = 5 Cash Points" width="25" height="25" /> 7786 <strong class="fs-18 lh-26">Pro 1 ⬠Einkaufswert = 5 Cash Points</strong> 7787 </div> 7788 </div> 7789 <div> 7790 <p class="font-bold fs-18 lh-26 mb-1">Das machst Du mit Cash Points:</p> 7791 <p class="font-regular fs-18 lh-26"> 7792 Du kannst diese gegen Rabatt tauschen: <strong class="fs-18 lh-26">100 Cash Points = 1 ⬠Rabatt</strong> 7793 </p> 7794 </div> 7795 </div> 7796 </div> 7797 <div class="flex justify-start items-start gap-2 bg-main-white px-2 py-3 max-tablet:flex-wrap level-points"> 7798 <picture> 7799 7800 <source type="image/webp" 7801 srcset="https://www.justspices.de/media/opti_image/webp/wysiwyg/relaunch-2024/gfc/level-points.webp"> 7802 7803 <source type="image/png" 7804 srcset="https://www.justspices.de/media/wysiwyg/relaunch-2024/gfc/level-points.png"> 7805 7806 <img src="https://www.justspices.de/media/wysiwyg/relaunch-2024/gfc/level-points.png" alt="" /> </picture> 7807 7808 7809 <div class="flex flex-col gap-4 justify-start items-start"> 7810 <div> 7811 <p class="font-bold fs-18 lh-26 mb-1">Level Points</p> 7812 <p class="font-regular fs-18 lh-26"> 7813 Level Points sind <strong class="fs-18 lh-26">wichtig, um in den Leveln aufzusteigen</strong> und so <strong class="fs-18 lh-26">Vorteile freizuschalten.</strong> Diese sammelst Du durch bestimmte Aktivitäten. 7814 </p> 7815 </div> 7816 <div> 7817 <p class="font-bold fs-18 lh-26 mb-2">So sammelst Du Level Points:</p> 7818 <div class="flex justify-start items-center gap-1 mb-2 level-point-benefit"> 7819 <picture> 7820 7821 <source type="image/webp" 7822 srcset="https://www.justspices.de/media/opti_image/webp/wysiwyg/relaunch-2024/cms/goodfoodclub/benefit-rainbow-cart.webp"> 7823 7824 <source type="image/png" 7825 srcset="https://www.justspices.de/media/wysiwyg/relaunch-2024/cms/goodfoodclub/benefit-rainbow-cart.png"> 7826 7827 <img src="https://www.justspices.de/media/wysiwyg/relaunch-2024/cms/goodfoodclub/benefit-rainbow-cart.png" alt="1⬠= 5 Cash Points" width="40" height="40" /> </picture> 7828 7829 7830 <strong class="fs-18 lh-26">Pro 1 ⬠Einkaufswert = 5 Level Points</strong> 7831 </div> 7832 <div class="flex justify-start items-center gap-1 mb-2 level-point-benefit"> 7833 <picture> 7834 7835 <source type="image/webp" 7836 srcset="https://www.justspices.de/media/opti_image/webp/wysiwyg/relaunch-2024/cms/goodfoodclub/benefit-rainbow-account.webp"> 7837 7838 <source type="image/png" 7839 srcset="https://www.justspices.de/media/wysiwyg/relaunch-2024/cms/goodfoodclub/benefit-rainbow-account.png"> 7840 7841 <img src="https://www.justspices.de/media/wysiwyg/relaunch-2024/cms/goodfoodclub/benefit-rainbow-account.png" alt="50 Level Points für Kundenkonto Daten" width="40" height="40" /> </picture> 7842 7843 7844 <p class="fs-18 lh-26">Daten im <a class="fs-18 lh-26 underline" href="https://www.justspices.de/customer/account/edit/">Kundenkonto</a> angeben: Du bekommst <strong class="fs-18 lh-26">je 50 Level Points</strong></p> 7845 </div> 7846 <div class="flex justify-start items-center gap-1 mb-2 level-point-benefit"> 7847 <picture> 7848 7849 <source type="image/webp" 7850 srcset="https://www.justspices.de/media/opti_image/webp/wysiwyg/relaunch-2024/cms/goodfoodclub/benefit-rainbow-chat.webp"> 7851 7852 <source type="image/png" 7853 srcset="https://www.justspices.de/media/wysiwyg/relaunch-2024/cms/goodfoodclub/benefit-rainbow-chat.png"> 7854 7855 <img src="https://www.justspices.de/media/wysiwyg/relaunch-2024/cms/goodfoodclub/benefit-rainbow-chat.png" alt="100 Level Points für Newsletter Anmeldung" width="40" height="40" /> </picture> 7856 7857 7858 <p class="fs-18 lh-26">Zu unserem <a class="fs-18 lh-26 underline" href="https://www.justspices.de/newsletter">Newsletter</a> anmelden: Du bekommst <strong class="fs-18 lh-26">100 Level Points</strong></p> 7859 </div> 7860 <div class="flex justify-start items-center gap-1 mb-2 level-point-benefit"> 7861 <picture> 7862 7863 <source type="image/webp" 7864 srcset="https://www.justspices.de/media/opti_image/webp/wysiwyg/relaunch-2024/cms/goodfoodclub/benefit-rainbow-chat.webp"> 7865 7866 <source type="image/png" 7867 srcset="https://www.justspices.de/media/wysiwyg/relaunch-2024/cms/goodfoodclub/benefit-rainbow-chat.png"> 7868 7869 <img src="https://www.justspices.de/media/wysiwyg/relaunch-2024/cms/goodfoodclub/benefit-rainbow-chat.png" alt="10 Level Points für Produkt Bewertung" width="40" height="40" /> </picture> 7870 7871 7872 <p class="fs-18 lh-26">Produkt bewerten: Du bekommst <strong class="fs-18 lh-26">10 Level Points</strong></p> 7873 </div> 7874 </div> 7875 </div> 7876 </div> 7877 </div> 7878 <a href="https://www.justspices.de/goodfoodclub" class="button primary link-to-landingpage hidden" style="width: 320px">Mehr erfahren</a> 7879 </div> 7880</div></div><div data-content-type="html" data-appearance="default" data-element="main" data-decoded="true">
7880<script> 7881document.addEventListener('DOMContentLoaded', function() { 7882 let isLoginPage = window.location.pathname.includes('login'); 7883 7884 if (isLoginPage) { 7885 checkForAppLoginPage(); 7886 setTimeout(checkForAppLoginPage, 1000); 7887 setTimeout(checkForAppLoginPage, 2000); 7888 } 7889 7890 function checkForAppLoginPage() { 7891 if (document.body.classList.contains('is-sg-app')) { 7892 document.querySelector('.login-form-container').classList.add('hidden'); 7893 document.querySelector('.register-form-container').classList.remove('hidden'); 7894 document.querySelector('a.login-button').classList.add('secondary'); 7895 document.querySelector('a.login-button').classList.remove('primary'); 7896 document.querySelector('a.register-button').classList.remove('secondary'); 7897 document.querySelector('a.register-button').classList.add('primary'); 7898 if (window.grecaptcha) grecaptcha.reset(); 7899 document.querySelector('.button-container')?.classList.add('hidden'); 7900 } 7901 } 7902}); 7903</script>
7903</div><div data-content-type="html" data-appearance="default" data-element="main" data-decoded="true"><div id="faq" class="container mb-8"> 7904 <div class="faq-headline mb-3"> 7905 <h2 class="font-recoleta text-xl">Du fragst, <span class="font-recoleta text-xl block laptop:inline-block">wir antworten.</span></h2> 7906 </div> 7907 <div class="accordion pb-2 faq-question-wrapper"> 7908 <div class="card" itemscope="" itemprop="mainEntity" itemtype="https://schema.org/Question"> 7909 <div class="card-header active" id="heading-1" data-role="collapsible"> 7910 <h3 class="mb-0"> 7911 <button class="btn btn-link text-s collapsed w-full text-left p-0 pr-3 relative" type="button" data-role="trigger" aria-expanded="true" aria-controls="collapse-1" onclick="toggleFaq(this)"> 7912 <span itemprop="name">Was ist der Good Food Club?</span> 7913 <i class="fa-light fa-chevron-down"></i> 7914 </button> 7915 </h3> 7916 </div> 7917 <div itemscope="" itemprop="acceptedAnswer" itemtype="https://schema.org/Answer" id="collapse-1" class="collapse" aria-labelledby="heading-1" data-role="content" style="display: block;"> 7918 <div itemprop="text" class="card-body text-s">Der Good Food Club ist unser Treueprogramm, in dem Du Punkte sammeln und einlösen, im Level aufsteigen, Dir spezielle Benefits sichern und sparen kannst. 7919 </div> 7920 </div> 7921 </div> 7922 </div> 7923 <div class="accordion pb-2 faq-question-wrapper"> 7924 <div class="card" itemscope="" itemprop="mainEntity" itemtype="https://schema.org/Question"> 7925 <div class="card-header " id="heading-2" data-role="collapsible"> 7926 <h3 class="mb-0"> 7927 <button class="btn btn-link text-s collapsed w-full text-left p-0 pr-3 relative" type="button" data-role="trigger" aria-expanded="true" aria-controls="collapse-2" onclick="toggleFaq(this)"> 7928 <span itemprop="name">Ist der Good Food Club das Treueprogramm? </span> 7929 <i class="fa-light fa-chevron-down"></i> 7930 </button> 7931 </h3> 7932 </div> 7933 <div itemscope="" itemprop="acceptedAnswer" itemtype="https://schema.org/Answer" id="collapse-2" class="collapse" aria-labelledby="heading-2" data-role="content"> 7934 <div itemprop="text" class="card-body text-s">Ja, der Good Food Club ist unser Treueprogramm. Wir haben vier verschiedene Levels, in denen Du je nach gesammelten Punkten aufsteigst und Dir damit verschiedene Benefits sicherst. Die Benefits haben wir überarbeitet, sodass jetzt noch mehr für Dich drin ist. Mit Deinen Käufen und weiteren Aktivitäten sammelst du Level Points und Cash Points. Die Cash Points kannst Du jetzt auch als Direktrabatt einlösen. Alle Infos dazu findest Du <a href="https://www.justspices.de/treueprogramm">hier</a>.</div> 7935 </div> 7936 </div> 7937 </div> 7938 <div class="accordion pb-2 faq-question-wrapper"> 7939 <div class="card" itemscope="" itemprop="mainEntity" itemtype="https://schema.org/Question"> 7940 <div class="card-header " id="heading-3" data-role="collapsible"> 7941 <h3 class="mb-0"> 7942 <button class="btn btn-link text-s collapsed w-full text-left p-0 pr-3 relative" type="button" data-role="trigger" aria-expanded="true" aria-controls="collapse-3" onclick="toggleFaq(this)"> 7943 <span itemprop="name">Wie funktioniert der Good Food Club?</span> 7944 <i class="fa-light fa-chevron-down"></i> 7945 </button> 7946 </h3> 7947 </div> 7948 <div itemscope="" itemprop="acceptedAnswer" itemtype="https://schema.org/Answer" id="collapse-3" class="collapse" aria-labelledby="heading-3" data-role="content"> 7949 <div itemprop="text" class="card-body text-s">Melde Dich mit Deinem Kundenkonto an oder erstelle Dir ein neues Kundenkonto in nur einer Minute. Dann bist Du direkt im Club und profitierst von verschiedenen Vorteilen. Mit jedem Kauf sammelst du Cash Points und Level Points und steigst damit spielend in unseren Levels auf: Vom Spice starter wirst du Flavour friend, vom Flavour friend wirst du Spice pro, vom Spice pro wirst du Taste master. Je nach Level erhältst du Zugang zu spannenden Benefits.</div> 7950 </div> 7951 </div> 7952 </div> 7953 <div class="accordion pb-2 faq-question-wrapper"> 7954 <div class="card" itemscope="" itemprop="mainEntity" itemtype="https://schema.org/Question"> 7955 <div class="card-header " id="heading-4" data-role="collapsible"> 7956 <h3 class="mb-0"> 7957 <button class="btn btn-link text-s collapsed w-full text-left p-0 pr-3 relative" type="button" data-role="trigger" aria-expanded="true" aria-controls="collapse-4" onclick="toggleFaq(this)">
7958 <span itemprop="name">Ist der Good Food Club kostenlos?</span> 7959 <i class="fa-light fa-chevron-down"></i> 7960 </button> 7961 </h3> 7962 </div> 7963 <div itemscope="" itemprop="acceptedAnswer" itemtype="https://schema.org/Answer" id="collapse-4" class="collapse" aria-labelledby="heading-4" data-role="content"> 7964 <div itemprop="text" class="card-body text-s">Ja, unser Good Food Club (Treueprogramm) ist ein kostenloses Angebot für Dich. Wir möchten, dass Du von Deinen Einkäufen profitierst â so macht Shoppen mehr SpaÃ.</div> 7965 </div> 7966 </div> 7967 </div> 7968 <div class="accordion pb-2 faq-question-wrapper"> 7969 <div class="card" itemscope="" itemprop="mainEntity" itemtype="https://schema.org/Question"> 7970 <div class="card-header " id="heading-5" data-role="collapsible"> 7971 <h3 class="mb-0"> 7972 <button class="btn btn-link text-s collapsed w-full text-left p-0 pr-3 relative" type="button" data-role="trigger" aria-expanded="true" aria-controls="collapse-5" onclick="toggleFaq(this)"> 7973 <span itemprop="name">Wo sehe ich mein aktuelles Level?</span> 7974 <i class="fa-light fa-chevron-down"></i> 7975 </button> 7976 </h3> 7977 </div> 7978 <div itemscope="" itemprop="acceptedAnswer" itemtype="https://schema.org/Answer" id="collapse-5" class="collapse" aria-labelledby="heading-5" data-role="content"> 7979 <div itemprop="text" class="card-body text-s">In Deinem Kundenkonto hast Du alle Infos aus dem Good Food Club auf einen Blick: Deine gesammelten Cash Points und Level Points, Dein aktuelles Level und natürlich Deine Benefits. 7980 </div> 7981 </div> 7982 </div> 7983 </div> 7984 <div class="accordion pb-2 faq-question-wrapper"> 7985 <div class="card" itemscope="" itemprop="mainEntity" itemtype="https://schema.org/Question"> 7986 <div class="card-header " id="heading-7" data-role="collapsible"> 7987 <h3 class="mb-0"> 7988 <button class="btn btn-link text-s collapsed w-full text-left p-0 pr-3 relative" type="button" data-role="trigger" aria-expanded="true" aria-controls="collapse-7" onclick="toggleFaq(this)"> 7989 <span itemprop="name">Wie sammle ich Cash Points und Level Points?</span> 7990 <i class="fa-light fa-chevron-down"></i> 7991 </button> 7992 </h3> 7993 </div> 7994 <div itemscope="" itemprop="acceptedAnswer" itemtype="https://schema.org/Answer" id="collapse-7" class="collapse" aria-labelledby="heading-7" data-role="content"> 7995 <div itemprop="text" class="card-body text-s">Ganz automatisch. Bist Du einmal im Good Food Club angemeldet, werden Deine Cash Points und Level Points bei jedem Einkauf automatisch gezählt und angerechnet. Für jeden ausgegebenen Euro kriegst Du 5 Cash Points und 5 Level Points. Dabei sind wir groÃzügig und runden auf: 4,99⬠= 25 Cash Points und 25 Level Points. 7996Zusätzlich belohnen wir die Vervollständigung deines Kundenkontos mit weiteren Level Points.</div> 7997 </div> 7998 </div> 7999 </div> 8000 <div class="accordion pb-2 faq-question-wrapper"> 8001 <div class="card" itemscope="" itemprop="mainEntity" itemtype="https://schema.org/Question"> 8002 <div class="card-header " id="heading-8" data-role="collapsible"> 8003 <h3 class="mb-0"> 8004 <button class="btn btn-link text-s collapsed w-full text-left p-0 pr-3 relative" type="button" data-role="trigger" aria-expanded="true" aria-controls="collapse-8" onclick="toggleFaq(this)"> 8005 <span itemprop="name">Wofür brauche ich Cash Points und Level Points?</span> 8006 <i class="fa-light fa-chevron-down"></i> 8007 </button> 8008 </h3> 8009 </div>
8010 <div itemscope="" itemprop="acceptedAnswer" itemtype="https://schema.org/Answer" id="collapse-8" class="collapse" aria-labelledby="heading-8" data-role="content"> 8011 <div itemprop="text" class="card-body text-s">Deine gesammelten Cash Points und Level Points haben unterschiedliche Vorteile. 8012Die Cash Points kannst du für bare Münze nehmen: Du kannst sie für Folgekäufe als Direktrabatt einsetzen. 100 eingesetzte Cash Points reduzieren Deinen Warenkorb um 1â¬. 8013Die Level Points entscheiden darüber, in welchem Level Du Dich befindest. Pro Level (Spice starter, Flavour friend, Spice pro, Taste master) gibt es auch unterschiedliche Rabatte und Deals. HeiÃt: Mit jedem gesammelten Level Point, kommst Du näher ans nächste Level. 8014</div> 8015 </div> 8016 </div> 8017 </div> 8018 <div class="accordion pb-2 faq-question-wrapper"> 8019 <div class="card" itemscope="" itemprop="mainEntity" itemtype="https://schema.org/Question"> 8020 <div class="card-header " id="heading-9" data-role="collapsible"> 8021 <h3 class="mb-0"> 8022 <button class="btn btn-link text-s collapsed w-full text-left p-0 pr-3 relative" type="button" data-role="trigger" aria-expanded="true" aria-controls="collapse-9" onclick="toggleFaq(this)"> 8023 <span itemprop="name">Kann ich mein Level verlieren?</span> 8024 <i class="fa-light fa-chevron-down"></i> 8025 </button> 8026 </h3> 8027 </div> 8028 <div itemscope="" itemprop="acceptedAnswer" itemtype="https://schema.org/Answer" id="collapse-9" class="collapse" aria-labelledby="heading-9" data-role="content"> 8029 <div itemprop="text" class="card-body text-s">Ja, Du verlierst Dein aktuelles Level, wenn Du innerhalb von 12 Monaten keinen Kauf in unserem Online-Shop tätigst. In diesem Fall wirst Du ein Level zurückgestuft. Auch Deine gesammelten Cash Points verfallen und die Level Points reduzieren sich auf den Schwellwert des unteren Rangs. Die Einlösung von Cash Points hat dabei natürlich keinen Einfluss auf dein Level. Wichtig: Bevor das passiert, schreiben wir Dir eine E-Mail und informieren Dich. Also stell am besten gleich sicher, dass Du zum Newsletter angemeldet bist, damit wir Dich erreichen können.</div> 8030 </div> 8031 </div> 8032 </div> 8033 <div class="accordion pb-2 faq-question-wrapper"> 8034 <div class="card" itemscope="" itemprop="mainEntity" itemtype="https://schema.org/Question"> 8035 <div class="card-header " id="heading-10" data-role="collapsible"> 8036 <h3 class="mb-0"> 8037 <button class="btn btn-link text-s collapsed w-full text-left p-0 pr-3 relative" type="button" data-role="trigger" aria-expanded="true" aria-controls="collapse-10" onclick="toggleFaq(this)"> 8038 <span itemprop="name">Welchen Vorteil habe ich als Good Food Club-Member?</span> 8039 <i class="fa-light fa-chevron-down"></i> 8040 </button> 8041 </h3> 8042 </div> 8043 <div itemscope="" itemprop="acceptedAnswer" itemtype="https://schema.org/Answer" id="collapse-10" class="collapse" aria-labelledby="heading-10" data-role="content"> 8044 <div itemprop="text" class="card-body text-s">So oder so: Du profitierst. Wovon, unterscheidet sich pro Level. Eine Ãbersicht der Vorteile pro Level findest Du <a href="">hier</a>.</div> 8045 </div> 8046 </div> 8047 </div> 8048 <div class="accordion pb-2 faq-question-wrapper"> 8049 <div class="card" itemscope="" itemprop="mainEntity" itemtype="https://schema.org/Question"> 8050 <div class="card-header " id="heading-11" data-role="collapsible"> 8051 <h3 class="mb-0"> 8052 <button class="btn btn-link text-s collapsed w-full text-left p-0 pr-3 relative" type="button" data-role="trigger" aria-expanded="true" aria-controls="collapse-11" onclick="toggleFaq(this)"> 8053 <span itemprop="name">
8053Wie kann ich meine Cash Points einlösen?</span> 8054 <i class="fa-light fa-chevron-down"></i> 8055 </button> 8056 </h3> 8057 </div> 8058 <div itemscope="" itemprop="acceptedAnswer" itemtype="https://schema.org/Answer" id="collapse-11" class="collapse" aria-labelledby="heading-11" data-role="content"> 8059 <div itemprop="text" class="card-body text-s">Wenn Du Dich über Dein Kundenkonto angemeldet hast, werden Deine Cash Points Dir im Bestellprozesses angezeigt. Da kannst Du dann wählen, wie viele Cash Points du einlösen möchtest. Die Einlösung ist in Hunderterschritten möglich. </div> 8060 </div> 8061 </div> 8062 </div> 8063 <div class="accordion pb-2 faq-question-wrapper"> 8064 <div class="card" itemscope="" itemprop="mainEntity" itemtype="https://schema.org/Question"> 8065 <div class="card-header " id="heading-12" data-role="collapsible"> 8066 <h3 class="mb-0"> 8067 <button class="btn btn-link text-s collapsed w-full text-left p-0 pr-3 relative" type="button" data-role="trigger" aria-expanded="true" aria-controls="collapse-12" onclick="toggleFaq(this)"> 8068 <span itemprop="name">Wie erreiche ich ein höheres Level?</span> 8069 <i class="fa-light fa-chevron-down"></i> 8070 </button> 8071 </h3> 8072 </div> 8073 <div itemscope="" itemprop="acceptedAnswer" itemtype="https://schema.org/Answer" id="collapse-12" class="collapse" aria-labelledby="heading-12" data-role="content"> 8074 <div itemprop="text" class="card-body text-s">Anhand Deiner gesammelten Level Points wirst Du einem Level zugeordnet. Du kannst jederzeit aufsteigen, sobald Du die Anzahl der Level Points für das nächste Level gesammelt hast. Dein Level hast Du für 12 Monate gesichert und kannst somit bei jedem Kauf von den Vorteilen profitieren. Kaufst Du innerhalb der 12 Monate erneut, dann sicherst Du Dir Dein Level und Deine Points für weitere 12 Monate. Hast Du durch den neuen Kauf genug Punkte für das nächste Level gesammelt, steigst Du auf. </div> 8075 </div> 8076 </div> 8077 </div> 8078 <div class="accordion pb-2 faq-question-wrapper"> 8079 <div class="card" itemscope="" itemprop="mainEntity" itemtype="https://schema.org/Question"> 8080 <div class="card-header " id="heading-13" data-role="collapsible"> 8081 <h3 class="mb-0"> 8082 <button class="btn btn-link text-s collapsed w-full text-left p-0 pr-3 relative" type="button" data-role="trigger" aria-expanded="true" aria-controls="collapse-13" onclick="toggleFaq(this)"> 8083 <span itemprop="name">Sind meine Level-Vorteile mit anderen Aktionen kombinierbar?</span> 8084 <i class="fa-light fa-chevron-down"></i> 8085 </button> 8086 </h3> 8087 </div> 8088 <div itemscope="" itemprop="acceptedAnswer" itemtype="https://schema.org/Answer" id="collapse-13" class="collapse" aria-labelledby="heading-13" data-role="content"> 8089 <div itemprop="text" class="card-body text-s">Cash Points und Level Points sammelst Du mit jedem Einkauf, auch während Aktionszeiträumen. Grundsätzlich kannst Du deine Cash Points jederzeit einlösen, auch in Kombination mit Rabattcodes. Beim Kauf von Geschenkgutscheinen sammelst Du ebenfalls Cash Points und Level Points, bei der Einlösung derer allerdings nicht. </div> 8090 </div> 8091 </div> 8092 </div> 8093 <div class="accordion pb-2 faq-question-wrapper"> 8094 <div class="card" itemscope="" itemprop="mainEntity" itemtype="https://schema.org/Question"> 8095 <div class="card-header " id="heading-14" data-role="collapsible"> 8096 <h3 class="mb-0"> 8097 <button class="btn btn-link text-s collapsed w-full text-left p-0 pr-3 relative" type="button" data-role="trigger" aria-expanded="true" aria-controls="collapse-14" onclick="toggleFaq(this)">
8098 <span itemprop="name">Kann ich die Cash Points für alle Produkte ausgeben?</span> 8099 <i class="fa-light fa-chevron-down"></i> 8100 </button> 8101 </h3> 8102 </div> 8103 <div itemscope="" itemprop="acceptedAnswer" itemtype="https://schema.org/Answer" id="collapse-14" class="collapse" aria-labelledby="heading-14" data-role="content"> 8104 <div itemprop="text" class="card-body text-s">Grundsätzlich ja, aber es gibt zwei Ausnahmen: Kochbücher und Geschenkgutscheine.</div> 8105 </div> 8106 </div> 8107 </div> 8108</div></div></div></div></main><footer class="page-footer"><div class="footer content"><div data-content-type="html" data-appearance="default" data-element="main" data-decoded="true"><div class="container laptop:flex laptop:flex-wrap laptop:justify-between"> 8109 <div class="newsletter-section mb-5 laptop:order-2"> 8110 </div> 8111 <div class="social-section flex justify-between flex-wrap mb-4 laptop:mb-6 laptop:block laptop:order-1 laptop:self-center"> 8112 <div class="logo laptop:mb-3"> 8113 <svg xmlns="http://www.w3.org/2000/svg" width="53" height="47" viewBox="0 0 53 47" fill="none"> 8114 <path d="M10.4355 11.4145C10.4355 11.2456 10.4312 11.0696 10.4239 10.8921L10.4151 10.6917C10.3904 10.1564 10.3656 9.60249 10.354 9.05573C10.3525 8.97844 10.3525 8.90115 10.3525 8.82529C10.3525 8.5104 10.3642 8.19265 10.3773 7.88492C10.3846 7.71889 10.3904 7.55286 10.3948 7.38683C10.4006 7.1936 10.4035 6.99894 10.4035 6.80572C10.4035 5.81812 10.3307 4.8391 10.1865 3.89873C10.1661 3.76562 10.1472 3.63108 10.1268 3.49797C10.0525 2.99844 9.97682 2.48317 9.86614 1.98365C9.79479 1.6616 9.64916 1.36819 9.38996 1.03183C9.31132 0.928776 9.2254 0.892993 9.12638 0.925913C8.94435 0.984596 8.76815 1.02467 8.61379 1.06046C8.05897 1.18641 7.83325 1.25654 7.83325 1.72172C7.83325 1.76752 7.83616 1.81619 7.84053 1.86914C7.89296 2.44882 7.99635 3.93309 8.02984 4.40828C8.06042 4.85198 8.06333 5.28567 8.06333 5.65065C8.06333 5.84102 8.06333 6.02995 8.06042 6.22031C8.06042 6.40924 8.05897 6.59818 8.05897 6.78711C8.05897 6.9603 8.05897 7.13205 8.06333 7.30524V7.32957C8.06333 7.36679 8.06188 7.404 8.06042 7.44122C8.06042 7.47414 8.05751 7.50563 8.05751 7.53711C8.05751 7.61011 8.06625 7.65877 8.08663 7.70171L8.10411 7.73893V9.03283L8.08227 9.0729C8.06916 9.09724 8.06479 9.12873 8.06479 9.19027V9.27186C8.05314 10.477 8.02256 11.8883 7.87548 13.3196C7.86674 13.4026 7.85073 13.4842 7.83616 13.5629C7.81578 13.6688 7.79684 13.769 7.79684 13.8635C7.79684 13.9093 7.80121 13.9508 7.81141 13.9894C7.85946 14.1798 7.88276 14.3788 7.88276 14.5963C7.88276 14.8869 7.84199 15.1703 7.80121 15.4451C7.58715 16.9179 7.24348 18.1875 6.74836 19.3225C6.28674 20.3817 5.59794 20.9499 4.64703 21.0572C4.59897 21.063 4.55237 21.0701 4.50432 21.0801C4.14463 21.1588 3.84028 20.9985 3.68009 20.6421C3.60146 20.4647 3.517 20.29 3.43108 20.1169C3.16168 19.5601 2.88208 18.9833 2.77723 18.3206C2.75393 18.1717 2.72481 18.0229 2.69568 17.8726C2.6287 17.5276 2.5588 17.1712 2.5588 16.8105V16.7705C2.5588 16.4813 2.48599 16.2495 2.30542 15.9732C2.2428 15.8759 2.17144 15.833 2.07388 15.833C2.02728 15.833 1.9734 15.843 1.91515 15.8644C1.76516 15.9174 1.63118 15.9632 1.51469 16.0019C0.9919 16.1765 0.852102 16.2323 0.780747 16.4527C0.780747 16.4556 0.773466 16.5257 0.773466 16.8463C0.773466 17.0667 0.777835 17.3315 0.780747 17.5605C0.78366 17.7366 0.785116 17.8926 0.785116 17.9899C0.785116 18.0472 0.785116 18.0887 0.782204 18.1059C0.751623 18.4608 0.737061 18.8187 0.737061 19.1665C0.737061 19.719 0.776379 20.2714 0.852102 20.8067C0.996269 21.813 1.41129 22.7476 2.12193 23.6636C2.50929 24.1632 3.05537 24.5024 3.84173 24.7328C4.37908 24.8903 4.91789 24.7242 5.50183 24.2133C5.54552 24.176 5.58629 24.136 5.62852 24.0959C5.7756 23.9556 5.92851 23.8082 6.13966 23.7452C6.57216 23.6164 6.95369 23.3774 7.35706 23.124L7.42114 23.084C7.7517 22.8764 8.04295 22.6045 8.34002 22.228C8.52059 21.999 8.64728 21.7371 8.78271 21.458C8.85261 21.3163 8.92396 21.1689 9.0026 21.0272C9.16424 20.7366 9.25744 20.4203 9.35501 20.0839C9.43073 19.8249 9.50937 19.5572 9.6215 19.3039C9.62004 19.3067 9.6215 19.2982 9.6215 19.2795V19.2209C9.6215 18.9604 9.71469 18.7342 9.78896 18.5524C9.8807 18.3277 9.93313 18.1502 9.95788 17.9742L10.0525 17.3101C10.1283 16.7848 10.204 16.2609 10.2739 15.7342L10.3016 15.5295C10.3554 15.1402 10.4108 14.738 10.4108 14.3444C10.4108 14.2242 10.4049 14.1082 10.3948 13.9966C10.3685 13.7204 10.3554 13.4427 10.3554 13.1707C10.3554 12.8988 10.3685 12.6168 10.3948 12.3477C10.4239 12.0457 10.4384 11.7308 10.4384 11.4131L10.4355 11.4145Z" fill="black"/> 8115 <path d="M21.0655 12.0549C21.0655 11.8831 21.0567 11.7071 21.0494 11.5367L21.0465 11.4838C21.0276 11.0615 20.9548 10.6307 20.8849 10.2142C20.866 10.0983 20.8456 9.98233 20.8281 9.8664C20.6694 8.86162 20.5354 7.8368 20.4058 6.84634L20.3592 6.49281C20.317 6.17506 20.266 5.85158 20.2179 5.53813C20.1422 5.06007 20.065 4.56484 20.017 4.06961C20.0039 3.9365 19.9631 3.78621 19.8947 3.62304C19.8262 3.46273 19.6952 3.39689 19.6282 3.4384C19.369 3.59871 19.1025 3.62877 18.8433 3.65739C18.7675 3.66598 18.6918 3.67457 18.6175 3.68602C18.2375 3.74613 17.9826 3.9823 17.8152 4.426C17.7249 4.66646 17.6972 4.9241 17.6681 5.19604C17.655 5.31341 17.6419 5.42935 17.6244 5.54671C17.521 6.29529 17.47 7.12401 17.47 8.07726C17.47 8.50236 17.4788 8.96324 17.5006 9.52718C17.5225 10.1355 17.572 10.7552 17.6186 11.355C17.655 11.813 17.6914 12.2867 17.7176 12.7533C1
81157.7336 13.041 17.7409 13.333 17.7409 13.6479C17.7409 14.4151 17.6928 15.178 17.6506 15.7576C17.6361 15.9595 17.6288 16.1627 17.6215 16.366C17.6055 16.771 17.5895 17.1904 17.5239 17.604C17.4526 18.0463 17.3987 18.4786 17.3623 18.8879C17.3055 19.5277 17.2618 20.1818 17.221 20.8145L17.2167 20.8903C17.1715 21.5788 16.9385 22.1842 16.7143 22.7696C16.6647 22.8984 16.6152 23.0287 16.5672 23.1575C16.4652 23.4337 16.2395 23.6084 15.9454 23.637C15.3687 23.6942 14.8474 23.335 14.6231 22.7295C14.3595 22.0139 14.1921 21.4485 14.0814 20.8932C13.927 20.1203 13.7931 19.2858 13.662 18.2639C13.5426 17.5224 13.4057 16.532 13.4057 15.51C13.4057 15.4614 13.4057 15.4127 13.4057 15.364C13.4057 15.2996 13.4057 15.2352 13.4057 15.1708C13.4057 14.4065 13.3504 13.6307 13.2965 12.8807C13.2761 12.6073 13.2572 12.334 13.2397 12.0606L13.2135 11.6498C13.1552 10.7495 13.0955 9.81773 13.0955 8.89454C13.0955 8.7786 13.0955 8.66267 13.0985 8.54673C13.0985 8.47373 13.1014 8.40074 13.1043 8.32774C13.1072 8.22755 13.1101 8.12736 13.1101 8.0286C13.1101 7.89835 13.1057 7.79386 13.0926 7.69654C13.0679 7.50474 13.0562 7.2972 13.0562 7.06676C13.0562 6.79195 13.0737 6.51571 13.0912 6.24805C13.1072 5.99615 13.1232 5.73708 13.1247 5.48231V4.78097C13.1247 4.61637 13.0824 4.48039 12.9965 4.36016C12.947 4.29289 12.8975 4.25281 12.864 4.25281C12.8334 4.25281 12.7912 4.28717 12.7475 4.34728C12.3922 4.84538 12.0645 5.30482 12.0645 5.93746C12.0645 5.96609 12.0645 5.99328 12.066 6.02191C12.0704 6.12353 12.0733 6.22515 12.0733 6.32678C12.0733 6.70035 12.0441 7.11256 11.9844 7.62497C11.9582 7.84969 11.9553 8.07154 11.9553 8.31915V8.4079C11.9553 8.54959 11.9553 8.69129 11.948 8.83156C11.8956 10.0367 11.8577 11.229 11.833 12.3798C11.8315 12.4814 11.8301 12.583 11.8301 12.6846C11.8301 13.2715 11.8636 13.8698 11.8942 14.448C11.9247 15.0148 11.9582 15.6002 11.9597 16.1813C11.9626 16.9728 11.9641 17.8688 12.0791 18.7376C12.1082 18.9595 12.1286 19.1842 12.149 19.4018C12.1796 19.7252 12.2102 20.0602 12.2684 20.3793C12.4111 21.1565 12.5815 21.8536 12.7897 22.5091C12.8407 22.6709 12.8888 22.8355 12.9368 23.0015C13.0591 23.4252 13.1873 23.8631 13.3795 24.2396C13.8673 25.2214 14.5416 25.7539 15.3847 25.824C15.4401 25.8283 15.4969 25.8312 15.5536 25.8312C15.9745 25.8312 16.2992 25.6852 16.5468 25.386C16.6982 25.2028 16.8701 25.1098 17.0521 25.1227C17.0841 25.1241 17.1191 25.1255 17.154 25.1255C17.3972 25.1255 17.6506 25.0797 17.92 25.0311C18.0336 25.011 18.1501 24.9896 18.2666 24.9724C18.5127 24.9352 18.7297 24.835 18.9496 24.6546C19.5291 24.1809 19.8248 23.4896 20.0374 22.877C20.3257 22.0468 20.4204 21.1637 20.5121 20.3092C20.5674 19.7982 20.5936 19.2729 20.6213 18.7634C20.6388 18.427 20.6577 18.0807 20.6825 17.7386L20.6912 17.6183C20.7567 16.7467 20.8252 15.8464 20.8252 14.959C20.8252 14.8402 20.8252 14.7214 20.8223 14.6026C20.8194 14.4967 20.8179 14.3893 20.8179 14.2834C20.8179 13.8798 20.8368 13.3473 20.9795 12.8106C21.0363 12.5959 21.064 12.3554 21.064 12.052L21.0655 12.0549Z" fill="black"/> 8116 <path d="M31.7215 20.7797C31.8905 19.7148 31.972 18.6742 31.972 17.5979C31.972 17.4505 31.9705 17.3031 31.9676 17.1556C31.9574 16.6833 31.8963 16.2038 31.8366 15.7415C31.7958 15.418 31.7521 15.0831 31.7274 14.7496C31.6545 13.8135 31.3327 13.0163 30.7706 12.3779C30.6497 12.2405 30.5274 12.1046 30.4051 11.9686C30.0629 11.5893 29.7105 11.1957 29.3916 10.7792C29.2984 10.6589 29.1717 10.553 28.9911 10.4485C28.7654 10.3068 28.5819 10.1294 28.4042 9.95759L28.3344 9.89032C28.2193 9.78011 28.1043 9.66704 27.9907 9.5554C27.5626 9.13316 27.1199 8.69661 26.6116 8.38745C26.1646 8.1155 25.8588 7.66178 25.6403 7.29823C25.4539 6.9862 25.3564 6.5382 25.3564 6.00003C25.3564 5.04392 25.6622 3.96185 26.0539 3.53533C26.2825 3.28628 26.4864 3.05727 26.6553 2.79963L26.6932 2.74238L26.7558 2.73236C26.7704 2.7295 26.7878 2.72377 26.8082 2.68942L26.8432 2.63074L26.9058 2.61786C27.5509 2.47616 28.1756 2.91557 28.5805 3.78294C28.7042 4.04916 28.7741 4.33829 28.8353 4.61167C28.8673 4.75623 28.8833 4.88075 28.8833 4.99526C28.8833 5.16845 28.8469 5.28581 28.8149 5.38887C28.7872 5.47618 28.7639 5.55204 28.7639 5.66511C28.7639 5.75385 28.7785 5.8569 28.8076 5.98C28.8906 6.3321 29.0552 6.66845 29.31 7.01054C29.4891 7.25099 29.709 7.32972 30.009 7.26388C30.1546 7.23239 30.3119 7.20949 30.4794 7.18659C31.1507 7.09212 31.6312 6.99479 31.6895 6.59116C31.6982 6.52962 31.7026 6.45662 31.7026 6.3736C31.7026 6.17465 31.7099 6.0215 31.7157 5.89984C31.7201 5.8111 31.723 5.73381 31.723 5.65795C31.723 5.52627 31.7128 5.39173 31.6618 5.17131C31.6575 5.15127 31.6545 5.1298 31.6545 5.10547C31.6545 5.08113 31.6575 5.0568 31.6618 5.0339C31.6633 4.97522 31.656 4.96377 31.6414 4.94946L31.5905 4.90365L31.5657 4.54583C31.4609 3.81443 31.241 3.04296 30.8944 2.19992C30.8653 2.12978 30.8551 2.10974 30.8391 2.10259L30.8056 2.08971L30.7808 2.06108C30.0469 1.22949 28.2295 0 26.6611 0C26.102 0 25.6127 0.154581 25.2078 0.459449C24.6079 0.911742 24.0429 1.53722 23.5288 2.32015C23.0279 3.0816 22.6915 4.56587 22.6915 6.01435C22.6915 6.657 22.7585 7.25529 22.8866 7.74623C23.3643 9.5783 24.8452 10.5416 26.1529 11.3918C27.28 12.1246 28.3445 12.8173 28.579 13.9538C28.6314 14.2057 28.7013 14.4605 28.7683 14.7067C28.828 14.9257 28.8906 15.1518 28.9416 15.3794C29.0727 15.9648 29.1935 16.5974 29.1935 17.2429C29.1935 17.4906 29.176 17.7239 29.1411 17.9529C29.0552 18.5755 28.9547 19.2081 28.8557 19.8193C28.8091 20.1084 28.7639 20.3975 28.7188 20.6867C28.6358 21.2234 27.7227 22.1337 27.1373 22.1337C27.0703 22.1337 27.0077 22.1223 26.9509 22.1008C26.5694 21.9534 26.2782 21.7229 26.0423 21.5168C25.4146 20.9686 25.1219 20.2158 25.1219 19.1466C25.1219 18.8131 25.1525 18.4452 25.2107 18.0502C25.2355 17.8684 25.3593 16.9152 25.3593 16.3441C25.3593 16.1823 25.3491 16.095 25.3404 16.0507C25.3025 15.8574 24.9836 15.7501 24.4433 15.7501C24.1171 15.7501 23.7735 15.7873 23.4982 15.8159C23.4123 15.8245 23.3351 15.8331 23.2667 15.8388C23.1968 15.846 23.1196 15.8717 23.0526 15.909C22.6725 16.1251 22.409 16.367 22.2226 16.669C22.0711 16.9137 21.9969 17.2787 21.9969 17.784C21.9969 17.9157 22.0012 18.0345 22.0056 18.1289C22.0085 18.1962 22.01 18.2506 22.01 18.2921V18.3264C22.0027 18.5039 21.9925 18.6599 21.9837 18.8045C21.9706 19.0092 21.9604 19.1852 21.9
8116604 19.3656C21.9604 19.7993 22.0216 20.2601 22.3216 21.2105C22.5313 21.8761 22.7701 22.6304 23.2521 23.1872C24.4404 24.5569 25.5879 25.1423 27.0907 25.1423C27.1825 25.1423 27.2728 25.1409 27.3645 25.1366C28.4756 25.0908 31.1216 24.5741 31.7259 20.7811L31.7215 20.7797Z" fill="black"/> 8117 <path d="M41.9858 6.11138C42.213 6.02263 42.4693 5.92101 42.9557 5.84515L43.1188 5.82082C43.3081 5.79219 43.4988 5.76357 43.6882 5.72779C43.8862 5.69057 43.9386 5.58036 43.9605 5.50021C44.0245 5.26404 44.0566 5.02931 44.0566 4.80173C44.0566 4.55841 44.0187 4.33369 43.9459 4.13188C43.8381 3.83846 43.809 3.51213 43.7814 3.19581C43.7377 2.70487 43.7013 2.27977 43.3969 2.07939C43.2265 1.96632 42.411 1.8103 41.9902 1.8103C41.8897 1.8103 41.8606 1.82032 41.8591 1.82032C41.297 2.04504 40.8267 2.17815 40.3796 2.23826C40.2136 2.26116 40.0447 2.28263 39.8743 2.3041C39.286 2.37996 38.6787 2.45868 38.0526 2.59036C38.022 2.59609 37.9914 2.60181 37.9608 2.60611C37.8516 2.62042 37.8181 2.63187 37.7963 2.67481L37.7424 2.77643L37.6361 2.76212C37.4701 2.73922 37.3099 2.77214 37.1337 2.80649C37.0842 2.81651 37.0347 2.82653 36.9851 2.83512C36.7201 2.88521 36.5177 2.90668 36.3313 2.90668C35.9643 2.90668 35.6498 2.81508 35.3702 2.62615C35.3323 2.60325 35.2872 2.59036 35.2377 2.59036C35.2144 2.59036 35.1911 2.59323 35.1663 2.59895C34.8911 2.66336 34.6159 2.67767 34.3479 2.69199C34.1441 2.70201 33.9518 2.71203 33.7582 2.74208C33.7174 2.74781 33.6766 2.75496 33.6358 2.76069C33.263 2.81365 33.0286 2.86231 32.9237 3.18006C32.8757 3.32462 32.8072 3.45774 32.7402 3.58512C32.6354 3.7855 32.5364 3.97587 32.5364 4.1877C32.5364 4.23064 32.5407 4.27215 32.548 4.31509C32.5611 4.38665 32.564 4.45392 32.5684 4.51976C32.5684 4.54982 32.5713 4.57845 32.5742 4.60707C32.5932 4.82893 32.6893 4.96919 32.8684 5.03647L32.9732 5.07654C33.2426 5.1796 33.5193 5.28408 33.7931 5.32988C34.6872 5.47874 35.5624 5.74639 36.3983 6.12569C36.707 6.26596 36.7827 6.39621 36.7827 6.79411V6.82846C36.7827 7.16911 36.7798 7.51119 36.7755 7.85184L36.7711 8.31129L36.7478 8.52456C36.742 8.54173 36.7332 8.55891 36.7259 8.57752C36.7216 8.5861 36.7172 8.59612 36.7143 8.60471C36.6837 9.3676 36.6546 10.1477 36.6255 10.9263C36.6255 10.9621 36.6284 10.9893 36.6327 11.0165C36.7332 11.5146 36.7492 12.0069 36.7609 12.5537C36.7696 13.0518 36.8002 13.557 36.8293 14.0465C36.8555 14.4845 36.8818 14.9368 36.8949 15.3848C36.9342 16.6486 36.9531 17.7966 36.9531 18.8958V19.1992C36.9531 19.3309 36.9531 19.4612 36.956 19.5928C36.956 19.726 36.9589 19.8591 36.9589 19.9922C36.9589 20.2899 36.9531 20.6449 36.9109 21.0098C36.8788 21.2846 36.8381 21.5609 36.8002 21.8285C36.7216 22.3739 36.6386 22.9378 36.624 23.496C36.6153 23.8581 36.5978 24.1845 36.4653 24.5008C36.458 24.5194 36.4536 24.5394 36.4536 24.5595C36.4536 24.5996 36.4711 24.6382 36.5002 24.6683C36.9152 25.0533 37.2123 25.0461 37.5429 24.6053L37.5793 24.5566C37.7191 24.3705 37.8618 24.1773 38.0628 24.0256C38.1778 23.9383 38.2826 23.851 38.2826 23.7608C38.2826 23.7336 38.2812 23.7093 38.2812 23.6849C38.2812 23.4388 38.338 23.2169 38.3933 23.0036C38.421 22.8949 38.4487 22.7918 38.4661 22.6859C38.5768 22.0647 38.619 21.4192 38.6598 20.7951C38.6685 20.6592 38.6773 20.5218 38.6875 20.3858L38.6904 20.3615C38.8331 19.6286 38.8462 18.86 38.8608 18.1172C38.8637 17.9683 38.8666 17.8195 38.8695 17.672C38.8914 17.3385 38.935 17.0165 38.9787 16.7045C39.0297 16.3366 39.0821 15.9588 39.0923 15.5852V15.5265C39.0952 15.4735 39.0967 15.422 39.0967 15.3705C39.0967 15.1944 39.0777 15.0613 38.9816 14.9411L38.9467 14.8982L38.9409 14.8409C38.8972 14.4029 38.8972 13.9621 38.8957 13.5341C38.8957 13.2221 38.8943 12.8986 38.8768 12.5837C38.8724 12.4979 38.871 12.4134 38.871 12.3275C38.871 12.0985 38.8855 11.8681 38.9001 11.6448C38.9132 11.4272 38.9278 11.2025 38.9278 10.9835C38.9278 10.7187 38.9074 10.4983 38.8622 10.2908C38.8549 10.2622 38.8549 10.2335 38.8549 10.2164C38.8549 10.2035 38.8549 10.1906 38.8549 10.1791V10.1591L38.8477 9.27886C38.8418 8.59183 38.8346 7.9048 38.8287 7.21777V7.17054C38.8287 6.64096 38.9554 6.4921 39.4462 6.45059C39.9282 6.40622 40.5005 6.35613 41.083 6.31605C41.5388 6.28456 41.747 6.20298 41.9887 6.10708L41.9858 6.11138Z" fill="black"/> 8118 <path d="M12.4873 39.1475C12.4873 39.1818 12.4873 39.2176 12.4902 39.2577C12.5179 39.8474 12.5659 40.4371 12.5805 41.0254C12.5936 41.6036 12.7421 42.1404 12.8586 42.6928C12.9911 43.3155 13.1571 43.9381 13.1571 44.585C13.1571 44.6351 13.1571 44.6838 13.1542 44.7339C13.1542 44.7539 13.1542 44.774 13.1542 44.7954C13.1542 44.9429 13.1775 45.086 13.2358 45.2234C13.2707 45.3064 13.2867 45.3837 13.2867 45.4538C13.2867 45.7115 13.0756 45.8732 12.8615 45.929C12.7669 45.9534 12.6635 45.9634
811812.5557 45.9634C11.9834 45.9634 11.2844 45.6571 11.0354 45.3193C10.7646 44.9529 10.6204 44.5435 10.4602 44.137C10.45 44.1113 10.4456 44.0812 10.4456 44.0511C10.4456 44.024 10.45 43.9982 10.4573 43.9739C10.5563 43.649 10.5534 43.314 10.5811 42.9805C10.6102 42.6456 10.6175 42.3121 10.6306 41.9786C10.5927 41.4133 10.6248 40.8436 10.5418 40.2811C10.533 40.221 10.5301 40.1609 10.5301 40.1022C10.5301 39.939 10.5549 39.7773 10.5549 39.6141C10.5549 38.4748 10.552 37.334 10.584 36.1961C10.6233 34.7791 10.683 33.3636 10.7675 31.9495C10.7908 31.5558 10.8403 31.1608 10.8403 30.7658V30.7157C10.8403 30.7157 10.8403 30.7057 10.8403 30.7014C10.8403 30.4924 10.8927 30.2906 10.9379 30.0873C10.9539 30.0143 10.9626 29.9528 10.9626 29.8984C10.9626 29.7309 10.8796 29.6322 10.6699 29.5077C10.5592 29.4418 10.45 29.3745 10.3423 29.3058C10.1952 29.2114 10.1311 29.0926 10.1311 28.9451C10.1311 28.9022 10.1369 28.8564 10.1471 28.8092C10.2549 28.3082 10.5753 27.9962 11.1228 27.886C11.6427 27.7815 12.1494 27.7242 12.6431 27.7242C13.0188 27.7242 13.3872 27.7572 13.7469 27.8287C14.1226 27.9032 14.4867 28.0449 14.8566 28.1551C15.0517 28.2138 15.2468 28.2724 15.4434 28.3283C15.6939 28.4013 15.8978 28.5687 16.122 28.6961C16.7001 29.0038 17.22 29.4103 17.7341 29.8254C17.9263 29.98 18.0952 30.1589 18.2073 30.3679C18.6151 31.1279 18.9762 31.9022 18.9762 32.7682C18.9762 32.8483 18.9733 32.9299 18.9675 33.0129C18.9442 33.3049 18.9005 33.5883 18.7607 33.8531C18.5597 34.2338 18.4928 34.6604 18.2918 35.0411C18.0836 35.4361 17.8375 35.7911 17.4588 36.0702C17.1792 36.2763 16.9448 36.5354 16.6943 36.7744C16.4336 37.0249 16.1672 37.2367 15.8439 37.3555C15.4623 37.4958 15.1158 37.7233 14.7153 37.8207C14.574 37.855 14.4415 37.9481 14.3178 38.0339C13.8853 38.3302 13.4324 38.5664 12.9169 38.6752C12.5834 38.7453 12.4975 38.8484 12.4975 39.1475H12.4873ZM12.6431 37.0979C12.6984 37.0979 12.7698 37.075 12.8601 37.0335C13.5634 36.7 14.2304 36.3021 14.8449 35.8111C15.1274 35.585 15.3109 35.2901 15.3823 34.9266C15.4056 34.8035 15.4449 34.6904 15.4988 34.5816C15.6458 34.2839 15.7609 33.9719 15.8686 33.657C16.0215 33.209 16.1133 32.7653 16.1133 32.3116C16.1133 32.0024 16.071 31.689 15.9779 31.3683C15.8177 30.8187 15.6007 30.3793 15.0531 30.1875C15.0022 30.1703 14.957 30.1389 14.9075 30.1174C14.4503 29.9084 13.9755 29.8454 13.4921 29.8454C13.3232 29.8454 13.1542 29.8526 12.9853 29.8655C12.6649 29.8869 12.579 29.9814 12.5747 30.3192C12.5659 30.8431 12.5746 31.3683 12.547 31.8922C12.5251 32.3144 12.4975 32.7367 12.4887 33.1603C12.4815 33.4852 12.4538 33.8102 12.4538 34.1365C12.4538 34.3226 12.4625 34.5101 12.4887 34.6976C12.4946 34.7491 12.4975 34.8006 12.4975 34.8521C12.4975 35.0497 12.4611 35.2486 12.4611 35.4447C12.4611 35.5148 12.4654 35.585 12.4785 35.6551C12.4698 35.9356 12.445 36.209 12.445 36.481C12.445 36.5783 12.448 36.6742 12.4567 36.7715C12.4756 36.9977 12.5251 37.1022 12.6445 37.1022L12.6431 37.0979Z" fill="black"/> 8119 <path d="M31.5567 27.0973C31.5567 27.2662 31.478 27.4165 31.3513 27.5467C31.2421 27.6612 31.1315 27.7786 30.9917 27.8487C30.6451 28.019 30.3495 28.2681 30.0378 28.4971C29.5005 28.9065 28.9413 29.1941 28.3996 29.5133C28.0821 29.7008 27.8491 29.9556 27.6642 30.3091C27.054 31.4828 26.6638 32.7438 26.4992 34.1021C26.4934 34.1493 26.473 34.1937 26.4599 34.2395C26.438 34.4728 26.4031 34.7047 26.3958 34.938C26.3929 35.0654 26.39 35.1928 26.39 35.3201C26.39 36.2047 26.4919 37.0706 26.8079 37.8965C26.8269 37.9451 26.8618 37.9681 26.8807 38.011C26.9652 38.1527 27.0482 38.2958 27.1327 38.439C27.2797 38.688 27.4501 38.907 27.6991 39.0229C27.9045 39.1188 28.053 39.302 28.1841 39.4981C28.4156 39.8416 28.7432 40.0349 29.0476 40.2581C29.1656 40.344 29.301 40.3655 29.4408 40.3655C29.5646 40.3655 29.6927 40.3497 29.8194 40.3483C29.9446 40.3483 30.0699 40.3383 30.1936 40.3383C30.3174 40.3383 30.4383 40.3469 30.5606 40.3784C30.6043 40.3898 30.6538 40.3955 30.7019 40.3955C30.7499 40.3955 30.7994 40.3898 30.8431 40.3769C30.948 40.3455 31.047 40.3311 31.1387 40.3311C31.5275 40.3311 31.8173 40.5859 32.0824 40.8979C32.212 41.0497 32.3183 41.21 32.3183 41.3975C32.3183 41.4819 32.2964 41.5721 32.2455 41.6694C32.2236 41.7095 32.2163 41.7553 32.2163 41.8025C32.2163 41.8426 32.2222 41.8855 32.2294 41.9256C32.2411 41.99 32.2469 42.0516 32.2469 42.1145C32.2469 42.3622 32.161 42.5969 32.0853 42.8288C32.0023 43.0807 31.813 43.241 31.5727 43.3054C31.2276 43.3984 30.881 43.4743 30.5592 43.6446C30.4907 43.6818 30.415 43.6961 30.3393 43.6961C30.2839 43.6961 30.2271 43.6876 30.1747 43.6732C30.0611 43.6432 29.9505 43.6303 29.8427 43.6303C29.598 43.6303 29.3709 43.699 29.1539 43.7935C29.0112 43.855 28.8728 43.8865 28.736 43.8865C28.5641 43.8865 28.3967 43.8364 28.2277 43.7334C27.2652 43.1465 26.3871 42.4323 25.6065 41.4533C25.4929 41.3102 25.3633 41.1799 25.2381 41.0482C24.6265 40.4113 24.242 39.6584 24.0324 38.7739C23.8984 38.2042 23.8474 37.6374 23.8474 37.0706C23.8474 36.6183 23.8794 36.1646 23.9275 35.7095C23.9333 35.6479 23.9348 35.5864 23.9348 35.5234C23.9348 35.4747 23.9348 35.4261 23.9348 35.3774C23.9348 35.3516 23.9348 35.3273 23.9348 35.3015C23.977 33.8659 24.2013 32.469 24.7794 31.1522C24.8129 30.9833 24.8915 30.8373 24.9847 30.6985C25.0095 30.5653 25.059 30.4422 25.1376 30.332C25.1493 30.1946 25.2032 30.0744 25.2803 29.9656C25.2803 29.9599 25.2803 29.9527 25.2803 29.947C25.2803 29.8912 25.2905 29.8397 25.3444 29.8067C25.4143 29.5777 25.5454 29.3874 25.6925 29.207C25.8089 29.1111 25.857 28.9637 25.9473 28.8478C26.0623 28.5243 26.2895 28.2881 26.5152 28.0691C26.805 27.7743 27.1225 27.5195 27.4647 27.3148C27.7312 27.156 28.002 27.0085 28.2743 26.8654C28.6471 26.6708 29.0345 26.5706 29.451 26.5634C29.5718 26.562 29.6956 26.5605 29.8194 26.5605C30.1689 26.5605 30.5257 26.5691 30.8839 26.5963C30.932 26.5992 30.9786 26.5978 31.0266 26.6035C31.245 26.6321 31.4606 26.6836 31.5319 26.9384C31.5465 26.9928 31.5538 27.0443 31.5538 27.0959L31.5567 27.0973Z" fill="black"/> 8120 <path d="M37.3779 26.4278C37.7929 26.4278 38.2182 26.4779 38.6594 26.581C38.971 26.6526 38.9535 26.6454 39.2652 26.7198C39.9307 26.8801 40.302 26.9503 40.302 27.603C40.302 27.726 40.2889 27.8706 40.2627 28.0395C40.1695 28.6249 40.0676 28.6664 39.7603 28.6664C39.7108 28.6664 39.6554 28.6664 39.5957 28.6664C39.536 28.6664 39.472 28.6664 39.3991 28.6707C39.1691 28.6836 38.939 28.695 38.7089 28.695C38.4657 28.695 38.2225 28.6822 37.9793 28.6449C37.4332 28.5548 36.9017 28.4131 36.3542 28.4131C36.3221 28.4131 36.2901 28.4131 36.2581 28.4145C35.9828 28.4231 35.7207 28.5075 35.4295 28.5648C35.2431 28.6006 35.1455 28.7337 35.1455 28.9555C35.1455 28.9741 35.1455 28.9927 35.147 29.0128C35.1877 29.6068 35.246 30.1993 35.2999 30.7919C35.4193 32.0872 35.6814 33.3611 35.7877 34.6579C35.8416 35.3492 35.8736 36.0391 35.91 36.7304C35.9231 36.9937 36.0222 37.0982 36.2464 37.134C36.3556 37.1512 36.4634 37.1598 36.5697 37.1598C36.8711 37.1598 37.1638 37.0925 37.4551 36.9665C37.6182 36.895 37.7915 36.8349 37.972 36.8349C38.1031 36.8349 38.2371 36.8678 38.3725 36.9522C38.7031 37.1927 39.0438 37.5849 39.0584 37.947C39.0584 37.9771 39.0598 38.0085 39.0598 38.0386C39.0598 38.103 39.0584 38.1688 39.0584 38.2333C39.0584 38.332 39.0628 38.4308 39.0861 38.531C39.0904 38.5496 39.0919 38.5682 39.0919 38.5854C39.0919 38.8115 38.738 38.9017 38.5167 39.0376C38.0973 39.2981 37.6692 39.4785 37.2483 39.6188C37.0808 39.6746 36.9148 39.719 36.7488 39.719C36.6454 39.719 36.542 39.7018 36.4372 39.6617C36.3891 39.6431 36.3425 39.6331 36.2959 39.6331C36.2406 39.6331 36.1853 39.6474 36.1314 39.6803C36.1052 39.7461 36.06 39.7991 36.0557 39.8807C36.0324 40.3587 35.9974 40.8368 35.9974 41.3149C35.9974 41.6054 36.0105 41.896 36.0455 42.1865C36.0819 42.5186 36.1547 42.6131 36.427 42.6131C36.4357 42.6131 36.4459 42.6131 36.4547 42.6131C36.8508 42.6045 37.2425 42.53 37.6327 42.4613C38.0419 42.3926 38.4715 42.2982 38.9113 42.2738C39.1268 42.261 39.3351 42.1937 39.5113 42.062C39.6132 41.9861 39.7122 41.9575 39.8098 41.9575C39.9962 41.9575 40.1753 42.062 40.3501 42.1278C40.4476 42.1636 40.5059 42.2624 40.5059 42.3726C40.5059 42.417 40.4957 42.4642 40.4753 42.5114C40.3282 42.8349 40.3806 43.1956 40.2874 43.5291C40.2845 43.5377 40.2816 43.5491 40.2816 43.5577C40.2816 43.5606 40.2816 43.5634 40.2816 43.5649C40.3049 43.6364 40.3151 43.7037 40.3151 43.7667C40.3151 44.063 40.0879 44.2619 39.9394 44.5095C39.6613 44.9761 39.2841 45.2252 38.7759 45.3282C38.4177 45.4012 38.0856 45.5902 37.7303 45.6431C37.6793 45.6517 37.6226 45.6775 37.5861 45.719C37.3255 46.0138 36.9847 46.0038 36.6614 46.0525C36.4183 46.0883 36.1707 46.0611 35.9129 46.1198C35.8824 46.1255 35.8503 46.1298 35.8183 46.1298C35.7542 46.1298 35.6901 46.1183 35.6319 46.0997C35.4018 46.0239 35.1688 45.9909 34.93 45.9866C34.9256 45.9866 34.9227 45.9866 34.9183 45.9866C34.7771 45.9866 34.5281 46.0224 34.3067 46.0224C34.1029 46.0224 33.9223 45.9924 33.8669 45.875C33.7723 45.6746 33.74
812061 45.4413 33.7461 45.1937C33.7461 44.9046 33.781 44.5968 33.7854 44.2948V44.2905C33.7854 44.1818 33.7271 44.0758 33.7228 43.9685C33.6966 43.0639 33.6762 42.1593 33.6543 41.2547C33.6514 41.1245 33.65 40.9942 33.65 40.864C33.65 40.7008 33.65 40.5362 33.65 40.3731C33.65 39.948 33.6412 39.5243 33.5728 39.1006C33.5597 39.0233 33.5568 38.9446 33.5568 38.8659C33.5568 38.7242 33.5699 38.5811 33.5699 38.4394C33.5699 38.3993 33.5699 38.3592 33.567 38.3206C33.5087 37.4303 33.4359 36.54 33.3791 35.6512C33.3791 35.6311 33.3777 35.6111 33.3777 35.5911C33.3777 35.4379 33.4111 35.2819 33.4111 35.1288C33.4111 35.1059 33.4111 35.0815 33.4082 35.0586C33.3718 34.5806 33.3675 34.1025 33.3675 33.6245C33.3675 33.4828 33.3675 33.3411 33.3675 33.1994C33.3675 32.8644 33.366 32.5295 33.3514 32.196C33.3456 32.0672 33.3442 31.9369 33.3442 31.8081C33.3442 31.5033 33.3558 31.1984 33.366 30.8935C33.366 30.8678 33.366 30.8434 33.366 30.8191C33.366 30.643 33.3398 30.4799 33.2277 30.3324C33.1345 30.2094 33.117 30.0648 33.117 29.9116C33.117 29.8988 33.117 29.8873 33.117 29.8744C33.1184 29.7657 33.1199 29.6569 33.1199 29.5481C33.1199 29.2475 33.1141 28.9455 33.1141 28.6449C33.1141 28.4174 33.0835 28.0195 33.0835 27.6445C33.0835 27.331 33.1039 27.0333 33.1811 26.8644C33.3019 26.5967 33.532 26.5552 33.8029 26.5552C33.9281 26.5552 34.0621 26.5638 34.1975 26.5638C34.2849 26.5638 34.3723 26.5595 34.4596 26.5481C34.8819 26.4908 35.3086 26.4737 35.7295 26.3921C35.763 26.3849 35.7994 26.3806 35.8358 26.3806C35.878 26.3806 35.9202 26.3878 35.9552 26.4064C36.0979 26.4822 36.2406 26.5051 36.3848 26.5051C36.5144 26.5051 36.6469 26.4865 36.7794 26.4708C36.9774 26.4479 37.1769 26.435 37.3794 26.435L37.3779 26.4278Z" fill="black"/> 8121 <path d="M4.86962 26.3272C5.04 26.3272 5.25552 26.3143 5.47104 26.3143C5.79432 26.3143 6.11906 26.343 6.29381 26.489C6.72194 26.8182 7.0161 27.0786 7.47918 27.4823C7.9408 27.8873 8.17525 28.8406 8.36165 29.3974C8.47523 29.7394 8.53203 30.1073 8.53203 30.3978C8.53203 30.5796 8.51018 30.7313 8.4665 30.8244C8.35437 31.0648 8.04274 31.145 7.82867 31.248C7.55636 31.3769 7.40782 31.3525 7.13551 31.4556C7.10784 31.4656 7.07726 31.4713 7.04522 31.4713C6.88067 31.4713 6.66951 31.3339 6.43797 31.1579C6.16129 30.946 6.10013 30.7628 6.06809 30.1245C6.03897 29.4875 5.55696 28.8492 5.0633 28.7161C4.94534 28.6846 4.83321 28.6688 4.72691 28.6688C4.05413 28.6688 3.61872 29.2585 3.37699 29.791C3.26631 30.0357 3.21535 30.2604 3.21535 30.468C3.21535 32.0181 5.98218 32.6679 6.96658 33.9847C7.57383 34.7962 8.09079 35.7753 8.20729 36.6441C8.32379 37.5114 8.42427 38.0868 8.58008 38.4962C8.73735 38.9041 8.80434 39.1875 8.83638 39.4623C8.86841 39.7371 8.93103 39.9905 9.04899 40.6102C9.07374 40.7376 9.08539 40.8779 9.08539 41.0253C9.08539 41.5892 8.90628 42.2591 8.55678 42.7686C8.117 43.4127 7.76896 43.7763 7.43549 43.8965C7.10201 44.0167 6.98552 44.1327 6.91125 44.4318C6.83698 44.7309 6.52389 44.8927 6.23847 44.9642C5.988 45.0301 5.80597 45.0458 5.69384 45.0458H5.66472C5.64142 45.0458 5.62249 45.0444 5.59919 45.0444C5.51181 45.0444 5.36619 45.0501 4.75749 45.0673C4.73856 45.0673 4.71963 45.0673 4.7007 45.0673C3.91725 45.0673 2.59791 44.6136 1.74893 43.4599C0.843155 42.2777 0.483467 41.1899 0.3859 40.3869C0.288333 39.584 0.152904 39.166 0.0684426 38.7781C0.013106 38.5234 0 38.2872 0 38.0897C0 37.9866 0.00291245 37.8936 0.00728113 37.8134C0.0174747 37.5787 0.0509679 37.4542 0.256296 37.2123C0.461624 36.9704 0.816943 36.6197 1.21012 36.4537C1.36303 36.3893 1.48244 36.3564 1.58146 36.3564C1.73582 36.3564 1.84067 36.4365 1.9528 36.5997C2.13483 36.8673 2.27171 37.1307 2.30521 37.4799C2.33579 37.8292 2.44209 38.2085 2.55131 38.6035C2.66052 39 2.77848 39.4065 2.88187 39.8158C2.98526 40.2252 3.15419 40.5859 3.31437 40.8149C3.4731 41.0439 3.57795 41.1656 3.75561 41.5892C3.93327 42.0115 4.46624 42.1861 4.81865 42.2076C4.93806 42.2147 5.0298 42.2204 5.10844 42.2204C5.26134 42.2204 5.36619 42.2033 5.53366 42.1589C5.78704 42.0916 5.88606 41.7037 5.9283 41.4532C5.97053 41.2028 5.95596 41.0997 5.988 41.0382C6.02149 40.9766 6.01713 40.928 6.03023 40.8564C6.04188 40.7863 6.04479 40.6904 6.06955 40.626C6.09722 40.5615 6.09431 40.5129 6.11324 40.4284C6.12052 40.3969 6.12052 40.3597 6.12052 40.3197V40.2867C6.12052 40.2252 6.12052 40.1551 6.14236 40.0835C6.17877 39.9504 6.16712 39.7901 6.19624 39.6011C6.21372 39.4881 6.221 39.3635 6.221 39.2533C6.221 39.1789 6.21808 39.1116 6.21226 39.0587C6.19915 38.927 6.19333 38.8812 6.1642 38.8168C6.13508 38.7524 6.14236 38.6522 6.12489 38.5205C6.10741 38.3903 6.08265 38.2271 6.0346 37.603C5.98654 36.979 5.24096 36.4537 4.75166 35.7624C4.0119 34.719 2.75081 34.1607 1.9062 33.2261C1.41108 32.6793 1.0412 31.7805 1.0412 30.7199C1.0412 30.0486 1.18974 29.3115 1.55088 28.56C1.85669 27.9231 2.11298 27.6025 2.47704 27.2218C2.8411 26.8411 3.79784 26.5791 4.39926 26.3959C4.55799 26.3472 4.71526 26.3258 4.86671 26.3258L4.86962 26.3272Z" fill="black"/> 8122 <path d="M21.938 45.3626C21.8477 45.3626 21.7356 45.344 21.5856 45.3125C21.5288 45.3011 21.4691 45.2925 21.4108 45.2925C21.3963 45.2925 21.3817 45.2925 21.3686 45.2939C2
81221.3045 45.2982 21.2419 45.3011 21.1837 45.3011C20.3492 45.3011 20.1075 44.8545 19.9968 44.1017C19.9313 43.6522 19.9153 43.1999 19.9153 42.7491C19.9153 42.4857 19.9211 42.2224 19.924 41.959C19.9371 40.834 19.9633 39.709 19.9837 38.5854C19.9837 38.5153 19.9837 38.4451 19.9837 38.375C19.9837 38.0644 19.9735 37.7524 19.9735 37.4404C19.9735 37.2214 19.9779 37.0024 19.9954 36.7834C20.0871 35.614 20.09 34.4375 20.2386 33.2724C20.2429 33.2352 20.2502 33.1965 20.2502 33.1579V33.0334C20.2502 32.7958 20.2633 32.5639 20.4905 32.4007C20.8312 32.1546 21.156 31.8683 21.5812 31.8683C21.6569 31.8683 21.7356 31.8769 21.8186 31.8969C21.9234 31.9227 22.037 31.9356 22.0982 32.0486C22.2482 32.1445 22.3006 32.2891 22.3122 32.4666C22.3981 33.7905 22.5015 35.1116 22.503 36.4399C22.5045 37.6536 22.5758 38.8645 22.5947 40.0783C22.5991 40.3259 22.602 40.5735 22.602 40.8197C22.602 41.3392 22.5904 41.8588 22.5583 42.3784C22.5481 42.5372 22.5438 42.6961 22.5438 42.8564C22.5438 43.2958 22.5787 43.7367 22.6355 44.1747C22.6443 44.2462 22.6501 44.3164 22.6501 44.3851C22.6501 44.5812 22.602 44.7644 22.4418 44.9146C22.2496 45.2481 22.1564 45.3612 21.9365 45.3612L21.938 45.3626ZM20.3944 29.3206C20.3944 28.5634 20.9361 27.8563 21.6977 27.7375C21.7618 27.6875 21.8259 27.6646 21.8885 27.6646C21.9642 27.6646 22.0385 27.6989 22.1098 27.7576C22.4986 27.9351 22.6544 28.1283 22.6544 28.4876C22.6544 28.5334 22.653 28.5806 22.6472 28.6307C22.618 28.9298 22.5758 29.2275 22.5161 29.521C22.4316 29.9446 22.1724 30.2223 21.7996 30.3941C21.6802 30.4441 21.5535 30.4685 21.4283 30.4685C21.0104 30.4685 20.5997 30.2051 20.4686 29.8015C20.4177 29.6426 20.3929 29.4794 20.3929 29.3206H20.3944Z" fill="black"/> 8123 <path d="M50.3548 30.334C50.3228 30.0234 50.2616 29.6985 50.234 29.4222C50.2311 29.3951 50.2296 29.3679 50.2267 29.3421C50.2136 29.1889 50.2005 29.0558 50.1888 28.9385C50.1146 28.2099 50.0417 28.0639 49.6078 27.2867C49.35 26.9561 49.0107 26.7199 48.718 26.4322C48.2651 25.9885 47.7424 25.6665 47.2138 25.3931C46.9822 25.2672 46.7376 25.2071 46.4856 25.2128C46.2716 25.2185 46.0575 25.2314 45.8464 25.2543C45.3061 25.3144 44.7789 25.4446 44.2722 25.6966C44.2605 25.7023 44.2489 25.7066 44.2372 25.7123C44.2707 25.7366 44.2984 25.7653 44.3202 25.801C44.3319 25.8211 44.345 25.8397 44.3625 25.8569C44.3799 25.874 44.3887 25.8969 44.393 25.9213C44.4003 25.9599 44.396 26 44.4091 26.0372C44.4105 26.0429 44.4091 26.0515 44.4105 26.0572C44.4105 26.0615 44.4105 26.0673 44.4105 26.0716C44.4105 26.0973 44.4032 26.1231 44.396 26.1489C44.3901 26.176 44.3829 26.2018 44.3697 26.2276C44.3552 26.2591 44.3333 26.2905 44.3246 26.3249C44.3086 26.3807 44.2678 26.4179 44.2183 26.4423C44.1528 26.4723 44.0872 26.4924 44.0159 26.4924C43.9897 26.4924 43.9635 26.4895 43.9372 26.4838C43.8994 26.4752 43.8601 26.468 43.8266 26.4509C43.8149 26.4451 43.8047 26.4408 43.796 26.4308C43.7654 26.3965 43.7348 26.365 43.6926 26.3464C43.6868 26.3435 43.681 26.3392 43.6751 26.3349C43.6547 26.3192 43.6358 26.3034 43.6285 26.2791C43.6169 26.2347 43.595 26.1932 43.5805 26.1489C43.5717 26.1231 43.5674 26.0988 43.5674 26.073C43.5674 26.0558 43.5688 26.0401 43.5746 26.0229C43.5776 26.0129 43.5776 26.0029 43.579 25.9928C43.2921 26.1703 43.0519 26.4194 42.8494 26.7285C42.8931 26.7056 42.9383 26.687 42.9849 26.667C43.0315 26.6455 43.0752 26.657 43.1188 26.6727C43.1305 26.677 43.1421 26.6813 43.1538 26.6856C43.1713 26.6856 43.1887 26.6899 43.2033 26.6956C43.2659 26.7171 43.2994 26.7715 43.3183 26.8402C43.33 26.8831 43.346 26.9246 43.3708 26.9618C43.3984 27.0005 43.4115 27.0477 43.3955 27.0878C43.3912 27.0992 43.3839 27.1107 43.3751 27.1207C43.3023 27.2066 43.2499 27.3082 43.1713 27.3884C43.097 27.4671 42.9892 27.4757 42.8931 27.4642C42.8524 27.4599 42.816 27.4513 42.7854 27.4413C42.666 27.3984 42.6004 27.3082 42.5888 27.1937C42.4985 27.3597 42.3864 27.5029 42.2305 27.6088C42.1898 27.636 42.1548 27.6675 42.1228 27.7004C42.165 27.7061 42.2072 27.7147 42.248 27.7319C42.2844 27.7491 42.3194 27.7691 42.3558 27.7877C42.4111 27.8149 42.4563 27.8564 42.4868 27.9108C42.5 27.9294 42.5116 27.9494 42.5291 27.9666C42.5465 27.9838 42.5553 28.0067 42.5582 28.031C42.5655 28.0697 42.5611 28.1097 42.5742 28.147C42.5757 28.1527 42.5742 28.1598 42.5757 28.167C42.5757 28.1713 42.5757 28.177 42.5757 28.1813C42.5757 28.2071 42.5684 28.2328 42.5611 28.2572C42.5553 28.2844 42.5465 28.3101 42.5349 28.3359C42.5203 28.3688 42.4985 28.3989 42.4898 28.4332C42.4737 28.489 42.433 28.5262 42.3835 28.5506C42.3179 28.5806 42.2524 28.6007 42.181 28.6007C42.1548 28.6007 42.1286 28.5978 42.1024 28.5921C42.0645 28.5835 42.0252 28.5778 41.9917 28.5592C41.9801 28.5549 41.9699 28.5492 41.9611 28.5391C41.9306 28.5048 41.9 28.4733 41.8578 28.4547C41.8519 28.4518 41.8461 28.4475 41.8403 28.4432C41.8199 28.4275 41.7995 28.4117 41.7937 28.3874C41.7922 28.3803 41.7893 28.3745 41.7864 28.3674C41.7092 28.6422 41.6714 28.927 41.6029 29.2047C41.4835 29.6885 41.4631 30.168 41.5112 30.6417C41.5447 30.9738 41.6131 31.303 41.7048 31.6293C41.8985 32.3249 42.1505 33.0048 42.7169 33.4872C42.8684 33.616 43.014 33.7534 43.1625 33.8865C43.3256 34.1541 43.5601 34.3416 43.7989 34.5291C44.3071 34.9442 44.8547 35.1718 45.4139 35.3765C46.0954 35.627 47.2807 36.6503 47.3404 37.24C47.3404 37.2415 47.3404 37.2443 47.3404 37.2458C47.3463 37.3216 47.3477 37.4018 47.3565 37.4791C47.3565 37.4977 47.3608 37.5149 47.3637 37.5335C47.3798 37.6336 47.3929 37.7353 47.4045 37.8355C47.4366 38.1518 47.4409 38.471 47.438 38.7887C47.4307 39.5215 47.3696 40.2458 47.2443 40.9643C47.1861 41.3007 47.074 41.5626 46.8715 41.7973C46.6531 42.0507 46.4187 42.2782 46.1463 42.4529C46.126 42.4571 46.1041 42.46 46.0837 42.4614C45.9279 42.4786 45.7721 42.4557 45.6236 42.4013C44.5314 42.0049 44.1076 41.6771 44.0071 40.6981C43.9635 40.273 43.9809 39.7248 44.0304 38.9934C44.0668 38.4481 44.2387 37.9342 44.3625 37.4104C44.3785 37.3417 44.4047 37.2672 44.3974 37.1971C44.393 37.1527 44.3756 37.1098 44.3348 37.0711C44.2314 36.9695 43.5455 36.4442 43.4145 36.46C43.4115 36.46 43.4086 36.46 43.4057 36.4614C43.0999 36.5831 42.6208 36.7133 42.3951 36.9438C42.1286 37.2143 41.7646 37.4762 41.632 37.8741C41.4631 38.3779 41.4529 38.9834 41.5155 39.5931C41.5884 40.2987 41.7558 41.013 41.8854 41.5898C41.9408 41.8431 42.0048 42.105 42.1446 42.3341C42.5334 42.9738 42.8465 43.6666 43.3591 44.2205C43.3984 44.2635 43.445 44.3093 43.464 44.3622C43.5237 44.534 43.6606 44.6241 43.7873 44.7272C44.5226 45.3341 45.3935 45.5774 46.1827 45.8479C46.3386 45.9009 46.49 45.9195 46.6356 45.9037C46.8963 45.8751 47.138 45.7334 47.3492 45.4815C47.5268 45.2697 47.7089 45.055 47.939 44.9104C48.3554 44.6628 48.7632 44.3608 49.136 44.0259C49.4986 43.701 49.8583 43.3489 49.9573 42.8107C50.068 42.2067 50.1481 41.5969 50.1364 40.98C50.1335 40.8498 50.1539 40.7195 50.1408 40.5893C50.1364 40.5521 50.1306 40.5134 50.1189 40.4762C50.0782 40.3331 50.0505 40.1885 50.0359 40.0425C50.0068 39.7577 50.0228 39.47 50.0607 39.1838C50.0985 38.8975 50.1 38.617 50.0723 38.3421C50.025
81237 37.8856 49.8976 37.4433 49.7243 37.0082C49.2758 35.4137 47.7205 33.5244 46.5512 32.7286C45.9177 32.2977 45.2595 31.9199 44.5969 31.5535C44.3392 31.4103 44.0916 31.2586 43.9183 30.9795C43.8848 30.9265 43.8644 30.8435 43.8542 30.7405C43.7829 30.0477 44.1863 28.4175 44.4688 28.2801C44.9217 28.0596 45.3323 27.7233 45.8318 27.6288C45.7284 27.5515 45.6949 27.4213 45.7342 27.2681C45.7357 27.2595 45.7386 27.251 45.7415 27.2409C45.7634 27.1837 45.8027 27.1307 45.8391 27.0778C45.9061 26.9833 46.0138 26.9432 46.1172 26.9003C46.1653 26.8788 46.2075 26.8903 46.2512 26.9046C46.2628 26.9089 46.2745 26.9132 46.2861 26.9175C46.3036 26.9189 46.3211 26.9232 46.3357 26.9275C46.3983 26.9504 46.4318 27.0033 46.4507 27.0735C46.4623 27.1164 46.4784 27.1579 46.5031 27.1951C46.5308 27.2352 46.5439 27.281 46.5279 27.3211C46.5235 27.3325 46.5162 27.344 46.5089 27.354C46.4405 27.437 46.3866 27.5301 46.3153 27.6088C46.4638 27.6288 46.6036 27.6775 46.7361 27.782C47.4613 28.3559 47.7788 29.1875 47.8778 30.1451C47.8792 30.168 47.8822 30.1923 47.8851 30.2166C47.8865 30.2395 47.8894 30.2596 47.8909 30.2796C47.9331 30.6975 47.9812 30.5873 48.1137 31.0368C48.2302 31.406 48.6991 31.6408 49.0326 31.6036C49.0501 31.6021 49.0675 31.5993 49.085 31.595C49.5874 31.4891 50.2849 31.4833 50.3592 30.9022C50.381 30.7276 50.3723 30.5286 50.3519 30.324L50.3548 30.334ZM43.4523 29.3335C43.448 29.345 43.4407 29.3564 43.4319 29.3664C43.3591 29.4537 43.3067 29.5539 43.2281 29.6355C43.1538 29.7142 43.046 29.7228 42.9499 29.7114C42.9092 29.7071 42.8742 29.6985 42.8422 29.687C42.6718 29.6255 42.6092 29.4709 42.6587 29.2791C42.6601 29.2705 42.663 29.2619 42.666 29.2534C42.6878 29.1961 42.7286 29.1417 42.7635 29.0902C42.8305 28.9957 42.9383 28.9556 43.0417 28.9113C43.0897 28.8898 43.1334 28.9013 43.1771 28.917C43.1887 28.9213 43.2004 28.9256 43.212 28.9299C43.2295 28.9313 43.247 28.9356 43.2616 28.9399C43.3242 28.9628 43.3577 29.0158 43.3766 29.0859C43.3882 29.1288 43.4043 29.1703 43.429 29.2076C43.4567 29.2476 43.4683 29.292 43.4538 29.3335H43.4523ZM44.1295 28.23C44.1251 28.2414 44.1178 28.2529 44.1091 28.2629C44.0363 28.3502 43.9838 28.4504 43.9052 28.532C43.8309 28.6107 43.7232 28.6193 43.6271 28.6078C43.5878 28.6035 43.5499 28.595 43.5193 28.5849C43.3489 28.5234 43.2863 28.3674 43.3358 28.177C43.3373 28.1684 43.3402 28.1598 43.3431 28.1498C43.3635 28.0926 43.4043 28.0396 43.4407 27.9866C43.5077 27.8922 43.6154 27.8521 43.7188 27.8077C43.7669 27.7877 43.8106 27.7977 43.8528 27.812C43.8644 27.8163 43.8761 27.8206 43.8877 27.8249C43.9052 27.8263 43.9227 27.8306 43.9372 27.8349C43.9999 27.8578 44.0334 27.9108 44.0523 27.9809C44.0639 28.0239 44.0785 28.0654 44.1047 28.1026C44.1324 28.1427 44.1455 28.1885 44.1295 28.2285V28.23ZM44.977 27.3354C44.9712 27.3626 44.9624 27.3884 44.9508 27.4141C44.9362 27.447 44.9144 27.4771 44.9056 27.5115C44.8896 27.5673 44.8488 27.6059 44.7993 27.6288C44.7338 27.6589 44.6683 27.6789 44.5969 27.6789C44.5707 27.6789 44.5459 27.6761 44.5183 27.6703C44.4804 27.6617 44.4426 27.6546 44.4062 27.6388C44.396 27.6331 44.3843 27.6274 44.3756 27.6174C44.3464 27.5844 44.3144 27.5515 44.2722 27.5329C44.2664 27.5301 44.2605 27.5258 44.2547 27.5215C44.2343 27.5072 44.2154 27.49 44.2096 27.4657C44.1979 27.4213 44.1761 27.3798 44.1615 27.3354C44.1528 27.3096 44.1484 27.2853 44.1484 27.2595C44.1484 27.2424 44.1499 27.2266 44.1557 27.2094C44.1615 27.1865 44.1644 27.1622 44.1659 27.1379C44.1688 27.0921 44.1688 27.0463 44.179 27.0019C44.1921 26.9518 44.211 26.906 44.2576 26.876C44.2736 26.8659 44.2897 26.8531 44.3057 26.843C44.3668 26.7987 44.4353 26.7729 44.5125 26.7729H44.5197C44.5678 26.7772 44.6158 26.7872 44.661 26.8073C44.6974 26.8244 44.7323 26.8445 44.7687 26.8631C44.8241 26.8917 44.8692 26.9332 44.8998 26.9862C44.9129 27.0062 44.9246 27.0262 44.942 27.042C44.9595 27.0606 44.9683 27.0821 44.9712 27.1078C44.9784 27.1465 44.9741 27.1865 44.9872 27.2238C44.9886 27.2295 44.9872 27.2381 44.9886 27.2438C44.9886 27.2481 44.9886 27.2538 44.9886 27.2581C44.9886 27.2839 44.9799 27.3096 44.9755 27.334L44.977 27.3354ZM46.0036 26.0515C45.9993 26.063 45.992 26.0744 45.9847 26.0844C45.9119 26.1703 45.8595 26.2719 45.7808 26.3521C45.7066 26.4308 45.5988 26.4394 45.5027 26.428C45.4634 26.4237 45.427 26.4151 45.3949 26.4051C45.2231 26.3435 45.1605 26.1875 45.2114 25.9971C45.2129 25.9885 45.2158 25.98 45.2187 25.9714C45.2406 25.9141 45.2799 25.8597 45.3163 25.8082C45.3833 25.7137 45.491 25.6737 45.5944 25.6293C45.6425 25.6092 45.6862 25.6193 45.7299 25.635C45.7415 25.6393 45.7532 25.6436 45.7648 25.6479C45.7823 25.6493 45.7998 25.6522 45.8143 25.6579C45.8769 25.6808 45.9104 25.7338 45.9294 25.8039C45.941 25.8468 45.9556 25.8884 45.9818 25.9256C46.0095 25.9656 46.0226 26.0114 46.0065 26.0515H46.0036Z" fill="black"/> 8124 <path d="M42.1998 23.4849C42.2013 23.4764 42.2042 23.4678 42.2071 23.4578C42.2289 23.4005 42.2697 23.3461 42.3047 23.2946C42.3716 23.2001 42.4794 23.16 42.5828 23.1157C42.6308 23.0956 42.6745 23.1056 42.7182 23.1214C42.7299 23.1257 42.7415 23.13 42.7532 23.1328C42.7706 23.1343 42.7881 23.1386 42.8027 23.1429C42.8653 23.1658 42.8988 23.2187 42.9177 23.2889C42.9308 23.3318 42.9454 23.3733 42.9701 23.4105C42.9978 23.4506 43.0095 23.4964 42.9949 23.5365C42.9905 23.5479 42.9833 23.5594 42.9745 23.5694C42.901
81247 23.6553 42.8493 23.7569 42.7706 23.837C42.6964 23.9158 42.5886 23.9244 42.4925 23.9129C42.4532 23.9086 42.4168 23.9 42.3847 23.89C42.2144 23.8285 42.1517 23.6724 42.2013 23.4821L42.1998 23.4849Z" fill="black"/> 8125 <path d="M41.9738 25.9816C41.9767 25.9715 41.9781 25.9644 41.981 25.9558C42.0029 25.8985 42.0437 25.8442 42.0786 25.7926C42.1456 25.6982 42.2534 25.6581 42.3567 25.6137C42.4048 25.5937 42.447 25.6037 42.4907 25.6194C42.5024 25.6237 42.514 25.628 42.5271 25.6323C42.5446 25.6338 42.5621 25.6366 42.5766 25.6423C42.6393 25.6652 42.6728 25.7182 42.6917 25.7883C42.7033 25.8313 42.7193 25.8728 42.7441 25.91C42.7718 25.9501 42.7834 25.9959 42.7689 26.0359C42.7645 26.0474 42.7572 26.0589 42.7499 26.0689C42.6771 26.1547 42.6232 26.2564 42.5461 26.3365C42.4718 26.4152 42.3655 26.4238 42.2679 26.4124C42.2286 26.4081 42.1922 26.3995 42.1602 26.3895C41.9883 26.3279 41.9257 26.1719 41.9767 25.9816H41.9738Z" fill="black"/> 8126 <path d="M41.0116 24.4296C41.0145 24.3852 41.0145 24.3394 41.0262 24.2936C41.0378 24.2435 41.0582 24.1991 41.1048 24.1691C41.1208 24.159 41.1368 24.1476 41.1529 24.1347C41.214 24.0903 41.2825 24.0646 41.3596 24.0646H41.3669C41.415 24.0689 41.463 24.0789 41.5082 24.0989C41.5446 24.1161 41.5795 24.1361 41.6159 24.1547C41.6713 24.1819 41.7164 24.2234 41.747 24.2778C41.7601 24.2979 41.7717 24.3165 41.7892 24.3337C41.8067 24.3508 41.8154 24.3737 41.8184 24.3995C41.8256 24.4381 41.8213 24.4782 41.8344 24.5154C41.8358 24.5212 41.8344 24.5297 41.8358 24.5355C41.8358 24.5398 41.8358 24.5455 41.8358 24.5498C41.8358 24.5756 41.8271 24.6013 41.8213 24.6271C41.8154 24.6543 41.8067 24.68 41.7951 24.7058C41.7805 24.7387 41.7601 24.7688 41.7499 24.8031C41.7339 24.8589 41.6931 24.8962 41.6436 24.9205C41.5781 24.9506 41.5111 24.972 41.4412 24.972C41.415 24.972 41.3888 24.9692 41.3626 24.9634C41.3247 24.9548 41.2854 24.9477 41.2504 24.9305C41.2388 24.9248 41.2286 24.9205 41.2198 24.9105C41.1907 24.8761 41.1587 24.8446 41.1164 24.826C41.1106 24.8232 41.1048 24.8189 41.099 24.8146C41.0786 24.7988 41.0597 24.7831 41.0524 24.7588C41.0407 24.7144 41.0189 24.6729 41.0043 24.6285C40.9956 24.6027 40.9912 24.577 40.9912 24.5526C40.9912 24.5355 40.9927 24.5197 40.9985 24.5026C41.0043 24.4797 41.0072 24.4553 41.0087 24.431L41.0116 24.4296Z" fill="black"/> 8127 <path d="M41.0609 27.073C41.0638 27.0286 41.0638 26.9828 41.074 26.9384C41.0871 26.8884 41.1061 26.8425 41.1527 26.8125C41.1687 26.8025 41.1847 26.791 41.2007 26.7781C41.2619 26.7338 41.3303 26.708 41.4075 26.708H41.4148C41.4628 26.7123 41.5109 26.7223 41.556 26.7424C41.5924 26.7595 41.6274 26.7796 41.6638 26.7982C41.7191 26.8268 41.7643 26.8683 41.7949 26.9213C41.808 26.9413 41.8196 26.9613 41.8371 26.9771C41.8546 26.9943 41.8633 27.0172 41.8662 27.0429C41.8735 27.0816 41.8691 27.1217 41.8822 27.1589C41.8822 27.1646 41.8822 27.1732 41.8822 27.1789C41.8822 27.1832 41.8822 27.1889 41.8822 27.1932C41.8822 27.219 41.8749 27.2447 41.8691 27.2691C41.8633 27.2963 41.8546 27.322 41.8429 27.3478C41.8283 27.3807 41.8065 27.4108 41.7978 27.4451C41.7817 27.501 41.741 27.5382 41.6915 27.5625C41.6259 27.594 41.5604 27.614 41.489 27.614C41.4628 27.614 41.4381 27.6112 41.4119 27.6054C41.374 27.5968 41.3347 27.5911 41.2997 27.5739C41.2881 27.5682 41.2779 27.5639 41.2692 27.5539C41.24 27.5196 41.2095 27.4881 41.1658 27.4695C41.1599 27.4666 41.1541 27.4623 41.1483 27.458C41.1279 27.4423 41.1075 27.4265 41.1017 27.4022C41.09 27.3578 41.0682 27.3163 41.0536 27.2719C41.0449 27.2476 41.0405 27.2218 41.0405 27.1961C41.0405 27.1803 41.042 27.1632 41.0478 27.146C41.0536 27.1231 41.0565 27.0988 41.058 27.073H41.0609Z" fill="black"/> 8128 <path d="M46.472 5.28774C45.6157 5.28774 44.9502 4.61216 44.9502 3.79202C44.9502 2.97188 45.6244 2.28772 46.4807 2.28772C47.337 2.28772 48.0024 2.9633 48.0024 3.78343C48.0024 4.60357 47.3282 5.28774 46.472 5.28774ZM46.4807 2.45375C45.7089 2.45375 45.1279 3.0549 45.1279 3.79202C45.1279 4.52914 45.706 5.12171 46.4734 5.12171C47.2408 5.12171 47.8277 4.52056 47.8277 3.78343C47.8277 3.04631 47.2496 2.45375 46.4821 2.45375H46.4807ZM46.8564 3.97094L47.2525 4.54346H46.8346L46.4894 4.02962H46.2069V4.54346H45.8487V2.94755H46.5695C46.9583 2.94755 47.2059 3.14221 47.2059 3.47427C47.2059 3.73477 47.0617 3.89651 46.8564 3.97094ZM46.5564 3.25815H46.2069V3.72618H46.5651C46.7457 3.72618 46.8433 3.63028 46.8433 3.49431C46.8433 3.33687 46.7341 3.25815 46.5564 3.25815Z" fill="black"/> 8129 <path d="M50.5571 17.4832C49.9454 17.9197 49.5858 18.7327 48.9057 19.0705C48.2256 19.4083 47.7844 19.8992 47.3927 20.3014C46.9995 20.7036 46.4942 21.2404 45.7646 21.5452C45.4326 21.6841 45.1676 21.7972 44.9506 21.8558C44.6957 21.9245 44.505 21.9188 44.3477 21.7914C44.0725 21.5681 44.0026 21.123 44.2239 20.758C44.4409 20.4002 44.7948 20.1268 45.4719 19.3725C46.1447 18.6225 47.1582 18.1974 47.3475 17.8811C47.5368 17.5634 48.3916 17.0839 47.7728 16.0576C47.7728 16.0576 46.9296 15.0543 46.551 15.2146C46.1724 15.3735 45.6161 15.8501 45.204 16.4469C44.7919 17.0438 44.5807 17.4174 44.5225 17.5605C44.4642 17.7036 44.2283 18.8258 44.2065 19.1407C44.2065 19.1507 44.1569 19.57 44.1468 19.5958C44.0987 19.7332 43.8832 20.1325 43.5439 20.7008C43.4521 20.8539 43.4128 21.2862 43.4652 21.576
81297C43.49 21.6483 43.4914 21.8 43.6414 21.9603C43.6662 21.9861 43.7201 22.0534 43.7652 22.092C43.8191 22.1392 43.9458 22.1836 43.9589 22.2337C43.9691 22.2766 43.8963 22.3282 43.8351 22.3582C43.6633 22.4441 43.6414 22.4241 43.4259 22.4312C43.3881 22.4312 43.3473 22.4255 43.3065 22.414C43.273 22.4055 43.241 22.394 43.2104 22.3826C43.0939 22.3396 43.0065 22.1893 42.8929 21.6841C42.8609 21.541 42.759 21.2976 42.7211 21.0915C42.6498 20.7036 42.7153 20.5505 42.7138 20.2814C42.7109 19.6946 42.7997 19.2122 42.8128 18.5953C42.8128 18.5295 42.7735 18.0514 42.7546 17.9541C42.6978 17.6635 42.5726 17.2113 43.0109 16.5858C43.2497 16.2451 43.4201 15.7957 43.5876 15.4837C43.9968 14.7251 44.2094 14.2928 44.272 14.1554C44.4846 13.6888 44.6608 13.1048 45.5462 12.7585C45.8767 12.6296 46.3049 12.5337 46.8713 12.4894C48.5824 12.269 48.048 12.3076 49.0513 12.0657C49.3994 11.9813 50.0066 11.9455 50.4872 11.9555C50.9663 11.9655 51.4104 11.9956 51.6186 11.9913C52.7705 11.9669 52.9773 12.5967 52.989 13.0132C53.0079 13.7346 53.0341 14.3129 52.7691 14.9541C52.4851 15.6411 51.8691 16.4011 50.5571 17.4846V17.4832Z" fill="black"/> 8130 <path d="M44.9519 18.8715C44.9519 18.8715 45.1223 17.8696 45.2548 17.549C45.3888 17.2269 45.7266 16.8118 45.7994 16.7431C45.8723 16.6744 45.932 16.5914 45.9713 16.5428C46.0106 16.4941 46.2654 16.1377 46.3907 16.0976C46.5145 16.0561 46.6309 16.0733 46.663 16.0919C46.695 16.1091 46.8057 16.1534 46.9324 16.2837C47.0256 16.3782 47.113 16.5399 47.0999 16.6687C47.0897 16.7632 46.9615 17.1267 46.9324 17.1496C46.9033 17.174 46.5945 17.6492 46.1315 17.9054C46.1315 17.9054 45.8883 18.0599 45.8548 18.1015C45.8213 18.143 45.3873 18.4264 44.9738 18.8829C44.9621 18.8901 44.9461 18.9144 44.9519 18.8744V18.8715Z" fill="black"/> 8131 <path d="M43.755 13.424C43.608 13.5256 42.8915 14.3372 42.3818 14.8424C42.226 14.997 41.9945 15.1244 41.9304 15.1788C41.7425 15.3419 41.7076 15.4021 41.5445 15.5438C41.5285 15.5581 41.5139 15.5709 41.4979 15.5838C41.3654 15.7012 41.262 15.8014 41.1644 15.8887C41.0144 16.0218 40.9067 16.2179 40.8775 16.2637C40.7552 16.4469 40.6824 16.6659 40.8382 17.2184C40.9154 17.4918 41.0159 17.7093 41.0902 17.9097C41.1266 18.0113 41.3639 18.5023 41.5328 18.9717C41.6348 19.2537 42.0017 20.2442 42.0382 20.3086C42.0615 20.3501 42.0848 20.3801 42.127 20.4503C42.1415 20.4746 42.178 20.1926 42.1663 20.0295C42.092 19.0304 42.2828 18.4794 42.0047 17.6392C41.8838 17.2728 41.9581 16.9278 42.0309 16.7904C42.0964 16.6673 42.194 16.5356 42.5362 16.0476C42.6702 15.8558 43.6764 13.8219 43.7317 13.7289C43.9196 13.4154 44.1788 13.2694 44.1788 13.2694C44.1788 13.2694 43.9516 13.2909 43.755 13.4269V13.424Z" fill="black"/> 8132 </svg> 8133 </div> 8134 <div class="social flex gap-2"> 8135 <a href="https://www.instagram.com/justspices/" title="Just Spices bei Instagram"> 8136 <svg class="hover-scale" xmlns="http://www.w3.org/2000/svg" width="40" height="41" viewBox="0 0 40 41" fill="none"> 8137 <circle cx="20" cy="20.0648" r="20" fill="white"/> 8138 <path d="M30.4028 24.3849C30.3187 26.0635 29.9354 27.5501 28.7107 28.775C27.4861 30.0047 25.9995 30.388 24.3216 30.4675C22.5921 30.5655 17.4082 30.5655 15.6786 30.4675C14.0004 30.3833 12.5189 30 11.2895 28.775C10.0601 27.5501 9.67685 26.0632 9.59743 24.3849C9.49942 22.655 9.49942 17.4699 9.59743 15.74C9.68158 14.0614 10.0601 12.5748 11.2895 11.3499C12.5189 10.1249 14.0051 9.74158 15.6786 9.66215C17.4082 9.56411 22.5921 9.56411 24.3216 9.66215C25.9998 9.74631 27.4861 10.1296 28.7107 11.3546C29.9402 12.5795 30.3234 14.0664 30.4028 15.7447C30.5008 17.4746 30.5008 22.655 30.4028 24.3849ZM28.5891 20.0648C28.5891 18.5407 28.7152 15.2678 28.1684 13.8887C27.799 12.9676 27.0934 12.2615 26.1772 11.8971C24.8029 11.3546 21.5262 11.4763 20.0025 11.4763C18.4787 11.4763 15.2065 11.3502 13.8277 11.8971C12.9068 12.2665 12.2009 12.9723 11.8366 13.8887C11.2942 15.2633 11.4159 18.5407 11.4159 20.0648C11.4159 21.5889 11.2898 24.8619 11.8366 26.241C12.2059 27.1621 12.9116 27.8682 13.8277 28.2325C15.2021 28.775 18.4787 28.6534 20.0025 28.6534C21.5262 28.6534 24.7985 28.7795 26.1772 28.2325C27.098
81381 27.8631 27.8041 27.1573 28.1684 26.241C28.7152 24.8663 28.5891 21.5889 28.5891 20.0648ZM25.3733 20.0648C25.3733 23.0383 22.9753 25.4368 20.0025 25.4368C17.0297 25.4368 14.6317 23.0383 14.6317 20.0648C14.6317 17.0913 17.0297 14.6928 20.0025 14.6928C22.9753 14.6928 25.3733 17.0913 25.3733 20.0648ZM23.494 20.0648C23.494 18.1385 21.9281 16.5721 20.0022 16.5721C18.0763 16.5721 16.5103 18.1385 16.5103 20.0648C16.5103 21.9911 18.081 23.5575 20.0022 23.5575C21.9233 23.5575 23.494 21.9911 23.494 20.0648ZM25.593 15.7261C24.8965 15.7261 24.3402 15.165 24.3402 14.4731C24.3402 13.7812 24.9012 13.2201 25.593 13.2201C26.2847 13.2201 26.8457 13.7812 26.8457 14.4731C26.8457 15.165 26.2847 15.7261 25.593 15.7261Z" fill="black"/> 8139 </svg> 8140 </a> 8141 <a href="https://www.facebook.com/JustSpices/" title="Just Spices bei Facebook"> 8142 <svg class="hover-scale" xmlns="http://www.w3.org/2000/svg" width="40" height="41" viewBox="0 0 40 41" fill="none"> 8143 <circle cx="20" cy="20.0648" r="20" fill="white"/> 8144 <path d="M22.0384 30.5407V23.1753H24.3683L24.8119 20.1286H22.0384V18.1503C22.0384 17.3171 22.4258 16.5042 23.668 16.5042H24.9294V13.9116C24.9294 13.9116 23.7848 13.7059 22.6906 13.7059C20.4057 13.7059 18.9137 15.1649 18.9137 17.8062V20.1283H16.3735V23.175H18.9137V30.5404C14.1328 29.7496 10.4761 25.3891 10.4761 20.1286C10.4761 14.3062 14.9519 9.58862 20.4761 9.58862C26.0002 9.58862 30.4761 14.3062 30.4761 20.1286C30.4761 25.3891 26.8193 29.7496 22.0387 30.541L22.0384 30.5407Z" fill="black"/> 8145 </svg> 8146 </a> 8147 <a href="https://www.tiktok.com/@justspices" title="Just Spices bei TikTok"> 8148 <svg class="hover-scale" xmlns="http://www.w3.org/2000/svg" width="40" height="41" viewBox="0 0 40 41" fill="none"> 8149 <circle cx="20" cy="20.0648" r="20" fill="white"/> 8150 <path d="M29.5019 18.181C27.5664 18.181 25.766 17.5827 24.3025 16.5742V23.8899C24.3011 27.561 21.2037 30.541 17.3893 30.541C13.5748 30.541 10.4761 27.5596 10.4761 23.8871C10.4761 20.2147 13.5737 17.2333 17.3893 17.2333C17.7136 17.2333 18.0258 17.2545 18.3384 17.2965V20.9761C18.0379 20.885 17.7179 20.8359 17.3861 20.8359C15.6345 20.8359 14.2125 22.2045 14.2125 23.8904C14.2125 25.5764 15.6345 26.945 17.3861 26.945C19.1378 26.945 20.5597 25.5756 20.5597 23.8899V9.58862H24.3022C24.3022 9.60242 24.3022 9.6165 24.3022 9.6303C24.3022 9.92753 24.3295 10.2134 24.3816 10.496C24.6489 11.8704 25.4959 13.0489 26.6744 13.7799C27.4902 14.299 28.4674 14.6012 29.5174 14.6012L29.5237 14.6043V18.181H29.5019Z" fill="black"/> 8151 </svg> 8152 </a> 8153 <a href="https://www.pinterest.de/justspices/" title="Just Spices bei Pinterest"> 8154 <svg class="hover-scale" xmlns="http://www.w3.org/2000/svg" width="40" height="41" viewBox="0 0 40 41" fill="none"> 8155 <circle cx="20" cy="20.0648" r="20" fill="white"/> 8156 <path d="M19.9958 9.58862C14.204 9.58862 9.52393 14.2774 9.52393 20.0605C9.52393 24.4991 12.2819 28.2914 16.1778 29.817C16.083 28.9895 16.0053 27.7141 16.2121 26.8091C16.4018 25.9904 17.4361 21.6035 17.4361 21.6035C17.4361 21.6035 17.1258 20.9743 17.1258 20.052C17.1258 18.5953 17.9704 17.5095 19.0219 17.5095C19.9184 17.5095 20.3492 18.1817 20.3492 18.9833C20.3492 19.8798 19.7802 21.2242 19.4786 22.474C19.2287 23.5168 20.0045 24.3702 21.0301 24.3702C22.8917 24.3702 24.3224 22.4051 24.3224 19.5781C24.3224 17.07 22.5211 15.3204 19.944 15.3204C16.962 15.3204 15.2122 17.5528 15.2122 19.8626C15.2122 20.759 15.5569 21.7242 15.9879 22.25C16.074 22.3535 16.0827 22.4484 16.0569 22.5517C15.9792 22.8792 15.7983 23.5944 15.7639 23.741C15.7209 23.9307 15.6089 23.9737 15.4105 23.8789C14.1176 23.2582 13.3075 21.3449 13.3075 19.8108C13.3075 16.5098 15.7037 13.476 20.2285 13.476C23.857 13.476 26.684 16.0615 26.684 19.5264C26.684 22.9912 24.4085 26.0423 21.2541 26.0423C20.1939 26.0423 19.1941 25.4908 18.8579 24.8358C18.8579 24.8358 18.3321 26.8355 18.2029 27.3268C17.9702 28.2404 17.3323 29.378 16.9015 30.0761C17.8841 30.3777 18.9184 30.5415 20.0042 30.5415C25.7875 30.5415 30.4761 25.8527 30.4761 20.0696C30.4678 14.2774 25.7791 9.58862 19.9958 9.58862Z" fill="black"/> 8157 </svg> 8158 </a> 8159 <a href="https://www.youtube.com/channel/UCOGQpoP4yRDnO_E1aMY4hvA" title="Just Spices bei Youtube"> 8160 <svg class="hover-scale" xmlns="http://www.w3.org/2000/svg" width="40" height="41" viewBox="0 0 40 41" fill="none"> 8161 <circle cx="20" cy="20.0648" r="20" fill="white"/> 8162 <path d="M31.4287 20.082C31.4287 20.082 31.4287 24.0745 30.951 25.9885C30.688 27.0444 29.9134 27.8411 28.9301 28.1234C27.1476 28.6363 20.0001 28.6363 20.0001 28.6363C20.0001 28.6363 12.8528 28.6363 11.0701 28.1234C10.0868 27.8414 9.31222 27.0444 9.04924 25.9885C8.57153 24.0749 8.57153 20.082 8.57153 20.082C8.57153 20.082 8.57153 16.0894 9.04924 14.1758C9.31222 13.1199 10.
81620868 12.2883 11.0701 12.0063C12.8526 11.4934 20.0001 11.4934 20.0001 11.4934C20.0001 11.4934 27.1474 11.4934 28.9301 12.0063C29.9134 12.2883 30.688 13.1199 30.951 14.1758C31.4287 16.0894 31.4287 20.082 31.4287 20.082ZM23.6367 20.082L17.6629 16.4566V23.7067L23.6367 20.0817V20.082Z" fill="black"/> 8163 </svg> 8164 </a> 8165 </div> 8166 </div> 8167 <div class="w-full border-b-[2px] border-solid border-main-black mb-5 laptop:order-3"></div> 8168 <div class="footer-navigation mb-4 laptop:mb-5 laptop:order-4 laptop:w-full laptop:flex" id="accordion-footer-links"> 8169 <div class="footer-navigation-link category-footer-links mb-3 laptop:mb-0 laptop:mr-13"> 8170 <div data-role="collapsible" class="flex w-full justify-between"> 8171 <p class="font-bold text-s">Top Kategorien</p> 8172 <i class="fa-regular fa-chevron-down text-m"></i> 8173 </div> 8174 <div data-role="content" style="display: none;"> 8175 <div class=""> 8176 <a class="footer-bottom-link block text-s mt-3" href="https://www.justspices.de/alle-produkte.html" data-event="ev" data-category="footer" data-action="links" data-label="Alle Produkte">Alle Produkte</a> 8177 <a class="footer-bottom-link block text-s mt-3" href="https://www.justspices.de/bestseller.html" data-event="ev" data-category="footer" data-action="links" data-label="Bestseller Produkte">Bestseller</a> 8178 <a class="footer-bottom-link block text-s mt-3" href="https://www.justspices.de/gewuerzmischungen/dips-und-aufstriche.html" data-event="ev" data-category="footer" data-action="links" data-label="Gewürzmischungen für Dips & Aufstriche">Für Dips & Aufstriche</a> 8179 <a class="footer-bottom-link block text-s mt-3" href="https://www.justspices.de/gewuerzmischungen/salat-und-dressing.html" data-event="ev" data-category="footer" data-action="links" data-label="Gewürzmischungen für Salat & Dressing">Für Salat & Dressing</a> 8180 <a class="footer-bottom-link block text-s mt-3" href="https://www.justspices.de/gewuerzmischungen/grillen.html" data-event="ev" data-category="footer" data-action="links" data-label="Gewürzmischungen zum Grillen">Für Grillen & Marinieren</a> 8181 <a class="footer-bottom-link block text-s mt-3" href="https://www.justspices.de/gewuerzmischungen/airfryer.html" data-event="ev" data-category="footer" data-action="links" data-label="Gewürzmischungen für den Airfryer">Für den Airfryer</a> 8182 <a class="footer-bottom-link block text-s mt-3" href="https://www.justspices.de/gewuerzmischungen/thermomix.html" data-event="ev" data-category="footer" data-action="links" data-label="Gewürzmischungen für den Thermomix">Für den Thermomix®</a> 8183 </div> 8184 <div> 8185 <a class="footer-bottom-link block text-s mt-3" href="https://www.justspices.de/gewuerzmischungen/indisch.html" data-event="ev" data-category="footer" data-action="links" data-label="Indische Gewürzmischungen">Indische Gewürze</a> 8186 <a class="footer-bottom-link block text-s mt-3 mb-3 laptop:mb-0" href="https://www.justspices.de/gewuerzmischungen/italienisch.html" data-event="ev" data-category="footer" data-action="links" data-label="Italienische Gewürzmischungen">Italienische Gewürze</a> 8187 <a class="footer-bottom-link block text-s mt-3" href="https://www.justspices.de/gewuerzmischungen/asiatisch.html" data-event="ev" data-category="footer" data-action="links" data-label="Asiatische Gewürzmischungen">Asiatische Gewürze</a> 8188 <a class="footer-bottom-link block text-s mt-3" href="https://www.justspices.de/gewuerzmischungen/orientalisch.html" data-event="ev" data-category="footer" data-action="links" data-label="Orientalische Gewürzmischungen">Orientalische Gewürze</a> 8189 <a class="footer-bottom-link block text-s mt-3" href="https://www.justspices.de/gewuerzmischungen/mexikanisch.html" data-event="ev" data-category="footer" data-action="links" data-label="Mexikanische Gewürzmischungen">Mexikanische Gewürze</a> 8190 <a class="footer-bottom-link block text-s mt-3" href="https://www.justspices.de/gewuerzmischungen/griechisch.html" data-event="ev" data-category="footer" data-action="links" data-label="Griechische Gewürzmischungen">Griechische Gewürze</a> 8191 </div> 8192 <div> 8193 <a class="footer-bottom-link block text-s mt-3" href="https://www.justspices.de/gewuerzmischungen/backen-und-suesses.html" data-event="ev" data-category="footer" data-action="links" data-label="Gewürzmischungen zum Backen">Zum Backen</a> 8194 <a class="footer-bottom-link block text-s mt-3" href="https://www.justspices.de/gewuerzmischungen/fruehstueck.html" data-event="ev" data-category="footer" data-action="links" data-label="Gewürzmischungen zum Frühstück">Zum Frühstück</a> 8195 <a class="footer-bottom-link block text-s mt-3" href="https://www.justspices.de/gewuerzmischungen/fleisch.html" data-event="ev" data-category="footer" data-action="links" data-label="Gewürzmischungen für Fleisch">Für Fleisch</a> 8196 <a class="footer-bottom-link block text-s mt-3" href="https://www.justspices.de/gewuerzmischungen/fisch.html" data-event="ev" data-category="footer" data-action="links" data-label="Gewürzmischungen für Fisch">Für Fisch</a> 8197 <a class="footer-bottom-link block text-s mt-3" href="https://www.justspices.de/gewuerzmischungen/kartoffeln.html" data-event="ev" data-category="footer" data-action="links" data-label="Gewürzmischungen für Kartoffeln">Für Kartoffeln</a> 8198 <a class="footer-bottom-link block text-s mt-3" href="https://www.justspices.de/gewuerzmischungen/gemuese.html" data-event="ev" data-category="footer" data-action="links" data-label="Gewürzmischungen für Gemüse">
8198Für Gemüse</a> 8199 </div> 8200 </div> 8201 </div> 8202 <div class="footer-navigation-link mb-3 laptop:mb-0 laptop:mr-13"> 8203 <div data-role="collapsible" class="flex w-full justify-between"> 8204 <p class="font-bold text-s">Just Spices</p> 8205 <i class="fa-regular fa-chevron-down text-m"></i> 8206 </div> 8207 <div data-role="content" style="display: none;"> 8208 <a class="footer-bottom-link block text-s mt-3" href="https://www.justspices.de/about" data-event="ev" data-category="footer" data-action="links" data-label="Ãber uns">Ãber uns</a> 8209 <a class="footer-bottom-link block text-s mt-3" href="https://www.justspices.de/jobs" data-event="ev" data-category="footer" data-action="links" data-label="Jobs">Jobs</a> 8210 <a class="footer-bottom-link block text-s mt-3" href="https://www.justspices.de/presse" data-event="ev" data-category="footer" data-action="links" data-label="Presse">Presse</a> 8211 <a class="footer-bottom-link block text-s mt-3" href="https://www.justspices.de/storefinder" data-event="ev" data-category="footer" data-action="links" data-label="Store Finder">Store Finder</a> 8212 </div> 8213 </div> 8214 <div class="footer-navigation-link mb-3 laptop:mb-0"> 8215 <div data-role="collapsible" class="flex w-full justify-between"> 8216 <p class="font-bold text-s">Hilfe & Kontakt</p> 8217 <i class="fa-regular fa-chevron-down text-m"></i> 8218 </div> 8219 <div data-role="content" style="display: none;"> 8220 <a class="footer-bottom-link block text-s mt-3" href="https://www.justspices.de/kontakt" data-event="ev" data-category="footer" data-action="links" data-label="Kontakt">Kontakt</a> 8221 <a class="footer-bottom-link block text-s mt-3" href="https://www.justspices.de/impressum" data-event="ev" data-category="footer" data-action="links" data-label="Impressum">Impressum</a> 8222 <a class="footer-bottom-link block text-s mt-3" href="#" data-acsb-custom-trigger="true" data-event="ev" data-category="footer" data-action="links" data-label="Barrierefreiheit">Barrierefreiheit</a> 8223 </div> 8224 </div> 8225 </div> 8226 <div class="w-full border-b-[2px] border-solid border-main-black mb-3 laptop:hidden"></div> 8227 <div class="language-selection laptop:order-5 laptop:w-full"> 8228 <select id="language-selection-dropdown" class="fs-14 lh-16 font-bold"> 8229 <option value="">⬠EUR</option> 8230 <option value="https://www.justspices.es">⬠ES</option> 8231 <option value="https://www.justspices.co.uk">£ UK</option> 8232 <option value="https://www.justspices.com">$ US</option> 8233 </select> 8234 </div> 8235 <div class="required-links mt-4 laptop:mt-5 flex flex-wrap gap-2 mb-13 laptop:order-6"> 8236 <a class="text-xs" href="https://www.justspices.de/impressum" title="Impressum">Impressum</a> 8237 <a class="text-xs" href="https://www.justspices.de/agb" title="AGB">AGB</a> 8238 <a class="text-xs" href="https://www.justspices.de/widerruf" title="Widerrufsbelehrung">Widerrufsbelehrung</a> 8239 <a class="text-xs" href="https://www.justspices.de/datenschutz" title="Datenschutz">Datenschutz</a> 8240 <a class="text-xs" href="https://www.justspices.de/erklaerung-zur-barrierefreiheit" title="Erklärung zur Barrierefreiheit">Barrierefreiheit</a> 8241 </div> 8242 8243</div>
8244<script> 8245 let accordionFooterLinks = document.getElementById('accordion-footer-links'); 8246 8247 if (accordionFooterLinks) { 8248 jQuery(document).ready(function () { 8249 let accordionContentItems = accordionFooterLinks.querySelectorAll('[data-role="content"]'); 8250 accordionContentItems.forEach((accordionContentItem) => { 8251 accordionContentItem.style.display = "none"; 8252 }); 8253 }); 8254 8255 let accordionItems = accordionFooterLinks.querySelectorAll('[data-role="collapsible"]'); 8256 accordionItems.forEach((accordionItem) => { 8257 accordionItem.onclick = function () { 8258 toggleAccordion(this); 8259 }; 8260 }); 8261 } 8262 8263 8264 function toggleAccordion(element) { 8265 let collapseContainer = element.parentElement.querySelector('[data-role="content"]'); 8266 8267 element.classList.toggle("active"); 8268 collapseContainer.classList.toggle("block"); 8269 if(collapseContainer.style.display === "none") { 8270 collapseContainer.style.display = "block"; 8271 } else { 8272 collapseContainer.style.display = "none"; 8273 } 8274 8275 } 8276 8277 document.getElementById('language-selection-dropdown').addEventListener('change', function() { 8278 const url = this.value; 8279 if (url) { 8280 window.location.href = url; 8281 } 8282 }); 8283</script>
8283</div><div data-content-type="html" data-appearance="default" data-element="main" data-decoded="true"><style> 8284.vlogin-index-check footer .newsletter-section, 8285.vlogin-index-check footer .social-section, 8286.vlogin-index-check footer .footer-navigation, 8287.vlogin-index-check footer .language-selection, 8288.vlogin-index-check footer .info-icons, 8289.vlogin-index-check footer .w-full.border-solid, 8290.vlogin-index-index footer .newsletter-section, 8291.vlogin-index-index footer .social-section, 8292.vlogin-index-index footer .footer-navigation, 8293.vlogin-index-index footer .language-selection, 8294.vlogin-index-index footer .info-icons, 8295.vlogin-index-index footer .w-full.border-solid { 8296 display: none !important; 8297} 8298</style></div><div data-content-type="html" data-appearance="default" data-element="main" data-decoded="true">
8298<script> 8299 let currentUrl = window.location.href; 8300 if(currentUrl.includes('vlogin/index/index')) { 8301 document.querySelector('.login-register-container h1').innerText = 'Melde Dich jetzt im Konto an'; 8302 document.querySelector('.login-register-container p.pt-1.text-center.fs-16.lh-24').innerText = '...und dann gehts ab zur Kasse. So sammelst Du mit Deinem Einkauf Punkte, die Du anschlieÃend einlösen kannst.'; 8303 } 8304 8305 if(currentUrl.includes('vlogin/index/check')) { 8306 document.querySelector('.login-register-container h1').innerText = 'Einloggen oder registrieren'; 8307 document.querySelector('.login-register-container p.pt-1.text-center.fs-16.lh-24').innerText = 'Gib zum Fortfahren Deine E-Mailadresse ein'; 8308 } 8309</script>
8309</div></div></footer>
8309<script type="text/javascript"> 8310 let lazyLoadInstance = new LazyLoad({ 8311 // Your custom settings go here 8312 elements_selector: ".lozad", 8313 }); 8314</script>
8314 8315
8316<script> 8317 (() => { 8318 function src_default(Alpine) { 8319 Alpine.directive("intersect", (el, { value, expression, modifiers }, { evaluateLater, cleanup }) => { 8320 let evaluate = evaluateLater(expression); 8321 let options = { 8322 rootMargin: getRootMargin(modifiers), 8323 threshold: getThreshhold(modifiers) 8324 }; 8325 let observer = new IntersectionObserver((entries) => { 8326 entries.forEach((entry) => { 8327 if (entry.isIntersecting === (value === "leave")) 8328 return; 8329 evaluate(); 8330 modifiers.includes("once") && observer.disconnect(); 8331 }); 8332 }, options); 8333 observer.observe(el); 8334 cleanup(() => { 8335 observer.disconnect(); 8336 }); 8337 }); 8338 } 8339 function getThreshhold(modifiers) { 8340 if (modifiers.includes("full")) 8341 return 0.99; 8342 if (modifiers.includes("half")) 8343 return 0.5; 8344 if (!modifiers.includes("threshold")) 8345 return 0; 8346 let threshold = modifiers[modifiers.indexOf("threshold") + 1]; 8347 if (threshold === "100") 8348 return 1; 8349 if (threshold === "0") 8350 return 0; 8351 return Number(`.${threshold}`); 8352 } 8353 function getLengthValue(rawValue) { 8354 let match = rawValue.match(/^(-?[0-9]+)(px|%)?$/); 8355 return match ? match[1] + (match[2] || "px") : void 0; 8356 } 8357 function getRootMargin(modifiers) { 8358 const key = "margin"; 8359 const fallback = "0px 0px 0px 0px"; 8360 const index = modifiers.indexOf(key); 8361 if (index === -1) 8362 return fallback; 8363 let values = []; 8364 for (let i = 1; i < 5; i++) { 8365 values.push(getLengthValue(modifiers[index + i] || "")); 8366 } 8367 values = values.filter((v) => v !== void 0); 8368 return values.length ? values.join(" ").trim() : fallback; 8369 } 8370 8371 document.addEventListener("alpine:init", () => { 8372 window.Alpine.plugin(src_default); 8373 }); 8374 })(); 8375</script>
vendor: 1 bytes, line 8375
8375
8376<script> 8377 for (const [selector, deferUntil] of Object.entries({".product-slider section[x-data]":"intersect",".product-info [x-data]":"intersect","#filters-content [x-data]":"intersect","#review_form":"intersect","section[x-data^=initRecentlyViewedProductsComponent]":"intersect","#product_addtocart_form [x-data]":"intersect","#notice-cookie-block":"intersect"})) { 8378 document.querySelectorAll(selector).forEach(el => el.setAttribute('x-defer', `${deferUntil}`)); 8379 } 8380</script>
vendor: 1 bytes, line 8380
8380
8381<script> 8382 (function () { 8383 "use strict"; 8384 8385 const hasAlpine = new Promise(resolve => { 8386 window.addEventListener('alpine:initialized', resolve, {once: true, passive: true}); 8387 }); 8388 8389 const hasInteract = new Promise(resolve => { 8390 (events => { 8391 const onInteract = () => { 8392 resolve(); 8393 events.forEach(type => window.removeEventListener(type, onInteract)); 8394 } 8395 events.forEach(type => window.addEventListener(type, onInteract, {once: true, passive: true})) 8396 })(['touchstart', 'mouseover', 'wheel', 'scroll', 'keydown']) 8397 }); 8398 8399 const onIntersect = (el) => { 8400 return new Promise(resolve => { 8401 const observer = new IntersectionObserver(entries => { 8402 for (const entry of entries) { 8403 if (entry.isIntersecting) { 8404 observer.disconnect() 8405 resolve(); 8406 } 8407 } 8408 }, {}); 8409 observer.observe(el); 8410 }); 8411 } 8412 8413 function runComponent(el) { 8414 hasAlpine.then(() => { 8415 el.removeAttribute('x-ignore'); 8416 queueMicrotask(() => Alpine.initTree(el)); 8417 }); 8418 } 8419 8420 function initDeferredComponents() { 8421 document.querySelectorAll('[x-data][x-defer]').forEach(el => { 8422 el.setAttribute('x-ignore', ''); 8423 const deferUntil = (el.getAttribute('x-defer') || '').trim(); 8424 switch (deferUntil) { 8425 case 'interact': 8426 hasInteract.then(() => runComponent(el)); 8427 break; 8428 case 'intersect': 8429 onIntersect(el).then(() => runComponent(el)) 8430 break; 8431 case 'idle': 8432 window.requestIdleCallback 8433 ? window.requestIdleCallback(() => runComponent(el), {timeout: 4000}) 8434 : setTimeout(() => runComponent(el), 4000); 8435 break; 8436 case 'eager': 8437 runComponent(el); 8438 break; 8439 default: 8440 if (deferUntil.startsWith('event:') && deferUntil.length > 6) { 8441 window.addEventListener(deferUntil.substring(6), () => runComponent(el), {once: true, passive: true}); 8442 } 8443 } 8444 }); 8445 } 8446 8447 window.addEventListener('alpine:init', initDeferredComponents, {once: true, passive: true}); 8448 })() 8449</script>
8449 8450
8451<script type="module" 8452 src="https://www.justspices.de/static/version1790005904/frontend/Justspices/relaunch/de_DE/Hyva_Theme/js/alpine3.min.js" 8453 defer 8454 crossorigin 8455></script>
vendor: 1 bytes, line 8455
8455
8456<script> 8457 'use strict'; 8458 function dispatchMessages(messages, hideAfter) { 8459 const messagesEvent = new CustomEvent("messages-loaded", { 8460 detail: { 8461 messages: messages, 8462 hideAfter: hideAfter 8463 } 8464 }); 8465 window.dispatchEvent(messagesEvent); 8466 } 8467 8468 if (typeof hyva === 'undefined' || (!hyva.getBrowserStorage || !hyva.getCookie || !hyva.setCookie)) { 8469 console.warn("Hyvä helpers are not loaded yet. Make sure they are included before this script"); 8470 } 8471 8472 (function( hyva, undefined ) { 8473 8474 hyva.initFormKey = () => { 8475 const inputSelector = 'input[name="form_key"]', 8476 formKey = hyva.getFormKey(); 8477 8478 Array.from(document.querySelectorAll(inputSelector)).map(function (input) { 8479 input.value = formKey 8480 }); 8481 } 8482 8483 hyva.initMessages = () => { 8484 try { 8485 const messages = hyva.getCookie('mage-messages'); 8486 window.mageMessages = messages ? JSON.parse(decodeURIComponent(messages).replace(/\+/g, ' ')) : []; 8487 8488 dispatchMessages(window.mageMessages); 8489 8490 // empty `mage-messages` cookie 8491 const skipSetDomain = true; 8492 hyva.setCookie('mage-messages','', -1, skipSetDomain); 8493 8494 } catch (error) { 8495 console.warn('Error parsing Cookie Messages:', error); 8496 } 8497 } 8498 8499 window.addEventListener('DOMContentLoaded', hyva.initFormKey); 8500 hyva.alpineInitialized(hyva.initMessages) 8501 8502 }( window.hyva = window.hyva || {} )); 8503</script>
vendor: 1 bytes, line 8503
8503
8504<script> 8505 'use strict'; 8506 { 8507 const private_content_key = 'mage-cache-storage'; 8508 const private_content_expire_key = 'mage-cache-timeout'; 8509 const private_content_version_key = 'private_content_version'; 8510 const section_data_ids_key = 'section_data_ids'; 8511 const mage_cache_session_id_key = 'mage-cache-sessid'; 8512 const last_visited_store_key = 'last_visited_store'; 8513 8514 const ttl = 3600; 8515 8516 if (typeof hyva === 'undefined' || (!hyva.getBrowserStorage || !hyva.getCookie || !hyva.setCookie)) { 8517 console.warn("Hyvä helpers are not loaded yet. Make sure they are included before this script"); 8518 } 8519 8520 function loadSectionData () { 8521 const browserStorage = hyva.getBrowserStorage(); 8522 if (!browserStorage) { 8523 console.error('Please enable LocalStorage in your browser.'); 8524 typeof window.dispatchMessages !== "undefined" && window.dispatchMessages( 8525 [{ 8526 type: "warning", 8527 text: "Please enable LocalStorage in your browser." 8528 }] 8529 ); 8530 return; 8531 } 8532 try { 8533 let isInvalid = false; 8534 8535 if (hyva.getCookie(last_visited_store_key) !== CURRENT_STORE_CODE) { 8536 isInvalid = true; 8537 } 8538 hyva.setCookie(last_visited_store_key, CURRENT_STORE_CODE, false, false); 8539 8540 if (!hyva.getCookie(mage_cache_session_id_key)) { 8541 isInvalid = true; 8542 browserStorage.removeItem(private_content_key); 8543 const skipSetDomain = true; 8544 const days = false; 8545 hyva.setCookie(mage_cache_session_id_key, true, days, skipSetDomain) 8546 } 8547 8548 const cookieVersion = hyva.getCookie(private_content_version_key); 8549 const storageVersion = browserStorage.getItem(private_content_version_key); 8550 8551 if (cookieVersion && !storageVersion || cookieVersion !== storageVersion) { 8552 isInvalid = true; 8553 } 8554 8555 const privateContentExpires = browserStorage.getItem(private_content_expire_key); 8556 if (privateContentExpires && new Date(privateContentExpires) < new Date()) { 8557 browserStorage.removeItem(private_content_key); 8558 } 8559 8560 if (isInvalid && cookieVersion) { 8561 fetchPrivateContent([]); 8562 } else if (cookieVersion && storageVersion && cookieVersion === storageVersion) { 8563 const privateContent = JSON.parse(browserStorage.getItem(private_content_key)); 8564 if ( 8565 privateContent && 8566 privateContentExpires && 8567 privateContent.cart && 8568 privateContent.customer 8569 ) { 8570 dispatchPrivateContent(privateContent); 8571 } else { 8572 fetchPrivateContent([]); 8573 } 8574 } else { 8575 if (document.getElementById('default-section-data')) { 8576 const privateContent = JSON.parse(document.getElementById('default-section-data').innerText.trim()); 8577 dispatchPrivateContent(privateContent); 8578 } else { 8579 dispatchPrivateContent({}); 8580 } 8581 } 8582 8583 } catch (error) { 8584 console.warn('Error retrieving Private Content:', error); 8585 } 8586 window.localStorageLoaded = true; 8587 } 8588 8589 hyva.alpineInitialized(loadSectionData) 8590 window.addEventListener('reload-customer-section-data', loadSectionData); 8591 8592 window.addEventListener('reload-private-content', function (event) { 8593 fetchPrivateContent(event.detail.section); 8594 }); 8595 8596 function dispatchPrivateContent(data) { 8597 const privateContentEvent = new CustomEvent("private-content-loaded", { 8598 detail: { 8599 data: data 8600 } 8601 }); 8602 window.dispatchEvent(privateContentEvent); 8603 } 8604 8605 function fetchPrivateContent(sections) { 8606 fetch(`${BASE_URL}customer/section/load/?sections=${encodeURIComponent(sections.join(','))}`, { 8607 method: 'GET', 8608 headers: { 8609 'Content-Type': 'application/json', 8610 'X-Requested-With': 'XMLHttpRequest' 8611 } 8612 }) 8613 .then(response => response.json()) 8614 .then( 8615 data => { 8616 if (data) { 8617 try { 8618 const browserStorage = hyva.getBrowserStorage(); 8619 8620 // merge new data preserving non-invalidated sections 8621 const oldSectionData = JSON.parse(browserStorage.getItem(private_content_key) || '{}') || {}; 8622 8623 if ((! data.cart || ! data.cart.cartId) && oldSectionData['checkout-data']) { 8624 delete oldSectionData['checkout-data']; 8625 } 8626 const newSectionData = Object.assign(oldSectionData, data); 8627 8628 // don't persist messages, they've been dispatched already 8629 if (newSectionData.messages && newSectionData.messages.messages ) { 8630 newSectionData.messages.messages = []; 8631 } 8632 8633 browserStorage.setItem(private_content_key, JSON.stringify(newSectionData)); 8634 8635 const expiresAt = new Date(Date.now() + (ttl * 1000)).toISOString(); 8636 browserStorage.setItem(private_content_expire_key, expiresAt); 8637 8638 const newCookieVersion = hyva.getCookie(private_content_version_key); 8639 browserStorage.setItem(private_content_version_key, newCookieVersion); 8640 8641 // We don't need the section_data_ids in Hyvä, but we store them for compatibility 8642 // with Luma Fallback. Otherwise, not all sections are loaded in Luma Checkout 8643 hyva.setCookie( 8644 section_data_ids_key, 8645 JSON.stringify( 8646 Object.keys(data).reduce((sectionDataIds, sectionKey) => { 8647 sectionDataIds[sectionKey] = data[sectionKey]['data_id']; 8648 return sectionDataIds; 8649 }, {}) 8650 ), 8651 false, 8652 true 8653 ); 8654 dispatchPrivateContent(newSectionData); 8655 } catch (error) { 8656 console.warn("Couldn't store privateContent", error); 8657 } 8658 } 8659 } 8660 ); 8661 } 8662 } 8663</script>
vendor: 1 bytes, line 8663
8663
8664<script> 8665 (() => { 8666 document.addEventListener('submit', event => event.target.action = event.target.action.replace('%25uenc%25', hyva.getUenc())); 8667 })() 8668</script>
vendor: 1 bytes, line 8668
8668
8669<script> 8670 (events => { 8671 const dispatchUserInteractionEvent = () => { 8672 events.forEach(type => window.removeEventListener(type, dispatchUserInteractionEvent)) 8673 window.dispatchEvent(new Event('init-external-scripts')) 8674 }; 8675 events.forEach(type => window.addEventListener(type, dispatchUserInteractionEvent, {once: true, passive: true})) 8676 })(['touchstart', 'mouseover', 'wheel', 'scroll', 'keydown']) 8677</script>
vendor: 1 bytes, line 8677
8677
8678<script> 8679 function initConfigurableOptions(productId, optionConfig) { 8680 8681 function findPathParam(key) { 8682 const baseUrl = (BASE_URL.substring(0, 2) === '//' ? 'http:' : '') + BASE_URL; 8683 const baseUrlParts = (new URL(baseUrl)).pathname.replace(/\/$/, '').split('/'); 8684 const pathParts = window.location.pathname.split('/').slice(baseUrlParts.length + 3); 8685 for (let i = 0; i < pathParts.length; i += 2) { 8686 if (pathParts[i] === key && pathParts.length > i) { 8687 return pathParts[i + 1]; 8688 } 8689 } 8690 } 8691 8692 return { 8693 optionConfig, 8694 productId, 8695 itemId: (new URLSearchParams(window.location.search)).get('id') || findPathParam('id'), 8696 allowedAttributeOptions: [], 8697 selectedValues: [], 8698 init() { 8699 this.findAllowedAttributeOptions(); 8700 this.$nextTick(() => { 8701 if (typeof this.optionConfig.defaultValues === 'object') { 8702 for (const [attributeId, value] of Object.entries(this.optionConfig.defaultValues)) { 8703 this.changeOption(attributeId, value + ''); 8704 } 8705 } 8706 }); 8707 }, 8708 findSimpleIndex() { 8709 this.productIndex = this.calculateSimpleIndexForPartialSelection(this.selectedValues); 8710 }, 8711 calculateSimpleIndexForPartialSelection(selectedValues) { 8712 if (selectedValues.length === 0) return 0; 8713 let productIndexIds = Object.keys(this.optionConfig.index); 8714 Object.keys(this.optionConfig.attributes).forEach((attribute) => { 8715 const productsWithAttributeMatch = selectedValues[attribute] 8716 ? productIndexIds.filter((productIndex) => { 8717 return this.optionConfig.index[productIndex][attribute] === this.selectedValues[attribute] 8718 }) 8719 : []; 8720 8721 productIndexIds = productsWithAttributeMatch.length ? productsWithAttributeMatch : productIndexIds 8722 }) 8723 return productIndexIds[0]; 8724 }, 8725 calculateSimpleIndexForFullSelection(selectedValues) { 8726 const productIndexes = this.optionConfig.index; 8727 return Object.keys(productIndexes).find(productIndex => { 8728 const productCandidateOptions = productIndexes[productIndex]; 8729 8730 for (const productOption in productCandidateOptions) { 8731 if ( 8732 ! selectedValues[productOption] || 8733 selectedValues[productOption] !== productCandidateOptions[productOption] 8734 ) { 8735 return false; 8736 } 8737 } 8738 return productIndex; 8739 }); 8740 }, 8741 productIndex: 0, 8742 findAllowedAttributeOptions() { 8743 this.allowedAttributeOptions = this.calculateAllowedAttributeOptions(this.selectedValues); 8744 }, 8745 calculateAllowedAttributeOptions(selectedValues) { 8746 const allAttributes = this.optionConfig.attributes; 8747 const allAttributesSorted = Object.values(allAttributes).sort((a,b) => { 8748 return a.position - b.position 8749 }); 8750 8751 const newAllowedAttributeOptions = []; 8752 8753 allAttributesSorted.forEach(attribute => { 8754 const selectionWithoutAttr = Object.assign({}, this.removeAttrFromSelection(selectedValues, attribute.id)); 8755 const availableIndexes = this.calculateAvailableProductIndexes(selectionWithoutAttr); 8756 newAllowedAttributeOptions[attribute.id] = allAttributes[attribute.id].options.filter(option => { 8757 return !!option.products.find(product => { 8758 return availableIndexes.includes(product); 8759 }) 8760 }); 8761 }); 8762 return newAllowedAttributeOptions; 8763 }, 8764 calculateAvailableProductIndexes(selectedOptions) { 8765 if (Object.keys(selectedOptions).length === 0) { 8766 if (Object.values(this.optionConfig.salable || {}).length) { 8767 return [].concat.apply([], [].concat.apply([], Object.values(this.optionConfig.salable).map(Object.values))).filter((x, i, a) => a.indexOf(x) === i) 8768 } 8769 return Object.keys(this.optionConfig.index); 8770 } 8771 8772 const selectedIds = Object.keys(selectedOptions); 8773 if (Object.values(this.optionConfig.salable || {}).length) { 8774 const selectedOptionIndexes = selectedIds.map(attrId => { 8775 const optionValue = selectedOptions[attrId]; 8776 return this.optionConfig.salable[attrId] && this.optionConfig.salable[attrId][optionValue] || [] 8777 }) 8778 return selectedOptionIndexes.reduce((acc, optionIndexes) => { 8779 return acc.filter(index => optionIndexes.includes(index)); 8780 }); 8781 } else { 8782 const productIndexes = this.optionConfig.index; 8783 return Object.keys(productIndexes).filter(index => { 8784 for (const attrId of selectedIds) { 8785 if (productIndexes[index][attrId] !== `${selectedOptions[attrId]}`) return false 8786 } 8787 return true 8788 }); 8789 } 8790 }, 8791 findAttributeByOptionId(optionId) { 8792 for (const attributeId in this.optionConfig.attributes) { 8793 const attributeOptions = this.optionConfig.attributes[attributeId].options || []; 8794 if (attributeOptions.find(option => option.id === optionId)) { 8795 return attributeId; 8796 } 8797 } 8798 }, 8799 getAllowedAttributeOptions(attributeId) { 8800 return this.allowedAttributeOptions[attributeId] || [] 8801 }, 8802 getProductIdsForOption(option) { 8803 const attributeId = this.findAttributeByOptionId(option.id); 8804 const allOptions = this.optionConfig.attributes[attributeId]; 8805 const opt = (allOptions && allOptions.options || []).find(o => o.id === option.id); 8806 return opt && opt.products 8807 ? opt.products 8808 : []; 8809 }, 8810 findProductIdsForPartialSelection(optionSelection) { 8811 const candidateProducts = Object.values(optionSelection).reduce((candidates, optionId) => { 8812 const newCandidates = this.getProductIdsForOption({id: optionId}); 8813 return candidates === null 8814 ? newCandidates 8815 : candidates.filter(productId => newCandidates.includes(productId)); 8816 }, null); 8817 return candidateProducts || []; 8818 },
8819 findCheapestProductForPartialSelection(optionSelection) { 8820 const candidateProducts = this.findProductIdsForPartialSelection(optionSelection); 8821 return candidateProducts.reduce((cheapest, simpleIdx) => { 8822 // in the first iteration we start with simpleIdx as the currently cheapest product 8823 if (! this.optionConfig.optionPrices[cheapest]) return simpleIdx; 8824 const knownCheapestPrice = this.optionConfig.optionPrices[cheapest].finalPrice.amount; 8825 return knownCheapestPrice > this.optionConfig.optionPrices[simpleIdx].finalPrice.amount 8826 ? simpleIdx 8827 : cheapest; 8828 }, 0) 8829 }, 8830 findProductIdToUseForOptionPrice(option) { 8831 // try to find a product for a complete selection 8832 const attributeId = this.findAttributeByOptionId(option.id); 8833 const optionSelection = Object.assign({}, this.selectedValues, {[attributeId]: option.id}); 8834 const matchingSimpleIndex = this.calculateSimpleIndexForFullSelection(optionSelection); 8835 // if there is no complete selection, use the cheapest product for the option 8836 return matchingSimpleIndex || this.findCheapestProductForPartialSelection(optionSelection); 8837 }, 8838 getAttributeOptionLabel(option) { 8839 const optionProduct = this.findProductIdToUseForOptionPrice(option); 8840 if ((! optionProduct) || (optionProduct === this.productIndex)) { 8841 return option.label; 8842 } 8843 8844 const currentPrice = this.getOptionPriceAdjustmentBasePrice(); 8845 8846 if (this.optionConfig.optionPrices[optionProduct]) { 8847 const optionPrice = this.optionConfig.optionPrices[optionProduct].finalPrice.amount; 8848 if (optionPrice !== currentPrice){ 8849 return option.label + ' ' + hyva.formatPrice(optionPrice - currentPrice, true); 8850 } 8851 } 8852 return option.label; 8853 }, 8854 getOptionPriceAdjustmentBasePrice() { 8855 if (this.optionConfig.optionPrices[this.productIndex]) { 8856 return this.optionConfig.optionPrices[this.productIndex].finalPrice.amount 8857 } 8858 const cheapestForSelection = this.findCheapestProductForPartialSelection(this.selectedValues); 8859 return this.optionConfig.optionPrices[cheapestForSelection] 8860 ? this.optionConfig.optionPrices[cheapestForSelection].finalPrice.amount 8861 : this.optionConfig.prices.finalPrice.amount; // default price if no option selection 8862 }, 8863 clearOptionIfActive(optionId, value) { 8864 if (this.selectedValues[optionId] === value) { 8865 this.blurLabel() 8866 this.changeOption(optionId, '') 8867 } 8868 }, 8869 removeAttrFromSelection(selectedValues, attributeId) { 8870 attributeId = parseInt(attributeId); 8871 return selectedValues.reduce((newSelection, val, attr) => { 8872 if (attr !== attributeId) { 8873 newSelection[attr] = val; 8874 } 8875 return newSelection; 8876 }, []); 8877 }, 8878 changeOption(attributeId, value) { 8879 if (value === '') { 8880 this.selectedValues = this.removeAttrFromSelection(this.selectedValues, attributeId) 8881 } else if (value && this.getAllowedAttributeOptions(attributeId).find(option => option.id === value)) { 8882 this.selectedValues[attributeId] = value; 8883 } 8884 this.findSimpleIndex(); 8885 this.findAllowedAttributeOptions(); 8886 this.updatePrices(); 8887 this.updateGallery(); 8888 window.dispatchEvent( 8889 new CustomEvent( 8890 'configurable-selection-changed', 8891 { 8892 detail: { 8893 productId: this.productId, 8894 optionId: attributeId, 8895 value: value, 8896 productIndex: this.productIndex, 8897 selectedValues: this.selectedValues, 8898 candidates: this.findProductIdsForPartialSelection(this.selectedValues), 8899 } 8900 } 8901 ) 8902 ); 8903 }, 8904 calculateIsMinimalPrice() { 8905 return ( 8906 this.selectedValues.filter(value => !!value).length < 8907 Object.keys(this.optionConfig.attributes).length 8908 ); 8909 }, 8910 updatePrices() { 8911 const value = this.productIndex ? 8912 this.optionConfig.optionPrices[this.productIndex] : 8913 this.optionConfig.prices; 8914 window.dispatchEvent( 8915 new CustomEvent( 8916 "update-prices-" + this.productId, 8917 { 8918 detail: Object.assign( 8919 value, 8920 { isMinimalPrice: this.calculateIsMinimalPrice() } 8921 ) 8922 } 8923 ) 8924 ); 8925 }, 8926 updateGallery () { 8927 if (this.productIndex) { 8928 const images = this.optionConfig.images[this.productIndex]; 8929 images && window.dispatchEvent(new CustomEvent( 8930 "update-gallery", 8931 { detail: this.sortImagesByPosition(images) } 8932 )); 8933 } else { 8934 window.dispatchEvent(new Event("reset-gallery")); 8935 } 8936 }, 8937 sortImagesByPosition(images) { 8938 return images.sort((x, y) => { 8939 return x.position === y.position ? 0 : (parseInt(x.position) > parseInt(y.position) ? 1 : -1) 8940 }); 8941 }, 8942 onGetCartData(data) { 8943 }, 8944 preselectCartItems(data) { 8945 // pre-select options based on cart data for current (quote) itemId 8946 const cart = data && data.cart; 8947 if (cart && cart.items) { 8948 const cartItem = cart.items.find((item) => { 8949 return ( 8950 item.item_id === this.itemId 8951 && item.product_id === this.productId 8952 ) 8953 }); 8954 if (cartItem && cartItem.options && cartItem.options.length) { 8955 cartItem.options.map(option => { 8956 this.changeOption(option.option_id, option.option_value); 8957 }) 8958 } 8959 } 8960 }, 8961 preselectQuerystringItems() { 8962 // pre-select option like ?size=167 8963 const urlQueryParams = new URLSearchParams(window.location.search.replace('?','')); 8964 this.preselectItemsBasedOnLocation(attribute => urlQueryParams.get(attribute.code)); 8965 }, 8966 preselectLocationHashItems() { 8967 // pre-select option like #144=167 8968 const urlHashParams = new URLSearchParams(window.location.hash.replace('#','')); 8969 this.preselectItemsBasedOnLocation(attribute => urlHashParams.get(attribute.id)); 8970 }, 8971 preselectItemsBasedOnLocation(getLocationValue) { 8972 Object.values(this.optionConfig.attributes).map(attribute => { 8973 this.changeOption(attribute.id, getLocationValue(attribute)) 8974 }); 8975 } 8976 } 8977 } 8978 8979</script>
vendor: 1 bytes, line 8979
8979
8980<script> 8981 function initSwatchOptions(swatchConfig) { 8982 return { 8983 swatchConfig, 8984 getAttributeSwatchData(attributeId) { 8985 const swatchConfig = Object.assign({}, this.swatchConfig[attributeId]); 8986 swatchConfig['details'] = JSON.parse(swatchConfig['additional_data']); 8987 8988 return swatchConfig; 8989 }, 8990 getAllAttributeOptions(attributeId) { 8991 return ( 8992 this.optionConfig.attributes[attributeId] && 8993 this.optionConfig.attributes[attributeId].options 8994 ) || [] 8995 }, 8996 optionIsActive(attributeId, optionId) { 8997 // return true if a product with this option is in stock 8998 return !!this.getAllowedAttributeOptions(attributeId).find( 8999 option => option.id === optionId 9000 ) 9001 }, 9002 optionIsEnabled(attributeId, optionId) { 9003 // return true if a product with this option is enabled 9004 for (const productId in this.optionConfig.index) { 9005 if (this.optionConfig.index[productId][attributeId] === optionId) { 9006 return true; 9007 } 9008 } 9009 return false; 9010 }, 9011 mapSwatchTypeNumberToTypeCode(typeNumber) { 9012 switch ("" + typeNumber) { 9013 case "1": 9014 return "color" 9015 case "2": 9016 return "image" 9017 case "3": 9018 return "empty" 9019 case "0": 9020 default: 9021 return "text" 9022 } 9023 }, 9024 getTypeOfFirstOption(attributeId) { 9025 for (const optionId in this.swatchConfig[attributeId]) { 9026 const option = this.swatchConfig[attributeId][optionId]; 9027 if (typeof option.type !== 'undefined') { 9028 return this.mapSwatchTypeNumberToTypeCode(option.type); 9029 } 9030 } 9031 }, 9032 getVisualSwatchType(attributeId, targetOptionId) { 9033 // If a type configuration is present for the given option id, use it 9034 const config = this.swatchConfig[attributeId]; 9035 if (config[targetOptionId] && typeof config[targetOptionId].type !== 'undefined') { 9036 return this.mapSwatchTypeNumberToTypeCode(config[targetOptionId].type); 9037 } 9038 9039 // Otherwise - if no config is present for the target option - use the type of the first option 9040 // with a type property from the attribute, thus assuming its the same type as the target option. 9041 // (This edge case condition can occur on single swatch products if some options are not salable) 9042 return this.getTypeOfFirstOption(attributeId); 9043 }, 9044 getSwatchType(attributeId, optionId) { 9045 // Deserialize the attribute details the first time they are used 9046 if (this.swatchConfig[attributeId] && ! this.swatchConfig[attributeId].details) { 9047 this.swatchConfig[attributeId] = this.getAttributeSwatchData(attributeId); 9048 } 9049 const type = this.swatchConfig[attributeId] && 9050 this.swatchConfig[attributeId].details && 9051 this.swatchConfig[attributeId].details.swatch_input_type || 9052 "empty"; 9053 return type === 'visual' ? this.getVisualSwatchType(attributeId, optionId) : type; 9054 }, 9055 isTextSwatch(attributeId, optionId) { 9056 return this.getSwatchType(attributeId, optionId) === 'text'; 9057 }, 9058 isVisualSwatch(attributeId, optionId) { 9059 const type = this.getSwatchType(attributeId, optionId); 9060 9061 return ['image', 'color'].includes(type); 9062 }, 9063 getSwatchBackgroundStyle(attributeId, optionId) {
9064 const config = this.getSwatchConfig(attributeId, optionId); 9065 const type = this.getSwatchType(attributeId, optionId); 9066 9067 if (type === "color") { 9068 return 'background-color:' + config.value; 9069 } else if (type === "image") { 9070 return "background: #ffffff url('" + config.value + "') no-repeat center"; 9071 } else { 9072 return ''; 9073 } 9074 }, 9075 getSwatchText(attributeId, optionId) { 9076 const config = this.getSwatchConfig(attributeId, optionId); 9077 return config.label || config.value || this.getOptionLabelFromOptionConfig(attributeId, optionId); 9078 }, 9079 getOptionLabelFromOptionConfig(attributeId, optionId) { 9080 // Fallback if no value is present in swatchConfig data 9081 // Reference issue https://gitlab.hyva.io/hyva-themes/magento2-default-theme/-/issues/190 9082 const option = this.getAllAttributeOptions(attributeId).filter(option => option.id === optionId); 9083 return option && option[0] && option[0].label ||''; 9084 }, 9085 getSwatchConfig(attributeId, optionId) { 9086 return this.swatchConfig[attributeId] && this.swatchConfig[attributeId][optionId] 9087 ? this.swatchConfig[attributeId][optionId] 9088 : false; 9089 }, 9090 activeTooltipItem: false, 9091 tooltipPositionElement: false, 9092 isTooltipVisible() { 9093 return this.activeTooltipItem &&
9094 this.getSwatchConfig( 9095 this.activeTooltipItem.attribute, 9096 this.activeTooltipItem.item 9097 ); 9098 }, 9099 isFirstItemCol() { 9100 return this.activeTooltipItem.index === 0; 9101 }, 9102 getTooltipImageStyle(attributeId, optionId) { 9103 const config = this.getSwatchConfig(attributeId, optionId); 9104 const type = this.getSwatchType(attributeId, optionId); 9105 9106 if (type === "color") { 9107 return 'background-color:' + config.value + '; width: 110px; height: 90px;'; 9108 } else if (type === "image") { 9109 return "background: #ffffff url('" + config.thumb + 9110 "') center center no-repeat; width: 110px; height: 90px;"; 9111 } else { 9112 return 'display:none'; 9113 } 9114 }, 9115 getTooltipPosition() { 9116 return this.tooltipPositionElement ? 9117 `top: ${this.tooltipPositionElement.offsetTop}px;` + 9118 `left: ${ 9119 this.tooltipPositionElement.offsetLeft - ( 9120 this.tooltipPositionElement.closest('.snap') && 9121 this.tooltipPositionElement.closest('.snap').scrollLeft || 9122 0 9123 ) 9124 }px;` : '' 9125 }, 9126 getTooltipLabel() { 9127 return this.getSwatchConfig(this.activeTooltipItem.attribute, this.activeTooltipItem.item).label 9128 }, 9129 focusedLabel: false, 9130 focusLabel(optionId) { 9131 this.focusedLabel = optionId; 9132 }, 9133 blurLabel() { 9134 this.focusedLabel = false; 9135 }, 9136 showSwatches: false, 9137 initShowSwatchesIntersect() { 9138 if ('IntersectionObserver' in window && !window.scrollY) { 9139 let io = new IntersectionObserver( 9140 entries => { 9141 entries.map(entry => { 9142 if (entry.isIntersecting) { 9143 this.showSwatches = true; 9144 io.unobserve(this.$root); 9145 } 9146 }) 9147 } 9148 ); 9149 io.observe(this.$root); 9150 } else { 9151 this.showSwatches = true 9152 } 9153 } 9154 } 9155 } 9156</script>
vendor: 1 bytes, line 9156
9156
9157<script> 9158 'use strict'; 9159 9160 const grecaptchaV2LoadCallbacks = []; 9161 9162 function executeRecaptchaLoadCallbacks () { 9163 while (window.grecaptcha && grecaptchaV2LoadCallbacks.length > 0) { 9164 const callback = grecaptchaV2LoadCallbacks.pop(); 9165 typeof callback === 'string' ? window[callback]() : callback(); 9166 } 9167 } 9168 9169 (function() { 9170 const loadRecaptchaScript = (event) => { 9171 9172 if (window.grecaptcha || !event.target.form) { 9173 return; 9174 } 9175 9176 const url = 'https://www.google.com/recaptcha/api.js?onload=executeRecaptchaLoadCallbacks'; 9177 const siteKey = ''; 9178 const script = document.createElement('script'); 9179 script.type = 'text/javascript'; 9180 script.src = siteKey ? `${url}&render=${siteKey}` : `${url}&render=explicit`; 9181 script.async = true; 9182 document.head.appendChild(script); 9183 9184 script.addEventListener('load', () => { 9185 Array.from(document.querySelectorAll('button[data-recaptcha-btn]:disabled')).forEach(btn => btn.removeAttribute('disabled')); 9186 }); 9187 } 9188 9189 window.forceLoadRecaptchaScript = (form) => { 9190 loadRecaptchaScript({target: {form: form || 'dummy'}}); 9191 executeRecaptchaLoadCallbacks(); 9192 }; 9193 9194 document.body.addEventListener('input', loadRecaptchaScript, { once: true }); 9195 document.body.addEventListener('focus', loadRecaptchaScript, { once: true }); 9196 9197 }()); 9198 9199</script>
vendor: 1 bytes, line 9199
9199
9200<script> (function () { 9201 var s = document.createElement('script'); 9202 var h = document.querySelector('head') || document.body; 9203 s.src = 'https://acsbapp.com/apps/app/dist/js/app.js'; 9204 s.async = true; 9205 s.defer = true; 9206 s.onload = function () { 9207 acsbJS.init({ 9208 statementLink: '', 9209 footerHtml: '', 9210 hideMobile: false, 9211 hideTrigger: false, 9212 disableBgProcess: false, 9213 language: 'de', 9214 position: 'right', 9215 leadColor: '#00a57e', 9216 triggerColor: '#00a57e', 9217 triggerRadius: '50%', 9218 triggerPositionX: 'right', 9219 triggerPositionY: 'bottom', 9220 triggerIcon: 'people', 9221 triggerSize: 'medium', 9222 triggerOffsetX: 20, 9223 triggerOffsetY: 20, 9224 mobile: { 9225 triggerSize: 'small', 9226 triggerPositionX: 'right', 9227 triggerPositionY: 'center', 9228 triggerOffsetX: 10, 9229 triggerOffsetY: 0, 9230 triggerRadius: '50%' 9231 } 9232 }); 9233 }; 9234 h.appendChild(s); 9235 })(); </script>
9235 9236<div class="acsb-custom-trigger" id="acsb-custom-trigger">
9237<script>if(localStorage.getItem('acsb-trigger-hidden')==='1'){document.getElementById('acsb-custom-trigger').classList.add('acsb-custom-trigger--hidden')}</script>
9237 9238 <button class="acsb-custom-trigger__open" 9239 data-acsb-custom-trigger="true" 9240 aria-label="Open accessibility menu"> 9241 <svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" xml:space="preserve" viewBox="0 0 100 131.3" aria-hidden="true"> 9242 <path d="M71.6 131.3c1 0 2.1-.3 3.1-.8 3.9-1.8 5.5-6.2 3.6-10.1 0 0-14.3-32.7-16.9-44.7-1-4.2-1.6-15.3-1.8-20.5 0-1.8 1-3.4 2.6-3.9l32-9.6c3.9-1 6.2-5.5 5.2-9.4-1-3.9-5.5-6.2-9.4-5.2 0 0-29.6 9.6-40.3 9.6-10.4 0-39.8-9.4-39.8-9.4-3.9-1-8.3.8-9.6 4.7-1.3 4.2 1 8.6 5.2 9.6l32 9.6c1.6.5 2.9 2.1 2.6 3.9-.3 5.2-.8 16.4-1.8 20.5-2.6 12-16.9 44.7-16.9 44.7-1.8 3.9 0 8.3 3.6 10.1 1 .5 2.1.8 3.1.8 2.9 0 5.7-1.6 6.8-4.4l15.3-31.2L64.8 127c1.3 2.7 3.9 4.3 6.8 4.3z"/> 9243 <circle cx="50.3" cy="14.6" r="14.6"/> 9244 </svg> 9245 </button> 9246 <span class="acsb-custom-trigger__divider"></span> 9247 <button class="acsb-custom-trigger__close" 9248 aria-label="Hide accessibility button" 9249 onclick="localStorage.setItem('acsb-trigger-hidden','1');document.getElementById('acsb-custom-trigger').classList.add('acsb-custom-trigger--hidden')"> 9250 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="#000" stroke-width="1.5" stroke-linecap="round" aria-hidden="true"> 9251 <line x1="4" y1="4" x2="20" y2="20"/><line x1="20" y1="4" x2="4" y2="20"/> 9252 </svg> 9253 </button> 9254</div>
9255<script> 9256 'use strict'; 9257 9258 (function () { 9259 const modals = []; 9260 const excludedFromFocusTrapping = new Set(); 9261 9262 function trapFocusInNextModalWithOverlay() { 9263 for (let idx = modals.length -1; idx >= 0; idx--) { 9264 const nextOnStack = modals[idx]; 9265 const nextDialogElement = nextOnStack.instance.$refs[nextOnStack.name]; 9266 if (! isOverlayDisabled(nextDialogElement)) { 9267 hyva.trapFocus(nextDialogElement); 9268 break; 9269 } 9270 } 9271 } 9272 9273 function focusables(dialogElement) { 9274 const selector = 'button, [href], input, textarea, select, details, [tabindex]:not([tabindex="-1"])'; 9275 return Array.from(dialogElement.querySelectorAll(selector)) 9276 .filter(el => !el.hasAttribute('disabled')); 9277 } 9278 9279 function firstVisible(elements) { 9280 const a = Array.from(elements); 9281 for (let i = 0; i < a.length; i++) { 9282 if (a[i].offsetWidth || a[i].offsetHeight || a[i].getClientRects().length) return a[i]; 9283 } 9284 return null; 9285 } 9286 9287 function isInViewport(element) { 9288 const rect = element && element.getBoundingClientRect(); 9289 return rect && 9290 rect.top >= 0 && 9291 rect.left >= 0 && 9292 rect.right <= window.innerWidth && 9293 rect.bottom <= window.innerHeight; 9294 } 9295 9296 function setFocusAfterTransition(dialogElement, duration) { 9297 const nested = Array.from(dialogElement.querySelectorAll('[role="dialog"]')); 9298 const candidates = Array.from(dialogElement.querySelectorAll('[x-focus-first]')); 9299 next: for (let candidate of candidates) { 9300 for (let child of nested) { 9301 if (child.contains(candidate)) continue next; 9302 } 9303 setTimeout(() => candidate.focus(), 50); 9304 break; 9305 } 9306 window.setTimeout(() => { 9307 const focusElement = firstVisible(dialogElement.querySelectorAll('[x-focus-first]')) || 9308 focusables(dialogElement)[0] || 9309 null; 9310 focusElement && isInViewport(focusElement) && focusElement.focus(); 9311 }, Math.max(1, duration)); 9312 } 9313 9314 function determineTrigger($refs, dialog, trigger) { 9315 if (typeof trigger === 'undefined' && typeof dialog === 'object' && dialog.target instanceof HTMLElement) { 9316 return dialog.target; 9317 } 9318 if (typeof dialog === 'string' && typeof trigger === 'object' && trigger.target instanceof HTMLElement) { 9319 return trigger.target; 9320 } 9321 if (typeof trigger === 'string') { 9322 try { 9323 return $refs[trigger] || document.querySelector(trigger) 9324 } catch (e) {} 9325 } 9326 if (trigger instanceof Element) { 9327 return trigger; 9328 } 9329 9330 return null; 9331 } 9332 9333 function isOverlayDisabled(dialog) { 9334 return dialog && dialog.hasAttribute('x-no-overlay') 9335 } 9336 9337 function areRemainingModalsWithoutOverlay(modals) 9338 { 9339 const overflowDisabled = modals.map(modal => modal.instance.$refs[modal.name]).filter(isOverlayDisabled); 9340 9341 return overflowDisabled.length === modals.length; 9342 } 9343 9344 window.hyva.modal = function(options) { 9345 9346 const config = Object.assign({ 9347 dialog: 'dialog', duration: 300, transitionEnter: 'transition ease-out duration-300', 9348 transitionEnterStart: 'opacity-0', 9349 transitionEnterEnd: 'opacity-100', 9350 transitionLeave: 'transition ease-in duration-300', 9351 transitionLeaveStart: 'opacity-100', 9352 transitionLeaveEnd: 'opacity-0', 9353 }, options); 9354 let lastHide = 0; 9355 9356 return { 9357 opened: {}, 9358 show(dialog, trigger) { 9359 const focusTargetAfterHide = determineTrigger(this.$refs, dialog, trigger); 9360 const name = typeof dialog === 'string' ? dialog : config.dialog; 9361 const dialogElement = this.$refs[name]; 9362 if (! dialogElement) { 9363 return; 9364 } 9365 const useOverlay = ! dialogElement.hasAttribute('x-no-overlay'); 9366 9367 dialogElement.scrollTop = 0; 9368 9369 if (this.opened[name]) { 9370 return; 9371 } 9372 9373 if (focusTargetAfterHide) { 9374 focusTargetAfterHide.setAttribute('aria-expanded', 'true'); 9375 } 9376 9377 this.opened[name] = true; 9378 useOverlay && this.$nextTick(() => hyva.trapFocus(dialogElement)); 9379 setFocusAfterTransition(dialogElement, config.duration); 9380 9381 const frame = {name, instance: this, focusTarget: focu
9381sTargetAfterHide, time: Date.now()}; 9382 9383 modals.push(frame); 9384 if (useOverlay) { 9385 document.body.classList.add('overflow-hidden'); 9386 } 9387 return new Promise(resolve => frame.resolve = resolve); 9388 }, 9389 cancel() { 9390 this.hide(false); 9391 }, 9392 ok() { 9393 this.hide(true); 9394 }, 9395 hide(value) { 9396 if (Date.now() - lastHide < config.duration) { 9397 return; 9398 } 9399 lastHide = Date.now(); 9400 9401 const modal = modals.pop() || {}; 9402 const name = modal.name; 9403 this.opened[name] = false; 9404 hyva.releaseFocus(modal.instance.$refs[modal.name]) 9405 trapFocusInNextModalWithOverlay(); 9406 9407 const nextFocusAfterHide = modal.focusTarget; 9408 nextFocusAfterHide && setTimeout(() => { 9409 nextFocusAfterHide.setAttribute('aria-expanded', 'false'); 9410 nextFocusAfterHide.focus() 9411 }, config.duration); 9412 9413 if (modals.length === 0 || areRemainingModalsWithoutOverlay(modals)) { 9414 document.body.classList.remove('overflow-hidden'); 9415 } 9416 9417 modal.resolve(value); 9418 }, 9419 overlay(dialog) { 9420 const name = typeof dialog === 'string' ? dialog : config.dialog; 9421 return { 9422 ['x-show']() { 9423 return this.opened[name] 9424 }, 9425 ['x-transition:enter']: config.transitionEnter, 9426 ['x-transition:enter-start']: config.transitionEnterStart, 9427 ['x-transition:enter-end']: config.transitionEnterEnd, 9428 ['x-transition:leave']: config.transitionLeave, 9429 ['x-transition:leave-start']: config.transitionLeaveStart, 9430 ['x-transition:leave-end']: config.transitionLeaveEnd, 9431 ['@hyva-modal-show.window'](event) { 9432 event.detail && event.detail.dialog === name && this.show(name, event.detail.focusAfterHide) 9433 } 9434 }; 9435 } 9436 }; 9437 } 9438 9439 window.hyva.modal.peek = () => modals.length > 0 && modals[modals.length -1] 9440 9441 window.hyva.modal.pop = function () { 9442 if (modals.length > 0) { 9443 const modal = modals[modals.length -1]; 9444 modal.instance.hide(); 9445 } 9446 } 9447 9448 window.hyva.modal.excludeSelectorsFromFocusTrap = function (selectors) { 9449 typeof selectors === 'string' || selectors instanceof String 9450 ? excludedFromFocusTrapping.add(selectors) 9451 : selectors.map(selector => excludedFromFocusTrapping.add(selector)); 9452 } 9453 9454 window.hyva.modal.eventListeners = { 9455 keydown: event => { 9456 if (event.key === 'Escape') { 9457 window.hyva.modal.pop(); 9458 } 9459 }, 9460 click: event => { 9461 if (modals.length > 0) { 9462 const modal = modals[modals.length -1]; 9463 const dialog = modal.instance.$refs[modal.name]; 9464 if (modal.time + 50 < Date.now() && // if last click processing is more than 50ms ago 9465 ! isOverlayDisabled(dialog) && // if dialog has overlay 9466 ! dialog.contains(event.target)) { // if click is outside of dialog 9467 modal.instance.hide(); 9468 } 9469 } 9470 } 9471 }; 9472 9473 document.addEventListener('keydown', window.hyva.modal.eventListeners.keydown); 9474 9475 document.addEventListener('click', window.hyva.modal.eventListeners.click); 9476 })(); 9477</script>
9477 9478
9479<script> 9480 'use strict'; 9481 (() => { 9482 function _calculateStrength({elementID, valid}) { 9483 const password = document.getElementById(elementID), 9484 emailElm = document.getElementById('email_address'); 9485 let displayScore; 9486 // Display score is based on combination of whether password is empty, valid, and zxcvbn strength 9487 if (!password || !password.value) { 9488 displayScore = 0; 9489 } else { 9490 // We should only perform this check in case there is an email field on screen 9491 if (emailElm && password.value && emailElm.value && 9492 password.value.toLowerCase() === emailElm.value.toLowerCase()) { 9493 displayScore = 1; 9494 } else { 9495 const zxcvbnScore = zxcvbn(password.value).score; 9496 displayScore = valid && zxcvbnScore > 0 ? zxcvbnScore : 1; 9497 } 9498 } 9499 9500 _displayStrength(displayScore); 9501 } 9502 9503 function _displayStrength(displayScore) { 9504 let strengthLabel = '', 9505 className; 9506 9507 switch (displayScore) { 9508 case 0: 9509 strengthLabel = "Kein\u0020Passwort"; 9510 className = 'password-none'; 9511 break; 9512 9513 case 1: 9514 strengthLabel = "Schwach"; 9515 className = 'password-weak'; 9516 break; 9517 9518 case 2: 9519 strengthLabel = "Mittel"; 9520 className = 'password-medium'; 9521 break; 9522 9523 case 3: 9524 strengthLabel = "Sicher"; 9525 className = 'password-strong'; 9526 break; 9527 9528 case 4: 9529 strengthLabel = "Sehr\u0020sicher"; 9530 className = 'password-very-strong'; 9531 break; 9532 } 9533 const meterElm = document.getElementById('password-strength-meter-container'), 9534 meterLabelElm = document.getElementById('password-strength-meter-label'); 9535 meterElm.className = ''; 9536 meterElm.classList.add(className); 9537 meterLabelElm.textContent = strengthLabel; 9538 } 9539 9540 let loading = false; 9541 const callbacks = []; 9542 9543 function loadZxcvbn(cb) { 9544 callbacks.push(cb); 9545 if (loading) return; 9546 loading = true; 9547 9548 const script = document.createElement('script'); 9549 script.type = 'text/javascript'; 9550 script.src = 'https\u003A\u002F\u002Fwww.justspices.de\u002Fstatic\u002Fversion1790005904\u002Ffrontend\u002FJustspices\u002Frelaunch\u002Fde_DE\u002Fjs\u002Fzxcvbn.js'; 9551 script.async = true; 9552 script.onload = () => callbacks.forEach(cb => cb()); 9553 document.head.appendChild(script); 9554 } 9555 9556 window.addEventListener('password-validate', function (evt) { 9557 const meterElm = document.getElementById('password-strength-meter-container'), 9558 meterLabelElm = document.getElementById('password-strength-meter-label'); 9559 if (meterElm && meterLabelElm) { 9560 if (evt.detail && evt.detail.elementID) { 9561 const cb = () => _calculateStrength(evt.detail); 9562 window.zxcvbn ? cb() : loadZxcvbn(cb) 9563 } 9564 } 9565 }); 9566 9567 9568 document.addEventListener('DOMContentLoaded', () => { 9569 hyva && hyva.formValidation && hyva.formValidation.addRule('password-strength', function(value, options, field, context) { 9570 let counter = 0; 9571 const minCharacterSets = options.minCharacterSets !== undefined ? options.minCharacterSets : 1; 9572 if (value.match(/\d+/)) { 9573 counter++; 9574 } 9575 9576 if (value.match(/[a-z]+/)) { 9577 counter++; 9578 } 9579 9580 if (value.match(/[A-Z]+/)) { 9581 counter++; 9582 } 9583 9584 if (value.match(/[^a-zA-Z0-9]+/)) { 9585 counter++; 9586 } 9587 9588 queueMicrotask(() => { 9589 window.dispatchEvent(new CustomEvent('password-validate', { detail: {
9590 elementID: field.element.id || 'password', 9591 valid: field.state.valid 9592 }})); 9593 }); 9594 9595 if (counter < minCharacterSets) { 9596 const missing = minCharacterSets - counter; 9597 return hyva.str('Das\u0020Kennwort\u0020muss\u0020mindestens\u0020\u00251\u0020der\u0020folgenden\u0020Buchstaben\u0020enthalten\u003A\u0020Gro\u00DFbuchstaben\u0020\u0028A\u2013Z\u0029,\u0020Kleinbuchstaben\u0020\u0028a\u2013z\u0029,\u0020Zahlen\u0020und\u0020Sonderzeichen.', missing); 9598 } 9599 return true; 9600 }); 9601 }) 9602 })(); 9603 9604</script>
vendor: 1 bytes, line 9604
9604
9605<script type="application/json" id="default-section-data"> 9606 {"messages":[],"customer":[],"compare-products":[],"last-ordered-items":[],"cart":[],"directory-data":{"AT":{"name":"\u00d6sterreich","regions":{"102":{"code":"BL","name":"Burgenland"},"99":{"code":"KN","name":"K\u00e4rnten"},"96":{"code":"NO","name":"Nieder\u00f6sterreich"},"97":{"code":"OO","name":"Ober\u00f6sterreich"},"98":{"code":"SB","name":"Salzburg"},"100":{"code":"ST","name":"Steiermark"},"101":{"code":"TI","name":"Tirol"},"103":{"code":"VB","name":"Vorarlberg"},"95":{"code":"WI","name":"Wien"}}},"CH":{"name":"Schweiz","regions":{"104":{"code":"AG","name":"Aargau"},"106":{"code":"AR","name":"Appenzell Ausserrhoden"},"105":{"code":"AI","name":"Appenzell Innerrhoden"},"108":{"code":"BL","name":"Basel-Landschaft"},"109":{"code":"BS","name":"Basel-Stadt"},"107":{"code":"BE","name":"Bern"},"110":{"code":"FR","name":"Friburg"},"111":{"code":"GE","name":"Geneva"},"112":{"code":"GL","name":"Glarus"},"113":{"code":"GR","name":"Graub\u00fcnden"},"114":{"code":"JU","name":"Jura"},"115":{"code":"LU","name":"Lucerne"},"116":{"code":"NE","name":"Neuch\u00e2tel"},"117":{"code":"NW","name":"Nidwalden"},"118":{"code":"OW","name":"Obwalden"},"120":{"code":"SH","name":"Schaffhausen"},"122":{"code":"SZ","name":"Schwyz"},"121":{"code":"SO","name":"Solothurn"},"119":{"code":"SG","name":"St. Gallen"},"123":{"code":"TG","name":"Thurgau"},"124":{"code":"TI","name":"Ticino"},"125":{"code":"UR","name":"Uri"},"126":{"code":"VD","name":"Vaud"},"127":{"code":"VS","name":"Wallis"},"128":{"code":"ZG","name":"Zug"},"129":{"code":"ZH","name":"Z\u00fcrich"}}},"DE":{"name":"Deutschland","regions":{"80":{"code":"BAW","name":"Baden-W\u00fcrttemberg"},"81":{"code":"BAY","name":"Bayern"},"82":{"code":"BER","name":"Berlin"},"83":{"code":"BRG","name":"Brandenburg"},"84":{"code":"BRE","name":"Bremen"},"85":{"code":"HAM","name":"Hamburg"},"86":{"code":"HES","name":"Hessen"},"87":{"code":"MEC","name":"Mecklenburg-Vorpommern"},"79":{"code":"NDS","name":"Niedersachsen"},"88":{"code":"NRW","name":"Nordrhein-Westfalen"},"89":{"code":"RHE","name":"Rheinland-Pfalz"},"90":{"code":"SAR","name":"Saarland"},"91":{"code":"SAS","name":"Sachsen"},"92":{"code":"SAC","name":"Sachsen-Anhalt"},"93":{"code":"SCN","name":"Schleswig-Holstein"},"94":{"code":"THE","name":"Th\u00fcringen"}}},"ES":{"name":"Spanien","regions":{"130":{"code":"A Coru\u0441a","name":"A Coru\u00f1a"},"131":{"code":"Alava","name":"Alava"},"132":{"code":"Albacete","name":"Albacete"},"133":{"code":"Alicante","name":"Alicante"},"134":{"code":"Almeria","name":"Almeria"},"135":{"code":"Asturias","name":"Asturias"},"136":{"code":"Avila","name":"Avila"},"137":{"code":"Badajoz","name":"Badajoz"},"138":{"code":"Baleares","name":"Baleares"},"139":{"code":"Barcelona","name":"Barcelona"},"140":{"code":"Burgos","name":"Burgos"},"141":{"code":"Caceres","name":"Caceres"},"142":{"code":"Cadiz","name":"Cadiz"},"143":{"code":"Cantabria","name":"Cantabria"},"144":{"code":"Castellon","name":"Castellon"},"145":{"code":"Ceuta","name":"Ceuta"},"146":{"code":"Ciudad Real","name":"Ciudad Real"},"147":{"code":"Cordoba","name":"Cordoba"},"148":{"code":"Cuenca","name":"Cuenca"},"149":{"code":"Girona","name":"Girona"},"150":{"code":"Granada","name":"Granada"},"151":{"code":"Guadalajara","name":"Guadalajara"},"152":{"code":"Guipuzcoa","name":"Guipuzcoa"},"153":{"code":"Huelva","name":"Huelva"},"154":{"code":"Huesca","name":"Huesca"},"155":{"code":"Jaen","name":"Jaen"},"156":{"code":"La Rioja","name":"La Rioja"},"157":{"code":"Las Palmas","name":"Las Palmas"},"158":{"code":"Leon","name":"Leon"},"159":{"code":"Lleida","name":"Lleida"},"160":{"code":"Lugo","name":"Lugo"},"161":{"code":"Madrid","name":"Madrid"},"162":{"code":"Malaga","name":"Malaga"},"163":{"code":"Melilla","name":"Melilla"},"164":{"code":"Murcia","name":"Murcia"},"165":{"code":"Navarra","name":"Navarra"},"166":{"code":"Ourense","name":"Ourense"},"167":{"code":"Palencia","name":"Palencia"},"168":{"code":"Pontevedra","name":"Pontevedra"},"169":{"code":"Salamanca","name":"Salamanca"},"170":{"code":"Santa Cruz de Tenerife","name":"Santa Cruz de Tenerife"},"171":{"code":"Segovia","name":"Segovia"},"172":{"code":"Sevilla","name":"Sevilla"},"173":{"code":"Soria","name":"Soria"},"174":{"code":"Tarragona","name":"Tarragona"},"175":{"code":"Teruel","name":"Teruel"},"176":{"code":"Toledo","name":"Toledo"},"177":{"code":"Valencia","name":"Valencia"},"178":{"code":"Valladolid","name":"Valladolid"}
9606,"179":{"code":"Vizcaya","name":"Vizcaya"},"180":{"code":"Zamora","name":"Zamora"},"181":{"code":"Zaragoza","name":"Zaragoza"}}},"IT":{"name":"Italien"},"NL":{"name":"Niederlande"},"data_id":1790939132},"instant-purchase":[],"loggedAsCustomer":[],"captcha":[],"persistent":[],"review":[],"wishlist":{"items":[]},"ammessages":[],"rewards":[],"recently_viewed_product":[],"recently_compared_product":[],"product_data_storage":[],"paypal-billing-agreement":[]}</script>
9606 9607</div></body> 9608</html>
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.