1(function() { 2 "use strict"; 3 4 const select = function(selector, all) { 5 return all ? Array.from(document.querySelectorAll(selector)) : document.querySelector(selector); 6 }; 7 8 const header = select("#header"); 9 const navbar = select("#navbar"); 10 const mobileToggle = select(".mobile-nav-toggle"); 11 const backToTop = select(".back-to-top"); 12 const reducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches; 13 14 const updateHeader = function() { 15 if (!header) { 16 return; 17 } 18 19 header.classList.toggle("header-scrolled", window.scrollY > 60); 20 21 if (backToTop) { 22 backToTop.classList.toggle("active", window.scrollY > 500); 23 } 24 }; 25 26 window.addEventListener("load", updateHeader); 27 window.addEventListener("scroll", updateHeader, { passive: true }); 28 29 if (mobileToggle && navbar) { 30 mobileToggle.addEventListener("click", function() { 31 const open = navbar.classList.toggle("navbar-mobile"); 32 document.body.classList.toggle("nav-open", open); 33 mobileToggle.querySelector("i").className = open ? "bi bi-x" : "bi bi-list"; 34 }); 35 } 36 37 select(".scrollto", true).forEach(function(link) { 38 link.addEventListener("click", function(event) { 39 const target = document.querySelector(link.getAttribute("href")); 40 41 if (!target) { 42 return; 43 } 44 45 event.preventDefault(); 46 const offset = header ? header.offsetHeight : 0; 47 window.scrollTo({ 48 top: target.offsetTop - offset, 49 behavior: reducedMotion ? "auto" : "smooth" 50 }); 51 52 if (navbar && navbar.classList.contains("navbar-mobile")) { 53 navbar.classList.remove("navbar-mobile"); 54 document.body.classList.remove("nav-open"); 55 mobileToggle.querySelector("i").className = "bi bi-list"; 56 } 57 }); 58 }); 59 60 if (window.jQuery && jQuery.fn.slick) { 61 jQuery("#nearest-camps").slick({ 62 infinite: false, 63 slidesToShow: 4, 64 slidesToScroll: 1, 65 swipe: true, 66 draggable: true, 67 touchMove: true, 68 prevArrow: '<button type="button" class="slick-prev" aria-label="' + ((window.HTA_I18N && window.HTA_I18N.prevLesson) || "PÅedchozà výuka") + '"><i class="bi bi-arrow-left"></i></button>', 69 nextArrow: '<button type="button" class="slick-next" aria-label="' + ((window.HTA_I18N && window.HTA_I18N.nextLesson) || "Dalšà výuka") + '"><i class="bi bi-arrow-right"></i></button>', 70 responsive: [ 71 { 72 breakpoint: 1400, 73 settings: { 74 slidesToShow: 3 75 } 76 }, 77 { 78 breakpoint: 992, 79 settings: { 80 slidesToShow: 2 81 } 82 }, 83 { 84 breakpoint: 576, 85 settings: { 86 slidesToShow: 1 87 } 88 } 89 ] 90 }); 91 92 jQuery("#recommended-camps").slick({ 93 infinite: false, 94 slidesToShow: 3, 95 slidesToScroll: 1, 96 swipe: true, 97 draggable: true, 98 touchMove: true, 99 prevArrow: '<button type="button" class="slick-prev" aria-label="' + ((window.HTA_I18N && window.HTA_I18N.prevRecommended) || "PÅedchozà doporuÄená výuka") + '"><i class="bi bi-arrow-left"></i></button>', 100 nextArrow: '<button type="button" class="slick-next" aria-label="' + ((window.HTA_I18N && window.HTA_I18N.nextRecommended) || "Dalšà doporuÄená výuka") + '"><i class="bi bi-arrow-right"></i></button>', 101 responsive: [ 102 { 103 breakpoint: 992, 104 settings: { 105 slidesToShow: 2 106 } 107 }, 108 { 109 breakpoint: 576, 110 settings: { 111 slidesToShow: 1 112 } 113 } 114 ] 115 }); 116 117 jQuery("#alumni-testimonials").slick({ 118 infinite: true, 119 slidesToShow: 2, 120 slidesToScroll: 1, 121 swipe: true, 122 draggable: true, 123 touchMove: true, 124 prevArrow: '<button type="button" class="slick-prev" aria-label="' + ((window.HTA_I18N && window.HTA_I18N.prevTestimonial) || "PÅedchozà komentáÅ") + '"><i class="bi bi-arrow-left"></i></button>', 125 nextArrow: '<button type="button" class="slick-next" aria-label="' + ((window.HTA_I18N && window.HTA_I18N.nextTestimonial) || "Dalšà komentáÅ") + '"><i class="bi bi-arrow-right"></i></button>', 126 responsive: [ 127 { 128 breakpoint: 992, 129 settings: { 130 slidesToShow: 1 131 } 132 } 133 ] 134 }); 135 136 const testimonialSlider = jQuery("#alumni-testimonials"); 137 const testimonialTextLimit = 550; 138 139 testimonialSlider.find(".alumni-testimonial-card").each(function() { 140 const card = this; 141 const quote = card.querySelector("blockquote"); 142 143 if (!quote) { 144 return; 145 } 146 147 const fullText = quote.textContent.replace(/\s+/g, " ").trim(); 148 149 if (fullText.length <= testimonialTextLimit) { 150 quote.textContent = fullText; 151 return; 152 } 153 154 let collapsedText = fullText.slice(0, testimonialTextLimit); 155 const lastSpace = collapsedText.lastIndexOf(" "); 156 157 if (lastSpace > testimonialTextLimit - 60) { 158 collapsedText = collapsedText.slice(0, lastSpace); 159 } 160 161 collapsedText = collapsedText.trim() + "..."; 162 quote.textContent = collapsedText; 163 164 const toggle = document.createElement("button"); 165 toggle.type = "button"; 166 toggle.className = "alumni-testimonial-toggle"; 167 toggle.textContent = (window.HTA_I18N && window.HTA_I18N.more) || "VÃce"; 168 toggle.setAttribute("aria-expanded", "false"); 169 quote.insertAdjacentElement("afterend", toggle); 170 171 toggle.addEventListener("click", function() { 172 const expanded = card.classList.toggle("is-expanded"); 173 quote.textContent = expanded ? fullText : collapsedText; 174 toggle.textContent = expanded ? ((window.HTA_I18N && window.HTA_I18N.less) || "MénÄ")
174: ((window.HTA_I18N && window.HTA_I18N.more) || "VÃce"); 175 toggle.setAttribute("aria-expanded", expanded ? "true" : "false"); 176 177 window.requestAnimationFrame(function() { 178 testimonialSlider.slick("setPosition"); 179 }); 180 }); 181 }); 182 } 183 184 185 /* Trenérská akademie â delšà reference držÃme kompaktnà a rozbalitelné. */ 186 const academyReferenceTextLimit = 430; 187 188 document.querySelectorAll(".academy-reference-text").forEach(function(referenceText) { 189 const referenceCard = referenceText.closest(".academy-reference"); 190 const fullHtml = referenceText.innerHTML; 191 const fullText = referenceText.textContent.replace(/\s+/g, " ").trim(); 192 193 if (!referenceCard || fullText.length <= academyReferenceTextLimit) { 194 return; 195 } 196 197 let collapsedText = fullText.slice(0, academyReferenceTextLimit); 198 const lastSpace = collapsedText.lastIndexOf(" "); 199 200 if (lastSpace > academyReferenceTextLimit - 70) { 201 collapsedText = collapsedText.slice(0, lastSpace); 202 } 203 204 collapsedText = collapsedText.trim() + "... "; 205 206 const toggle = document.createElement("button"); 207 toggle.type = "button"; 208 toggle.className = "academy-reference-toggle"; 209 toggle.setAttribute("aria-expanded", "false"); 210 211 function renderReference(expanded) { 212 if (expanded) { 213 referenceText.innerHTML = fullHtml; 214 toggle.textContent = (window.HTA_I18N && window.HTA_I18N.less) || "MénÄ"; 215 } else { 216 referenceText.innerHTML = ""; 217 218 const preview = document.createElement("p"); 219 preview.className = "academy-reference-preview"; 220 preview.textContent = collapsedText; 221 222 referenceText.appendChild(preview); 223 toggle.textContent = (window.HTA_I18N && window.HTA_I18N.more) || "VÃce"; 224 } 225 226 referenceText.appendChild(toggle); 227 toggle.setAttribute("aria-expanded", expanded ? "true" : "false"); 228 } 229 230 renderReference(false); 231 232 toggle.addEventListener("click", function() { 233 const expanded = referenceCard.classList.toggle("is-expanded"); 234 renderReference(expanded); 235 }); 236 }); 237 238 239 if (window.AOS) { 240 AOS.init({ 241 duration: 550, 242 easing: "ease-out-cubic", 243 once: true, 244 offset: 35, 245 delay: 0, 246 disable: reducedMotion 247 }); 248 249 window.addEventListener("load", function() { 250 AOS.refreshHard(); 251 }); 252 } 253 254 const campsFilter = select(".camps-filter"); 255 const campsGrid = select("#camps-list-grid"); 256 const campsItems = select(".camps-list-item", true); 257 const campsEmpty = select("#camps-filter-empty"); 258
259 if (campsFilter && campsGrid && campsItems.length) { 260 const allowedCampFilters = ["offseason", "inseason"]; 261 const urlParams = new URLSearchParams(window.location.search); 262 const requestedFilter = urlParams.get("category"); 263 const initialFilter = allowedCampFilters.indexOf(requestedFilter) !== -1 ? requestedFilter : "*"; 264 265 const filterCamps = function(filter) { 266 let visibleCount = 0; 267 268 campsItems.forEach(function(item) { 269 const visible = filter === "*" || item.dataset.campCategory === filter; 270 271 if (visible) { 272 item.hidden = false; 273 requestAnimationFrame(function() { 274 item.classList.remove("is-filtering-out"); 275 }); 276 visibleCount += 1; 277 } else { 278 item.classList.add("is-filtering-out"); 279 window.setTimeout(function() { 280 item.hidden = true; 281 }, reducedMotion ? 0 : 220); 282 } 283 }); 284 285 if (campsEmpty) { 286 campsEmpty.classList.toggle("visible", visibleCount === 0); 287 } 288 289 window.setTimeout(function() { 290 if (window.AOS) { 291 AOS.refresh(); 292 } 293 }, reducedMotion ? 0 : 240); 294 }; 295 296 const setActiveCampFilter = function(filter) { 297 campsFilter.querySelectorAll("[data-camp-filter]").forEach(function(item) { 298 item.classList.toggle("active", item.dataset.campFilter === filter); 299 }); 300 }; 301 302 setActiveCampFilter(initialFilter); 303 filterCamps(initialFilter); 304 305 campsFilter.addEventListener("click", function(event) { 306 const button = event.target.closest("[data-camp-filter]"); 307 308 if (!button) { 309 return; 310 } 311 312 const filter = button.dataset.campFilter; 313 setActiveCampFilter(filter); 314 filterCamps(filter); 315 316 const nextUrl = new URL(window.location.href); 317 if (filter === "*") { 318 nextUrl.searchParams.delete("category"); 319 } else { 320 nextUrl.searchParams.set("category", filter); 321 } 322 window.history.replaceState({}, "", nextUrl.pathname + nextUrl.search + nextUrl.hash); 323 }); 324 } 325 326 327 const campGalleryImage = select("#camp-gallery-main-image"); 328 const campGalleryThumbs = select("[data-gallery-image]", true); 329 330 if (campGalleryImage && campGalleryThumbs.length) { 331 campGalleryThumbs.forEach(function(thumb) { 332 thumb.addEventListener("click", function() { 333 const nextImage = thumb.dataset.galleryImage; 334 if (!nextImage || campGalleryImage.getAttribute("src") === nextImage) { 335 return; 336 } 337 campGalleryThumbs.forEach(function(item) { 338 item.classList.toggle("active", item === thumb); 339 }); 340 campGalleryImage.style.opacity = "0"; 341 window.setTimeout(function() { 342 campGalleryImage.setAttribute("src", nextImage); 343 campGalleryImage.style.opacity = "1"; 344 }, reducedMotion ? 0 : 180); 345 }); 346 }); 347 } 348 349 const campSkills = select("[data-camp-skills]"); 350 351 if (campSkills) { 352 const skillRows = select(".camp-skill[data-skill]", true); 353 let skillsStarted = false; 354 355 const startSkills = function() { 356 if (skillsStarted) { 357 return; 358 } 359 skillsStarted = true; 360 361 skillRows.forEach(function(row, index) { 362 const target = Math.max(0, Math.min(100, Number(row.dataset.skill || 0))); 363 const bar = row.querySelector("i"); 364 const label = row.querySelector("strong"); 365 const delay = reducedMotion ? 0 : index * 90; 366 367 if (bar) { 368 bar.style.setProperty("--skill-target", target + "%"); 369 } 370 371 window.setTimeout(function() { 372 row.classList.add("skill-active"); 373 374 if (!label) { 375 return; 376 } 377 378 if (reducedMotion) { 379 label.textContent = target + " %"; 380 return; 381 } 382 383 const duration = 1050; 384 const start = performance.now(); 385 const tick = function(now) { 386 const progress = Math.min((now - start) / duration, 1); 387 const eased = 1 - Math.pow(1 - progress, 3); 388 label.textContent = Math.round(target * eased) + " %"; 389 if (progress < 1) { 390 requestAnimationFrame(tick); 391 } 392 }; 393 requestAnimationFrame(tick); 394 }, delay); 395 }); 396 }; 397 398 if ("IntersectionObserver" in window && !reducedMotion) { 399 const skillsObserver = new IntersectionObserver(function(entries, observer) { 400 entries.forEach(function(entry) { 401 if (entry.isIntersecting) { 402 startSkills(); 403 observer.disconnect(); 404 } 405 }); 406 }, { threshold: 0.15 }); 407 skillsObserver.observe(campSkills); 408 } else { 409 startSkills(); 410 } 411 } 412 413 const campQuantity = select("#camp-quantity"); 414 const campQuantityButtons = select("[data-quantity-change]", true); 415 416 if (campQuantity && campQuantityButtons.length) { 417 campQuantityButtons.forEach(function(button) { 418 button.addEventListener("click", function() { 419 const change = Number(button.dataset.quantityChange || 0); 420 const minimum = Number(campQuantity.min || 1); 421 const maximum = Number(campQuantity.max || 99); 422 const current = Number(campQuantity.value || minimum); 423 campQuantity.value = Math.max(minimum, Math.min(maximum, current + change)); 424 }); 425 }); 426 } 427 428 const counters = select(".counter", true); 429 const runCounter = function(counter) { 430 const target = Number(counter.dataset.target || 0); 431 const duration = reducedMotion ? 0 : 1400; 432 const start = performance.now(); 433 434 const tick = function(now) { 435 const progress = duration === 0 ? 1 : Math.min((now - start) / duration, 1); 436 const eased = 1 - Math.pow(1 - progress, 3);
437 counter.textContent = Math.round(target * eased).toLocaleString((window.HTA_I18N && window.HTA_I18N.locale) || "cs-CZ"); 438 439 if (progress < 1) { 440 requestAnimationFrame(tick); 441 } 442 }; 443 444 requestAnimationFrame(tick); 445 }; 446 447 if ("IntersectionObserver" in window && !reducedMotion) { 448 const counterObserver = new IntersectionObserver(function(entries, observer) { 449 entries.forEach(function(entry) { 450 if (entry.isIntersecting) { 451 runCounter(entry.target); 452 observer.unobserve(entry.target); 453 } 454 }); 455 }, { 456 threshold: 0.4 457 }); 458 459 counters.forEach(function(counter) { 460 counterObserver.observe(counter); 461 }); 462 } else { 463 counters.forEach(runCounter); 464 } 465 466 const analysisRows = select(".analysis-values [data-analysis-min][data-analysis-max]", true); 467 468 if (analysisRows.length) { 469 const analysisStates = analysisRows.map(function(row) { 470 const visualMin = Number(row.dataset.analysisVisualMin); 471 const visualMax = Number(row.dataset.analysisVisualMax); 472 const current = visualMin + Math.random() * (visualMax - visualMin); 473 474 return { 475 current: current, 476 target: current, 477 nextChange: 0 478 }; 479 }); 480 481 const drawAnalysisValues = function(time) { 482 analysisRows.forEach(function(row, index) { 483 const visualMin = Number(row.dataset.analysisVisualMin);
484 const visualMax = Number(row.dataset.analysisVisualMax); 485 const state = analysisStates[index]; 486 487 if (!reducedMotion && time >= state.nextChange) { 488 state.target = visualMin + Math.random() * (visualMax - visualMin); 489 state.nextChange = time + 3500 + Math.random() * 3500; 490 } 491 492 if (!reducedMotion) { 493 state.current += (state.target - state.current) * 0.004; 494 } 495 496 const current = reducedMotion ? (visualMin + visualMax) / 2 : state.current; 497 const rounded = Math.round(current); 498 const barValue = Math.max(0, Math.min(120, current)) / 120 * 100; 499 const label = row.querySelector("strong"); 500 const bar = row.querySelector("i"); 501 502 if (label) { 503 label.textContent = rounded + " %"; 504 } 505 506 if (bar) { 507 bar.style.setProperty("--value", barValue.toFixed(2) + "%"); 508 } 509 }); 510 511 if (!reducedMotion) { 512 requestAnimationFrame(drawAnalysisValues); 513 } 514 }; 515 516 requestAnimationFrame(drawAnalysisValues); 517 } 518 519 520 const checkoutQuantity = select("[data-checkout-quantity]"); 521 const checkoutQuantityButtons = select("[data-checkout-quantity-change]", true); 522 const checkoutCountLabels = select("[data-checkout-count]", true); 523 const checkoutLineTotals = select("[data-checkout-line-total]", true); 524 525 if (checkoutQuantity && checkoutQuantityButtons.length) { 526 const formatCheckoutPrice = function(amount, currency) { 527 return Math.round(amount).toLocaleString((window.HTA_I18N && window.HTA_I18N.locale) || "cs-CZ") + (currency === "EUR" ? " â¬" : " KÄ"); 528 }; 529 530 const updateCheckoutQuantity = function() { 531 const quantity = Number(checkoutQuantity.value || 1); 532 const activeCurrency = select(".currency-btn.active"); 533 const currency = activeCurrency ? activeCurrency.dataset.currency : "CZK"; 534
535 checkoutCountLabels.forEach(function(label) { 536 label.textContent = quantity; 537 }); 538 539 checkoutLineTotals.forEach(function(total) { 540 const czkTotal = Number(total.dataset.unitCzk || 0) * quantity; 541 const eurTotal = Number(total.dataset.unitEur || 0) * quantity; 542 total.dataset.czk = formatCheckoutPrice(czkTotal, "CZK"); 543 total.dataset.eur = formatCheckoutPrice(eurTotal, "EUR"); 544 total.textContent = currency === "EUR" ? total.dataset.eur : total.dataset.czk; 545 }); 546 547 }; 548 549 checkoutQuantityButtons.forEach(function(button) { 550 button.addEventListener("click", function() { 551 const change = Number(button.dataset.checkoutQuantityChange || 0); 552 const minimum = Number(checkoutQuantity.min || 1); 553 const maximum = Number(checkoutQuantity.max || 99); 554 const current = Number(checkoutQuantity.value || minimum); 555 checkoutQuantity.value = Math.max(minimum, Math.min(maximum, current + change)); 556 updateCheckoutQuantity(); 557 }); 558 }); 559 560 updateCheckoutQuantity(); 561 } 562 563 const checkoutCompanyToggle = select("[data-company-toggle]"); 564 const checkoutCompanyFields = select("[data-company-fields]"); 565 566 if (checkoutCompanyToggle && checkoutCompanyFields) { 567 const updateCheckoutCompanyFields = function() { 568 const isCompany = checkoutCompanyToggle.checked; 569 checkoutCompanyFields.hidden = !isCompany; 570 Array.from(checkoutCompanyFields.querySelectorAll("input, select, textarea")).forEach(function(field) { 571 field.disabled = !isCompany; 572 }); 573 }; 574 575 checkoutCompanyToggle.addEventListener("change", updateCheckoutCompanyFields); 576 updateCheckoutCompanyFields(); 577 } 578 579 const checkoutCountrySelects = select(".checkout-country-select", true); 580 581 if (checkoutCountrySelects.length && window.jQuery && jQuery.fn.selectpicker) { 582 const setCountrySearchPlaceholder = function(countrySelect) { 583 const wrapper = countrySelect.closest(".bootstrap-select"); 584 const searchInput = wrapper ? wrapper.querySelector(".bs-searchbox input") : null; 585 586 if (searchInput) { 587 searchInput.setAttribute("placeholder", (window.HTA_I18N && window.HTA_I18N.countrySearch) || "Vyhledat zemi..."); 588 searchInput.setAttribute("autocomplete", "off"); 589 } 590 }; 591 592 checkoutCountrySelects.forEach(function(countrySelect) { 593 const countryPicker = jQuery(countrySelect); 594 countryPicker.selectpicker(); 595 setCountrySearchPlaceholder(countrySelect); 596 countryPicker.on("shown.bs.select", function() { 597 setCountrySearchPlaceholder(countrySelect); 598 }); 599 }); 600 } 601 602 const checkoutPlayerGroups = select("[data-player-group]", true); 603 604 if (checkoutPlayerGroups.length) { 605 const refreshCheckoutPlayerAvailability = function() { 606 /* Vzdy nejdrive znovu povolime vsechny ulozene hrace ve vsech kempech. 607 * Duplicitni vyber se pak omezi pouze uvnitr konkretniho kempu. 608 */ 609 checkoutPlayerGroups.forEach(function(playerGroup) { 610 const groupSelects = Array.from(playerGroup.querySelectorAll(".checkout-player-select")); 611 612 groupSelects.forEach(function(playerSelect) { 613 Array.from(playerSelect.options).forEach(function(option) { 614 if (option.value !== "new") { 615 option.disabled = false; 616 } 617 }); 618 }); 619 620 const selectedValues = groupSelects.map(function(playerSelect) { 621 return playerSelect.value; 622 }).filter(function(value) { 623 return value !== "new"; 624 }); 625 626 groupSelects.forEach(function(playerSelect) { 627 Array.from(playerSelect.options).forEach(function(option) { 628 if (option.value === "new" || option.value === playerSelect.value) { 629 return; 630 } 631 632 option.disabled = selectedValues.indexOf(option.value) !== -1; 633 }); 634 }); 635 }); 636 }; 637 638 const updateCheckoutPlayerCard = function(changedSelect) { 639 const playerCard = changedSelect.closest("[data-player-card]"); 640 const selectedOption = changedSelect.options[changedSelect.selectedIndex]; 641 const isNewPlayer = changedSelect.value === "new"; 642 643 if (!playerCard) { 644 return; 645 } 646 647 playerCard.classList.toggle("is-new", isNewPlayer); 648 const playerIcon = playerCard.querySelector(".checkout-player-card-head i"); 649 if (playerIcon) {
650 playerIcon.className = isNewPlayer ? "bi bi-person-plus" : "bi bi-person-check"; 651 } 652 653 const fields = { 654 firstname: playerCard.querySelector("[data-player-firstname]"), 655 lastname: playerCard.querySelector("[data-player-lastname]"), 656 birthdate: playerCard.querySelector("[data-player-birthdate]"), 657 country: playerCard.querySelector("[data-player-country]") 658 }; 659 660 if (isNewPlayer) { 661 if (fields.firstname) fields.firstname.value = ""; 662 if (fields.lastname) fields.lastname.value = ""; 663 if (fields.birthdate) fields.birthdate.value = ""; 664 return; 665 } 666 667 if (fields.firstname) fields.firstname.value = selectedOption.dataset.firstname || ""; 668 if (fields.lastname) fields.lastname.value = selectedOption.dataset.lastname || ""; 669 if (fields.birthdate) fields.birthdate.value = selectedOption.dataset.birthdate || ""; 670 if (fields.country) fields.country.value = selectedOption.dataset.country || "CZ"; 671 }; 672 673 checkoutPlayerGroups.forEach(function(playerGroup) { 674 const groupSelects = Array.from(playerGroup.querySelectorAll(".checkout-player-select")); 675 676 groupSelects.forEach(function(playerSelect) { 677 playerSelect.addEventListener("change", function() { 678 updateCheckoutPlayerCard(playerSelect); 679 refreshCheckoutPlayerAvailability(); 680 }); 681 }); 682 }); 683 684 refreshCheckoutPlayerAvailability(); 685 } 686 687 const radarPolygon = select("#radarPolygon"); 688 const radarPoints = select("#radarPoints"); 689 const radarChart = select("#htaRadar"); 690 691 if (radarPolygon && radarPoints && radarChart) { 692 const center = { x: 210, y: 194 }; 693 const radius = 152; 694 const values = [0.75, 0.72, 0.68, 0.66, 0.64, 0.73]; 695 const amplitudes = [0.035, 0.025, 0.03, 0.02, 0.028, 0.024]; 696 const speeds = [0.00072, 0.00061, 0.00078, 0.00054, 0.00067, 0.00058]; 697 const phases = [0, 1.2, 2.1, 0.7, 2.8, 1.8]; 698 const circles = []; 699 700 for (let index = 0; index < 6; index += 1) { 701 const circle = document.createElementNS("http://www.w3.org/2000/svg", "circle"); 702 circle.setAttribute("r", "5"); 703 radarPoints.appendChild(circle); 704 circles.push(circle); 705 } 706 707 const drawRadar = function(time) { 708 const points = values.map(function(value, index) { 709 const animatedValue = reducedMotion ? value : value + Math.sin(time * speeds[index] + phases[index]) * amplitudes[index]; 710 const angle = -Math.PI / 2 + index * Math.PI / 3; 711 return { 712 x: center.x + Math.cos(angle) * radius * animatedValue, 713 y: center.y + Math.sin(angle) * radius * animatedValue 714 }; 715 }); 716 717 radarPolygon.setAttribute("points", points.map(function(point) { 718 return point.x.toFixed(2) + "," + point.y.toFixed(2); 719 }).join(" ")); 720 721 points.forEach(function(point, index) { 722 circles[index].setAttribute("cx", point.x.toFixed(2)); 723 circles[index].setAttribute("cy", point.y.toFixed(2)); 724 }); 725 726 if (!reducedMotion) { 727 requestAnimationFrame(drawRadar); 728 } 729 }; 730 731 requestAnimationFrame(drawRadar); 732 } 733})(); 734 735$(document).ready(function() { 736 const postFormButtons = function($form) { 737 let $buttons = $form.find('button[type="submit"], input[type="submit"]'); 738 const formId = $form.attr("id"); 739 740 /* Checkout má submit i mimo samotný <form> v pravém souhrnu. */ 741 if (formId) { 742 $('[form]').each(function() { 743 const $button = $(this); 744 if ($button.attr("form") === formId && ($button.is('button[type="submit"]') || $button.is('input[type="submit"]'))) { 745 $buttons = $buttons.add($button); 746 } 747 }); 748 } 749 750 return $buttons; 751 }; 752 753 const setPostFormLoading = function($form, loading) { 754 const $buttons = postFormButtons($form); 755 const loadingText = ($("body").attr("data-postform-loading") || "Please waitâ¦"); 756 757 $buttons.each(function() { 758 const $button = $(this); 759 760 if (loading) { 761 if ($button.data("postFormLoading")) { 762 return; 763 } 764 765 $button.data("postFormLoading", true); 766 $button.data("postFormWasDisabled", $button.prop("disabled")); 767 768 if ($button.is("input")) { 769 $button.data("postFormOriginalValue", $button.val()); 770 $button.val(loadingText); 771 } else { 772 $button.data("postFormOriginalHtml", $button.html()); 773 $button.html('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> ' + $('<div>').text(loadingText).html()); 774 } 775 776 $button.prop("disabled", true).attr("aria-busy", "true"); 777 } else { 778 if (!$button.data("postFormLoading")) { 779 return; 780 } 781 782 if ($button.is("input")) { 783 $button.val($button.data("postFormOriginalValue")); 784 $button.removeData("postFormOriginalValue"); 785 } else { 786 $button.html($button.data("postFormOriginalHtml")); 787 $button.removeData("postFormOriginalHtml"); 788 } 789 790 const wasDisabled = !!$button.data("postFormWasDisabled"); 791 $button.prop("disabled", wasDisabled).removeAttr("aria-busy"); 792 $button.removeData("postFormWasDisabled"); 793 $button.removeData("postFormLoading"); 794 } 795 }); 796 }; 797 798 jQuery(".postForm").submit(function(event) { 799 event.preventDefault(); 800 801 const $form = jQuery(this); 802 if ($form.data("postFormSubmitting")) { 803 return false;
804 } 805 806 const url = $form.attr("action"); 807 $form.data("postFormSubmitting", true); 808 setPostFormLoading($form, true); 809 810 jQuery.ajax({ 811 url: url, 812 type: "POST", 813 data: $form.serialize(), 814 success: function(data) { 815 jQuery("#postRsl").empty().append(data); 816 }, 817 complete: function() { 818 setPostFormLoading($form, false); 819 $form.removeData("postFormSubmitting"); 820 } 821 }); 822 823 return false; 824 }); 825 826 $(".imageForm").submit(function(event) { 827 event.preventDefault(); 828 829 const $form = jQuery(this); 830 if ($form.data("postFormSubmitting")) { 831 return false; 832 } 833 834 const url = $form.attr("action"); 835 const formData = new FormData($(this)[0]); 836 837 $form.data("postFormSubmitting", true); 838 setPostFormLoading($form, true); 839 840 $.ajax({ 841 url: url, 842 type: "POST", 843 data: formData, 844 async: true, 845 success: function(data) { 846 jQuery("#postRsl").empty().append(data); 847 }, 848 complete: function() { 849 setPostFormLoading($form, false); 850 $form.removeData("postFormSubmitting"); 851 }, 852 cache: false, 853 contentType: false, 854 processData: false 855 }); 856 857 return false; 858 }); 859});
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.