1<!doctype html> 2<html lang="nl"> 3<head > 4 <meta charset="utf-8"/> 5<meta name="title" content="Klant-login"/> 6<meta name="description" content="Girav lange T-shirts voor mannen online kopen. Dé nummer 1 in lange heren T-shirts!"/> 7<meta name="robots" content="INDEX,FOLLOW"/> 8<meta name="viewport" content="width=device-width, initial-scale=1"/> 9<meta name="apple-mobile-web-app-title" content="Girav"/> 10<meta name="application-name" content="Girav"/> 11<meta name="msapplication-TileColor" content="#000000"/> 12<meta name="theme-color" content="#000000"/> 13<title>Klant-login</title> 14 <link rel="stylesheet" type="text/css" media="all" href="https://www.girav.nl/static/version1790837059/frontend/Girav/hyva/nl_NL/css/styles.css" /> 15<link rel="shortcut icon" href="https://www.girav.nl/static/version1790837059/frontend/Girav/hyva/nl_NL/Magento_Theme/icons/favicon.ico" /> 16<link rel="apple-touch-icon" sizes="180x180" href="https://www.girav.nl/static/version1790837059/frontend/Girav/hyva/nl_NL/Magento_Theme/icons/apple-touch-icon.png" /> 17<link rel="icon" type="image/png" sizes="192x192" href="https://www.girav.nl/static/version1790837059/frontend/Girav/hyva/nl_NL/Magento_Theme/icons/web-app-manifest-192x192.png" /> 18<link rel="icon" type="image/png" sizes="384x384" href="https://www.girav.nl/static/version1790837059/frontend/Girav/hyva/nl_NL/Magento_Theme/icons/web-app-manifest-512x512.png" /> 19<link rel="manifest" href="https://www.girav.nl/static/version1790837059/frontend/Girav/hyva/nl_NL/Magento_Theme/icons/site.webmanifest.json" /> 20<link rel="canonical" href="https://www.girav.nl/customer/account/login" /> 21<link rel="icon" type="image/x-icon" href="https://www.girav.nl/media/favicon/stores/2/Favicon.png" /> 22<link rel="shortcut icon" type="image/x-icon" href="https://www.girav.nl/media/favicon/stores/2/Favicon.png" />
23<script> 24(function (w,d,s,l,i) { 25 w[l]=w[l]||[]; 26 w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'}); 27 var f=d.getElementsByTagName(s)[0],j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:''; 28 j.async=true; 29 j.src='https://a.girav.nl/dg.js?id='+i+dl;f.parentNode.insertBefore(j,f); 30 })(window,document,'script','dataLayer','GTM-5X69RK5'); 31</script>
31 32 33<meta name="google-site-verification" content="_Jzaa8EscJHguylqAd82ACrWT_iAprR3zq5pl3-270E" /> 34 35<style> 36 37.dialog-content h3 {font-size:18px!important;} 38 39@media only screen and (min-width: 1024px) { 40.checkout-cart-index .w-full.lg\:order-1 {width: calc(100% - 335px);} 41} 42div#storeselector-popup { 43 z-index: 2147483631; 44 position: relative; 45} 46 /* ES-4176: TEMP: fix for missing styles in Hyva template */ 47 @media (max-width: 767px) { 48 .hide-on-mobile { 49 display: none !important; 50 } 51.grv-mobile-off {display:none;} 52.pt-mob {padding-top:40px!important;} 53 } 54} 55 56 57 @media (min-width: 768px) { 58 .hide-on-desktop { 59 display: none !important; 60 } 61.grv-mobile-on {display:none;} 62 } 63 64@media (max-width: 1023px) { 65.page-with-filter .sidebar-main .floating-button { 66z-index: 10; 67} 68} 69 /* ES-4443: TEMP: fix for product info being clickthrough */ 70.product-info-main .product-label-block { pointer-events: auto; } 71 72/* ES-4584 - styling buttons overrides */ 73@media (max-width: 479px) { 74 .wp-block-columns.has-cover-scroll>.wp-block-column .d-none { 75 display: flex !important; 76 } 77 .kt-block-spacer.kt-block-spacer-halign-center { 78 height: 0px !important; 79 } 80} 81 82.page.messages { 83z-index: 10; 84} 85 86#search_mini_form .top-full { 87 z-index: 2; 88} 89 90/* fix success page - font of the print receipt */ 91.checkout-onepage-success a.ml-auto {font-size: 14px!important;} 92 93/* Pagebuilder 2025 */ 94 95@media (max-width: 767px) { 96.grv-mobile-off {display:none!important;} 97} 98 99 @media (min-width: 768px) { 100.grv-mobile-on {display:none!important;} 101 } 102 103 104/* Free Gift 2025 - 1974d0 */ 105.free-gift-message {color: #fff!important; 106font-size:18px!important; 107background-color: #c91322!important; 108border-color: #c91322!important; 109} 110 111.free-gift-message svg {color: #fff!important;} 112 113/* FREE GIFT */ 114.aw-afptc__promo-offer-link .swatch-attribute {display:none!important;} 115.free-gift-message {background-color: #c91322Â !important; border-color: #c91322Â !important;} 116.aw-afptc__promo-offer-link .modal-content {max-width: 1200px !important;} 117.aw-afptc__promo-offer-link .text-action {color: rgb(0 171 108 / var(--tw-text-opacity))!important;} 118 119@supports (font: -apple-system-body) and (-webkit-appearance: none) { 120@media only screen and (min-width: 1024px) { 121 .free-gift-promo-rule:before { 122 content: none; 123 } 124} 125} 126 127</style> 128 129<!-- begin Convert Experiences code-->
130<script data-cookieconsent="analytics" type="text/javascript" src="https://cdn-4.convertexperiments.com/v1/js/10046443-100412527.js?environment=production"></script>
130 131<!-- end Convert Experiences code --> 132 133<!-- Cloudflare Web Analytics -->
vendor: 158 bytes, lines 133-134
133 134<script type="text/plain" data-cookieconsent="analytics" type='module' src='https://static.cloudflareinsights.com/beacon.min.js' data-cf-beacon='{"token": "
1343225dcedd3044541b8c94327797a9ff0
vendor: 15 bytes, line 134
134"}'></script>
135<!-- End Cloudflare Web Analytics --> 136 137 138 139
140<script async src="https://storefront.gominimal.ai/storefront-widget.js" data-widget-id="sw_pub_738c6bd02b3403c219d62a91"></script>
140 141 142 143
143<script src="https://www.girav.nl/static/version1790837059/frontend/Girav/hyva/nl_NL/Hyva_JustBetterSentry/js/sentry-local.js" crossorigin="anonymous"></script>
vendor: 1 bytes, line 143
143
144<script> 145 if (typeof Sentry !== 'undefined') { 146 Sentry.init({ 147 dsn: 'https://5c29d45999835f6eb72d9aebf18546f5@o4503959776198656.ingest.us.sentry.io/4503998080352256', 148 release: '1790837059', 149 environment: '', 150 sampleRate: 0.25, 151 integrations: [ 152 ], 153 ignoreErrors: [], 154 beforeSend: function(event) { 155 event.exception.values.map(function (value) { 156 if (value.stacktrace === undefined || ! value.stacktrace) { 157 return value; 158 } 159 160 value.stacktrace.frames.map(function (frame) { 161 frame.filename = frame.filename.replace(/version[0-9]{10}\//, ''); 162 return frame; 163 }); 164 165 166 return value; 167 }); 168 return event; 169 } 170 }); 171 } 172</script>
172 173
174<script data-hash="85bcb57601ba391a912ef0b7aadd3f5a5ef34c344eaa1ec58be9502cc3f47eb4" data-type="text/x-magento-template">!function(r,o,s,a,n){var c=n.currentScript.getAttribute("data-hash"),i="data-cookieconsent",d="data-blocked-src",t=n.documentElement.style,e=new Map(n.cookie.split("; ").map(e=>{e=e.split("=") 175return[e.shift(),e.join("=")]})),l=e.has(r)?JSON.parse(decodeURIComponent(e.get(r)??"")):null,p=l?.user??self.crypto.randomUUID(),u=()=>{var e=n.getElementById("_ec-details-target"),t=n.getElementById("_ec-dialog") 176e&&(e.innerHTML=""),t&&t.style.setProperty(o,"none")},h=e=>!(!l||l.hash!==c)&&(l?.groups?.includes(e)??l?.all??!1),m=(e,t)=>e.getAttribute(t),g=(e,t)=>e.removeAttribute(t),v=encodeURIComponent,y=a.requestAnimationFrame,f=e=>n.querySelectorAll(e),A=e=>{var t 177n.cookie=r+`=${v(JSON.stringify(e))};SameSite=Lax;path=/;Max-Age=`+32e6,l=e,b(),t="consent-change",e={detail:e},a.dispatchEvent(new CustomEvent(t,e))},E=a.cookieApi={getGroupConsent:h,showBanner(){t.removeProperty(o) 178var e=n.getElementById("_ec-dialog") 179e&&e.style.removeProperty(o)},user:p,hash:c,acceptGroup(e){A({hash:c,user:p,groups:l.groups?[...l.groups,e]:[e]})},acceptGroups(e){u(),y(()=>{A({hash:c,user:p,groups:e})})},acceptAll(){u(),y(()=>{A({hash:c,user:p,all:!0})})},declineAll(){u(),y(()=>{A({hash:c,user:p,none:!0})})},hasConsent:()=>l&&l.hash===c},b=async()=>{var e,t 180for(e of f(`iframe[${i}]`)){var r=m(e,i),o=m(e,d) 181h(r??"")&&o&&(g(e,i),e.src=o)}for(t of f(`script[${i}]`))await(async e=>{var r,t=m(e,i) 182t&&h(t)&&(r=e.cloneNode(!0),g(r,i),g(r,"type"),e.parentNode?.insertBefore(r,e),e.remove(),r.async&&r.defer||!r.src||await new Promise(t=>["load","error"].forEach(e=>r.addEventListener(e,t,{once:!0}))))})(t)} 183new MutationObserver(e=>{for(var t of e)for(var r of t.addedNodes){var o,a=r.nodeName 184"SCRIPT"===a&&m(o=r,i)&&(h(m(o,i)??"")?(g(o,i),g(o,"type")):o.type="text/plain"),"IFRAME"===a&&(a=m(o=r,i))&&(h(a??"")?g(o,i):(o.setAttribute(d,o.src),o.src=s+"?g="+v(a)+"&s="+v(o.src)+"&h="+v(c)))}}).observe(n,{childList:!0,subtree:!0}),a.addEventListener("message",e=>{"consent-accept"===e.data.t&&e.data.h===c&&E.acceptGroup(e.data.g)}),null!==l&&l.hash===c&&t.setProperty(o,"none")}("emico-cookie-consent","--cookiebar-display","/iframe",window,document) 185</script>
185 186
186<script data-type="text/x-magento-template">!function(i,r,g){g[i]??=[],g.gtag??=function(){g[i].push(arguments)} 187var e=(e,t,a,n)=>{var o="granted",s="denied" 188g.gtag?.("consent",e?"update":"default",{ad_personalization:t?o:s,ad_storage:t?o:s,ad_user_data:t?o:s,analytics_storage:a?o:s,functionality_storage:n?o:s,personalization_storage:n?o:s,security_storage:o,...e?{}:{wait_for_update:500}}),g.gtag?.("set","ads_data_redaction",!t),r&&g.gtag?.("set","url_passthrough",!0),e&&g[i]?.push({event:"cookie_consent_update"})},t=()=>{g.cookieApi.hasConsent()&&e(!0,g.cookieApi.getGroupConsent("marketing"),g.cookieApi.getGroupConsent("analytics"),g.cookieApi.getGroupConsent("preferences"))} 189g.addEventListener("consent-change",t),e(!1,!1,!1,!1),t()}("dataLayer",!1,window) 190</script>
190 191
192<script> 193 window.dataLayer = window.dataLayer || []; 194 </script>
194 195
196<script type="text/plain" src="https://app.aiden.cx/webshop/build/aiden-embedded.min.js" data-cookieconsent="analytics" async=""></script>
196 197
198<script type="text/javascript"> 199 (function () { 200 window.dataLayer = window.dataLayer || []; 201 202 window.addEventListener('data-layer-push', (e) => { 203 window.dataLayer.push(e.detail); 204 }); 205 206 window.addEventListener('private-content-loaded', (e) => { 207 const sections = e.detail.data; 208 const dataLayerSection = sections['mooore-google-tag-manager']; 209 const cookieArray = document.cookie.split(';'); 210 const dataLayerCookie = cookieArray.find((cookie) => cookie.trim().startsWith('mooore-google-tag-manager=1')); 211 212 if (dataLayerSection && dataLayerCookie) { 213 dataLayerSection.events.forEach((event) => { 214 const pushEvent = new CustomEvent("data-layer-push", { 215 detail: event 216 }); 217 window.dispatchEvent(pushEvent); 218 }); 219 } 220 221 // Delete mooore-google-tag-manager cookie to indicate new events were pushed to the data layer 222 if (dataLayerCookie) { 223 document.cookie = 'mooore-google-tag-manager=1;path=/;max-age=0'; 224 } 225 }); 226 })(); 227</script>
227 228<style> 229 :root { 230 --color-white: #ffffff; 231 --color-black: #000000; 232 --color-dark-gray: #2A2A2A; 233 --bg-input-gray: #4E5055; 234 --primary-red: #C91322; 235 --primary-red-hover: #970F1A; 236 } 237 238 .page-layout-black-friday { 239 background: var(--color-dark-gray); 240 color: var(--color-white); 241 } 242 243 .page-layout-black-friday .page-main { 244 margin-top: 0; 245 margin-bottom: 0; 246 } 247 248 .page-layout-black-friday .columns { 249 max-width: none; 250 padding-left: 0; 251 padding-right: 0; 252 } 253 254 .page-layout-black-friday .btn-primary { 255 --btn-bg: var(--primary-red); 256 --btn-color: var(--color-white); 257 --btn-focus-bg: var(--primary-red-hover); 258 --btn-focus-color: var(--color-white); 259 --btn-active-bg: var(--primary-red-hover); 260 --btn-active-color: var(--color-white); 261 } 262 263 .page-layout-black-friday [data-liveview-element="accordion_list"] { 264 padding: 1rem; 265 background: var(--color-white); 266 } 267 268 .page-layout-black-friday .banner-countdown .value { 269 color: var(--primary-red); 270 } 271 272 .page-layout-black-friday [data-liveview-element="banner"] strong { 273 color: var(--primary-red); 274 } 275 276 .page-layout-black-friday footer { 277 color: var(--color-dark-gray); 278 } 279 280 .page-layout-black-friday input { 281 background: var(--bg-input-gray); 282 color: var(--color-white); 283 } 284</style>
285<script> 286 window.addEventListener('private-content-loaded', (e) => { 287 const sectionData = e.detail.data; 288 const customerId = sectionData.customer?.customer_id ?? null; 289 const event = { 290 'event': 'page_load', 291 'page_type': 'customer', 292 }; 293 294 if (customerId) { 295 event['user_id'] = customerId; 296 } 297 298 const pushEvent = new CustomEvent("data-layer-push", { 299 detail: event 300 }); 301 window.dispatchEvent(pushEvent); 302 }); 303</script>
303 304<style>[x-cloak]{display: none;}</style><link rel="preload" href="https://www.girav.nl/static/version1790837059/frontend/Girav/hyva/nl_NL/fonts/balto/baltoweb-book.woff2" as="font" type="font/woff2" 305 crossorigin="anonymous"/> 306<link rel="preload" href="https://www.girav.nl/static/version1790837059/frontend/Girav/hyva/nl_NL/fonts/balto/baltoweb-medium.woff2" as="font" type="font/woff2" 307 crossorigin="anonymous"/>
308<script> 309 function viewSwatchColorVersion() { 310 const el = event.currentTarget; 311 const rawUri = el && el.getAttribute('data-baseuri'); 312 if (!rawUri) return; 313 314 const url = atob(rawUri); 315 window.location.href = url; 316} 317</script>
317 318
319<script> 320 var BASE_URL = 'https://www.girav.nl/'; 321 var THEME_PATH = 'https://www.girav.nl/static/version1790837059/frontend/Girav/hyva/nl_NL'; 322 var COOKIE_CONFIG = { 323 "expires": null, 324 "path": "\u002F", 325 "domain": ".www.girav.nl", 326 "secure": true, 327 "lifetime": "172800", 328 "cookie_restriction_enabled": false }; 329 var CURRENT_STORE_CODE = 'nl_nl'; 330 var CURRENT_WEBSITE_ID = '2'; 331 332 window.hyva = window.hyva || {} 333 334 window.cookie_consent_groups = window.cookie_consent_groups || {} 335 window.cookie_consent_groups['necessary'] = true; 336 337 window.cookie_consent_config = window.cookie_consent_config || {}; 338 window.cookie_consent_config['necessary'] = [].concat( 339 window.cookie_consent_config['necessary'] || [], 340 [ 341 'user_allowed_save_cookie', 342 'form_key', 343 'mage-messages', 344 'private_content_version', 345 'mage-cache-sessid', 346 'last_visited_store', 347 'section_data_ids' 348 ] 349 ); 350 //# sourceURL=hyva-variables.js 351</script>
vendor: 1 bytes, line 351
351
352<script> 353 (function( hyva, undefined ) { 354 355 function lifetimeToExpires(options, defaults) { 356 357 const lifetime = options.lifetime || defaults.lifetime; 358 359 if (lifetime) { 360 const date = new Date; 361 date.setTime(date.getTime() + lifetime * 1000); 362 return date; 363 } 364 365 return null; 366 } 367 368 function generateRandomString() { 369 370 const allowedCharacters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 371 length = 16; 372 373 let formKey = '', 374 charactersLength = allowedCharacters.length; 375 376 for (let i = 0; i < length; i++) { 377 formKey += allowedCharacters[Math.round(Math.random() * (charactersLength - 1))] 378 } 379 380 return formKey; 381 } 382 383 const sessionCookieMarker = {noLifetime: true} 384 385 const cookieTempStorage = {}; 386 387 const internalCookie = { 388 get(name) { 389 const v = document.cookie.match('(^|;) ?' + name + '=([^;]*)(;|$)'); 390 return v ? v[2] : null; 391 }, 392 set(name, value, days, skipSetDomain) { 393 let expires, 394 path, 395 domain, 396 secure, 397 samesite; 398 399 const defaultCookieConfig = { 400 expires: null, 401 path: '/', 402 domain: null, 403 secure: false, 404 lifetime: null, 405 samesite: 'lax' 406 }; 407 408 const cookieConfig = window.COOKIE_CONFIG || {}; 409 410 expires = days && days !== sessionCookieMarker 411 ? lifetimeToExpires({lifetime: 24 * 60 * 60 * days, expires: null}, defaultCookieConfig) 412 : lifetimeToExpires(window.COOKIE_CONFIG, defaultCookieConfig) || defaultCookieConfig.expires; 413 414 path = cookieConfig.path || defaultCookieConfig.path; 415 domain = !skipSetDomain && (cookieConfig.domain || defaultCookieConfig.domain); 416 secure = cookieConfig.secure || defaultCookieConfig.secure; 417 samesite = cookieConfig.samesite || defaultCookieConfig.samesite; 418 419 document.cookie = name + "=" + encodeURIComponent(value) + 420 (expires && days !== sessionCookieMarker ? '; expires=' + expires.toGMTString() : '') + 421 (path ? '; path=' + path : '') + 422 (domain ? '; domain=' + domain : '') + 423 (secure ? '; secure' : '') + 424 (samesite ? '; samesite=' + samesite : 'lax'); 425 }, 426 isWebsiteAllowedToSaveCookie() { 427 const allowedCookies = this.get('user_allowed_save_cookie'); 428 if (allowedCookies) { 429 const allowedWebsites = JSON.parse(unescape(allowedCookies)); 430 431 return allowedWebsites[CURRENT_WEBSITE_ID] === 1; 432 } 433 return false; 434 }, 435 getGroupByCookieName(name) { 436 const cookieConsentConfig = window.cookie_consent_config || {}; 437 let group = null; 438 for (let prop in cookieConsentConfig) { 439 if (!cookieConsentConfig.hasOwnProperty(prop)) continue; 440 if (cookieConsentConfig[prop].includes(name)) { 441 group = prop; 442 break; 443 } 444 } 445 return group; 446 }, 447 isCookieAllowed(name) { 448 const cookieGroup = this.getGroupByCookieName(name); 449 return cookieGroup 450 ? window.cookie_consent_groups[cookieGroup] 451 : this.isWebsiteAllowedToSaveCookie(); 452 }, 453 saveTempStorageCookies() { 454 for (const [name, data] of Object.entries(cookieTempStorage)) { 455 if (this.isCookieAllowed(name)) { 456 this.set(name, data['value'], data['days'], data['skipSetDomain']); 457 delete cookieTempStorage[name]; 458 } 459 } 460 } 461 }; 462 463 hyva.getCookie = (name) => { 464 const cookieConfig = window.COOKIE_CONFIG || {}; 465 466 if (cookieConfig.cookie_restriction_enabled && ! internalCookie.isCookieAllowed(name)) { 467 return cookieTempStorage[name] ? cookieTempStorage[name]['value'] : null; 468 } 469 470 return internalCookie.get(name); 471 } 472 473 hyva.setCookie = (name, value, days, skipSetDomain) => { 474 const cookieConfig = window.COOKIE_CONFIG || {}; 475 476 if (cookieConfig.cookie_restriction_enabled && ! internalCookie.isCookieAllowed(name)) { 477 cookieTempStorage[name] = {value, days, skipSetDomain}; 478 return; 479 } 480 return internalCookie.set(name, value, days, skipSetDomain); 481 } 482 483 484 hyva.setSessionCookie = (name, value, skipSetDomain) => { 485 return hyva.setCookie(name, value, sessionCookieMarker, skipSetDomain) 486 } 487 488 hyva.getBrowserStorage = () => { 489 const browserStorage = window.localStorage || window.sessionStorage; 490 if (!browserStorage) { 491 console.warn('Browser Storage is unavailable'); 492 return false;
493 } 494 try { 495 browserStorage.setItem('storage_test', '1'); 496 browserStorage.removeItem('storage_test'); 497 } catch (error) { 498 console.warn('Browser Storage is not accessible', error); 499 return false; 500 } 501 return browserStorage; 502 } 503 504 hyva.postForm = (postParams) => { 505 const form = document.createElement("form"); 506 507 let data = postParams.data; 508 509 if (! postParams.skipUenc && ! data.uenc) { 510 data.uenc = btoa(window.location.href); 511 } 512 form.method = "POST"; 513 form.action = postParams.action; 514 515 Object.keys(postParams.data).map(key => { 516 const field = document.createElement("input"); 517 field.type = 'hidden' 518 field.value = postParams.data[key]; 519 field.name = key; 520 form.appendChild(field); 521 }); 522 523 const form_key = document.createElement("input"); 524 form_key.type = 'hidden'; 525 form_key.value = hyva.getFormKey(); 526 form_key.name="form_key"; 527 form.appendChild(form_key); 528 529 document.body.appendChild(form); 530 531 form.submit(); 532 } 533 534 hyva.getFormKey = function () { 535 let formKey = hyva.getCookie('form_key'); 536 537 if (!formKey) { 538 formKey = generateRandomString(); 539 hyva.setCookie('form_key', formKey); 540 } 541 542 return formKey; 543 } 544 545 hyva.formatPrice = (value, showSign, options = {}) => { 546 const groupSeparator = options.groupSeparator; 547 const decimalSeparator = options.decimalSeparator 548 delete options.groupSeparator; 549 delete options.decimalSeparator; 550 const formatter = new Intl.NumberFormat( 551 'nl\u002DNL', 552 Object.assign({ 553 style: 'currency', 554 currency: 'EUR', 555 signDisplay: showSign ? 'always' : 'auto' 556 }, options) 557 ); 558 return (typeof Intl.NumberFormat.prototype.formatToParts === 'function') ? 559 formatter.formatToParts(value).map(({type, value}) => { 560 switch (type) { 561 case 'currency': 562 return '\u20AC' || value; 563 case 'minusSign': 564 return '- '; 565 case 'plusSign': 566 return '+ '; 567 case 'group': 568 return groupSeparator !== undefined ? groupSeparator : value; 569 case 'decimal': 570 return decimalSeparator !== undefined ? decimalSeparator : value; 571 default : 572 return value; 573 } 574 }).reduce((string, part) => string + part) : 575 formatter.format(value); 576 } 577 578 const formatStr = function (str, nStart) { 579 const args = Array.from(arguments).slice(2); 580 581 return str.replace(/(%+)([0-9]+)/g, (m, p, n) => { 582 const idx = parseInt(n) - nStart; 583 584 if (args[idx] === null || args[idx] === void 0) { 585 return m; 586 } 587 return p.length % 2 588 ? p.slice(0, -1).replace('%%', '%') + args[idx] 589 : p.replace('%%', '%') + n; 590 }) 591 } 592 593 hyva.str = function (string) { 594 const args = Array.from(arguments); 595 args.splice(1, 0, 1); 596 597 return formatStr.apply(undefined, args); 598 } 599 600 hyva.strf = function () { 601 const args = Array.from(arguments); 602 args.splice(1, 0, 0); 603 604 return formatStr.apply(undefined, args); 605 } 606 607 /** 608 * Take a html string as `content` parameter and 609 * extract an element from the DOM to replace in 610 * the current page under the same selector, 611 * defined by `targetSelector` 612 */ 613 hyva.replaceDomElement = (targetSelector, content) => { 614 // Parse the content and extract the DOM node using the `targetSelector` 615 const parser = new DOMParser(); 616 const doc = parser.parseFromString(content, 'text/html');
617 const contentNode = doc.querySelector(targetSelector); 618 619 // Bail if content or target can't be found 620 if (!contentNode || !document.querySelector(targetSelector)) { 621 return; 622 } 623 624 hyva.activateScripts(contentNode); 625 626 // Replace the old DOM node with the new content 627 document.querySelector(targetSelector).replaceWith(contentNode); 628 629 // Reload customerSectionData and display cookie-messages if present 630 window.dispatchEvent(new CustomEvent("reload-customer-section-data")); 631 hyva.initMessages(); 632 } 633 634 hyva.removeScripts = (contentNode) => { 635 const scripts = contentNode.getElementsByTagName('script'); 636 for (let i = 0; i < scripts.length; i++) { 637 scripts[i].parentNode.removeChild(scripts[i]); 638 } 639 const templates = contentNode.getElementsByTagName('template'); 640 for (let i = 0; i < templates.length; i++) { 641 const container = document.createElement('div'); 642 container.innerHTML = templates[i].innerHTML; 643 hyva.removeScripts(container); 644 templates[i].innerHTML = container.innerHTML; 645 } 646 } 647 648 hyva.activateScripts = (contentNode) => { 649 // Create new array from HTMLCollection to avoid mutation of collection while manipulating the DOM. 650 const scripts = Array.from(contentNode.getElementsByTagName('script')); 651 652 // Iterate over all script tags to duplicate+inject each into the head 653 for (const original of scripts) { 654 const script = document.createElement('script'); 655 original.type && (script.type = original.type); 656 script.innerHTML = original.innerHTML; 657 658 // Remove the original (non-executing) script from the contentNode 659 original.parentNode.removeChild(original) 660 661 // Add script to head 662 document.head.appendChild(script); 663 } 664 665 return contentNode; 666 } 667 668 const replace = {['+']: '-', ['/']: '_', ['=']: ','}; 669 hyva.getUenc = () => btoa(window.location.href).replace(/[+/=]/g, match => replace[match]); 670 671 let currentTrap; 672 673 const focusableElements = (rootElement) => { 674 const selector = 'button, [href], input, select, textarea, details, [tabindex]:not([tabindex="-1"]'; 675 return Array.from(rootElement.querySelectorAll(selector)) 676 .filter(el => { 677 return el.style.display !== 'none' 678 && !el.disabled 679 && el.tabIndex !== -1 680 && (el.offsetWidth || el.offsetHeight || el.getClientRects().length) 681 }) 682 } 683 684 const focusTrap = (e) => { 685 const isTabPressed = e.key === 'Tab' || e.keyCode === 9; 686 if (!isTabPressed) return; 687 688 const focusable = focusableElements(currentTrap) 689 const firstFocusableElement = focusable[0] 690 const lastFocusableElement = focusable[focusable.length - 1] 691 692 e.shiftKey 693 ? document.activeElement === firstFocusableElement && (lastFocusableElement.focus(), e.preventDefault()) 694 : document.activeElement === lastFocusableElement && (firstFocusableElement.focus(), e.preventDefault()) 695 }; 696 697 hyva.releaseFocus = (rootElement) => { 698 if (currentTrap && (!rootElement || rootElement === currentTrap)) { 699 currentTrap.removeEventListener('keydown', focusTrap) 700 currentTrap = null 701 } 702 } 703 hyva.trapFocus = (rootElement) => { 704 if (!rootElement) return; 705 hyva.releaseFocus() 706 currentTrap = rootElement 707 rootElement.addEventListener('keydown', focusTrap) 708 const firstElement = focusableElements(rootElement)[0] 709 firstElement && firstElement.focus() 710 } 711 712 hyva.safeParseNumber = (rawValue) => { 713 const number = rawValue ? parseFloat(rawValue) : null; 714 715 return Array.isArray(number) || isNaN(number) ? rawValue : number; 716 } 717 718 const toCamelCase = s => s.split('_').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(''); 719 hyva.createBooleanObject = (name, value = false, additionalMethods = {}) => { 720 721 const camelCase = toCamelCase(name);
722 const key = '__hyva_bool_' + name 723 724 return new Proxy(Object.assign( 725 additionalMethods, 726 { 727 [key]: !!value, 728 [name]() {return !!this[key]}, 729 ['!' + name]() {return !this[key]}, // @deprecated This does not work with non-CSP Alpine 730 ['not' + camelCase]() {return !this[key]}, 731 ['toggle' + camelCase]() {this[key] = !this[key]}, 732 [`set${camelCase}True`]() {this[key] = true}, 733 [`set${camelCase}False`]() {this[key] = false}, 734 } 735 ), { 736 set(target, prop, value) { 737 return prop === name 738 ? (target[key] = !!value) 739 : Reflect.set(...arguments); 740 } 741 }) 742 } 743 744 hyva.alpineInitialized = (fn) => window.addEventListener('alpine:initialized', fn, {once: true}) 745 window.addEventListener('alpine:init', () => Alpine.data('{}', () => ({})), {once: true}); 746 window.addEventListener('user-allowed-save-cookie', () => internalCookie.saveTempStorageCookies()) 747 748 }( window.hyva = window.hyva || {} )); 749 //# sourceURL=hyva.js 750</script>
vendor: 1 bytes, line 750
750
751<script type="speculationrules"> 752{ 753 "tag": "Hyva Theme", 754 "prefetch": [{ 755 "source": "document", 756 "where": { 757 "and": [ 758 { "href_matches": "/*" }, 759 { "not": { 760 "href_matches": ["/customer/*","/search/*","/sales/*","/wishlist/*","/checkout/*","/paypal/*","/newsletter/*","/stores/store/redirect/*"] }}, 761 { "not": { 762 "selector_matches": [".no-preload", ".do-not-prerender", "[download]", "[rel~=nofollow]", "[target]"] 763 }} 764 ] 765 }, 766 "eagerness": "moderate" 767 }] 768} 769</script>
769 770 771
771<script> 772 const Squeezely = { 773 init() { 774 window._sqzl = (typeof _sqzl !== 'undefined' && _sqzl) ? _sqzl : []; 775 776 this.pageView(); 777 this.updateCart(); 778 779 window.addEventListener('private-content-loaded', (event) => { 780 const oldCartData = JSON.parse(localStorage.getItem('mage-cache-storage'))?.cart; 781 const newCartData = event.detail.data.cart; 782 783 if (newCartData.summary_count && oldCartData?.summary_count) { 784 newCartData.summary_count < oldCartData?.summary_count 785 ? this.pushRemoveFromCart(oldCartData.items, newCartData.items) 786 : this.pushAddToCart(oldCartData.items, newCartData.items); 787 } 788 }); 789 }, 790 791 pageView() { 792 window._sqzl.push({"event": "PageView"}); 793 }, 794 795 updateCart() { 796 if (!sessionStorage.getItem("new-session")) { 797 window._sqzl.push({ 798 "event": "UpdateCart", 799 "set_cart": true, 800 "products": [] 801 }); 802 803 sessionStorage.setItem("new-session", "true"); 804 } 805 }, 806 807 pushAddToCart(itemsOld, itemsNew) { 808 let productData; 809 if (itemsNew.length !== itemsOld.length) { 810 productData = this.createPushAddData(itemsNew[0], itemsNew[0].qty); 811 } else { 812 for (let i = 0; i < itemsNew.length; i++) { 813 if (itemsNew[i].qty !== itemsOld[i].qty) { 814 productData = this.createPushAddData(itemsNew[i], itemsNew[i].qty - itemsOld[i].qty); 815 } 816 } 817 } 818 819 window._sqzl.push({ 820 "event": "AddToCart", 821 "products": [productData], 822 }); 823 }, 824 825 pushRemoveFromCart(itemsOld, itemsNew) { 826 itemsOld.forEach((obj) => { 827 if (itemsNew.findIndex((el) => el.product_sku === obj.product_sku) === -1) { 828 window._sqzl.push({ 829 "event": "RemoveFromCart", 830 "products": [{"id": obj.product_sku}], 831 }); 832 } 833 }); 834 }, 835 836 pushPageEvent(html) { 837 const mutation = html.replace(/"/g, '"').replace(/</g, '<').replace(/>/g, '>'); 838 const data = mutation.match(/\([^]*}\)/gi)[0].slice(1, -1); 839 window._sqzl.push(JSON.parse(data)); 840 }, 841 842 createPushAddData(data, qty) { 843 return { 844 "id": data.product_sku, 845 "name": data.product_name, 846 "price": data.product_price_value.incl_tax ? +data.product_price_value.incl_tax : data.product_price_value, 847 "quantity": qty, 848 }; 849 } 850 }; 851 852 function initSqueezely() { 853 if (!window.cookieApi?.getGroupConsent("marketing")) { 854 return; 855 } 856 857 const script = document.createElement("script"); 858 script.setAttribute("type", "text/javascript"); 859 script.setAttribute("src", 'https://squeezely.tech/tracker/SQ-25651264/sqzl.js'); 860 document.body.appendChild(script); 861 862 script.onload = () => { 863 setTimeout(() => { 864 Squeezely.init(); 865 }, 500); 866 }; 867 } 868 869 if (document.readyState === "loading") { 870 document.addEventListener("DOMContentLoaded", initSqueezely, {once: true}); 871 } else { 872 initSqueezely(); 873 } 874 875 window.addEventListener("consent-change", initSqueezely); 876 </script>
876 877 </head> 878<body id="html-body" class="customer-account-login page-layout-1column"> 879 880 <div 881 role="dialog" 882 id="_ec-dialog" 883 aria-labelledby="_ec-title" 884 aria-modal="true" 885 data-nosnippet > 886 <div class="fixed top-0 left-0 w-full h-full opacity-75 bg-black z-[99999]" 887 style="display: var(--cookiebar-display, flex)" 888 > 889 </div> 890 <div 891 class="fixed inset-0 mx-auto top-auto md:max-w-[900px] sm:top-1/2 md:top-1/2 sm:-translate-y-1/2 sm:bottom-auto md:bottom-auto z-[99999] flex max-h-full flex-col gap-2 overflow-auto bg-white pt-6 pl-6 pr-6 shadow-xl ring-1 ring-gray-900/5 sm:inset-5 sm:max-h-[calc(100vh-theme(space.10))] sm:rounded-lg md:inset-10 md:max-h-[calc(100vh-theme(space.10)-theme(space.10))]" 892 style="display: var(--cookiebar-display, flex)" 893 > 894 <h3 id="_ec-title" class="heading-3 md:mb-6 text-[24px] font-[600]"><p>Bij Girav respecteren we je privacy.</p></h3> 895 <div class="contents" id="_ec-default"> 896 <div class="text-base mb-3"><p>We gebruiken cookies om content en advertenties te personaliseren, om functies voor social media te bieden en om ons websiteverkeer te analyseren. Ook delen we informatie over uw gebruik van onze site met onze partners voor social media, adverteren en analyse. Deze partners kunnen deze gegevens combineren met andere informatie die u aan ze heeft verstrekt of die ze hebben verzameld op basis van uw gebruik van hun services.</p></div> 897 <div class="flex gap-2 flex-col-reverse sm:flex-row pt-3 pb-4"> 898 <button class="underline _ec-learn-more">Meer informatie en aanpassen</button> 899 <button class="btn btn-primary !ml-0 sm:!ml-auto _ec-accept-all">Accepteer alles</button> 900 </div> 901 </div> 902 <form class="hidden" id="_ec-details"> 903 <div class="divide-y divide-gray-300/50"> 904 <div> 905 <div class="text-base py-4"><p>Cookies zijn kleine tekstbestanden die door websites kunnen worden gebruikt om gebruikerservaringen efficiënter te maken.<br><br>Volgens de wet mogen wij cookies op uw apparaat opslaan als ze strikt noodzakelijk zijn voor het gebruik van de site. Voor alle andere soorten cookies hebben we uw toestemming nodig.<br><br>Deze website maakt gebruik van verschillende soorten cookies. Sommige cookies worden geplaatst door diensten van derden die op onze pagina's worden weergegeven.<br><br>Via de cookieverklaring op onze website kunt u uw toestemming op elk moment wijzigen of intrekken.<br><br>In ons privacybeleid vindt u meer informatie over wie we zijn, hoe u contact met ons kunt opnemen en hoe we persoonlijke gegevens verwerken.<br><br>Als u vragen heeft over uw toestemming, vermeld dan het ID en de datum van de toestemming alstublieft.</p></div> 906 <div class="text-sm text-muted pb-4"> 907 Content-hash: <span class="_ec-proof-hash"></span><br/> 908 Willekeurige gebruikers-ID: <span class="_ec-proof-user"></span><br/> 909 </div> 910 </div> 911 <div class="divide-y divide-gray-300/50" id="_ec-groups"></div> 912 </div> 913 <div class="flex gap-2 flex-col-reverse sm:flex-row pt-3 pb-4 sticky bg-white bottom-0"> 914 <button class="underline _ec-go-back" type="button">Terug</button> 915 <button class="btn btn-primary !ml-0 sm:!ml-auto _ec-save" type="submit">Opslaan en doorgaan</button> 916 </div> 917 </form> 918 </div> 919 </div> 920 921
921<script type="application/json" id="_ec-json"> 922 {"cookies":[{"cookie_id":"1","name":"last_visited_store","provider":"Magento","group":"essential","description":"Used by the store to keep track what store the user visited, used by Magento","retention":"1 hour","type":"cookie","store_id":["0"]},{"cookie_id":"2","name":"mage-cache-sessid","provider":"Magento","group":"essential","description":"The value of this cookie triggers the cleanup of local cache storage. Used by Magento.","retention":"1 hour","type":"cookie","store_id":["0"]},{"cookie_id":"3","name":"form_key","provider":"Magento","group":"essential","description":"A security measure that appends a random string to all form submissions to protect the data from Cross-Site Request Forgery (CSRF). Used by Magento.","retention":"1 hour","type":"cookie","store_id":["0"]},{"cookie_id":"4","name":"mage-cache-storage","provider":"Magento","group":"essential","description":"Local storage of visitor-specific content that enables ecommerce functions. Used by Magento.","retention":"persistent","type":"localstorage","store_id":["0"]},{"cookie_id":"5","name":"guest-view","provider":"Magento","group":"essential","description":"Links a guest order to a guest (because there is no account for guest).","retention":"persistent","type":"cookie","store_id":["0"]},{"cookie_id":"6","name":"login_redirect","provider":"Magento","group":"essential","description":"Saves redirect URL to route user if successful login and user registration. Saves the page that a user was on prior to log in (to determine the location they will go back to after they log in).","retention":"persistent","type":"cookie","store_id":["0"]},{"cookie_id":"7","name":"mage-messages","provider":"Magento","group":"essential","description":"Tracks error messages and other notifications that are shown to the user, such as the cookie consent message, and various error messages. The message is deleted from the cookie after it is shown to the shopper. There is not an option to disable this cooki","retention":"persistent","type":"cookie","store_id":["0"]},{"cookie_id":"8","name":"product_data_storage","provider":"Magento","group":"essential","description":"Stores configuration for product data used to use \u201cRecently Viewed\u201d and \u201cCompare Products\u201d functions. Stores a user\u2019s specific settings (for example, if they have recently viewed a product or compared products).","retention":"persistent","type":"localstorage","store_id":["0"]},{"cookie_id":"9","name":"recently_compared_product","provider":"Magento","group":"essential","description":"Stores product IDs of recently compared products.","retention":"persistent","type":"localstorage","store_id":["0"]},{"cookie_id":"10","name":"recently_compared_product_previous","provider":"Magento","group":"essential","description":"Stores product IDs of previously compared products for easy navigation.","retention":"persistent","type":"localstorage","store_id":["0"]},{"cookie_id":"11","name":"recently_viewed_product","provider":"Magento","group":"essential","description":"Stores product IDs of recently viewed products for easy navigation.","retention":"persistent","type":"localstorage","store_id":["0"]},{"cookie_id":"12","name":"recently_viewed_product_previous","provider":"Magento","group":"essential","description":"Stores product IDs of recently viewed products for easy navigation.","retention":"persistent","type":"localstorage","store_id":["0"]},{"cookie_id":"13","name":"stf","provider":"Magento","group":"essential","description":"Records the time messages are sent by the SendFriend (Email a Friend) module. When a shopper sends a link to a product, this cookie records a time-stamp and maintains a count.","retention":"persistent","type":"cookie","store_id":["0"]},{"cookie_id":"14","name":"X-Magento-Vary","provider":"Magento","group":"essential","description":"Indicates when a new version of a page needs to be served from the cache. Supports website performance.","retention":"persistent","type":"cookie","store_id":["0"]},{"cookie_id":"15","name":"mage-cache-storage-section-invalidation","provider":"Magento","group":"essential","description":"Stores information related to which sections of the page need to be invalidated and removed.","retention":"persistent","type":"cookie","store_id":["0"]},{"cookie_id":"16","name":"persistent_shopping_cart","provider":"Magento","group":"essential","description":"Stores the key ID of a persistent cart to make it possible to restore the cart for an anonymous shopper.","retention":"persistent","type":"cookie","store_id":["0"]},{"cookie_id":"17","name":"private_content_version","provider":"Magento","group":"essential","description":"Appends a random, unique number and time to pages with customer content to prevent them from being cached on the server. It is set in multiple places: in PHP, in JavaScript as a cookie, and in JavaScript to local storage.","retention":"persistent","type":"cookie","store_id":["0"]},{"cookie_id":"18","name":"section_data_ids","provider":"Magento","group":"essential","description":"Stores customer-specific information related to shopper-initiated actions, such as wish list display and checkout information.","retention":"persistent","type":"cookie","store_id":["0"]},{"cookie_id":"19","name":"store","provider":"Magento","group":"essential","description":"Tracks the specific store view\/locale selected by the shopper.","retention":"persistent","type":"cookie","store_id":["0"]},{"cookie_id":"20","name":"admin","provider":"Magento","group":"essential","description":"Tracks user sessions on the Admin side.","retention":"persistent","type":"cookie","store_id":["0"]},{"cookie_id":"21","name":"loggedOutReasonCode","provider":"Magento","group":"essential","description":"Set when an Admin user is locked out after a certain
922number of unsuccessful password attempts.","retention":"persistent","type":"cookie","store_id":["0"]},{"cookie_id":"22","name":"section_data_clean","provider":"Magento","group":"essential","description":"Set when a user switches store view. The presence of this cookie triggers JavaScript to reload certain sections on the page to reflect the correct store view.","retention":"persistent","type":"cookie","store_id":["0"]},{"cookie_id":"23","name":"CookieConsent","provider":"Girav","group":"essential","description":"Stores the user's cookie consent status for the current domain.","retention":"1 year","type":"cookie","store_id":["0"]},{"cookie_id":"24","name":"XSRF-TOKEN","provider":"Girav","group":"essential","description":"Ensures browsing security by preventing Cross-Site Request Forgery (CSRF) attacks. This cookie is essential for the security of the website and its visitors.","retention":"1 dag","type":"cookie","store_id":["0"]},{"cookie_id":"25","name":"rc::a","provider":"Google","group":"essential","description":"Used to distinguish humans from bots. This helps the website generate accurate usage reports.","retention":"Permanent ","type":"localstorage","store_id":["0"]},{"cookie_id":"26","name":"rc::c","provider":"Google","group":"essential","description":"Used to distinguish humans from bots.","retention":"Session","type":"localstorage","store_id":["0"]},{"cookie_id":"27","name":"form_key","provider":"Girav","group":"essential","description":"Ensures browsing security by preventing Cross-Site Request Forgery (CSRF) attacks. This cookie is essential for the security of the website and its visitors.","retention":"2 dagen","type":"cookie","store_id":["0"]},{"cookie_id":"28","name":"mage-cache-sessid","provider":"Girav","group":"essential","description":"This cookie is used in conjunction with traffic distribution - This optimizes the response rate between the visitor and the site by distributing traffic across multiple network links or servers.","retention":"2 days","type":"cookie","store_id":["0"]},{"cookie_id":"29","name":"mage-messages","provider":"Girav","group":"essential","description":"Necessary for the functionality of the website's chatbox feature.","retention":"Session","type":"cookie","store_id":["0"]},{"cookie_id":"30","name":"rc::a","provider":"Girav","group":"essential","description":"This cookie is used to distinguish between humans and bots. This is beneficial for the website to generate accurate reports on website usage.","retention":"Permanent ","type":"localstorage","store_id":["0"]},{"cookie_id":"31","name":"rc::c","provider":"Girav","group":"essential","description":"This cookie is used to distinguish between humans and bots.","retention":"Session","type":"localstorage","store_id":["0"]},{"cookie_id":"32","name":"new-session","provider":"Girav","group":"essential","description":"Used to identify and maintain a new user session during website visits.","retention":"Session","type":"localstorage","store_id":["0"]},{"cookie_id":"33","name":"PHPSESSID","provider":"Girav","group":"essential","description":"Maintains the user session state across page requests.","retention":"2 days","type":"cookie","store_id":["0"]},{"cookie_id":"34","name":"mf_initialDomQueue","provider":"Mouseflow","group":"analytics","description":"Records visitor interactions for internal analytics and website optimization purposes.","retention":"Session","type":"localstorage","store_id":["0"]},{"cookie_id":"35","name":"_conv_r","provider":"Girav","group":"analytics","description":"Used as a referral cookie that stores the visitor profile. The cookie is overwritten when the visitor returns to the website and new visitor information is collected and stored.","retention":"Session","type":"cookie","store_id":["0"]},{"cookie_id":"36","name":"_conv_s","provider":"Girav","group":"analytics","description":"Contains an ID string created based on the current session. This ID string contains non-personal information about the subpages visited by the user. This information is used to improve the visitor experience.","retention":"1 day","type":"cookie","store_id":["0"]},{"cookie_id":"37","name":"_conv_v","provider":"Girav","group":"analytics","description":"This cookie is used to identify the frequency of visits and determine how long a visitor stays on the website. It is used to determine the number of visits and which subpages the visitor views on the website.","retention":"6 months","type":"cookie","store_id":["0"]},{"cookie_id":"38","name":"_ga","provider":"Girav","group":"analytics","description":"Registers a unique ID that is used to generate statistical data about how the visitor uses the website.","retention":"2 years","type":"cookie","store_id":["0"]},{"cookie_id":"39","name":"_ga_#","provider":"Girav","group":"analytics","description":"Collects data about the number of times a user has visited the website, as well as information about the first and most recent visit. Used by Google Analytics.","retention":"2 years","type":"cookie","store_id":["0"]},{"cookie_id":"40","name":"_gd#","provider":"Girav","group":"analytics","description":"Used to collect statistical information about website usage and visitor behavior for analytics purposes.","retention":"Session","type":"cookie","store_id":["0"]},{"cookie_id":"41","name":"FPAU","provider":"Girav","group":"analytics","description":"Assigns a unique ID to the visitor. This allows the website to determine the number of unique user visits for analysis and statistics.","retention":"3 months","type":"cookie","store_id":["0"]},{"cookie_id":"42","name":"FPGSID","provider":"Girav","group":"analytics","description":"Records statistical data about visitor behavior on the website. Used for internal analysis by the website administrator.","retention":"1 day","type":"cookie","store_id":["0"]},{"cookie_id":"43","name":"FPID","provider":"Girav","group":"analytics","description":"Records statistical data about visitor behavior on the website. Used for internal analysis by the website administrator.","retention":"400 days","type":"cookie","store_id":["0"]},{"cookie_id":"44","name":"FPLC","provider":"Girav","group":"analytics","description":"Registers a unique ID that is used to generate statistical data about how the visitor uses the website.","retention":"1 day","type":"cookie","store_id":["0"]},{"cookie_id":"45","name":"sqzl_vw","provider":"Girav","group":"analytics","description":"This cookie is used by the website operator in connection with testing multiple variations. It is a tool used to combine or modify content on the website, allowing the website to determine the best version of the site.","retention":"1 year","type":"cookie","store_id":["0"]},{"cookie_id":"46","name":"_kbuid","provider":"Kickbite","group":"analytics","description":"Used to identify the visitor for analytics purposes and to support website optimization.","retention":"Permanent","type":"localstorage","store_id":["0"]},{"cookie_id":"47","name":"last_visited_store","provider":"Girav","group":"analytics","description":"This cookie is used to determine when the user last visited different subpages of the website. The cookie stores a timestamp indicating when the session was started.","retention":"2 days","type":"cookie","store_id":["0"]},{"cookie_id":"48","name":"_\/set_cookie","provider":"Girav","group":"marketing","description":"Used by Google Tag Manager on the server side to set or update cookies required for analytics or marketing tags.","retention":"Session","type":"cookie","store_id":["0"]},{"cookie_id":"49","name":"_gcl_ls","provider":"Girav","group":"marketing","description":"Tracks the conversion rate between users and advertising banners on the website. This is used to optimize the relevance of advertisements displayed on the website.","retention":"Permanent","type":"localstorage","store_id":["0"]},{"cookie_id":"50","name":"tt_appInfo","provider":"TikTok","group":"marketing","description":"Used by the social networking service TikTok to track the use of embedded services.","retention":"Session","type":"localstorage","store_id":["0"]},{"cookie_id":"51","name":"tt_pixel_session_index","provider":"TikTok","group":"marketing","description":"Used by the social networking service TikTok to track the use of embedded services.","retention":"Session","type":"localstorage","store_id":["0"]},{"cookie_id":"52","name":"tt_sessionId","provider":"TikTok","group":"marketing","description":"Used by the social networking service TikTok to track the use of embedded services.","retention":"Session","type":"localstorage","store_id":["0"]},{"cookie_id":"53","name":"#-#-#-#-#","provider":"Aiden","group":"marketing","description":"Used to support marketing activities and track user interactions with website content.","retention":"Session","type":"localstorage","store_id":["0"]},{"cookie_id":"54","name":"aidenUserId","provider":"Aiden","group":"marketing","description":"Used to identify the user for marketing purposes and to support personalized experiences.","retention":"Permanent","type":"localstorage","store_id":["0"]},{"cookie_id":"55","name":"aiden-visitor-id","provider":"Aiden","group":"marketing","description":"Used to identify the visitor for marketing purposes and to support visitor tracking.","retention":"Permanent","type":"localstorage","store_id":["0"]},{"cookie_id":"56","name":"_uetsid","provider":"Microsoft","group":"marketing","description":"Used to track visitors across multiple websites in order to present relevant advertisements based on visitor preferences.","retention":"Permanent","type":"localstorage","store_id":["0"]},{"cookie_id":"57","name":"_uetsid_exp","provider":"Microsoft","group":"marketing","description":"Contains the expiration date of the associated cookie.","retention":"Permanent","type":"localstorage","store_id":["0"]},{"cookie_id":"58","name":"_uetvid","provider":"Microsoft","group":"marketing","description":"Used to track visitors across multiple websites in order to present relevant advertisements based on visitor preferences.","retention":"Permanent","type":"localstorage","store_id":["0"]},{"cookie_id":"59","name":"_uetvid_exp","provider":"Microsoft","group":"marketing","description":"Contains the expiration date of the associated cookie.","retention":"Permanent","type":"localstorage","store_id":["0"]},{"cookie_id":"60","name":"MUID","provider":"Microsoft","group":"marketing","description":"Widely used by Microsoft as a unique user ID. The cookie enables user tracking by synchronizing the ID across multiple Microsoft domains.","retention":"1 year","type":"cookie","store_id":["0"]}
922,{"cookie_id":"61","name":"lastExternalReferrer","provider":"Meta","group":"marketing","description":"Determines how the user arrived at the website by recording the user\u2019s previous URL address.","retention":"Permanent","type":"localstorage","store_id":["0"]},{"cookie_id":"62","name":"lastExternalReferrerTime","provider":"Meta","group":"marketing","description":"Determines how the user arrived at the website by recording the timestamp of the user\u2019s previous URL visit.","retention":"Permanent","type":"localstorage","store_id":["0"]},{"cookie_id":"63","name":"cto_bundle","provider":"Microsoft","group":"marketing","description":"Used to provide visitors with relevant content and advertisements. The service is provided by third-party advertising platforms, enabling real-time bidding for advertisers.","retention":"Permanent","type":"localstorage","store_id":["0"]},{"cookie_id":"64","name":"uid","provider":"Microsoft","group":"marketing","description":"Collects data regarding the user's visits to the website, such as the number of visits, the average time spent on the website, and which pages were loaded, with the aim of displaying targeted advertisements.","retention":"1 year","type":"cookie","store_id":["0"]},{"cookie_id":"65","name":"IDE","provider":"Microsoft","group":"marketing","description":"Used by Google DoubleClick to record and report the actions of the website user after viewing or clicking on one of the advertiser's advertisements with the aim of measuring the effectiveness of an advertisement and to display targeted advertisements","retention":"400 days","type":"cookie","store_id":["0"]},{"cookie_id":"66","name":"test_cookie","provider":"Microsoft","group":"marketing","description":"Used to check if the user's browser supports cookies.","retention":"1 day","type":"cookie","store_id":["0"]},{"cookie_id":"67","name":"_conv_sptest","provider":"Girav","group":"marketing","description":"This cookie is used by the website operator in connection with multivariant testing. This is a tool used to combine or modify content on the website. This allows the website to find the best edition\/version of the site","retention":"Session","type":"cookie","store_id":["0"]},{"cookie_id":"68","name":"_fbp","provider":"Girav","group":"marketing","description":"Used by Facebook to deliver a range of advertising products, such as real-time bidding from third-party advertisers.","retention":"3 months","type":"cookie","store_id":["0"]},{"cookie_id":"69","name":"_gcl_au","provider":"Girav","group":"marketing","description":"Used by Google AdSense to experiment with the efficiency of ads on websites that use their services.","retention":"3 months","type":"cookie","store_id":["0"]},{"cookie_id":"70","name":"_gtmeec","provider":"Girav","group":"marketing","description":"Used to temporarily store and process interaction data regarding e-commerce to ensure reliable analytical event tracking when loading pages.","retention":"3 months","type":"cookie","store_id":["0"]},{"cookie_id":"71","name":"_tt_enable_cookie","provider":"Girav","group":"marketing","description":"Used by the social network service, TikTok, to track the use of embedded services.","retention":"1 year","type":"cookie","store_id":["0"]},{"cookie_id":"72","name":"_ttp","provider":"Girav","group":"marketing","description":"Used by the social network service, TikTok, to track the use of embedded services.","retention":"1 year","type":"cookie","store_id":["0"]},{"cookie_id":"73","name":"_uetsid","provider":"Girav","group":"marketing","description":"Collects data on visitor behavior from multiple websites, to display more relevant advertisements - This also allows the website to limit the number of times the visitor sees the same advertisement.","retention":"1 day","type":"cookie","store_id":["0"]},{"cookie_id":"74","name":"_uetvid","provider":"Girav","group":"marketing","description":"Used to track visitors across multiple websites, to present relevant advertisements based on the visitor's preferences.","retention":"1 year","type":"cookie","store_id":["0"]},{"cookie_id":"75","name":"cto_bundle","provider":"Girav","group":"marketing","description":"Used to present relevant content and advertisements to the visitor - The service is provided by third-party advertising hubs, facilitating real-time bidding for advertisers.","retention":"13 months","type":"cookie","store_id":["0"]},{"cookie_id":"76","name":"cto_tld_test","provider":"Girav","group":"marketing","description":"Used to identify the visitor during visits, and across different devices. This allows the website to provide the visitor with relevant advertisements. The service is provided by third-party advertising hubs, enabling real-time bidding v","retention":"1 day","type":"cookie","store_id":["0"]},{"cookie_id":"77","name":"mf_#","provider":"Girav","group":"marketing","description":"Collects data about the user's navigation and interaction on the website to personalize the purchase experience.","retention":"3 months","type":"cookie","store_id":["0"]},{"cookie_id":"78","name":"sqzl_session_id","provider":"Girav","group":"marketing","description":"Collects data about visitors. This information is used to segment visitors, making website advertising more efficient.","retention":"1 day","type":"cookie","store_id":["0"]},{"cookie_id":"79","name":"sqzllocal","provider":"Girav","group":"marketing","description":"Collects data regarding the user's visits to the website, such as the number of visits, the average time spent on the website, and which pages were loaded, with the aim of displaying targeted advertisements.","retention":"30 year","type":"cookie","store_id":["0"]},{"cookie_id":"80","name":"ttcsid","provider":"Girav","group":"marketing","description":"Used to track visitors across multiple websites, to present relevant advertisements based on the visitor's preferences.","retention":"1 year","type":"cookie","store_id":["0"]},{"cookie_id":"81","name":"ttcsid_#","provider":"Girav","group":"marketing","description":"Tracks the conversion rate between the user and the advertising banners on the website - This serves to optimize the relevance of the advertisements on the website.","retention":"1 year","type":"cookie","store_id":["0"]},{"cookie_id":"82","name":"ads\/ga-audiences","provider":"Google","group":"marketing","description":"","retention":"Session","type":"cookie","store_id":["0"]},{"cookie_id":"83","name":"pagead\/1p-user-list\/#","provider":"Google","group":"marketing","description":"Used to track whether the visitor has shown interest in specific products or events across multiple websites and detects how the visitor navigates between sites - This is used for measuring advertising efforts and ver","retention":"Session","type":"cookie","store_id":["0"]},{"cookie_id":"84","name":"track.php","provider":"Roeye","group":"marketing","description":"Collects data about the visitor across various websites. This data is used to make advertisements more relevant.","retention":"Session","type":"cookie","store_id":["0"]},{"cookie_id":"85","name":"_fbp","provider":"Spotler","group":"marketing","description":"This cookie is used by Facebook to display targeted advertisements based on visitor behavior and preferences across multiple websites - The cookie contains an encrypted ID that allows Facebook to identify the visitor on websites.","retention":"Permanent ","type":"localstorage","store_id":["0"]},{"cookie_id":"86","name":"sqzl_session_id","provider":"Spotler","group":"marketing","description":"Collects data about visitors. This information is used to segment visitors, making website ads more efficient.","retention":"Permanent ","type":"localstorage","store_id":["0"]},{"cookie_id":"87","name":"sqzl_vw","provider":"Spotler","group":"marketing","description":"Collects data about visitors. This information is used to segment visitors, making website ads more efficient.","retention":"Permanent ","type":"localstorage","store_id":["0"]},{"cookie_id":"88","name":"sqzllocal","provider":"Spotler","group":"marketing","description":"Collects data regarding the user's visits to the website, such as the number of visits, the average time spent on the website, and which pages were loaded, with the aim of displaying targeted ads.","retention":"Permanent ","type":"localstorage","store_id":["0"]},{"cookie_id":"89","name":"t","provider":"Spotler","group":"marketing","description":"","retention":"Session","type":"cookie","store_id":["0"]},{"cookie_id":"90","name":"_ttp","provider":"Tiktok","group":"marketing","description":"Used by the social network service, TikTok, to track the use of embedded services.","retention":"1 year","type":"cookie","store_id":["0"]},{"cookie_id":"91","name":"criteo_write_test","provider":"Girav","group":"marketing","description":"Set
922s a unique ID for the visitor, allowing external advertisers to target the visitor with relevant advertisements. This linking service is provided by third-party advertising hubs, which improves real-time bidding for advertisers","retention":"1 day","type":"cookie","store_id":["0"]},{"cookie_id":"92","name":"__Secure-ROLLOUT_TOKEN","provider":"Youtube","group":"marketing","description":"Used to track user interaction with embedded content.","retention":"180 days","type":"cookie","store_id":["0"]},{"cookie_id":"93","name":"__Secure-YEC","provider":"Youtube","group":"marketing","description":"Stores the user's video player preferences with embedded YouTube video","retention":"Session","type":"cookie","store_id":["0"]},{"cookie_id":"94","name":"__Secure-YNID","provider":"Youtube","group":"marketing","description":"Used to track user interaction with embedded content.","retention":"180 days","type":"cookie","store_id":["0"]},{"cookie_id":"95","name":"LAST_RESULT_ENTRY_KEY","provider":"Youtube","group":"marketing","description":"Used to track user interaction with embedded content.","retention":"Session","type":"cookie","store_id":["0"]},{"cookie_id":"96","name":"LogsDatabaseV2:V#||LogsRequestsStore","provider":"Youtube","group":"marketing","description":"Used to track user interaction with embedded content.","retention":"Permanent ","type":"cookie","store_id":["0"]},{"cookie_id":"97","name":"TESTCOOKIESENABLED","provider":"Youtube","group":"marketing","description":"Used to track user interaction with embedded content.","retention":"1 day","type":"cookie","store_id":["0"]},{"cookie_id":"98","name":"VISITOR_INFO1_LIVE","provider":"Youtube","group":"marketing","description":"Attempts to estimate user bandwidth on pages with embedded YouTube videos.","retention":"180 days","type":"cookie","store_id":["0"]},{"cookie_id":"99","name":"YSC","provider":"Youtube","group":"marketing","description":"Registers a unique ID to track statistics on which YouTube videos the user has watched.","retention":"Session","type":"cookie","store_id":["0"]},{"cookie_id":"100","name":"yt-icons-last-purged","provider":"Youtube","group":"marketing","description":"Necessary for the implementation and functionality of YouTube videos on the website.","retention":"Permanent ","type":"localstorage","store_id":["0"]},{"cookie_id":"101","name":"ytidb::LAST_RESULT_ENTRY_KEY","provider":"Youtube","group":"marketing","description":"Stores the user's video player preferences with embedded YouTube video","retention":"Permanent ","type":"localstorage","store_id":["0"]},{"cookie_id":"102","name":"YtIdbMeta#databases","provider":"Youtube","group":"marketing","description":"Used to track user interaction with embedded content.","retention":"Permanent ","type":"cookie","store_id":["0"]},{"cookie_id":"103","name":"client_cookie","provider":"Girav","group":"preferences","description":"","retention":"Permanent ","type":"localstorage","store_id":["0"]},{"cookie_id":"104","name":"girav_configurator_session","provider":"Girav","group":"preferences","description":"","retention":"1 day","type":"cookie","store_id":["0"]},{"cookie_id":"105","name":"rumv","provider":"Rumvision","group":"preferences","description":"","retention":"Session","type":"localstorage","store_id":["0"]},{"cookie_id":"106","name":"lantern","provider":"Girav","group":"preferences","description":"","retention":"30 days","type":"cookie","store_id":["0"]},{"cookie_id":"107","name":"_conv_check_cookies","provider":"Girav","group":"preferences","description":"","retention":"5 year","type":"cookie","store_id":["0"]},{"cookie_id":"108","name":"_conv_t","provider":"Girav","group":"preferences","description":"","retention":"Session","type":"cookie","store_id":["0"]},{"cookie_id":"109","name":"_kbuid","provider":"Girav","group":"preferences","description":"","retention":"Session","type":"cookie","store_id":["0"]},{"cookie_id":"110","name":"#_lantern","provider":"Roeye","group":"preferences","description":"","retention":"6 months","type":"cookie","store_id":["0"]},{"cookie_id":"111","name":"APPID","provider":"Roeye","group":"preferences","description":"","retention":"Session","type":"cookie","store_id":["0"]},{"cookie_id":"112","name":"convert#config","provider":"Girav","group":"preferences","description":"","retention":"Permanent","type":"cookie","store_id":["0"]},{"cookie_id":"113","name":"convert#signals","provider":"Girav","group":"preferences","description":"","retention":"Permanent","type":"cookie","store_id":["0"]},{"cookie_id":"114","name":"custom_culture","provider":"Girav","group":"preferences","description":"","retention":"Permanent","type":"localstorage","store_id":["0"]}],"groups":[{"name":"Essential","identifier":"essential","description":"Necessary cookies help make a website usable by enabling basic functions like page navigation and access to secure areas of the website. The website cannot function properly without these cookies."},{"name":"Marketing","identifier":"marketing","description":"Marketing cookies are used to track visitors across websites. The intention is to display ads that are relevant and engaging for the individual user and thereby more valuable for publishers and third party advertisers."},{"name":"Preferences","identifier":"preferences","description":"Preference cookies enable a website to remember information that changes the way the website behaves or looks, like your preferred language or the region that you are in."},{"name":"Analytics","identifier":"analytics","description":"Statistic cookies help website owners to understand how visitors interact with websites by collecting and reporting information anonymously."}],"providers":[{"name":"Google","description":"Some of the data collected by this provider is for the purposes of personalization and measuring advertising effectiveness.","url":"https:\/\/business.safety.google\/privacy\/"},{"name":"Meta","description":"Marketing cookies are used to track visitors across websites. The intention is to display ads that are relevant and engaging for the individual user and thereby more valuable for publishers and third party advertisers.","url":"https:\/\/www.facebook.com\/privacy\/policies\/cookies\/"}
922,{"name":"Magento","description":"These cookies are essential for the website's functionality and security. They enable core features such as user authentication, session management, and compliance with legal obligations","url":"https:\/\/business.adobe.com\/products\/magento\/magento-commerce.html"},{"name":"Adobe Commerce","description":"These cookies are essential for the website's functionality and security. They enable core features such as user authentication, session management, and compliance with legal obligations","url":"https:\/\/business.adobe.com\/products\/magento\/magento-commerce.html"},{"name":"Girav","description":"Dit zijn cookies voor analyse van onze klanten voor website optimalisatie","url":"https:\/\/girav.nl"},{"name":"Mouseflow","description":"Mouseflow","url":"https:\/\/mouseflow.com\/"},{"name":"Youtube","description":"Youtube","url":"https:\/\/youtube.nl"},{"name":"Kickbite","description":"Kickbite","url":"https:\/\/www.kickbite.io\/nl"},{"name":"Aiden","description":"Aiden","url":"https:\/\/aiden.eu\/"},{"name":"Tiktok","description":"Tiktok","url":"https:\/\/www.tiktok.com\/nl-NL\/"},{"name":"Microsoft","description":"Microsoft","url":"https:\/\/www.microsoft.com\/nl-nl"},{"name":"Spotler","description":"Spotler","url":"https:\/\/spotler.com\/nl-nl"},{"name":"Rumvision","description":"Rumvision","url":"https:\/\/www.rumvision.com\/"},{"name":"Roeye","description":"Roeye","url":"https:\/\/roeye.com\/"}],"storeCode":"nl_nl"} 923 </script>
923 924
924<script src="https://www.girav.nl/static/version1790837059/frontend/Girav/hyva/nl_NL/Emico_CookieBanner/js/banner.js" async></script>
924 925 926<!-- GOOGLE TAG MANAGER --> 927<noscript> 928 <iframe src="https://a.girav.nl/ns.html?id=GTM-5X69RK5" aria-hidden="true" 929 height="0" width="0" style="display:none;visibility:hidden"></iframe> 930</noscript> 931<!-- END GOOGLE TAG MANAGER --> 932
932<script type="application/ld+json">{"@context":"http:\/\/schema.org","@type":"WebPage","name":"","headline":"","description":"","url":"https:\/\/www.girav.nl\/customer\/account\/login\/"}</script>
932 933 <input name="form_key" type="hidden" value="x2axT8CBZcoKxPKB" /> 934 <noscript> 935 <section 936 class="message global noscript border-b-2 border-blue-500 bg-blue-50 shadow-none m-0 px-0 rounded-none font-normal" 937 aria-labelledby="messageGlobalNoScriptMessage" 938 > 939 <div class="container text-center"> 940 <p id="messageGlobalNoScriptMessage"> 941 <strong>JavaScript lijkt te zijn uitgeschakeld in uw browser.</strong> 942 <span> 943 Voor de beste gebruikerservaring, zorg ervoor dat javascript ingeschakeld is voor uw browser. </span> 944 </p> 945 </div> 946 </section> 947 </noscript> 948 949
950<script> 951 document.body.addEventListener('touchstart', () => {}, {passive: true}) 952</script>
952 953<div class="page-wrapper"><header class="page-header"><a class="action skip sr-only focus:not-sr-only focus:absolute focus:z-40 focus:bg-white 954 contentarea" 955 href="#contentarea"> 956 <span> 957 Ga naar de inhoud </span> 958</a> 959
960<script> 961 function initHeader() { 962 return { 963 searchOpen: false, 964 cart: {}, 965 wishlist_count: null, 966 isSticky: false, 967 getData(data) { 968 if (data.cart) { 969 this.cart = data.cart 970 } 971 if (data.wishlist) { 972 this.wishlist_count = data.wishlist.items.length; 973 } 974 }, 975 isInViewPort() { 976 let element = this.$refs['stickyContainer']; 977 const rect = element && element.getBoundingClientRect(); 978 this.isSticky = !(rect && rect.top >= 0); 979 if (this.isSticky) { 980 document.documentElement.style.setProperty('--page-header-height', (element.clientHeight) + 'px'); 981 } else { 982 const pageHeader = document.getElementById('header'); 983 let pageHeaderHeight = pageHeader.clientHeight; 984 985 document.documentElement.style.setProperty('--page-header-height', (pageHeaderHeight) + 'px'); 986 } 987 }, 988 onInit() { 989 this.isInViewPort(); 990 } 991 } 992 } 993 994</script>
994 995 996 997 998<div 999 id="header" 1000 class="relative w-full text-white h-[88px]" 1001 x-data="initHeader()" 1002 @keydown.window.escape="searchOpen = false;" 1003 @private-content-loaded.window="getData(event.detail.data)" 1004 x-init="onInit" 1005 @scroll.window="isInViewPort" 1006> 1007 <div class="top-header bg-[#2A2A2A] h-7"> 1008 <div class="container flex justify-between"> 1009 1010 <div class="usps-list relative justify-self-center lg:justify-self-start w-full h-4 mt-1"> 1011 1012 <div class="usps-list relative justify-self-center lg:justify-self-start w-full h-4"> 1013 <div class="usps-item text-[10px] lg:text-[13px] !leading-none w-full flex flex-row justify-center lg:justify-start items-center absolute opacity-0 will-change-[opacity] font-medium" 1014 style="animation: fadeInOut 12s infinite 0s;"> 1015 <div>Perfecte pasvorm â elke maat in <b>3 lengtes</b></div> 1016 </div> 1017 <div class="usps-item text-[10px] lg:text-[13px] !leading-none w-full flex flex-row justify-center lg:justify-start items-center absolute opacity-0 will-change-[opacity] font-medium" 1018 style="animation: fadeInOut 12s infinite 4s;"> 1019 <div>Altijd <b>gratis</b> verzending</div> 1020 </div> 1021 <div class="usps-item text-[10px] lg:text-[13px] !leading-none w-full flex flex-row justify-center lg:justify-start items-center absolute opacity-0 will-change-[opacity] font-medium" 1022 style="animation: fadeInOut 12s infinite 8s;"> 1023 <div>100 dagen <b>gratis</b> retourneren</div> 1024 </div> 1025 </div> 1026 </div> 1027 1028 <div class="kiyoh hidden lg:flex justify-self-end"> 1029 <span class="flex flex-col justify-center mr-1"> 1030 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 34 32" class="text-[#3398FF] inline" width="17" height="17" role="img"> 1031 <path fill="currentColor" d="m17 0-4 12.2H0l10.5 7.6-4 12.2L17 24.4 27.5 32l-4-12.2L34 12.2H21z"/> 1032<title>trust-star</title></svg> 1033 </span> 1034 <a href="https://www.kiyoh.com/reviews/1047750/girav" target="_blank" rel="nofollow" class="flex flex-row text-xs w-max mt-1"> 1035 <div class="kiyoh-total font-medium"> 1036 <span class="kiyoh-score font-medium text-[#3999FB]">9.1</span> 1037 <span class="kiyoh-score font-medium text-white"> / 10 </span> 1038 </div> 1039 <div class="kiyoh-content font-medium text-[#919191]"> 1040 11.343 reviews </div> 1041 </a> 1042 </div> 1043 </div> 1044 </div> 1045 1046 <div class="action-header h-[60px]" x-ref="stickyContainer"> 1047 <div 1048 class="h-[60px] mobile-sticky-header relative z-30" 1049 :class="{'sticky': isSticky}" 1050 > 1051 <div 1052 class="header-backdrop absolute top-0 left-0 h-full w-full" 1053 :class="{'bg-white/50 backdrop-blur-xl shadow-[0_12px_16px_-4px_rgba(16,24,40,0.08)]': isSticky}" 1054 > 1055 </div> 1056 <div class="h-[60px] container grid grid-cols-[minmax(0,1fr)_auto_minmax(0,1fr)] items-center relative z-10 md:bg-transparent"> 1057 <div class="flex flex-row flex-wrap md:justify-self-start gap-x-2 lg:gap-x-4 xl:gap-x-8"> 1058 1059 1060 1061 <div 1062 x-data="initMenu_6ac56e269904b()" 1063 @click.away="setMenuOpen(false)" 1064 @toggle-menu.window="setMenuOpen(false)" 1065 @keydown.window.escape="setMenuOpen(false)" 1066 class="default-menu offcanvas-menu" 1067 > 1068 <button 1069 @click="open = !open, setMenuOpen(open)" 1070 class="h-full flex-col justify-center flex gap-2 items-center font-semibold" 1071 aria-label="Open menu" 1072 > 1073 <span x-show="!open"> 1074 <svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="main-menu-item text-[#2a2a2a] p-2" width="40" height="40" aria-hidden="true"><g fill="currentColor" fill-rule="nonzero"><path d="M3 7.75c-.41 0-.75-.34-.75-.75s.34-.75.75-.75h18c.41 0 .75.34.75.75s-.34.75-.75.75H3zM3 12.75c-.41 0-.75-.34-.75-.75s.34-.75.75-.75h18c.41 0 .75.34.75.75s-.34.75-.75.75H3zM3 17.75c-.41 0-.75-.34-.75-.75s.34-.75.75-.75h18c.41 0 .75.34.75.75s-.34.75-.75.75H3z"/></g></svg> 1075 </span>
1076 <span x-cloak x-show="open"> 1077 <svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 44 44" fill="none" class="main-menu-item text-[#2a2a2a]" aria-hidden="true"> 1078 <path d="M28 16L16 28M16 16L28 28" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/> 1079</svg> 1080 </span> 1081 </button> 1082 1083 <div class="backdrop" @click="open = !open, setMenuOpen(open)"></div> 1084 <template x-if="open"> 1085 <dialog class="offcanvas-dialog"> 1086 <div class="dialog-inner"> 1087 <div 1088 class="menu-level level-0 pt-6 lg:pt-0" 1089 :class="{ 1090 'lg-max:overflow-hidden' : menuPanelActiveId !== null, 1091 'lg-max:overflow-scroll' : menuPanelActiveId === null 1092 }" 1093 > 1094 <div class="hidden lg:flex justify-between items-center px-10 pt-6 pb-4"> 1095 <span class="">Menu</span> 1096 <button @click="$dispatch('toggle-menu')" class="p-2"> 1097 <svg xmlns="http://www.w3.org/2000/svg" role="img" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="closeIconTitle" stroke="currentColor" stroke-width="1.5" stroke-linecap="square" stroke-linejoin="miter" fill="none" color="currentColor" aria-hidden="true"> <title id="closeIconTitle">Close</title> <path d="M6.34314575 6.34314575L17.6568542 17.6568542M6.34314575 17.6568542L17.6568542 6.34314575"/> </svg> 1098 </button> 1099 </div> 1100 <div 1101 class="menu-item " 1102 :class="{ 1103 'overflow-hidden' : menuPanelActiveId === '0', 1104 }"> 1105 <a 1106 class="menu-link level-0 group" 1107 href="https://www.girav.nl/nieuw-binnen" 1108 title="Nieuw binnen" 1109 style="" 1110 > 1111 Nieuw binnen <span> 1112 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="px-2 w-10" width="18" height="18" aria-hidden="true"> 1113 <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m9 18 6-6-6-6"/> 1114</svg> 1115 </span> 1116 </a> 1117 1118 </div> 1119 <div 1120 class="menu-item " 1121 :class="{ 1122 'overflow-hidden' : menuPanelActiveId === '1', 1123 }"> 1124 <a 1125 class="menu-link level-0 group" 1126 href="https://www.girav.nl/bestsellers" 1127 title="Bestsellers" 1128 style="" 1129 > 1130 Bestsellers <span> 1131 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="px-2 w-10" width="18" height="18" aria-hidden="true"> 1132 <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m9 18 6-6-6-6"/> 1133</svg> 1134 </span> 1135 </a> 1136 1137 </div> 1138 <div 1139 class="menu-item " 1140 :class="{ 1141 'overflow-hidden' : menuPanelActiveId === '2', 1142 }"> 1143 <a 1144 class="menu-link level-0 group" 1145 href="https://www.girav.nl/nieuwe-collectie" 1146 title="Herfst/Winter Collectie '26" 1147 style="color: #254ef0" 1148 > 1149 Herfst/Winter Collectie '
114926 <span> 1150 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="px-2 w-10" width="18" height="18" aria-hidden="true"> 1151 <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m9 18 6-6-6-6"/> 1152</svg> 1153 </span> 1154 </a> 1155 1156 </div> 1157 <div 1158 class="menu-item " 1159 :class="{ 1160 'overflow-hidden' : menuPanelActiveId === '3', 1161 }"> 1162 <button 1163 class="menu-link level-0 group" 1164 :class="{ 1165 'active' : menuPanelActiveId === '4', 1166 }" 1167 @click="menuPanelActiveId = menuPanelActiveId === '4' 1168 ? 0 1169 : '4' 1170 " 1171 > 1172 T-shirts <span> 1173 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="px-2 w-10" width="18" height="18" aria-hidden="true"> 1174 <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m9 18 6-6-6-6"/> 1175</svg> 1176 </span> 1177 </button> 1178 1179 <div class="submenu level-1" 1180 :class="{ 1181 'open' : menuPanelActiveId === '4' 1182 }" 1183 @click="window.innerWidth >= 1024 ? setMenuOpen(false) : null" 1184 > 1185 <div class="menu-level level-1"> 1186 <div class="container py-3 lg:px-10 lg:pt-12 flex flex-col gap-4 lg:gap-10"> 1187 <button @click="menuPanelActiveId = null" class="flex gap-2 lg:hidden text-left items-center"> 1188 <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 15 10" fill="none" aria-hidden="true"> 1189 <path d="M2 5L6 1M2 5L6 9M2 5H14.5" stroke="currentColor" stroke-width="1.5"/> 1190</svg> 1191 Terug </button> 1192 1193 <span 1194 class="text-xl font-bold inline" 1195 style="" 1196 > 1197 T-shirts in 3 lengtes </span> 1198 </div> 1199 1200 <div class="menu-item group "> 1201 <a 1202 class="menu-link level-1" 1203 href="https://www.girav.nl/t-shirts" 1204 title="Alle T-shirts" 1205 style=""> 1206 <strong class="flex items-start gap-2"> 1207 <span>Alle T-shirts</span> 1208 </strong> 1209 <sp
1209an class="menu-subtitle">Bekijk de hele T-shirt collectie</span> 1210 </a> 1211 <div class="submenu level-2 lg:group-hover:open"> 1212 <div class="menu-level level-2"> 1213 <div class=""> 1214 <img src="https://www.girav.nl/media/menu/Menu_Alle_T-shirts_1.jpg" /> 1215 </div> 1216 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 1217 <strong class="text-xl font-bold">Alle T-shirts</strong> 1218 </div> 1219 </div> 1220 </div> 1221 </div> 1222 <div class="menu-item group "> 1223 <a 1224 class="menu-link level-1" 1225 href="https://www.girav.nl/t-shirts/basic" 1226 title="Premium basic T-shirts" 1227 style=""> 1228 <strong class="flex items-start gap-2"> 1229 <span>Premium basic T-shirts</span> 1230 </strong> 1231 <span class="menu-subtitle">In zwart, wit en navy</span> 1232 </a> 1233 <div class="submenu level-2 lg:group-hover:open"> 1234 <div class="menu-level level-2"> 1235 <div class=""> 1236 <img src="https://www.girav.nl/media/menu/Menu_Afbeeldingen_Basic_t-shirts_6.jpg" /> 1237 </div> 1238 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 1239 <strong class="text-xl font-bold">Premium basic T-shirts</strong> 1240 <p class="text-gray-500 text-base">Ruime keuze uit verschillende modellen v-hals en ronde hals t-shirts in wit, zwart en navy. Perfect als ondershirt of gewoon als T-shirt.</p> 1241 </div> 1242 </div> 1243 </div> 1244 </div> 1245 <div class="menu-item group "> 1246 <a 1247 class="menu-link level-1" 1248 href="https://www.girav.nl/t-shirts/effen" 1249 title="Gekleurde T-shirts" 1250 style=""> 1251 <strong class="flex items-start gap-2">
1252 <span>Gekleurde T-shirts</span> 1253 <label class="menu-label" style="background-color: #000000;color: #FFFFFF"> 1254 2 voor ⬠40 </label> 1255 </strong> 1256 <span class="menu-subtitle">In 30 kleuren. Nu 2 voor â¬40, mixen mogelijk.</span> 1257 </a> 1258 <div class="submenu level-2 lg:group-hover:open"> 1259 <div class="menu-level level-2"> 1260 <div class=""> 1261 <img src="https://www.girav.nl/media/menu/Menu_Sydney_colored_1.jpg" /> 1262 </div> 1263 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 1264 <strong class="text-xl font-bold">Gekleurde T-shirts</strong> 1265 <p class="text-gray-500 text-base">Onze bestseller T-shirts in ronde hals en v-hals. Verkrijgbaar in 30 kleuren.</p> 1266 </div> 1267 </div> 1268 </div> 1269 </div> 1270 <div class="menu-item group "> 1271 <a 1272 class="menu-link level-1" 1273 href="https://www.girav.nl/t-shirts/sixpack" 1274 title="6-pack voordeel" 1275 style=""> 1276 <strong class="flex items-start gap-2"> 1277 <span>6-pack voordeel</span> 1278 <label class="menu-label" style="background-color: #000000;color: #ffffff"> 1279 -10% korting </label> 1280 </strong> 1281 <span class="menu-subtitle">Multipacks in zwart, wit en navy</span> 1282 </a> 1283 <div class="submenu level-2 lg:group-hover:open"> 1284 <div class="menu-level level-2"> 1285 <div class=""> 1286 <img src="https://www.girav.nl/media/menu/6-pack_T-shirt-1.jpg" /> 1287 </div> 1288 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 1289 <strong class="text-xl font-bold">6-pack voordeel</strong> 1290 <p class="text-gray-500 text-base">Profiteer van 10% korting op onze 6-pack T-shirts.</p> 1291 </div> 1292 </div> 1293 </div> 1294 </div> 1295 <div class="menu-item group "> 1296 <a 1297 class="menu-link level-1" 1298 href="https://www.girav.nl/t-shirts/oversized" 1299 title="Oversized T-shirts" 1300 style=""> 1301 <strong class="flex items-start gap-2">
1302 <span>Oversized T-shirts</span> 1303 </strong> 1304 <span class="menu-subtitle">220 gram, extra zwaar katoen</span> 1305 </a> 1306 <div class="submenu level-2 lg:group-hover:open"> 1307 <div class="menu-level level-2"> 1308 <div class=""> 1309 <img src="https://www.girav.nl/media/menu/Menu_Afbeeldingen_Oversized_6.jpg" /> 1310 </div> 1311 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 1312 <strong class="text-xl font-bold">Oversized T-shirts</strong> 1313 <p class="text-gray-500 text-base">Comfortabele T-shirts met extra ruime pasvorm. Gemaakt van premium Amerikaans katoen. In 3 lengtes.</p> 1314 </div> 1315 </div> 1316 </div> 1317 </div> 1318 <div class="menu-item group "> 1319 <a 1320 class="menu-link level-1" 1321 href="https://www.girav.nl/t-shirts/merino" 1322 title="Merinowol T-shirts" 1323 style=""> 1324 <strong class="flex items-start gap-2"> 1325 <span>Merinowol T-shirts</span> 1326 </strong> 1327 <span class="menu-subtitle">Antibacterieel en vochtregulerend</span> 1328 </a> 1329 <div class="submenu level-2 lg:group-hover:open"> 1330 <div class="menu-level level-2"> 1331 <div class=""> 1332 <img src="https://www.girav.nl/media/menu/Menu_Afbeeldingen_Merino_ondershirt_1.jpg" /> 1333 </div> 1334 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 1335 <strong class="text-xl font-bold">Merinowol T-shirts</strong> 1336 <p class="text-gray-500 text-base">Luxe T-shirts gemaakt van 100% fijne merino wol. De wol is zacht en kriebelt niet, is ademend, vochtregulerend en antibacterieel. 1337</p> 1338 </div> 1339 </div> 1340 </div> 1341 </div> 1342 <div class="menu-item group "> 1343 <a 1344 class="menu-link level-1" 1345 href="https://www.girav.nl/t-shirts/shirts-lange-mouw" 1346 title="Longsleeves" 1347 style=""> 1348 <strong class="flex items-start gap-2">
1349 <span>Longsleeves</span> 1350 </strong> 1351 <span class="menu-subtitle">T-shirts met lange mouw</span> 1352 </a> 1353 <div class="submenu level-2 lg:group-hover:open"> 1354 <div class="menu-level level-2"> 1355 <div class=""> 1356 <img src="https://www.girav.nl/media/menu/Menu_Afbeeldingen_longsleeves_6.jpg" /> 1357 </div> 1358 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 1359 <strong class="text-xl font-bold">Longsleeves</strong> 1360 <p class="text-gray-500 text-base">Draag casual of als ondershirt tijdens koele dagen. Keuze uit regular fit en slim fit.</p> 1361 </div> 1362 </div> 1363 </div> 1364 </div> 1365 <div class="menu-item group "> 1366 <a 1367 class="menu-link level-1" 1368 href="https://www.girav.nl/t-shirts/ondershirts" 1369 title="Ondershirts" 1370 style=""> 1371 <strong class="flex items-start gap-2"> 1372 <span>Ondershirts</span> 1373 </strong> 1374 <span class="menu-subtitle">Perfect voor onder een overhemd</span> 1375 </a> 1376 <div class="submenu level-2 lg:group-hover:open"> 1377 <div class="menu-level level-2"> 1378 <div class=""> 1379 <img src="https://www.girav.nl/media/menu/Menu_Afbeeldingen_Hanoi_1.jpg" /> 1380 </div> 1381 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 1382 <strong class="text-xl font-bold">Ondershirts</strong> 1383 <p class="text-gray-500 text-base">T-shirts speciaal ontwikkeld om onzichtbaar te zijn onder een overhemd. Extra lichte stof en diepere v-hals.</p> 1384 </div> 1385 </div> 1386 </div> 1387 </div> 1388 <div class="menu-item group "> 1389 <a 1390 class="menu-link level-1" 1391 href="https://www.girav.nl/t-shirts/hemden" 1392 title="Hemden" 1393 style=""> 1394 <strong class="flex items-start gap-2">
1395 <span>Hemden</span> 1396 </strong> 1397 <span class="menu-subtitle">In zwart, wit en invisible</span> 1398 </a> 1399 <div class="submenu level-2 lg:group-hover:open"> 1400 <div class="menu-level level-2"> 1401 <div class=""> 1402 <img src="https://www.girav.nl/media/menu/Menu_Afbeeldingen_Singlets_1_1.jpg" /> 1403 </div> 1404 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 1405 <strong class="text-xl font-bold">Hemden</strong> 1406 <p class="text-gray-500 text-base">Multifunctioneel onderhemd, ideaal voor sport, casual in de zomer of als ondershirt. Gemaakt van comfortabele stretch katoen.</p> 1407 </div> 1408 </div> 1409 </div> 1410 </div> 1411 <div class="menu-item group "> 1412 <a 1413 class="menu-link level-1" 1414 href="https://www.girav.nl/sportkleding/sportshirts" 1415 title="Sportshirts" 1416 style=""> 1417 <strong class="flex items-start gap-2"> 1418 <span>Sportshirts</span> 1419 </strong> 1420 <span class="menu-subtitle">Met Polygiene Stay Fresh Technology</span> 1421 </a> 1422 <div class="submenu level-2 lg:group-hover:open"> 1423 <div class="menu-level level-2"> 1424 <div class=""> 1425 <img src="https://www.girav.nl/media/menu/Menu_Afbeeldingen_Sportshirts_7.jpg" /> 1426 </div> 1427 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 1428 <strong class="text-xl font-bold">Sportshirts</strong> 1429 <p class="text-gray-500 text-base">Comfortabele sportshirts met Polygiene Stay Fresh Technology, hierdoor blijf je ook fris tijdens het sporten. In 3 lengtes</p> 1430 </div> 1431 </div> 1432 </div> 1433 </div> 1434 </div> 1435 </div> 1436 </div> 1437 <div 1438 class="menu-item " 1439 :class="{ 1440 'overflow-hidden' : menuPanelActiveId === '4', 1441 }"> 1442 <button 1443 class="menu-link level-0 group" 1444 :class="{ 1445 'active' : menuPanelActiveId === '5', 1446 }" 1447 @click="menuPanelActiveId = menuPanelActiveId === '5' 1448 ? 0 1449 : '5' 1450 " 1451 > 1452 Polo'
1452s <span> 1453 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="px-2 w-10" width="18" height="18" aria-hidden="true"> 1454 <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m9 18 6-6-6-6"/> 1455</svg> 1456 </span> 1457 </button> 1458 1459 <div class="submenu level-1" 1460 :class="{ 1461 'open' : menuPanelActiveId === '5' 1462 }" 1463 @click="window.innerWidth >= 1024 ? setMenuOpen(false) : null" 1464 > 1465 <div class="menu-level level-1"> 1466 <div class="container py-3 lg:px-10 lg:pt-12 flex flex-col gap-4 lg:gap-10"> 1467 <button @click="menuPanelActiveId = null" class="flex gap-2 lg:hidden text-left items-center"> 1468 <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 15 10" fill="none" aria-hidden="true"> 1469 <path d="M2 5L6 1M2 5L6 9M2 5H14.5" stroke="currentColor" stroke-width="1.5"/> 1470</svg> 1471 Terug </button> 1472 1473 <span 1474 class="text-xl font-bold inline" 1475 style="" 1476 > 1477 Polo's in 3 lengtes </span> 1478 </div> 1479 1480 <div class="menu-item group "> 1481 <a 1482 class="menu-link level-1" 1483 href="https://www.girav.nl/polo-shirts" 1484 title="Alle polo's" 1485 style=""> 1486 <strong class="flex items-start gap-2"> 1487 <span>Alle polo's</span> 1488 </strong> 1489 <span class="menu-subtitle">Bekijk de hele polo collectie</span> 1490 </a> 1491 <div class="submenu level-2 lg:group-hover:open"> 1492 <div class="menu-level level-2"> 1493 <div class=""> 1494 <img src="https://www.girav.nl/media/menu/Menu_Lange_Mouwen_Polo_s_1.jpg" /> 1495 </div> 1496 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 1497 <strong class="text-xl font-bold">Alle polo's</strong> 1498 </div> 1499 </div> 1500 </div> 1501 </div> 1502 <div class="menu-item group "> 1503 <a 1504 class="menu-link level-1" 1505 href="https://www.girav.nl/polo-shirts/madrid" 1506 title="Klassieke polo's" 1507 style=""> 1508 <strong class="flex items-start gap-2">
1509 <span>Klassieke polo's</span> 1510 <label class="menu-label" style="background-color: #000000;color: #ffffff"> 1511 BESTSELLER </label> 1512 </strong> 1513 <span class="menu-subtitle">100% piqué katoen</span> 1514 </a> 1515 <div class="submenu level-2 lg:group-hover:open"> 1516 <div class="menu-level level-2"> 1517 <div class=""> 1518 <img src="https://www.girav.nl/media/menu/Menu_Madrid_nieuwe_kleur_1.jpg" /> 1519 </div> 1520 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 1521 <strong class="text-xl font-bold">Klassieke polo's</strong> 1522 <p class="text-gray-500 text-base">Het Madrid poloshirt heeft de typische polostof met wafelstructuur, polokraag en een normale pasvorm (regular fit). In 3 lengtes.</p> 1523 </div> 1524 </div> 1525 </div> 1526 </div> 1527 <div class="menu-item group "> 1528 <a 1529 class="menu-link level-1" 1530 href="https://www.girav.nl/polo-shirts/lange-mouw" 1531 title="Longsleeve polo's" 1532 style=""> 1533 <strong class="flex items-start gap-2"> 1534 <span>Longsleeve polo's</span> 1535 </strong> 1536 <span class="menu-subtitle">Gemaakt van 100% katoen of supreme jersey</span> 1537 </a> 1538 <div class="submenu level-2 lg:group-hover:open"> 1539 <div class="menu-level level-2"> 1540 <div class=""> 1541 <img src="https://www.girav.nl/media/menu/gir3201_50_CP-1_1.jpg" /> 1542 </div> 1543 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 1544 <strong class="text-xl font-bold">Longsleeve polo's</strong> 1545 <p class="text-gray-500 text-base">Tijdloze longsleeve polo's met extra lange mouwen. Kies uit klassieke of strijkvrije polo's of rugby shirts. In 3 lengtes. </p> 1546 </div> 1547 </div> 1548 </div> 1549 </div> 1550 <div class="menu-item group "> 1551 <a 1552 class="menu-link level-1" 1553 href="https://www.girav.nl/polo-shirts/slim-fit" 1554 title="Stretch polo's" 1555 style=""> 1556 <strong class="flex items-start gap-2">
1557 <span>Stretch polo's</span> 1558 </strong> 1559 <span class="menu-subtitle">Slim Fit polo's die meebewegen</span> 1560 </a> 1561 <div class="submenu level-2 lg:group-hover:open"> 1562 <div class="menu-level level-2"> 1563 <div class=""> 1564 <img src="https://www.girav.nl/media/menu/Menu_Marbella_1.jpg" /> 1565 </div> 1566 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 1567 <strong class="text-xl font-bold">Stretch polo's</strong> 1568 <p class="text-gray-500 text-base">De Marbella polo heeft een aangesloten pasvorm. Het stretch katoen zorgt voor veel comfort en bewegingsvrijheid. In 3 lengtes.</p> 1569 </div> 1570 </div> 1571 </div> 1572 </div> 1573 <div class="menu-item group "> 1574 <a 1575 class="menu-link level-1" 1576 href="https://www.girav.nl/polo-shirts/cadiz" 1577 title="Strijkvrije polo's" 1578 style=""> 1579 <strong class="flex items-start gap-2"> 1580 <span>Strijkvrije polo's</span> 1581 </strong> 1582 <span class="menu-subtitle">Luxe piqué stof, overhemdkraag</span> 1583 </a> 1584 <div class="submenu level-2 lg:group-hover:open"> 1585 <div class="menu-level level-2"> 1586 <div class=""> 1587 <img src="https://www.girav.nl/media/menu/Menu_Cadiz_1.jpg" /> 1588 </div> 1589 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 1590 <strong class="text-xl font-bold">Strijkvrije polo's</strong> 1591 <p class="text-gray-500 text-base">Ons Cadiz poloshirt is gemaakt van piqué stof. De overhemdkraag zorgt voor een elegante look. In 3 lengtes.</p> 1592 </div> 1593 </div> 1594 </div> 1595 </div> 1596 <div class="menu-item group "> 1597 <a 1598 class="menu-link level-1" 1599 href="https://www.girav.nl/polo-shirts/bilbao" 1600 title="Tech polo's" 1601 style=""> 1602 <strong class="flex items-start gap-2">
1603 <span>Tech polo's</span> 1604 </strong> 1605 <span class="menu-subtitle">Sneldrogend en antibacterieel</span> 1606 </a> 1607 <div class="submenu level-2 lg:group-hover:open"> 1608 <div class="menu-level level-2"> 1609 <div class=""> 1610 <img src="https://www.girav.nl/media/menu/Menu_Bilbao_1.jpg" /> 1611 </div> 1612 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 1613 <strong class="text-xl font-bold">Tech polo's</strong> 1614 <p class="text-gray-500 text-base">De Bilbao polo is gemaakt van technische stof: luchtig piqué en voorkomt transpiratie. Ideaal als vrijetijds- en outdoor polo. In 3 lengtes.</p> 1615 </div> 1616 </div> 1617 </div> 1618 </div> 1619 <div class="menu-item group "> 1620 <a 1621 class="menu-link level-1" 1622 href="https://www.girav.nl/girav-poloshirts" 1623 title="Polo uitleg" 1624 style=""> 1625 <strong class="flex items-start gap-2"> 1626 <span>Polo uitleg</span> 1627 </strong> 1628 <span class="menu-subtitle">Vergelijk de modellen</span> 1629 </a> 1630 </div> 1631 </div> 1632 </div> 1633 </div> 1634 <div 1635 class="menu-item " 1636 :class="{ 1637 'overflow-hidden' : menuPanelActiveId === '5', 1638 }"> 1639 <button 1640 class="menu-link level-0 group" 1641 :class="{ 1642 'active' : menuPanelActiveId === '6', 1643 }" 1644 @click="menuPanelActiveId = menuPanelActiveId === '6' 1645 ? 0 1646 : '6' 1647 " 1648 > 1649 Overhemden <span> 1650 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="px-2 w-10" width="18" height="18" aria-hidden="true"> 1651 <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m9 18 6-6-6-6"/> 1652</svg> 1653 </span> 1654 </button> 1655 1656 <div class="submenu level-1" 1657 :class="{ 1658 'open' : menuPanelActiveId === '6' 1659 }" 1660 @click="window.innerWidth >= 1024 ? setMenuOpen(false) : null" 1661 > 1662 <div class="menu-level level-1"> 1663 <div class="container py-3 lg:px-10 lg:pt-12 flex flex-col gap-4 lg:gap-10"> 1664 <button @click="menuPanelActiveId = null" class="flex gap-2 lg:hidden text-left items-center"> 1665 <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewB
1665ox="0 0 15 10" fill="none" aria-hidden="true"> 1666 <path d="M2 5L6 1M2 5L6 9M2 5H14.5" stroke="currentColor" stroke-width="1.5"/> 1667</svg> 1668 Terug </button> 1669 1670 <span 1671 class="text-xl font-bold inline" 1672 style="" 1673 > 1674 Overhemden in 3 lengtes </span> 1675 </div> 1676 1677 <div class="menu-item group "> 1678 <a 1679 class="menu-link level-1" 1680 href="https://www.girav.nl/overhemden" 1681 title="Alle overhemden" 1682 style=""> 1683 <strong class="flex items-start gap-2"> 1684 <span>Alle overhemden</span> 1685 </strong> 1686 <span class="menu-subtitle">Bekijk de hele overhemden collectie</span> 1687 </a> 1688 <div class="submenu level-2 lg:group-hover:open"> 1689 <div class="menu-level level-2"> 1690 <div class=""> 1691 <img src="https://www.girav.nl/media/menu/Menu_Alle_Overhemden_1.jpg" /> 1692 </div> 1693 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 1694 <strong class="text-xl font-bold">Alle overhemden</strong> 1695 </div> 1696 </div> 1697 </div> 1698 </div> 1699 <div class="menu-item group "> 1700 <a 1701 class="menu-link level-1" 1702 href="https://www.girav.nl/overhemden/strijkvrij" 1703 title="Strijkvrije overhemden" 1704 style=""> 1705 <strong class="flex items-start gap-2"> 1706 <span>Strijkvrije overhemden</span> 1707 <label class="menu-label" style="background-color: #000000;color: #FFFFFF"> 1708 Bestseller </label> 1709 </strong> 1710 <span class="menu-subtitle">Unieke katoenblend: snel droog en strijkvrij</span> 1711 </a> 1712 <div class="submenu level-2 lg:group-hover:open"> 1713 <div class="menu-level level-2"> 1714 <div class=""> 1715 <img src="https://www.girav.nl/media/menu/Pisa_overhemden-2_1.jpg" /> 1716 </div> 1717 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 1718 <strong class="text-xl font-bold">Strijkvrije overhemden</strong> 1719 <p class="text-gray-500 text-base">Comfortabele overhemden met een natuurlijke stretch. Ga voor comfort en ook voor het gemak van strijkvrij. </p> 1720 </div> 1721 </div> 1722 </div> 1723 </div> 1724 <div class="menu-item group "> 1725 <a 1726 class="menu-link level-1" 1727 href="https://www.girav.nl/overhemden/casual-overhemd" 1728 title="Casual overhemden" 1729 style=""> 1730 <strong class="flex items-start gap-2">
1731 <span>Casual overhemden</span> 1732 <label class="menu-label" style="background-color: #000000;color: #FFFFFF"> 1733 Nieuw </label> 1734 </strong> 1735 <span class="menu-subtitle">100% premium katoen lanel of warm merinowol</span> 1736 </a> 1737 <div class="submenu level-2 lg:group-hover:open"> 1738 <div class="menu-level level-2"> 1739 <div class=""> 1740 <img src="https://www.girav.nl/media/menu/Menu_casual_overhemden_1.jpg" /> 1741 </div> 1742 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 1743 <strong class="text-xl font-bold">Casual overhemden</strong> 1744 <p class="text-gray-500 text-base">Warme casual overhemden voor elke dag met perfecte pasvorm. In 3 lengtes</p> 1745 </div> 1746 </div> 1747 </div> 1748 </div> 1749 <div class="menu-item group "> 1750 <a 1751 class="menu-link level-1" 1752 href="https://www.girav.nl/overhemden/business" 1753 title="Business overhemden" 1754 style=""> 1755 <strong class="flex items-start gap-2"> 1756 <span>Business overhemden</span> 1757 <label class="menu-label" style="background-color: #000000;color: #ffffff"> 1758 New </label> 1759 </strong> 1760 <span class="menu-subtitle">Strijkvrij, premium stretch katoen</span> 1761 </a> 1762 <div class="submenu level-2 lg:group-hover:open"> 1763 <div class="menu-level level-2"> 1764 <div class=""> 1765 <img src="https://www.girav.nl/media/menu/Menu_Lucca_overhemd_1.jpg" /> 1766 </div> 1767 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 1768 <strong class="text-xl font-bold">Business overhemden</strong> 1769 <p class="text-gray-500 text-base">Het zakelijke overhemd voor naar kantoor. Gemaakt van stretch katoen met genoeg rek. In 3 lengtes</p> 1770 </div> 1771 </div> 1772 </div> 1773 </div> 1774 <div class="menu-item group "> 1775 <a 1776 class="menu-link level-1" 1777 href="https://www.girav.nl/overhemden/denim-overhemd-heren" 1778 title="Denim overhemden" 1779 style=""> 1780 <strong class="flex items-start gap-2">
1781 <span>Denim overhemden</span> 1782 <label class="menu-label" style="background-color: #000000;color: #ffffff"> 1783 Nieuw </label> 1784 </strong> 1785 <span class="menu-subtitle">Casual overhemd van 100% premium katoen</span> 1786 </a> 1787 <div class="submenu level-2 lg:group-hover:open"> 1788 <div class="menu-level level-2"> 1789 <div class=""> 1790 <img src="https://www.girav.nl/media/menu/Menu_Afbeeldingen_Varese_Denim_1.jpg" /> 1791 </div> 1792 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 1793 <strong class="text-xl font-bold">Denim overhemden</strong> 1794 <p class="text-gray-500 text-base">Casual denim overhemden met een soepele fit. Perfect voor elke dag.</p> 1795 </div> 1796 </div> 1797 </div> 1798 </div> 1799 <div class="menu-item group "> 1800 <a 1801 class="menu-link level-1" 1802 href="https://www.girav.nl/overhemden/linnen" 1803 title="Linnen overhemden" 1804 style=""> 1805 <strong class="flex items-start gap-2"> 1806 <span>Linnen overhemden</span> 1807 </strong> 1808 <span class="menu-subtitle">Luchtige overhemden voor de zomer</span> 1809 </a> 1810 <div class="submenu level-2 lg:group-hover:open"> 1811 <div class="menu-level level-2"> 1812 <div class=""> 1813 <img src="https://www.girav.nl/media/menu/Linnen_overhemden-2_1.jpg" /> 1814 </div> 1815 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 1816 <strong class="text-xl font-bold">Linnen overhemden</strong> 1817 <p class="text-gray-500 text-base">Heerlijk luchtig overhemd voor de lente en zomer. Deze casual komt in regular fit.</p> 1818 </div> 1819 </div> 1820 </div> 1821 </div> 1822 </div> 1823 </div> 1824 </div> 1825 <div 1826 class="menu-item " 1827 :class="{ 1828 'overflow-hidden' : menuPanelActiveId === '6', 1829 }"> 1830 <button 1831 class="menu-link level-0 group" 1832 :class="{ 1833 'active' : menuPanelActiveId === '7', 1834 }" 1835 @click="menuPanelActiveId = menuPanelActiveId === '7' 1836 ? 0 1837 : '7' 1838 " 1839 > 1840 Truien en vesten <sp
1840an> 1841 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="px-2 w-10" width="18" height="18" aria-hidden="true"> 1842 <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m9 18 6-6-6-6"/> 1843</svg> 1844 </span> 1845 </button> 1846 1847 <div class="submenu level-1" 1848 :class="{ 1849 'open' : menuPanelActiveId === '7' 1850 }" 1851 @click="window.innerWidth >= 1024 ? setMenuOpen(false) : null" 1852 > 1853 <div class="menu-level level-1"> 1854 <div class="container py-3 lg:px-10 lg:pt-12 flex flex-col gap-4 lg:gap-10"> 1855 <button @click="menuPanelActiveId = null" class="flex gap-2 lg:hidden text-left items-center"> 1856 <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 15 10" fill="none" aria-hidden="true"> 1857 <path d="M2 5L6 1M2 5L6 9M2 5H14.5" stroke="currentColor" stroke-width="1.5"/> 1858</svg> 1859 Terug </button> 1860 1861 <span 1862 class="text-xl font-bold inline" 1863 style="" 1864 > 1865 Truien en vesten in 3 lengtes </span> 1866 </div> 1867 1868 <div class="menu-item group "> 1869 <a 1870 class="menu-link level-1" 1871 href="https://www.girav.nl/truien" 1872 title="Alle truien en vesten" 1873 style=""> 1874 <strong class="flex items-start gap-2"> 1875 <span>Alle truien en vesten</span> 1876 </strong> 1877 <span class="menu-subtitle">Bekijk de hele truien en vesten collectie</span> 1878 </a> 1879 <div class="submenu level-2 lg:group-hover:open"> 1880 <div class="menu-level level-2"> 1881 <div class=""> 1882 <img src="https://www.girav.nl/media/menu/Menu_truien_en_vesten_1.jpg" /> 1883 </div> 1884 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 1885 <strong class="text-xl font-bold">Alle truien en vesten</strong> 1886 </div> 1887 </div> 1888 </div> 1889 </div> 1890 <div class="menu-item group "> 1891 <a 1892 class="menu-link level-1" 1893 href="https://www.girav.nl/truien/sweaters" 1894 title="Sweaters & hoodies" 1895 style=""> 1896 <strong class="flex items-start gap-2">
1897 <span>Sweaters & hoodies</span> 1898 </strong> 1899 <span class="menu-subtitle">Zacht comfortabele sweatstof</span> 1900 </a> 1901 <div class="submenu level-2 lg:group-hover:open"> 1902 <div class="menu-level level-2"> 1903 <div class=""> 1904 <img src="https://www.girav.nl/media/menu/Sweaters-2_1.jpg" /> 1905 </div> 1906 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 1907 <strong class="text-xl font-bold">Sweaters & hoodies</strong> 1908 <p class="text-gray-500 text-base">Comfortabele truien, hoodies en vesten van sweatstof en lichtgewicht sweatstof. Keuze uit Regular en Oversized fit. In 3 lengtes</p> 1909 </div> 1910 </div> 1911 </div> 1912 </div> 1913 <div class="menu-item group "> 1914 <a 1915 class="menu-link level-1" 1916 href="https://www.girav.nl/truien/pullover/katoen" 1917 title="Katoenen pullovers" 1918 style=""> 1919 <strong class="flex items-start gap-2"> 1920 <span>Katoenen pullovers</span> 1921 </strong> 1922 <span class="menu-subtitle">Pullovers van 100% premium katoen</span> 1923 </a> 1924 <div class="submenu level-2 lg:group-hover:open"> 1925 <div class="menu-level level-2"> 1926 <div class=""> 1927 <img src="https://www.girav.nl/media/menu/Katoenen_truien-2_1.jpg" /> 1928 </div> 1929 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 1930 <strong class="text-xl font-bold">Katoenen pullovers</strong> 1931 <p class="text-gray-500 text-base">Ademende truien met een perfecte fit. Verkrijgbaar in ronde hals en half-zip en in 3 lengtes.</p> 1932 </div> 1933 </div> 1934 </div> 1935 </div> 1936 <div class="menu-item group "> 1937 <a 1938 class="menu-link level-1" 1939 href="https://www.girav.nl/truien/half-zip" 1940 title="Half-zip truien" 1941 style=""> 1942 <strong class="flex items-start gap-2">
1943 <span>Half-zip truien</span> 1944 </strong> 1945 <span class="menu-subtitle">Half-zip pullovers uit 100% katoen of merinowol</span> 1946 </a> 1947 <div class="submenu level-2 lg:group-hover:open"> 1948 <div class="menu-level level-2"> 1949 <div class=""> 1950 <img src="https://www.girav.nl/media/menu/half-zip_pullovers-2_1.jpg" /> 1951 </div> 1952 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 1953 <strong class="text-xl font-bold">Half-zip truien</strong> 1954 <p class="text-gray-500 text-base">Comfortabele, zachte truien met een rits, gemaakt van de beste katoen en merinowol. In 3 lengtes.</p> 1955 </div> 1956 </div> 1957 </div> 1958 </div> 1959 <div class="menu-item group "> 1960 <a 1961 class="menu-link level-1" 1962 href="https://www.girav.nl/truien/pullover/merino" 1963 title="Merinowol pullovers" 1964 style=""> 1965 <strong class="flex items-start gap-2"> 1966 <span>Merinowol pullovers</span> 1967 </strong> 1968 <span class="menu-subtitle">Gemaakt van extra fijne 100% merino</span> 1969 </a> 1970 <div class="submenu level-2 lg:group-hover:open"> 1971 <div class="menu-level level-2"> 1972 <div class=""> 1973 <img src="https://www.girav.nl/media/menu/Merino_pullovers-2_2.jpg" /> 1974 </div> 1975 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 1976 <strong class="text-xl font-bold">Merinowol pullovers</strong> 1977 <p class="text-gray-500 text-base">Comfortabele gebreide truien in 100% merinowol</p> 1978 </div> 1979 </div> 1980 </div> 1981 </div> 1982 <div class="menu-item group "> 1983 <a 1984 class="menu-link level-1" 1985 href="https://www.girav.nl/truien/vesten" 1986 title="Vesten" 1987 style=""> 1988 <strong class="flex items-start gap-2">
1989 <span>Vesten</span> 1990 </strong> 1991 <span class="menu-subtitle">Full-zip vesten, Regular Fit</span> 1992 </a> 1993 <div class="submenu level-2 lg:group-hover:open"> 1994 <div class="menu-level level-2"> 1995 <div class=""> 1996 <img src="https://www.girav.nl/media/menu/Menu_Afbeeldingen_Alle_vesten_Bern_1.jpg" /> 1997 </div> 1998 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 1999 <strong class="text-xl font-bold">Vesten</strong> 2000 <p class="text-gray-500 text-base">Comfortabele sweatvesten en vesten gemaakt van 100% merinowol.</p> 2001 </div> 2002 </div> 2003 </div> 2004 </div> 2005 <div class="menu-item group "> 2006 <a 2007 class="menu-link level-1" 2008 href="https://www.girav.nl/truien/coltruien" 2009 title="Coltruien" 2010 style=""> 2011 <strong class="flex items-start gap-2"> 2012 <span>Coltruien</span> 2013 </strong> 2014 <span class="menu-subtitle">Coltruien in katoen en merinowol</span> 2015 </a> 2016 <div class="submenu level-2 lg:group-hover:open"> 2017 <div class="menu-level level-2"> 2018 <div class=""> 2019 <img src="https://www.girav.nl/media/menu/Menu_Afbeeldingen_Coltruien_1.jpg" /> 2020 </div> 2021 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 2022 <strong class="text-xl font-bold">Coltruien</strong> 2023 <p class="text-gray-500 text-base">Premium coltruien van 100% katoen en in 3 lengtes.</p> 2024 </div> 2025 </div> 2026 </div> 2027 </div> 2028 </div> 2029 </div> 2030 </div> 2031 <div 2032 class="menu-item " 2033 :class="{ 2034 'overflow-hidden' : menuPanelActiveId === '7', 2035 }"> 2036 <button 2037 class="menu-link level-0 group" 2038 :class="{ 2039 'active' : menuPanelActiveId === '8', 2040 }" 2041 @click="menuPanelActiveId = menuPanelActiveId === '8' 2042 ? 0 2043 : '8' 2044 " 2045 > 2046 Knitwear <sp
2046an> 2047 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="px-2 w-10" width="18" height="18" aria-hidden="true"> 2048 <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m9 18 6-6-6-6"/> 2049</svg> 2050 </span> 2051 </button> 2052 2053 <div class="submenu level-1" 2054 :class="{ 2055 'open' : menuPanelActiveId === '8' 2056 }" 2057 @click="window.innerWidth >= 1024 ? setMenuOpen(false) : null" 2058 > 2059 <div class="menu-level level-1"> 2060 <div class="container py-3 lg:px-10 lg:pt-12 flex flex-col gap-4 lg:gap-10"> 2061 <button @click="menuPanelActiveId = null" class="flex gap-2 lg:hidden text-left items-center"> 2062 <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 15 10" fill="none" aria-hidden="true"> 2063 <path d="M2 5L6 1M2 5L6 9M2 5H14.5" stroke="currentColor" stroke-width="1.5"/> 2064</svg> 2065 Terug </button> 2066 2067 <span 2068 class="text-xl font-bold inline" 2069 style="" 2070 > 2071 Knitwear in 3 lengtes </span> 2072 </div> 2073 2074 <div class="menu-item group "> 2075 <a 2076 class="menu-link level-1" 2077 href="https://www.girav.nl/truien/gebreide-truien" 2078 title="Alle knitwear" 2079 style=""> 2080 <strong class="flex items-start gap-2"> 2081 <span>Alle knitwear</span> 2082 </strong> 2083 <span class="menu-subtitle">Bekijk de hele knitwear collectie</span> 2084 </a> 2085 <div class="submenu level-2 lg:group-hover:open"> 2086 <div class="menu-level level-2"> 2087 <div class=""> 2088 <img src="https://www.girav.nl/media/menu/Menu_knitwear_1.jpg" /> 2089 </div> 2090 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 2091 <strong class="text-xl font-bold">Alle knitwear</strong> 2092 <p class="text-gray-500 text-base">Comfortabele truien gebreid van 100% merinowol of lamswol.</p> 2093 </div> 2094 </div> 2095 </div> 2096 </div> 2097 <div class="menu-item group "> 2098 <a 2099 class="menu-link level-1" 2100 href="https://www.girav.nl/truien/katoen" 2101 title="Katoenen truien" 2102 style=""> 2103 <strong class="flex items-start gap-2">
2104 <span>Katoenen truien</span> 2105 </strong> 2106 <span class="menu-subtitle">Pullovers van 100% premium katoen</span> 2107 </a> 2108 <div class="submenu level-2 lg:group-hover:open"> 2109 <div class="menu-level level-2"> 2110 <div class=""> 2111 <img src="https://www.girav.nl/media/menu/Katoenen_truien-2_2.jpg" /> 2112 </div> 2113 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 2114 <strong class="text-xl font-bold">Katoenen truien</strong> 2115 <p class="text-gray-500 text-base">Truien voor de lente & zomer met een perfecte fit. Verkrijgbaar in ronde hals en half-zip en in 3 lengtes.</p> 2116 </div> 2117 </div> 2118 </div> 2119 </div> 2120 <div class="menu-item group "> 2121 <a 2122 class="menu-link level-1" 2123 href="https://www.girav.nl/truien/pullover/merino" 2124 title="Merinowol pullovers" 2125 style=""> 2126 <strong class="flex items-start gap-2"> 2127 <span>Merinowol pullovers</span> 2128 </strong> 2129 </a> 2130 <div class="submenu level-2 lg:group-hover:open"> 2131 <div class="menu-level level-2"> 2132 <div class=""> 2133 <img src="https://www.girav.nl/media/menu/Merino_pullovers-2_3.jpg" /> 2134 </div> 2135 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 2136 <strong class="text-xl font-bold">Merinowol pullovers</strong> 2137 <p class="text-gray-500 text-base">Comfortabele gebreide ronde en V-hals truien in 100% merinowol. In 3 lengtes.</p> 2138 </div> 2139 </div> 2140 </div> 2141 </div> 2142 <div class="menu-item group "> 2143 <a 2144 class="menu-link level-1" 2145 href="https://www.girav.nl/truien/half-zip" 2146 title="Half-zip pullovers" 2147 style=""> 2148 <strong class="flex items-start gap-2">
2149 <span>Half-zip pullovers</span> 2150 </strong> 2151 <span class="menu-subtitle">Merino truien met open ritsbare kraag</span> 2152 </a> 2153 <div class="submenu level-2 lg:group-hover:open"> 2154 <div class="menu-level level-2"> 2155 <div class=""> 2156 <img src="https://www.girav.nl/media/menu/Menu_Afbeeldingen_Aspen_1.jpg" /> 2157 </div> 2158 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 2159 <strong class="text-xl font-bold">Half-zip pullovers</strong> 2160 <p class="text-gray-500 text-base">Comfortabele half-zip pullovers van 100% merinowol of Egyptisch katoen.</p> 2161 </div> 2162 </div> 2163 </div> 2164 </div> 2165 <div class="menu-item group "> 2166 <a 2167 class="menu-link level-1" 2168 href="https://www.girav.nl/truien/lamswol" 2169 title="Lamswol truien" 2170 style=""> 2171 <strong class="flex items-start gap-2"> 2172 <span>Lamswol truien</span> 2173 </strong> 2174 <span class="menu-subtitle">Truien van premium lamswol</span> 2175 </a> 2176 <div class="submenu level-2 lg:group-hover:open"> 2177 <div class="menu-level level-2"> 2178 <div class=""> 2179 <img src="https://www.girav.nl/media/menu/Menu_Afbeeldingen_Lamswol_trui_1.jpg" /> 2180 </div> 2181 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 2182 <strong class="text-xl font-bold">Lamswol truien</strong> 2183 <p class="text-gray-500 text-base">Lamswol truien met ronde hals, half-zip en kabeltruien.</p> 2184 </div> 2185 </div> 2186 </div> 2187 </div> 2188 <div class="menu-item group "> 2189 <a 2190 class="menu-link level-1" 2191 href="https://www.girav.nl/truien/coltruien" 2192 title="Coltruien" 2193 style=""> 2194 <strong class="flex items-start gap-2">
2195 <span>Coltruien</span> 2196 </strong> 2197 <span class="menu-subtitle">Tijdloze turtlenecks van zachte merino</span> 2198 </a> 2199 <div class="submenu level-2 lg:group-hover:open"> 2200 <div class="menu-level level-2"> 2201 <div class=""> 2202 <img src="https://www.girav.nl/media/menu/Menu_Afbeeldingen_Coltruien_5.jpg" /> 2203 </div> 2204 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 2205 <strong class="text-xl font-bold">Coltruien</strong> 2206 <p class="text-gray-500 text-base">Premium coltruien met perfecte pasvorm. Gemaakt van 100% merinowol en in 3 lengtes.</p> 2207 </div> 2208 </div> 2209 </div> 2210 </div> 2211 <div class="menu-item group "> 2212 <a 2213 class="menu-link level-1" 2214 href="https://www.girav.nl/truien/vesten/merino" 2215 title="Gebreide vesten" 2216 style=""> 2217 <strong class="flex items-start gap-2"> 2218 <span>Gebreide vesten</span> 2219 </strong> 2220 <span class="menu-subtitle">Gemaakt van 100% zacht merino</span> 2221 </a> 2222 <div class="submenu level-2 lg:group-hover:open"> 2223 <div class="menu-level level-2"> 2224 <div class=""> 2225 <img src="https://www.girav.nl/media/menu/Menu_Afbeeldingen_Alle_vesten_Bern_2.jpg" /> 2226 </div> 2227 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 2228 <strong class="text-xl font-bold">Gebreide vesten</strong> 2229 <p class="text-gray-500 text-base">Gebreide, stijlvolle vesten gemaakt van 100% merinowol. Verkrijgbaar in 3 lengtes.</p> 2230 </div> 2231 </div> 2232 </div> 2233 </div> 2234 </div> 2235 </div> 2236 </div> 2237 <div 2238 class="menu-item " 2239 :class="{ 2240 'overflow-hidden' : menuPanelActiveId === '8', 2241 }"> 2242 <button 2243 class="menu-link level-0 group" 2244 :class="{ 2245 'active' : menuPanelActiveId === '9', 2246 }" 2247 @click="menuPanelActiveId = menuPanelActiveId === '9' 2248 ? 0 2249 : '9' 2250 " 2251 >
2252 Jassen en overshirts <span> 2253 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="px-2 w-10" width="18" height="18" aria-hidden="true"> 2254 <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m9 18 6-6-6-6"/> 2255</svg> 2256 </span> 2257 </button> 2258 2259 <div class="submenu level-1" 2260 :class="{ 2261 'open' : menuPanelActiveId === '9' 2262 }" 2263 @click="window.innerWidth >= 1024 ? setMenuOpen(false) : null" 2264 > 2265 <div class="menu-level level-1"> 2266 <div class="container py-3 lg:px-10 lg:pt-12 flex flex-col gap-4 lg:gap-10"> 2267 <button @click="menuPanelActiveId = null" class="flex gap-2 lg:hidden text-left items-center"> 2268 <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 15 10" fill="none" aria-hidden="true"> 2269 <path d="M2 5L6 1M2 5L6 9M2 5H14.5" stroke="currentColor" stroke-width="1.5"/> 2270</svg> 2271 Terug </button> 2272 2273 <span 2274 class="text-xl font-bold inline" 2275 style="" 2276 > 2277 Jassen & overshirts in 3 lengtes </span> 2278 </div> 2279 2280 <div class="menu-item group "> 2281 <a 2282 class="menu-link level-1" 2283 href="https://www.girav.nl/jassen" 2284 title="Alle jassen en overshirts" 2285 style=""> 2286 <strong class="flex items-start gap-2"> 2287 <span>Alle jassen en overshirts</span> 2288 </strong> 2289 <span class="menu-subtitle">Bekijk de hele jassen & overshirts collectie</span> 2290 </a> 2291 <div class="submenu level-2 lg:group-hover:open"> 2292 <div class="menu-level level-2"> 2293 <div class=""> 2294 <img src="https://www.girav.nl/media/menu/Menu_Jassen_1.jpg" /> 2295 </div> 2296 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 2297 <strong class="text-xl font-bold">Alle jassen en overshirts</strong> 2298 </div> 2299 </div> 2300 </div> 2301 </div> 2302 <div class="menu-item group "> 2303 <a 2304 class="menu-link level-1" 2305 href="https://www.girav.nl/jassen/softshell" 2306 title="Softshell jassen" 2307 style=""> 2308 <strong class="flex items-start gap-2">
2309 <span>Softshell jassen</span> 2310 <label class="menu-label" style="background-color: #000000;color: #ffffff"> 2311 Nieuw </label> 2312 </strong> 2313 <span class="menu-subtitle">Waterafstotende jassen met comfort stretch</span> 2314 </a> 2315 <div class="submenu level-2 lg:group-hover:open"> 2316 <div class="menu-level level-2"> 2317 <div class=""> 2318 <img src="https://www.girav.nl/media/menu/Softshell_jassen-2_1.jpg" /> 2319 </div> 2320 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 2321 <strong class="text-xl font-bold">Softshell jassen</strong> 2322 <p class="text-gray-500 text-base">Comfortabele softshell jackets voor het voorjaar. In 3 lengtes</p> 2323 </div> 2324 </div> 2325 </div> 2326 </div> 2327 <div class="menu-item group "> 2328 <a 2329 class="menu-link level-1" 2330 href="https://www.girav.nl/jassen/bodywarmer" 2331 title="Bodywarmers" 2332 style=""> 2333 <strong class="flex items-start gap-2"> 2334 <span>Bodywarmers</span> 2335 </strong> 2336 <span class="menu-subtitle">Bodywarmers met stretch-stof</span> 2337 </a> 2338 <div class="submenu level-2 lg:group-hover:open"> 2339 <div class="menu-level level-2"> 2340 <div class=""> 2341 <img src="https://www.girav.nl/media/menu/Menu_Afbeeldingen_Watson_bodywarmer_1.jpg" /> 2342 </div> 2343 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 2344 <strong class="text-xl font-bold">Bodywarmers</strong> 2345 <p class="text-gray-500 text-base">Beweeg vrijuit en blijf warm tijdens de koelere dagen met de Watson bodywarmer. In 3 lengtes. </p> 2346 </div> 2347 </div> 2348 </div> 2349 </div> 2350 <div class="menu-item group "> 2351 <a 2352 class="menu-link level-1" 2353 href="https://www.girav.nl/jassen/parka" 2354 title="Parka jassen" 2355 style=""> 2356 <strong class="flex items-start gap-2">
2357 <span>Parka jassen</span> 2358 </strong> 2359 <span class="menu-subtitle">Parka's met extra warme binnenvoering</span> 2360 </a> 2361 <div class="submenu level-2 lg:group-hover:open"> 2362 <div class="menu-level level-2"> 2363 <div class=""> 2364 <img src="https://www.girav.nl/media/menu/Menu_Afbeeldingen_Parka_1.jpg" /> 2365 </div> 2366 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 2367 <strong class="text-xl font-bold">Parka jassen</strong> 2368 <p class="text-gray-500 text-base">Lange parka's in 3 lengtes voor extra warmte.</p> 2369 </div> 2370 </div> 2371 </div> 2372 </div> 2373 <div class="menu-item group "> 2374 <a 2375 class="menu-link level-1" 2376 href="https://www.girav.nl/jassen/puffer" 2377 title="Puffer jassen" 2378 style=""> 2379 <strong class="flex items-start gap-2"> 2380 <span>Puffer jassen</span> 2381 </strong> 2382 <span class="menu-subtitle">Ideale gewatteerde jassen voor de herfst & winter</span> 2383 </a> 2384 <div class="submenu level-2 lg:group-hover:open"> 2385 <div class="menu-level level-2"> 2386 <div class=""> 2387 <img src="https://www.girav.nl/media/menu/Menu_Afbeeldingen_Alaska_1.jpg" /> 2388 </div> 2389 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 2390 <strong class="text-xl font-bold">Puffer jassen</strong> 2391 <p class="text-gray-500 text-base">Puffer jackets voor de warmere herfstdagen en winterjassen voor de koudere dagen. In 3 lengtes.</p> 2392 </div> 2393 </div> 2394 </div> 2395 </div> 2396 <div class="menu-item group "> 2397 <a 2398 class="menu-link level-1" 2399 href="https://www.girav.nl/jassen/overshirt" 2400 title="Overshirts" 2401 style=""> 2402 <strong class="flex items-start gap-2">
2403 <span>Overshirts</span> 2404 </strong> 2405 <span class="menu-subtitle">Tussenjassen voor het voorjaar en najaar</span> 2406 </a> 2407 <div class="submenu level-2 lg:group-hover:open"> 2408 <div class="menu-level level-2"> 2409 <div class=""> 2410 <img src="https://www.girav.nl/media/menu/Menu_overshirts_2.jpg" /> 2411 </div> 2412 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 2413 <strong class="text-xl font-bold">Overshirts</strong> 2414 <p class="text-gray-500 text-base">Comfortabele overshirts die je als tussenjas, vest of overhemd kunt dragen. Regular fit en in 3 lengtes.</p> 2415 </div> 2416 </div> 2417 </div> 2418 </div> 2419 </div> 2420 </div> 2421 </div> 2422 <div 2423 class="menu-item " 2424 :class="{ 2425 'overflow-hidden' : menuPanelActiveId === '9', 2426 }"> 2427 <button 2428 class="menu-link level-0 group" 2429 :class="{ 2430 'active' : menuPanelActiveId === '10', 2431 }" 2432 @click="menuPanelActiveId = menuPanelActiveId === '10' 2433 ? 0 2434 : '10' 2435 " 2436 > 2437 Broeken <span> 2438 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="px-2 w-10" width="18" height="18" aria-hidden="true"> 2439 <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m9 18 6-6-6-6"/> 2440</svg> 2441 </span> 2442 </button> 2443 2444 <div class="submenu level-1" 2445 :class="{ 2446 'open' : menuPanelActiveId === '10' 2447 }" 2448 @click="window.innerWidth >= 1024 ? setMenuOpen(false) : null" 2449 > 2450 <div class="menu-level level-1"> 2451 <div class="container py-3 lg:px-10 lg:pt-12 flex flex-col gap-4 lg:gap-10"> 2452 <button @click="menuPanelActiveId = null" class="flex gap-2 lg:hidden text-left items-center"> 2453 <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewB
2453ox="0 0 15 10" fill="none" aria-hidden="true"> 2454 <path d="M2 5L6 1M2 5L6 9M2 5H14.5" stroke="currentColor" stroke-width="1.5"/> 2455</svg> 2456 Terug </button> 2457 2458 <span 2459 class="text-xl font-bold inline" 2460 style="" 2461 > 2462 Broeken t/m lengtemaat 38 </span> 2463 </div> 2464 2465 <div class="menu-item group "> 2466 <a 2467 class="menu-link level-1" 2468 href="https://www.girav.nl/broeken" 2469 title="Alle broeken" 2470 style=""> 2471 <strong class="flex items-start gap-2"> 2472 <span>Alle broeken</span> 2473 </strong> 2474 <span class="menu-subtitle">Bekijk de hele broeken-collectie</span> 2475 </a> 2476 <div class="submenu level-2 lg:group-hover:open"> 2477 <div class="menu-level level-2"> 2478 <div class=""> 2479 <img src="https://www.girav.nl/media/menu/Menu_Alle_Broeken_1.jpg" /> 2480 </div> 2481 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 2482 <strong class="text-xl font-bold">Alle broeken</strong> 2483 </div> 2484 </div> 2485 </div> 2486 </div> 2487 <div class="menu-item group "> 2488 <a 2489 class="menu-link level-1" 2490 href="https://www.girav.nl/broeken/jeans" 2491 title="Jeans" 2492 style="color: #000000"> 2493 <strong class="flex items-start gap-2"> 2494 <span>Jeans</span> 2495 </strong> 2496 <span class="menu-subtitle">Tijloze spijkerbroeken met de perfecte fit</span> 2497 </a> 2498 <div class="submenu level-2 lg:group-hover:open"> 2499 <div class="menu-level level-2"> 2500 <div class=""> 2501 <img src="https://www.girav.nl/media/menu/Menu_jeans_1.jpg" /> 2502 </div> 2503 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 2504 <strong class="text-xl font-bold">Jeans</strong> 2505 <p class="text-gray-500 text-base">Tapered Fit spijkerbroek van premium denim voor elke dag. Verkrijgbaar in 4 lengtematen: 32 t/m 38.</p> 2506 </div> 2507 </div> 2508 </div> 2509 </div> 2510 <div class="menu-item group "> 2511 <a 2512 class="menu-link level-1" 2513 href="https://www.girav.nl/broeken/lange-chino" 2514 title="Chino's" 2515 style=""> 2516 <strong class="flex items-start gap-2">
2517 <span>Chino's</span> 2518 </strong> 2519 <span class="menu-subtitle">Klassieke, stretch en linnen chino's</span> 2520 </a> 2521 <div class="submenu level-2 lg:group-hover:open"> 2522 <div class="menu-level level-2"> 2523 <div class=""> 2524 <img src="https://www.girav.nl/media/menu/Chino_s_1.jpg" /> 2525 </div> 2526 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 2527 <strong class="text-xl font-bold">Chino's</strong> 2528 <p class="text-gray-500 text-base">Op zoek naar een comfortabele chino die wel lang genoeg is? Verkrijgbaar in 4 lengtes.</p> 2529 </div> 2530 </div> 2531 </div> 2532 </div> 2533 <div class="menu-item group "> 2534 <a 2535 class="menu-link level-1" 2536 href="https://www.girav.nl/sportkleding/joggingbroeken" 2537 title="Joggingbroeken" 2538 style=""> 2539 <strong class="flex items-start gap-2"> 2540 <span>Joggingbroeken</span> 2541 </strong> 2542 <span class="menu-subtitle">Zacht sweatstof -perfecte pasvorm</span> 2543 </a> 2544 <div class="submenu level-2 lg:group-hover:open"> 2545 <div class="menu-level level-2"> 2546 <div class=""> 2547 <img src="https://www.girav.nl/media/menu/Menu_Jogging_groot_7.jpeg" /> 2548 </div> 2549 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 2550 <strong class="text-xl font-bold">Joggingbroeken</strong> 2551 <p class="text-gray-500 text-base">Nooit meer te korte joggingbroeken door de 4 lengtes. Gemaakt van een zachte katoen-mix.</p> 2552 </div> 2553 </div> 2554 </div> 2555 </div> 2556 <div class="menu-item group "> 2557 <a 2558 class="menu-link level-1" 2559 href="https://www.girav.nl/broeken/linnen" 2560 title="Linnen broeken" 2561 style=""> 2562 <strong class="flex items-start gap-2">
2563 <span>Linnen broeken</span> 2564 </strong> 2565 <span class="menu-subtitle">100% linnen, tot lengtemaat 38</span> 2566 </a> 2567 <div class="submenu level-2 lg:group-hover:open"> 2568 <div class="menu-level level-2"> 2569 <div class=""> 2570 <img src="https://www.girav.nl/media/menu/Linnen_broeken_1.jpg" /> 2571 </div> 2572 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 2573 <strong class="text-xl font-bold">Linnen broeken</strong> 2574 <p class="text-gray-500 text-base">Licht en ademend â 100% linnen om je koel te houden op warme dagen.</p> 2575 </div> 2576 </div> 2577 </div> 2578 </div> 2579 <div class="menu-item group "> 2580 <a 2581 class="menu-link level-1" 2582 href="https://www.girav.nl/broeken/korte-broeken" 2583 title="Korte broeken" 2584 style=""> 2585 <strong class="flex items-start gap-2"> 2586 <span>Korte broeken</span> 2587 </strong> 2588 <span class="menu-subtitle">Comfortabele shorts met stretch</span> 2589 </a> 2590 <div class="submenu level-2 lg:group-hover:open"> 2591 <div class="menu-level level-2"> 2592 <div class=""> 2593 <img src="https://www.girav.nl/media/menu/Korte_broeken_1.jpg" /> 2594 </div> 2595 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 2596 <strong class="text-xl font-bold">Korte broeken</strong> 2597 <p class="text-gray-500 text-base">Comfortabele short die altijd lang genoeg zijn. Verkrijgbaar in 3 lengtes.</p> 2598 </div> 2599 </div> 2600 </div> 2601 </div> 2602 </div> 2603 </div> 2604 </div> 2605 <div 2606 class="menu-item " 2607 :class="{ 2608 'overflow-hidden' : menuPanelActiveId === '10', 2609 }"> 2610 <button 2611 class="menu-link level-0 group" 2612 :class="{ 2613 'active' : menuPanelActiveId === '11', 2614 }" 2615 @click="menuPanelActiveId = menuPanelActiveId === '11' 2616 ? 0 2617 : '11' 2618 " 2619 > 2620 Sportkleding <sp
2620an> 2621 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="px-2 w-10" width="18" height="18" aria-hidden="true"> 2622 <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m9 18 6-6-6-6"/> 2623</svg> 2624 </span> 2625 </button> 2626 2627 <div class="submenu level-1" 2628 :class="{ 2629 'open' : menuPanelActiveId === '11' 2630 }" 2631 @click="window.innerWidth >= 1024 ? setMenuOpen(false) : null" 2632 > 2633 <div class="menu-level level-1"> 2634 <div class="container py-3 lg:px-10 lg:pt-12 flex flex-col gap-4 lg:gap-10"> 2635 <button @click="menuPanelActiveId = null" class="flex gap-2 lg:hidden text-left items-center"> 2636 <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 15 10" fill="none" aria-hidden="true"> 2637 <path d="M2 5L6 1M2 5L6 9M2 5H14.5" stroke="currentColor" stroke-width="1.5"/> 2638</svg> 2639 Terug </button> 2640 2641 <span 2642 class="text-xl font-bold inline" 2643 style="" 2644 > 2645 Sportkleding in 3 lengtes </span> 2646 </div> 2647 2648 <div class="menu-item group "> 2649 <a 2650 class="menu-link level-1" 2651 href="https://www.girav.nl/sportkleding" 2652 title="Alle sportkleding" 2653 style=""> 2654 <strong class="flex items-start gap-2"> 2655 <span>Alle sportkleding</span> 2656 </strong> 2657 <span class="menu-subtitle">Bekijk de hele sportcollectie</span> 2658 </a> 2659 <div class="submenu level-2 lg:group-hover:open"> 2660 <div class="menu-level level-2"> 2661 <div class=""> 2662 <img src="https://www.girav.nl/media/menu/Menu_sportcollectie.jpg" /> 2663 </div> 2664 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 2665 <strong class="text-xl font-bold">Alle sportkleding</strong> 2666 </div> 2667 </div> 2668 </div> 2669 </div> 2670 <div class="menu-item group "> 2671 <a 2672 class="menu-link level-1" 2673 href="https://www.girav.nl/sportkleding/sportshirts" 2674 title="Sportshirts" 2675 style=""> 2676 <strong class="flex items-start gap-2">
2677 <span>Sportshirts</span> 2678 </strong> 2679 <span class="menu-subtitle">Met Polygiene Stay Fresh Technology</span> 2680 </a> 2681 <div class="submenu level-2 lg:group-hover:open"> 2682 <div class="menu-level level-2"> 2683 <div class=""> 2684 <img src="https://www.girav.nl/media/menu/Menu_Afbeeldingen_Sport_shirts_1_1.jpg" /> 2685 </div> 2686 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 2687 <strong class="text-xl font-bold">Sportshirts</strong> 2688 <p class="text-gray-500 text-base">Comfortabele sportshirts met Polygiene Stay Fresh Technology, hierdoor blijf je ook fris tijdens het sporten. In 3 lengtes.</p> 2689 </div> 2690 </div> 2691 </div> 2692 </div> 2693 <div class="menu-item group "> 2694 <a 2695 class="menu-link level-1" 2696 href="https://www.girav.nl/sportkleding/joggingbroeken" 2697 title="Trainings- en joggingbroeken" 2698 style=""> 2699 <strong class="flex items-start gap-2"> 2700 <span>Trainings- en joggingbroeken</span> 2701 </strong> 2702 <span class="menu-subtitle">In maar liefst 4 lengtematen.</span> 2703 </a> 2704 <div class="submenu level-2 lg:group-hover:open"> 2705 <div class="menu-level level-2"> 2706 <div class=""> 2707 <img src="https://www.girav.nl/media/menu/Menu_Jogging_groot_8.jpeg" /> 2708 </div> 2709 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 2710 <strong class="text-xl font-bold">Trainings- en joggingbroeken</strong> 2711 <p class="text-gray-500 text-base">Nooit meer te korte trainings- en joggingbroeken door de 4 lengtematen. Gemaakt van een zachte cottenblend sweatstof.</p> 2712 </div> 2713 </div> 2714 </div> 2715 </div> 2716 </div> 2717 </div> 2718 </div> 2719 <div 2720 class="menu-item " 2721 :class="{ 2722 'overflow-hidden' : menuPanelActiveId === '11', 2723 }"> 2724 <button 2725 class="menu-link level-0 group" 2726 :class="{ 2727 'active' : menuPanelActiveId === '12', 2728 }" 2729 @click="menuPanelActiveId = menuPanelActiveId === '12' 2730 ? 0 2731 : '12' 2732 " 2733 > 2734 Ondergoed <sp
2734an> 2735 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="px-2 w-10" width="18" height="18" aria-hidden="true"> 2736 <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m9 18 6-6-6-6"/> 2737</svg> 2738 </span> 2739 </button> 2740 2741 <div class="submenu level-1" 2742 :class="{ 2743 'open' : menuPanelActiveId === '12' 2744 }" 2745 @click="window.innerWidth >= 1024 ? setMenuOpen(false) : null" 2746 > 2747 <div class="menu-level level-1"> 2748 <div class="container py-3 lg:px-10 lg:pt-12 flex flex-col gap-4 lg:gap-10"> 2749 <button @click="menuPanelActiveId = null" class="flex gap-2 lg:hidden text-left items-center"> 2750 <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 15 10" fill="none" aria-hidden="true"> 2751 <path d="M2 5L6 1M2 5L6 9M2 5H14.5" stroke="currentColor" stroke-width="1.5"/> 2752</svg> 2753 Terug </button> 2754 2755 <span 2756 class="text-xl font-bold inline" 2757 style="" 2758 > 2759 Ondergoed </span> 2760 </div> 2761 2762 <div class="menu-item group "> 2763 <a 2764 class="menu-link level-1" 2765 href="https://www.girav.nl/ondergoed" 2766 title="Alle ondergoed" 2767 style=""> 2768 <strong class="flex items-start gap-2"> 2769 <span>Alle ondergoed</span> 2770 </strong> 2771 <span class="menu-subtitle">Bekijk de hele ondergoed collectie</span> 2772 </a> 2773 <div class="submenu level-2 lg:group-hover:open"> 2774 <div class="menu-level level-2"> 2775 <div class=""> 2776 <img src="https://www.girav.nl/media/menu/boxershorts_MEnu.jpg" /> 2777 </div> 2778 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 2779 <strong class="text-xl font-bold">Alle ondergoed</strong> 2780 </div> 2781 </div> 2782 </div> 2783 </div> 2784 <div class="menu-item group "> 2785 <a 2786 class="menu-link level-1" 2787 href="https://www.girav.nl/ondergoed/boxershorts" 2788 title="Boxershorts" 2789 style=""> 2790 <strong class="flex items-start gap-2">
2791 <span>Boxershorts</span> 2792 </strong> 2793 <span class="menu-subtitle">Perfecte pasvorm</span> 2794 </a> 2795 <div class="submenu level-2 lg:group-hover:open"> 2796 <div class="menu-level level-2"> 2797 <div class=""> 2798 <img src="https://www.girav.nl/media/menu/Menu_Afbeeldingen_Boxers_1_1.jpg" /> 2799 </div> 2800 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 2801 <strong class="text-xl font-bold">Boxershorts</strong> 2802 <p class="text-gray-500 text-base">Comfortabele boxershort van stretch katoen. Optimaal draagcomfort door de naadloze achterkant.</p> 2803 </div> 2804 </div> 2805 </div> 2806 </div> 2807 <div class="menu-item group "> 2808 <a 2809 class="menu-link level-1" 2810 href="https://www.girav.nl/t-shirts/hemden" 2811 title="Hemden" 2812 style=""> 2813 <strong class="flex items-start gap-2"> 2814 <span>Hemden</span> 2815 </strong> 2816 <span class="menu-subtitle">In zwart, wit en invisible</span> 2817 </a> 2818 <div class="submenu level-2 lg:group-hover:open"> 2819 <div class="menu-level level-2"> 2820 <div class=""> 2821 <img src="https://www.girav.nl/media/menu/Menu_Afbeeldingen_Singlets_1_3.jpg" /> 2822 </div> 2823 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 2824 <strong class="text-xl font-bold">Hemden</strong> 2825 <p class="text-gray-500 text-base">Multifunctioneel onderhemd, ideaal voor sport, casual in de zomer of als ondershirt. Gemaakt van comfortabele stretch katoen.</p> 2826 </div> 2827 </div> 2828 </div> 2829 </div> 2830 <div class="menu-item group "> 2831 <a 2832 class="menu-link level-1" 2833 href="https://www.girav.nl/ondergoed/sokken" 2834 title="Sokken" 2835 style=""> 2836 <strong class="flex items-start gap-2">
2837 <span>Sokken</span> 2838 </strong> 2839 <span class="menu-subtitle">Tot maat 48-50 met Polygiene Stay Fresh Technology</span> 2840 </a> 2841 <div class="submenu level-2 lg:group-hover:open"> 2842 <div class="menu-level level-2"> 2843 <div class=""> 2844 <img src="https://www.girav.nl/media/menu/Menu_Afbeeldingen_Sokken_1.jpg" /> 2845 </div> 2846 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 2847 <strong class="text-xl font-bold">Sokken</strong> 2848 <p class="text-gray-500 text-base">Naadloze sokken en onzichtbare sneakersokken van stretch katoen met Polygiene Stay Fresh Technology. Naadloze sokken van merino wolmix. </p> 2849 </div> 2850 </div> 2851 </div> 2852 </div> 2853 </div> 2854 </div> 2855 </div> 2856 <div 2857 class="menu-item " 2858 :class="{ 2859 'overflow-hidden' : menuPanelActiveId === '12', 2860 }"> 2861 <button 2862 class="menu-link level-0 group" 2863 :class="{ 2864 'active' : menuPanelActiveId === '13', 2865 }" 2866 @click="menuPanelActiveId = menuPanelActiveId === '13' 2867 ? 0 2868 : '13' 2869 " 2870 > 2871 Accessoires <span> 2872 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="px-2 w-10" width="18" height="18" aria-hidden="true"> 2873 <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m9 18 6-6-6-6"/> 2874</svg> 2875 </span> 2876 </button> 2877 2878 <div class="submenu level-1" 2879 :class="{ 2880 'open' : menuPanelActiveId === '13' 2881 }" 2882 @click="window.innerWidth >= 1024 ? setMenuOpen(false) : null" 2883 > 2884 <div class="menu-level level-1"> 2885 <div class="container py-3 lg:px-10 lg:pt-12 flex flex-col gap-4 lg:gap-10"> 2886 <button @click="menuPanelActiveId = null" class="flex gap-2 lg:hidden text-left items-center"> 2887 <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewB
2887ox="0 0 15 10" fill="none" aria-hidden="true"> 2888 <path d="M2 5L6 1M2 5L6 9M2 5H14.5" stroke="currentColor" stroke-width="1.5"/> 2889</svg> 2890 Terug </button> 2891 2892 <span 2893 class="text-xl font-bold inline" 2894 style="" 2895 > 2896 Accessoires </span> 2897 </div> 2898 2899 <div class="menu-item group "> 2900 <a 2901 class="menu-link level-1" 2902 href="https://www.girav.nl/accessoires" 2903 title="Alle accessoires" 2904 style=""> 2905 <strong class="flex items-start gap-2"> 2906 <span>Alle accessoires</span> 2907 </strong> 2908 </a> 2909 </div> 2910 <div class="menu-item group "> 2911 <a 2912 class="menu-link level-1" 2913 href="https://www.girav.nl/ondergoed/sokken" 2914 title="Sokken" 2915 style=""> 2916 <strong class="flex items-start gap-2"> 2917 <span>Sokken</span> 2918 </strong> 2919 <span class="menu-subtitle">Tot maat 48-50 met Polygiene Stay Fresh Technology</span> 2920 </a> 2921 <div class="submenu level-2 lg:group-hover:open"> 2922 <div class="menu-level level-2"> 2923 <div class=""> 2924 <img src="https://www.girav.nl/media/menu/Menu_Afbeeldingen_Sokken_4.jpg" /> 2925 </div> 2926 <div class="px-10 py-8 flex-1 flex flex-col gap-2 border-l border-gray-100"> 2927 <strong class="text-xl font-bold">Sokken</strong> 2928 <p class="text-gray-500 text-base">Naadloze sokken en onzichtbare sneakersokken van stretch katoen met Polygiene Stay Fresh Technology. Naadloze sokken van merino wolmix. </p> 2929 </div> 2930 </div> 2931 </div> 2932 </div> 2933 <div class="menu-item group "> 2934 <a 2935 class="menu-link level-1" 2936 href="https://www.girav.nl/accessoires/mutsen" 2937 title="Mutsen" 2938 style=""> 2939 <strong class="flex items-start gap-2">
2940 <span>Mutsen</span> 2941 </strong> 2942 <span class="menu-subtitle">Gemaakt van extra warme 100% merinowol</span> 2943 </a> 2944 </div> 2945 </div> 2946 </div> 2947 </div> 2948 <div 2949 class="menu-item " 2950 :class="{ 2951 'overflow-hidden' : menuPanelActiveId === '13', 2952 }"> 2953 <a 2954 class="menu-link level-0 group" 2955 href="https://www.girav.nl/outlet" 2956 title="Outlet" 2957 style="color: #000000" 2958 > 2959 Outlet <span> 2960 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="px-2 w-10" width="18" height="18" aria-hidden="true"> 2961 <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m9 18 6-6-6-6"/> 2962</svg> 2963 </span> 2964 </a> 2965 2966 </div> 2967 <div 2968 class="menu-item " 2969 :class="{ 2970 'overflow-hidden' : menuPanelActiveId === '14', 2971 }"> 2972 <a 2973 class="menu-link level-0 group" 2974 href="https://www.girav.nl/girav-giftcard" 2975 title="Giftcards" 2976 style="" 2977 > 2978 Giftcards <span> 2979 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="px-2 w-10" width="18" height="18" aria-hidden="true"> 2980 <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m9 18 6-6-6-6"/> 2981</svg> 2982 </span> 2983 </a> 2984 2985 </div> 2986 <div 2987 class="menu-item content-item" 2988 :class="{ 2989 'overflow-hidden' : menuPanelActiveId === '15', 2990 }"> 2991 <button 2992 class="menu-link level-0 group" 2993 :class="{ 2994 'active' : menuPanelActiveId === '16', 2995 }" 2996 @click="menuPanelActiveId = menuPanelActiveId === '16' 2997 ? 0 2998 : '16' 2999 " 3000 > 3001 Klantenservice <span> 3002 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="px-2 w-10" width="18" height="18" aria-hidden="true"> 3003 <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m9 18 6-6-6-6"/> 3004</svg> 3005 </span> 3006 </button> 3007 3008 <div class="submenu level-1" 3009 :class="{ 3010 'open' : menuPanelActiveId === '16' 3011 }" 3012 @click="window.innerWidth >= 1024 ? setMenuOpen(false) : null" 3013 > 3014 <div class="menu-level level-1"> 3015 <div class="container py-3 lg:px-10 lg:pt-12 flex flex-col gap-4 lg:gap-10"> 3016 <button @click="menuPanelActiveId = null" class="flex gap-2 lg:hidden text-left items-center"> 3017 <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewB
3017ox="0 0 15 10" fill="none" aria-hidden="true"> 3018 <path d="M2 5L6 1M2 5L6 9M2 5H14.5" stroke="currentColor" stroke-width="1.5"/> 3019</svg> 3020 Terug </button> 3021 3022 <span 3023 class="text-xl font-bold inline" 3024 style="" 3025 > 3026 Klantenservice </span> 3027 </div> 3028 3029 <div class="menu-item group "> 3030 <a 3031 class="menu-link level-1" 3032 href="tel:+31204721002" 3033 title="Telefoon" 3034 style=""> 3035 <strong class="flex items-start gap-2"> 3036 <span>Telefoon</span> 3037 </strong> 3038 <span class="menu-subtitle">020-4721002</span> 3039 </a> 3040 </div> 3041 <div class="menu-item group "> 3042 <a class="menu-link level-1" href="/cdn-cgi/l/email-protection#8bfceee9f8e3e4fbcbece2f9eafda5e5e7" title="E-mail" style=""> 3043 <strong class="flex items-start gap-2"> 3044 <span>E-mail</span> 3045 </strong> 3046 <span class="menu-subtitle"><span class="__cf_email__" data-cfemail="493e2c2b3a212639092e203b283f672725">[email protected]</span></span> 3047 </a> 3048 </div> 3049 <div class="menu-item group "> 3050 <a 3051 class="menu-link level-1" 3052 href="https://www.girav.nl/klantenservice" 3053 title="Naar Klantenservice" 3054 style=""> 3055 <strong class="flex items-start gap-2"> 3056 <span>Naar Klantenservice</span> 3057 </strong> 3058 </a> 3059 </div> 3060 </div> 3061 </div> 3062 </div> 3063 <div 3064 class="menu-item content-item" 3065 :class="{ 3066 'overflow-hidden' : menuPanelActiveId === '16', 3067 }"> 3068 <a 3069 class="menu-link level-0 group" 3070 href="https://www.girav.nl/bereken-je-maat" 3071 title="Maatkiezer - vind jouw maat" 3072 style="" 3073 > 3074 Maatkiezer - vind jouw maat <sp
3074an> 3075 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="px-2 w-10" width="18" height="18" aria-hidden="true"> 3076 <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m9 18 6-6-6-6"/> 3077</svg> 3078 </span> 3079 </a> 3080 3081 </div> 3082 <div 3083 class="menu-item content-item" 3084 :class="{ 3085 'overflow-hidden' : menuPanelActiveId === '17', 3086 }"> 3087 <a 3088 class="menu-link level-0 group" 3089 href="https://www.girav.nl/lookbook" 3090 title="Lookbook Fall/Winter '26" 3091 style="" 3092 > 3093 Lookbook Fall/Winter '26 <span> 3094 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="px-2 w-10" width="18" height="18" aria-hidden="true"> 3095 <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m9 18 6-6-6-6"/> 3096</svg> 3097 </span> 3098 </a> 3099 3100 </div> 3101 <div 3102 class="menu-item content-item" 3103 :class="{ 3104 'overflow-hidden' : menuPanelActiveId === '18', 3105 }"> 3106 <a 3107 class="menu-link level-0 group" 3108 href="https://www.girav.nl/shop-the-look" 3109 title="Shop The Look" 3110 style="" 3111 > 3112 Shop The Look <span> 3113 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="px-2 w-10" width="18" height="18" aria-hidden="true"> 3114 <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m9 18 6-6-6-6"/> 3115</svg> 3116 </span> 3117 </a> 3118 3119 </div> 3120 <div> 3121 <div> 3122 </dialog> 3123 </template> 3124 </div>
vendor: 114 bytes, lines 3124-3126
3124 3125 3126 <script data-cfasync="false" src="/cdn-cgi/scripts/5c5dd728/cloudflare-static/email-decode.min.js"></script>
3126<script> 3127 'use strict'; 3128 3129 const initMenu_6ac56e269904b = () => { 3130 return { 3131 menuPanelActiveId: null, 3132 open: false, 3133 setMenuOpen(newOpen) { 3134 this.open = newOpen; 3135 const modeClass = 'dark-mode'; 3136 3137 if (newOpen) { 3138 document.querySelector("body").classList.add("menu-open", modeClass); 3139 document.querySelector("body").classList.remove("menu-closed"); 3140 } 3141 else { 3142 document.querySelector("body").classList.remove("menu-open", modeClass); 3143 document.querySelector("body").classList.add("menu-closed"); 3144 this.menuPanelActiveId = null; 3145 } 3146 }, 3147 } 3148 } 3149 </script>
3149 3150 3151 <div class="search-mobile flex items-center lg:hidden"> 3152 <button id="menu-search-icon" class="inline-block no-underline p-2" @click.prevent="$dispatch('toggle-mobile-search',{});"> 3153 <span class="sr-only label"> 3154 Zoek </span> 3155 <svg xmlns="http://www.w3.org/2000/svg" width="21" height="21" viewBox="0 0 20 20" fill="none" class="main-menu-item text-[#2a2a2a]" role="img"> 3156 <circle cx="9" cy="9" r="8.25" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/> 3157 <path d="M15 15L19 19" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/> 3158<title>search</title></svg> 3159 </button> 3160 </div> 3161
3162<script> 3163 'use strict'; 3164 3165 function tweakwiseQuickSearchMobile() { 3166 return { 3167 minSearchLength: 3, 3168 suggestions: [], 3169 fetchedTerm: '', 3170 open: false, 3171 suggestionsActive: true, 3172 close() { 3173 this.suggestions = []; 3174 }, 3175 filterTitle(title) { 3176 if (!title || !this.fetchedTerm) { 3177 return title; 3178 } 3179 const term = this.fetchedTerm.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); 3180 const regex = new RegExp(`(${term})`, 'gi'); 3181 3182 return title.replace(regex, '<strong>$1</strong>'); 3183 }, 3184 suggest() { 3185 const term = this.$refs.searchInput.value 3186 this.suggestionsActive = !(term.length >= this.minSearchLength); 3187 if (!this.suggestionsActive) { 3188 this.fetchSuggestions(term); 3189 } 3190 }, 3191 fetchSuggestions(term) { 3192 fetch( 3193 window.BASE_URL + 'search/ajax/suggest?' + new URLSearchParams({q: term}), 3194 { 3195 headers: { 3196 'X-Requested-With': 'XMLHttpRequest' 3197 } 3198 } 3199 ) 3200 .then(response => response.json()) 3201 .then(result => { 3202 this.suggestions = result; 3203 this.fetchedTerm = term; 3204 }) 3205 }, 3206 clickSuggestion(suggestion) { 3207 if (suggestion.type === 'suggestion_group') { 3208 return 3209 } else if (suggestion.type === 'product') { 3210 this.goToProduct(suggestion.url) 3211 } else { 3212 this.search(suggestion.title) 3213 } 3214 }, 3215 search(term) { 3216 this.$refs.searchInput.value = term; 3217 document.getElementById('search_mini_form_mobile').submit() 3218 }, 3219 goToProduct(url) { 3220 window.location.href = url 3221 }, 3222 focusElement(element) { 3223 if (element && element.nodeName === 'DIV') { 3224 element.focus() 3225 this.$refs.searchInput.value = element.getAttribute('data-title') 3226 return true 3227 } else { 3228 return false 3229 } 3230 }, 3231 hasSpecialPrice(suggestion) { 3232 return (Math.abs(suggestion.final_price - suggestion.price) > 0.0001) 3233 }, 3234 formatPrice(price) { 3235 return hyva.formatPrice(price, false) 3236 }, 3237 clearSearch() { 3238 this.$refs.searchInput.value = ''; 3239 this.suggestions = []; 3240 this.fetchedTerm = ''; 3241 this.suggestionsActive = true; 3242 this.$refs.searchInput.focus(); 3243 } 3244 } 3245 } 3246</script>
3246 3247 3248<div 3249 class="z-40 mx-auto text-black fixed top-0 right-0 bottom-0 left-0 bg-white hidden" 3250 :class="{ 'hidden': !open }" x-data="tweakwiseQuickSearchMobile()" 3251 @toggle-mobile-search.window="open=true" 3252> 3253 <form 3254 class="form minisearch relative" 3255 id="search_mini_form_mobile" 3256 action="https://www.girav.nl/catalogsearch/result/" 3257 method="get" 3258 > 3259 <label class="sr-only" for="search-mobile" data-role="minisearch-label"> 3260 <span>Zoek</span> 3261 </label> 3262 <div class="flex items-center pt-2 pb-4 pr-2 bg-gray-100"> 3263 <button type="button" aria-label="Close form" class="btn btn-icon w-auto p-2" @click.prevent="close; open = false"> 3264 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" role="img"> 3265 <path d="M18 6 6 18"/> 3266 <path d="m6 6 12 12"/> 3267<title>x</title></svg> 3268 </button> 3269 <input 3270 id="search-mobile" 3271 x-ref="searchInput" 3272 type="search" 3273 autocomplete="off" 3274 name="q" 3275 value="" 3276 placeholder="Zoeken in onze collectie" 3277 maxlength="128" 3278 class="w-full p-2 text-lg transition appearance-none text-grey-800 focus:outline-none focus:border-transparent border-0 lg:text-xl bg-white" 3279 @focus.once="suggest" 3280 @input.debounce.300="suggest" 3281 @keydown.arrow-down.prevent="focusElement($root.querySelector('[tabindex]'))" 3282 /> 3283 </div> 3284 <template x-if="suggestions.length > 0 || suggestionsActive"> 3285 <div class="search-result-mobile"> 3286 3287<div class="w-full transition appearance-none text-[#181818] flex flex-col md:pb-8 md:overflow-y-auto"> 3288 <div class="flex flex-col gap-1"> 3289 <template x-if="suggestionsActive"> 3290 <div class="font-bold"> 3291 </div> 3292 </template> 3293 <template x-if="!suggestionsActive"> 3294 <div class="suggestions md:p-0 md-max:text-sm"> 3295 <template x-for="suggestion in suggestions.filter(i => i.type === 'suggestion').slice(0, 5)"> 3296 <div class="py-2 border-b border-[#D9D9D9] focus:bg-[#F5F5F5] hover:bg-[#F5F5F5] px-2"> 3297 <a 3298 :href="`/catalogsearch/result/?q=${encodeURIComponent(suggestion.title)}`" 3299 :title="suggestion.title" 3300 class="text-[12px] leading-5 flex justify-between cursor-pointer" 3301 > 3302 <span class="qs-option-name" x-html="filterTitle(suggestion.title)"></span> 3303 <span> 3304 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" class="text-[#2a2a2a]" width="24" height="24" role="img"> 3305 <path d="M14.0312 16L18.0312 12M18.0312 12L14.0312 8M18.0312 12H5.96875" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/> 3306<title>arrow-right</title></svg> 3307 </span> 3308 </a> 3309 </div> 3310 </template> 3311 </div> 3312 </template> 3313 <template x-if="!suggestionsActive"> 3314 <div class="product-suggestions md-max:absolute md-max:w-full md-max:p-4 md-max:bg-white md-max:rounded-xl md-max:mt-2"> 3315 <div class="products flex flex-col"> 3316 <template x-for="suggestion in suggestions.filter(i => i.type === 'product').slice(0, 5)"> 3317 <div class="product-item flex-none p-2 focus:bg-[#F5F5F5] hover:bg-[#F5F5F5] border-b border-[#D9D9D9] last-of-type:border-0 last-of-type:mb-0"> 3318 <a :href="suggestion.url" :title="suggestion.title" class="flex gap-5"> 3319 <template x-if="suggestion.image" > 3320 <div class="product-image flex justify-center"> 3321 <img 3322 class="qs-option-image w-auto" 3323 width="47" 3324 height="64" 3325 style="width: 47px; height: 64px" 3326 :src="suggestion.image ? suggestion.image: ''" 3327 :alt="suggestion.title ? suggestion.title : ''" 3328 /> 3329 </div> 3330 </template> 3331 3332 <div class="qs-option-info-container md:h-[64px] flex flex-col justify-center "> 3333 <div class="qs-option-name text-[12px]" x-html="filterTitle(suggestion.title)"></div> 3334 <div class="price-box text-[12px]"> 3335 <template x-if="!hasSpecialPrice(suggestion)">
3336 <span class="price-container"> 3337 <span class="price-wrapper"> 3338 <span x-html="formatPrice(suggestion.price)" class="price"></span> 3339 </span> 3340 </span> 3341 </template> 3342 3343 <template x-if="hasSpecialPrice(suggestion)"> 3344 <span class="price-container"> 3345 <span class="old-price sly-old-price mr-1"> 3346 <span class="price-label hidden">Normale prijs</span> 3347 <span class="price-wrapper"> 3348 <span x-html="formatPrice(suggestion.price)" class="price font-regular line-through text-gray-900"></span> 3349 </span> 3350 </span> 3351 <span class="special-price"> 3352 <span class="price-label hidden">Speciale prijs</span> 3353 <span class="price-wrapper"> 3354 <span x-html="formatPrice(suggestion.final_price)" class="price"></span> 3355 </span> 3356 </span> 3357 </span> 3358 </template> 3359 </div> 3360 </div> 3361 </a> 3362 </div> 3363 </template> 3364 </div> 3365 </div> 3366 </template> 3367 </div> 3368</div> 3369 </div> 3370 </template> 3371 <button type="submit" title="Zoek" class="action search sr-only" aria-label="Search"> 3372 Zoek </button> 3373 </form> 3374</div> 3375 3376 3377 3378 <div class="hidden lg:flex gap-x-2 lg:gap-x-4 xl:gap-x-8"> 3379 <a 3380 class="item flex flex-col justify-center w-max main-menu-item text-[#2a2a2a]" 3381 href="https://www.girav.nl/bestsellers/" 3382 data-ux-element="navigation" 3383 data-element-type="menu-item" 3384 data-element-category="" 3385 data-element-label="Bestsellers" 3386 data-element-link="https://www.girav.nl/bestsellers/" 3387 > 3388 Bestsellers </a> 3389 <a 3390 class="item flex flex-col justify-center w-max main-menu-item text-[#2a2a2a]" 3391 href="https://www.girav.nl/nieuw-binnen/" 3392 data-ux-element="navigation" 3393 data-element-type="menu-item" 3394 data-element-category="" 3395 data-element-label="Nieuw binnen" 3396 data-element-link="https://www.girav.nl/nieuw-binnen/" 3397 > 3398 Nieuw binnen </a> 3399 <a 3400 class="item flex flex-col justify-center w-max main-menu-item text-[#2a2a2a]" 3401 href="https://www.girav.nl/over-ons/" 3402 data-ux-element="navigation" 3403 data-element-type="menu-item" 3404 data-element-category="" 3405 data-element-label="Over ons" 3406 data-element-link="https://www.girav.nl/over-ons/" 3407 > 3408 Over ons </a> 3409 </div> 3410 </div> 3411 3412 <div class="flex justify-center"> 3413 <a 3414 class="flex flex-col justify-center" 3415 href="https://www.girav.nl/" 3416 aria-label="Home" 3417 > 3418 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 110 22" class="main-menu-item text-[#2a2a2a]" width="120" height="25" role="img">
3419 <path fill="currentColor" d="M6.4 7.3a6 6 0 0 1 2.4-2.4c1-.6 2.2-.8 3.6-.8a7 7 0 0 1 5 2 .6.6 0 0 0 .7 0L20.4 4c.2-.2.2-.6 0-.8-1-1-2-1.7-3.3-2.3-1.6-.6-3.3-1-5-.9-2 0-4 .4-5.9 1.4a10.2 10.2 0 0 0-5.2 7 .6.6 0 0 0 .5.6h3.8a.6.6 0 0 0 .6-.4c0-.5.3-1 .5-1.4M20 12.1c.2 0 .5.2.5.5v6.5a.6.6 0 0 1-.2.4c-1 .8-2.3 1.4-3.7 1.8-1.5.5-3 .7-4.5.7-2.1 0-4-.5-5.8-1.4a10.3 10.3 0 0 1-5.4-8c0-.3.2-.5.6-.5H5c.3 0 .5.2.6.5A6 6 0 0 0 8.8 17a7.8 7.8 0 0 0 7 .1l.2-.3v-3h-2c-.3 0-.6-.2-.6-.5v-.8c0-.3.3-.5.6-.5h6ZM32.7.3h-3.8c-.3 0-.5.3-.5.6v7.6c0 .3.2.5.6.5h3.6c.3 0 .6-.2.6-.5V.9c0-.3-.3-.6-.6-.6M29 21.7h3.8c.3 0 .5-.3.5-.6v-8.5c0-.3-.2-.5-.6-.5H29c-.3 0-.5.2-.5.5v8.5c0 .3.2.6.6.6M46.5 4.8c0-.3.2-.5.5-.5h3.4c1.4 0 2.5.3 3.3.9.7.6 1 1.5 1 2.7v.5c0 .3.3.6.6.6h3.8a.6.6 0 0 0 .5-.5V8a8 8 0 0 0-1-4c-.8-1.2-1.8-2-3.2-2.6-1.5-.7-3.1-1-4.8-1h-8.4c-.3 0-.5.3-.5.6v7.6c0 .3.2.5.5.5H46c.3 0 .6-.2.6-.5V4.8Zm11.7 7.3a.3.3 0 0 1 .3.4c-.7 1-1.6 1.7-2.6 2.2-.3.2-.3.6-.2.8l3.7 5.3c.3.4 0 .9-.4.9h-3.8a.6.6 0 0 1-.5-.3L50.9 16H47c-.3 0-.5.2-.5.5v4.7c0 .3-.3.6-.6.6h-3.7a.5.5 0 0 1-.5-.6v-8.5c0-.3.2-.5.5-.5h16Zm18.1-5.8 1 2.4a.6.6 0 0 0 .5.3h3.5c.4 0 .6-.4.5-.7L78.3.7a.6.6 0 0 0-.5-.4h-4a.6.6 0 0 0-.5.4L70 8.3c-.2.3 0 .7.5.7h3.4c.2 0 .4-.1.4-.3l1-2.4a.5.5 0 0 1 1 0m2 7.3h-5a.6.6 0 0 1-.4-.8c.1-.3-.2-.7-.5-.7h-3.5a.6.6 0 0 0-.5.3l-3.8 8.5c-.2.4 0 .8.5.8h3.7a.6.6 0 0 0 .5-.4l1.5-3.7a.6.6 0 0 1 .6-.4h8.9a.6.6 0 0 1 .4.3l1.6 3.8a.6.6 0 0 0 .5.4h3.9c.4 0 .6-.4.5-.8l-3.8-8.5c-.1-.2-.3-.3-.6-.3h-3.5a.5.5 0 0 0-.5.7.6.6 0 0 1-.5.8ZM91.7.3h-4a.5.5 0 0 0-.5.8l3.3 7.6c0 .2.2.3.4.3h4a.6.6 0 0 0 .5-.7L92.2.7a.6.6 0 0 0-.5-.4Zm17 0H105a.6.6 0 0 0-.5.4l-3.3 7.6c-.1.3.1.7.5.7h3.6a.6.6 0 0 0 .5-.3l3.3-7.6V1a.6.6 0 0 0-.5-.6ZM96.9 12.4a.6.6 0 0 0-.5-.3h-4a.5.5 0 0 0-.4.7l3.7 8.5a.6.6 0 0 0 .4.4h4a.6.6 0 0 0 .6-.4l-3.8-9v.1Z"/> 3420<title>girav-logo</title></svg> 3421 </a> 3422 </div> 3423 3424 <div class="flex flex-row justify-self-end items-center"> 3425 <div class="justify-self-center"> 3426 <div id="search-content" class="search-desktop hidden lg:block w-full"> 3427
3428<script> 3429 'use strict'; 3430 3431 function tweakwiseQuickSearch() { 3432 return { 3433 minSearchLength: 3, 3434 suggestions: [], 3435 fetchedTerm: '', 3436 suggestionsActive: false, 3437 3438 filterTitle(title) { 3439 if (!title || !this.fetchedTerm) { 3440 return title; 3441 } 3442 const term = this.fetchedTerm.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); 3443 const regex = new RegExp(`(${term})`, 'gi'); 3444 3445 return title.replace(regex, '<strong>$1</strong>'); 3446 }, 3447 3448 close() { 3449 this.suggestions = []; 3450 this.suggestionsActive = false; 3451 }, 3452 suggest() { 3453 const term = this.$refs.searchInput.value; 3454 this.suggestionsActive = !(term.length >= this.minSearchLength); 3455 3456 if (!this.suggestionsActive) { 3457 this.fetchSuggestions(term); 3458 } else { 3459 this.close(); 3460 } 3461 }, 3462 suggestBlur() { 3463 const term = this.$refs.searchInput.value; 3464 if (term === "") { 3465 this.suggestionsActive = false; 3466 } 3467 }, 3468 fetchSuggestions(term) { 3469 fetch( 3470 window.BASE_URL + 'search/ajax/suggest?' + new URLSearchParams({q: term}), 3471 { 3472 headers: { 3473 'X-Requested-With': 'XMLHttpRequest' 3474 } 3475 } 3476 ) 3477 .then(response => response.json()) 3478 .then(result => { 3479 this.suggestions = result; 3480 this.fetchedTerm = term; 3481 }) 3482 }, 3483 clickSuggestion(suggestion) { 3484 if (suggestion.type === 'suggestion_group') { 3485 return 3486 } else if (suggestion.type === 'product') { 3487 this.goToProduct(suggestion.url) 3488 } else { 3489 this.search(suggestion.title) 3490 } 3491 }, 3492 search(term) { 3493 this.$refs.searchInput.value = term; 3494 document.getElementById('search_mini_form').submit() 3495 }, 3496 goToProduct(url) { 3497 window.location.href = url 3498 }, 3499 focusElement(element) { 3500 if (element && element.nodeName === 'DIV') { 3501 element.focus() 3502 this.$refs.searchInput.value = element.getAttribute('data-title') 3503 return true 3504 } else { 3505 return false 3506 } 3507 }, 3508 hasSpecialPrice(suggestion) { 3509 return (Math.abs(suggestion.final_price - suggestion.price) > 0.0001) 3510 }, 3511 formatPrice(price) { 3512 return hyva.formatPrice(price, false) 3513 } 3514 } 3515 } 3516 3517 function initTypewriterEffect() { 3518 return { 3519 text: '', 3520 staticText: 'Zoek naar', 3521 textArray: ["poloshirt","vest","joggingbroek","slim fit","oversized"], 3522 textIndex: 0, 3523 charIndex: 0, 3524 pauseEnd: 1500, 3525 pauseStart: 0, 3526 typeSpeedForwards: 50, 3527 typeSpeedBackwards: 0, 3528 direction: 'forwards', 3529 init() { 3530 const self = this; 3531 let typingInterval = setInterval(startTyping, self.typeSpeedForwards); 3532 3533 function startTyping() { 3534 let current = self.textArray[self.textIndex]; 3535 if(self.charIndex > current.length) { 3536 self.direction = 'backwards'; 3537 clearInterval(typingInterval); 3538 setTimeout(function() { 3539 typingInterval = setInterval(startTyping, self.typeSpeedBack); 3540 }, self.pauseEnd); 3541 } 3542 3543 self.text = self.staticText + '\u00A0' + current.substring(0, self.charIndex); 3544 if(self.direction == 'forwards') { 3545 self.charIndex += 1; 3546 } else { 3547 if(self.charIndex == 0) { 3548 self.direction = 'forwards'; 3549 clearInterval(typingInterval); 3550 setTimeout(function() { 3551 3552 self.textIndex += 1; 3553 if(self.textIndex >= self.textArray.length) { 3554 self.textIndex = 0; 3555 } 3556 3557 typingInterval = setInterval(startTyping, self.typeSpeedForwards); 3558 }, self.pauseStart); 3559 } 3560 self.charIndex -= 1; 3561 } 3562 } 3563 } 3564 } 3565 } 3566</script>
3566 3567 3568<div class="mx-auto text-black" x-data="tweakwiseQuickSearch()"> 3569 <template x-if="suggestions.length > 0"> 3570 <div class="search-backdrop" @click.prevent="close"></div> 3571 </template> 3572 <form class="relative minisearch w-[200px]" id="search_mini_form" action="https://www.girav.nl/catalogsearch/result/" method="get"> 3573 <label class="sr-only" for="search-desktop" data-role="search-label"> 3574 <span>Zoek</span> 3575 </label> 3576 <div 3577 class="search-desktop-wrapper w-full h-10 relative rounded-full overflow-hidden border border-[#2a2a2a] bg-[#FFFFFF33] " 3578 x-data="initTypewriterEffect()" 3579 > 3580 <input 3581 id="search-desktop" 3582 x-ref="searchInput" 3583 x-bind:placeholder="text" 3584 type="search" 3585 autocomplete="off" 3586 name="q" 3587 value="" 3588 placeholder="Zoeken in onze collectie" 3589 maxlength="128" 3590 class="search-input md:z-50 relative text-center w-full h-full text-xs px-3 py-1 bg-transparent border-0 transition appearance-none focus:outline-none text-[#2a2a2a] focus:border-transparent placeholder-[#2a2a2a]" 3591 :class="{'bg-[#F4F4F4] text-primary': suggestions.length > 0, 'text-[#2a2a2a] bg-transparent': suggestions.length == 0}" 3592 @focus="suggest" 3593 @blur="suggestBlur" 3594 @input.debounce.300="suggest" 3595 @keydown.arrow-down.prevent="focusElement($root.querySelector('[tabindex]'))" 3596 style="font-size: 14px; padding: 0 10px 0 34px; text-align: center;" 3597 /> 3598 <button type="submit" 3599 title="Zoek" class="z-50 action search text-[#2a2a2a] h-full absolute top-0 left-3" 3600 aria-label="Search" 3601 :class="{'text-primary': suggestions.length > 0, 'text-[#2a2a2a]': suggestions.length == 0}" 3602 > 3603 <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" fill="none" class="main-menu-item" aria-hidden="true"> 3604 <circle cx="9" cy="9" r="8.25" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/> 3605 <path d="M15 15L19 19" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/> 3606</svg> 3607 </button> 3608 3609 <template x-if="suggestions.length > 0"> 3610 <div class="close-btn hidden lg:block lg:absolute right-1 z-50 bg-[#F4F4F4]"> 3611 <button @click.prevent="close" aria-label="Close panel" class="p-[6px] qs-btn-close"> 3612 <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 44 44" fill="none" role="img"> 3613 <path d="M28 16L16 28M16 16L28 28" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/> 3614<title>x</title></svg> 3615 </button> 3616 </div> 3617 </template> 3618 </div> 3619 <template x-if="suggestions.length > 0"> 3620 <div class="search-suggestions"> 3621 <div class="container relative search-result-desktop"> 3622 3623<div class="w-full transition appearance-none text-[#181818] flex flex-col md:pb-8 md:overflow-y-auto"> 3624 <div class="flex flex-col gap-1"> 3625 <template x-if="suggestionsActive"> 3626 <div class="font-bold"> 3627 </div> 3628 </template> 3629 <template x-if="!suggestionsActive"> 3630 <div class="suggestions md:p-0 md-max:text-sm"> 3631 <template x-for="suggestion in suggestions.filter(i => i.type === 'suggestion').slice(0, 5)"> 3632 <div class="py-2 border-b border-[#D9D9D9] focus:bg-[#F5F5F5] hover:bg-[#F5F5F5] px-2"> 3633 <a 3634 :href="`/catalogsearch/result/?q=${encodeURIComponent(suggestion.title)}`" 3635 :title="suggestion.title" 3636 class="text-[12px] leading-5 flex justify-between cursor-pointer" 3637 >
3638 <span class="qs-option-name" x-html="filterTitle(suggestion.title)"></span> 3639 <span> 3640 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" class="text-[#2a2a2a]" width="24" height="24" role="img"> 3641 <path d="M14.0312 16L18.0312 12M18.0312 12L14.0312 8M18.0312 12H5.96875" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/> 3642<title>arrow-right</title></svg> 3643 </span> 3644 </a> 3645 </div> 3646 </template> 3647 </div> 3648 </template> 3649 <template x-if="!suggestionsActive"> 3650 <div class="product-suggestions md-max:absolute md-max:w-full md-max:p-4 md-max:bg-white md-max:rounded-xl md-max:mt-2"> 3651 <div class="products flex flex-col"> 3652 <template x-for="suggestion in suggestions.filter(i => i.type === 'product').slice(0, 5)"> 3653 <div class="product-item flex-none p-2 focus:bg-[#F5F5F5] hover:bg-[#F5F5F5] border-b border-[#D9D9D9] last-of-type:border-0 last-of-type:mb-0"> 3654 <a :href="suggestion.url" :title="suggestion.title" class="flex gap-5"> 3655 <template x-if="suggestion.image" > 3656 <div class="product-image flex justify-center"> 3657 <img 3658 class="qs-option-image w-auto" 3659 width="47" 3660 height="64" 3661 style="width: 47px; height: 64px" 3662 :src="suggestion.image ? suggestion.image: ''" 3663 :alt="suggestion.title ? suggestion.title : ''" 3664 /> 3665 </div> 3666 </template> 3667 3668 <div class="qs-option-info-container md:h-[64px] flex flex-col justify-center "> 3669 <div class="qs-option-name text-[12px]" x-html="filterTitle(suggestion.title)"></div> 3670 <div class="price-box text-[12px]"> 3671 <template x-if="!hasSpecialPrice(suggestion)"> 3672 <span class="price-container"> 3673 <span class="price-wrapper"> 3674 <span x-html="formatPrice(suggestion.price)" class="price"></span> 3675 </span> 3676 </span> 3677 </template> 3678 3679 <template x-if="hasSpecialPrice(suggestion)"> 3680 <span class="price-container"> 3681 <span class="old-price sly-old-price mr-1"> 3682 <span class="price-label hidden">Normale prijs</span> 3683 <span class="price-wrapper"> 3684 <span x-html="formatPrice(suggestion.price)" class="price font-regular line-through text-gray-900"></span> 3685 </span> 3686 </span> 3687 <span class="special-price"> 3688 <span class="price-label hidden">Speciale prijs</span> 3689 <span class="price-wrapper"> 3690 <span x-html="formatPrice(suggestion.final_price)" class="price"></span> 3691 </span> 3692 </span> 3693 </span> 3694 </template> 3695 </div> 3696 </div> 3697 </a> 3698 </div> 3699 </template> 3700 </div> 3701 </div> 3702 </template> 3703 </div> 3704</div> 3705 </div> 3706 </div> 3707 </template> 3708 </form> 3709</div> 3710 </div> 3711 </div> 3712 <div class="action-links flex flex-row items-center"> 3713 <button class="relative p-2 lg:p-3 lg:px-2 bg-transparent hidden"> 3714 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 25 21" class="main-menu-item text-[#2a2a2a]" width="25" height="21" role="img"> 3715 <g stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width=".8"> 3716 <path d="M9.8 12c4.7 0 8.5-2.4 8.5-5.4 0-3-3.8-5.5-8.5-5.5S1.3 3.5 1.3 6.6c0 3 3.8 5.5 8.5 5.5Zm0 8c-4.7 0-8.5-2.5-8.5-5.6m0 0V6.6M24.4 20H9.8m14.6-8H9.8m14.6 8v-8m-6.1-5.4V12"/> 3717 <path d="M9.8 8.7c2.1 0 3.8-1 3.8-2.1 0-1.2-1.7-2.2-3.8-2.2-2.2 0-3.9 1-3.9 2.2 0 1.2 1.7 2.1 3.9 2.1Zm11.5 9.6V20m-3-3.2v3.1m-3.1-1.6V20M12 16.8v3.1m-3-1.6V20m-3-3.8v3.1"/> 3718 </g> 3719<title>measure</title></svg> 3720 </button> 3721 3722 <div 3723 x-data="{ open: false }" 3724 @mouseenter="open = true" 3725 @mouseleave="open = false" 3726 > 3727 <a 3728 class="relative hover:underline p-2 lg:p-3 lg:px-2 block" 3729 href="https://www.girav.nl/customer/account/" 3730 aria-label="Account" 3731 > 3732 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 23 23" class="main-menu-item text-[#2a2a2a]" width="23" height="23" role="img"> 3733 <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.2" d="M2.9 19.2c2.2-2.4 5.3-3.9 8.6-3.9s6.4 1.5 8.6 3.9m-4.3-12a4.3 4.3 0 1 1-8.6 0 4.3 4.3 0 0 1 8.6 0Z"/> 3734<title>user</title></svg> 3735
3736 <span class="absolute top-2 right-2 lg:top-[12px] lg:right-[10px] w-[5px] h-[5px] rounded-full bg-[#ae1d28]"></span> 3737 3738 <div 3739 x-cloak 3740 x-show="open" 3741 x-transition.opacity 3742 class="absolute top-full hidden lg:block" 3743 > 3744 <svg xmlns="http://www.w3.org/2000/svg" width="26" height="12" viewBox="0 0 26 12" fill="none" class="text-[#ffffff] hover:text-[#ffffff]" role="img"><path d="M-3.8147e-06 11.7573L26 11.7573L15.1213 0.878645C13.9497 -0.292928 12.0503 -0.292927 10.8787 0.878645L-3.8147e-06 11.7573Z" fill="currentColor"/><title>menu-triangle</title></svg> 3745 </div> 3746 </a> 3747 3748 <div 3749 x-cloak 3750 x-show="open" 3751 x-transition.opacity 3752 class="absolute right-4 top-[calc(100%+1px)] lg:top-[calc(100%+5px)] w-[213px] rounded-xl bg-white z-30 shadow-[0px_1px_2px_0px_rgba(0,0,0,0.08)] hidden lg:block" 3753 > 3754 <div class="p-4"> 3755 <a 3756 href="https://www.girav.nl/customer/account/" 3757 class="block text-sm font-medium text-[#181818] px-4 py-2.5 hover:no-underline" 3758 > 3759 Mijn account </a> 3760 3761 <a 3762 href="https://www.girav.nl/sales/order/history/" 3763 class="block text-sm font-medium text-[#181818] px-4 py-2.5 hover:no-underline" 3764 > 3765 Mijn bestellingen </a> 3766 3767 <a 3768 href="https://www.girav.nl/customer/account/edit/" 3769 class="block text-sm font-medium text-[#181818] px-4 py-2.5 hover:no-underline" 3770 > 3771 Accountgegevens </a> 3772 3773 <div class="mt-4"> 3774 <a 3775 href="https://www.girav.nl/customer/account/login/" 3776 class="flex items-center shadow-sm justify-center gap-2 h-10 rounded-xl border border-[#f4f4f4] text-sm font-medium text-[#181818] bg-[#f4f4f4] hover:text-white hover:bg-[#2542F3] transition-colors duration-200" 3777 > 3778 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 23 23" width="16" height="16" role="img"> 3779 <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.2" d="M2.9 19.2c2.2-2.4 5.3-3.9 8.6-3.9s6.4 1.5 8.6 3.9m-4.3-12a4.3 4.3 0 1 1-8.6 0 4.3 4.3 0 0 1 8.6 0Z"/> 3780<title>user</title></svg> 3781 Inloggen </a> 3782 </div> 3783 </div> 3784 </div> 3785 </div> 3786 3787 <a 3788 class="relative hover:underline p-2 lg:p-3 lg:px-2 hidden lg:block" 3789 href="https://www.girav.nl/wishlist/" 3790 aria-label="Wishlist" 3791 > 3792 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 23 23" class="main-menu-item text-[#2a2a2a]" width="23" height="23" role="img"> 3793 <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.2" d="M11.5 5C9.5 2.6 6.4 2 4 4a5.7 5.7 0 0 0-.9 8c1.6 2 6.3 6.2 7.9 7.6l.4.2h.2l.4-.2c1.5-1.4 6.3-5.6 7.9-7.7A5.7 5.7 0 0 0 19 4c-2.4-2-5.6-1.4-7.5.8Z" clip-rule="evenodd"/> 3794<title>heart</title></svg> 3795 </a> 3796 3797 <a 3798 id="menu-cart-icon" 3799 @click.prevent="$dispatch('toggle-cart',{});" class="relative hover:underline p-2 lg:p-3 lg:px-2 pr-0 lg:pr-0" 3800 href="https://www.girav.nl/checkout/cart/index/" 3801 aria-label="Jouw winkelwagen" 3802 > 3803 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 21" class="main-menu-item text-[#2a2a2a]" width="23" height="23" role="img"> 3804 <path stroke="currentColor" stroke-width="1.2" d="m.7 1.2.8 2.6m0 0 3.2 10.7h14.6v-8a2.7 2.7 0 0 0-2.6-2.7H1.5Zm15.2 16a1.3 1.3 0 1 1 0-2.6 1.3 1.3 0 0 1 0 2.6ZM6 18.5a1.3 1.3 0 1 1 2.7 0 1.3 1.3 0 0 1-2.7 0Z"/> 3805<title>cart</title></svg>
3806 <span 3807 x-cloak 3808 x-text="cart.summary_count" 3809 class="absolute top-0 -right-2 lg:top-1 flex justify-center items-center h-3 w-3 rounded-full 3810 bg-primary text-[8px] font-semibold text-center text-white uppercase transform -translate-x-1 translate-y-1/2" 3811 :class="{'hidden': !cart.summary_count, 'block': cart.summary_count }" 3812 style="color: #ffffff;" 3813 > 3814 </span> 3815 </a> 3816 </div> 3817 </div> 3818 </div> 3819 </div> 3820 </div> 3821
3821<script> 3822 function initAuthentication() { 3823 return { 3824 open: false, 3825 close() { 3826 this.open = false; 3827 }, 3828 forceAuthentication: false, 3829 checkoutUrl: 'https://www.girav.nl/checkout/index/', 3830 errors: 0, 3831 hasCaptchaToken: 0, 3832 displayErrorMessage: false, 3833 errorMessages: [], 3834 setErrorMessages(message) { 3835 this.errorMessages = [message]; 3836 this.displayErrorMessage = true; 3837 }, 3838 submitForm() { 3839 // Do not rename $form, the variable is expected to be declared in the recaptcha output 3840 const $form = document.querySelector('#login-form'); 3841 3842 if (this.errors === 0) { 3843 this.dispatchLoginRequest($form); 3844 } 3845 }, 3846 onPrivateContentLoaded() { 3847 const data = this.$event.detail.data; 3848 const isLoggedIn = data.customer && data.customer.firstname; 3849 if (data.cart && !isLoggedIn) { 3850 this.forceAuthentication = !data.cart.isGuestCheckoutAllowed; 3851 } 3852 }, 3853 redirectIfAuthenticated() { 3854 const event = this.$event; 3855 this.open = this.forceAuthentication; 3856 3857 if (event.detail && event.detail.url) { 3858 this.checkoutUrl = event.detail.url; 3859 } 3860 if (!this.forceAuthentication) { 3861 window.location.href = this.checkoutUrl; 3862 } 3863 }, 3864 resetErrors() { 3865 this.errors = 0; 3866 }, 3867 dispatchLoginRequest(form) { 3868 this.isLoading = true; 3869 const username = this.$refs['customer-email'].value; 3870 const password = this.$refs['customer-password'].value; 3871 const formKey = hyva.getFormKey(); 3872 const bodyFields = { 3873 'username': username, 3874 'password': password, 3875 'formKey': formKey 3876 }; 3877 const fieldName = 'g\u002Drecaptcha\u002Dresponse'; 3878 const recaptchaField = fieldName && form[fieldName]; 3879 if (recaptchaField) { 3880 bodyFields[fieldName] = recaptchaField.value; 3881 } 3882 fetch('https://www.girav.nl/customer/ajax/login/', { 3883 method: 'POST', 3884 headers: { 3885 'Content-Type': 'application/json', 3886 'X-Requested-With': 'XMLHttpRequest' 3887 }, 3888 body: JSON.stringify(bodyFields) 3889 } 3890 ).then(response => { 3891 return response.json() 3892 } 3893 ).then(data => { 3894 this.isLoading = false; 3895 if (data.errors) { 3896 this.setErrorMessages(data.message); 3897 this.errors = 1; 3898 this.hasCaptchaToken = 0; 3899 } else { 3900 window.location.href = this.checkoutUrl; 3901 } 3902 }); 3903 }, 3904 eventListeners: { 3905 ['@private-content-loaded.window']() { 3906 this.onPrivateContentLoaded(); 3907 }, 3908 ['@toggle-authentication.window']() { 3909 this.redirectIfAuthenticated(); 3910 }, 3911 ['@pageshow.window'](event) { 3912 if (event.persisted) { 3913 this.close(); 3914 }; 3915 } 3916 } 3917 } 3918 } 3919 3920 window.addEventListener('alpine:init', () => Alpine.data('initAuthentication', initAuthentication), {once: true}) 3921</script>
3921 3922 3923<dialog 3924 id="authentication-popup" 3925 aria-labelledby="authentication-popup-title" 3926 class="open:flex flex-col transition ease-out duration-300 motion-reduce:duration-0 p-0" 3927 x-data="initAuthentication" 3928 x-bind="eventListeners" 3929 x-show="open" 3930 x-htmldialog="close" 3931 closeby="any" 3932 x-transition 3933> 3934 <div class="pt-8 px-8"> 3935 <div class="flex gap-2 justify-between items-center"> 3936 <p id="authentication-popup-title" class="text-xl"> 3937 <strong>Klant-login</strong> 3938 </p> 3939 <button 3940 type="button" 3941 class="btn bg-transparent border-transparent p-2" 3942 @click="close" 3943 aria-label="Close panel" 3944 > 3945 <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" viewBox="0 0 24 24" aria-hidden="true"><path d="M18 6 6 18M6 6l12 12"/></svg> 3946 </button> 3947 </div> 3948 3949 <div class="message error" x-show="errors" x-cloak> 3950 <template x-for="(message, index) in errorMessages" :key="index"> 3951 <div> 3952 <template x-if="message"> 3953 <span x-html="message"></span> 3954 </template> 3955 </div> 3956 </template> 3957 </div> 3958 </div> 3959 3960 <div class="block-customer-login p-8"> 3961 <p id="authenticate-customer-login" class="text-lg mb-2"> 3962 <strong>Checkout using your account</strong> 3963 </p> 3964 3965 <form 3966 id="login-form" 3967 class="form form-login" 3968 method="post" 3969 @submit.prevent="submitForm" 3970 > 3971 <input name="context" type="hidden" value="checkout"> 3972 3973 <div class="flex flex-col gap-4"> 3974 <div class="field email required"> 3975 <label for="form-login-username"> 3976 <span>E-mailadres</span> 3977 </label> 3978 <div class="control"> 3979 <input 3980 id="form-login-username" 3981 name="username" 3982 type="email" 3983 class="form-input w-full" 3984 required 3985 autocomplete="email" 3986 x-ref="customer-email" 3987 @change="resetErrors" 3988 > 3989 </div> 3990 </div> 3991 <div class="field password required"> 3992 <label for="form-login-password"> 3993 <span>Wachtwoord</span> 3994 </label> 3995 <div class="control"> 3996 <input 3997 id="form-login-password" 3998 name="password" 3999 type="password" 4000 class="form-input w-full" 4001 required 4002 autocomplete="current-password" 4003 x-ref="customer-password" 4004 @change="resetErrors" 4005 > 4006 </div> 4007 </div> 4008 </div> 4009 4010 <div class="actions-toolbar"> 4011 <button 4012 type="submit" 4013 class="btn btn-primary" 4014 > 4015 Inloggen </button> 4016 <a 4017 href="https://www.girav.nl/customer/account/forgotpassword/" 4018 class="underline hover:no-underline" 4019 > 4020 Wachtwoord vergeten? </a> 4021 </div> 4022 </form> 4023 </div> 4024 <div class="block-new-customer p-8 border-t border-gray-300"> 4025 <p id="authenticate-new-customer" class="text-lg mb-2"> 4026 <strong>Checkout as a new customer</strong> 4027 </p> 4028 4029 <div class="block-content"> 4030 <p class="mb-1"> 4031 Het aanmaken van een account heeft vele voordelen: </p> 4032 <ul class="list-disc pl-5"> 4033 <li> Bekijk bestelling en verzendstatus</li> 4034 <li> Bekijk bestelgeschiedenis</li> 4035 <li> Reken sneller af</li> 4036 </ul> 4037 <div class="actions-toolbar mt-6 mb-2"> 4038 <a href="https://www.girav.nl/customer/account/create/" 4039 class="inline-flex btn btn-primary"> 4040 Account aanmaken </a> 4041 </div> 4042 </div> 4043 </div> 4044</dialog> 4045</div> 4046</header>
4046<main id="maincontent" class="page-main"><div id="contentarea" tabindex="-1"></div> 4047<div class="page messages">
4048<script> 4049 function initMessages() { 4050 "use strict"; 4051 return { 4052 messages: window.mageMessages || [], 4053 isEmpty() { 4054 return this.messages.reduce( 4055 function (isEmpty, message) { 4056 return isEmpty && message === undefined 4057 }, true 4058 ) 4059 }, 4060 hasMessages() { 4061 return !this.isEmpty(); 4062 }, 4063 hasMessage() { 4064 return !!this.message; 4065 }, 4066 removeMessage() { 4067 this.messages[this.index] = undefined; 4068 }, 4069 addMessages(messages, hideAfter) { 4070 messages.map((message) => { 4071 this.messages = this.messages.concat(message); 4072 if (hideAfter === undefined && message.type === 'success' && window.defaultSuccessMessageTimeout) { 4073 hideAfter = window.defaultSuccessMessageTimeout; 4074 } 4075 if (hideAfter) { 4076 this.setHideTimeOut(this.messages.length -1, hideAfter); 4077 } 4078 }); 4079 }, 4080 setHideTimeOut(messageIndex, hideAfter) { 4081 setTimeout((messageIndex) => { 4082 this.messages[messageIndex] = undefined; 4083 }, hideAfter, messageIndex); 4084 }, 4085 eventListeners: { 4086 ['@messages-loaded.window'](event) { 4087 this.addMessages(event.detail.messages, event.detail.hideAfter) 4088 }, 4089 ['@private-content-loaded.window'](event) { 4090 const data = event.detail.data; 4091 if ( 4092 data.messages && 4093 data.messages.messages && 4094 data.messages.messages.length 4095 ) { 4096 this.addMessages(data.messages.messages); 4097 } 4098 }, 4099 ['@clear-messages.window']() { 4100 this.messages = []; 4101 }, 4102 ['@pageshow.window'](event) { 4103 if (event.persisted) { 4104 this.messages = []; 4105 } 4106 } 4107 }, 4108 getMessageUiId() { 4109 return 'message-' + this.message.type; 4110 }, 4111 isAlert() { 4112 return this.message.type === 'error' || this.message.type === 'info'; 4113 }, 4114 isSuccess() { 4115 return this.message.type === 'success' 4116 }, 4117 isWarning() { 4118 return this.message.type === 'warning' || this.message.type === 'notice' 4119 }, 4120 isFreeGift() { 4121 return this.message.type === 'freegift' 4122 }, 4123 } 4124 } 4125 4126 window.addEventListener('alpine:init', () => Alpine.data('initMessages', initMessages), {once: true}) 4127</script>
4127 4128 4129<section 4130 id="messages" 4131 x-data="initMessages" 4132 x-bind="eventListeners" 4133 role="alert" 4134> 4135 <template x-if="hasMessages"> 4136 <div class="w-full"> 4137 <div class="messages container mx-auto py-3"> 4138 <template x-for="(message, index) in messages" :key="index"> 4139 <div> 4140 <template x-if="hasMessage"> 4141 <div class="message" 4142 :class="message.type" 4143 :ui-id="getMessageUiId" 4144 > 4145 <template x-if="isFreeGift"> 4146 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 25" class="text-[#0065CC]" width="24" height="24" role="img"> 4147 <path fill="currentColor" d="M11.17 11.24V25H1.65a.83.83 0 0 1-.83-.82V11.24h10.35Zm11.83 0v12.94c0 .45-.38.82-.84.82h-9.33V11.24H23Zm.17-5.56h-4.7A3.29 3.29 0 0 0 20 3.84c.36-1.26-.36-2.5-1.25-3.16a2.93 2.93 0 0 0-2.68-.56c-1.2.35-2.37 1.51-3.45 3.45-.24.42-.45.84-.62 1.2-.17-.36-.38-.78-.62-1.2C10.3 1.63 9.14.47 7.93.12a2.93 2.93 0 0 0-2.68.56c-.89.67-1.61 1.9-1.25 3.16.2.72.72 1.33 1.54 1.84H.84A.83.83 0 0 0 0 6.5v3.1h11.17V5.68h1.66V9.6H24V6.5a.83.83 0 0 0-.83-.82ZM6.93 4.56c-.75-.35-1.21-.75-1.33-1.16-.16-.55.32-1.17.66-1.42.35-.27.64-.34.87-.34.12 0 .23.02.32.05.75.22 1.63 1.16 2.47 2.65.23.41.43.82.6 1.17a13.28 13.28 0 0 1-3.6-.95ZM18.4 3.4c-.12.4-.58.81-1.33 1.16-.86.4-2.06.73-3.58.95.16-.35.36-.76.6-1.17.83-1.49 1.7-2.43 2.46-2.65.09-.03.2-.05.32-.05.23 0 .52.07.87.34.34.25.82.87.66 1.42Z"/> 4148<title>free-gift</title></svg> 4149 </template> 4150 4151 <template x-if="isAlert"> 4152 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" role="img"> 4153 <circle cx="12" cy="12" r="10"/> 4154 <line x1="12" x2="12" y1="8" y2="12"/> 4155 <line x1="12" x2="12.01" y1="16" y2="16"/> 4156<title>alert-circle</title></svg> 4157 </template> 4158 4159 <template x-if="isSuccess"> 4160 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" role="img"> 4161 <path d="M12 22c5.523 0 10-4.477 10-10S17.523 2 12 2 2 6.477 2 12s4.477 10 10 10z"/> 4162 <path d="m9 12 2 2 4-4"/> 4163<title>check-circle-2</title></svg> 4164 </template> 4165 4166 <template x-if="isWarning"> 4167 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" role="img"> 4168 <path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z"/> 4169 <path d="M12 9v4"/> 4170 <path d="M12 17h.01"/> 4171<title>alert-triangle</title></svg> 4172 </template> 4173 <span x-html="message.text"></span> 4174 <button 4175 type="button" 4176 class="text-gray-600 hover:text-black" 4177 aria-label="Close message" 4178 @click.prevent="removeMessage" 4179 > 4180 <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="stroke-current" aria-hidden="true"> 4181 <path d="M18 6 6 18"/> 4182 <path d="m6 6 12 12"/> 4183</svg> 4184 </button> 4185 </div> 4186 </template> 4187 </div> 4188 </template> 4189 </div> 4190 </div> 4191 </template> 4192</section> 4193</div><div class="columns"><div class="column main">
4193<script> 4194 function mergedConfigurations(defaultItem = null) { 4195 return { 4196 selectedItem: defaultItem, 4197 setHiddenAttributeValues(productId) { 4198 window.dispatchEvent(new CustomEvent('update-button', { 4199 detail: {product_id: productId} 4200 })) 4201 const values = this.selectedItem.split('_'); 4202 const hiddenElements = this.getHiddenElements(productId); 4203 let attributes = []; 4204 4205 // Unfold the values to represent the attributes 4206 for (let i = 0; i < values.length; i += 2) { 4207 attributes.push({ 4208 attributeId: values[i], 4209 value: values[i + 1] 4210 }) 4211 } 4212 4213 // Loop over the attributes and set the hidden elements 4214 for (let i = 0; i < attributes.length; i++) { 4215 const attribute = attributes[i]; 4216 if (attribute.attributeId !== '') { 4217 const hiddenElement = hiddenElements[i]; 4218 4219 hiddenElement.setAttribute('name', 'super_attribute[' + attribute.attributeId + ']'); 4220 hiddenElement.setAttribute('value', attribute.value); 4221 } 4222 } 4223 }, 4224 4225 getHiddenElements(productId) { 4226 const parentElement = document.getElementById('fused_configuration_' + productId); 4227 4228 return parentElement.querySelectorAll('input'); 4229 }, 4230 } 4231 } 4232 window.addEventListener('alpine:init', () => Alpine.data('mergedConfigurations', mergedConfigurations), {once: true}) 4233</script>
4233 4234 4235
4235<script> 4236 /* e.g. hyva theme */ 4237 document.addEventListener('DOMContentLoaded', function(){ 4238 var items = document.getElementsByClassName('mfblogunveil'); 4239 var el, url; 4240 if (items.length) { 4241 for (var i=0; i<items.length;i++) { 4242 el = items[i]; 4243 url = el.getAttribute('data-original'); 4244 if (!url) { 4245 continue; 4246 }; 4247 if ('IMG' == el.tagName) { 4248 el.src = url; 4249 } else { 4250 el.style.backgroundImage = "url('" + url + "')"; 4251 } 4252 } 4253 } 4254 }); 4255 </script>
4255<div id="customer-login-container" class="login-container"> 4256<div class="inner w-full md:w-1/2 md:p-6 bg-transparent md:bg-[#f9f9f9] text-[#2a2a2a] flex flex-col rounded-xl"> 4257 <div aria-labelledby="block-customer-login-heading"> 4258 <form 4259 class="form form-login" 4260 action="https://www.girav.nl/customer/account/loginPost/" 4261 method="post" 4262 x-data="initCustomerLoginForm" 4263 @submit.prevent="submitForm" 4264 id="customer-login-form" 4265 > 4266 <input name="form_key" type="hidden" value="x2axT8CBZcoKxPKB" /> <fieldset class="fieldset login mt-0 mb-2 flex flex-col" x-data="textualPassword"> 4267 <legend class="mb-0 md:mb-3"> 4268 <h2 class="text-xl font-semibold title-font text-primary"> 4269 Inloggen </h2> 4270 </legend> 4271 <div class="md:mb-6 text-[14px] md:text-[16px]"> 4272 Als je al een Girav-account hebt, log dan hier in om je gegevens te bekijken. </div> 4273 <div class="!my-2 !md:my-4 field email required"> 4274 <label class="label" for="email"> 4275 <span class="mr-0.5">E-mailadres</span> 4276 </label> 4277 <div class="control"> 4278 <input 4279 name="login[username]" 4280 class="form-input" 4281 required 4282 value="" 4283 autocomplete="username" 4284 id="email" 4285 type="email" 4286 placeholder="naam@email.nl" 4287 title="E-mailadres" 4288 /> 4289 </div> 4290 </div> 4291 <div class="!my-2 !md:my-4 field password required" 4292 > 4293 <label for="pass" class="label"> 4294 <span class="mr-0.5">Wachtwoord</span> 4295 </label> 4296 <div class="control flex items-center relative"> 4297 <input 4298 name="login[password]" 4299 class="form-input w-full" 4300 required 4301 :type="passwordOrText" 4302 autocomplete="current-password" 4303 id="pass" 4304 title="Wachtwoord" 4305 > 4306 <div 4307 x-on:click="toggleVisible" 4308 class="cursor-pointer px-4 absolute right-0" 4309 :aria-label="ariaLabel" 4310 > 4311 <template x-if="notVisible"> 4312 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 15 11" class="w-5 h-5" width="24" height="24" role="img"> 4313<path fill="currentColor" d="m.5 5.5-.46-.19a.5.5 0 0 0 0 .38L.5 5.5Zm14 0 .46.19a.5.5 0 0 0 0-.38l-.46.19Zm-7 4.5a6.6 6.6 0 0 1-5-2.33A9.37 9.37 0 0 1 .97 5.32L.5 5.5l-.46.19a2.1 2.1 0 0 0 .1.24l.32.6c.27.49.7 1.15 1.3 1.8A7.6 7.6 0 0 0 7.5 11v-1Zm-7-4.5.46.19v-.01a2.62 2.62 0 0 1 .09-.18A9.37 9.37 0 0 1 2.5 3.34 6.6 6.6 0 0 1 7.5 1V0a7.6 7.6 0 0 0-5.75 2.67A10.37 10.37 0 0 0 .04 5.3l.46.19Zm7-4.5a6.6 6.6 0 0 1 5 2.33 9.37 9.37 0 0 1 1.53 2.35 68.89 68.89 0 0 1 .93-.37.66.66 0 0 0-.02-.06 6.16 6.16 0 0 0-.4-.78 9.37 9.37 0 0 0-1.3-1.8A7.6 7.6 0 0 0 7.5 0v1Zm7 4.5-.46-.19v.01a1.99 1.99 0 0 1-.09.18 9.37 9.37 0 0 1-1.45 2.16 6.6 6.6 0 0 1-5 2.34v1a7.6 7.6 0 0 0 5.75-2.67 10.36 10.36 0 0 0 1.71-2.64l-.46-.19ZM7.5 7A1.5 1.5 0 0 1 6 5.5H5A2.5 2.5 0 0 0 7.5 8V7ZM9 5.5C9 6.33 8.33 7 7.5 7v1A2.5 2.5 0 0 0 10 5.5H9ZM7.5 4C8.33 4 9 4.67 9 5.5h1A2.5 2.5 0 0 0 7.5 3v1Zm0-1A2.5 2.5 0 0 0 5 5.5h1C6 4.67 6.67 4 7.5 4V3Z"/> 4314<title>eye</title></svg> 4315 </template> 4316 <template x-if="visible"> 4317 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="w-5 h-5" width="24" height="24" role="img"> 4318 <path fill-rule="evenodd" d="M3.707 2.293a1 1 0 00-1.414 1.414l14 14a1 1 0 001.414-1.414l-1.473-1.473A10.014 10.014 0 0019.542 10C18.268 5.943 14.478 3 10 3a9.958 9.958 0 00-4.512 1.074l-1.78-1.781zm4.261 4.26l1.514 1.515a2.003 2.003 0 012.45 2.45l1.514 1.514a4 4 0 00-5.478-5.478z" clip-rule="evenodd"/> 4319 <path d="M12.454 16.697L9.75 13.992a4 4 0 01-3.742-3.741L2.335 6.578A9.98 9.98 0 00.458 10c1.274 4.057 5.065 7 9.542 7 .847 0 1.669-.105 2.454-.303z"/> 4320<title>
4320eye-off</title></svg> 4321 </template> 4322 </div> 4323 </div> 4324 </div> 4325 4326 4327 4328 <div 4329 class="actions-toolbar flex justify-between flex-wrap pb-0 mb-0 items-center" 4330 > 4331 <button type="submit" class="btn btn-primary disabled:opacity-75 w-full" name="send" 4332 > 4333 <span>Inloggen</span> 4334 </button> 4335 <div class="flex w-full justify-between"> 4336 <a 4337 class="underline text-[#2a2a2a] md:text-secondary font-normal sm:font-bold text-[12px] md:text-[13px] w-full text-center md:text-left" 4338 href="https://www.girav.nl/customer/account/forgotpassword/" 4339 > 4340 <span>Wachtwoord vergeten?</span> 4341 </a> 4342 4343 </div> 4344 </div> 4345 <div> 4346 <template x-if="displayErrorMessage"> 4347 <p class="text-red flex items-center"> 4348 <span class="inline-block w-8 h-8 mr-3"> 4349 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" width="24" height="24" role="img"> 4350 <path stroke-linecap="round" stroke-linejoin="round" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/> 4351<title>exclamation-circle</title></svg> 4352 </span> 4353 <template x-for="errorMessage in errorMessages"> 4354 <span x-html="errorMessage"></span> 4355 </template> 4356 </p> 4357 </template> 4358 </div> 4359 </fieldset> 4360 </form> 4361 </div> 4362 <div class="w-full"> 4363 </div> 4364
4364<script> 4365 function initCustomerLoginForm() { 4366 return { 4367 form: this.$el, 4368 errors: 0, 4369 hasCaptchaToken: 0, 4370 passwordMode: true, 4371 displayErrorMessage: false, 4372 errorMessages: [], 4373 setErrorMessages(messages) { 4374 this.errorMessages = [messages]; 4375 this.displayErrorMessage = this.errorMessages.length; 4376 }, 4377 validateForm($form) { 4378 }, 4379 submitForm() { 4380 const $form = document.querySelector('#customer-login-form'); 4381 this.validateForm($form) 4382 4383 const redirectUrl = hyva.getCookie('login_redirect'); 4384 const hasLogoutSuccess = redirectUrl?.includes("logoutSuccess"); 4385 4386 if (hasLogoutSuccess) { 4387 hyva.setCookie('login_redirect', 4388 window.location.href 4389 ) 4390 } 4391 4392 if (this.errors === 0) { 4393 $form.submit(); 4394 } 4395 }, 4396 isValidEmail(value) { 4397 return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value); 4398 }, 4399 magicLogin() { 4400 let emailField = document.getElementById('email'); 4401 4402 if (this.isValidEmail(emailField.value)) { 4403 const $magicForm = document.querySelector('#form-email-login-link'); 4404 document.getElementById('email-for-login-link').value = emailField.value; 4405 4406 $magicForm.submit(); 4407 } else { 4408 emailField.reportValidity(); 4409 } 4410 } 4411 } 4412 } 4413 4414 window.addEventListener('alpine:init', () => { 4415 Alpine.data('initCustomerLoginForm', initCustomerLoginForm); 4416 Alpine.data('textualPassword', () => hyva.createBooleanObject('visible', false, { 4417 passwordOrText() {return this.visible() ? 'text': 'password'}, 4418 ariaLabel() {return this.visible() ? 'Wachtwoord\u0020verbergen' : 'Wachtwoord\u0020tonen'} 4419 })); 4420 }, {once: true}); 4421 </script>
4421 4422 </div> 4423 4424 <div class="block-new-customer w-full md:w-[35%] flex flex-col justify-between p-6 text-[#2a2a2a] bg-white overflow-hidden md:ml-3 rounded-xl flex-grow"> 4425 <div> 4426 <div class="block-title"> 4427 <h2 class="text-xl font-bold title-font mb-3 text-primary" role="heading" aria-level="2"> 4428 Nieuw account aanmaken </h2> 4429 </div> 4430 <div class="block-content" aria-labelledby="block-new-customer-heading"> 4431 <p>Maak binnen één minuut een account aan.</p> 4432 </div> 4433 <ul class="mt-8 flex flex-col gap-3"> 4434 <li class="flex gap-3"> 4435 <span class="flex flex-col justify-center"> 4436 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 22 22" class="text-[#254EF3]" width="22" height="22" role="img"> 4437 <path stroke="currentColor" stroke-width="1.5" d="m6.3 11 4 3.3 5.4-6.6M11 20.3a9.3 9.3 0 1 1 0-18.6 9.3 9.3 0 0 1 0 18.6Z"/> 4438<title>check-circle</title></svg> 4439 </span> 4440 <span>Op de hoogte van je bestelling</span> 4441 </li> 4442 <li class="flex gap-3"> 4443 <span class="flex flex-col justify-center"> 4444 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 22 22" class="text-[#254EF3]" width="22" height="22" role="img"> 4445 <path stroke="currentColor" stroke-width="1.5" d="m6.3 11 4 3.3 5.4-6.6M11 20.3a9.3 9.3 0 1 1 0-18.6 9.3 9.3 0 0 1 0 18.6Z"/> 4446<title>check-circle</title></svg> 4447 </span> 4448 <span>Eenvoudig herhaalaankopen doen</span> 4449 </li> 4450 <li class="flex gap-3"> 4451 <span class="flex flex-col justify-center"> 4452 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 22 22" class="text-[#254EF3]" width="22" height="22" role="img"> 4453 <path stroke="currentColor" stroke-width="1.5" d="m6.3 11 4 3.3 5.4-6.6M11 20.3a9.3 9.3 0 1 1 0-18.6 9.3 9.3 0 0 1 0 18.6Z"/> 4454<title>check-circle</title></svg> 4455 </span> 4456 <span>Makkelijk en gratis retourneren</span> 4457 </li> 4458 </ul> 4459 </div> 4460 <div class="w-full actions-toolbar flex self-end md:mb-[51px]"> 4461 <a href="https://www.girav.nl/customer/account/create/" 4462 class="btn btn-secondary w-full"><span>Account aanmaken</span> 4463 </a> 4464 </div> 4465 </div> 4466 4467<div class="hidden md:block bg-transparent w-full md:w-1/4 my-8 md:my-0 h-auto rounded-xl md:ml-3 overflow-hidden"> 4468 <style>.cmsb69-w-full { 4469width: 100% 4470}</style> 4471<div data-content-type="html" data-appearance="default" data-element="main" data-decoded="true"><img src="https://www.girav.nl/media/wysiwyg/Girav_TShirt_1_kopie.jpg" alt="Girav Customer Page Visual" class="cmsb69-w-full"/></div></div> 4472</div></div></div></main><footer class="page-footer"><div class="footer content"> 4473<div class="footer-pre bg-[#2A2A2A] text-white md:py-10"> 4474 <div class="container flex flex-col md:flex-row md:flex-wrap"> 4475 4476 <section 4477 class="section-item section-item-toggle flex-0 border-[#1D1D1D] py-4 lg:pr-4 order-1 md:order-1 footer-block-contact" 4478 > 4479 <span 4480 id="column-footer.section.contact" 4481 class="font-light font-header text-lg md:text-xl" 4482 >Hulp & Contact</span> 4483 <nav 4484 class="mt-5" 4485 aria-label="column-footer.section.contact" 4486 > 4487<div class="customer-service"> 4488 <div x-data="whatsapp()" class="customer-service-menu"> 4489 <a href="tel:020-4721002" class="customer-service-item flex gap-4"> 4490 <div class="icon"> 4491 <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" fill="none" role="img"><path d="M6.292.667H3.333C1.861.667.667 1.861.667 3.333v2.667C.667 13.364 6.636 19.333 14 19.333h2.667c1.473 0 2.667-1.194 2.667-2.667v-1.842c0-.505-.285-.967-.737-1.192l-3.221-1.611c-.726-.363-1.605.001-1.862.771l-.397 1.191c-.257.771-1.048 1.23-1.846 1.071-3.192-.639-5.687-3.134-6.326-6.326-.16-.798.299-1.589 1.07-1.846l1.478-.492c.661-.22 1.041-.912.872-1.588L8.368 4.802 7.586 1.677C7.437 1.083 6.904.667 6.292.667Z" stroke="#fff"/><title>footer-phone</title></svg> 4492 </div> 4493 <div class="text">
4494 <span class="font-header font-normal text-white text-sm md:text-base block mb-2">Telefoon </span> 4495 <span class="text-sm md:text-base text-[#ABABAB]">Bel ons op 020-4721002</span> 4496 </div> 4497 </a> 4498 4499 <a href="/cdn-cgi/l/email-protection#1f687a7d6c77706f5f78766d7e69317c7072" class="customer-service-item flex gap-4"> 4500 <div class="icon"> 4501 <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="none" role="img"><path stroke="#fff" d="M.613 6 9.2 11.333 17.787 6M1.84 2h14.72c.678 0 1.227.597 1.227 1.333v13.334c0 .736-.549 1.333-1.227 1.333H1.84c-.677 0-1.227-.597-1.227-1.333V3.333C.613 2.597 1.163 2 1.84 2Z"/><title>footer-email</title></svg> 4502 </div> 4503 <div class="text"> 4504 <span class="font-header font-normal text-white text-sm md:text-base block mb-2">Mail ons </span> 4505 <span class="text-sm md:text-base text-[#ABABAB] break-all">Mail ons op <span class="__cf_email__" data-cfemail="5027353223383f201037392231267e333f3d">[email protected]</span></span> 4506 </div> 4507 </a> 4508 4509 <template x-if="shouldShow"> 4510 <a href="https://wa.me/310850872005" class="customer-service-item flex gap-4"> 4511 <div class="icon"> 4512 <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" fill="none" role="img"><g clip-path="url(#a)"><path d="M10.003 0.952H9.998C5.01 0.952.953 5.01.953 10c0 1.979.637 3.814 1.722 5.303l-1.127 3.361 3.478-1.111A9.041 9.041 0 0 0 10.003 19.048c4.989 0 9.046-4.059 9.046-9.047 0-4.988-4.057-9.048-9.046-9.048Z" stroke="#fff" stroke-miterlimit="10"/><path d="M15.268 13.728c-.219.617-1.086 1.128-1.776 1.278-.474.101-1.09.181-3.169-.68-2.659-1.102-4.372-3.803-4.505-3.979-.129-.175-1.074-1.43-1.074-2.729 0-1.298.66-1.931.925-2.201.219-.223.58-.325.925-.325.113 0 .213.005.305.01.266.012.4.028.575.447.218.525.749 1.824.814 1.957.064.133.128.314.038.49-.085.181-.159.261-.292.415a6.5 6.5 0 0 1-.394.437c-.122.144-.26.298-.106.564.154.259.686 1.127 1.468 1.823 1.01.9 1.829 1.187 2.123 1.308.219.091.479.069.638-.101.202-.217.453-.579.707-.936.181-.256.409-.286.648-.196.244.085 1.536.724 1.803.857.266.133.441.197.505.309.062.112.062.637-.155 1.255Z" fill="#fff"/></g><defs><clipPath id="a"><rect width="20" height="20" fill="#fff"/></clipPath></defs><title>footer-whatsapp</title></svg> 4513 </div> 4514 <div class="text"> 4515 <span class="font-header font-normal text-white text-sm md:text-base block mb-2">Whatsapp </span> 4516 <span class="text-sm md:text-base text-[#ABABAB]">WhatsApp naar +31 085 - 087 20 05 (maandag t/m vrijdag)</span> 4517 </div> 4518 </a> 4519 </template> 4520 </div> 4521 </div>
vendor: 110 bytes, lines 4521-4523
4521 4522 4523<script data-cfasync="false" src="/cdn-cgi/scripts/5c5dd728/cloudflare-static/email-decode.min.js"></script>
4523<script> 4524 function whatsapp() { 4525 return { 4526 configurationData: [{"day":"monday","from":"9:00 am","to":"5:00 pm"},{"day":"tuesday","from":"9:00 am","to":"5:00 pm"},{"day":"wednesday","from":"9:00 am","to":"5:00 pm"},{"day":"thursday","from":"9:00 am","to":"5:00 pm"},{"day":"friday","from":"9:00 am","to":"5:00 pm"},{"day":"saturday","from":"","to":""},{"day":"sunday","from":"","to":""}], 4527 shouldShow() { 4528 const today = this.getLocalizedDateTime(); 4529 4530 const todayData = this.configurationData.find((data) => { 4531 return data.day.toLowerCase() === today.toLocaleString('en-US', { 4532 weekday: 'long' 4533 }).toLowerCase(); 4534 }); 4535 4536 if (!todayData) { 4537 return false; 4538 } 4539 4540 if (!todayData.from || !todayData.to) { 4541 return false; 4542 } 4543 4544 const todayFrom = this.createDateTimeFrom12hoursString(todayData.from.toUpperCase()); 4545 const todayTo = this.createDateTimeFrom12hoursString(todayData.to.toUpperCase()); 4546 4547 if (!(todayFrom instanceof Date) || !(todayTo instanceof Date)) { 4548 return false; 4549 } 4550 4551 return today >= todayFrom && today <= todayTo; 4552 }, 4553 4554 /** 4555 * @returns {Date} 4556 */ 4557 getLocalizedDateTime() { 4558 const timeZone = 'Europe/Amsterdam'; 4559 const dutchTimeString = new Date().toLocaleString('en-US', { timeZone: timeZone }); 4560 4561 return new Date(dutchTimeString); 4562 }, 4563 4564 createDateTimeFrom12hoursString(timeString) { 4565 const startTime = this.getLocalizedDateTime(); 4566 const parts = timeString.match(/(\d+):(\d+) (AM|PM)/); 4567 4568 if (!parts) { 4569 return null; 4570 } 4571 4572 let hours = parseInt(parts[1]) 4573 const minutes = parseInt(parts[2]), 4574 tt = parts[3]; 4575 4576 if (tt === 'PM' && hours < 12) hours += 12; 4577 4578 startTime.setHours(hours, minutes, 0, 0); 4579 4580 return startTime; 4581 } 4582 } 4583 } 4584</script>
4584 4585</nav> 4586 </section> 4587 4588 <section 4589 class="section-item section-item-toggle flex-0 border-[#1D1D1D] py-4 lg:pr-4 order-0 md:order-1 footer-block-newsletter" 4590 > 4591 <span 4592 id="column-footer.section.newsletter" 4593 class="font-light font-header text-lg md:text-xl" 4594 >Niets missen?</span> 4595 <nav 4596 class="mt-5" 4597 aria-label="column-footer.section.newsletter" 4598 > 4599<div class="footer-newsletter-block w-full"> 4600 <p class="text-[#D9D9D9] md:text-[#ABABAB] text-sm md:text-base mb-4 md:mb-8"> 4601 Schrijf je in voor de nieuwsbrief. Je mist niets van nieuwe collecties en profiteert als eerst van de beste deals. </p> 4602 <form class="form subscribe" 4603 action="https://www.girav.nl/newsletter/subscriber/new/" 4604 method="post" 4605 x-data="iniFooterNewsletterForm()" 4606 @submit.prevent="submitForm()" 4607 id="footer-newsletter-validate-detail"> 4608 <input type="hidden" name="subscription_source" value="footer-website"/> 4609 <div class="relative"> 4610 <label for="newsletter-subscribe" class="sr-only"> 4611 E-mailadres </label> 4612 <input name="email" 4613 type="email" 4614 required 4615 id="newsletter-subscribe" 4616 class="w-full bg-[#4E5055] border-0 rounded-[5px] h-[45px] md:h-[62px] text-xs md:text-base leading-none text-white font-normal pl-5 placeholder:text-white" 4617 placeholder="Vul je emailadres in" 4618 autocomplete="email" 4619 > 4620 <input name="form_key" type="hidden" value="x2axT8CBZcoKxPKB" /> <div class="control"> 4621 <input type="hidden" 4622 value="" 4623 name="g-recaptcha-response" 4624 > 4625</div> 4626 <button class="h-[30px] w-[30px] md:w-auto md:h-[46px] absolute right-2 md:right-4 top-2 flex items-center justify-center text-[#2A2A2A] md:text-white text-xs md:text-base font-medium bg-[#D9D9D9] md:bg-transparent rounded-[6px] md:rounded-none"> 4627 <span class="hidden md:block mr-5">Inschrijven</span> 4628 <svg class="block md:hidden" width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> 4629 <path d="M14.0312 16L18.0312 12M18.0312 12L14.0312 8M18.0312 12H5.96875" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/> 4630 </svg> 4631 <svg class="hidden md:block" xmlns="http://www.w3.org/2000/svg" width="21" height="24" viewBox="0 0 21 24" fill="none"> 4632 <path d="M18.9 12L13.3 5.59998M18.9 12L13.3 18.4M18.9 12H1.40002" stroke="currentColor" stroke-width="2"/> 4633 </svg> 4634 <span class="sr-only">Inschrijven</span> 4635 </button> 4636 </div> 4637 <div> 4638 <template x-if="displayErrorMessage"> 4639 <p class="flex items-center text-red"> 4640 <span class="inline-block w-8 h-8 mr-3"> 4641 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" width="24" height="24" role="img"> 4642 <path stroke-linecap="round" stroke-linejoin="round" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/> 4643<title>exclamation-circle</title></svg> 4644 </span> 4645 <template x-for="errorMessage in errorMessages"> 4646 <span x-html="errorMessage"></span> 4647 </template> 4648 </p> 4649 </template> 4650 </div> 4651 </form> 4652 <div class="w-full"> 4653 </div> 4654 4655
4655<script> 4656 function iniFooterNewsletterForm() { 4657 return { 4658 errors: 0, 4659 hasCaptchaToken: 0, 4660 displayErrorMessage: false, 4661 errorMessages: [], 4662 setErrorMessages(messages) { 4663 this.errorMessages = [messages] 4664 this.displayErrorMessage = this.errorMessages.length 4665 }, 4666 submitForm() { 4667 const $form = document.querySelector('#footer-newsletter-validate-detail'); 4668 if (!this.hasCaptchaToken) { 4669 this.errors = 1; 4670 4671 4672 const executeGreCaptcha = () => { 4673 grecaptcha.ready(() => { 4674 grecaptcha.execute( 4675 '6LeWP7cqAAAAAJYu\u002DYl_w0Bow2yZSVS1cHmllSm9', 4676 {action: 'submit'} 4677 ).then((token) => { 4678 const tokenElement = $form['g\u002Drecaptcha\u002Dresponse']; 4679 4680 if (tokenElement && token && token.length > 0) { 4681 $form['g\u002Drecaptcha\u002Dresponse'].value = token; 4682 this.errors = 0; 4683 this.hasCaptchaToken = 1; 4684 (this.submitForm || $form.submit).call(this); 4685 } else { 4686 this.errors = 1; 4687 const error = tokenElement 4688 ? 'ReCaptcha\u0020validation\u0020failed,\u0020please\u0020try\u0020again' 4689 : 'ReCaptcha\u0020token\u0020element\u0020is\u0020missing.\u0020Please\u0020refresh\u0020the\u0020page\u0020and\u0020trying\u0020again.'; 4690 if (this.setErrorMessages) { 4691 this.setErrorMessages([error]) 4692 this.displayErrorMessage = true; 4693 } else { 4694 window.dispatchMessages && window.dispatchMessages([{type: "error", text: error}], 5000); 4695 } 4696 } 4697 }).catch(exception => { 4698 console.error(exception || `An unknown error occurred during ReCaptcha validation. Are the tokens and the domain correctly set up in the Google console?`) 4699 }); 4700 }) 4701 } 4702 4703 if (window.grecaptcha) { 4704 executeGreCaptcha(); 4705 } else { 4706 const recaptchaUrl = "https://www.google.com/recaptcha/api.js?render=6LeWP7cqAAAAAJYu\u002DYl_w0Bow2yZSVS1cHmllSm9"; 4707 const script = document.createElement('script'); 4708 script.setAttribute('type', 'text/javascript'); 4709 script.setAttribute('src', recaptchaUrl); 4710 document.head.appendChild(script); 4711 4712 script.addEventListener("load", executeGreCaptcha, false); 4713 } 4714 } 4715 4716 if (this.errors === 0) { 4717 window.dataLayer.push({ 4718 event: 'footer_newsletter_signup_clicked' 4719 } 4720 ); 4721 $form.submit(); 4722 } 4723 } 4724 } 4725 } 4726 </script>
4726 4727 </div> 4728</nav> 4729 </section> 4730 </div> 4731</div> 4732<div class="footer-main bg-[#313131] text-white md:py-10"> 4733 <div class="container flex flex-col md:flex-row md:flex-wrap"> 4734 4735 <section 4736 x-data="initColumnItem()" 4737 class="section-item section-item-mobile lg:hidden flex-1 accordion border-[#1D1D1D] order-1 md:order-1 footer-block-categories" 4738 > 4739 <button @click="open = !open" class="py-4 text-white" :aria-expanded="open"> 4740 <span 4741 id="column-footer.section.categories" 4742 class="font-light font-header text-lg md:text-xl" 4743 >Bestsellers</span> 4744 4745 <svg x-show="!open" xmlns="http://www.w3.org/2000/svg" width="14" height="13" viewBox="0 0 14 13" fill="none"> 4746 <path d="M7.375 0V13M0.875 6.5H13.875" stroke="currentColor" stroke-width="1.5"/> 4747 </svg> 4748 <svg x-cloak x-show="open" xmlns="http://www.w3.org/2000/svg" width="13" height="1" viewBox="0 0 13 1" fill="none"> 4749 <path d="M0 0.5H13" stroke="currentColor"/> 4750 </svg> 4751 </button> 4752 4753 <nav 4754 x-show="open" 4755 class="pt-0 pb-4 md:pt-4 md:pb-6 pl-6 md:pl-0 pr-0" 4756 aria-label="column-footer.section.categories" 4757 ><ul> 4758<li><a href="/t-shirts">Lange T-shirts</a></li> 4759<li><a href="/polo-shirts">Lange poloshirts</a></li> 4760<li><a href="/broeken/lange-chino">Chino broeken</a></li> 4761<li><a href="/overhemden">Overhemden</a></li> 4762<li><a href="/truien/merino">Merino wol Truien</a></li> 4763</ul></nav> 4764 </section> 4765 4766 <section 4767 class="section-item section-item-desktop hidden lg:block py-4 order-1 md:order-1 footer-block-categories" 4768 > 4769 <span 4770 id="column-footer.section.categories" 4771 class="font-light font-header text-lg md:text-xl" 4772 >Bestsellers</span> 4773 <nav 4774 class="mt-6" 4775 aria-label="column-footer.section.categories" 4776 ><ul> 4777<li><a href="/t-shirts">Lange T-shirts</a></li> 4778<li><a href="/polo-shirts">Lange poloshirts</a></li> 4779<li><a href="/broeken/lange-chino">Chino broeken</a></li> 4780<li><a href="/overhemden">Overhemden</a></li> 4781<li><a href="/truien/merino">Merino wol Truien</a></li> 4782</ul></nav> 4783 </section> 4784 4785 <section 4786 x-data="initColumnItem()" 4787 class="section-item section-item-mobile lg:hidden flex-1 accordion border-[#1D1D1D] order-1 md:order-1 footer-block-customer-service" 4788 > 4789 <button @click="open = !open" class="py-4 text-white" :aria-expanded="open"> 4790 <span 4791 id="column-footer.section.customer.service" 4792 class="font-light font-header text-lg md:text-xl" 4793 >Klantenservice</span> 4794 4795 <svg x-show="!open" xmlns="http://www.w3.org/2000/svg" width="14" height="13" viewBox="0 0 14 13" fill="none"> 4796 <path d="M7.375 0V13M0.875 6.5H13.875" stroke="currentColor" stroke-width="1.5"/> 4797 </svg> 4798 <svg x-cloak x-show="open" xmlns="http://www.w3.org/2000/svg" width="13" height="1" viewBox="0 0 13 1" fill="none"> 4799 <path d="M0 0.5H13" stroke="currentColor"/> 4800 </svg> 4801 </button> 4802 4803 <nav 4804 x-show="open" 4805 class="pt-0 pb-4 md:pt-4 md:pb-6 pl-6 md:pl-0 pr-0" 4806 aria-label="column-footer.section.customer.service" 4807 ><div data-content-type="html" data-appearance="default" data-element="main" data-decoded="true"><ul> 4808<li><a href="/klantenservice">Klantenservice</a></li> 4809<li><a href="/klantenservice/bezorgen">Bezorgen</a></li> 4810<li><a href="/klantenservice/betalen">Betalen</a></li> 4811<li><a href="/klantenservice/retourneren">Retourneren</a></li> 4812<li><a href="/klantenservice/bestellen">Bestellen</a></li> 4813<li><a href="/klantenservice/girav-maattabel">Maattabellen</a></li> 4814<li><a href="/customer/account">Mijn Girav account</a></li> 4815<li><a href="/Herroepingsrecht">Herroepingsrecht</a></li> 4816</ul></div></nav> 4817 </section> 4818 4819 <section 4820 class="section-item section-item-desktop hidden lg:block py-4 order-1 md:order-1 footer-block-customer-service" 4821 >
4822 <span 4823 id="column-footer.section.customer.service" 4824 class="font-light font-header text-lg md:text-xl" 4825 >Klantenservice</span> 4826 <nav 4827 class="mt-6" 4828 aria-label="column-footer.section.customer.service" 4829 ><div data-content-type="html" data-appearance="default" data-element="main" data-decoded="true"><ul> 4830<li><a href="/klantenservice">Klantenservice</a></li> 4831<li><a href="/klantenservice/bezorgen">Bezorgen</a></li> 4832<li><a href="/klantenservice/betalen">Betalen</a></li> 4833<li><a href="/klantenservice/retourneren">Retourneren</a></li> 4834<li><a href="/klantenservice/bestellen">Bestellen</a></li> 4835<li><a href="/klantenservice/girav-maattabel">Maattabellen</a></li> 4836<li><a href="/customer/account">Mijn Girav account</a></li> 4837<li><a href="/Herroepingsrecht">Herroepingsrecht</a></li> 4838</ul></div></nav> 4839 </section> 4840 4841 <section 4842 x-data="initColumnItem()" 4843 class="section-item section-item-mobile lg:hidden flex-1 accordion border-[#1D1D1D] order-1 md:order-1 footer-block-about" 4844 > 4845 <button @click="open = !open" class="py-4 text-white" :aria-expanded="open"> 4846 <span 4847 id="column-footer.section.about" 4848 class="font-light font-header text-lg md:text-xl" 4849 >Over Girav</span> 4850 4851 <svg x-show="!open" xmlns="http://www.w3.org/2000/svg" width="14" height="13" viewBox="0 0 14 13" fill="none"> 4852 <path d="M7.375 0V13M0.875 6.5H13.875" stroke="currentColor" stroke-width="1.5"/> 4853 </svg> 4854 <svg x-cloak x-show="open" xmlns="http://www.w3.org/2000/svg" width="13" height="1" viewBox="0 0 13 1" fill="none"> 4855 <path d="M0 0.5H13" stroke="currentColor"/> 4856 </svg> 4857 </button> 4858 4859 <nav 4860 x-show="open" 4861 class="pt-0 pb-4 md:pt-4 md:pb-6 pl-6 md:pl-0 pr-0" 4862 aria-label="column-footer.section.about" 4863 ><div data-content-type="html" data-appearance="default" data-element="main" data-decoded="true"><ul> 4864<li><a href="https://www.girav.nl/klantenservice">Klantenservice</a></li> 4865<li><a href="https://www.girav.nl/klantenservice/retourneren">Retourneren</a></li> 4866<li><a title="Antwoord op de vraag: wat is mijn maat? Gebaseerd op het altijd goed passende lange heren maatsysteem van Girav" href="/over-girav/maatsysteem">Girav maatsysteem</a></li> 4867<li><a href="https://www.girav.nl/over-ons">Over Girav</a></li> 4868<li><a href="https://www.girav.nl/girav-giftcard">Girav Giftcard</a></li> 4869<li><a href="https://www.girav.nl/werken-bij-girav">Werken bij Girav</a></li> 4870<li><a title="Lees alles over lange T-shirts voor mannen, van hoe je ze moet wassen tot hoe je zweetplekken voorkomt in witte Girav T-shirts in onze Stories" href="/stories">Blog</a></li> 4871<li><a title="Nieuws en persberichten" href="/nieuws">Nieuws</a></li> 4872<li><a title="Mis niets over Girav, heren T-shirts en interessante aanbiedingen en schrijf je in op nieuwsbrief" href="/nieuwsbrief">Nieuwsbrief</a></li> 4873</ul></div></nav> 4874 </section> 4875 4876 <section 4877 class="section-item section-item-desktop hidden lg:block py-4 order-1 md:order-1 footer-block-about" 4878 > 4879 <span 4880 id="column-footer.section.about" 4881 class="font-light font-header text-lg md:text-xl" 4882 >Over Girav</span> 4883 <nav 4884 class="mt-6" 4885 aria-label="column-footer.section.about" 4886 ><div data-content-type="html" data-appearance="default" data-element="main" data-decoded="true"><ul> 4887<li><a href="https://www.girav.nl/klantenservice">Klantenservice</a></li> 4888<li><a href="https://www.girav.nl/klantenservice/retourneren">Retourneren</a></li> 4889<li><a title="Antwoord op de vraag: wat is mijn maat? Gebaseerd op het altijd goed passende lange heren maatsysteem van Girav" href="/over-girav/maatsysteem">Girav maatsysteem</a></li> 4890<li><a href="https://www.girav.nl/over-ons">Over Girav</a></li> 4891<li><a href="https://www.girav.nl/girav-giftcard">Girav Giftcard</a></li> 4892<li><a href="https://www.girav.nl/werken-bij-girav">Werken bij Girav</a></li> 4893<li><a title="Lees alles over lange T-shirts voor mannen, van hoe je ze moet wassen tot hoe je zweetplekken voorkomt in witte Girav T-shirts in onze Stories" href="/stories">Blog</a></li> 4894<li><a title="Nieuws en persberichten" href="/nieuws">Nieuws</a></li> 4895<li><a title="Mis niets over Girav, heren T-shirts en interessante aanbiedingen en schrijf je in op nieuwsbrief" href="/nieuwsbrief">Nieuwsbrief</a></li> 4896</ul></div></nav> 4897 </section> 4898<div class="mainfooter-sections-inner-wrapper"> 4899 <section
4900 x-data="initColumnItem()" 4901 class="section-item section-item-mobile lg:hidden flex-1 accordion border-[#1D1D1D] order-1 md:order-1 footer-block-inspiration" 4902 > 4903 <button @click="open = !open" class="py-4 text-white" :aria-expanded="open"> 4904 <span 4905 id="column-footer.section.inspiration" 4906 class="font-light font-header text-lg md:text-xl" 4907 >Inspiratie</span> 4908 4909 <svg x-show="!open" xmlns="http://www.w3.org/2000/svg" width="14" height="13" viewBox="0 0 14 13" fill="none"> 4910 <path d="M7.375 0V13M0.875 6.5H13.875" stroke="currentColor" stroke-width="1.5"/> 4911 </svg> 4912 <svg x-cloak x-show="open" xmlns="http://www.w3.org/2000/svg" width="13" height="1" viewBox="0 0 13 1" fill="none"> 4913 <path d="M0 0.5H13" stroke="currentColor"/> 4914 </svg> 4915 </button> 4916 4917 <nav 4918 x-show="open" 4919 class="pt-0 pb-4 md:pt-4 md:pb-6 pl-6 md:pl-0 pr-0" 4920 aria-label="column-footer.section.inspiration" 4921 ><div data-content-type="html" data-appearance="default" data-element="main" data-decoded="true"><ul> 4922<li><a href="/stories">Stories</a></li> 4923<li><a href="/magazine">Magazine</a></li> 4924<li><a href="/lookbook">Lookbook</a></li> 4925</ul></div></nav> 4926 </section> 4927 4928 <section 4929 class="section-item section-item-desktop hidden lg:block py-4 order-1 md:order-1 footer-block-inspiration" 4930 > 4931 <span 4932 id="column-footer.section.inspiration" 4933 class="font-light font-header text-lg md:text-xl" 4934 >Inspiratie</span> 4935 <nav 4936 class="mt-6" 4937 aria-label="column-footer.section.inspiration" 4938 ><div data-content-type="html" data-appearance="default" data-element="main" data-decoded="true"><ul> 4939<li><a href="/stories">Stories</a></li> 4940<li><a href="/magazine">Magazine</a></li> 4941<li><a href="/lookbook">Lookbook</a></li> 4942</ul></div></nav> 4943 </section> 4944 4945 <section 4946 class="section-item section-item-toggle flex-0 border-[#1D1D1D] py-4 lg:pr-4 order-1 md:order-1 footer-block-social" 4947 > 4948 <span 4949 id="column-footer.section.social" 4950 class="font-light font-header text-lg md:text-xl" 4951 >Volg ons</span> 4952 <nav 4953 class="mt-5" 4954 aria-label="column-footer.section.social" 4955 > 4956<div class="footer-social"> 4957 <div class="social-icons"> 4958 4959 <a 4960 href="https://facebook.com/giravlongfit.bnl/" 4961 class="social-icon facebook h-5 w-5 block" 4962 title="Facebook" 4963 rel="noopener" 4964 target="_blank"> 4965 <span class="sr-only">Facebook</span> 4966 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" class="icon" role="img"><g clip-path="url(#a_2)"><path fill="#8C8E94" d="M10 0C4.477 0 0 4.481 0 10.009c0 4.666 3.19 8.586 7.508 9.695v-6.721h-2.56v-2.884h2.56V8.063c.068-3.816 2.526-4.495 5.971-3.817.026.936-.032 1.448-.006 2.384-2.508-.179-2.932.245-2.882 2.451V10.1h2.748l-.424 2.884h-2.323V20C15.839 19.694 20 15.338 20 10.009 20 4.48 15.523 0 10 0Z"/></g><defs><clipPath id="a_2"><path fill="#fff" d="M0 0h20v20H0z"/></clipPath></defs><title>facebook</title></svg> 4967 </a> 4968 <a 4969 href="https://www.instagram.com/girav/" 4970 class="social-icon instagram h-5 w-5 block" 4971 title="Instagram" 4972 rel="noopener" 4973 target="_blank"> 4974 <span class="sr-only">Instagram</span> 4975 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" class="icon" role="img"><g fill="#8C8E94" clip-path="url(#a_3)"><path d="M10 7.765a2.235 2.235 0 1 0 0 4.47 2.235 2.235 0 0 0 0-4.47Z"/><path d="M12.89 4.578a125.058 125.058 0 0 0-5.78 0c-1.424.04-2.492 1.109-2.532 2.532a125.085 125.085 0 0 0 0 5.78c.04 1.425 1.109 2.493 2.532 2.533 1.826.044 3.955.044 5.78 0 1.424-.04 2.493-1.108 2.533-2.532.044-1.826.044-3.955 0-5.78-.04-1.424-1.109-2.493-2.532-2.533ZM10 13.372a3.371 3.371 0 1 1 0-6.742 3.371 3.371 0 0 1 0 6.742Zm3.561-6.1a.758.758 0 1 1 0-1.516.758.758 0 0 1 0 1.516Z"/><path d="M10 0C4.477 0 0 4.477 0 10s4.477 10 10 10 10-4.477 10-10S15.523 0 10 0Zm6.55 13.01c-.071 1.965-1.575 3.469-3.54 3.54a107.25 107.25 0 0 1-6.02 0c-1.964-.071-3.468-1.575-3.54-3.54a107.281 107.281 0 0 1 0-6.02c.072-1.964 1.576-3.468 3.54-3.54a107.25 107.25 0 0 1 6.02 0c1.965.072 3.469 1.576 3.54 3.54.057 1.855.057 4.165 0 6.02Z"/></g><defs><clipPath id="a_3"><path fill="#fff" d="M0 0h20v20H0z"/></clipPath></defs><title>instagram</title></svg> 4976 </a> 4977 <a 4978 href="https://wa.me/310850872005" 4979 class="social-icon whatsapp h-5 w-5 block" 4980 title="Whatsapp" 4981 rel="noopener" 4982 target="_blank">
4983 <span class="sr-only">Whatsapp</span> 4984 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" class="icon" role="img"><path fill="#8C8E94" fill-rule="evenodd" d="M10.023 0h-.046C4.467 0 0 4.467 0 9.977v.046C0 15.533 4.467 20 9.977 20h.046C15.533 20 20 15.533 20 10.023v-.046C20 4.467 15.533 0 10.023 0ZM7.306 8.282a4.65 4.65 0 0 0 4.643 4.643 1.179 1.179 0 0 0 1.02-1.764.068.068 0 0 0-.048-.032l-1.705-.27-.011-.001a.064.064 0 0 0-.044.017c-.166.15-.285.34-.344.552l-.03.102-.098-.039c-.889-.35-1.6-1.06-1.949-1.949l-.038-.098.102-.03c.213-.059.403-.178.552-.343a.065.065 0 0 0 .017-.055l-.27-1.705a.066.066 0 0 0-.033-.047 1.147 1.147 0 0 0-.587-.157c-.648 0-1.176.527-1.177 1.176Zm9.182 1.156a6.28 6.28 0 0 0-2.012-4.073A6.28 6.28 0 0 0 10.213 3.7 6.308 6.308 0 0 0 3.912 10a6.27 6.27 0 0 0 .93 3.291l-1.357 3.006 4.347-.463a6.245 6.245 0 0 0 3.041.433 6.325 6.325 0 0 0 5.64-6.233V10c0-.189-.008-.379-.025-.562ZM5.594 14.771 8 14.515v.001l.092.044a4.977 4.977 0 0 0 2.682.44 5.016 5.016 0 0 0 4.468-4.879v-.008l.001-.111c0-.138-.006-.277-.018-.416-.212-2.587-2.414-4.615-5.012-4.615a5.035 5.035 0 0 0-5.03 5.03 4.986 4.986 0 0 0 .986 2.986l.144.193-.719 1.591Z" clip-rule="evenodd"/><title>whatsapp</title></svg> 4985 </a> 4986 </div> 4987</div> 4988</nav> 4989 </section> 4990</div> </div> 4991</div> 4992<div class="footer-sub bg-[#F1F1F1] text-black pt-4 md:py-6"> 4993 <div class="container flex flex-col md:flex-row md:flex-wrap"> 4994 4995<div class="w-full"> 4996 <div class="flex justify-center md-max:flex-wrap md:items-center md:justify-between gap-4 border-b border-gray-100 pb-4"> 4997 <div class="payment-methods"> 4998 <strong>Betaalmethodes</strong> 4999 <div data-content-type="html" data-appearance="default" data-element="main" data-decoded="true"><ul> 5000<li><img src="https://www.girav.nl/media/wysiwyg/Payment_icons/mollie_icon_idealwero.png" alt="iDeal - Wero" width="38" height="29" loading="lazy"></li> 5001<li><img src="https://www.girav.nl/media/wysiwyg/Payment_icons/mollie_icon_visa.png" alt="Visa" width="38" height="29" loading="lazy"></li> 5002<li><img src="https://www.girav.nl/media/wysiwyg/Payment_icons/mollie_icon_mastercard.png" alt="Mastercard" width="38" height="29" loading="lazy"></li> 5003<li><img src="https://www.girav.nl/media/wysiwyg/Payment_icons/mollie_icon_amex.png" alt="American Express" width="38" height="29" loading="lazy"></li> 5004<li><img src="https://www.girav.nl/media/wysiwyg/Payment_icons/mollie_icon_applepay.png" alt="ApplePay" width="38" height="29" loading="lazy"></li> 5005<li><img src="https://www.girav.nl/media/wysiwyg/Payment_icons/mollie_icon_paypal.png" alt="PayPal" width="38" height="29" loading="lazy"></li> 5006<li><img src="https://www.girav.nl/media/wysiwyg/Payment_icons/mollie_icon_giftcard.png" alt="Girav Giftcard" width="38" height="29" loading="lazy"></li> 5007 5008</ul> 5009 5010</div> </div> 5011 </div> 5012 <div class="copyright py-4 md:pb-0 text-xs md-max:text-center md:flex md:items-center md:justify-between"> 5013 <div class="copyright-rights"> 5014 <span>© 2026 Girav Long Fit. All Rights Reserved</span> 5015 </div> 5016 <div class="copyright-links md-max:mt-2"> 5017 <p><a title="Lees de algemene voorwaarden voor het gebruik van de website en bestellen bij Girav lange T-shirts, polo's, overhemden en truien voor mannen" href="/algemene-voorwaarden">Algemene voorwaarden</a> | <a title="Lees het Privacy Statement van Girav lange herenmode" href="/privacy-statement">Privacy Policy</a> | <a title="Lees de disclaimer van Girav herenmode voor de lange man" href="/disclaimer">Disclaimer</a> | <a title="Cookie informatie omtrent je bezoek aan Girav.nl, de beste lange herenmode site van Nederland" href="/cookie-informatie">Cookie info</a></p> </div> 5018 </div> 5019</div> 5020 </div> 5021</div> 5022</div></footer>
5022<script> 5023 5024 function rovingTabRelatedColors(group) { 5025 const buttons = Array.from(group.querySelectorAll('button')); 5026 let index = 0; 5027 5028 group.addEventListener('keydown', (event) => { 5029 const key = event.key; 5030 5031 if (key === 'ArrowRight' || key === 'ArrowDown') { 5032 event.preventDefault(); 5033 index = (index + 1) % buttons.length; 5034 } else if (key === 'ArrowLeft' || key === 'ArrowUp') { 5035 event.preventDefault(); 5036 index = (index - 1 + buttons.length) % buttons.length; 5037 } else { 5038 return; 5039 } 5040 5041 buttons.forEach((button, i) => button.setAttribute('tabindex', i === index ? '0' : '-1')); 5042 buttons[index].focus(); 5043 }); 5044 } 5045 5046 let groups = document.getElementsByClassName('relatedcolors-grid'); 5047 5048 for (let i = 0; i < groups.length; i++) { 5049 rovingTabRelatedColors(groups[i]); 5050 } 5051 5052 function debounce(func, wait) { 5053 let timeout; 5054 return function(...args) { 5055 const context = this; 5056 clearTimeout(timeout); 5057 timeout = setTimeout(() => func.apply(context, args), wait); 5058 }; 5059 } 5060 5061 const imgs = document.getElementsByClassName('product-image-photo'); 5062 const buttons = document.getElementsByClassName('mouseHoverRelatedColor'); 5063 5064 for (let i = 0; i < imgs.length; i++) { 5065 if (imgs[i].dataset.hoverImage) { 5066 imgs[i].addEventListener('mouseover', function () { 5067 this.src = this.dataset.hoverImage 5068 }) 5069 5070 imgs[i].addEventListener('mouseleave', function () { 5071 this.src = this.dataset.initialImage 5072 5073 }) 5074 } 5075 } 5076 5077 for (let i = 0; i < buttons.length; i++) { 5078 if (buttons[i].dataset.hoverImage) { 5079 buttons[i].addEventListener('mouseover', function () { 5080 let image = document.getElementById(this.dataset.selector); 5081 const item = image.closest('.product-item'); 5082 const priceBox = item.querySelector('.price-box'); 5083 const hoverPrice = hyva.formatPrice(this.getAttribute('data-hover-price')); 5084 const hoverFinalPrice = hyva.formatPrice(this.getAttribute('data-hover-final-price')); 5085 5086 let priceHtml = ''; 5087 let finalPriceClass = ''; 5088 5089 if (hoverPrice !== hoverFinalPrice) { 5090 priceHtml = `<span class="old-price"> 5091 <span class="price-container price-old_price"> 5092 <span data-price-type="oldPrice" class="price-wrapper"> 5093 <span class="price">${hoverPrice}</span> 5094 </span> 5095 </span> 5096 </span>`; 5097 finalPriceClass = 'text-action'; 5098 } 5099 5100 priceHtml += `<span class="price-container price-final_price ${finalPriceClass}"> 5101 <span data-price-type="finalPrice" class="price-wrapper"> 5102 <span class="price">${hoverFinalPrice}</span> 5103 </span> 5104 </span>`; 5105 5106 priceBox.innerHTML = priceHtml; 5107 5108 image.src = this.dataset.hoverImage; 5109 }) 5110 5111 buttons[i].addEventListener('mouseleave', function () { 5112 let image = document.getElementById(this.dataset.selector); 5113 const item = image.closest('.product-item'); 5114 const priceBox = item.querySelector('.price-box'); 5115 let hoverPrice = hyva.formatPrice(this.getAttribute('data-init-price')); 5116 const hoverFinalPrice = hyva.formatPrice(this.getAttribute('data-init-final-price')); 5117 5118 let priceHtml = ''; 5119 let finalPriceClass = ''; 5120 5121 if (this.getAttribute('data-init-price') === '0') { 5122 hoverPrice = hoverFinalPrice; 5123 } 5124 5125 if (hoverPrice !== hoverFinalPrice) { 5126 priceHtml = `<span class="old-price">
5127 <span class="price-container price-old_price"> 5128 <span data-price-type="oldPrice" class="price-wrapper"> 5129 <span class="price">${hoverPrice}</span> 5130 </span> 5131 </span> 5132 </span>`; 5133 finalPriceClass = 'text-action'; 5134 } 5135 5136 priceHtml += `<span class="price-container price-final_price ${finalPriceClass}"> 5137 <span data-price-type="finalPrice" class="price-wrapper"> 5138 <span class="price">${hoverFinalPrice}</span> 5139 </span> 5140 </span>`; 5141 5142 priceBox.innerHTML = priceHtml; 5143 5144 image.src = this.dataset.initialImage; 5145 }) 5146 } 5147 } 5148</script>
5148 5149 <template id="_ec-group-tpl"> 5150 <div class="py-4"> 5151 <label class="inline-flex items-center cursor-pointer"> 5152 <input 5153 type="checkbox" 5154 name="group" 5155 value="" 5156 class="sr-only peer _ec-checkbox" /> 5157 <div 5158 class="peer relative h-6 w-11 rounded-full bg-gray-200 after:absolute after:start-[2px] after:top-[2px] after:h-5 after:w-5 after:rounded-full after:border after:border-gray-300 after:bg-white after:transition-all after:content-[''] peer-checked:bg-secondary peer-checked:after:translate-x-full peer-checked:after:border-white peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300 peer-disabled:peer-checked:bg-secondary/50 rtl:peer-checked:after:-translate-x-full dark:border-gray-600 dark:bg-gray-700 dark:peer-focus:ring-blue-800"></div> 5159 <span 5160 class="ms-3 text-xl font-bold text-gray-900 dark:text-gray-300 _ec-group-name"></span> 5161 </label> 5162 <p class="_ec-group-description"></p> 5163 <details class="group"> 5164 <summary 5165 class="py-2 font-bold flex items-center group-open:text-primary-red cursor-pointer hide-marker"> 5166 Meer informatie </summary> 5167 Leveranciers: <div class="p-2 relative _ec-vendors"></div> 5168 </details> 5169 </div> 5170 </template> 5171 <template id="_ec-provider-tpl"> 5172 <details class="group"> 5173 <summary 5174 class="py-2 font-bold flex items-center group-open:text-primary-red cursor-pointer hide-marker gap-1"> 5175 <span aria-hidden="true">›</span> <span class="_ec-provider-name"></span> 5176 </summary> 5177 <div class="relative overflow-x-auto mb-10"> 5178 <table 5179 class="w-full text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400"> 5180 <thead 5181 class="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400"> 5182 <tr> 5183 <th scope="col" class="px-4 py-3">Cookienaam</th> 5184 <th scope="col" class="px-4 py-3">Type</th> 5185 <th scope="col" class="px-4 py-3">Verloopt</th> 5186 <th scope="col" class="px-4 py-3">Omschrijving</th> 5187 </tr> 5188 </thead> 5189 <tbody class="_ec-tbody"></tbody> 5190 </table> 5191 </div> 5192 </details> 5193 <a 5194 href="" 5195 target="_blank" 5196 style="margin-top: -32px" 5197 rel="noopener nofollow" 5198 class="underline absolute right-2 _ec-provider-link"><span aria-hidden="true">↗</span> Meer details over deze leverancier</a> 5199 </template> 5200 <template id="_ec-cookie-tpl"> 5201 <tr 5202 class="bg-white border-b dark:bg-gray-800 dark:border-gray-700"> 5203 <th 5204 scope="row" 5205 class="_ec-name px-4 py-4 font-medium text-gray-900 whitespace-nowrap dark:text-white"></th> 5206 <td class="_ec-type px-4 py-4"></td> 5207 <td class="_ec-retention px-4 py-4"></td> 5208 <td class="_ec-description px-4 py-4"></td> 5209 </tr> 5210 </template>
5211<script type="module"> 5212 import { ScrollSnapExtensions } from 'https://www.girav.nl/static/version1790837059/frontend/Girav/hyva/nl_NL/Emico_Slider/js/scroll-snap-extensions.min.js'; 5213 5214 const initSlider = (slider) => { 5215 slider.querySelector('.emico-slider-wrapper ').style.setProperty('--scrollbar-width', (window.innerWidth - document.documentElement.clientWidth) + "px"); 5216 slider.querySelector('.overflow-white').style.setProperty('--overflow-color', window.getComputedStyle(slider).getPropertyValue('background-color')); 5217 slider.querySelector('.nav-carousel').insertAdjacentHTML( 5218 'beforeend', 5219 '' 5220 ); 5221 5222 slider.querySelector('.emico-slider').id = slider.id; 5223 5224 slider.querySelectorAll('.nav-carousel button').forEach(button => { 5225 button.setAttribute('aria-controls', slider.id); 5226 }); 5227 5228 slider = slider.querySelector('.emico-slider'); 5229 5230 if (slider instanceof HTMLElement) { 5231 requestAnimationFrame(() => { 5232 new ScrollSnapExtensions(slider, { 5233 orientation: "horizontal", 5234 }); 5235 5236 }); 5237 } 5238 }; 5239 5240 requestAnimationFrame(() => { 5241 document.querySelectorAll( 5242 ` 5243 .pagebuilder-carousel 5244 ` 5245 ).forEach(element => { 5246 initSlider(element); 5247 }); 5248 }); 5249</script>
vendor: 1 bytes, line 5249
5249
5250<script> 5251 document.querySelectorAll('div[data-content-type="row"], div[data-content-type="column"]').forEach(el => { 5252 el.addEventListener('click', () => { 5253 const url = el.getAttribute('href'); 5254 const target = el.getAttribute('target'); 5255 5256 if (url) { 5257 if (target === '_blank') { 5258 window.open(url, '_blank'); 5259 } else { 5260 window.location.href = url; 5261 } 5262 } 5263 }); 5264 }); 5265</script>
5265 5266<div class="block block-customer-login-link" style="display: none;"> 5267 <div class="block-content" aria-labelledby="block-customer-login-heading"> 5268 <form class="form form-login" 5269 action="https://www.girav.nl/customer/index/sendLoginLink/" 5270 method="post" 5271 x-data="initCustomerLoginLinkForm()" 5272 @submit.prevent="submitForm()" 5273 id="form-email-login-link" 5274 data-mage-init='{"validation":{}}'> 5275 <input name="form_key" type="hidden" value="x2axT8CBZcoKxPKB" /> <fieldset class="fieldset login" data-hasrequired="* Verplichte velden"> 5276 <div class="field note">If you have an account, enter your email address to receive a password less login link.</div> 5277 <div class="field email required"> 5278 <label class="label" for="email"><span>E-mailadres</span></label> 5279 <div class="control"> 5280 <input name="email" value="" id="email-for-login-link" type="email" class="form-input w-full input-text" title="E-mailadres" data-mage-init='{"mage/trim-input":{}}' data-validate="{required:true, 'validate-email':true}"> 5281 </div> 5282 </div> 5283 <div class="w-full"> 5284 </div> 5285 <div class="actions-toolbar"> 5286 <div class="primary"> 5287 <button type="submit" class="action login primary" name="send" id="send-customer-login-link"> 5288 <span>Verzenden</span> 5289 </button> 5290 </div> 5291 </div> 5292 </fieldset> 5293 </form> 5294 </div> 5295</div>
5296<script> document.addEventListener('click', function (e){ 5297 if (e.target.classList.contains('customer-login-link') || e.target.parentElement.classList.contains('customer-login-link')) { 5298 customerLoginLinkForm(); 5299 } 5300 }); 5301 function initCustomerLoginLinkForm() { 5302 return { 5303 errors: 0, 5304 hasCaptchaToken: 0, 5305 displayErrorMessage: false, 5306 errorMessages: [], 5307 setErrorMessages(messages) { 5308 this.errorMessages = [messages] 5309 this.displayErrorMessage = this.errorMessages.length 5310 }, 5311 submitForm() { 5312 // do not rename form - it is the expected name in the child block output 5313 const form = document.querySelector('#form-email-login-link'); 5314 5315 if (this.errors === 0) { 5316 form.submit(); 5317 } 5318 } 5319 } 5320 }</script>
vendor: 1 bytes, line 5320
5320
5321<script> 5322 let SnapSlider = class { 5323 constructor(el, { 5324 labelSepparator = 'of', 5325 autoPager, 5326 groupPager 5327 } = {}) { 5328 this.el = el; 5329 this.track = this.el.querySelector("[data-track]"); 5330 if (!this.track) { 5331 console.warn( 5332 "No Slider track defined, reverting back to CSS slider.\nPlease create a wrapper for your slides with the attribute data-track", 5333 this.el 5334 ); 5335 return; 5336 } 5337 this.initialLoad = true; 5338 this.slides = []; 5339 this.inViewObserver; 5340 this.mutationObserver; 5341 this.resizeObserver; 5342 this.pager = this.el.querySelector("[data-pager]"); 5343 this.navBtns = Array.from( 5344 this.el.querySelectorAll("[data-next], [data-prev]") 5345 ); 5346 this.slideLabelSepparator = this.el.dataset.slideLabelSepparator || labelSepparator; 5347 this.useAutoPager = autoPager || this.el.hasAttribute("data-auto-pager") || false; 5348 this.useGroupPager = groupPager || this.el.hasAttribute("data-group-pager") || false; 5349 this.sliderLabel = this.el.hasAttribute("aria-label") && this.el.getAttribute("aria-label").toLowerCase().trim().replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, ""); 5350 this.sliderId = this.el.id || this.sliderLabel || "slider"; 5351 this.markerIdName = "data-target-id"; 5352 this.pagerClasses = this.el.dataset.pagerClass || "snap-pager"; 5353 this.markerClasses = this.el.dataset.markerClass || "snap-marker"; 5354 this.init(); 5355 } 5356 init() { 5357 this.setupSlides(); 5358 this.setupNav(); 5359 if (this.useAutoPager) { 5360 this.createPager(); 5361 } else { 5362 this.setupPager(); 5363 } 5364 this.setupObservers(); 5365 this.setupMutationObserver(); 5366 this.setupResizeObserver(); 5367 this.el.addEventListener("click", this.eventHandler.bind(this)); 5368 this.el.addEventListener("keydown", this.eventHandler.bind(this)); 5369 } 5370 destroy() { 5371 this.inViewObserver?.disconnect(); 5372 this.mutationObserver?.disconnect(); 5373 this.resizeObserver?.disconnect(); 5374 this.el.removeEventListener("click", this.eventHandler.bind(this)); 5375 this.el.removeEventListener("keydown", this.eventHandler.bind(this)); 5376 } 5377 roundUpIfGreaterThan(number, min = 8) { 5378 const decimalPart = number - Math.floor(number); 5379 return decimalPart >= min ? Math.ceil(number) : Math.floor(number); 5380 } 5381 getInViewItems() { 5382 const inViewSlides = this.track.querySelectorAll("[data-in-view]"); 5383 const firstInViewSlide = inViewSlides[0] || null; 5384 const lastInViewSlide = inViewSlides[inViewSlides.length - 1] || null; 5385 const isAtStart = firstInViewSlide === this.slides[0]; 5386 const isAtEnd = lastInViewSlide === this.slides[this.slides.length - 1]; 5387 return { 5388 inViewSlides, 5389 totalInViewSlides: inViewSlides.length, 5390 firstInViewSlide, 5391 lastInViewSlide, 5392 isAtStart, 5393 isAtEnd, 5394 hasNoOverflow: isAtStart && isAtEnd 5395 }; 5396 } 5397 groupPagerMarkers() { 5398 if (this.slides.length === 0 || !this.pager || !this.useGroupPager) return; 5399 const totalVisibleSlides = this.roundUpIfGreaterThan( 5400 this.track.offsetWidth / this.slides[0].offsetWidth 5401 ); 5402 const markers = Array.from(this.pager.querySelectorAll("a, button")); 5403 markers.forEach((marker, index) => { 5404 marker.style.display = index % totalVisibleSlides === 0 ? null : "none"; 5405 }); 5406 } 5407 handleInView(entries) { 5408 entries.forEach((entry) => { 5409 const marker = this.pager && (this.pager.querySelector(`[href="#${entry.target.id}"]`) || this.pager.querySelector( 5410 `[${this.markerIdName}="${entry.target.id}"]` 5411 )); 5412 entry.target.toggleAttribute("data-in-view", entry.isIntersecting); 5413 entry.target.toggleAttribute("inert", !entry.isIntersecting); 5414 marker?.setAttribute("aria-current", entry.isIntersecting); 5415 marker?.setAttribute("tabindex", entry.isIntersecting ? "0" : "-1"); 5416 }); 5417 const { 5418 isAtStart, 5419 isAtEnd, 5420 hasNoOverflow 5421 } = this.getInViewItems(); 5422 this.navBtns.forEach((btn) => { 5423 if (btn.hasAttribute("data-next")) { 5424 btn.style.visibility = hasNoOverflow ? "hidden" : null; 5425 isAtEnd ? btn.setAttribute("disabled", "") : btn.removeAttribute("disabled"); 5426 } 5427 if (btn.hasAttribute("data-prev")) { 5428 btn.style.visibility = hasNoOverflow ? "hidden" : null; 5429 isAtStart ? btn.setAttribute("disabled", "") : btn.removeAttribute("disabled"); 5430 } 5431 }); 5432 if (this.pager) { 5433 this.pager.style.visibility = hasNoOverflow ? "hidden" : null; 5434 } 5435 if (!this.initialLoad) { 5436 this.el.dispatchEvent( 5437 new CustomEvent("slideChange", { 5438 detail: this.getInViewItems() 5439 }) 5440 ); 5441 } else { 5442 this.initialLoad = false;
5443 } 5444 if (document.activeElement.parentElement.hasAttribute("data-pager")) { 5445 const activeItems = this.pager.querySelectorAll('[tabindex="0"]'); 5446 if (activeItems.length) { 5447 activeItems[0].focus({ preventScroll: true }); 5448 } 5449 } 5450 } 5451 getSlides() { 5452 if (!this.track) return []; 5453 return Array.from(this.track.children).filter( 5454 (child) => child.tagName.toLowerCase() !== "template" && child.tagName.toLowerCase() !== "style" && child.tagName.toLowerCase() !== "script" 5455 ); 5456 } 5457 refreshSlides() { 5458 this.initialLoad = true; 5459 this.slides = this.getSlides(); 5460 this.setupSlides(); 5461 if (this.useAutoPager) { 5462 this.createPager(); 5463 } else { 5464 this.setupPager(); 5465 } 5466 this.groupPagerMarkers(); 5467 this.setupObservers(); 5468 } 5469 setupSlides() { 5470 this.slides = this.getSlides(); 5471 this.slides.forEach((slide, index) => { 5472 const totalSlides = this.slides.length; 5473 const currentSlide = index + 1; 5474 const existingLabel = slide.getAttribute("aria-label") || ""; 5475 const isImage = slide.tagName.toLowerCase() === "img" || slide.tagName.toLowerCase() === "picture"; 5476 const slideLabelTag = isImage ? "alt" : "aria-label"; 5477 const hasAutoLabel = existingLabel.startsWith( 5478 `${currentSlide} ${this.slideLabelSepparator} ` 5479 ); 5480 if (!slide.hasAttribute("id")) { 5481 slide.setAttribute( 5482 "id", 5483 `${this.sliderId}-item-${currentSlide}` 5484 ); 5485 } 5486 if (!slide.hasAttribute(slideLabelTag) || slide.getAttribute(slideLabelTag) === "" || hasAutoLabel) { 5487 slide.setAttribute( 5488 slideLabelTag, 5489 `${currentSlide} ${this.slideLabelSepparator} ${totalSlides}` 5490 ); 5491 } 5492 if (slide.tagName.toLowerCase() === "div" && !slide.hasAttribute("role")) { 5493 slide.setAttribute("role", "group"); 5494 } 5495 if (this.pager && !isImage) { 5496 slide.setAttribute("role", "tabpanel"); 5497 } 5498 if (slide.getAttribute("role") === "group") { 5499 slide.setAttribute("aria-roledescription", "item"); 5500 } 5501 }); 5502 if (!this.el.hasAttribute("role") && this.el.tagName !== "SECTION") { 5503 this.el.setAttribute("role", "region"); 5504 } 5505 if (!this.el.hasAttribute("aria-roledescription")) { 5506 this.el.setAttribute("aria-roledescription", "carousel"); 5507 } 5508 this.track.setAttribute("tabindex", 0); 5509 this.track.setAttribute("aria-live", "polite"); 5510 } 5511 setupNav() { 5512 this.navBtns.forEach((btn) => { 5513 btn.setAttribute("disabled", ""); 5514 btn.removeAttribute("hidden"); 5515 btn.classList.remove("invisible"); 5516 btn.style.visibility = null; 5517 }); 5518 } 5519 createPager() { 5520 const newPager = document.createElement("nav"); 5521 newPager.setAttribute("data-pager", ""); 5522 newPager.setAttribute("role", "tablist"); 5523 newPager.classList.add(...this.pagerClasses.split(" ")); 5524 this.slides.forEach((slide, index) => { 5525 const marker = document.createElement("button"); 5526 const slideId = slide.id || `${this.sliderId}-item-${index + 1}`; 5527 marker.setAttribute(this.markerIdName, slideId); 5528 marker.classList.add(...this.markerClasses.split(" ")); 5529 this.setupPagerMarker(marker, index); 5530 newPager.appendChild(marker); 5531 if (slide.tagName.toLowerCase() !== "img" && slide.tagName.toLowerCase() !== "picture") { 5532 slide.removeAttribute("aria-roledescription"); 5533 slide.setAttribute("role", "tabpanel"); 5534 } 5535 }); 5536 if (this.pager) { 5537 this.pager.setAttribute("role", "tablist"); 5538 this.pager.replaceChildren(...newPager.children); 5539 } else { 5540 this.track.after(newPager); 5541 this.pager = this.el.querySelector("[data-pager]"); 5542 } 5543 } 5544 setupPager() { 5545 if (!this.pager) return; 5546 this.pager.setAttribute("role", "tablist"); 5547 const items = Array.from(this.pager.querySelectorAll("a, button"));
5548 items.forEach((marker, index) => this.setupPagerMarker(marker, index)); 5549 } 5550 setupPagerMarker(marker, index) { 5551 const markerId = marker.getAttribute("href")?.slice(1) || marker.getAttribute(this.markerIdName); 5552 const slideId = markerId || `${this.sliderId}-item-${index + 1}`; 5553 if (!markerId) { 5554 marker.setAttribute(this.markerIdName, slideId); 5555 } 5556 marker.setAttribute("role", "tab"); 5557 marker.setAttribute("aria-controls", slideId); 5558 marker.setAttribute("aria-posinset", index + 1); 5559 marker.setAttribute("aria-setsize", this.slides.length); 5560 marker.setAttribute("tabindex", "-1"); 5561 if (!marker.hasAttribute("aria-label")) { 5562 marker.setAttribute("aria-label", `Slide ${index + 1}`); 5563 } 5564 } 5565 setupObservers() { 5566 if (this.inViewObserver) { 5567 this.inViewObserver.disconnect(); 5568 } 5569 this.inViewObserver = new IntersectionObserver( 5570 this.handleInView.bind(this), { 5571 root: this.track, 5572 threshold: 0.8 5573 } 5574 ); 5575 this.slides.forEach((slide) => this.inViewObserver.observe(slide)); 5576 } 5577 setupMutationObserver() { 5578 this.mutationObserver = new MutationObserver( 5579 this.refreshSlides.bind(this) 5580 ); 5581 this.mutationObserver.observe(this.track, { 5582 childList: true, 5583 subtree: false 5584 }); 5585 } 5586 setupResizeObserver() { 5587 this.resizeObserver = new ResizeObserver( 5588 this.groupPagerMarkers.bind(this) 5589 ); 5590 this.resizeObserver.observe(this.el); 5591 } 5592 goToSlideDir(dir = "next") { 5593 const { 5594 firstInViewSlide, 5595 lastInViewSlide 5596 } = this.getInViewItems(); 5597 const isPrev = dir === "prev"; 5598 let targetSlide = isPrev ? firstInViewSlide?.previousElementSibling : lastInViewSlide?.nextElementSibling; 5599 if (!targetSlide) return; 5600 if (targetSlide.tagName.toLowerCase() === "template") { 5601 targetSlide = isPrev ? targetSlide?.previousElementSibling : targetSlide?.nextElementSibling; 5602 } 5603 targetSlide.scrollIntoView({ block: "nearest", inline: isPrev ? "end" : "start" }); 5604 } 5605 pagerToSlide(event) { 5606 if (!event.target.closest("[data-pager]")) return; 5607 const marker = event.target.closest("a, button"); 5608 if (!marker) return; 5609 event.preventDefault(); 5610 const slideId = marker.getAttribute("href")?.slice(1) || marker.getAttribute(this.markerIdName); 5611 const targetSlide = this.track.querySelector(`#${slideId}`); 5612 targetSlide?.scrollIntoView({ block: "nearest", inline: "start" }); 5613 } 5614 eventHandler(event) { 5615 const target = event.target.closest( 5616 "[data-next], [data-prev], [data-pager]" 5617 ); 5618 if (!target) return; 5619 if (event.type === "click") { 5620 if (target.hasAttribute("data-next")) { 5621 this.goToSlideDir("next"); 5622 } else if (target.hasAttribute("data-prev")) { 5623 this.goToSlideDir("prev"); 5624 } else if (target.closest("[data-pager]")) { 5625 this.pagerToSlide(event); 5626 } 5627 } 5628 if (event.type === "keydown" && target.closest("[data-pager]")) { 5629 if (event.key === "ArrowRight") { 5630 this.goToSlideDir("next"); 5631 } else if (event.key === "ArrowLeft") { 5632 this.goToSlideDir("prev"); 5633 } 5634 } 5635 } 5636 }; 5637 5638 (() => { 5639 function alpineSnapSlider(Alpine) { 5640 Alpine.directive("snap-slider", (el, { 5641 modifiers 5642 }, { 5643 cleanup 5644 }) => { 5645 const autoPager = modifiers.includes("auto-pager");
5646 const groupPager = modifiers.includes("group-pager"); 5647 const slider = new SnapSlider(el, { 5648 autoPager, 5649 groupPager 5650 }); 5651 cleanup(() => { 5652 slider.destroy(); 5653 }); 5654 }); 5655 } 5656 5657 document.addEventListener("alpine:init", () => { 5658 window.Alpine.plugin(alpineSnapSlider); 5659 }); 5660 })(); 5661 //# sourceURL=alpine-snap-slider.js 5662</script>
5662 5663
5664<script> 5665 (() => { 5666 // src/dialog.js 5667 function dialog_default(Alpine) { 5668 Alpine.directive("htmldialog", fylgjaAlpineDialog); 5669 function fylgjaAlpineDialog(el, { expression, modifiers }, { evaluateLater, cleanup }) { 5670 const evaluate = expression.length ? evaluateLater(expression) : () => {}; 5671 const canEvaluate = expression.length > 0; 5672 const lockPageScroll = modifiers.includes("noscroll"); 5673 const closeBy = el.getAttribute("closeby") || modifierValue(modifiers, "closeby", "closerequest"); 5674 el.style.display = null; 5675 el.style.length === 0 && el.removeAttribute("style"); 5676 if (el._x_isShown) { 5677 open(); 5678 } 5679 const closeBySupported = (() => { 5680 return "closedBy" in HTMLDialogElement.prototype; 5681 })(); 5682 function scrollLock(use = true) { 5683 document.body.style.overflow = use ? "hidden" : ""; 5684 } 5685 function dialogSubmit(event) { 5686 if (event.target.getAttribute("method") === "dialog" || event.submitter?.getAttribute("formmethod") === "dialog") { 5687 event.preventDefault(); 5688 evaluate(); 5689 } 5690 } 5691 function escapeDialog(event) { 5692 if (event.key !== "Escape") return; 5693 event.preventDefault(); 5694 if (closeBy === "none") return; 5695 evaluate(); 5696 } 5697 function handleCloseByEvent(event) { 5698 if (event.target !== el) return; 5699 const rect = el.getBoundingClientRect(); 5700 const isInDialog = rect.top <= event.clientY && event.clientY <= rect.top + rect.height && rect.left <= event.clientX && event.clientX <= rect.left + rect.width; 5701 if (!isInDialog) { 5702 if (closeBy === "any") { 5703 if (closeBySupported) { 5704 event.preventDefault(); 5705 } 5706 evaluate(); 5707 } 5708 } 5709 } 5710 function handleCloseEvent() { 5711 evaluate(); 5712 } 5713 function open() { 5714 if (el.hasAttribute("open")) return; 5715 el.showModal(); 5716 scrollLock(lockPageScroll); 5717 } 5718 function close() { 5719 if (!el.hasAttribute("open")) return; 5720 el.close(); 5721 scrollLock(false); 5722 } 5723 el._x_doShow = () => open(); 5724 el._x_doHide = () => close(); 5725 el.addEventListener("keydown", escapeDialog); 5726 el.addEventListener("submit", dialogSubmit); 5727 el.addEventListener("click", handleCloseByEvent); 5728 el.addEventListener("cancel", handleCloseEvent); 5729 cleanup(() => { 5730 el.removeEventListener("keydown", escapeDialog); 5731 el.removeEventListener("submit", dialogSubmit); 5732 el.removeEventListener("click", handleCloseByEvent); 5733 el.removeEventListener("cancel", handleCloseEvent); 5734 scrollLock(false); 5735 }); 5736 } 5737 } 5738 function modifierValue(modifiers, key, fallback) { 5739 if (modifiers.indexOf(key) === -1) return fallback; 5740 const rawValue = modifiers[modifiers.indexOf(key) + 1]; 5741 if (!rawValue) return fallback; 5742 if (key === "closeby") { 5743 const allowedValues = ["auto", "none", "closerequest", "any"]; 5744 const options = allowedValues.join(", "); 5745 if (!allowedValues.includes(rawValue)) { 5746 console.warn( 5747 `"${rawValue}" is not one of the allowed values for closeby: ${options}` 5748 ); 5749 return fallback; 5750 } 5751 } 5752 return rawValue; 5753 } 5754 5755 // src/cdn.js 5756 document.addEventListener("alpine:init", () => { 5757 window.Alpine.plugin(dialog_default); 5758 }); 5759 })(); 5760 //# sourceURL=alpine-htmldialog.js 5761</script>
5761 5762
5763<script> 5764 (() => { 5765 function src_default(Alpine) { 5766 Alpine.directive("intersect", Alpine.skipDuringClone((el, { value, expression, modifiers }, { evaluateLater, cleanup }) => { 5767 let evaluate = evaluateLater(expression); 5768 let options = { 5769 rootMargin: getRootMargin(modifiers), 5770 threshold: getThreshold(modifiers) 5771 }; 5772 let observer = new IntersectionObserver((entries) => { 5773 entries.forEach((entry) => { 5774 if (entry.isIntersecting === (value === "leave")) 5775 return; 5776 evaluate(); 5777 modifiers.includes("once") && observer.disconnect(); 5778 }); 5779 }, options); 5780 observer.observe(el); 5781 cleanup(() => { 5782 observer.disconnect(); 5783 }); 5784 })); 5785 } 5786 function getThreshold(modifiers) { 5787 if (modifiers.includes("full")) 5788 return 0.99; 5789 if (modifiers.includes("half")) 5790 return 0.5; 5791 if (!modifiers.includes("threshold")) 5792 return 0; 5793 let threshold = modifiers[modifiers.indexOf("threshold") + 1]; 5794 if (threshold === "100") 5795 return 1; 5796 if (threshold === "0") 5797 return 0; 5798 return Number(`.${threshold}`); 5799 } 5800 function getLengthValue(rawValue) { 5801 let match = rawValue.match(/^(-?[0-9]+)(px|%)?$/); 5802 return match ? match[1] + (match[2] || "px") : void 0; 5803 } 5804 function getRootMargin(modifiers) { 5805 const key = "margin"; 5806 const fallback = "0px 0px 0px 0px"; 5807 const index = modifiers.indexOf(key); 5808 if (index === -1) 5809 return fallback; 5810 let values = []; 5811 for (let i = 1; i < 5; i++) { 5812 values.push(getLengthValue(modifiers[index + i] || "")); 5813 } 5814 values = values.filter((v) => v !== void 0); 5815 return values.length ? values.join(" ").trim() : fallback; 5816 } 5817 5818 document.addEventListener("alpine:init", () => { 5819 window.Alpine.plugin(src_default); 5820 }); 5821 })(); 5822 //# sourceURL=alpine-intersect.js 5823</script>
5823 5824
5825<script> 5826 for (const [selector, deferUntil] of Object.entries({".product-slider section[x-data]:not([x-data] [x-data])":"intersect",".product-info [x-data]:not([x-data] [x-data])":"intersect","#filters-content [x-data]:not([x-data] [x-data])":"intersect","#review_form":"intersect","section[x-data^=initRecentlyViewedProductsComponent]":"intersect","div[x-data^=initBundleOptions]":"intersect","#product_addtocart_form [x-data]:not([x-data] [x-data])":"intersect","#notice-cookie-block":"idle"})) { 5827 document.querySelectorAll(selector).forEach(el => el.setAttribute('x-defer', `${deferUntil}`)); 5828 } 5829 //# sourceURL=alpine-defer-rules.js 5830</script>
vendor: 1 bytes, line 5830
5830
5831<script> 5832 (() => { 5833 const hasAlpine = new Promise(resolve => { 5834 window.addEventListener('alpine:initialized', resolve, {once: true, passive: true}); 5835 }); 5836 5837 const hasInteract = new Promise(resolve => { 5838 (events => { 5839 const onInteract = () => { 5840 resolve(); 5841 events.forEach(type => window.removeEventListener(type, onInteract)); 5842 } 5843 events.forEach(type => window.addEventListener(type, onInteract, {once: true, passive: true})) 5844 })(['touchstart', 'mouseover', 'wheel', 'scroll', 'keydown']) 5845 }); 5846 5847 const onIntersect = (el) => { 5848 return new Promise(resolve => { 5849 const observer = new IntersectionObserver(entries => { 5850 for (const entry of entries) { 5851 if (entry.isIntersecting) { 5852 observer.disconnect() 5853 resolve(); 5854 } 5855 } 5856 }, {}); 5857 observer.observe(el); 5858 }); 5859 } 5860 5861 function runComponent(el) { 5862 hasAlpine.then(() => { 5863 el.removeAttribute('x-ignore'); 5864 queueMicrotask(() => Alpine.initTree(el)); 5865 }); 5866 } 5867 5868 function initDeferredComponents() { 5869 document.querySelectorAll('[x-data][x-defer]').forEach(el => { 5870 el.setAttribute('x-ignore', ''); 5871 const deferUntil = (el.getAttribute('x-defer') || '').trim(); 5872 switch (deferUntil) { 5873 case 'interact': 5874 hasInteract.then(() => runComponent(el)); 5875 break; 5876 case 'intersect': 5877 onIntersect(el).then(() => runComponent(el)) 5878 break; 5879 case 'idle': 5880 window.requestIdleCallback 5881 ? window.requestIdleCallback(() => runComponent(el), {timeout: 4000}) 5882 : setTimeout(() => runComponent(el), 4000); 5883 break; 5884 case 'eager': 5885 runComponent(el); 5886 break; 5887 default: 5888 if (deferUntil.startsWith('event:') && deferUntil.length > 6) { 5889 window.addEventListener(deferUntil.substring(6), () => runComponent(el), {once: true, passive: true}); 5890 } 5891 } 5892 }); 5893 } 5894 5895 window.addEventListener('alpine:init', initDeferredComponents, {once: true, passive: true}); 5896 })(); 5897 //# sourceURL=alpine-defer.js 5898</script>
5898 5899
5900<script> 5901 (() => { 5902 // src/dialog.js 5903 function dialog_default(Alpine) { 5904 Alpine.directive("dialog", fylgjaAlpineDialog); 5905 function fylgjaAlpineDialog(el, { expression, modifiers }, { evaluateLater, cleanup }) { 5906 const evaluate = expression.length ? evaluateLater(expression) : () => { 5907 }; 5908 const lockPageScroll = modifiers.includes("noscroll"); 5909 el.style.display = null; 5910 el.hidden = false; 5911 el.style.length === 0 && el.removeAttribute("style"); 5912 function scrollLock(use = true) { 5913 document.body.style.overflow = use ? "hidden" : ""; 5914 } 5915 function escapeDialog(event) { 5916 if (event.key !== "Escape") 5917 return; 5918 event.preventDefault(); 5919 evaluate(); 5920 } 5921 function backdropDialog(event) { 5922 const rect = el.getBoundingClientRect(); 5923 const isInDialog = rect.top <= event.clientY && event.clientY <= rect.top + rect.height && rect.left <= event.clientX && event.clientX <= rect.left + rect.width; 5924 if (isInDialog) 5925 return; 5926 evaluate(); 5927 } 5928 el._x_doShow = () => { 5929 if (el.hasAttribute("open")) 5930 return; 5931 el.showModal(); 5932 document.addEventListener("keydown", escapeDialog); 5933 el.addEventListener("click", backdropDialog); 5934 scrollLock(lockPageScroll); 5935 }; 5936 el._x_doHide = () => { 5937 if (!el.hasAttribute("open")) 5938 return; 5939 el.close(); 5940 document.removeEventListener("keydown", escapeDialog); 5941 el.removeEventListener("click", backdropDialog); 5942 scrollLock(false); 5943 }; 5944 cleanup(() => { 5945 document.removeEventListener("keydown", escapeDialog); 5946 el.removeEventListener("click", backdropDialog); 5947 scrollLock(false); 5948 }); 5949 } 5950 } 5951 5952 // src/cdn.js 5953 document.addEventListener("alpine:init", () => { 5954 window.Alpine.plugin(dialog_default); 5955 }); 5956 })(); 5957</script>
5957 5958
5959<script type="module" 5960 src="https://www.girav.nl/static/version1790837059/frontend/Girav/hyva/nl_NL/Hyva_Theme/js/alpine3.min.js" 5961 defer 5962 crossorigin 5963></script>
vendor: 1 bytes, line 5963
5963
5964<script> 5965 document.addEventListener("alpine:init", () => { 5966 Alpine.data('hyvaCmsToggle', () => ({ 5967 open: false, 5968 notOpen() { 5969 return !this.open; 5970 }, 5971 show() { 5972 this.open = true 5973 }, 5974 hide() { 5975 this.open = false 5976 }, 5977 toggle() { 5978 this.open = !this.open 5979 } 5980 })) 5981 }); 5982</script>
5982 5983
5984<script> 5985 function dispatchMessages(messages, hideAfter) { 5986 const messagesEvent = new CustomEvent("messages-loaded", { 5987 detail: { 5988 messages: messages, 5989 hideAfter: hideAfter 5990 } 5991 }); 5992 5993 window.dispatchEvent(messagesEvent); 5994 } 5995 5996 if (typeof hyva === 'undefined' || (!hyva.getBrowserStorage || !hyva.getCookie || !hyva.setCookie)) { 5997 console.warn("Hyvä helpers are not loaded yet. Make sure they are included before this script"); 5998 } 5999 6000 (function( hyva, undefined ) { 6001 6002 hyva.initFormKey = () => { 6003 const inputSelector = 'input[name="form_key"]', 6004 formKey = hyva.getFormKey(); 6005 6006 Array.from(document.querySelectorAll(inputSelector)).map(function (input) { 6007 input.value = formKey 6008 }); 6009 } 6010 6011 hyva.initMessages = () => { 6012 try { 6013 const messages = hyva.getCookie('mage-messages'); 6014 window.mageMessages = messages ? JSON.parse(decodeURIComponent(messages).replace(/\+/g, ' ')) : []; 6015 6016 dispatchMessages(window.mageMessages); 6017 6018 // empty `mage-messages` cookie 6019 const skipSetDomain = true; 6020 hyva.setCookie('mage-messages','', -1, skipSetDomain); 6021 6022 } catch (error) { 6023 console.warn('Error parsing Cookie Messages:', error); 6024 } 6025 } 6026 6027 window.addEventListener('DOMContentLoaded', hyva.initFormKey); 6028 hyva.alpineInitialized(hyva.initMessages) 6029 6030 }( window.hyva = window.hyva || {} )); 6031 //# sourceURL=hyva-cookies.js 6032</script>
6032 6033
6034<script> 6035 (function() { 6036 const private_content_key = 'mage-cache-storage'; 6037 const private_content_expire_key = 'mage-cache-timeout'; 6038 const private_content_version_key = 'private_content_version'; 6039 const section_data_ids_key = 'section_data_ids'; 6040 const mage_cache_session_id_key = 'mage-cache-sessid'; 6041 const last_visited_store_key = 'last_visited_store'; 6042 6043 const ttl = 172800; 6044 6045 if (typeof hyva === 'undefined' || (!hyva.getBrowserStorage || !hyva.getCookie || !hyva.setCookie)) { 6046 console.warn("Hyvä helpers are not loaded yet. Make sure they are included before this script"); 6047 } 6048 6049 function loadSectionData () { 6050 const browserStorage = hyva.getBrowserStorage(); 6051 if (!browserStorage) { 6052 typeof window.dispatchMessages !== "undefined" && window.dispatchMessages( 6053 [{ 6054 type: "warning", 6055 text: "Please enable LocalStorage in your browser." 6056 }] 6057 ); 6058 return; 6059 } 6060 try { 6061 let isInvalid = false; 6062 6063 if (hyva.getCookie(last_visited_store_key) !== CURRENT_STORE_CODE) { 6064 isInvalid = true; 6065 } 6066 hyva.setCookie(last_visited_store_key, CURRENT_STORE_CODE, false, false); 6067 6068 if (!hyva.getCookie(mage_cache_session_id_key)) { 6069 isInvalid = true; 6070 browserStorage.removeItem(private_content_key); 6071 const skipSetDomain = true; 6072 const days = false; 6073 hyva.setCookie(mage_cache_session_id_key, true, days, skipSetDomain) 6074 } 6075 6076 const cookieVersion = hyva.getCookie(private_content_version_key); 6077 const storageVersion = browserStorage.getItem(private_content_version_key); 6078 6079 if (cookieVersion && !storageVersion || cookieVersion !== storageVersion) { 6080 isInvalid = true; 6081 } 6082 6083 const privateContentExpires = browserStorage.getItem(private_content_expire_key); 6084 if (privateContentExpires && new Date(privateContentExpires) < new Date()) { 6085 browserStorage.removeItem(private_content_key); 6086 } 6087 6088 if (isInvalid && cookieVersion) { 6089 fetchPrivateContent([]); 6090 } else if (cookieVersion && storageVersion && cookieVersion === storageVersion) { 6091 const privateContent = JSON.parse(browserStorage.getItem(private_content_key)); 6092 if ( 6093 privateContent && 6094 privateContentExpires && 6095 privateContent.cart && 6096 privateContent.customer 6097 ) { 6098 dispatchPrivateContent(privateContent); 6099 } else { 6100 fetchPrivateContent([]); 6101 } 6102 } else { 6103 if (document.getElementById('default-section-data')) { 6104 const privateContent = JSON.parse(document.getElementById('default-section-data').innerText.trim()); 6105 dispatchPrivateContent(privateContent); 6106 } else { 6107 dispatchPrivateContent({}); 6108 } 6109 } 6110 6111 } catch (error) { 6112 console.warn('Error retrieving Private Content:', error); 6113 } 6114 } 6115 6116 hyva.alpineInitialized(loadSectionData) 6117 window.addEventListener('reload-customer-section-data', loadSectionData); 6118 6119 window.processSectionDataBeforeDispatch = window.processSectionDataBeforeDispatch || (data => data); 6120 6121 function dispatchPrivateContent(data) { 6122 6123 const privateContentEvent = new CustomEvent("private-content-loaded", { 6124 detail: { 6125 data: window.processSectionDataBeforeDispatch(data) 6126 } 6127 }); 6128 window.dispatchEvent(privateContentEvent); 6129 } 6130 6131 function fetchPrivateContent(sections) { 6132 fetch(`${BASE_URL}customer/section/load/?sections=${encodeURIComponent(sections.join(','))}`, { 6133 method: 'GET', 6134 headers: { 6135 'Content-Type': 'application/json', 6136 'X-Requested-With': 'XMLHttpRequest' 6137 } 6138 }) 6139 .then(response => response.ok && response.json()) 6140 .then( 6141 data => { 6142 if (data) { 6143 try { 6144 const browserStorage = hyva.getBrowserStorage(); 6145 6146 // merge new data preserving non-invalidated sections 6147 const oldSectionData = JSON.parse(browserStorage.getItem(private_content_key) || '{}') || {}; 6148 6149 if ((! data.cart || ! data.cart.cartId) && oldSectionData['checkout-data']) { 6150 delete oldSectionData['checkout-data']; 6151 } 6152 const newSectionData = Object.assign(oldSectionData, data); 6153 6154 dispatchPrivateContent(newSectionData); 6155 6156 // don't persist messages, they've been dispatched already 6157 if (newSectionData.messages && newSectionData.messages.messages ) { 6158 newSectionData.messages.messages = []; 6159 } 6160 6161 browserStorage.setItem(private_content_key, JSON.stringify(newSectionData)); 6162 6163 const expiresAt = new Date(Date.now() + (ttl * 1000)).toISOString(); 6164 browserStorage.setItem(private_content_expire_key, expiresAt); 6165 6166 const newCookieVersion = hyva.getCookie(private_content_version_key); 6167 browserStorage.setItem(private_content_version_key, newCookieVersion); 6168 6169 // We don't need the section_data_ids in Hyvä, but we store them for compatibility 6170 // with Luma Fallback. Otherwise, not all sections are loaded in Luma Checkout 6171 hyva.setCookie( 6172 section_data_ids_key, 6173 JSON.stringify( 6174 Object.keys(data).reduce((sectionDataIds, sectionKey) => { 6175 sectionDataIds[sectionKey] = data[sectionKey]['data_id']; 6176 return sectionDataIds; 6177 }, {}) 6178 ), 6179 false, 6180 true 6181 ); 6182 } catch (error) { 6183 console.warn("Couldn't store privateContent", error); 6184 } 6185 } 6186 } 6187 ) 6188 .catch(error => { 6189 console.warn("Couldn't fetch privateContent", error); 6190 }); 6191 } 6192 })(); 6193 //# sourceURL=hyva-private-content.js 6194</script>
vendor: 1 bytes, line 6194
6194
6195<script> 6196 (() => { 6197 document.addEventListener('submit', event => event.target.action = event.target.action.replace('%25uenc%25', hyva.getUenc())); 6198 })() 6199</script>
vendor: 1 bytes, line 6199
6199
6200<script> 6201 (events => { 6202 const dispatchUserInteractionEvent = () => { 6203 events.forEach(type => window.removeEventListener(type, dispatchUserInteractionEvent)) 6204 window.dispatchEvent(new Event('init-external-scripts')) 6205 }; 6206 events.forEach(type => window.addEventListener(type, dispatchUserInteractionEvent, {once: true, passive: true})) 6207 })(['touchstart', 'mousemove', 'wheel', 'scroll', 'keydown']); 6208 //# sourceURL=hyva-init-external-scripts.js 6209</script>
6209 6210
6211<script> 6212 function initConfigurableOptions(productId, optionConfig) { 6213 (() => { 6214 let products = Object.values(optionConfig.product_information); 6215 6216 for (let i = 0; i < products.length; i++) { 6217 const product = products[i]; 6218 if (product.qty > 0) { 6219 return; 6220 } 6221 } 6222 6223 document.querySelector("#product-addtocart-button").setAttribute("disabled", true); 6224 document.querySelector("#product-addtocart-button").innerHTML = "Product niet op voorraad"; 6225 })(); 6226 6227 function findPathParam(key) { 6228 const baseUrl = (BASE_URL.substr(0, 2) === '//' ? 'http:' : '') + BASE_URL; 6229 const baseUrlParts = (new URL(baseUrl)).pathname.replace(/\/$/, '').split('/'); 6230 const pathParts = window.location.pathname.split('/').slice(baseUrlParts.length + 3); 6231 for (let i = 0; i < pathParts.length; i += 2) { 6232 if (pathParts[i] === key && pathParts.length > i) { 6233 return pathParts[i + 1]; 6234 } 6235 } 6236 } 6237 6238 return { 6239 optionConfig, 6240 productId, 6241 itemId: (new URLSearchParams(window.location.search)).get('id') || findPathParam('id'), 6242 allowedAttributeOptions: [], 6243 selectedValues: [], 6244 init() { 6245 this.sendReloadPersonalization(); 6246 this.findAllowedAttributeOptions(); 6247 this.$nextTick(() => { 6248 if (typeof this.optionConfig.defaultValues === 'object') { 6249 for (const [optionId, value] of Object.entries(this.optionConfig.defaultValues)) { 6250 this.changeOption(optionId, value + ''); 6251 } 6252 } 6253 this.preselectSession(); 6254 }); 6255 6256 window.addEventListener('update-selected-size', () => { 6257 this.preselectSession(); 6258 6259 this.preselectUrlParameters(); 6260 }); 6261 }, 6262 findSimpleIndex() { 6263 this.productIndex = this.calculateSimpleIndexForPartialSelection(this.selectedValues); 6264 }, 6265 calculateSimpleIndexForPartialSelection(selectedValues) { 6266 if (selectedValues.length === 0) return 0; 6267 let productIndexIds = Object.keys(this.optionConfig.index); 6268 Object.keys(this.optionConfig.attributes).forEach((attribute) => { 6269 const productsWithAttributeMatch = selectedValues[attribute] ? 6270 productIndexIds.filter((productIndex) => { 6271 return this.optionConfig.index[productIndex][attribute] === this.selectedValues[attribute] 6272 }) : 6273 []; 6274 productIndexIds = productsWithAttributeMatch.length ? productsWithAttributeMatch : productIndexIds 6275 }) 6276 return productIndexIds[0]; 6277 }, 6278 calculateSimpleIndexForFullSelection(selectedValues) { 6279 const productIndexes = this.optionConfig.index; 6280 return Object.keys(productIndexes).find(productIndex => { 6281 const productCandidateOptions = productIndexes[productIndex]; 6282 6283 for (const productOption in productCandidateOptions) { 6284 if ( 6285 !selectedValues[productOption] || 6286 selectedValues[productOption] !== productCandidateOptions[productOption] 6287 ) { 6288 return false; 6289 } 6290 } 6291 return productIndex; 6292 }); 6293 }, 6294 productIndex: 0, 6295 findAllowedAttributeOptions() { 6296 this.allowedAttributeOptions = this.calculateAllowedAttributeOptions(this.selectedValues); 6297 }, 6298 calculateAllowedAttributeOptions(selectedValues) { 6299 const allAttributes = this.optionConfig.attributes; 6300 const allAttributesSorted = Object.values(allAttributes).sort((a, b) => { 6301 return a.position - b.position 6302 }); 6303 const productIndexes = this.optionConfig.index; 6304 let previousOption = false;
6305 let availableIndexes = Object.keys(productIndexes); 6306 6307 const newAllowedAttributeOptions = []; 6308 6309 allAttributesSorted.forEach(attribute => { 6310 if (previousOption && selectedValues[previousOption]) { 6311 availableIndexes = availableIndexes.filter(availableIndex => { 6312 return productIndexes[availableIndex][previousOption] === 6313 selectedValues[previousOption] 6314 }) 6315 } 6316 newAllowedAttributeOptions[attribute.id] = 6317 allAttributes[attribute.id].options.filter(option => { 6318 return !!option.products.find(product => { 6319 return availableIndexes.includes(product); 6320 }) 6321 }); 6322 previousOption = attribute.id; 6323 }); 6324 return newAllowedAttributeOptions; 6325 }, 6326 findAttributeByOptionId(optionId) { 6327 for (const attributeId in this.optionConfig.attributes) { 6328 const attributeOptions = this.optionConfig.attributes[attributeId].options || []; 6329 if (attributeOptions.find(option => option.id === optionId)) { 6330 return attributeId; 6331 } 6332 } 6333 }, 6334 getAllowedAttributeOptions(attributeId) { 6335 return this.allowedAttributeOptions[attributeId] || [] 6336 }, 6337 getProductIdsForOption(option) { 6338 const attributeId = this.findAttributeByOptionId(option.id); 6339 const allOptions = this.optionConfig.attributes[attributeId]; 6340 const opt = (allOptions && allOptions.options || []).find(o => o.id === option.id); 6341 return opt && opt.products ? 6342 opt.products : 6343 []; 6344 }, 6345 findProductIdsForPartialSelection(optionSelection) { 6346 const candidateProducts = Object.values(optionSelection).reduce((candidates, optionId) => { 6347 const newCandidates = this.getProductIdsForOption({ 6348 id: optionId 6349 }); 6350 return candidates === null ? 6351 newCandidates : 6352 candidates.filter(productId => newCandidates.includes(productId)); 6353 }, null); 6354 return candidateProducts || []; 6355 }, 6356 findCheapestProductForPartialSelection(optionSelection) { 6357 const candidateProducts = this.findProductIdsForPartialSelection(optionSelection); 6358 return candidateProducts.reduce((cheapest, simpleIdx) => { 6359 if (!this.optionConfig.optionPrices[cheapest]) return simpleIdx; 6360 const knownCheapestPrice = this.optionConfig.optionPrices[cheapest].finalPrice.amount; 6361 return knownCheapestPrice > this.optionConfig.optionPrices[simpleIdx].finalPrice.amount ? 6362 simpleIdx : 6363 cheapest; 6364 }, 0) 6365 }, 6366 findProductIdToUseForOptionPrice(option) { 6367 const attributeId = this.findAttributeByOptionId(option.id); 6368 const optionSelection = Object.assign({}, this.selectedValues, { 6369 [attributeId]: option.id 6370 }); 6371 const matchingSimpleIndex = this.calculateSimpleIndexForFullSelection(optionSelection); 6372 return matchingSimpleIndex || this.findCheapestProductForPartialSelection(optionSelection); 6373 }, 6374 getAttributeOptionLabel(option) { 6375 const optionProduct = this.findProductIdToUseForOptionPrice(option); 6376 if ((!optionProduct) || (optionProduct === this.productIndex)) { 6377 return option.label; 6378 } 6379 6380 const currentPrice = this.getOptionPriceAdjustmentBasePrice(); 6381 6382 if (this.optionConfig.optionPrices[optionProduct]) { 6383 const optionPrice = this.optionConfig.optionPrices[optionProduct].finalPrice.amount; 6384 if (optionPrice !== currentPrice) { 6385 return option.label + ' ' + hyva.formatPrice(optionPrice - currentPrice, true); 6386 } 6387 } 6388 return option.label; 6389 }, 6390 getOptionPriceAdjustmentBasePrice() { 6391 if (this.optionConfig.optionPrices[this.productIndex]) { 6392 return this.optionConfig.optionPrices[this.productIndex].finalPrice.amount 6393 } 6394 const cheapestForSelection = this.findCheapestProductForParti
6394alSelection(this.selectedValues); 6395 return this.optionConfig.optionPrices[cheapestForSelection] ? 6396 this.optionConfig.optionPrices[cheapestForSelection].finalPrice.amount : 6397 this.optionConfig.prices.finalPrice.amount; 6398 }, 6399 touchstartOptionLabel(optionId, event) { 6400 if ((navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPod/i))) { 6401 const value = document.getElementById(event.currentTarget.htmlFor).value; 6402 event.preventDefault(); 6403 this.changeOption(optionId, value); 6404 } 6405 }, 6406 changeOption(optionId, value, saveToSizeStorage = false) { 6407 if (value === '') { 6408 this.selectedValues = this.selectedValues.reduce((newSelection, val, opt) => { 6409 if (opt !== optionId) { 6410 newSelection[opt] = val; 6411 } 6412 return newSelection; 6413 }, []); 6414 } else { 6415 this.selectedValues[optionId] = value; 6416 } 6417 6418 if (saveToSizeStorage) { 6419 const attribute = this.optionConfig.attributes[optionId]; 6420 6421 if (attribute) { 6422 const storageKey = 'selected_size'; 6423 const stored = localStorage.getItem(storageKey); 6424 6425 const selection = stored 6426 ? JSON.parse(stored) 6427 : { 6428 selected_size: '', 6429 selected_length: '', 6430 size_attribute_code: 'filter_size', 6431 length_attribute_code: 'filter_length' 6432 }; 6433 6434 if (attribute.code === selection.size_attribute_code) { 6435 selection.selected_size = value; 6436 } 6437 6438 if (attribute.code === selection.length_attribute_code) { 6439 selection.selected_length = value; 6440 } 6441 6442 localStorage.setItem(storageKey, JSON.stringify(selection)); 6443 } 6444 } 6445 6446 this.findSimpleIndex(); 6447 this.findAllowedAttributeOptions(); 6448 this.updatePrices(); 6449 this.updateGallery(); 6450 this.removeCustomValidity(optionId); 6451 this.sendDataLayer(this.selectedValues); 6452 this.castStock(optionId, value); 6453 6454 window.dispatchEvent( 6455 new CustomEvent('configurable-selection-changed', { 6456 detail: { 6457 productId: this.productId, 6458 optionId: this.optionId, 6459 value: this.value, 6460 productIndex: this.productIndex, 6461 selectedValues: this.selectedValues, 6462 isSaleable: this.optionIsActive(optionId, value), 6463 } 6464 }) 6465 ); 6466 }, 6467 sendDataLayer(selectedValues) { 6468 const selectedAttributes = Object.keys(this.optionConfig.attributes).length; 6469 const selectedItems = Object.values(selectedValues).filter(Boolean).length; 6470 6471 if (selectedItems < selectedAttributes) { 6472 return; 6473 } 6474 6475 const optionId = this.getProductsArrayFromMapping(selectedValues); 6476 const variantId = this.getSku(optionId); 6477 6478 if (variantId) { 6479 this.sendReloadPersonalization(); 6480 6481 window.dataLayer = window.dataLayer || []; 6482 window.dataLayer.push({ 6483 event: 'view_variant', 6484 variant_id: variantId 6485 }); 6486 } 6487 }, 6488 sendReloadPersonalization() { 6489 window._sqzl = window._sqzl || []; 6490 window._sqzl.push({ 6491 "event": "ReloadPersonalization" 6492 }); 6493 }, 6494 getProductsArrayFromMapping(mapping) { 6495 const productArrays = []; 6496 for (const attributeId in mapping) { 6497 const optionId = mapping[attributeId]; 6498 const attribute = this.optionConfig.attributes[attributeId]; 6499 if (attribute && optionId) { 6500 const option = attribute.options.find((opt) => opt.id === optionId); 6501 if (option) { 6502 productArrays.push(option.products); 6503 } 6504 } 6505 } 6506 6507 if (productArrays.length === 0) { 6508 return null; 6509 } 6510 6511 for (const value of productArrays[0]) { 6512 if (productArrays.every((arr) => arr.includes(value))) { 6513 return value; 6514 } 6515 } 6516 6517 return null; 6518 }, 6519 6520 calculateIsMinimalPrice() { 6521 return ( 6522 this.selectedValues.filter(value => !!value).length < 6523 Object.keys(this.optionConfig.attributes).length 6524 ); 6525 }, 6526 getSku(optionId) { 6527 const sku = this.optionConfig.product_information[optionId]?.sku; 6528 return sku ?? null; 6529 }, 6530 getMatchingIds(attribute, value) { 6531 return Object.entries(this.optionConfig.index).map(([id, product]) => { 6532 if (product[attribute] === value) { 6533 return id; 6534 } 6535 }).filter(id => !!id); 6536 }, 6537 hasAvailableQuantity(attribute, value) { 6538 const matchingProductIds = this.getMatchingIds(attribute, value); 6539 6540 if (matchingProductIds.length === 0) { 6541 return false;
6542 } 6543 6544 for (productKey in this.optionConfig.product_information) { 6545 if (matchingProductIds.includes(productKey) && this.optionConfig.product_information[productKey].qty > 0) { 6546 return true; 6547 } 6548 } 6549 return false; 6550 }, 6551 removeCustomValidity(optionId) { 6552 const swatches = document.querySelectorAll('input[name="super_attribute[' + optionId + ']'); 6553 let countSelected = 0; 6554 swatches.forEach((swatch) => { 6555 if (swatch.checked) { 6556 countSelected++; 6557 } 6558 }); 6559 6560 if (countSelected === 0) { 6561 return; 6562 } 6563 6564 swatches.forEach((swatch) => { 6565 swatch.setCustomValidity(''); 6566 }); 6567 }, 6568 updatePrices() { 6569 const value = this.productIndex ? 6570 this.optionConfig.optionPrices[this.productIndex] : 6571 this.optionConfig.prices; 6572 window.dispatchEvent( 6573 new CustomEvent( 6574 "update-prices-" + this.productId, { 6575 detail: Object.assign( 6576 value, { 6577 isMinimalPrice: this.calculateIsMinimalPrice() 6578 } 6579 ) 6580 } 6581 ) 6582 ); 6583 }, 6584 updateGallery() { 6585 if (this.productIndex) { 6586 const images = this.optionConfig.images[this.productIndex]; 6587 images && window.dispatchEvent(new CustomEvent( 6588 "update-gallery", { 6589 detail: this.sortImagesByPosition(images) 6590 } 6591 )); 6592 } else { 6593 window.dispatchEvent(new Event("reset-gallery")); 6594 } 6595 }, 6596 sortImagesByPosition(images) { 6597 return images.sort((x, y) => { 6598 return x.position === y.position ? 0 : (parseInt(x.position) > parseInt(y.position) ? 1 : -1) 6599 }); 6600 }, 6601 onGetCartData(data) { 6602 this.preselectCartItems(data); 6603 this.preselectQuerystringItems(); 6604 this.preselectLocationHashItems(); 6605 }, 6606 preselectCartItems(data) { 6607 const cart = data && data.cart; 6608 if (cart && cart.items) { 6609 const cartItem = cart.items.find((item) => { 6610 return ( 6611 item.item_id === this.itemId && 6612 item.product_id === this.productId 6613 ) 6614 }); 6615 if (cartItem && cartItem.options && cartItem.options.length) { 6616 cartItem.options.map(option => { 6617 this.changeOption(option.option_id, option.option_value); 6618 }) 6619 } 6620 } 6621 }, 6622 preselectQuerystringItems() { 6623 const urlQueryParams = new URLSearchParams(window.location.search.replace('?', '')); 6624 Object.values(this.optionConfig.attributes).map(attribute => { 6625 urlQueryParams.get(attribute.code) && 6626 this.changeOption(attribute.id, urlQueryParams.get(attribute.code)); 6627 }); 6628 }, 6629 preselectSession() { 6630 if (window.customerSizeSettings) { 6631 const sizeSettings = window.customerSizeSettings.getMappedState() 6632 6633 Object.entries(sizeSettings).forEach(([index, value]) => { 6634 Object.values(this.optionConfig.attributes).map(attribute => { 6635 if (attribute.code === index) { 6636 if (this.hasAvailableQuantity(attribute.id, value)) { 6637 this.changeOption(attribute.id, value); 6638 } 6639 } 6640 }); 6641 }); 6642 } 6643 this.preselectUrlParameters(); 6644 }, 6645 preselectUrlParameters() { 6646 const params = new URL(window.location.href).searchParams; 6647 6648 if (!params.size) { 6649 return; 6650 } 6651 Object.values(this.optionConfig.attributes).map(attribute => { 6652 let optionId = null; 6653 const value = params.get(attribute.label.toLowerCase()) 6654 6655 Object.values(attribute.options).map(obj => { 6656 if (obj.label.toLowerCase().replace(/\s+/g, '') === value) { 6657 optionId = obj.id; 6658 } 6659 }) 6660 6661 if (optionId) { 6662 this.changeOption(attribute.id, optionId) 6663 } 6664 }) 6665 6666 }, 6667 preselectLocationHashItems() { 6668 const urlHashParams = new URLSearchParams(window.location.hash.replace('#', '')); 6669 Object.values(this.optionConfig.attributes).map(attribute => { 6670 urlHashParams.get(attribute.id) && 6671 this.changeOption(attribute.id, urlHashParams.get(attribute.id)); 6672 }); 6673 }, 6674 castStock(attributeId, optionId) { 6675 let stock = 0; 6676 6677 let selectedValues = [...this.selectedValues.entries()].filter((val, index, arr) => { 6678 if (!val[1]) { 6679 return false;
6680 } 6681 return val[0] !== attributeId; 6682 6683 }); 6684 6685 for (const productId in this.optionConfig.index) { 6686 if (this.optionConfig.index.hasOwnProperty.call(this.optionConfig.index, productId)) { 6687 const product = this.optionConfig.index[productId]; 6688 6689 if (selectedValues.length === 0) { 6690 if (product[attributeId] === optionId) { 6691 let product = this.optionConfig.product_information[productId]; 6692 6693 if (product.qty > 0) { 6694 stock = product.qty; 6695 break; 6696 } 6697 } 6698 } else { 6699 let optionsAreValid = true; 6700 6701 for (let i = 0; i < selectedValues.length; i++) { 6702 const val = selectedValues[i]; 6703 let optAttributeId = val[0]; 6704 let optOptionId = val[1]; 6705 6706 if (!val[1]) { 6707 continue; 6708 } 6709 6710 optionsAreValid = product[optAttributeId] === optOptionId; 6711 6712 if (!optionsAreValid) { 6713 break; 6714 } 6715 } 6716 if (product[attributeId] === optionId && optionsAreValid) { 6717 let product = this.optionConfig.product_information[productId]; 6718 6719 if (product.qty > 0) { 6720 stock = product.qty; 6721 break; 6722 } 6723 } 6724 } 6725 } 6726 } 6727 window.dispatchEvent( 6728 new CustomEvent( 6729 'update-stock-message', { 6730 detail: { 6731 stock: stock 6732 } 6733 } 6734 ) 6735 ); 6736 } 6737 } 6738 } 6739</script>
vendor: 1 bytes, line 6739
6739
6740<script> 6741 function initSwatchOptions(swatchConfig) { 6742 return { 6743 swatchConfig, 6744 getAttributeSwatchData(attributeId) { 6745 const swatchConfig = Object.assign({}, this.swatchConfig[attributeId]); 6746 swatchConfig['details'] = JSON.parse(swatchConfig['additional_data']); 6747 6748 return swatchConfig; 6749 }, 6750 getAllAttributeOptions(attributeId) { 6751 return ( 6752 this.optionConfig.attributes[attributeId] && 6753 this.optionConfig.attributes[attributeId].options 6754 ) || []; 6755 }, 6756 optionIsActive(attributeId, optionId, superAttributeIndex = 0) { 6757 // return true if a product with this option is in stock 6758 let item = this.getAllowedAttributeOptions(attributeId).find( 6759 option => option.id === optionId, 6760 ); 6761 6762 let targetProductId = null; 6763 let selectedValues = [...this.selectedValues.entries()].filter((val, index, arr) => { 6764 if (!val[1]) { return false; } 6765 return val[0] !== attributeId; 6766 6767 }); 6768 6769 if (superAttributeIndex) { 6770 for (const productId in this.optionConfig.index) { 6771 if (this.optionConfig.index.hasOwnProperty.call(this.optionConfig.index, productId)) { 6772 } 6773 } 6774 } 6775 6776 let targetStock = 0; 6777 for (const productId in this.optionConfig.index) { 6778 if (this.optionConfig.index.hasOwnProperty.call(this.optionConfig.index, productId)) { 6779 const product = this.optionConfig.index[productId]; 6780 6781 if (selectedValues.length === 0) { 6782 if (product[attributeId] === optionId) { 6783 let product = this.optionConfig.product_information[productId]; 6784 6785 if (product.qty > 0) { 6786 targetStock = product.qty; 6787 break; 6788 } 6789 } 6790 } 6791 else { 6792 let optionsAreValid = true; 6793 6794 for (let i = 0; i < selectedValues.length; i++) { 6795 const val = selectedValues[i]; 6796 let optAttributeId = val[0]; 6797 let optOptionId = val[1]; 6798 6799 if (!val[1]) { 6800 continue; 6801 } 6802 6803 optionsAreValid = product[optAttributeId] === optOptionId; 6804 6805 if (!optionsAreValid) { 6806 break; 6807 } 6808 } 6809 if (product[attributeId] === optionId && optionsAreValid) { 6810 let product = this.optionConfig.product_information[productId]; 6811 6812 if (product.qty > 0) { 6813 targetStock = product.qty; 6814 break; 6815 } 6816 } 6817 } 6818 } 6819 } 6820 6821 return targetStock !== 0; 6822 }, 6823 optionIsEnabled(attributeId, optionId, optionIndex = 0) { 6824 // return true if a product with this option is enabled 6825 6826 let currentValid = false; 6827 for (const productId in this.optionConfig.index) { 6828 if (this.optionConfig.index[productId][attributeId] == optionId) { 6829 currentValid = true; 6830 } 6831 } 6832 6833 let selectedValues = [...this.selectedValues.entries()].filter((val, index, arr) => { 6834 if (!val[1]) { return false; } 6835 ; 6836 if (val[0] === attributeId) { return false; } 6837 ; 6838 return true; 6839 }); 6840 6841 if (optionIndex === 0 || selectedValues.length === 0) { 6842 return currentValid; 6843 } 6844 6845 // Try to find one combination with set values and current item, if it's set, 6846 // it's an applicable combination of swatches, and it'll show 6847 const applicableItems = Object.values(this.optionConfig.index). 6848 filter(isApplicableItem). 6849 filter(item => item[attributeId] === optionId); 6850 6851 // Losse functie voor de isApplicable check 6852 function isApplicableItem(item) { 6853 return selectedValues.reduce((isApplicable, [key, value]) => { 6854 if (item[key] !== value) { 6855 return false;
6856 } 6857 6858 return isApplicable; 6859 }, true); 6860 } 6861 6862 return applicableItems.length > 0; 6863 }, 6864 mapSwatchTypeNumberToTypeCode(typeNumber) { 6865 switch ('' + typeNumber) { 6866 case '1': 6867 return 'color'; 6868 case '2': 6869 return 'image'; 6870 case '3': 6871 return 'empty'; 6872 case '0': 6873 default: 6874 return 'text'; 6875 } 6876 }, 6877 getTypeOfFirstOption(attributeId) { 6878 for (const optionId in this.swatchConfig[attributeId]) { 6879 const option = this.swatchConfig[attributeId][optionId]; 6880 if (typeof option.type !== 'undefined') { 6881 return this.mapSwatchTypeNumberToTypeCode(option.type); 6882 } 6883 } 6884 }, 6885 getVisualSwatchType(attributeId, targetOptionId) { 6886 // If a type configuration is present for the given option id, use it 6887 const config = this.swatchConfig[attributeId]; 6888 if (config[targetOptionId] && typeof config[targetOptionId].type !== 'undefined') { 6889 return this.mapSwatchTypeNumberToTypeCode(config[targetOptionId].type); 6890 } 6891 6892 // Otherwise - if no config is present for the target option - use the type of the first option 6893 // with a type property from the attribute, thus assuming its the same type as the target option. 6894 // (This edge case condition can occur on single swatch products if some options are not salable) 6895 return this.getTypeOfFirstOption(attributeId); 6896 }, 6897 getSwatchType(attributeId, optionId) { 6898 // Deserialize the attribute details the first time they are used 6899 if (this.swatchConfig[attributeId] && !this.swatchConfig[attributeId].details) { 6900 this.swatchConfig[attributeId] = this.getAttributeSwatchData(attributeId); 6901 } 6902 const type = this.swatchConfig[attributeId] && 6903 this.swatchConfig[attributeId].details && 6904 this.swatchConfig[attributeId].details.swatch_input_type || 6905 'empty'; 6906 return type === 'visual' ? this.getVisualSwatchType(attributeId, optionId) : type; 6907 }, 6908 isTextSwatch(attributeId, optionId) { 6909 return this.getSwatchType(attributeId, optionId) === 'text'; 6910 }, 6911 isVisualSwatch(attributeId, optionId) { 6912 const type = this.getSwatchType(attributeId, optionId); 6913 6914 return ['image', 'color'].includes(type); 6915 }, 6916 getSwatchBackgroundStyle(attributeId, optionId) { 6917 const config = this.getSwatchConfig(attributeId, optionId); 6918 const type = this.getSwatchType(attributeId, optionId); 6919 6920 if (type === 'color') { 6921 return 'background-color:' + config.value; 6922 } 6923 else if (type === 'image') { 6924 return 'background: #ffffff url(\'' + config.value + '\') no-repeat center'; 6925 } 6926 else { 6927 return ''; 6928 } 6929 }, 6930 getSwatchText(attributeId, optionId) { 6931 const config = this.getSwatchConfig(attributeId, optionId); 6932 return config.label || config.value || this.getOptionLabelFromOptionConfig(attributeId, optionId); 6933 }, 6934 setCustomMessage(element) { 6935 element.setCustomValidity('Selecteer je maat'); 6936 }, 6937 getOptionLabelFromOptionConfig(attributeId, optionId) { 6938 // Fallback if no value is present in swatchConfig data 6939 // Reference issue https://gitlab.hyva.io/hyva-themes/magento2-default-theme/-/issues/190 6940 const option = this.getAllAttributeOptions(attributeId).filter(option => option.id === optionId); 6941 return option && option[0] && option[0].label || ''; 6942 }, 6943 getSwatchConfig(attributeId, optionId) { 6944 return this.swatchConfig[attributeId] && this.swatchConfig[attributeId][optionId] 6945 ? this.swatchConfig[attributeId][optionId] 6946 : false;
6947 }, 6948 activeTooltipItem: false, 6949 tooltipPositionElement: false, 6950 isTooltipVisible() { 6951 return this.activeTooltipItem && 6952 this.getSwatchConfig( 6953 this.activeTooltipItem.attribute, 6954 this.activeTooltipItem.item, 6955 ); 6956 }, 6957 getTooltipImageStyle(attributeId, optionId) { 6958 const config = this.getSwatchConfig(attributeId, optionId); 6959 const type = this.getSwatchType(attributeId, optionId); 6960 6961 if (type === 'color') { 6962 return 'background-color:' + config.value + '; width: 110px; height: 90px;'; 6963 } 6964 else if (type === 'image') { 6965 return 'background: #ffffff url(\'' + config.thumb + 6966 '\') center center no-repeat; width: 110px; height: 90px;'; 6967 } 6968 else { 6969 return 'display:none'; 6970 } 6971 }, 6972 getTooltipPosition() { 6973 return this.tooltipPositionElement ? 6974 `top: ${this.tooltipPositionElement.offsetTop}px;` + 6975 `left: ${ 6976 this.tooltipPositionElement.offsetLeft - ( 6977 this.tooltipPositionElement.closest('.snap') && 6978 this.tooltipPositionElement.closest('.snap').scrollLeft || 6979 0 6980 ) 6981 }px;` : ''; 6982 }, 6983 getTooltipLabel() { 6984 return this.getSwatchConfig(this.activeTooltipItem.attribute, this.activeTooltipItem.item).label; 6985 }, 6986 deselectOption(attributeId, optionId) { 6987 if (this.selectedValues[attributeId] === optionId) { 6988 this.selectedValues[attributeId] = null; 6989 } 6990 }, 6991 focusedLabel: false, 6992 focusLabel(optionId) { 6993 this.focusedLabel = optionId; 6994 }, 6995 blurLabel() { 6996 this.focusedLabel = false; 6997 }, 6998 showSwatches: false, 6999 initShowSwatchesIntersect() { 7000 this.showSwatches = true; 7001 setTimeout(() => { 7002 window.dispatchEvent(new CustomEvent('review-form-options')); 7003 },0) 7004 }, 7005 }; 7006 } 7007</script>
vendor: 1 bytes, line 7007
7007
7008<script> 7009 'use strict'; 7010 7011 const grecaptchaV2LoadCallbacks = []; 7012 7013 function executeRecaptchaLoadCallbacks () { 7014 while (window.grecaptcha && grecaptchaV2LoadCallbacks.length > 0) { 7015 const callback = grecaptchaV2LoadCallbacks.pop(); 7016 typeof callback === 'string' ? window[callback]() : callback(); 7017 } 7018 } 7019 7020 (function() { 7021 const loadRecaptchaScript = (event) => { 7022 7023 if (window.grecaptcha || !event.target.form) { 7024 return; 7025 } 7026 7027 const url = 'https://www.google.com/recaptcha/api.js?onload=executeRecaptchaLoadCallbacks'; 7028 const siteKey = '6LeWP7cqAAAAAJYu\u002DYl_w0Bow2yZSVS1cHmllSm9'; 7029 const script = document.createElement('script'); 7030 script.type = 'text/javascript'; 7031 script.src = siteKey ? `${url}&render=${siteKey}` : `${url}&render=explicit`; 7032 script.async = true; 7033 document.head.appendChild(script); 7034 7035 script.addEventListener('load', () => { 7036 Array.from(document.querySelectorAll('button[data-recaptcha-btn]:disabled')).forEach(btn => btn.removeAttribute('disabled')); 7037 }); 7038 } 7039 7040 window.forceLoadRecaptchaScript = (form) => { 7041 loadRecaptchaScript({target: {form: form || 'dummy'}}); 7042 executeRecaptchaLoadCallbacks(); 7043 }; 7044 7045 document.body.addEventListener('input', loadRecaptchaScript, { once: true }); 7046 document.body.addEventListener('focus', loadRecaptchaScript, { once: true }); 7047 7048 }()); 7049 7050</script>
7050 7051 7052<!-- Global components -->
7053<script> 7054 function initColumnItem(defaultOpen = false) { 7055 return { 7056 open: defaultOpen, 7057 }; 7058 } 7059</script>
7059 7060
7061<script> 7062 function widgetContentReadmore(elements) { 7063 const targets = document.querySelectorAll(elements); 7064 if (!targets) return; 7065 7066 targets.forEach(el => { 7067 const readMoreText = 'Lees meer'; 7068 const readLessText = 'Lees minder'; 7069 if (el.offsetHeight <= 480) return; 7070 7071 el.classList.add('has-readmore'); 7072 el.setAttribute('aria-expanded', 'false'); 7073 7074 let readmoreBtn = document.createElement("button"); 7075 readmoreBtn.appendChild(document.createTextNode(readMoreText)); 7076 readmoreBtn.classList.add('btn', 'btn-readmore'); 7077 readmoreBtn.setAttribute('type', 'button'); 7078 7079 readmoreBtn.addEventListener('click', () => { 7080 const isOpen = el.getAttribute('aria-expanded') === 'true'; 7081 el.setAttribute('aria-expanded', !isOpen); 7082 readmoreBtn.innerText = isOpen ? readMoreText : readLessText; 7083 }); 7084 7085 el.appendChild(readmoreBtn); 7086 }); 7087 } 7088 7089 widgetContentReadmore('.big-content'); 7090</script>
7090 7091
7092<script> 7093 function pageBuilderReadMore(elements) { 7094 const targets = document.querySelectorAll(elements); 7095 if (!targets) return; 7096 7097 targets.forEach(el => { 7098 const readMoreText = 'Lees meer'; 7099 const readLessText = 'Lees minder'; 7100 if (el.offsetHeight <= 480) return; 7101 7102 el.classList.add('has-readmore prose-sm'); 7103 el.setAttribute('aria-expanded', 'false'); 7104 7105 let readmoreBtn = document.createElement("button"); 7106 readmoreBtn.appendChild(document.createTextNode(readMoreText)); 7107 readmoreBtn.classList.add('readmore-btn'); 7108 readmoreBtn.setAttribute('type', 'button'); 7109 7110 readmoreBtn.addEventListener('click', () => { 7111 const isOpen = el.getAttribute('aria-expanded') === 'true'; 7112 el.setAttribute('aria-expanded', !isOpen); 7113 readmoreBtn.innerText = isOpen ? readMoreText : readLessText; 7114 }); 7115 7116 el.appendChild(readmoreBtn); 7117 }); 7118 } 7119 7120 pageBuilderReadMore('.readmore'); 7121</script>
7121 7122
7123<script> 7124 window.setAjaxCart = (selectors = '#product_addtocart_form', recursive = true) => { 7125 const SIZE_NAME = 'super_attribute[274]'; 7126 const LENGTH_NAME = 'super_attribute[275]'; 7127 7128 const addToCartForms = document.querySelectorAll(selectors); 7129 const delay = parseInt('1000', 10); 7130 7131 if ((navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPod/i))) { 7132 addToCartForms.forEach(form => { 7133 document.getElementById("product-addtocart-button").click = (e) => { 7134 onAddToCartEvent(e, form); 7135 }; 7136 }); 7137 } 7138 7139 const handleProductListForm = (action, data, button) => { 7140 disableButton(button); 7141 7142 fetch(`${action}?ajax=true`, { 7143 method: 'POST', 7144 body: data, 7145 headers: { 7146 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8', 7147 'X-Requested-With': 'XMLHttpRequest' 7148 } 7149 }) 7150 .then(res => { 7151 return res.json(); 7152 }) 7153 .then(() => { 7154 window.dispatchEvent(new CustomEvent('reload-customer-section-data')); 7155 }) 7156 .catch(err => { 7157 window.dispatchEvent(new CustomEvent('product-addtocart-error')); 7158 7159 setMessage({ 7160 text: 'There was a problem adding your item to the cart.', 7161 type: 'error' 7162 }); 7163 }) 7164 .finally(() => { 7165 try { 7166 var messages = hyva.getCookie('mage-messages'); 7167 messages = messages ? JSON.parse(decodeURIComponent(messages).replace(/\+/g, ' ')) : []; 7168 document.cookie = 'mage-messages=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT;'; 7169 } catch (error) { 7170 console.warn('Error parsing Cookie Messages:', error); 7171 return; 7172 } 7173 7174 setTimeout(() => { 7175 button.classList.remove('is-loading'); 7176 button.removeAttribute("disabled"); 7177 7178 messages.forEach(message => { 7179 setMessage(message); 7180 }); 7181 }, delay); 7182 }); 7183 }; 7184 7185 const disableButton = (button) => { 7186 button.classList.add('is-loading'); 7187 button.setAttribute("disabled", true); 7188 }; 7189 7190 const onAddToCartEvent = (e, form) => { 7191 e.preventDefault(); 7192 const formData = new FormData(form); 7193 const data = new URLSearchParams(formData); 7194 const productListButton = form.querySelector('button[id^="product_item_list_addtocart_button_"]'); 7195 7196 if (productListButton) { 7197 handleProductListForm(form.action, data, productListButton); 7198 return; 7199 } 7200 7201 const button = form.querySelector('#product-addtocart-button') || document.getElementById('product-addtocart-button') 7202 const size = formData.get(SIZE_NAME); 7203 const length = formData.get(LENGTH_NAME); 7204 const fields = [...form.querySelectorAll('input.is-required')].map(el => el.getAttribute('name')).filter((v, i, self) => i == self.indexOf(v)); 7205 7206 for (let i = 0; i < fields.length; i++) { 7207 const field = fields[i]; 7208 7209 7210 if (!formData.get(field)) { 7211 setMessage({ 7212 text: 'De maat van dit product is niet (volledig) geselecteerd.', 7213 type: 'error' 7214 }); 7215 return; 7216 } 7217 7218 const form = document.getElementById('product_addtocart_form'); 7219 7220 if (form) { 7221 const y = form.getBoundingClientRect().top + window.pageYOffset - 50; 7222 window.scrollTo({ top: y, behavior: 'smooth' }); 7223 } 7224 } 7225 7226 disableButton(button); 7227 7228 // Overwrite the selected_size in localStorage before submitting the form 7229 setSizeAndLengthInStorage({ 7230 size, 7231 length 7232 }); 7233 7234 fetch(`${form.action}?ajax=true`, { 7235 method: 'POST', 7236 body: data, 7237 headers: { 7238 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8', 7239 'X-Requested-With': 'XMLHttpRequest' 7240 } 7241 }) 7242 .then(res => { 7243 if (!res.ok) { 7244 form.submit(); 7245 } 7246 7247 return res.json(); 7248 }) 7249 .then(data => { 7250 if (data.backUrl) { 7251 form.submit(); 7252 } 7253 7254 window.dispatchEvent(new CustomEvent('reload-customer-section-data')); 7255 }) 7256 .catch(err => { 7257 window.dispatchEvent(new CustomEvent('product-addtocart-error')); 7258 7259 setMessage({ 7260 text: 'There was a problem adding your item to the cart.', 7261 type: 'error' 7262 }); 7263 }) 7264 .finally(() => { 7265 try { 7266 var messages = hyva.getCookie('mage-messages'); 7267 messages = messages ? JSON.parse(decodeURIComponent(messages).replace(/\+/g, ' ')) : []; 7268 document.cookie = 'mage-messages=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT;'; 7269 } catch (error) { 7270 console.warn('Error parsing Cookie Messages:', error); 7271 return; 7272 } 7273 7274 setTimeout(() => { 7275 if (messages.length === 0) { 7276 window.dispatchEvent(new CustomEvent('product-addtocart-success')); 7277 } 7278 7279 button.classList.remove('is-loading'); 7280 button.removeAttribute("disabled"); 7281
7282 messages.forEach(message => { 7283 setMessage(message); 7284 }); 7285 }, delay); 7286 }); 7287 }; 7288 7289 addToCartForms.forEach(form => { 7290 // Keep reference to registered add-to-cart forms to prevent the firing of multiple identical add-to-cart events 7291 window.addToCartEventListenersAdded = window.addToCartEventListenersAdded ?? []; 7292 if (!window.addToCartEventListenersAdded.includes(form.id)) { 7293 form.addEventListener('submit', (e) => onAddToCartEvent(e, form)); 7294 window.addToCartEventListenersAdded.push(form.id); 7295 } 7296 }); 7297 } 7298 7299 /** 7300 * Set Message 7301 */ 7302 function setMessage(message) { 7303 typeof window.dispatchMessages !== "undefined" && window.dispatchMessages( 7304 [message], 5000 7305 ); 7306 } 7307 7308 function setSizeAndLengthInStorage({ 7309 size, 7310 length 7311 }) { 7312 if (!window.customerSizeSettings) { 7313 return; 7314 } 7315 7316 if (size) { 7317 window.customerSizeSettings.setSelectedSize(size); 7318 } 7319 7320 if (length) { 7321 window.customerSizeSettings.setSelectedLength(length); 7322 } 7323 7324 if (window.customerSizeSettings) { 7325 window.customerSizeSettings.storeState(); 7326 } 7327 } 7328 7329 /** Init on pageload */ 7330 window.setAjaxCart(); 7331</script>
7331 7332
7332<script type="text/plain" data-cookieconsent="marketing" defer src="https://www.dwin1.com/123050.js"></script>
7332 7333
7334<script> 7335 window.dataLayer = window.dataLayer || []; 7336 </script>
vendor: 1 bytes, line 7336
7336
7337<script type="text/json" id="default-section-data"> 7338 {"messages":[],"customer":[],"compare-products":[],"last-ordered-items":[],"cart":[],"directory-data":{"AT":{"name":"Oostenrijk","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"}}},"AU":{"name":"Australi\u00eb","regions":{"569":{"code":"ACT","name":"Australian Capital Territory"},"570":{"code":"NSW","name":"New South Wales"},"576":{"code":"NT","name":"Northern Territory"},"572":{"code":"QLD","name":"Queensland"},"573":{"code":"SA","name":"South Australia"},"574":{"code":"TAS","name":"Tasmania"},"571":{"code":"VIC","name":"Victoria"},"575":{"code":"WA","name":"Western Australia"}}},"BE":{"name":"Belgi\u00eb","regions":{"609":{"code":"VAN","name":"Antwerpen"},"610":{"code":"WBR","name":"Brabant wallon"},"611":{"code":"BRU","name":"Brussels-Capital Region"},"612":{"code":"WHT","name":"Hainaut"},"614":{"code":"WLG","name":"Li\u00e8ge"},"613":{"code":"VLI","name":"Limburg"},"615":{"code":"WLX","name":"Luxembourg"},"616":{"code":"WNA","name":"Namur"},"617":{"code":"VOV","name":"Oost-Vlaanderen"},"618":{"code":"VBR","name":"Vlaams-Brabant"},"619":{"code":"VWV","name":"West-Vlaanderen"}}},"BG":{"name":"Bulgarije","regions":{"747":{"code":"BG-01","name":"Blagoevgrad"},"748":{"code":"BG-02","name":"Burgas"},"754":{"code":"BG-08","name":"Dobrich"},"753":{"code":"BG-07","name":"Gabrovo"},"772":{"code":"BG-26","name":"Haskovo"},"755":{"code":"BG-09","name":"Kardzhali"},"756":{"code":"BG-10","name":"Kyustendil"},"757":{"code":"BG-11","name":"Lovech"},"758":{"code":"BG-12","name":"Montana"},"759":{"code":"BG-13","name":"Pazardzhik"},"760":{"code":"BG-14","name":"Pernik"},"761":{"code":"BG-15","name":"Pleven"},"762":{"code":"BG-16","name":"Plovdiv"},"763":{"code":"BG-17","name":"Razgrad"},"764":{"code":"BG-18","name":"Ruse"},"773":{"code":"BG-27","name":"Shumen"},"765":{"code":"BG-19","name":"Silistra"},"766":{"code":"BG-20","name":"Sliven"},"767":{"code":"BG-21","name":"Smolyan"},"768":{"code":"BG-22","name":"Sofia City"},"769":{"code":"BG-23","name":"Sofia Province"},"770":{"code":"BG-24","name":"Stara Zagora"},"771":{"code":"BG-25","name":"Targovishte"},"749":{"code":"BG-03","name":"Varna"},"750":{"code":"BG-04","name":"Veliko Tarnovo"},"751":{"code":"BG-05","name":"Vidin"},"752":{"code":"BG-06","name":"Vratsa"},"774":{"code":"BG-28","name":"Yambol"}}},"BR":{"name":"Brazili\u00eb","regions":{"485":{"code":"AC","name":"Acre"},"486":{"code":"AL","name":"Alagoas"},"487":{"code":"AP","name":"Amap\u00e1"},"488":{"code":"AM","name":"Amazonas"},"489":{"code":"BA","name":"Bahia"},"490":{"code":"CE","name":"Cear\u00e1"},"511":{"code":"DF","name":"Distrito Federal"},"491":{"code":"ES","name":"Esp\u00edrito Santo"},"492":{"code":"GO","name":"Goi\u00e1s"},"493":{"code":"MA","name":"Maranh\u00e3o"},"494":{"code":"MT","name":"Mato Grosso"},"495":{"code":"MS","name":"Mato Grosso do Sul"},"496":{"code":"MG","name":"Minas Gerais"},"497":{"code":"PA","name":"Par\u00e1"},"498":{"code":"PB","name":"Para\u00edba"},"499":{"code":"PR","name":"Paran\u00e1"},"500":{"code":"PE","name":"Pernambuco"},"501":{"code":"PI","name":"Piau\u00ed"},"502":{"code":"RJ","name":"Rio de Janeiro"},"503":{"code":"RN","name":"Rio Grande do Norte"},"504":{"code":"RS","name":"Rio Grande do Sul"},"505":{"code":"RO","name":"Rond\u00f4nia"},"506":{"code":"RR","name":"Roraima"},"507":{"code":"SC","name":"Santa Catarina"},"508":{"code":"SP","name":"S\u00e3o Paulo"},"509":{"code":"SE","name":"Sergipe"},"510":{"code":"TO","name":"Tocantins"}}},"CA":{"name":"Canada","regions":{"66":{"code":"AB","name":"Alberta"},"67":{"code":"BC","name":"British Columbia"},"68":{"code":"MB","name":"Manitoba"},"70":{"code":"NB","name":"New Brunswick"},"69":{"code":"NL","name":"Newfoundland and Labrador"},"72":{"code":"NT","name":"Northwest Territories"},"71":{"code":"NS","name":"Nova Scotia"},"73":{"code":"NU","name":"Nunavut"},"74":{"code":"ON","name":"Ontario"},"75":{"code":"PE","name":"Prince Edward Island"},"76":{"code":"QC","name":"Quebec"},"77":{"code":"SK","name":"Saskatchewan"},"78":{"code":"YT","name":"Yukon Territory"}}},"CY":{"name":"Cyprus"},"CZ":{"name":"Tsjechi\u00eb","regions":{"1117":{"code":"CZ-31","name":"Jiho\u010desk\u00fd kraj"},"1125":{"code":"CZ-64","name":"Jihomoravsk\u00fd kraj"},"1119":{"code":"CZ-41","name":"Karlovarsk\u00fd kraj"},"1124":{"code":"CZ-63","name":"Kraj Vyso\u010dina"},"1122":{"code":"CZ-52","name":"Kr\u00e1lov\u00e9hradeck\u00fd kraj"},"1121":{"code":"CZ-51","name":"Libereck\u00fd kraj"},"1128":{"code":"CZ-80","name":"Moravskoslezsk\u00fd kraj"}
7338,"1126":{"code":"CZ-71","name":"Olomouck\u00fd kraj"},"1123":{"code":"CZ-53","name":"Pardubick\u00fd kraj"},"1118":{"code":"CZ-32","name":"Plze\u0148sk\u00fd kraj"},"1115":{"code":"CZ-10","name":"Praha, Hlavn\u00ed m\u011bsto"},"1116":{"code":"CZ-20","name":"St\u0159edo\u010desk\u00fd kraj"},"1120":{"code":"CZ-42","name":"\u00dasteck\u00fd kraj"},"1127":{"code":"CZ-72","name":"Zl\u00ednsk\u00fd kraj"}}},"DE":{"name":"Duitsland","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"}}},"DK":{"name":"Denemarken","regions":{"791":{"code":"DK-84","name":"Hovedstaden"},"792":{"code":"DK-82","name":"Midtjylland"},"793":{"code":"DK-81","name":"Nordjylland"},"794":{"code":"DK-85","name":"Sj\u00e6lland"},"795":{"code":"DK-83","name":"Syddanmark"}}},"EE":{"name":"Estland","regions":{"340":{"code":"EE-37","name":"Harjumaa"},"341":{"code":"EE-39","name":"Hiiumaa"},"342":{"code":"EE-44","name":"Ida-Virumaa"},"344":{"code":"EE-51","name":"J\u00e4rvamaa"},"343":{"code":"EE-49","name":"J\u00f5gevamaa"},"346":{"code":"EE-59","name":"L\u00e4\u00e4ne-Virumaa"},"345":{"code":"EE-57","name":"L\u00e4\u00e4nemaa"},"348":{"code":"EE-67","name":"P\u00e4rnumaa"},"347":{"code":"EE-65","name":"P\u00f5lvamaa"},"349":{"code":"EE-70","name":"Raplamaa"},"350":{"code":"EE-74","name":"Saaremaa"},"351":{"code":"EE-78","name":"Tartumaa"},"352":{"code":"EE-82","name":"Valgamaa"},"353":{"code":"EE-84","name":"Viljandimaa"},"354":{"code":"EE-86","name":"V\u00f5rumaa"}}},"ES":{"name":"Spanje","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"}
7338,"179":{"code":"Vizcaya","name":"Vizcaya"},"180":{"code":"Zamora","name":"Zamora"},"181":{"code":"Zaragoza","name":"Zaragoza"}}},"FI":{"name":"Finland","regions":{"339":{"code":"Ahvenanmaa","name":"Ahvenanmaa"},"333":{"code":"Etel\u00e4-Karjala","name":"Etel\u00e4-Karjala"},"326":{"code":"Etel\u00e4-Pohjanmaa","name":"Etel\u00e4-Pohjanmaa"},"325":{"code":"Etel\u00e4-Savo","name":"Etel\u00e4-Savo"},"337":{"code":"It\u00e4-Uusimaa","name":"It\u00e4-Uusimaa"},"322":{"code":"Kainuu","name":"Kainuu"},"335":{"code":"Kanta-H\u00e4me","name":"Kanta-H\u00e4me"},"330":{"code":"Keski-Pohjanmaa","name":"Keski-Pohjanmaa"},"331":{"code":"Keski-Suomi","name":"Keski-Suomi"},"338":{"code":"Kymenlaakso","name":"Kymenlaakso"},"320":{"code":"Lappi","name":"Lappi"},"334":{"code":"P\u00e4ij\u00e4t-H\u00e4me","name":"P\u00e4ij\u00e4t-H\u00e4me"},"328":{"code":"Pirkanmaa","name":"Pirkanmaa"},"327":{"code":"Pohjanmaa","name":"Pohjanmaa"},"323":{"code":"Pohjois-Karjala","name":"Pohjois-Karjala"},"321":{"code":"Pohjois-Pohjanmaa","name":"Pohjois-Pohjanmaa"},"324":{"code":"Pohjois-Savo","name":"Pohjois-Savo"},"329":{"code":"Satakunta","name":"Satakunta"},"336":{"code":"Uusimaa","name":"Uusimaa"},"332":{"code":"Varsinais-Suomi","name":"Varsinais-Suomi"}}},"FR":{"name":"Frankrijk","regions":{"182":{"code":"1","name":"Ain"},"183":{"code":"2","name":"Aisne"},"184":{"code":"3","name":"Allier"},"185":{"code":"4","name":"Alpes-de-Haute-Provence"},"187":{"code":"6","name":"Alpes-Maritimes"},"188":{"code":"7","name":"Ard\u00e8che"},"189":{"code":"8","name":"Ardennes"},"190":{"code":"9","name":"Ari\u00e8ge"},"191":{"code":"10","name":"Aube"},"192":{"code":"11","name":"Aude"},"193":{"code":"12","name":"Aveyron"},"249":{"code":"67","name":"Bas-Rhin"},"194":{"code":"13","name":"Bouches-du-Rh\u00f4ne"},"195":{"code":"14","name":"Calvados"},"196":{"code":"15","name":"Cantal"},"197":{"code":"16","name":"Charente"},"198":{"code":"17","name":"Charente-Maritime"},"199":{"code":"18","name":"Cher"},"200":{"code":"19","name":"Corr\u00e8ze"},"201":{"code":"2A","name":"Corse-du-Sud"},"203":{"code":"21","name":"C\u00f4te-d'Or"},"204":{"code":"22","name":"C\u00f4tes-d'Armor"},"205":{"code":"23","name":"Creuse"},"261":{"code":"79","name":"Deux-S\u00e8vres"},"206":{"code":"24","name":"Dordogne"},"207":{"code":"25","name":"Doubs"},"208":{"code":"26","name":"Dr\u00f4me"},"273":{"code":"91","name":"Essonne"},"209":{"code":"27","name":"Eure"},"210":{"code":"28","name":"Eure-et-Loir"},"211":{"code":"29","name":"Finist\u00e8re"},"212":{"code":"30","name":"Gard"},"214":{"code":"32","name":"Gers"},"215":{"code":"33","name":"Gironde"},"250":{"code":"68","name":"Haut-Rhin"},"202":{"code":"2B","name":"Haute-Corse"},"213":{"code":"31","name":"Haute-Garonne"},"225":{"code":"43","name":"Haute-Loire"},"234":{"code":"52","name":"Haute-Marne"},"252":{"code":"70","name":"Haute-Sa\u00f4ne"},"256":{"code":"74","name":"Haute-Savoie"},"269":{"code":"87","name":"Haute-Vienne"},"186":{"code":"5","name":"Hautes-Alpes"},"247":{"code":"65","name":"Hautes-Pyr\u00e9n\u00e9es"},"274":{"code":"92","name":"Hauts-de-Seine"},"216":{"code":"34","name":"H\u00e9rault"},"217":{"code":"35","name":"Ille-et-Vilaine"},"218":{"code":"36","name":"Indre"},"219":{"code":"37","name":"Indre-et-Loire"},"220":{"code":"38","name":"Is\u00e8re"},"221":{"code":"39","name":"Jura"},"222":{"code":"40","name":"Landes"},"223":{"code":"41","name":"Loir-et-Cher"},"224":{"code":"42","name":"Loire"},"226":{"code":"44","name":"Loire-Atlantique"},"227":{"code":"45","name":"Loiret"},"228":{"code":"46","name":"Lot"},"229":{"code":"47","name":"Lot-et-Garonne"},"230":{"code":"48","name":"Loz\u00e8re"},"231":{"code":"49","name":"Maine-et-Loire"},"232":{"code":"50","name":"Manche"},"233":{"code":"51","name":"Marne"},"235":{"code":"53","name":"Mayenne"},"236":{"code":"54","name":"Meurthe-et-Moselle"},"237":{"code":"55","name":"Meuse"},"238":{"code":"56","name":"Morbihan"},"239":{"code":"57","name":"Moselle"},"240":{"code":"58","name":"Ni\u00e8vre"},"241":{"code":"59","name":"Nord"},"242":{"code":"60","name":"Oise"},"243":{"code":"61","name":"Orne"},"257":{"code":"75","name":"Paris"},"244":{"code":"62","name":"Pas-de-Calais"},"245":{"code":"63","name":"Puy-de-D\u00f4me"},"246":{"code":"64","name":"Pyr\u00e9n\u00e9es-Atlantiques"},"248":{"code":"66","name":"Pyr\u00e9n\u00e9es-Orientales"},"251":{"code":"69","name":"Rh\u00f4ne"},"253":{"code":"71","name":"Sa\u00f4ne-et-Loire"},"254":{"code":"72","name":"Sarthe"},"255":{"code":"73","name":"Savoie"},"259":{"code":"77","name":"Seine-et-Marne"},"258":{"code":"76","name":"Seine-Maritime"},"275":{"code":"93","name":"Seine-Saint-Denis"},"262":{"code":"80","name":"Somme"},"263":{"code":"81","name":"Tarn"},"264":{"code":"82","name":"Tarn-et-Garonne"},"272":{"code":"90","name":"Territoire-de-Belfort"},"277":{"code":"95","name":"Val-d'Oise"}
7338,"276":{"code":"94","name":"Val-de-Marne"},"265":{"code":"83","name":"Var"},"266":{"code":"84","name":"Vaucluse"},"267":{"code":"85","name":"Vend\u00e9e"},"268":{"code":"86","name":"Vienne"},"270":{"code":"88","name":"Vosges"},"271":{"code":"89","name":"Yonne"},"260":{"code":"78","name":"Yvelines"}}},"GR":{"name":"Griekenland","regions":{"833":{"code":"GR-69","name":"\u00c1gion \u00d3ros"},"820":{"code":"GR-A","name":"Anatolik\u00ed Makedon\u00eda kai Thr\u00e1ki"},"821":{"code":"GR-I","name":"Attik\u00ed"},"822":{"code":"GR-G","name":"Dytik\u00ed Ell\u00e1da"},"823":{"code":"GR-C","name":"Dytik\u00ed Makedon\u00eda"},"824":{"code":"GR-F","name":"Ion\u00eda N\u00edsia"},"825":{"code":"GR-D","name":"\u00cdpeiros"},"826":{"code":"GR-B","name":"Kentrik\u00ed Makedon\u00eda"},"827":{"code":"GR-M","name":"Kr\u00edti"},"828":{"code":"GR-L","name":"N\u00f3tio Aiga\u00edo"},"829":{"code":"GR-J","name":"Pelop\u00f3nnisos"},"830":{"code":"GR-H","name":"Stere\u00e1 Ell\u00e1da"},"831":{"code":"GR-E","name":"Thessal\u00eda"},"832":{"code":"GR-K","name":"V\u00f3reio Aiga\u00edo"}}},"HR":{"name":"Kroati\u00eb","regions":{"518":{"code":"HR-07","name":"Bjelovarsko-bilogorska \u017eupanija"},"523":{"code":"HR-12","name":"Brodsko-posavska \u017eupanija"},"530":{"code":"HR-19","name":"Dubrova\u010dko-neretvanska \u017eupanija"},"532":{"code":"HR-21","name":"Grad Zagreb"},"529":{"code":"HR-18","name":"Istarska \u017eupanija"},"515":{"code":"HR-04","name":"Karlova\u010dka \u017eupanija"},"517":{"code":"HR-06","name":"Koprivni\u010dko-kri\u017eeva\u010dka \u017eupanija"},"513":{"code":"HR-02","name":"Krapinsko-zagorska \u017eupanija"},"520":{"code":"HR-09","name":"Li\u010dko-senjska \u017eupanija"},"531":{"code":"HR-20","name":"Me\u0111imurska \u017eupanija"},"525":{"code":"HR-14","name":"Osje\u010dko-baranjska \u017eupanija"},"522":{"code":"HR-11","name":"Po\u017ee\u0161ko-slavonska \u017eupanija"},"519":{"code":"HR-08","name":"Primorsko-goranska \u017eupanija"},"526":{"code":"HR-15","name":"\u0160ibensko-kninska \u017eupanija"},"514":{"code":"HR-03","name":"Sisa\u010dko-moslava\u010dka \u017eupanija"},"528":{"code":"HR-17","name":"Splitsko-dalmatinska \u017eupanija"},"516":{"code":"HR-05","name":"Vara\u017edinska \u017eupanija"},"521":{"code":"HR-10","name":"Viroviti\u010dko-podravska \u017eupanija"},"527":{"code":"HR-16","name":"Vukovarsko-srijemska \u017eupanija"},"524":{"code":"HR-13","name":"Zadarska \u017eupanija"},"512":{"code":"HR-01","name":"Zagreba\u010dka \u017eupanija"}}},"HU":{"name":"Hongarije"},"IE":{"name":"Ierland"},"IT":{"name":"Itali\u00eb","regions":{"852":{"code":"AG","name":"Agrigento"},"853":{"code":"AL","name":"Alessandria"},"854":{"code":"AN","name":"Ancona"},"855":{"code":"AO","name":"Aosta"},"857":{"code":"AR","name":"Arezzo"},"858":{"code":"AP","name":"Ascoli-Piceno"},"859":{"code":"AT","name":"Asti"},"860":{"code":"AV","name":"Avellino"},"861":{"code":"BA","name":"Bari"},"862":{"code":"BT","name":"Barletta-Andria-Trani"},"863":{"code":"BL","name":"Belluno"},"864":{"code":"BN","name":"Benevento"},"865":{"code":"BG","name":"Bergamo"},"866":{"code":"BI","name":"Biella"},"867":{"code":"BO","name":"Bologna"},"868":{"code":"BZ","name":"Bolzano"},"869":{"code":"BS","name":"Brescia"},"870":{"code":"BR","name":"Brindisi"},"871":{"code":"CA","name":"Cagliari"},"872":{"code":"CL","name":"Caltanissetta"},"873":{"code":"CB","name":"Campobasso"},"874":{"code":"CI","name":"Carbonia Iglesias"},"875":{"code":"CE","name":"Caserta"},"876":{"code":"CT","name":"Catania"},"877":{"code":"CZ","name":"Catanzaro"},"878":{"code":"CH","name":"Chieti"},"879":{"code":"CO","name":"Como"},"880":{"code":"CS","name":"Cosenza"},"881":{"code":"CR","name":"Cremona"},"882":{"code":"KR","name":"Crotone"},"883":{"code":"CN","name":"Cuneo"},"884":{"code":"EN","name":"Enna"},"885":{"code":"FM","name":"Fermo"},"886":{"code":"FE","name":"Ferrara"},"887":{"code":"FI","name":"Firenze"},"888":{"code":"FG","name":"Foggia"},"889":{"code":"FC","name":"Forli-Cesena"},"890":{"code":"FR","name":"Frosinone"},"891":{"code":"GE","name":"Genova"},"892":{"code":"GO","name":"Gorizia"},"893":{"code":"GR","name":"Grosseto"},"894":{"code":"IM","name":"Imperia"},"895":{"code":"IS","name":"Isernia"},"856":{"code":"AQ","name":"L'Aquila"},"896":{"code":"SP","name":"La-Spezia"},"897":{"code":"LT","name":"Latina"},"898":{"code":"LE","name":"Lecce"},"899":{"code":"LC","name":"Lecco"},"900":{"code":"LI","name":"Livorno"},"901":{"code":"LO","name":"Lodi"},"902":{"code":"LU","name":"Lucca"},"903":{"code":"MC","name":"Macerata"},"904":{"code":"MN","name":"Mantova"},"905":{"code":"MS","name":"Massa-Carrara"},"906":{"code":"MT","name":"Matera"},"907":{"code":"VS","name":"Medio Campidano"},"908":{"code":"ME","name":"Messina"},"909":{"code":"MI","name":"Milano"},"910":{"code":"MO","name":"Modena"},"911":{"code":"MB","name":"Monza-Brianza"},"912":{"code":"NA","name":"Napoli"},"913":{"code":"NO","name":"Novara"},"914":{"code":"NU","name":"Nuoro"},"915":{"code":"OG","name":"Ogliastra"},"916":{"code":"OT","name":"Olbia Tempio"},"917":{"code":"OR","name":"Oristano"},"918":{"code":"PD","name":"Padova"},"919":{"code":"PA","name":"Palermo"},"920":{"code":"PR","name":"Parma"},"921":{"code":"PV","name":"Pavia"},"922":{"code":"PG","name":"Perugia"},"923":{"code":"PU","name":"Pesaro-Urbino"},"924":{"code":"PE","name":"Pescara"},"925":{"code":"PC","name":"Piacenza"},"926":{"code":"PI","name":"Pisa"},"927":{"code":"PT","name":"Pistoia"},"928":{"code":"PN","name":"Pordenone"},"929":{"code":"PZ","name":"Potenza"},"930":{"code":"PO","name":"Prato"},"931":{"code":"RG","name":"Ragusa"},"932":{"code":"RA","name":"Ravenna"},"933":{"code":"RC","name":"Reggio-Calabria"},"934":{"code":"RE","name":"Reggio-Emilia"},"935":{"code":"RI","name":"Rieti"},"936":{"code":"RN","name":"Rimini"},"937":{"code":"RM","name":"Roma"},"938":{"code":"RO","name":"Rovigo"},"939":{"code":"SA","name":"Salerno"},"940":{"code":"SS","name":"Sassari"},"941":{"code":"SV","name":"Savona"},"942":{"code":"SI","name":"Siena"},"943":{"code":"SR","name":"Siracusa"},"944":{"code":"SO","name":"Sondrio"},"945":{"code":"TA","name":"Taranto"},"946":{"code":"TE","name":"Teramo"},"947":{"code":"TR","name":"Terni"},"948":{"code":"TO","name":"Torino"},"949":{"code":"TP","name":"Trapani"},"950":{"code":"TN","name":"Trento"},"951":{"code":"TV","name":"Treviso"},"952":{"code":"TS","name":"Trieste"},"953":{"code":"UD","name":"Udine"},"954":{"code":"VA","name":"Varese"},"955":{"code":"VE","name":"Venezia"},"956":{"code":"VB","name":"Verbania"},"957":{"code":"VC","name":"Vercelli"},"958":{"code":"VR","name":"Verona"}
7338,"959":{"code":"VV","name":"Vibo-Valentia"},"960":{"code":"VI","name":"Vicenza"},"961":{"code":"VT","name":"Viterbo"}}},"LT":{"name":"Litouwen","regions":{"475":{"code":"LT-AL","name":"Alytaus Apskritis"},"476":{"code":"LT-KU","name":"Kauno Apskritis"},"477":{"code":"LT-KL","name":"Klaip\u0117dos Apskritis"},"478":{"code":"LT-MR","name":"Marijampol\u0117s Apskritis"},"479":{"code":"LT-PN","name":"Panev\u0117\u017eio Apskritis"},"480":{"code":"LT-SA","name":"\u0160iauli\u0173 Apskritis"},"481":{"code":"LT-TA","name":"Taurag\u0117s Apskritis"},"482":{"code":"LT-TE","name":"Tel\u0161i\u0173 Apskritis"},"483":{"code":"LT-UT","name":"Utenos Apskritis"},"484":{"code":"LT-VL","name":"Vilniaus Apskritis"}}},"LU":{"name":"Luxemburg"},"LV":{"name":"Letland","regions":{"471":{"code":"\u0100da\u017eu novads","name":"\u0100da\u017eu novads"},"366":{"code":"Aglonas novads","name":"Aglonas novads"},"367":{"code":"LV-AI","name":"Aizkraukles novads"},"368":{"code":"Aizputes novads","name":"Aizputes novads"},"369":{"code":"Akn\u012bstes novads","name":"Akn\u012bstes novads"},"370":{"code":"Alojas novads","name":"Alojas novads"},"371":{"code":"Alsungas novads","name":"Alsungas novads"},"372":{"code":"LV-AL","name":"Al\u016bksnes novads"},"373":{"code":"Amatas novads","name":"Amatas novads"},"374":{"code":"Apes novads","name":"Apes novads"},"375":{"code":"Auces novads","name":"Auces novads"},"376":{"code":"Bab\u012btes novads","name":"Bab\u012btes novads"},"377":{"code":"Baldones novads","name":"Baldones novads"},"378":{"code":"Baltinavas novads","name":"Baltinavas novads"},"379":{"code":"LV-BL","name":"Balvu novads"},"380":{"code":"LV-BU","name":"Bauskas novads"},"381":{"code":"Bever\u012bnas novads","name":"Bever\u012bnas novads"},"382":{"code":"Broc\u0113nu novads","name":"Broc\u0113nu novads"},"383":{"code":"Burtnieku novads","name":"Burtnieku novads"},"384":{"code":"Carnikavas novads","name":"Carnikavas novads"},"387":{"code":"LV-CE","name":"C\u0113su novads"},"385":{"code":"Cesvaines novads","name":"Cesvaines novads"},"386":{"code":"Ciblas novads","name":"Ciblas novads"},"388":{"code":"Dagdas novads","name":"Dagdas novads"},"355":{"code":"LV-DGV","name":"Daugavpils"},"389":{"code":"LV-DA","name":"Daugavpils novads"},"390":{"code":"LV-DO","name":"Dobeles novads"},"391":{"code":"Dundagas novads","name":"Dundagas novads"},"392":{"code":"Durbes novads","name":"Durbes novads"},"393":{"code":"Engures novads","name":"Engures novads"},"472":{"code":"\u0112rg\u013cu novads","name":"\u0112rg\u013cu novads"},"394":{"code":"Garkalnes novads","name":"Garkalnes novads"},"395":{"code":"Grobi\u0146as novads","name":"Grobi\u0146as novads"},"396":{"code":"LV-GU","name":"Gulbenes novads"},"397":{"code":"Iecavas novads","name":"Iecavas novads"},"398":{"code":"Ik\u0161\u0137iles novads","name":"Ik\u0161\u0137iles novads"},"399":{"code":"Il\u016bkstes novads","name":"Il\u016bkstes novads"},"400":{"code":"In\u010dukalna novads","name":"In\u010dukalna novads"},"401":{"code":"Jaunjelgavas novads","name":"Jaunjelgavas novads"},"402":{"code":"Jaunpiebalgas novads","name":"Jaunpiebalgas novads"},"403":{"code":"Jaunpils novads","name":"Jaunpils novads"},"357":{"code":"J\u0113kabpils","name":"J\u0113kabpils"},"405":{"code":"LV-JK","name":"J\u0113kabpils novads"},"356":{"code":"LV-JEL","name":"Jelgava"},"404":{"code":"LV-JL","name":"Jelgavas novads"},"358":{"code":"LV-JUR","name":"J\u016brmala"},"406":{"code":"Kandavas novads","name":"Kandavas novads"},"412":{"code":"K\u0101rsavas novads","name":"K\u0101rsavas novads"},"473":{"code":"\u0136eguma novads","name":"\u0136eguma novads"},"474":{"code":"\u0136ekavas novads","name":"\u0136ekavas novads"},"407":{"code":"Kokneses novads","name":"Kokneses novads"},"410":{"code":"LV-KR","name":"Kr\u0101slavas novads"},"408":{"code":"Krimuldas novads","name":"Krimuldas novads"},"409":{"code":"Krustpils novads","name":"Krustpils novads"},"411":{"code":"LV-KU","name":"Kuld\u012bgas novads"},"413":{"code":"Lielv\u0101rdes novads","name":"Lielv\u0101rdes novads"},"359":{"code":"LV-LPX","name":"Liep\u0101ja"},"360":{"code":"LV-LE","name":"Liep\u0101jas novads"},"417":{"code":"L\u012bgatnes novads","name":"L\u012bgatnes novads"},"414":{"code":"LV-LM","name":"Limba\u017eu novads"},"418":{"code":"L\u012bv\u0101nu novads","name":"L\u012bv\u0101nu novads"},"415":{"code":"Lub\u0101nas novads","name":"Lub\u0101nas novads"},"416":{"code":"LV-LU","name":"Ludzas novads"},"419":{"code":"LV-MA","name":"Madonas novads"},"421":{"code":"M\u0101lpils novads","name":"M\u0101lpils novads"},"422":{"code":"M\u0101rupes novads","name":"M\u0101rupes novads"},"420":{"code":"Mazsalacas novads","name":"Mazsalacas novads"},"423":{"code":"Nauk\u0161\u0113nu novads","name":"Nauk\u0161\u0113nu novads"},"424":{"code":"Neretas novads","name":"Neretas novads"},"425":{"code":"N\u012bcas novads","name":"N\u012bcas novads"},"426":{"code":"LV-OG","name":"Ogres novads"},"427":{"code":"Olaines novads","name":"Olaines novads"},"428":{"code":"Ozolnieku novads","name":"Ozolnieku novads"},"432":{"code":"P\u0101rgaujas novads","name":"P\u0101rgaujas novads"},"433":{"code":"P\u0101vilostas novads","name":"P\u0101vilostas novads"},"434":{"code":"P\u013cavi\u0146u novads","name":"P\u013cavi\u0146u novads"},"429":{"code":"LV-PR","name":"Prei\u013cu novads"},"430":{"code":"Priekules novads","name":"Priekules novads"},"431":{"code":"Prieku\u013cu novads","name":"Prieku\u013cu novads"},"435":{"code":"Raunas novads","name":"Raunas novads"},"361":{"code":"LV-REZ","name":"R\u0113zekne"},"442":{"code":"LV-RE","name":"R\u0113zeknes novads"},"436":{"code":"Riebi\u0146u novads","name":"Riebi\u0146u novads"},"362":{"code":"LV-RIX","name":"R\u012bga"},"363":{"code":"LV-RI","name":"R\u012bgas novads"},"437":{"code":"Rojas novads","name":"Rojas novads"},"438":{"code":"Ropa\u017eu novads","name":"Ropa\u017eu novads"},"439":{"code":"Rucavas novads","name":"Rucavas novads"},"440":{"code":"Rug\u0101ju novads","name":"Rug\u0101ju novads"},"443":{"code":"R\u016bjienas novads","name":"R\u016bjienas novads"},"441":{"code":"Rund\u0101les novads","name":"Rund\u0101les novads"},"444":{"code":"Salacgr\u012bvas novads","name":"Salacgr\u012bvas novads"},"445":{"code":"Salas novads","name":"Salas novads"},"446":{"code":"Salaspils novads","name":"Salaspils novads"},"447":{"code":"LV-SA","name":"Saldus novads"},"448":{"code":"Saulkrastu novads","name":"Saulkrastu novads"},"455":{"code":"S\u0113jas novads","name":"S\u0113jas novads"},"449":{"code":"Siguldas novads","name":"Siguldas novads"}
7338,"451":{"code":"Skr\u012bveru novads","name":"Skr\u012bveru novads"},"450":{"code":"Skrundas novads","name":"Skrundas novads"},"452":{"code":"Smiltenes novads","name":"Smiltenes novads"},"453":{"code":"Stopi\u0146u novads","name":"Stopi\u0146u novads"},"454":{"code":"Stren\u010du novads","name":"Stren\u010du novads"},"456":{"code":"LV-TA","name":"Talsu novads"},"458":{"code":"T\u0113rvetes novads","name":"T\u0113rvetes novads"},"457":{"code":"LV-TU","name":"Tukuma novads"},"459":{"code":"Vai\u0146odes novads","name":"Vai\u0146odes novads"},"460":{"code":"LV-VK","name":"Valkas novads"},"364":{"code":"Valmiera","name":"Valmiera"},"461":{"code":"LV-VM","name":"Valmieras novads"},"462":{"code":"Varak\u013c\u0101nu novads","name":"Varak\u013c\u0101nu novads"},"469":{"code":"V\u0101rkavas novads","name":"V\u0101rkavas novads"},"463":{"code":"Vecpiebalgas novads","name":"Vecpiebalgas novads"},"464":{"code":"Vecumnieku novads","name":"Vecumnieku novads"},"365":{"code":"LV-VEN","name":"Ventspils"},"465":{"code":"LV-VE","name":"Ventspils novads"},"466":{"code":"Vies\u012btes novads","name":"Vies\u012btes novads"},"467":{"code":"Vi\u013cakas novads","name":"Vi\u013cakas novads"},"468":{"code":"Vi\u013c\u0101nu novads","name":"Vi\u013c\u0101nu novads"},"470":{"code":"Zilupes novads","name":"Zilupes novads"}}},"MC":{"name":"Monaco"},"MT":{"name":"Malta"},"NL":{"name":"Nederland"},"NO":{"name":"Noorwegen"},"NZ":{"name":"Nieuw-Zeeland"},"PL":{"name":"Polen","regions":{"686":{"code":"PL-02","name":"dolno\u015bl\u0105skie"},"687":{"code":"PL-04","name":"kujawsko-pomorskie"},"688":{"code":"PL-06","name":"lubelskie"},"689":{"code":"PL-08","name":"lubuskie"},"692":{"code":"PL-14","name":"mazowieckie"},"691":{"code":"PL-12","name":"ma\u0142opolskie"},"693":{"code":"PL-16","name":"opolskie"},"694":{"code":"PL-18","name":"podkarpackie"},"695":{"code":"PL-20","name":"podlaskie"},"696":{"code":"PL-22","name":"pomorskie"},"697":{"code":"PL-24","name":"\u015bl\u0105skie"},"698":{"code":"PL-26","name":"\u015bwi\u0119tokrzyskie"},"699":{"code":"PL-28","name":"warmi\u0144sko-mazurskie"},"700":{"code":"PL-30","name":"wielkopolskie"},"701":{"code":"PL-32","name":"zachodniopomorskie"},"690":{"code":"PL-10","name":"\u0142\u00f3dzkie"}}},"PT":{"name":"Portugal","regions":{"1006":{"code":"PT-01","name":"Aveiro"},"1007":{"code":"PT-02","name":"Beja"},"1008":{"code":"PT-03","name":"Braga"},"1009":{"code":"PT-04","name":"Bragan\u00e7a"},"1010":{"code":"PT-05","name":"Castelo Branco"},"1011":{"code":"PT-06","name":"Coimbra"},"1012":{"code":"PT-07","name":"\u00c9vora"},"1013":{"code":"PT-08","name":"Faro"},"1014":{"code":"PT-09","name":"Guarda"},"1015":{"code":"PT-10","name":"Leiria"},"1016":{"code":"PT-11","name":"Lisboa"},"1017":{"code":"PT-12","name":"Portalegre"},"1018":{"code":"PT-13","name":"Porto"},"1025":{"code":"PT-30","name":"Regi\u00e3o Aut\u00f3noma da Madeira"},"1024":{"code":"PT-20","name":"Regi\u00e3o Aut\u00f3noma dos A\u00e7ores"},"1019":{"code":"PT-14","name":"Santar\u00e9m"},"1020":{"code":"PT-15","name":"Set\u00fabal"},"1021":{"code":"PT-16","name":"Viana do Castelo"},"1022":{"code":"PT-17","name":"Vila Real"},"1023":{"code":"PT-18","name":"Viseu"}}},"RO":{"name":"Roemeni\u00eb","regions":{"278":{"code":"AB","name":"Alba"},"279":{"code":"AR","name":"Arad"},"280":{"code":"AG","name":"Arge\u015f"},"281":{"code":"BC","name":"Bac\u0103u"},"282":{"code":"BH","name":"Bihor"},"283":{"code":"BN","name":"Bistri\u0163a-N\u0103s\u0103ud"},"284":{"code":"BT","name":"Boto\u015fani"},"286":{"code":"BR","name":"Br\u0103ila"},"285":{"code":"BV","name":"Bra\u015fov"},"287":{"code":"B","name":"Bucure\u015fti"},"288":{"code":"BZ","name":"Buz\u0103u"},"290":{"code":"CL","name":"C\u0103l\u0103ra\u015fi"},"289":{"code":"CS","name":"Cara\u015f-Severin"},"291":{"code":"CJ","name":"Cluj"},"292":{"code":"CT","name":"Constan\u0163a"},"293":{"code":"CV","name":"Covasna"},"294":{"code":"DB","name":"D\u00e2mbovi\u0163a"},"295":{"code":"DJ","name":"Dolj"},"296":{"code":"GL","name":"Gala\u0163i"},"297":{"code":"GR","name":"Giurgiu"},"298":{"code":"GJ","name":"Gorj"},"299":{"code":"HR","name":"Harghita"},"300":{"code":"HD","name":"Hunedoara"},"301":{"code":"IL","name":"Ialomi\u0163a"},"302":{"code":"IS","name":"Ia\u015fi"},"303":{"code":"IF","name":"Ilfov"},"304":{"code":"MM","name":"Maramure\u015f"},"305":{"code":"MH","name":"Mehedin\u0163i"},"306":{"code":"MS","name":"Mure\u015f"},"307":{"code":"NT","name":"Neam\u0163"},"308":{"code":"OT","name":"Olt"},"309":{"code":"PH","name":"Prahova"},"311":{"code":"SJ","name":"S\u0103laj"},"310":{"code":"SM","name":"Satu-Mare"},"312":{"code":"SB","name":"Sibiu"},"313":{"code":"SV","name":"Suceava"},"314":{"code":"TR","name":"Teleorman"},"315":{"code":"TM","name":"Timi\u015f"},"316":{"code":"TL","name":"Tulcea"},"318":{"code":"VL","name":"V\u00e2lcea"},"317":{"code":"VS","name":"Vaslui"},"319":{"code":"VN","name":"Vrancea"}}},"SE":{"name":"Zweden","regions":{"1036":{"code":"SE-K","name":"Blekinge l\u00e4n"}
7338,"1037":{"code":"SE-W","name":"Dalarnas l\u00e4n"},"1039":{"code":"SE-X","name":"G\u00e4vleborgs l\u00e4n"},"1038":{"code":"SE-I","name":"Gotlands l\u00e4n"},"1040":{"code":"SE-N","name":"Hallands l\u00e4n"},"1041":{"code":"SE-Z","name":"J\u00e4mtlands l\u00e4n"},"1042":{"code":"SE-F","name":"J\u00f6nk\u00f6pings l\u00e4n"},"1043":{"code":"SE-H","name":"Kalmar l\u00e4n"},"1044":{"code":"SE-G","name":"Kronobergs l\u00e4n"},"1045":{"code":"SE-BD","name":"Norrbottens l\u00e4n"},"1055":{"code":"SE-T","name":"\u00d6rebro l\u00e4n"},"1056":{"code":"SE-E","name":"\u00d6sterg\u00f6tlands l\u00e4n"},"1046":{"code":"SE-M","name":"Sk\u00e5ne l\u00e4n"},"1048":{"code":"SE-D","name":"S\u00f6dermanlands l\u00e4n"},"1047":{"code":"SE-AB","name":"Stockholms l\u00e4n"},"1049":{"code":"SE-C","name":"Uppsala l\u00e4n"},"1050":{"code":"SE-S","name":"V\u00e4rmlands l\u00e4n"},"1051":{"code":"SE-AC","name":"V\u00e4sterbottens l\u00e4n"},"1052":{"code":"SE-Y","name":"V\u00e4sternorrlands l\u00e4n"},"1053":{"code":"SE-U","name":"V\u00e4stmanlands l\u00e4n"},"1054":{"code":"SE-O","name":"V\u00e4stra G\u00f6talands l\u00e4n"}}},"SG":{"name":"Singapore"},"SI":{"name":"Sloveni\u00eb"},"SK":{"name":"Slowakije"},"US":{"name":"Verenigde Staten","regions":{"1":{"code":"AL","name":"Alabama"},"2":{"code":"AK","name":"Alaska"},"3":{"code":"AS","name":"American Samoa"},"4":{"code":"AZ","name":"Arizona"},"5":{"code":"AR","name":"Arkansas"},"6":{"code":"AE","name":"Armed Forces Africa"},"7":{"code":"AA","name":"Armed Forces Americas"},"8":{"code":"AE","name":"Armed Forces Canada"},"9":{"code":"AE","name":"Armed Forces Europe"},"10":{"code":"AE","name":"Armed Forces Middle East"},"11":{"code":"AP","name":"Armed Forces Pacific"},"12":{"code":"CA","name":"California"},"13":{"code":"CO","name":"Colorado"},"14":{"code":"CT","name":"Connecticut"},"15":{"code":"DE","name":"Delaware"},"16":{"code":"DC","name":"District of Columbia"},"17":{"code":"FM","name":"Federated States Of Micronesia"},"18":{"code":"FL","name":"Florida"},"19":{"code":"GA","name":"Georgia"},"20":{"code":"GU","name":"Guam"},"21":{"code":"HI","name":"Hawaii"},"22":{"code":"ID","name":"Idaho"},"23":{"code":"IL","name":"Illinois"},"24":{"code":"IN","name":"Indiana"},"25":{"code":"IA","name":"Iowa"},"26":{"code":"KS","name":"Kansas"},"27":{"code":"KY","name":"Kentucky"},"28":{"code":"LA","name":"Louisiana"},"29":{"code":"ME","name":"Maine"},"30":{"code":"MH","name":"Marshall Islands"},"31":{"code":"MD","name":"Maryland"},"32":{"code":"MA","name":"Massachusetts"},"33":{"code":"MI","name":"Michigan"},"34":{"code":"MN","name":"Minnesota"},"35":{"code":"MS","name":"Mississippi"},"36":{"code":"MO","name":"Missouri"},"37":{"code":"MT","name":"Montana"},"38":{"code":"NE","name":"Nebraska"},"39":{"code":"NV","name":"Nevada"},"40":{"code":"NH","name":"New Hampshire"},"41":{"code":"NJ","name":"New Jersey"},"42":{"code":"NM","name":"New Mexico"},"43":{"code":"NY","name":"New York"},"44":{"code":"NC","name":"North Carolina"},"45":{"code":"ND","name":"North Dakota"},"46":{"code":"MP","name":"Northern Mariana Islands"},"47":{"code":"OH","name":"Ohio"},"48":{"code":"OK","name":"Oklahoma"},"49":{"code":"OR","name":"Oregon"},"50":{"code":"PW","name":"Palau"},"51":{"code":"PA","name":"Pennsylvania"},"52":{"code":"PR","name":"Puerto Rico"},"53":{"code":"RI","name":"Rhode Island"},"54":{"code":"SC","name":"South Carolina"},"55":{"code":"SD","name":"South Dakota"},"56":{"code":"TN","name":"Tennessee"},"57":{"code":"TX","name":"Texas"},"58":{"code":"UT","name":"Utah"},"59":{"code":"VT","name":"Vermont"},"60":{"code":"VI","name":"Virgin Islands"},"61":{"code":"VA","name":"Virginia"},"62":{"code":"WA","name":"Washington"},"63":{"code":"WV","name":"West Virginia"},"64":{"code":"WI","name":"Wisconsin"},"65":{"code":"WY","name":"Wyoming"}}},"data_id":1791323686},"loggedAsCustomer":[],"captcha":[],"persistent":[],"review":[],"wishlist":{"items":[]},"hyva_checkout":[],"mooore-google-tag-manager":[],"product-recommendations":[],"hyva_commerce_messages":[],"recently_viewed_product":[],"recently_compared_product":[],"product_data_storage":[],"paypal-billing-agreement":[],"paypal-buyer-country":[]}</script>
vendor: 1 bytes, line 7338
7338
7339<script> 7340 window.processSectionDataBeforeDispatch && (window.processSectionDataBeforeDispatch = new Proxy(window.processSectionDataBeforeDispatch, { 7341 apply(target, thisArg, [data]) { 7342 data.hyva_commerce_messages = data.hyva_commerce_messages || {}; 7343 return target.call(thisArg, data); 7344 } 7345 })); 7346</script>
7346 7347
7348<script> 7349 function initCartDrawer() { 7350 return { 7351 open: false, 7352 isLoading: false, 7353 cart: {}, 7354 hasCrosssells: false, 7355 maxItemsToDisplay: 10, 7356 itemsCount: 0, 7357 totalCartAmount: 0, 7358 modal: { 7359 open: false, 7360 item: null 7361 }, 7362 handleOpenDrawer(isOpen) { 7363 const path = window.location.pathname; 7364 const cartTable = document.querySelector('#shopping-cart-table'); 7365 if (cartTable) { 7366 const headerHeight = parseInt(getComputedStyle(document.documentElement).getPropertyValue('--page-header-height'), 10) || 0; 7367 const targetPosition = cartTable.getBoundingClientRect().top + window.pageYOffset; 7368 window.scrollTo({ top: targetPosition - headerHeight, behavior: 'smooth' }); 7369 return; 7370 } 7371 if (path.includes('/checkout/onepage/success/')) { 7372 return; 7373 } 7374 this.setDrawerOpen(isOpen); 7375 this.toggleBodyScrollLock(isOpen); 7376 this.pushViewCartEvent(); 7377 }, 7378 canShowProductLabel(item) { 7379 if (!item.product_label) { 7380 return false; 7381 } 7382 let now = new Date(); 7383 if (item.label_from_date) { 7384 if (new Date(item.label_from_date) > now) { 7385 return false; 7386 } 7387 } 7388 if (item.label_to_date) { 7389 if (new Date(item.label_to_date) <= now) { 7390 return false; 7391 } 7392 } 7393 return true; 7394 }, 7395 setDrawerOpen(isOpen) { 7396 this.open = isOpen; 7397 setTimeout(() => { 7398 window.setAjaxCart(); 7399 if (this.open) { 7400 document.getElementById('forceFocus').focus() 7401 } else { 7402 document.getElementById('menu-cart-icon').focus() 7403 } 7404 }, 0) 7405 }, 7406 toggleBodyScrollLock(lockScroll) { 7407 document.body.classList.toggle('cart-open', lockScroll); 7408 }, 7409 getData(data) { 7410 if (data.cart) { 7411 this.cart = data.cart; 7412 this.itemsCount = data.cart.items && data.cart.items.length || 0; 7413 this.totalCartAmount = this.cart.summary_count; 7414 this.setCartItems(); 7415 } 7416 7417 this.hasCrosssells = data['product-recommendations']?.crosssells?.items?.length 7418 7419 if (window.location.pathname.includes('/checkout/cart')) { 7420 this.pushViewCartEvent(); 7421 } 7422 7423 this.isLoading = false; 7424 }, 7425 pushViewCartEvent() { 7426 if (!this.cart.items || this.cart.items.length === 0) { 7427 return; 7428 } 7429 7430 let products = this.cart.items.map(item => ({ 7431 item_id: item.parent_product_sku ? item.parent_product_sku : item.product_sku, 7432 item_variant: item.product_sku, 7433 magento_id: item.parent_item_id ? item.parent_item_id : item.product_id, 7434 magento_variant: item.product_id, 7435 item_name: item.product_name, 7436 price: item.product_price_value, 7437 quantity: item.qty, 7438 })); 7439 7440 window.dataLayer = window.dataLayer || []; 7441 window.dataLayer.push({ 7442 event: "view_cart", 7443 ecommerce: { 7444 currency: "EUR", 7445 value: this.cart.subtotalAmount, 7446 items: products 7447 } 7448 }); 7449 }, 7450 cartItems: [], 7451 getItemCountTitle() { 7452 return hyva.strf('(%0 of %1)', this.maxItemsToDisplay, this.itemsCount) 7453 }, 7454 setCartItems() { 7455 let items = this.cart.items && this.cart.items.sort((a, b) =>
7455 b.item_id - a.item_id) || []; 7456 if (this.maxItemsToDisplay > 0) { 7457 items = items.slice(0, parseInt(this.maxItemsToDisplay, 10)); 7458 } 7459 items = items.map(item => ({ 7460 ...item, 7461 has_promo: item.product_price_value === '0.0000' 7462 })); 7463 this.cartItems = items; 7464 }, 7465 deleteItemFromCart(itemId) { 7466 const formKey = hyva.getFormKey(); 7467 const postUrl = BASE_URL + 'checkout/sidebar/removeItem/'; 7468 7469 fetch(postUrl, { 7470 "headers": { 7471 "content-type": "application/x-www-form-urlencoded; charset=UTF-8", 7472 }, 7473 "body": "form_key=" + formKey + "&item_id=" + itemId, 7474 "method": "POST", 7475 "mode": "cors", 7476 "credentials": "include" 7477 }).then(response => { 7478 if (response.redirected) { 7479 window.location.href = response.url; 7480 } else if (response.ok) { 7481 return response.json(); 7482 this.modal.item = null; 7483 } else { 7484 window.dispatchMessages && window.dispatchMessages([{ 7485 type: 'warning', 7486 text: 'Could\u0020not\u0020remove\u0020item\u0020from\u0020quote.' 7487 }]); 7488 } 7489 }).then(result => { 7490 window.dispatchEvent(new CustomEvent('reload-customer-section-data')); 7491 7492 setTimeout(() => { 7493 document.getElementById('forceFocus').focus() 7494 },0 ) 7495 }); 7496 7497 this.closeModal(); 7498 }, 7499 parseSizeOption(value) { 7500 if (!Array.isArray(value)) { 7501 return value; 7502 } 7503 let newVal = value[0]; 7504 7505 return this.extractSizes(newVal); 7506 }, 7507 extractSizes(str) { 7508 const shortSizeRegex = 7509 /\b(5XL|4XL|3XL|XXL|XL|L|M|S|XS|2XS|3XS|4XS|5XS)\b/; 7510 7511 const longSizes = [ 7512 "Standard Long Fit", 7513 "Extra Long Fit", 7514 "Long Fit", 7515 "SLF", 7516 "XLF", 7517 "LF", 7518 ]; 7519 7520 const shortMatch = str.match(shortSizeRegex); 7521 const shortSize = shortMatch ? shortMatch[1] : null; 7522 7523 const longSize = longSizes 7524 .sort((a, b) => b.length - a.length) 7525 .find(size => str.includes(size)); 7526 7527 if (!shortSize || !longSize) { 7528 return str; 7529 } 7530 7531 const longSizeFull = this.replaceFitCodes(longSize); 7532 return `${shortSize} - ${longSizeFull}`; 7533 }, 7534 replaceFitCodes(str) { 7535 const fitMap = { 7536 "SLF": "Standard Long Fit", 7537 "LF": "Long Fit", 7538 "XLF": "Extra Long Fit" 7539 }; 7540 7541 return str.replace(/\b(SLF|LF|XLF)\b/g, match => fitMap[match]); 7542 }, 7543 changeQtyItemFromCart(itemId, itemQty) { 7544 const formKey = hyva.getFormKey(); 7545 const postUrl = BASE_URL + 'checkout/sidebar/updateItemQty/'; 7546 7547 fetch(postUrl, { 7548 "headers": { 7549 "content-type": "application/x-www-form-urlencoded; charset=UTF-8", 7550 }, 7551 "body": "form_key=" + formKey + "&item_id=" + itemId + "&item_qty=" + itemQty, 7552 "method": "POST", 7553 "mode": "cors", 7554 "credentials": "include" 7555 }).then(response => { 7556 if (response.redirected) { 7557 window.location.href = response.url; 7558 } else if (response.ok) { 7559 return response.json(); 7560 } else { 7561 window.dispatchMessages && window.dispatchMessages([{ 7562 type: 'warning', 7563 text: 'Could\u0020not\u0020change\u0020quantity\u0020for\u0020this\u0020item.' 7564 }]); 7565 } 7566 }).then(result => { 7567 window.dispatchEvent(new CustomEvent('reload-customer-section-data')); 7568 }); 7569 }, 7570 closeModal() { 7571 this.modal.open = false;
7572 7573 setTimeout(() => { 7574 document.getElementById('forceFocus').focus() 7575 },0 ) 7576 }, 7577 openModal() { 7578 this.modal.open = true; 7579 7580 setTimeout(() => { 7581 document.getElementById('confirmationFocus').focus() 7582 },0 ) 7583 7584 } 7585 } 7586 } 7587</script>
7587 7588 7589<section id="cart-drawer" 7590 class="cart-drawer" 7591 x-data="initCartDrawer()" 7592 @private-content-loaded.window="getData($event.detail.data)" 7593 @toggle-cart.window="handleOpenDrawer(true)" 7594 @keydown.window.escape="handleOpenDrawer(false)" 7595 @product-addtocart-success.window="handleOpenDrawer(true)" 7596> 7597 <template x-if="cart"> 7598 <div role="dialog" class="dialog-wrapper dialog-cart focus-within:ring-1" x-cloak> 7599 <div 7600 class="backdrop backdrop-cart" 7601 x-show="open" 7602 @click="handleOpenDrawer(false)" 7603 aria-label="Close panel" 7604 ></div> 7605 7606 <div class="dialog offcanvas-end p-0" :class="{ 'is-open': open }"> 7607 <div class="dialog offcanvas-end p-0" :class="{ 'is-open': open }"> 7608 <div class="dialog-header px-4 md:pl-8 pb-0 flex flex-col"> 7609 <button id="forceFocus" @click="handleOpenDrawer(false)" class="absolute top-3 right-0" aria-label="Close panel" x-focus-first> 7610 <svg xmlns="http://www.w3.org/2000/svg" width="44" height="44" viewBox="0 0 44 44" fill="none" class="text-[#2a2a2a]" role="img"> 7611 <path d="M28 16L16 28M16 16L28 28" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/> 7612<title>x</title></svg> 7613 </button> 7614 <div class="w-full"> 7615 <span id="cart-drawer-title" class="flex w-full h-11 leading-11 flex-wrap gap-3 md:pr-4"> 7616 <span class="font-bold text-[20px] top-1 relative"> 7617 Jouw winkelwagen </span> 7618 <template x-if="totalCartAmount !== 0"> 7619 <a 7620 href="https://www.girav.nl/checkout/cart/" 7621 class="font-normal text-[#292929] text-sm underline flex flex-col justify-center"> 7622 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 20" class="text-[#2a2a2a]" width="16" height="16" role="img"> 7623 <path stroke="#2A2A2A" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="1.5" d="M9.9 4.2a5.1 5.1 0 0 0 4.55 4.3M2.5 18.33h15M11.05 3l-6.84 7.24c-.26.28-.51.82-.56 1.2l-.3 2.7c-.12.97.58 1.63 1.55 1.47l2.68-.46c.38-.07.9-.34 1.16-.63l6.84-7.24c1.19-1.25 1.72-2.67-.12-4.41-1.84-1.73-3.23-1.12-4.41.13Z"/> 7624<title>edit</title></svg> 7625 </a> 7626 </template> 7627 </span> 7628 </div> 7629 </div> 7630 <div class="dialog-content px-4 md:px-8 pt-0 grow"> 7631 <template x-if="totalCartAmount == 0"> 7632 <p><strong>Je hebt geen product(en) in uw winkelwagen.</strong></p> 7633 </template> 7634 <template x-if="totalCartAmount !== 0"> 7635 <div class="content active-items relative grid gap-4 pt-4 md:-mr-4 "> 7636 <template x-for="(item, itemIndex) in cartItems"> 7637 <div class="relative flex flex-row items-start transition duration-150 ease-in-out last:pb-0 bg-white rounded-[10px]" 7638 :class="{'has-free-gift': item.has_promo}"> 7639 <a :href="item.product_url" class="block relative h-full"> 7640 <img 7641 :src="item.product_image.src" 7642 :width="item.product_image.width" 7643 :height="item.product_image.height" 7644 loading="lazy" 7645 class="object-cover bg-gray-100 max-w-[130px] md:max-w-[138px] rounded-[10px] h-full" 7646 /> 7647 <template x-if="item.has_promo"> 7648 <div class="flex gap-1 left-1.5 right-1.5 rounded-full bg-white absolute bottom-1.5 h-[18px] justify-center">
7649 <span class="flex flex-col justify-center"> 7650 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 25" class="text-[#0065CC]" width="10" height="10" role="img"> 7651 <path fill="currentColor" d="M11.17 11.24V25H1.65a.83.83 0 0 1-.83-.82V11.24h10.35Zm11.83 0v12.94c0 .45-.38.82-.84.82h-9.33V11.24H23Zm.17-5.56h-4.7A3.29 3.29 0 0 0 20 3.84c.36-1.26-.36-2.5-1.25-3.16a2.93 2.93 0 0 0-2.68-.56c-1.2.35-2.37 1.51-3.45 3.45-.24.42-.45.84-.62 1.2-.17-.36-.38-.78-.62-1.2C10.3 1.63 9.14.47 7.93.12a2.93 2.93 0 0 0-2.68.56c-.89.67-1.61 1.9-1.25 3.16.2.72.72 1.33 1.54 1.84H.84A.83.83 0 0 0 0 6.5v3.1h11.17V5.68h1.66V9.6H24V6.5a.83.83 0 0 0-.83-.82ZM6.93 4.56c-.75-.35-1.21-.75-1.33-1.16-.16-.55.32-1.17.66-1.42.35-.27.64-.34.87-.34.12 0 .23.02.32.05.75.22 1.63 1.16 2.47 2.65.23.41.43.82.6 1.17a13.28 13.28 0 0 1-3.6-.95ZM18.4 3.4c-.12.4-.58.81-1.33 1.16-.86.4-2.06.73-3.58.95.16-.35.36-.76.6-1.17.83-1.49 1.7-2.43 2.46-2.65.09-.03.2-.05.32-.05.23 0 .52.07.87.34.34.25.82.87.66 1.42Z"/> 7652<title>free-gift</title></svg> 7653 </span> 7654 <span class="text-[10px] font-medium leading-[18px]"> 7655 Cadeau </span> 7656 </div> 7657 </template> 7658 </a> 7659 <div class="flex flex-row flex-wrap w-full h-full p-4"> 7660 <div class="flex flex-col grow justify-start"> 7661 <div> 7662 <p class="text-sm md:text-base font-medium mb-4"> 7663 <span x-html="item.product_name"></span> 7664 </p> 7665 </div> 7666 <div class="flex flex-col text-base"> 7667 <div class="flex w-full lg:flex-1 mb-1 gap-1 lg:mr-4"> 7668 <div class="flex w-full gap-1 flex-wrap"> 7669 <div class="text-[#2a2a2a] text-sm font-bold">Maat:</div> 7670 <div class="flex flex-row"> 7671 <template x-for="option in item.options"> 7672 <div class="flex gap-1 text-[#2A2A2A] items-center cart-drawer-option-value text-sm" 7673 x-html="parseSizeOption(option.value)" 7674 > 7675 </div> 7676 </template> 7677 </div> 7678 </div> 7679 </div> 7680 <template x-if="!item.has_promo"> 7681 <div class="text-[16px] text-[#2a2a2a] relative w-full lg:w-auto flex gap-1"> 7682 <p class="text-sm font-medium">Aantal:</p> 7683 <div class="flex items-center justify-end"> 7684 <select name="qty" class="qty form-input !text-sm font-normal !w-[62px] !pl-3 py-0 !h-6 text-left block !rounded-full border-[#D9D9D9]" 7685 style="background-color: transparent" 7686 id="qty" 7687 x-model="item.qty" 7688 x-on:change="changeQtyItemFromCart(item.item_id, $event.target.value)"> 7689 <template 7690 x-for="(_, optionValue) in new Array(15).fill(null)" 7691 :key="optionValue"> 7692 <option :value="optionValue + 1" x-text="optionValue + 1" 7693 :selected="parseInt(item.qty) == parseInt(optionValue + 1)"> 7694 </option> 7695 </template> 7696 </select> 7697 <button class="pl-3.5 text-black xs-max:flex xs-max:justify-end" 7698 @click="openModal(); modal.item=item.item_id;" 7699 > 7700 <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 20 20" fill="none" role="img"> 7701 <path d="M17.5 4.98366C14.725 4.70866 11.9333 4.56699 9.15 4.56699C7.5 4.56699 5.85 4.65033 4.2 4.81699L2.5 4.98366M7.08333 4.14199L7.26667 3.05033C7.4 2.25866 7.5 1.66699 8.90833 1.66699H11.0917C12.5 1.66699 12.6083 2.29199 12.7333 3.05866L12.9167 4.14199M15.7083 7.61699L15.1667 16.0087C15.075 17.317 15 18.3337 12.675 18.3337H7.325C5 18.3337 4.925 17.317 4.83333 16.0087L4.29167 7.61699M8.60833 13.7503H11.3833M7.91667 10.417H12.0833" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/> 7702<title>trash</title></svg> 7703 </button> 7704 </div> 7705 </div> 7706 </template> 7707 <div class="text-sm mt-1 font-medium" :class="item.is_saleable ? 'text-[#0F8A5D]' : 'text-[#AE1C28]'" x-text="item.is_saleable ? 'Op voorraad' : 'Niet op voorraad'"></div> 7708 </div> 7709 <div class="flex flex-row justify-between items-end w-full mt-auto bg-white"> 7710 <template x-if="item.afptc_discount_label"> 7711 <div class="flex justify-end"> 7712 <p class="text-sm text-[#00AB6C] font-medium">
7713 <span x-html="item.afptc_discount_label"></span> 7714 </p> 7715 </div> 7716 </template> 7717 <template x-if="canShowProductLabel(item)"> 7718 <div class="flex justify-end"> 7719 <div class="item-product-label flex flex-row justify-center items-center text-xs md:text-[10px] rounded-3xl px-2 min-w-16 h-[18px] whitespace-nowrap font-semibold text-white bg-[#2a2a2a]" 7720 x-text="item.product_label" 7721 style="background-color: #000000; color: #ffffff" 7722 > 7723 </div> 7724 </div> 7725 </template> 7726 <div class="flex justify-end gap-1 w-full"> 7727 <template x-if="item && item.product_old_price_value"> 7728 <p class="text-base font-normal line-through text-[#2a2a2a] relative top-1"> 7729 <span x-html="hyva.formatPrice(item.product_old_price_value)"></span> 7730 </p> 7731 </template> 7732 <p class="text-base font-normal" 7733 :class="{'text-[#AE1C28]': item.product_old_price_value, '!font-bold text-[#00AB6C]': item.has_promo}"> 7734 <span x-html="item.product_price"></span> 7735 </p> 7736 </div> 7737 </div> 7738 </div> 7739 </div> 7740 </template> 7741 </div> 7742 </template> 7743
7744<script> 7745 function initCrossSells() { 7746 return { 7747 active: 0, 7748 itemCount: 0, 7749 crossSellShow: false, 7750 crossSells: {}, 7751 crossSellsItems: {}, 7752 pageSize: 3, 7753 pageFillers: 1, 7754 getSlider() { 7755 return this.$root.querySelector('.js_crosssell_slides'); 7756 }, 7757 getData(data) { 7758 const recommendations = data['product-recommendations']; 7759 this.crossSells = recommendations.crosssells; 7760 7761 if (!this.crossSells) { 7762 return; 7763 } 7764 7765 this.itemCount = this.crossSells.items && this.crossSells.items.length || 0; 7766 this.crossSellShow = this.itemCount > 0; 7767 this.pageFillers = ( 7768 this.pageSize * Math.ceil(this.itemCount / this.pageSize) 7769 ) - this.itemCount; 7770 7771 if(this.crossSellShow) { 7772 this.setCrossSellItems(); 7773 setTimeout(() => this.calcActive(), 1000); 7774 } 7775 }, 7776 calcActive() { 7777 const slider = this.getSlider(); 7778 if (slider) { 7779 const sliderItems = this.itemCount + this.pageFillers; 7780 const calculatedActiveSlide = slider.scrollLeft / (slider.scrollWidth / sliderItems); 7781 this.pageSize = Math.round(slider.clientWidth / slider.querySelector('.js_slide')?.clientWidth); 7782 if (!this.pageSize) { 7783 return; 7784 } 7785 this.active = Math.round(calculatedActiveSlide / this.pageSize) * this.pageSize; 7786 } 7787 }, 7788 setCrossSellItems() { 7789 this.crossSellsItems = this.crossSells.items && this.crossSells.items.sort((a, b) => b.item_id - a.item_id) || []; 7790 }, 7791 scrollPrevious() { 7792 this.scrollTo(this.active - this.pageSize); 7793 }, 7794 scrollNext() { 7795 this.scrollTo(this.active + this.pageSize); 7796 }, 7797 scrollTo(idx) { 7798 const slider = this.getSlider(); 7799 if (slider) { 7800 const slideWidth = slider.scrollWidth / (this.itemCount + this.pageFillers); 7801 const scrollFiller = (idx + this.pageSize) === this.itemCount ? slider.scrollWidth : 0; 7802 slider.scrollLeft = (Math.floor(slideWidth) * idx) + scrollFiller; 7803 7804 this.active = idx; 7805 } 7806 }, 7807 selectedSizes: [], 7808 checkIfSizeIsSelected(product_id){ 7809 return this.selectedSizes.includes(product_id); 7810 }, 7811 addToSelectedSizes(product_id){ 7812 this.selectedSizes.push(product_id); 7813 } 7814 } 7815 } 7816</script>
7816 7817 7818<div 7819 x-show="crossSellShow" 7820 class="md:-mr-8 -mr-4 md:-ml-8 -ml-4 pl-4 md:pl-8 overflow-hidden flex-1" 7821 x-data="initCrossSells()" 7822 @update-button.window="addToSelectedSizes($event.detail.product_id)" 7823 @private-content-loaded.window="getData($event.detail.data)" 7824 @resize.window.debounce="initCrossSells(); $nextTick( function() { calcActive() })" 7825> 7826 <div class="mt-6 -ml-4 md:-ml-8 pl-4 md:pl-8 relative"> 7827 <div class="flex justify-between mb-4 mr-4 pt-6 border-t border-[#d9d9d9]"> 7828 <h3 class="font-medium text-[16px]">Misschien vind je dit ook leuk</h3> 7829 </div> 7830 <div class="flex-none relative"> 7831 <div 7832 class="relative flex flex-nowrap w-full overflow-auto transition-all js_crosssell_slides snap mb-8 pr-cart-slider" 7833 @scroll.debounce="calcActive"> 7834 <template x-for="(item, itemIndex) in crossSellsItems"> 7835 <div class="slider-item flex shrink-0 js_slide crosssell-item"> 7836 <form 7837 class="product_item_addtocart_form item product product-item cell w-full" 7838 method="post" 7839 :action="item.product_add_to_cart_url" 7840 :id="'product_addtocart_form_' + item.product_id" 7841 > 7842 <input name="form_key" type="hidden" :value="hyva.getFormKey()" /> 7843 <input type="hidden" name="product" :value="item.product_id" /> 7844 <div class="product-item-info" data-container="product-grid"> 7845 <div class="product-label-wrapper"> 7846 <template x-if="item.product_label"> 7847 <div class="product-labels absolute top-0 left-0" x-html="item.product_label"></div> 7848 </template> 7849 <a class="product-item-link" :href="item.product_url"> 7850 <img 7851 :src="item.product_image.src" 7852 :width="item.product_image.width" 7853 :height="item.product_image.height" 7854 loading="lazy" 7855 class="w-full h-auto" 7856 /> 7857 </a> 7858 </div> 7859 <div class="product details product-item-details mt-2"> 7860 <div class="flex flex-col"> 7861 <strong class="product name product-item-name"> 7862 <a class="product-item-link min-h-[40px] block md:inline" :href="item.product_url" x-html="item.product_style"></a> 7863 </strong> 7864 <div class="h-6 w-full text-[14px] text-[#2a2a2a] font-normal text-clipped-2" x-text="item.usps"></div> 7865 <div class="mb-2 flex flex-row gap-2"> 7866 <strong 7867 class="text-[16px] font-normal" 7868 :class="{'line-through text-[#ABABAB]' : item.product_special_price_value && (item.product_price_value !== item.product_special_price_value)}" 7869 > 7870 <span x-html="hyva.formatPrice(item.product_price_value)" class="price"></span> 7871 </strong> 7872 <template x-if="item.product_special_price_value && (item.product_price_value !== item.product_special_price_value)"> 7873 <strong class="text-[16px] font-normal text-action">
7874 <span x-html="hyva.formatPrice(item.product_special_price_value)" class="price"></span> 7875 </strong> 7876 </template> 7877 </div> 7878 <div class="flex gap-1 w-full"> 7879 <div 7880 class="flex-1" 7881 x-data="mergedConfigurations()" 7882 :id="'fused_configuration_' + item.product_id" 7883 > 7884 <template x-if="item.options"> 7885 <select 7886 class="flex-1 !h-[36px] !rounded-[12px] border border-[#D9D9D9] py-0 !bg-white grow" 7887 style="background-color: white !important;" 7888 name="fused_configrubales" 7889 x-model="selectedItem" 7890 x-on:change="setHiddenAttributeValues(item.product_id)" 7891 > 7892 7893 <option>Maat</option> 7894 <template x-for="(option) in item.options"> 7895 <option x-html="option.label" :value="option.value" :disabled="!option.in_stock"></option> 7896 </template> 7897 </select> 7898 </template> 7899 <template x-for="(option) in item.options"> 7900 <template x-if="option.is_selected"> 7901 <template x-for="(attribute) in option.attributes"> 7902 <input type="hidden" :name="'super_attribute[' + attribute.id +']'" :value="attribute.value"> 7903 </template> 7904 </template> 7905 </template> 7906 </div> 7907 <button 7908 @submit="getData($event.detail.data)" 7909 class="!w-[36px] !h-[36px] text-center !rounded-[12px] flex justify-center border border-[#D9D9D9] hover:bg-white" 7910 :id="'product_item_list_addtocart_button_' + item.product_id" 7911 type="submit" 7912 :disabled="!checkIfSizeIsSelected(item.product_id)" 7913 :class="{'opacity-30 cursor-not-allowed': !checkIfSizeIsSelected(item.product_id) }" 7914 title="Voeg toe +" 7915 > 7916 <span class="flex flex-col justify-center"> 7917 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 21" class="text-[#2a2a2a]" width="16" height="16" role="img"> 7918 <path stroke="currentColor" stroke-width="1.2" d="m.7 1.2.8 2.6m0 0 3.2 10.7h14.6v-8a2.7 2.7 0 0 0-2.6-2.7H1.5Zm15.2 16a1.3 1.3 0 1 1 0-2.6 1.3 1.3 0 0 1 0 2.6ZM6 18.5a1.3 1.3 0 1 1 2.7 0 1.3 1.3 0 0 1-2.7 0Z"/> 7919<title>cart</title></svg> 7920 </span> 7921 </button> 7922 </div> 7923 </div> 7924 </div> 7925 </div> 7926 </form> 7927 </div> 7928 </template> 7929 </div> 7930 </div> 7931 <div :class="pageSize < itemCount ? '' : 'hidden'" class="cart-crosssell-slider"> 7932 <button 7933 aria-label="Vorige" 7934 tabindex="-1" 7935 class="xl:-mr-6 slider-button !w-10 !h-10 !rounded-[12px] pointer-events-auto opacity-0 z-10 -ml-2" 7936 :class="{ 'opacity-0 pointer-events-none' : active === 0 }" 7937 @click="scrollPrevious">
7938 <span class="flex h-full flex-col justify-center"> 7939 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="24" height="24" role="img"> 7940 <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m15 6-6 6 6 6"/> 7941<title>chevron-left</title></svg> 7942 </span> 7943 </button> 7944 <button 7945 aria-label="Naar volgende stap" 7946 tabindex="-1" 7947 class="xl:-ml-6 slider-button !w-10 !h-10 !rounded-[12px] pointer-events-auto opacity-0 z-10" 7948 :class="{ 'opacity-0 pointer-events-none' : active >= itemCount-pageSize }" 7949 @click="scrollNext"> 7950 <span class="flex h-full flex-col justify-center"> 7951 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="24" height="24" role="img"> 7952 <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m9 18 6-6-6-6"/> 7953<title>chevron-right</title></svg> 7954 </span> 7955 </button> 7956 </div> 7957 </div> 7958</div> 7959 </div> 7960 <div x-cloak class="dialog-bottom sticky bottom-0 z-10"> 7961 <template x-if="totalCartAmount !== 0"> 7962 <div class="space-y-4 shadow-[0px_0px_18px_8px_rgba(0,0,0,0.08)] px-4 md:px-8 bg-[#F4F4F4] py-4"> 7963 <div class="flex justify-between items-center transition duration-150 ease-in-out"> 7964 <p class="font-medium">Subtotaal <span class="font-normal text-sm font-[#666769]">(incl. 21% BTW)</span></p> 7965 <span x-html="cart.subtotal_incl_tax_incl_discount" 7966 class="font-medium"></span> 7967 </div> 7968 <div class="flex justify-between gap-2 flex-col"> 7969 <a 7970 href="https://www.girav.nl/checkout/cart/" 7971 class="btn btn-cart py-3 w-full px-2 flex justify-center text-[18px] h-14 rounded-xl" 7972 > 7973 <span>Bestelling afronden</span> 7974 </a> 7975 <div class="w-full text-center font-medium text-[16px] underline text-[#292929] cursor-pointer" 7976 @click="handleOpenDrawer(false)"> 7977 Verder winkelen </div> 7978 </div> 7979 </div> 7980 </template> 7981 </div> 7982 </div> 7983 </div> 7984 <div class="flex flex-row justify-center items-center w-full h-full absolute select-none" 7985 style="left: 50%;top: 50%;transform: translateX(-50%) translateY(-50%);background: rgba(255,255,255,0.7);" 7986 x-show="isLoading" 7987 x-transition:enter="ease-out duration-200" 7988 x-transition:enter-start="opacity-0" 7989 x-transition:enter-end="opacity-100" 7990 x-transition:leave="ease-in duration-200" 7991 x-transition:leave-start="opacity-100" 7992 x-transition:leave-end="opacity-0"> 7993 <svg xmlns="http://www.w3.org/2000/svg" width="57" height="57" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="text-primary animate-spin" role="img"> 7994 <path d="M21 12a9 9 0 1 1-6.219-8.56"/> 7995<title>loader-2</title></svg> 7996 <div class="ml-10 text-primary text-xl"> 7997 Bezig met laden... </div> 7998</div> 7999 </div> 8000 </template> 8001 8002 <div class="modal px-4 fixed inset-0 z-50 focus-within:ring-1" x-show="modal.open" x-cloak> 8003 <div 8004 class="backdrop" 8005 @click="closeModal()" 8006 @keydown.window.escape="closeModal()"> 8007 </div> 8008 <div class="-translate-y-1/2 bg-white max-w-screen-md p-8 relative top-[50vh] transform w-full mx-auto z-50"> 8009 <button 8010 @click="closeModal()" 8011 class="absolute duration-150 ease-in-out hover:text-black p-2 right-6 text-gray-300 top-6 transition"> 8012 <svg xmlns="http://www.w3.org/2000/svg" width="44" height="44" viewBox="0 0 44 44" fill="none" class="text-[#2a2a2a]" role="img"> 8013 <path d="M28 16L16 28M16 16L28 28" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/> 8014<title>x</title></svg>
8015 <span class="sr-only">Sluiten</span> 8016 </button> 8017 <p>Weet je zeker dat je dit product wilt verwijderen uit je winkelwagen?</p> 8018 <div class="flex gap-4 mt-8"> 8019 <button id="confirmationFocus" class="btn btn-secondary focus:ring-2" @click="closeModal()"> 8020 Annuleer </button> 8021 <button class="btn btn-secondary focus:ring-2" @click="deleteItemFromCart(modal.item)"> 8022 OK </button> 8023 </div> 8024 </div> 8025 </div> 8026</section> 8027</div>
8027<script type="text/x-magento-init">{"*": 8028 {"Magento_Persistent/js/remember-me-config": { 8029 "config": {"persistenceConfig":{"isRememberMeCheckboxVisible":true,"isRememberMeCheckboxChecked":true}} 8030 }}}</script>
8030</body> 8031</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.