holdkarte=karte; function tagundmonatloop() { //////////////////////////////////////////////////////////////////// if(document.getElementById('timkarte')) { if(document.getElementById('timkarte').selectedIndex==2) { document.getElementById('alwayscard').style.display='block'; if(karte!=kartef)setTimeout("validate()",111); karte=kartef; document.getElementById('kartxt').innerHTML=document.getElementById('kartxt').innerHTML.replace(/Karte/,'ᴋᴀʀᴛᴇɴ'+' ('+document.form1.timrepeat.value+')'); document.getElementById('kartxt').innerHTML=document.getElementById('kartxt').innerHTML.replace(/card/,'ᴄᴀʀᴅs'+' ('+document.form1.timrepeat.value+')'); document.getElementById('kartxt').innerHTML=document.getElementById('kartxt').innerHTML.replace(/carte/,'ᴄᴀʀᴛᴇs'+' ('+document.form1.timrepeat.value+')'); } else { document.getElementById('alwayscard').style.display='none'; karte=holdkarte; } } //////////////////////////////////////////////////////////////////// tagundmonat(); if(whodelivers=='post') { document.getElementById('pexinfo').innerHTML="Pour la destination "+document.form1.toplz.value+" "+document.form1.toort.value+", la livraison est effectuée par colis express  ; les frais de livraison qui en résultent s'élèvent au total à "+document.getElementById("lieferung").innerHTML+" Si vous souhaitez une livraison plus économique par un magasin partenaire de Fleurop, veuillez indiquer le mot FLEUROP dans le champ «Instructions de livraison« ci-dessous.

"; } else document.getElementById('pexinfo').innerHTML=''; if(document.form1.prechf) { if(document.form1.prechf.value/document.form1.timrepeat.value0) { document.getElementsByTagName('table')[4].style.marginTop='-22px'; document.getElementsByTagName('table')[6].style.marginTop='-80px'; } else { document.getElementsByTagName('table')[5].style.marginTop='-22px'; document.getElementsByTagName('table')[7].style.marginTop='-55px'; } setTimeout("tagundmonatloop()",1111); } function tagundmonat() { womostring=document.getElementById('timwomo').innerHTML; if(location.href.indexOf("mobile.php")>0) { womostring=womostring.replace(/WOCHENTAG/g,document.getElementById('zeigwt').innerHTML.toUpperCase().substring(0,2)); womostring=womostring.replace(/MO/g,document.getElementById('zeigwt').innerHTML.toUpperCase().substring(0,2)); womostring=womostring.replace(/DI/g,document.getElementById('zeigwt').innerHTML.toUpperCase().substring(0,2)); womostring=womostring.replace(/MI/g,document.getElementById('zeigwt').innerHTML.toUpperCase().substring(0,2)); womostring=womostring.replace(/DO/g,document.getElementById('zeigwt').innerHTML.toUpperCase().substring(0,2)); womostring=womostring.replace(/FR/g,document.getElementById('zeigwt').innerHTML.toUpperCase().substring(0,2)); womostring=womostring.replace(/SA/g,document.getElementById('zeigwt').innerHTML.toUpperCase().substring(0,2)); womostring=womostring.replace(/SO/g,document.getElementById('zeigwt').innerHTML.toUpperCase().substring(0,2)); womostring=womostring.replace(/MO/g,document.getElementById('zeigwt').innerHTML.toUpperCase().substring(0,2)); womostring=womostring.replace(/TU/g,document.getElementById('zeigwt').innerHTML.toUpperCase().substring(0,2)); womostring=womostring.replace(/WE/g,document.getElementById('zeigwt').innerHTML.toUpperCase().substring(0,2)); womostring=womostring.replace(/TH/g,document.getElementById('zeigwt').innerHTML.toUpperCase().substring(0,2)); womostring=womostring.replace(/FR/g,document.getElementById('zeigwt').innerHTML.toUpperCase().substring(0,2)); womostring=womostring.replace(/SA/g,document.getElementById('zeigwt').innerHTML.toUpperCase().substring(0,2)); womostring=womostring.replace(/SU/g,document.getElementById('zeigwt').innerHTML.toUpperCase().substring(0,2)); womostring=womostring.replace(/LU/g,document.getElementById('zeigwt').innerHTML.toUpperCase().substring(0,2)); womostring=womostring.replace(/MA/g,document.getElementById('zeigwt').innerHTML.toUpperCase().substring(0,2)); womostring=womostring.replace(/ME/g,document.getElementById('zeigwt').innerHTML.toUpperCase().substring(0,2)); womostring=womostring.replace(/JE/g,document.getElementById('zeigwt').innerHTML.toUpperCase().substring(0,2)); womostring=womostring.replace(/VE/g,document.getElementById('zeigwt').innerHTML.toUpperCase().substring(0,2)); womostring=womostring.replace(/SA/g,document.getElementById('zeigwt').innerHTML.toUpperCase().substring(0,2)); womostring=womostring.replace(/DI/g,document.getElementById('zeigwt').innerHTML.toUpperCase().substring(0,2)); } else { womostring=womostring.replace(/WOCHENTAG/g,document.getElementById('zeigwt').innerHTML.toUpperCase()); womostring=womostring.replace(/MONTAG/g,document.getElementById('zeigwt').innerHTML.toUpperCase()); womostring=womostring.replace(/DIENSTAG/g,document.getElementById('zeigwt').innerHTML.toUpperCase()); womostring=womostring.replace(/MITTWOCH/g,document.getElementById('zeigwt').innerHTML.toUpperCase()); womostring=womostring.replace(/DONNERSTAG/g,document.getElementById('zeigwt').innerHTML.toUpperCase()); womostring=womostring.replace(/FREITAG/g,document.getElementById('zeigwt').innerHTML.toUpperCase()); womostring=womostring.replace(/SAMSTAG/g,document.getElementById('zeigwt').innerHTML.toUpperCase()); womostring=womostring.replace(/SONNTAG/g,document.getElementById('zeigwt').innerHTML.toUpperCase()); womostring=womostring.replace(/MONDAY/g,document.getElementById('zeigwt').innerHTML.toUpperCase()); womostring=womostring.replace(/TUESDAY/g,document.getElementById('zeigwt').innerHTML.toUpperCase()); womostring=womostring.replace(/WEDNESDAY/g,document.getElementById('zeigwt').innerHTML.toUpperCase()); womostring=womostring.replace(/THURSDAY/g,document.getElementById('zeigwt').innerHTML.toUpperCase()); womostring=womostring.replace(/FRIDAY/g,document.getElementById('zeigwt').innerHTML.toUpperCase()); womostring=womostring.replace(/SATURDAY/g,document.getElementById('zeigwt').innerHTML.toUpperCase()); womostring=womostring.replace(/SUNDAY/g,document.getElementById('zeigwt').innerHTML.toUpperCase()); womostring=womostring.replace(/LUNDI/g,document.getElementById('zeigwt').innerHTML.toUpperCase()); womostring=womostring.replace(/MARDI/g,document.getElementById('zeigwt').innerHTML.toUpperCase()); womostring=womostring.replace(/MERCREDI/g,document.getElementById('zeigwt').innerHTML.toUpperCase()); womostring=womostring.replace(/JEUDI/g,document.getElementById('zeigwt').innerHTML.toUpperCase()); womostring=womostring.replace(/VENDREDI/g,document.getElementById('zeigwt').innerHTML.toUpperCase()); womostring=womostring.replace(/SAMEDI/g,document.getElementById('zeigwt').innerHTML.toUpperCase()); womostring=womostring.replace(/DIMANCHE/g,document.getElementById('zeigwt').innerHTML.toUpperCase()); } womostring=womostring.replace(/31/g,'DDDDDDD'); womostring=womostring.replace(/30/g,'DDDDDDD'); womostring=womostring.replace(/29/g,'DDDDDDD'); womostring=womostring.replace(/28/g,'DDDDDDD'); womostring=womostring.replace(/27/g,'DDDDDDD'); womostring=womostring.replace(/26/g,'DDDDDDD'); womostring=womostring.replace(/25/g,'DDDDDDD'); womostring=womostring.replace(/24/g,'DDDDDDD'); womostring=womostring.replace(/23/g,'DDDDDDD'); womostring=womostring.replace(/22/g,'DDDDDDD'); womostring=womostring.replace(/21/g,'DDDDDDD'); womostring=womostring.replace(/20/g,'DDDDDDD'); womostring=womostring.replace(/19/g,'DDDDDDD'); womostring=womostring.replace(/18/g,'DDDDDDD'); womostring=womostring.replace(/17/g,'DDDDDDD'); womostring=womostring.replace(/16/g,'DDDDDDD'); womostring=womostring.replace(/15/g,'DDDDDDD'); womostring=womostring.replace(/14/g,'DDDDDDD'); womostring=womostring.replace(/13/g,'DDDDDDD'); womostring=womostring.replace(/12/g,'DDDDDDD'); womostring=womostring.replace(/11/g,'DDDDDDD'); womostring=womostring.replace(/10/g,'DDDDDDD'); womostring=womostring.replace(/9/g,'DDDDDDD'); womostring=womostring.replace(/8/g,'DDDDDDD'); womostring=womostring.replace(/7/g,'DDDDDDD'); womostring=womostring.replace(/6/g,'DDDDDDD'); womostring=womostring.replace(/5/g,'DDDDDDD'); womostring=womostring.replace(/4/g,'DDDDDDD'); womostring=womostring.replace(/3/g,'DDDDDDD'); womostring=womostring.replace(/2/g,'DDDDDDD'); womostring=womostring.replace(/1/g,'DDDDDDD'); womostring=womostring.replace(/DDDDDDD/g,document.getElementById('d').value); if(document.getElementById('timwomo').innerHTML!=womostring)document.getElementById('timwomo').innerHTML=womostring; } function validaterepeat() { if(document.getElementById('form1') && location.href.indexOf('s_order')<0) { if(document.getElementById('timkarte')) { if(document.getElementById('timkarte').selectedIndex==2)document.form1.kok.value=document.form1.kok.value*document.form1.timrepeat.value-0; if(document.getElementById('timkarte').selectedIndex>0)document.form1.kar[0].click(); else document.form1.kar[1].click(); } validateplz(); document.form1.kol.value=document.form1.kol.value*document.form1.timrepeat.value-0; if(document.form1.kol.value==='NaN')document.form1.kol.value=7*document.form1.timrepeat.value-0; if(document.form1.vas[0].checked)document.form1.kov.value=Math.floor((2.5*karte+0.2*document.form1.prechf.value/document.form1.timrepeat.value-0)); else document.form1.kov.value=0; document.form1.kot.value=(document.form1.prechf.value-0)+(document.form1.kok.value-0)+(document.form1.kov.value-0)+(document.form1.kol.value-0); } } function timrepval() { document.form1.wae.value=document.form1.timwae.value document.form1.pre.value=document.form1.timpre.value*document.form1.timrepeat.value document.form1.timrem.value='Subscription Abo: '+document.form1.timrepeat.value+'x '+document.form1.timpre.value+' '+document.form1.timwae.value.toUpperCase()+' '+document.form1.timjeden.value+' '+document.form1.timwomo.value+'; '+document.form1.timclosed.value+' '+String.fromCharCode(11044)+' '+document.form1.timdesc.value+' '+String.fromCharCode(11044)+' '+document.form1.timkarte.value+' '+String.fromCharCode(11044)+' '+document.form1.timremnew.value+' '; document.form1.timrem.value=document.form1.timrem.value.replace(/\s\s+/g,' '); if(document.getElementById('proapri'))document.getElementById('proapri').style.display='none'; if(document.getElementById('timkarte')) { if(document.getElementById('timkarte').selectedIndex==0) { if(document.getElementById('trkar1'))document.getElementById('trkar1').style.display='none'; if(document.getElementById('trkar2'))document.getElementById('trkar2').style.display='none'; if(document.getElementById('trkar3'))document.getElementById('trkar3').style.display='none'; } } if(document.getElementById('TrScLf'))document.getElementById('TrScLf').style.display='none'; if(document.getElementById('destination'))document.getElementById('destination').style.display='none'; if(document.getElementById('ttitle1'))document.getElementById('ttitle1').innerHTML='Première livraison le (arrivée)'; } function isInViewport(element) { var rect = element.getBoundingClientRect(); var html = document.documentElement; return ( rect.top >= 0 && rect.left >= 0 && rect.bottom <= (window.innerHeight || html.clientHeight) && rect.right <= (window.innerWidth || html.clientWidth) ); } function flashzeigtag() { if(!isInViewport(document.getElementById('zeigwt'))){document.getElementById('zeigwt').scrollIntoView();window.scrollBy(0,-100);} if(location.href.indexOf('mobile.php')>0)window.scrollBy(0,-50); document.getElementById('zeigwt').style.background='yellow'; setTimeout("document.getElementById('zeigwt').style.background='transparent'",777); setTimeout("document.getElementById('zeigwt').style.background='yellow'",777*2); setTimeout("document.getElementById('zeigwt').style.background='transparent'",777*3); setTimeout("document.getElementById('zeigwt').style.background='yellow'",777*4); setTimeout("document.getElementById('zeigwt').style.background='transparent'",777*5); setTimeout("document.getElementById('zeigwt').style.background='yellow'",777*6); setTimeout("document.getElementById('zeigwt').style.background='transparent'",777*7); setTimeout("document.getElementById('zeigwt').style.background='yellow'",777*8); setTimeout("document.getElementById('zeigwt').style.background='transparent'",777*9); setTimeout("document.getElementById('zeigwt').style.background='yellow'",777*10); setTimeout("document.getElementById('zeigwt').style.background='transparent'",777*11); setTimeout("document.getElementById('zeigwt').style.background='yellow'",777*12); setTimeout("document.getElementById('zeigwt').style.background='transparent'",777*13); setTimeout("document.getElementById('zeigwt').style.background='yellow'",777*14); setTimeout("document.getElementById('zeigwt').style.background='transparent'",777*15); setTimeout("document.getElementById('zeigwt').style.background='yellow'",777*16); setTimeout("document.getElementById('zeigwt').style.background='transparent'",777*17); } if(document.getElementById('form1') && location.href.indexOf('s_order')<0) { setTimeout("tagundmonatloop()",1111); setTimeout("timrepval()",111); setTimeout("tagundmonat()",222); andererwochentag="Dans le commutateur de sélection de la périodicité, le jour de la semaine de la date de la première livraison est pris en compte, que vous avez fixé ci-dessus.\n\nVeuillez fixer la date de la première livraison de manière à ce que le jour de la semaine (du lundi au samedi) convienne également aux livraisons suivantes."; document.getElementById('trtimrem').innerHTML='\ \ \ Prix par bouquet
\ \ \
Nombre d’exécutions et périodicité
\ \
\
\
Autre jour de la semaine?
\ \
Instructions de livraison (facultatif)
\
\ Sans indication contraire de votre part, nous joignons la fiche informative lors de la première livraison.
\ \

Description de ce que le destinataire aime et n’aime pas.\ Exemples\
\ \

Carte de vœux
\ \ \ \ '; if(location.href.indexOf('h=')>0) { document.getElementById('trtimrem').innerHTML+=''; setTimeout("document.getElementById('verlang').src='aa.php?h='+location.href.split('h=')[1]",1111); } //if(location.href.indexOf("mobile.php")>0)document.getElementById("timwomo").style.fontSize="80%"; } setTimeout("if(document.getElementById('TrScLf'))document.getElementById('TrScLf').style.display='none'",1111); setTimeout("if(document.getElementsByClassName('detailtext')[0])document.getElementsByClassName('detailtext')[0].style.display='none'",111); setTimeout("if(document.getElementsByClassName('detailtext')[0])document.getElementsByClassName('detailtext')[0].style.display='none'",1111); if(location.href.indexOf('s_order')>0)document.getElementById('trtimrem').innerHTML+=''; if(location.href.indexOf('s_order')>0) { person='ja'; if(person=='ja'&&location.href.indexOf('beilagen')<0) { setTimeout("if(document.getElementById('chkbei'))if(document.getElementById('dbeilauti'))document.getElementById('dbeilauti').innerHTML=''",777); setTimeout("if(document.getElementById('chkbei'))if(document.getElementById('mbeilauti'))document.getElementById('mbeilauti').innerHTML=''",777); } } setTimeout("if(location.href.indexOf('&id=1332&')>0 && document.getElementById('otherh1'))document.getElementById('otherh1').innerHTML='Abonnement'",1111); setTimeout("if(document.form1.bei)if(location.href.indexOf('s_order')<0)document.form1.bei[1].click()",1111); setTimeout("if(document.getElementById('dbeilauti'))document.getElementById('dbeilauti').style.display='none'",1); setTimeout("if(document.getElementById('mbeilauti'))document.getElementById('mbeilauti').style.display='none'",1); ///////////////////////////////////// function setSessionCookie(n,v){document.cookie=encodeURIComponent(n)+"="+encodeURIComponent(v)+"; path=/";} function getSessionCookie(n){for(let c of document.cookie.split(";")){let[a,b]=c.trim().split("=");if(a===decodeURIComponent(n))return decodeURIComponent(b);}return null;} document.addEventListener("DOMContentLoaded",function(){ const s=document.getElementById("timwomo");if(!s)return; s.addEventListener("change",()=>setSessionCookie("timwomo_value",s.value)); const v=getSessionCookie("timwomo_value"); if(v!==null && location.href.indexOf("x=")!==-1)setTimeout(()=>{s.value=v;s.dispatchEvent(new Event("change"));},5555); }); //////////////////////////////////// (function () { var isMobilePhp = location.href.indexOf('mobile.php') !== -1; function styleSelectById(id, fontSize) { var select = document.getElementById(id); if (!select) return; styleSelect(select, fontSize); } function styleSelect(select, fontSize) { select.style.textAlign = 'center'; select.style.textAlignLast = 'center'; select.style.marginTop = '5px'; select.style.marginBottom = '3px'; select.style.fontSize = fontSize; for (var i = 0; i < select.options.length; i++) { select.options[i].style.textAlign = 'center'; } } function styleTimrepeatEndState(el) { if (!el) return; el.style.textAlign = 'center'; el.style.textAlignLast = 'center'; el.style.fontSize = '200%'; el.style.marginTop = '12px'; el.style.marginBottom = '12px'; el.style.borderRadius = '10px'; el.style.padding = '4px 8px'; el.style.backgroundColor = '#fff6cf'; el.style.outline = '1px solid rgba(170,130,45,0.42)'; el.style.outlineOffset = '3px'; el.style.boxShadow = '0 0 10px rgba(180,140,60,0.14)'; for (var i = 0; i < el.options.length; i++) { el.options[i].style.textAlign = 'center'; } } styleSelectById('timwomo', isMobilePhp ? '100%' : '130%'); styleSelectById('timjeden', '130%'); styleSelectById('timclosed', '100%'); var repeats = document.getElementsByName('timrepeat'); for (var i = 0; i < repeats.length; i++) { styleTimrepeatEndState(repeats[i]); } })();(function() { if ( location.href.indexOf('a=z') <= 0 || (/[?&]x=/.test(location.search) && !/[?&]x=0(?:&|$)/.test(location.search)) ) return; function getTarget() { return document.getElementsByName('timrepeat')[0]; } function setTargetPosition(el) { if (!el || !el.options || el.options.length <= 9) return; el.selectedIndex = 9; } function waitUntilTargetIsReady(callback) { var stableCount = 0; var maxTries = 50; var lastTop = null; var lastHeight = null; function check() { var el = getTarget(); setTargetPosition(el); if (!el || !document.body.contains(el)) { if (maxTries-- > 0) setTimeout(check, 100); return; } var rect = el.getBoundingClientRect(); var currentTop = Math.round(rect.top); var currentHeight = Math.round(rect.height); if ( currentHeight > 0 && currentTop === lastTop && currentHeight === lastHeight ) { stableCount++; } else { stableCount = 0; lastTop = currentTop; lastHeight = currentHeight; } if (stableCount >= 2 || maxTries-- <= 0) { callback(el); } else { setTimeout(check, 120); } } check(); } function ensureHighlightStyle() { if (document.getElementById('timrepeat-highlight-style')) return; var style = document.createElement('style'); style.id = 'timrepeat-highlight-style'; style.innerHTML = '@keyframes timrepeatElegantBloom {' + ' 0% { transform: scale(1); box-shadow: 0 0 0 rgba(190,145,30,0); }' + ' 24% { transform: scale(1.030); box-shadow: 0 0 28px rgba(190,145,30,0.42); }' + ' 52% { transform: scale(1.012); box-shadow: 0 0 38px rgba(190,145,30,0.50); }' + ' 76% { transform: scale(1.020); box-shadow: 0 0 24px rgba(190,145,30,0.34); }' + ' 100% { transform: scale(1); box-shadow: 0 0 16px rgba(190,145,30,0.24); }' + '}' + '@keyframes timrepeatElegantGlowOnce {' + ' 0% { background-color: #fff2ad; }' + ' 45% { background-color: #ffe680; }' + ' 100% { background-color: #fff6cf; }' + '}'; document.head.appendChild(style); } function easeInOutCubic(t) { return t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2; } function slowScrollToElement(el, duration) { var rect = el.getBoundingClientRect(); var startY = window.pageYOffset || document.documentElement.scrollTop || 0; var targetY = startY + rect.top - ((window.innerHeight - rect.height) / 2); var diff = targetY - startY; var startTime = null; function step(timestamp) { if (!startTime) startTime = timestamp; var elapsed = timestamp - startTime; var progress = Math.min(elapsed / duration, 1); var eased = easeInOutCubic(progress); window.scrollTo(0, startY + diff * eased); if (progress < 1) { window.requestAnimationFrame(step); } } window.requestAnimationFrame(step); } function prepareTarget(el) { el.style.fontSize = '12px'; el.style.borderRadius = '8px'; el.style.padding = '3px 7px'; el.style.marginTop = '12px'; el.style.marginBottom = '12px'; el.style.backgroundColor = '#fff9d8'; el.style.outline = '1px solid rgba(185,140,35,0.30)'; el.style.outlineOffset = '3px'; el.style.boxShadow = '0 0 0 rgba(190,145,30,0)'; el.style.transition = 'font-size 850ms ease, ' + 'background-color 950ms ease, ' + 'box-shadow 950ms ease, ' + 'transform 950ms ease, ' + 'outline-color 950ms ease, ' + 'outline-offset 950ms ease'; } function highlightTarget(el) { ensureHighlightStyle(); var originalTransition = el.style.transition; var originalTransform = el.style.transform; prepareTarget(el); setTargetPosition(el); requestAnimationFrame(function() { setTargetPosition(el); el.style.fontSize = '400%'; el.style.borderRadius = '14px'; el.style.padding = '6px 12px'; el.style.backgroundColor = '#ffe680'; el.style.outline = '1px solid rgba(185,140,35,0.78)'; el.style.outlineOffset = '5px'; el.style.boxShadow = '0 0 32px rgba(190,145,30,0.42)'; el.style.animation = 'timrepeatElegantBloom 1500ms ease-in-out 0s 1'; }); setTimeout(function() { setTargetPosition(el); el.style.fontSize = '200%'; el.style.borderRadius = '10px'; el.style.padding = '4px 8px'; el.style.backgroundColor = '#fff2ad'; el.style.outline = '1px solid rgba(185,140,35,0.58)'; el.style.outlineOffset = '4px'; el.style.boxShadow = '0 0 18px rgba(190,145,30,0.26)'; }, 880); setTimeout(function() { el.style.animation = 'timrepeatElegantGlowOnce 1500ms ease-in-out 0s 1'; }, 1800); setTimeout(function() { el.style.animation = ''; el.style.transition = 'font-size 900ms ease, ' + 'background-color 1300ms ease, ' + 'box-shadow 1300ms ease, ' + 'transform 900ms ease, ' + 'outline-color 1300ms ease, ' + 'outline-offset 1300ms ease'; el.style.fontSize = '200%'; el.style.backgroundColor = '#fff6cf'; el.style.outline = '1px solid rgba(170,130,45,0.42)'; el.style.outlineOffset = '3px'; el.style.boxShadow = '0 0 10px rgba(180,140,60,0.14)'; el.style.transform = originalTransform; }, 3400); setTimeout(function() { el.style.transition = originalTransition; }, 4900); } function run(el) { setTargetPosition(el); prepareTarget(el); setTimeout(function() { setTargetPosition(el); slowScrollToElement(el, 1500); }, 120); setTimeout(function() { setTargetPosition(el); try { el.focus({ preventScroll: true }); } catch (e) { el.focus(); } highlightTarget(el); }, 1050); } function start() { waitUntilTargetIsReady(run); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', start); } else { start(); } window.addEventListener('load', function() { if (!getTarget()) start(); }); })(); (function () { function findAboParam() { return document.getElementById('aboparam') || document.querySelector('[name="aboparam"]') || document.querySelector('.aboparam'); } function start() { var box = findAboParam(); if (!box) { window.setTimeout(start, 300); return; } if (box._aboBotanicalCanvasStarted) return; box._aboBotanicalCanvasStarted = true; var CFG = { fps: 18, opacity: 0.70, dprMax: 1.5, growth: { startFastMs: 65000, buildMs: 190000, matureMs: 420000, earlyGrowDelay: [125, 275], buildGrowDelay: [360, 760], matureGrowDelay: [1200, 2600], calmGrowDelay: [4200, 8200], mainSeedUntilMs: 180000, mainSeedDelay: [4200, 8200], refreshDelayBuild: [1300, 2600], refreshDelayCalm: [2800, 5600] }, structure: { mainStraightness: 0.58, mainTargetPull: 0.26, mainPreviousAngleMemory: 0.16, mainRandomness: 0.044, verticalTargetLeftDrift: [0.006, 0.055], verticalTargetRightDrift: [-0.055, -0.006], verticalTargetNeutralDrift: [-0.026, 0.026], verticalTargetEarlyLift: [0.24, 0.37], verticalTargetLaterLift: [0.13, 0.25], lowerBranchLimit: 0.34, lowerBranchSuppression: 0.58, branchOpenFromMain: [0.86, 1.14], branchOpenFromBranch: [0.70, 1.00], branchRandomness: 0.048, upperBranchLengthFromMain: [40, 72], upperBranchLengthFromBranch: [27, 50], lowerBranchLengthFromMain: [12, 22], lowerBranchLengthFromBranch: [7, 16], upperHeightFactor: 0.42, mainLength: [34, 58], secondaryMainLength: [25, 44], sprayLength: [17, 34], mainBend: 0.16, branchBend: 0.14, decorativeTipChance: 0.56, decorativeTipStrength: [0.60, 0.84], structuralTipStrength: [0.88, 0.98], earlyMainTipPreferenceMs: 48000, earlyMainTipPreference: 0.62, lateMainTipPreference: 0.22 }, bouquet: { centerY: 0.41, radiusX: 0.68, radiusY: 0.68, generousRadiusX: 0.82, generousRadiusY: 0.82, bottomFreeY: 0.97 }, floristry: { leafDensityMain: 1, leafDensityStructural: 2, leafDensityBranch: 2, leafSkipBranchChance: 0.07, longLeafChance: 0.50, leafDistributionJitter: 0.15, leafDistributionMin: 0.12, leafDistributionMax: 0.96, leafAngleFromStem: [0.42, 0.74], leafLifeMain: [1100000, 1900000], leafLifeBranch: [1000000, 1800000], budChanceOnMain: 0.18, budChanceOnBranch: 0.60, flowerChanceOnMain: 0.11, flowerChanceOnBranch: 0.60, sprayChanceOnBranch: 0.44, budLife: [1000000, 1800000], flowerLife: [1100000, 2000000], sprayLife: [950000, 1700000], crownRefreshStartMs: 18000, crownRefreshBuildChance: 0.78, crownRefreshCalmChance: 0.72, crownX: [0.08, 0.92], crownY: [0.04, 0.62] }, freshness: { fadeStart: 0.975, minimumFade: 0.76, maxStems: 720, maxLeaves: 2100, maxBuds: 520, maxFlowers: 760, maxSprays: 340, maxTips: 220 }, visual: { backgroundAlpha: 0.008, stemColor: [44, 118, 48], stemHighlightColor: [126, 168, 76], leafColorA: [54, 138, 58], leafColorB: [69, 152, 64], leafColorC: [92, 152, 60], leafVeinColor: [32, 90, 36], budColor: [176, 202, 48], budLightColor: [255, 238, 80], flowerPaleColor: [255, 255, 178], flowerWarmColor: [255, 224, 0], flowerGreenColor: [246, 238, 86], flowerCenterColor: [210, 148, 0], sprayStemColor: [72, 136, 58], sprayDotColor: [255, 232, 62], softBackgroundColor: [118, 156, 76] } }; if (!box.style.position || box.style.position === 'static') { box.style.position = 'relative'; } box.style.overflow = 'visible'; var canvasBleed = Math.max(18, Math.round(box.getBoundingClientRect().width * 0.045)); var canvas = document.createElement('canvas'); canvas.setAttribute('aria-hidden', 'true'); canvas.style.position = 'absolute'; canvas.style.left = '-' + canvasBleed + 'px'; canvas.style.top = '0'; canvas.style.width = 'calc(100% + ' + (canvasBleed * 2) + 'px)'; canvas.style.height = '100%'; canvas.style.pointerEvents = 'none'; canvas.style.zIndex = '0'; canvas.style.opacity = String(CFG.opacity); box.insertBefore(canvas, box.firstChild); var children = box.children; for (var i = 0; i < children.length; i++) { if (children[i] !== canvas) { children[i].style.position = 'relative'; children[i].style.zIndex = '0'; } } var ctx = canvas.getContext('2d'); if (!ctx) return; var w = 0; var h = 0; var dpr = Math.min(window.devicePixelRatio || 1, CFG.dprMax); var startedAt = performance.now(); var stems = []; var leaves = []; var buds = []; var flowers = []; var sprays = []; var tips = []; var lastFrame = 0; var nextGrowAt = 0; var nextMainSeedAt = 0; var nextRefreshAt = 0; var nextCleanupAt = 0; var frameInterval = 1000 / CFG.fps; function rnd(min, max) { return min + Math.random() * (max - min); } function rndRange(a) { return rnd(a[0], a[1]); } function clamp(v, min, max) { return Math.max(min, Math.min(max, v)); } function rgba(rgb, alpha) { return 'rgba(' + rgb[0] + ',' + rgb[1] + ',' + rgb[2] + ',' + alpha.toFixed(3) + ')'; } function easeOutCubic(t) { t = clamp(t, 0, 1); return 1 - Math.pow(1 - t, 3); } function easeOutQuart(t) { t = clamp(t, 0, 1); return 1 - Math.pow(1 - t, 4); } function normalizeAngle(a) { while (a <= -Math.PI) a += Math.PI * 2; while (a > Math.PI) a -= Math.PI * 2; return a; } function weightedAngle(a, b, c, wa, wb, wc) { var x = Math.cos(a) * wa + Math.cos(b) * wb + Math.cos(c) * wc; var y = Math.sin(a) * wa + Math.sin(b) * wb + Math.sin(c) * wc; return Math.atan2(y, x); } function scheduleGrow(now) { var age = now - startedAt; var delay; if (age < CFG.growth.startFastMs) { delay = rndRange(CFG.growth.earlyGrowDelay); } else if (age < CFG.growth.buildMs) { delay = rndRange(CFG.growth.buildGrowDelay); } else if (age < CFG.growth.matureMs) { delay = rndRange(CFG.growth.matureGrowDelay); } else { delay = rndRange(CFG.growth.calmGrowDelay); } nextGrowAt = now + delay; } function scheduleMainSeed(now) { nextMainSeedAt = now + rndRange(CFG.growth.mainSeedDelay); } function scheduleRefresh(now) { var age = now - startedAt; var delay = age < CFG.growth.buildMs ? rndRange(CFG.growth.refreshDelayBuild) : rndRange(CFG.growth.refreshDelayCalm); nextRefreshAt = now + delay; } function bouquetCenterY() { return h * CFG.bouquet.centerY; } function insideBouquet(x, y, generous) { if (!w || !h) return true; var cx = w * 0.50; var cy = bouquetCenterY(); var rx = w * (generous ? CFG.bouquet.generousRadiusX : CFG.bouquet.radiusX); var ry = h * (generous ? CFG.bouquet.generousRadiusY : CFG.bouquet.radiusY); var dx = (x - cx) / rx; var dy = (y - cy) / ry; if (y > h * CFG.bouquet.bottomFreeY) return true; return dx * dx + dy * dy <= (generous ? 1.24 : 1.12); } function verticalPull(x, y, side, age) { var phase = Math.min(1, age / 52000); var targetX; if (side === 'left') { targetX = x + rnd(w * CFG.structure.verticalTargetLeftDrift[0], w * CFG.structure.verticalTargetLeftDrift[1]); } else if (side === 'right') { targetX = x + rnd(w * CFG.structure.verticalTargetRightDrift[0], w * CFG.structure.verticalTargetRightDrift[1]); } else { targetX = x + rnd(w * CFG.structure.verticalTargetNeutralDrift[0], w * CFG.structure.verticalTargetNeutralDrift[1]); } targetX = clamp(targetX, w * 0.07, w * 0.93); var lift = phase < 0.55 ? rndRange(CFG.structure.verticalTargetEarlyLift) : rndRange(CFG.structure.verticalTargetLaterLift); var targetY = y - h * lift; targetY = clamp(targetY, h * 0.08, h * 0.98); return Math.atan2(targetY - y, targetX - x); } function scaleItem(item, sx, sy) { var keysX = ['x', 'x1', 'x2', 'c1x', 'c2x']; var keysY = ['y', 'y1', 'y2', 'c1y', 'c2y']; for (var i = 0; i < keysX.length; i++) { if (typeof item[keysX[i]] === 'number') item[keysX[i]] *= sx; } for (var j = 0; j < keysY.length; j++) { if (typeof item[keysY[j]] === 'number') item[keysY[j]] *= sy; } } function resize(keepPlant) { var oldW = w || 1; var oldH = h || 1; var rect = box.getBoundingClientRect(); canvasBleed = Math.max(18, Math.round(rect.width * 0.045)); canvas.style.left = '-' + canvasBleed + 'px'; canvas.style.width = 'calc(100% + ' + (canvasBleed * 2) + 'px)'; w = Math.max(1, Math.floor(rect.width + canvasBleed * 2)); h = Math.max(1, Math.floor(rect.height)); canvas.width = Math.floor(w * dpr); canvas.height = Math.floor(h * dpr); ctx.setTransform(dpr, 0, 0, dpr, 0, 0); if (keepPlant && tips.length && oldW > 1 && oldH > 1) { var sx = w / oldW; var sy = h / oldH; for (var i = 0; i < stems.length; i++) scaleItem(stems[i], sx, sy); for (var j = 0; j < leaves.length; j++) scaleItem(leaves[j], sx, sy); for (var k = 0; k < buds.length; k++) scaleItem(buds[k], sx, sy); for (var l = 0; l < flowers.length; l++) scaleItem(flowers[l], sx, sy); for (var m = 0; m < sprays.length; m++) scaleItem(sprays[m], sx, sy); for (var n = 0; n < tips.length; n++) scaleItem(tips[n], sx, sy); } else { seed(); } } function seed() { stems = []; leaves = []; buds = []; flowers = []; sprays = []; tips = []; startedAt = performance.now(); var now = startedAt; addMainTip(w * 0.060, h * 0.990, 'left', 1.18, now, true); addMainTip(w * 0.145, h * 0.985, 'left', 1.06, now + 90, true); addMainTip(w * 0.235, h * 0.975, 'left', 0.94, now + 180, false); addMainTip(w * 0.940, h * 0.990, 'right', 1.18, now + 45, true); addMainTip(w * 0.855, h * 0.985, 'right', 1.06, now + 135, true); addMainTip(w * 0.765, h * 0.975, 'right', 0.94, now + 225, false); scheduleGrow(now); scheduleMainSeed(now); scheduleRefresh(now); nextCleanupAt = now + 4200; } function addMainTip(x, y, side, strength, now, strong) { var angle = -Math.PI / 2 + rnd(-0.030, 0.030); var tip = { x: x + rnd(-3, 3), y: y + rnd(-3, 1), angle: angle, generation: 0, strength: strength, side: side, main: true, decorative: false, born: now }; tips.push(tip); addStem(now, tip, true, true, strong ? 'main' : 'secondary'); if (Math.random() < 0.70) { addStem(now + rnd(220, 620), tip, true, false, 'secondary'); } } function addBottomSeed(now, preferredSide) { var side = preferredSide || (Math.random() < 0.5 ? 'left' : 'right'); var x; if (side === 'left') { x = rnd(w * 0.045, w * 0.225); } else { x = rnd(w * 0.775, w * 0.955); } var tip = { x: x, y: rnd(h * 0.930, h * 0.995), angle: -Math.PI / 2 + rnd(-0.030, 0.030), generation: 0, strength: rnd(0.84, 1.06), side: side, main: true, decorative: false, born: now }; tips.push(tip); addStem(now, tip, true, true, 'main'); if (Math.random() < 0.44) { addStem(now + rnd(260, 720), tip, true, false, 'secondary'); } trimTips(now); } function trimTips(now) { if (tips.length <= CFG.freshness.maxTips) return; var useful = []; for (var i = 0; i < tips.length; i++) { if ( tips[i].main || (!tips[i].decorative && tips[i].y > h * 0.16) || now - tips[i].born < 52000 ) { useful.push(tips[i]); } } tips = useful.length > 42 ? useful : tips.slice(Math.max(0, tips.length - 115)); while (tips.length > CFG.freshness.maxTips) { tips.shift(); } } function chooseTip(now) { if (!tips.length) seed(); var age = now - startedAt; var lower = []; var middle = []; var crown = []; var mainTips = []; var structuralTips = []; for (var i = 0; i < tips.length; i++) { var t = tips[i]; if (t.main) mainTips.push(t); if (!t.decorative) structuralTips.push(t); if (t.y > h * 0.66) { lower.push(t); } else if (t.y > h * 0.36) { middle.push(t); } else if (t.y > h * 0.10) { crown.push(t); } } if ( age < CFG.structure.earlyMainTipPreferenceMs && mainTips.length && Math.random() < CFG.structure.earlyMainTipPreference ) { return mainTips[Math.floor(Math.random() * mainTips.length)]; } if (age < CFG.growth.buildMs) { if (mainTips.length && Math.random() < 0.40) { return mainTips[Math.floor(Math.random() * mainTips.length)]; } if (middle.length && Math.random() < 0.34) { return middle[Math.floor(Math.random() * middle.length)]; } if (crown.length && Math.random() < 0.20) { return crown[Math.floor(Math.random() * crown.length)]; } if (lower.length && Math.random() < 0.18) { return lower[Math.floor(Math.random() * lower.length)]; } } else { if (mainTips.length && Math.random() < CFG.structure.lateMainTipPreference) { return mainTips[Math.floor(Math.random() * mainTips.length)]; } if (crown.length && Math.random() < 0.28) { return crown[Math.floor(Math.random() * crown.length)]; } if (structuralTips.length && Math.random() < 0.26) { return structuralTips[Math.floor(Math.random() * structuralTips.length)]; } if (middle.length && Math.random() < 0.18) { return middle[Math.floor(Math.random() * middle.length)]; } } if (structuralTips.length && Math.random() < 0.80) { return structuralTips[Math.floor(Math.random() * structuralTips.length)]; } return tips[Math.floor(Math.random() * tips.length)]; } function addStem(now, base, forced, mainGrowth, kind) { if (!w || !h) return; if (!base) base = chooseTip(now); if (!base) return; var age = now - startedAt; if (base.y < h * 0.08 && !forced) { return; } var side = base.side || (base.x < w * 0.5 ? 'left' : 'right'); var straightUp = -Math.PI / 2; var desired = verticalPull(base.x, base.y, side, age); var angle; if (mainGrowth) { angle = weightedAngle( straightUp, desired, base.angle, CFG.structure.mainStraightness, CFG.structure.mainTargetPull, CFG.structure.mainPreviousAngleMemory ); angle += rnd(-CFG.structure.mainRandomness, CFG.structure.mainRandomness); } else { var heightFactor = 1 - (base.y / h); if ( heightFactor < CFG.structure.lowerBranchLimit && !forced && Math.random() < CFG.structure.lowerBranchSuppression ) { return; } var branchSide; if (side === 'left') { branchSide = Math.random() < 0.66 ? 1 : -1; } else if (side === 'right') { branchSide = Math.random() < 0.66 ? -1 : 1; } else { branchSide = Math.random() < 0.5 ? -1 : 1; } var branchOpen = base.main ? rndRange(CFG.structure.branchOpenFromMain) : rndRange(CFG.structure.branchOpenFromBranch); angle = straightUp + branchSide * branchOpen + rnd(-CFG.structure.branchRandomness, CFG.structure.branchRandomness); if (base.y < h * 0.34) { angle = weightedAngle(angle, straightUp, base.angle, 0.72, 0.22, 0.06); } if (!base.main && kind !== 'spray') { angle = weightedAngle(angle, straightUp, base.angle, 0.70, 0.24, 0.06); } } angle = normalizeAngle(angle); var len; var heightFactorForLength = 1 - (base.y / h); if (kind === 'main') { len = rndRange(CFG.structure.mainLength); } else if (kind === 'spray') { len = rndRange(CFG.structure.sprayLength); } else if (mainGrowth) { len = rndRange(CFG.structure.secondaryMainLength); } else if (heightFactorForLength > CFG.structure.upperHeightFactor) { len = base.main ? rndRange(CFG.structure.upperBranchLengthFromMain) : rndRange(CFG.structure.upperBranchLengthFromBranch); } else { len = base.main ? rndRange(CFG.structure.lowerBranchLengthFromMain) : rndRange(CFG.structure.lowerBranchLengthFromBranch); } len *= base.strength || 1; var x2 = base.x + Math.cos(angle) * len; var y2 = base.y + Math.sin(angle) * len; var generousForBranch = forced || (!mainGrowth && kind !== 'main'); if (!insideBouquet(x2, y2, generousForBranch)) { if (!forced && mainGrowth) return; if (!mainGrowth) { x2 = clamp(x2, -12, w + 12); y2 = clamp(y2, h * 0.045, h + 8); } else { x2 = clamp(x2, w * 0.035, w * 0.965); y2 = clamp(y2, h * 0.070, h * 0.995); } } if (mainGrowth) { if (x2 < 6 || x2 > w - 6 || y2 < 6 || y2 > h - 4) { if (!forced) return; x2 = clamp(x2, 8, w - 8); y2 = clamp(y2, 8, h - 6); } } else { if (x2 < -22 || x2 > w + 22 || y2 < 4 || y2 > h + 12) { if (!forced) return; x2 = clamp(x2, -16, w + 16); y2 = clamp(y2, 6, h + 8); } } var bend = mainGrowth ? rnd(-CFG.structure.mainBend, CFG.structure.mainBend) : rnd(-CFG.structure.branchBend, CFG.structure.branchBend); var c1x = base.x + Math.cos(angle + bend) * len * rnd(0.30, 0.42); var c1y = base.y + Math.sin(angle + bend) * len * rnd(0.30, 0.42); var c2x = base.x + Math.cos(angle - bend * 0.70) * len * rnd(0.68, 0.84); var c2y = base.y + Math.sin(angle - bend * 0.70) * len * rnd(0.68, 0.84); var stem = { x1: base.x, y1: base.y, c1x: c1x, c1y: c1y, c2x: c2x, c2y: c2y, x2: x2, y2: y2, angle: angle, start: now, duration: kind === 'main' ? rnd(5200, 8500) : mainGrowth ? rnd(5600, 9300) : rnd(4200, 7200), width: kind === 'main' ? rnd(1.12, 1.72) : mainGrowth ? rnd(0.82, 1.24) : rnd(0.42, 0.72), alpha: kind === 'main' ? rnd(0.32, 0.48) : mainGrowth ? rnd(0.22, 0.36) : rnd(0.13, 0.23), born: now, life: kind === 'main' ? 999999999 : mainGrowth ? rnd(360000, 620000) : rnd(220000, 420000), main: kind === 'main' || mainGrowth, structural: !!mainGrowth, side: side, kind: kind || 'normal' }; stems.push(stem); var newTip = { x: x2, y: y2, angle: angle, generation: (base.generation || 0) + 1, strength: mainGrowth ? Math.max(0.54, (base.strength || 1) * rndRange(CFG.structure.structuralTipStrength)) : Math.max(0.32, (base.strength || 1) * rndRange(CFG.structure.decorativeTipStrength)), side: side, main: !!mainGrowth, decorative: !mainGrowth, born: now }; if (mainGrowth || Math.random() < CFG.structure.decorativeTipChance) { tips.push(newTip); } trimTips(now); addLeaves(stem, now); if (y2 < h * 0.78 && y2 > h * 0.12) { if (Math.random() < (mainGrowth ? CFG.floristry.budChanceOnMain : CFG.floristry.budChanceOnBranch)) { addBud(x2, y2, angle, now + rnd(1200, 3200)); } if (Math.random() < (mainGrowth ? CFG.floristry.flowerChanceOnMain : CFG.floristry.flowerChanceOnBranch)) { addFlower(x2, y2, angle, now + rnd(1800, 5200)); } if (!mainGrowth && Math.random() < CFG.floristry.sprayChanceOnBranch && y2 < h * 0.60) { addSpray(x2, y2, angle, now + rnd(1600, 4200), side); } } } function pointOnCurve(s, t) { var mt = 1 - t; return { x: mt * mt * mt * s.x1 + 3 * mt * mt * t * s.c1x + 3 * mt * t * t * s.c2x + t * t * t * s.x2, y: mt * mt * mt * s.y1 + 3 * mt * mt * t * s.c1y + 3 * mt * t * t * s.c2y + t * t * t * s.y2 }; } function tooCloseToExistingLeaf(x, y, minDist) { var min2 = minDist * minDist; for (var i = leaves.length - 1; i >= 0 && i > leaves.length - 90; i--) { var dx = leaves[i].x - x; var dy = leaves[i].y - y; if (dx * dx + dy * dy < min2) return true; } return false; } function addLeaves(stem, now) { var count; if (stem.kind === 'main') { count = CFG.floristry.leafDensityMain + (Math.random() < 0.30 ? 1 : 0); } else if (stem.main) { count = CFG.floristry.leafDensityStructural + (Math.random() < 0.22 ? 1 : 0); } else { count = CFG.floristry.leafDensityBranch; } count = Math.max(0, count); for (var i = 0; i < count; i++) { if (!stem.main && Math.random() < CFG.floristry.leafSkipBranchChance) continue; var baseT = CFG.floristry.leafDistributionMin + (CFG.floristry.leafDistributionMax - CFG.floristry.leafDistributionMin) * ((i + 0.5) / Math.max(1, count)); var t = clamp( baseT + rnd(-CFG.floristry.leafDistributionJitter, CFG.floristry.leafDistributionJitter), CFG.floristry.leafDistributionMin, CFG.floristry.leafDistributionMax ); var p = pointOnCurve(stem, t); if (tooCloseToExistingLeaf(p.x, p.y, stem.main ? 7 : 9)) { continue; } var leafSide = i % 2 === 0 ? -1 : 1; if (Math.random() < 0.32) leafSide *= -1; var longLeaf = stem.kind === 'main' && Math.random() < CFG.floristry.longLeafChance; var angleFromStem = CFG.floristry.leafAngleFromStem ? rndRange(CFG.floristry.leafAngleFromStem) : rnd(0.42, 0.74); leaves.push({ x: p.x, y: p.y, angle: stem.angle + leafSide * angleFromStem, rx: longLeaf ? rnd(9.5, 15.2) : stem.main ? rnd(6.4, 10.8) : rnd(4.6, 8.2), ry: longLeaf ? rnd(2.2, 3.5) : stem.main ? rnd(1.9, 3.2) : rnd(1.4, 2.4), start: now + rnd(700, 2800), duration: rnd(1900, 4200), alpha: longLeaf ? rnd(0.20, 0.34) : stem.main ? rnd(0.17, 0.31) : rnd(0.14, 0.26), veinAlpha: rnd(0.055, 0.13), born: now, life: stem.main ? rndRange(CFG.floristry.leafLifeMain) : rndRange(CFG.floristry.leafLifeBranch), hue: rnd(0, 1) }); } } function addBud(x, y, angle, startTime) { buds.push({ x: x + rnd(-1.8, 1.8), y: y + rnd(-1.8, 1.8), angle: angle + rnd(-0.28, 0.28), r: rnd(1.5, 3.2), start: startTime, duration: rnd(2200, 5200), alpha: rnd(0.14, 0.28), born: startTime, life: rndRange(CFG.floristry.budLife) }); } function addFlower(x, y, angle, startTime) { var pale = Math.random() < 0.62; flowers.push({ x: x + rnd(-4.0, 4.0), y: y + rnd(-4.0, 4.0), angle: angle + rnd(-0.45, 0.45), r: rnd(2.4, 5.3), petals: Math.floor(rnd(5, 8.99)), start: startTime, duration: rnd(2600, 6200), alpha: pale ? rnd(0.12, 0.23) : rnd(0.10, 0.19), born: startTime, life: rndRange(CFG.floristry.flowerLife), pale: pale, warm: Math.random() < 0.38 }); } function addSpray(x, y, angle, startTime, side) { var sprayAngle = angle + (side === 'left' ? rnd(-0.20, 0.42) : rnd(-0.42, 0.20)); var count = Math.floor(rnd(3, 7.99)); var dots = []; for (var i = 0; i < count; i++) { dots.push({ t: (i + 1) / (count + 1), side: rnd(-1, 1), r: rnd(0.7, 1.3) }); } sprays.push({ x: x, y: y, angle: sprayAngle, len: rnd(16, 32), count: count, dots: dots, start: startTime, duration: rnd(2600, 6400), alpha: rnd(0.10, 0.20), born: startTime, life: rndRange(CFG.floristry.sprayLife) }); } function freshFade(now, item) { var age = now - item.born; var life = item.life || 240000; if (age <= 0) return 1; if (life > 900000000) return 1; if (age >= life) return 0; if (age > life * CFG.freshness.fadeStart) { var f = 1 - ((age - life * CFG.freshness.fadeStart) / (life * (1 - CFG.freshness.fadeStart))); return Math.max(CFG.freshness.minimumFade, Math.min(1, f)); } return 1; } function drawStem(s, p, fade) { if (fade <= 0) return; p = easeOutCubic(p); ctx.beginPath(); ctx.moveTo(s.x1, s.y1); var steps = 42; var maxStep = Math.max(1, Math.floor(steps * p)); for (var i = 1; i <= maxStep; i++) { var t = i / steps; var pt = pointOnCurve(s, t); ctx.lineTo(pt.x, pt.y); } var alpha = s.alpha * p * fade; ctx.strokeStyle = rgba(CFG.visual.stemColor, alpha); ctx.lineWidth = s.width; ctx.lineCap = 'round'; ctx.lineJoin = 'round'; ctx.stroke(); if (s.main && p > 0.55) { ctx.beginPath(); ctx.moveTo(s.x1, s.y1); for (var j = 1; j <= maxStep; j++) { var tt = j / steps; var pp = pointOnCurve(s, tt); ctx.lineTo(pp.x, pp.y); } ctx.strokeStyle = rgba(CFG.visual.stemHighlightColor, alpha * 0.22); ctx.lineWidth = Math.max(0.35, s.width * 0.42); ctx.stroke(); } } function drawLeaf(l, p, fade) { if (p <= 0 || fade <= 0) return; var eased = easeOutQuart(p); var scale = 0.14 + 0.86 * eased; ctx.save(); ctx.translate(l.x, l.y); ctx.rotate(l.angle); ctx.scale(scale, scale); ctx.beginPath(); ctx.moveTo(-l.rx, 0); ctx.bezierCurveTo(-l.rx * 0.48, -l.ry * 1.72, l.rx * 0.50, -l.ry * 1.48, l.rx, 0); ctx.bezierCurveTo(l.rx * 0.50, l.ry * 1.48, -l.rx * 0.48, l.ry * 1.72, -l.rx, 0); ctx.closePath(); var a = l.alpha * eased * fade; if (l.hue < 0.34) { ctx.fillStyle = rgba(CFG.visual.leafColorA, a); } else if (l.hue < 0.72) { ctx.fillStyle = rgba(CFG.visual.leafColorB, a); } else { ctx.fillStyle = rgba(CFG.visual.leafColorC, a); } ctx.fill(); ctx.beginPath(); ctx.moveTo(-l.rx * 0.70, 0); ctx.lineTo(l.rx * 0.74, 0); ctx.strokeStyle = rgba(CFG.visual.leafVeinColor, l.veinAlpha * eased * fade); ctx.lineWidth = 0.42; ctx.stroke(); ctx.restore(); } function drawBud(b, p, fade) { if (p <= 0 || fade <= 0) return; var eased = easeOutCubic(p); var r = b.r * eased; ctx.save(); ctx.translate(b.x, b.y); ctx.rotate(b.angle); ctx.beginPath(); ctx.ellipse(0, 0, r * 0.68, r * 1.22, 0, 0, Math.PI * 2); ctx.fillStyle = rgba(CFG.visual.budColor, b.alpha * eased * fade); ctx.fill(); ctx.beginPath(); ctx.ellipse(0, -r * 0.20, r * 0.34, r * 0.72, 0, 0, Math.PI * 2); ctx.fillStyle = rgba(CFG.visual.budLightColor, b.alpha * 0.45 * eased * fade); ctx.fill(); ctx.restore(); } function drawFlower(f, p, fade) { if (p <= 0 || fade <= 0) return; var eased = easeOutQuart(p); var r = f.r * eased; ctx.save(); ctx.translate(f.x, f.y); ctx.rotate(f.angle); for (var i = 0; i < f.petals; i++) { var a = (Math.PI * 2 / f.petals) * i; ctx.save(); ctx.rotate(a); ctx.beginPath(); ctx.ellipse(0, -r * 0.72, r * 0.34, r * 0.82, 0, 0, Math.PI * 2); if (f.pale) { ctx.fillStyle = rgba(CFG.visual.flowerPaleColor, f.alpha * 0.82 * eased * fade); } else if (f.warm) { ctx.fillStyle = rgba(CFG.visual.flowerWarmColor, f.alpha * 0.78 * eased * fade); } else { ctx.fillStyle = rgba(CFG.visual.flowerGreenColor, f.alpha * 0.76 * eased * fade); } ctx.fill(); ctx.restore(); } ctx.beginPath(); ctx.arc(0, 0, Math.max(0.7, r * 0.30), 0, Math.PI * 2); ctx.fillStyle = rgba(CFG.visual.flowerCenterColor, f.alpha * 0.80 * eased * fade); ctx.fill(); ctx.restore(); } function drawSpray(s, p, fade) { if (p <= 0 || fade <= 0) return; var eased = easeOutCubic(p); var len = s.len * eased; ctx.save(); ctx.translate(s.x, s.y); ctx.rotate(s.angle); ctx.beginPath(); ctx.moveTo(0, 0); ctx.quadraticCurveTo(len * 0.14, -len * 0.38, len * 0.06, -len); ctx.strokeStyle = rgba(CFG.visual.sprayStemColor, s.alpha * eased * fade); ctx.lineWidth = 0.55; ctx.lineCap = 'round'; ctx.stroke(); for (var i = 0; i < s.dots.length; i++) { var d = s.dots[i]; var t = d.t; var px = len * 0.06 * t + Math.sin(t * Math.PI) * len * 0.08 * d.side; var py = -len * t; ctx.beginPath(); ctx.arc(px, py, d.r, 0, Math.PI * 2); ctx.fillStyle = rgba(CFG.visual.sprayDotColor, s.alpha * 1.25 * eased * fade); ctx.fill(); } ctx.restore(); } function cleanup(now) { var i; for (i = stems.length - 1; i >= 0; i--) { if (stems[i].life < 900000000 && now - stems[i].born > stems[i].life) { stems.splice(i, 1); } } for (i = leaves.length - 1; i >= 0; i--) { if (now - leaves[i].born > leaves[i].life) leaves.splice(i, 1); } for (i = buds.length - 1; i >= 0; i--) { if (now - buds[i].born > buds[i].life) buds.splice(i, 1); } for (i = flowers.length - 1; i >= 0; i--) { if (now - flowers[i].born > flowers[i].life) flowers.splice(i, 1); } for (i = sprays.length - 1; i >= 0; i--) { if (now - sprays[i].born > sprays[i].life) sprays.splice(i, 1); } if (stems.length > CFG.freshness.maxStems) stems.splice(0, stems.length - CFG.freshness.maxStems); if (leaves.length > CFG.freshness.maxLeaves) leaves.splice(0, leaves.length - CFG.freshness.maxLeaves); if (buds.length > CFG.freshness.maxBuds) buds.splice(0, buds.length - CFG.freshness.maxBuds); if (flowers.length > CFG.freshness.maxFlowers) flowers.splice(0, flowers.length - CFG.freshness.maxFlowers); if (sprays.length > CFG.freshness.maxSprays) sprays.splice(0, sprays.length - CFG.freshness.maxSprays); trimTips(now); } function refreshBouquet(now) { var age = now - startedAt; if (age < CFG.floristry.crownRefreshStartMs) return; var crownChance = age < CFG.growth.buildMs ? CFG.floristry.crownRefreshBuildChance : CFG.floristry.crownRefreshCalmChance; if (Math.random() < crownChance) { var x = rnd(w * CFG.floristry.crownX[0], w * CFG.floristry.crownX[1]); var y = rnd(h * CFG.floristry.crownY[0], h * CFG.floristry.crownY[1]); if (insideBouquet(x, y, true)) { if (Math.random() < 0.38) { addFlower(x, y, rnd(-Math.PI, Math.PI), now + rnd(0, 2400)); } else if (Math.random() < 0.76) { addBud(x, y, rnd(-Math.PI, Math.PI), now + rnd(0, 2100)); } else { addSpray(x, y, rnd(-2.4, -0.7), now + rnd(0, 2500), x < w * 0.5 ? 'left' : 'right'); } } } if (Math.random() < 0.22) { var base = chooseTip(now); if (base && base.main && base.y > h * 0.22 && base.y < h * 0.78) { addStem(now, base, false, false, 'spray'); } } } function drawSoftBackground(now) { var age = now - startedAt; var p = easeOutCubic(Math.min(1, age / 52000)); if (p <= 0) return; var cx = w * 0.5; var cy = h * 0.50; var rx = w * 0.42; var ry = h * 0.40; ctx.save(); ctx.beginPath(); ctx.ellipse(cx, cy, rx, ry, 0, 0, Math.PI * 2); ctx.fillStyle = rgba(CFG.visual.softBackgroundColor, CFG.visual.backgroundAlpha * p); ctx.fill(); ctx.restore(); } function drawAll(now) { ctx.clearRect(0, 0, w, h); drawSoftBackground(now); var i; var p; var fade; for (i = 0; i < stems.length; i++) { p = (now - stems[i].start) / stems[i].duration; fade = freshFade(now, stems[i]); drawStem(stems[i], p, fade); } for (i = 0; i < leaves.length; i++) { p = (now - leaves[i].start) / leaves[i].duration; fade = freshFade(now, leaves[i]); drawLeaf(leaves[i], p, fade); } for (i = 0; i < sprays.length; i++) { p = (now - sprays[i].start) / sprays[i].duration; fade = freshFade(now, sprays[i]); drawSpray(sprays[i], p, fade); } for (i = 0; i < buds.length; i++) { p = (now - buds[i].start) / buds[i].duration; fade = freshFade(now, buds[i]); drawBud(buds[i], p, fade); } for (i = 0; i < flowers.length; i++) { p = (now - flowers[i].start) / flowers[i].duration; fade = freshFade(now, flowers[i]); drawFlower(flowers[i], p, fade); } } function animate(now) { if (now - lastFrame < frameInterval) { window.requestAnimationFrame(animate); return; } lastFrame = now; var age = now - startedAt; if (age < CFG.growth.mainSeedUntilMs && now >= nextMainSeedAt) { addBottomSeed(now); scheduleMainSeed(now); } if (now >= nextGrowAt) { var base = chooseTip(now); if (base) { var heightFactor = 1 - (base.y / h); var mainGrowthChance; if (base.main) { mainGrowthChance = age < CFG.growth.buildMs ? 0.62 : 0.40; } else { mainGrowthChance = heightFactor < 0.42 ? 0.22 : 0.10; } addStem(now, base, false, Math.random() < mainGrowthChance, Math.random() < 0.12 ? 'secondary' : 'normal'); } scheduleGrow(now); } if (now >= nextRefreshAt) { refreshBouquet(now); scheduleRefresh(now); } if (now >= nextCleanupAt) { cleanup(now); nextCleanupAt = now + 4200; } drawAll(now); window.requestAnimationFrame(animate); } function handleResize() { clearTimeout(box._aboBotanicalResizeTimer); box._aboBotanicalResizeTimer = setTimeout(function () { resize(true); }, 160); } resize(false); window.addEventListener('resize', handleResize); window.requestAnimationFrame(animate); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', start); } else { start(); } window.addEventListener('load', function () { start(); }); })();(function () { var ua = navigator.userAgent; var isIOSSafari = /iP(ad|hone|od)/.test(ua) && /Safari/.test(ua) && !/CriOS|FxiOS|EdgiOS|OPiOS/.test(ua); if (!isIOSSafari) return; var lastScroll = 0; function scrollToInvalidSelect(el) { if (!el || el.tagName !== 'SELECT' || !el.required || el.validity.valid) return; var now = Date.now(); if (now - lastScroll < 400) return; lastScroll = now; setTimeout(function () { var rect = el.getBoundingClientRect(); var y = window.pageYOffset + rect.top - Math.round(window.innerHeight * 0.35); window.scrollTo(0, y); setTimeout(function () { try { el.focus(); } catch (e) {} }, 80); }, 30); } document.addEventListener('invalid', function (e) { scrollToInvalidSelect(e.target); }, true); document.addEventListener('submit', function (e) { var el = document.querySelector('select[required]:invalid'); if (el) { scrollToInvalidSelect(el); e.preventDefault(); e.stopPropagation(); } }, true); })();