1"use strict"; 2 3(function () { 4 // Global variables 5 var userAgent = navigator.userAgent.toLowerCase(), 6 initialDate = new Date(), 7 8 $document = $(document), 9 $window = $(window), 10 $html = $("html"), 11 $body = $("body"), 12 13 isDesktop = $html.hasClass("desktop"), 14 isIE = userAgent.indexOf("msie") !== -1 ? parseInt(userAgent.split("msie")[1], 10) : userAgent.indexOf("trident") !== -1 ? 11 : userAgent.indexOf("edge") !== -1 ? 12 : false, 15 isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent), 16 isNoviBuilder = false, 17 windowReady = false, 18 preloaderAnimateionDuration = 10, 19 plugins = { 20 pointerEvents: isIE < 11 ? "js/pointer-events.min.js" : false, 21 bootstrapTooltip: $("[data-toggle='tooltip']"), 22 bootstrapModalDialog: $('.modal'), 23 bootstrapTabs: $(".tabs-custom-init"), 24 rdNavbar: $(".rd-navbar"), 25 materialParallax: $(".parallax-container"), 26 maps: $('.google-map-container'), 27 rdMailForm: $(".rd-mailform"), 28 rdInputLabel: $(".form-label"), 29 regula: $("[data-constraints]"), 30 wow: $(".wow"), 31 copyrightYear: $(".copyright-year"), 32 owl: $(".owl-carousel"), 33 swiper: $(".swiper-slider"), 34 search: $(".rd-search"), 35 searchResults: $('.rd-search-results'), 36 statefulButton: $('.btn-stateful'), 37 isotope: $(".isotope"), 38 popover: $('[data-toggle="popover"]'), 39 viewAnimate: $('.view-animate'), 40 radio: $("input[type='radio']"), 41 checkbox: $("input[type='checkbox']"), 42 customToggle: $("[data-custom-toggle]"), 43 facebookWidget: $('#fb-root'), 44 //preloader: $('.preloader'), 45 captcha: $('.recaptcha'), 46 mailchimp: $('.mailchimp-mailform'), 47 campaignMonitor: $('.campaign-mailform'), 48 selectFilter: $("select"), 49 counter: document.querySelectorAll('.counter'), 50 progressLinear: document.querySelectorAll('.progress-linear'), 51 progressCircle: document.querySelectorAll('.progress-circle'), 52 countdown: document.querySelectorAll('.countdown') 53 }; 54 55 /** 56 * @desc Check the element was been scrolled into the view 57 * @param {object} elem - jQuery object 58 * @return {boolean} 59 */ 60 function isScrolledIntoView(elem) { 61 if (isNoviBuilder) return true; 62 return elem.offset().top + elem.outerHeight() >= $window.scrollTop() && elem.offset().top <= $window.scrollTop() + $window.height(); 63 } 64 65 /** 66 * @desc Calls a function when element has been scrolled into the view 67 * @param {object} element - jQuery object 68 * @param {function} func - init function 69 */ 70 function lazyInit(element, func) { 71 var scrollHandler = function () { 72 if ((!element.hasClass('lazy-loaded') && (isScrolledIntoView(element)))) { 73 func.call(element); 74 element.addClass('lazy-loaded'); 75 } 76 }; 77 78 scrollHandler(); 79 $window.on('scroll', scrollHandler); 80 } 81 82 $window.on('load', function () { 83/* 84 // Page loader & Page transition 85 if (plugins.preloader.length && !isNoviBuilder) { 86 pageTransition({ 87 target: document.querySelector('.page'), 88 delay: 0, 89 duration: 10, 90 classIn: 'fadeIn', 91 classOut: 'fadeOut', 92 classActive: 'animated', 93 conditions: function (event, link) { 94 return link && !/(\#|javascript:void\(0\)|callto:|tel:|mailto:|:\/\/)/.test(link) && !event.currentTarget.hasAttribute('data-lightgallery'); 95 }, 96 onTransitionStart: function (options) { 97 setTimeout(function () { 98 plugins.preloader.removeClass('loaded'); 99 }, options.duration * .75); 100 }, 101 onReady: function () { 102 plugins.preloader.addClass('loaded'); 103 windowReady = true; 104 } 105 }); 106 }*/ 107 windowReady = true; 108 // Counter 109 if (plugins.counter) { 110 for (var i = 0; i < plugins.counter.length; i++) { 111 var 112 node = plugins.counter[i], 113 counter = aCounter({ 114 node: node, 115 duration: node.getAttribute('data-duration') || 1000 116 }), 117 scrollHandler = (function () { 118 if (Util.inViewport(this) && !this.classList.contains('animated-first')) { 119 this.counter.run(); 120 this.classList.add('animated-first'); 121 } 122 }).bind(node), 123 blurHandler = (function () { 124 this.counter.params.to = parseInt(this.textContent, 10); 125 this.counter.run(); 126 }).bind(node); 127 128 if (isNoviBuilder) { 129 node.counter.run(); 130 node.addEventListener('blur', blurHandler); 131 } else { 132 scrollHandler(); 133 window.addEventListener('scroll', scrollHandler); 134 } 135 } 136 } 137 138 // Progress Bar 139 if (plugins.progressLinear) { 140 for (var i = 0; i < plugins.progressLinear.length; i++) { 141 var 142 container = plugins.progressLinear[i], 143 counter = aCounter({ 144 node: container.querySelector('.progress-linear-counter'), 145 duration: container.getAttribute('data-duration') || 1000, 146 onStart: function () { 147 this.custom.bar.style.width = this.params.to + '%'; 148 } 149 }); 150 151 counter.custom = { 152 container: container, 153 bar: container.querySelector('.progress-linear-bar'), 154 onScroll: (function () { 155 if ((Util.inViewport(this.custom.container) && !this.custom.container.classList.contains('animated')) || isNoviBuilder) { 156 this.run(); 157 this.custom.container.classList.add('animated'); 158 } 159 }).bind(counter), 160 onBlur: (function () { 161 this.params.to = parseInt(this.params.node.textContent, 10); 162 this.run(); 163 }).bind(counter) 164 }; 165 166 if (isNoviBuilder) { 167 counter.run(); 168 counter.params.node.addEventListener('blur', counter.custom.onBlur); 169 } else { 170 counter.custom.onScroll(); 171 document.addEventListener('scroll', counter.custom.onScroll); 172 } 173 } 174 } 175 176 // Progress Circle 177 if (plugins.progressCircle) { 178 for (var i = 0; i < plugins.progressCircle.length; i++) { 179 var 180 container = plugins.progressCircle[i], 181 counter = aCounter({ 182 node: container.querySelector('.progress-circle-counter'), 183 duration: 500, 184 onUpdate: function (value) { 185 this.custom.bar.render(value * 3.6); 186 } 187 }); 188 189 counter.params.onComplete = counter.params.onUpdate; 190 191 counter.custom = { 192 container: container, 193 bar: aProgressCircle({ node: container.querySelector('.progress-circle-bar') }), 194 onScroll: (function () { 195 if (Util.inViewport(this.custom.container) && !this.custom.container.classList.contains('animated')) { 196 this.run(); 197 this.custom.container.classList.add('animated'); 198 } 199 }).bind(counter), 200 onBlur: (function () { 201 this.params.to = parseInt(this.params.node.textContent, 10); 202 this.run(); 203 }).bind(counter) 204 }; 205 206 if (isNoviBuilder) { 207 counter.run(); 208 counter.params.node.addEventListener('blur', counter.custom.onBlur); 209 } else { 210 counter.custom.onScroll(); 211 window.addEventListener('scroll', counter.custom.onScroll); 212 } 213 } 214 } 215 216 // Isotope 217 if (plugins.isotope.length) { 218 for (var i = 0; i < plugins.isotope.length; i++) { 219 var 220 wrap = plugins.isotope[i], 221 filterHandler = function (event) { 222 event.preventDefault(); 223 for (var n = 0; n < this.isoGroup.filters.length; n++) this.isoGroup.filters[n].classList.remove('active'); 224 this.classList.add('active'); 225 this.isoGroup.isotope.arrange({ filter: this.getAttribute("data-isotope-filter") !== '*' ? '[data-filter*="' + this.getAttribute("data-isotope-filter") + '"]' : '*' });
226 }, 227 resizeHandler = function () { 228 this.isoGroup.isotope.layout(); 229 }; 230 231 wrap.isoGroup = {}; 232 wrap.isoGroup.filters = wrap.querySelectorAll('[data-isotope-filter]'); 233 wrap.isoGroup.node = wrap.querySelector('.isotope'); 234 wrap.isoGroup.layout = wrap.isoGroup.node.getAttribute('data-isotope-layout') ? wrap.isoGroup.node.getAttribute('data-isotope-layout') : 'masonry'; 235 wrap.isoGroup.isotope = new Isotope(wrap.isoGroup.node, { 236 itemSelector: '.isotope-item', 237 layoutMode: wrap.isoGroup.layout, 238 filter: '*', 239 columnWidth: (function () { 240 if (wrap.isoGroup.node.hasAttribute('data-column-class')) return wrap.isoGroup.node.getAttribute('data-column-class'); 241 if (wrap.isoGroup.node.hasAttribute('data-column-width')) return parseFloat(wrap.isoGroup.node.getAttribute('data-column-width')); 242 }()) 243 }); 244 245 for (var n = 0; n < wrap.isoGroup.filters.length; n++) { 246 var filter = wrap.isoGroup.filters[n]; 247 filter.isoGroup = wrap.isoGroup; 248 filter.addEventListener('click', filterHandler); 249 } 250 251 window.addEventListener('resize', resizeHandler.bind(wrap)); 252 } 253 } 254 255 }); 256 257 // Initialize scripts that require a finished document 258 $(function () { 259 isNoviBuilder = window.xMode; 260 /** 261 * @desc Google map function for getting latitude and longitude 262 */ 263 function getLatLngObject(str, marker, map, callback) { 264 var coordinates = {}; 265 try { 266 coordinates = JSON.parse(str); 267 callback(new google.maps.LatLng( 268 coordinates.lat, 269 coordinates.lng 270 ), marker, map) 271 } catch (e) { 272 map.geocoder.geocode({ 'address': str }, function (results, status) { 273 if (status === google.maps.GeocoderStatus.OK) { 274 var latitude = results[0].geometry.location.lat(); 275 var longitude = results[0].geometry.location.lng(); 276 277 callback(new google.maps.LatLng( 278 parseFloat(latitude), 279 parseFloat(longitude) 280 ), marker, map) 281 } 282 }) 283 } 284 } 285 286 /** 287 * @desc Initialize Google maps 288 */ 289 function initMaps() { 290 var key; 291 292 for (var i = 0; i < plugins.maps.length; i++) { 293 if (plugins.maps[i].hasAttribute("data-key")) { 294 key = plugins.maps[i].getAttribute("data-key"); 295 break; 296 } 297 } 298 299 $.getScript('//maps.google.com/maps/api/js?' + (key ? 'key=' + key + '&' : '') + 'libraries=geometry,places&v=quarterly', function () { 300 var head = document.getElementsByTagName('head')[0], 301 insertBefore = head.insertBefore; 302 303 head.insertBefore = function (newElement, referenceElement) { 304 if (newElement.href && newElement.href.indexOf('//fonts.googleapis.com/css?family=Roboto') !== -1 || newElement.innerHTML.indexOf('gm-style') !== -1) { 305 return; 306 } 307 insertBefore.call(head, newElement, referenceElement); 308 }; 309 var geocoder = new google.maps.Geocoder; 310 for (var i = 0; i < plugins.maps.length; i++) { 311 var zoom = parseInt(plugins.maps[i].getAttribute("data-zoom"), 10) || 11; 312 var styles = plugins.maps[i].hasAttribute('data-styles') ? JSON.parse(plugins.maps[i].getAttribute("data-styles")) : []; 313 var center = plugins.maps[i].getAttribute("data-center") || "New York"; 314 315 // Initialize map 316 var map = new google.maps.Map(plugins.maps[i].querySelectorAll(".google-map")[0], { 317 zoom: zoom, 318 styles: styles, 319 scrollwheel: false, 320 center: { lat: 0, lng: 0 } 321 }); 322 323 // Add map object to map node 324 plugins.maps[i].map = map; 325 plugins.maps[i].geocoder = geocoder; 326 plugins.maps[i].keySupported = true; 327 plugins.maps[i].google = google; 328 329 // Get Center coordinates from attribute
330 getLatLngObject(center, null, plugins.maps[i], function (location, markerElement, mapElement) { 331 mapElement.map.setCenter(location); 332 }); 333 334 // Add markers from google-map-markers array 335 var markerItems = plugins.maps[i].querySelectorAll(".google-map-markers li"); 336 337 if (markerItems.length) { 338 var markers = []; 339 for (var j = 0; j < markerItems.length; j++) { 340 var markerElement = markerItems[j]; 341 getLatLngObject(markerElement.getAttribute("data-location"), markerElement, plugins.maps[i], function (location, markerElement, mapElement) { 342 var icon = markerElement.getAttribute("data-icon") || mapElement.getAttribute("data-icon"); 343 var activeIcon = markerElement.getAttribute("data-icon-active") || mapElement.getAttribute("data-icon-active"); 344 var info = markerElement.getAttribute("data-description") || ""; 345 var infoWindow = new google.maps.InfoWindow({ 346 content: info 347 }); 348 markerElement.infoWindow = infoWindow; 349 var markerData = { 350 position: location, 351 map: mapElement.map 352 } 353 if (icon) { 354 markerData.icon = icon; 355 } 356 var marker = new google.maps.Marker(markerData); 357 markerElement.gmarker = marker; 358 markers.push({ markerElement: markerElement, infoWindow: infoWindow }); 359 marker.isActive = false; 360 // Handle infoWindow close click 361 google.maps.event.addListener(infoWindow, 'closeclick', (function (markerElement, mapElement) { 362 var markerIcon = null; 363 markerElement.gmarker.isActive = false; 364 markerIcon = markerElement.getAttribute("data-icon") || mapElement.getAttribute("data-icon"); 365 markerElement.gmarker.setIcon(markerIcon); 366 }).bind(this, markerElement, mapElement)); 367 368 369 // Set marker active on Click and open infoWindow 370 google.maps.event.addListener(marker, 'click', (function (markerElement, mapElement) { 371 if (markerElement.infoWindow.getContent().length === 0) return; 372 var gMarker, currentMarker = markerElement.gmarker, currentInfoWindow; 373 for (var k = 0; k < markers.length; k++) { 374 var markerIcon; 375 if (markers[k].markerElement === markerElement) { 376 currentInfoWindow = markers[k].infoWindow; 377 } 378 gMarker = markers[k].markerElement.gmarker; 379 if (gMarker.isActive && markers[k].markerElement !== markerElement) { 380 gMarker.isActive = false; 381 markerIcon = markers[k].markerElement.getAttribute("data-icon") || mapElement.getAttribute("data-icon") 382 gMarker.setIcon(markerIcon); 383 markers[k].infoWindow.close(); 384 } 385 } 386 387 currentMarker.isActive = !currentMarker.isActive; 388 if (currentMarker.isActive) { 389 if (markerIcon = markerElement.getAttribute("data-icon-active") || mapElement.getAttribute("data-icon-active")) { 390 currentMarker.setIcon(markerIcon); 391 } 392 393 currentInfoWindow.open(map, marker); 394 } else { 395 if (markerIcon = markerElement.getAttribute("data-icon") || mapElement.getAttribute("data-icon")) { 396 currentMarker.setIcon(markerIcon); 397 } 398 currentInfoWindow.close(); 399 } 400 }).bind(this, markerElement, mapElement)) 401 }) 402 } 403 } 404 } 405 }); 406 } 407 408 /** 409 * @desc Calculate the height of swiper slider basing on data attr
410 * @param {object} object - slider jQuery object 411 * @param {string} attr - attribute name 412 * @return {number} slider height 413 */ 414 function getSwiperHeight(object, attr) { 415 var val = object.attr("data-" + attr), 416 dim; 417 418 if (!val) { 419 return undefined; 420 } 421 422 dim = val.match(/(px)|(%)|(vh)|(vw)$/i); 423 424 if (dim.length) { 425 switch (dim[0]) { 426 case "px": 427 return parseFloat(val); 428 case "vh": 429 return $window.height() * (parseFloat(val) / 100); 430 case "vw": 431 return $window.width() * (parseFloat(val) / 100); 432 case "%": 433 return object.width() * (parseFloat(val) / 100); 434 } 435 } else { 436 return undefined; 437 } 438 } 439 440 /** 441 * @desc Toggle swiper videos on active slides 442 * @param {object} swiper - swiper slider 443 */ 444 function toggleSwiperInnerVideos(swiper) { 445 var prevSlide = $(swiper.slides[swiper.previousIndex]), 446 nextSlide = $(swiper.slides[swiper.activeIndex]), 447 videos; 448 449 prevSlide.find("video").each(function () { 450 this.pause(); 451 }); 452 453 videos = nextSlide.find("video"); 454 if (videos.length) { 455 videos.get(0).play(); 456 } 457 } 458 459 /** 460 * @desc Toggle swiper animations on active slides 461 * @param {object} swiper - swiper slider 462 */ 463 function toggleSwiperCaptionAnimation(swiper) { 464 var prevSlide = $(swiper.container), 465 nextSlide = $(swiper.slides[swiper.activeIndex]); 466 467 prevSlide 468 .find("[data-caption-animate]") 469 .each(function () { 470 var $this = $(this); 471 $this 472 .removeClass("animated") 473 .removeClass($this.attr("data-caption-animate")) 474 .addClass("not-animated"); 475 }); 476 477 nextSlide 478 .find("[data-caption-animate]") 479 .each(function () { 480 var $this = $(this), 481 delay = $this.attr("data-caption-delay"); 482 483 484 if (!isNoviBuilder) { 485 setTimeout(function () { 486 $this 487 .removeClass("not-animated") 488 .addClass($this.attr("data-caption-animate")) 489 .addClass("animated"); 490 }, delay ? parseInt(delay, 10) : 0); 491 } else { 492 $this 493 .removeClass("not-animated") 494 } 495 }); 496 } 497 498 499 /** 500 * @desc Initialize owl carousel plugin 501 * @param {object} c - carousel jQuery object 502 */ 503 function initOwlCarousel(c) { 504 var aliaces = ["-", "-sm-", "-md-", "-lg-", "-xl-", "-xxl-"], 505 values = [0, 576, 768, 992, 1200, 1600], 506 responsive = {}; 507 508 for (var j = 0; j < values.length; j++) { 509 responsive[values[j]] = {}; 510 for (var k = j; k >= -1; k--) { 511 if (!responsive[values[j]]["items"] && c.attr("data" + aliaces[k] + "items")) { 512 responsive[values[j]]["items"] = k < 0 ? 1 : parseInt(c.attr("data" + aliaces[k] + "items"), 10); 513 } 514 if (!responsive[values[j]]["stagePadding"] && responsive[values[j]]["stagePadding"] !== 0 && c.attr("data" + aliaces[k] + "stage-padding")) { 515 responsive[values[j]]["stagePadding"] = k < 0 ? 0 : parseInt(c.attr("data" + aliaces[k] + "stage-padding"), 10); 516 } 517 if (!responsive[values[j]]["margin"] && responsive[values[j]]["margin"] !== 0 && c.attr("data" + aliaces[k] + "margin")) { 518 responsive[values[j]]["margin"] = k < 0 ? 30 : parseInt(c.attr("data" + aliaces[k] + "margin"), 10); 519 } 520 } 521 } 522 523 // Enable custom pagination 524 if (c.attr('data-dots-custom')) { 525 c.on("initialized.owl.carousel", function (event) { 526 var carousel = $(event.currentTarget), 527 customPag = $(carousel.attr("data-dots-custom")), 528 active = 0; 529 530 if (carousel.attr('data-active')) { 531 active = parseInt(carousel.attr('data-active'), 10); 532 } 533 534 carousel.trigger('to.owl.carousel', [active, 300, true]); 535 customPag.find("[data-owl-item='" + active + "']").addClass("active"); 536 537 customPag.find("[data-owl-item]").on('click', function (e) { 538 e.preventDefault(); 539 carousel.trigger('to.owl.carousel', [parseInt(this.getAttribute("data-owl-item"), 10), 300, true]); 540 }); 541 542 carousel.on("translate.owl.carousel", function (event) { 543 customPag.find(".active").removeClass("active"); 544 customPag.find("[data-owl-item='" + (event.item.index + 1) % event.item.count + "']").addClass("active") 545 }); 546 }); 547 } 548 549 550 c.owlCarousel({ 551 autoplay: isNoviBuilder ? false : c.attr("data-autoplay") === "true", 552 autoplayTimeout: c.attr("data-autoplay-timeout") ? c.attr("data-autoplay-timeout")
552: 3500, 553 loop: isNoviBuilder ? false : c.attr("data-loop") !== "false", 554 items: 1, 555 center: c.attr("data-center") === "true", 556 dotsContainer: c.attr("data-pagination-container") || false, 557 navContainer: c.attr("data-navigation-container") || false, 558 mouseDrag: isNoviBuilder ? false : c.attr("data-mouse-drag") !== "false", 559 nav: c.attr("data-nav") === "true", 560 dots: c.attr("data-dots") === "true", 561 dotsEach: c.attr("data-dots-each") ? parseInt(c.attr("data-dots-each"), 10) : false, 562 animateIn: c.attr('data-animation-in') ? c.attr('data-animation-in') : false, 563 animateOut: c.attr('data-animation-out') ? c.attr('data-animation-out') : false, 564 responsive: responsive, 565 navText: function () { 566 try { 567 return JSON.parse(c.attr("data-nav-text")); 568 } catch (e) { 569 return []; 570 } 571 }(), 572 navClass: function () { 573 try { 574 return JSON.parse(c.attr("data-nav-class")); 575 } catch (e) { 576 return ['owl-prev', 'owl-next']; 577 } 578 }() 579 }); 580 } 581 582 /** 583 * @desc Check the element whas been scrolled into the view 584 * @param {object} elem - jQuery object 585 * @return {boolean} 586 */ 587 function isScrolledIntoView(elem) { 588 if (!isNoviBuilder) { 589 return elem.offset().top + elem.outerHeight() >= $window.scrollTop() && elem.offset().top <= $window.scrollTop() + $window.height(); 590 } 591 else { 592 return true; 593 } 594 } 595 596 597 /** 598 * @desc Create live search results 599 * @param {object} options 600 */ 601 function liveSearch(options) { 602 $('#' + options.live).removeClass('cleared').html(); 603 options.current++; 604 options.spin.addClass('loading'); 605 $.get(handler, { 606 s: decodeURI(options.term), 607 liveSearch: options.live, 608 dataType: "html", 609 liveCount: options.liveCount, 610 filter: options.filter, 611 template: options.template 612 }, function (data) { 613 options.processed++; 614 var live = $('#' + options.live); 615 if ((options.processed === options.current) && !live.hasClass('cleared')) { 616 live.find('> #search-results').removeClass('active'); 617 live.html(data); 618 setTimeout(function () { 619 live.find('> #search-results').addClass('active'); 620 }, 50); 621 } 622 options.spin.parents('.rd-search').find('.input-group-addon').removeClass('loading'); 623 }) 624 } 625 626 /** 627 * @desc Attach form validation to elements 628 * @param {object} elements - jQuery object 629 */ 630 function attachFormValidator(elements) { 631 // Custom validator - phone number 632 regula.custom({ 633 name: 'PhoneNumber', 634 defaultMessage: 'Invalid phone number format', 635 validator: function () { 636 if (this.value === '') return true; 637 else return /^(\+\d)?[0-9\-\(\) ]{5,}$/i.test(this.value); 638 } 639 }); 640 641 for (var i = 0; i < elements.length; i++) { 642 var o = $(elements[i]), v; 643 o.addClass("form-control-has-validation").after("<span class='form-validation'></span>"); 644 v = o.parent().find(".form-validation"); 645 if (v.is(":last-child")) o.addClass("form-control-last-child"); 646 } 647 648 elements.on('input change propertychange blur', function (e) { 649 var $this = $(this), results; 650 651 if (e.type !== "blur") if (!$this.parent().hasClass("has-error")) return; 652 if ($this.parents('.rd-mailform').hasClass('success')) return; 653 654 if ((results = $this.regula('validate')).length) { 655 for (i = 0; i < results.length; i++) { 656 $this.siblings(".form-validation").text(results[i].message).parent().addClass("has-error"); 657 } 658 } else { 659 $this.siblings(".form-validation").text("").parent().removeClass("has-error") 660 } 661 }).regula('bind'); 662 663 var regularConstraintsMessages = [ 664 { 665 type: regula.Constraint.Required, 666 newMessage: "The text field is required." 667 }, 668 { 669 type: regula.Constraint.Email, 670 newMessage: "The email is not a valid email." 671 }, 672 { 673 type: regula.Constraint.Numeric, 674 newMessage: "Only numbers are required" 675 }, 676 { 677 type: regula.Constraint.Selected, 678 newMessage: "Please choose an option." 679 } 680 ]; 681 682 683 for (var i = 0; i < regularConstraintsMessages.length; i++) { 684 var regularConstraint = regularConstraintsMessages[i]; 685 686 regula.override({ 687 constraintType: regularConstraint.type, 688 defaultMessage: regularConstraint.newMessage 689 }); 690 } 691 } 692 693 /**
694 * @desc Check if all elements pass validation 695 * @param {object} elements - object of items for validation 696 * @param {object} captcha - captcha object for validation 697 * @return {boolean} 698 */ 699 function isValidated(elements, captcha) { 700 var results, errors = 0; 701 702 if (elements.length) { 703 for (var j = 0; j < elements.length; j++) { 704 705 var $input = $(elements[j]); 706 if ((results = $input.regula('validate')).length) { 707 for (k = 0; k < results.length; k++) { 708 errors++; 709 $input.siblings(".form-validation").text(results[k].message).parent().addClass("has-error"); 710 } 711 } else { 712 $input.siblings(".form-validation").text("").parent().removeClass("has-error") 713 } 714 } 715 716 if (captcha) { 717 if (captcha.length) { 718 return validateReCaptcha(captcha) && errors === 0 719 } 720 } 721 722 return errors === 0; 723 } 724 return true; 725 } 726 727 /** 728 * @desc Validate google reCaptcha 729 * @param {object} captcha - captcha object for validation 730 * @return {boolean} 731 */ 732 function validateReCaptcha(captcha) { 733 var captchaToken = captcha.find('.g-recaptcha-response').val(); 734 735 if (captchaToken.length === 0) { 736 captcha 737 .siblings('.form-validation') 738 .html('Please, prove that you are not robot.') 739 .addClass('active'); 740 captcha 741 .closest('.form-wrap') 742 .addClass('has-error'); 743 744 captcha.on('propertychange', function () { 745 var $this = $(this), 746 captchaToken = $this.find('.g-recaptcha-response').val(); 747 748 if (captchaToken.length > 0) { 749 $this 750 .closest('.form-wrap') 751 .removeClass('has-error'); 752 $this 753 .siblings('.form-validation') 754 .removeClass('active') 755 .html(''); 756 $this.off('propertychange'); 757 } 758 }); 759 760 return false; 761 } 762 763 return true; 764 } 765 766 /** 767 * @desc Initialize Google reCaptcha 768 */ 769 window.onloadCaptchaCallback = function () { 770 for (var i = 0; i < plugins.captcha.length; i++) { 771 var 772 $captcha = $(plugins.captcha[i]), 773 resizeHandler = (function () { 774 var 775 frame = this.querySelector('iframe'), 776 inner = this.firstElementChild, 777 inner2 = inner.firstElementChild, 778 containerRect = null, 779 frameRect = null, 780 scale = null; 781 782 inner2.style.transform = ''; 783 inner.style.height = 'auto'; 784 inner.style.width = 'auto'; 785 786 containerRect = this.getBoundingClientRect(); 787 frameRect = frame.getBoundingClientRect(); 788 scale = containerRect.width / frameRect.width; 789 790 if (scale < 1) { 791 inner2.style.transform = 'scale(' + scale + ')'; 792 inner.style.height = (frameRect.height * scale) + 'px'; 793 inner.style.width = (frameRect.width * scale) + 'px'; 794 } 795 }).bind(plugins.captcha[i]); 796 797 grecaptcha.render( 798 $captcha.attr('id'), 799 { 800 sitekey: $captcha.attr('data-sitekey'), 801 size: $captcha.attr('data-size') ? $captcha.attr('data-size') : 'normal', 802 theme: $captcha.attr('data-theme') ? $captcha.attr('data-theme') : 'light', 803 callback: function () { 804 $('.recaptcha').trigger('propertychange'); 805 } 806 } 807 ); 808 809 $captcha.after("<span class='form-validation'></span>"); 810 811 if (plugins.captcha[i].hasAttribute('data-auto-size')) { 812 resizeHandler(); 813 window.addEventListener('resize', resizeHandler); 814 } 815 } 816 }; 817 818 /** 819 * @desc Initialize Bootstrap tooltip with required placement 820 * @param {string} tooltipPlacement 821 */ 822 function initBootstrapTooltip(tooltipPlacement) { 823 plugins.bootstrapTooltip.tooltip('dispose'); 824 825 if (window.innerWidth < 576) { 826 plugins.bootstrapTooltip.tooltip({ placement: 'bottom' }); 827 } else { 828 plugins.bootstrapTooltip.tooltip({ placement: tooltipPlacement }); 829 } 830 } 831 832 // Google ReCaptcha 833 if (plugins.captcha.length) { 834 $.getScript("//www.google.com/recaptcha/api.js?onload=onloadCaptchaCallback&render=explicit&hl=en"); 835 } 836 837 // Additional class on html if mac os. 838 if (navigator.platform.match(/(Mac)/i)) $html.addClass("mac-os"); 839 840 // Adds some loosing functionality to IE browsers (IE Polyfills) 841 if (isIE) { 842 if (isIE < 10) { 843 $html.addClass("lt-ie-10"); 844 } 845 846 if (isIE < 11) { 847 $.getScript('js/pointer-events.min.js') 848 .done(function () { 849 $html.addClass("ie-10"); 850 PointerEventsPolyfill.initialize({}); 851 }); 852 } 853 854 if (isIE === 11) { 855 $html.addClass("ie-11"); 856 } 857 858 if (isIE === 12) { 859 $html.addClass("ie-edge"); 860 } 861 } 862 863 // Bootstrap Tooltips 864 if (plugins.bootstrapTooltip.length) { 865 var tooltipPlacement = plugins.bootstrapTooltip.attr('data-placement'); 866 initBootstrapTooltip(tooltipPlacement); 867 868 $window.on('resize orientationchange', function () { 869 initBootstrapTooltip(tooltipPlacement); 870 }) 871 } 872 873 // Copyright Year (Evaluates correct copyright year) 874 if (plugins.copyrightYear.length) { 875 plugins.copyrightYear.text(initialDate.getFullYear()); 876 } 877 878 // Stop vioeo in bootstrapModalDialog 879 if (plugins.bootstrapModalDialog.length) { 880 for (var i = 0; i < plugins.bootstrapModalDialog.length; i++) { 881 var modalItem = $(plugins.bootstrapModalDialog[i]); 882 883 modalItem.on('hidden.bs.modal', $.proxy(function () { 884 var activeModal = $(this), 885 rdVideoInside = activeModal.find('video'), 886 youTubeVideoInside = activeModal.find('iframe'); 887 888 if (rdVideoInside.length) { 889 rdVideoInside[0].pause(); 890 } 891 892 if (youTubeVideoInside.length) { 893 var videoUrl = youTubeVideoInside.attr('src'); 894 895 youTubeVideoInside 896 .attr('src', '') 897 .attr('src', videoUrl); 898 } 899 }, modalItem)) 900 } 901 } 902 903 // Popovers 904 if (plugins.popover.length) { 905 if (window.innerWidth < 767) { 906 plugins.popover.attr('data-placement', 'bottom'); 907 plugins.popover.popover(); 908 } 909 else { 910 plugins.popover.popover(); 911 } 912 } 913 914 // Bootstrap Buttons 915 if (plugins.statefulButton.length) { 916 $(plugins.statefulButton).on('click', function () { 917 var statefulButtonLoading = $(this).button('loading'); 918 919 setTimeout(function () { 920 statefulButtonLoading.button('reset') 921 }, 2000); 922 }) 923 } 924 925 // Bootstrap tabs 926 if (plugins.bootstrapTabs.length) { 927 for (var i = 0; i < plugins.bootstrapTabs.length; i++) { 928 var bootstrapTabsItem = $(plugins.bootstrapTabs[i]); 929 930 //If have slick carousel inside tab - resize slick carousel on click 931 if (bootstrapTabsItem.find('.slick-slider').length) { 932 bootstrapTabsItem.find('.tabs-custom-list > li > a').on('click', $.proxy(function () { 933 var $this = $(this); 934 var setTimeOutTime = isNoviBuilder ? 1500 : 300; 935 936 setTimeout(function () { 937 $this.find('.tab-content .tab-pane.active .slick-slider').slick('setPosition'); 938 }, setTimeOutTime); 939 }, bootstrapTabsItem)); 940 } 941 } 942 } 943 944 // Facebook widget 945 if (plugins.facebookWidget.length) { 946 lazyInit(plugins.facebookWidget, function () { 947 (function (d, s, id) { 948 var js, fjs = d.getElementsByTagName(s)[0]; 949 if (d.getElementById(id)) return; 950 js = d.createElement(s); 951 js.id = id; 952 js.src = "//connect.facebook.net/en_EN/sdk.js#xfbml=1&version=v2.5"; 953 fjs.parentNode.insertBefore(js, fjs); 954 }(document, 'script', 'facebook-jssdk')); 955 }); 956 } 957 958 // Add custom styling options for input[type="radio"] 959 if (plugins.radio.length) { 960 for (var i = 0; i < plugins.radio.length; i++) { 961 $(plugins.radio[i]).addClass("radio-custom").after("<span class='radio-custom-dummy'></span>") 962 } 963 } 964 965 // Add custom styling options for input[type="checkbox"] 966 if (plugins.checkbox.length) { 967 for (var i = 0; i < plugins.checkbox.length; i++) { 968 $(plugins.checkbox[i]).addClass("checkbox-custom").after("<span class='checkbox-custom-dummy'></span>") 969 } 970 } 971 972 // UI To Top 973 if (isDesktop && !isNoviBuilder) { 974 $().UItoTop({
975 easingType: 'easeOutQuad', 976 containerClass: 'ui-to-top fa fa-angle-up' 977 }); 978 } 979 980 // RD Navbar 981 if (plugins.rdNavbar.length) { 982 var aliaces, i, j, len, value, values, responsiveNavbar; 983 984 aliaces = ["-", "-sm-", "-md-", "-lg-", "-xl-", "-xxl-"]; 985 values = [0, 576, 768, 992, 1200, 1600]; 986 responsiveNavbar = {}; 987 988 for (i = j = 0, len = values.length; j < len; i = ++j) { 989 value = values[i]; 990 if (!responsiveNavbar[values[i]]) { 991 responsiveNavbar[values[i]] = {}; 992 } 993 if (plugins.rdNavbar.attr('data' + aliaces[i] + 'layout')) { 994 responsiveNavbar[values[i]].layout = plugins.rdNavbar.attr('data' + aliaces[i] + 'layout'); 995 } 996 if (plugins.rdNavbar.attr('data' + aliaces[i] + 'device-layout')) { 997 responsiveNavbar[values[i]]['deviceLayout'] = plugins.rdNavbar.attr('data' + aliaces[i] + 'device-layout'); 998 } 999 if (plugins.rdNavbar.attr('data' + aliaces[i] + 'hover-on')) { 1000 responsiveNavbar[values[i]]['focusOnHover'] = plugins.rdNavbar.attr('data' + aliaces[i] + 'hover-on') === 'true'; 1001 } 1002 if (plugins.rdNavbar.attr('data' + aliaces[i] + 'auto-height')) { 1003 responsiveNavbar[values[i]]['autoHeight'] = plugins.rdNavbar.attr('data' + aliaces[i] + 'auto-height') === 'true'; 1004 } 1005 1006 if (isNoviBuilder) { 1007 responsiveNavbar[values[i]]['stickUp'] = false; 1008 } else if (plugins.rdNavbar.attr('data' + aliaces[i] + 'stick-up')) { 1009 responsiveNavbar[values[i]]['stickUp'] = plugins.rdNavbar.attr('data' + aliaces[i] + 'stick-up') === 'true'; 1010 } 1011 1012 if (plugins.rdNavbar.attr('data' + aliaces[i] + 'stick-up-offset')) { 1013 responsiveNavbar[values[i]]['stickUpOffset'] = plugins.rdNavbar.attr('data' + aliaces[i] + 'stick-up-offset'); 1014 } 1015 } 1016 1017 1018 plugins.rdNavbar.RDNavbar({ 1019 anchorNav: !isNoviBuilder, 1020 stickUpClone: (plugins.rdNavbar.attr("data-stick-up-clone") && !isNoviBuilder) ? plugins.rdNavbar.attr("data-stick-up-clone") === 'true' : false, 1021 responsive: responsiveNavbar, 1022 callbacks: { 1023 onStuck: function () { 1024 var navbarSearch = this.$element.find('.rd-search input'); 1025 1026 if (navbarSearch) { 1027 navbarSearch.val('').trigger('propertychange'); 1028 } 1029 }, 1030 onDropdownOver: function () { 1031 return !isNoviBuilder; 1032 }, 1033 onUnstuck: function () { 1034 if (this.$clone === null) 1035 return; 1036 1037 var navbarSearch = this.$clone.find('.rd-search input'); 1038 1039 if (navbarSearch) { 1040 navbarSearch.val('').trigger('propertychange'); 1041 navbarSearch.trigger('blur'); 1042 } 1043 1044 } 1045 } 1046 }); 1047 1048 1049 if (plugins.rdNavbar.attr("data-body-class")) { 1050 document.body.className += ' ' + plugins.rdNavbar.attr("data-body-class"); 1051 } 1052 } 1053 1054 1055 // RD Search 1056 if (plugins.search.length || plugins.searchResults) { 1057 var handler = "bat/rd-search.php"; 1058 var defaultTemplate = '<h5 class="search-title"><a target="_top" href="#{href}" class="search-link">#{title}</a></h5>' + 1059 '<p>...#{token}...</p>' + 1060 '<p class="match"><em>Terms matched: #{count} - URL: #{href}</em></p>'; 1061 var defaultFilter = '*.html'; 1062 1063 if (plugins.search.length) { 1064 for (var i = 0; i < plugins.search.length; i++) { 1065 var searchItem = $(plugins.search[i]), 1066 options = { 1067 element: searchItem, 1068 filter: (searchItem.attr('data-search-filter')) ? searchItem.attr('data-search-filter') : defaultFilter, 1069 template: (searchItem.attr('data-search-template')) ? searchItem.attr('data-search-template') : defaultTemplate, 1070 live: (searchItem.attr('data-search-live')) ? searchItem.attr('data-search-live') : false, 1071 liveCount: (searchItem.attr('data-search-live-count')) ? parseInt(searchItem.attr('data-search-live'), 10) : 4, 1072 current: 0, processed: 0, timer: {} 1073 }; 1074 1075 var $toggle = $('.rd-navbar-search-toggle'); 1076 if ($toggle.length) { 1077 $toggle.on('click', (function (searchItem) { 1078 return function () { 1079 if (!($(this).hasClass('active'))) { 1080 searchItem.find('input').val('').trigger('propertychange'); 1081 } 1082 } 1083 })(searchItem)); 1084 } 1085 1086 if (options.live) { 1087 var clearHandler = false; 1088 1089 searchItem.find('input').on("input propertychange", $.proxy(function () { 1090 this.term = this.element.find('input').val().trim(); 1091 this.spin = this.element.find('.input-group-addon'); 1092 1093 clearTimeout(this.timer); 1094 1095 if (this.term.length > 2) { 1096 this.timer = setTimeout(liveSearch(this), 200); 1097 1098 if (clearHandler === false) { 1099 clearHandler = true; 1100 1101 $body.on("click", function (e) { 1102 if ($(e.toElement).parents('.rd-search').length === 0) { 1103 $('#rd-search-results-live').addClass('cleared').html(''); 1104 } 1105 }) 1106 } 1107 1108 } else if (this.term.length === 0) { 1109 $('#' + this.live).addClass('cleared').html(''); 1110 } 1111 }, options, this)); 1112 } 1113 1114 searchItem.submit($.proxy(function () { 1115 $('<input />').attr('type', 'hidden') 1116 .attr('name', "filter") 1117 .attr('value', this.filter) 1118 .appendTo(this.element); 1119 return true; 1120 }, options, this)) 1121 } 1122 } 1123 1124 if (plugins.searchResults.length) { 1125 var regExp = /\?.*s=([^&]+)\&filter=([^&]+)/g; 1126 var match = regExp.exec(location.search); 1127 1128 if (match !== null) { 1129 $.get(handler, {
1130 s: decodeURI(match[1]), 1131 dataType: "html", 1132 filter: match[2], 1133 template: defaultTemplate, 1134 live: '' 1135 }, function (data) { 1136 plugins.searchResults.html(data); 1137 }) 1138 } 1139 } 1140 } 1141 1142 1143 // Add class in viewport 1144 if (plugins.viewAnimate.length) { 1145 for (var i = 0; i < plugins.viewAnimate.length; i++) { 1146 var $view = $(plugins.viewAnimate[i]).not('.active'); 1147 $document.on("scroll", $.proxy(function () { 1148 if (isScrolledIntoView(this)) { 1149 this.addClass("active"); 1150 } 1151 }, $view)) 1152 .trigger("scroll"); 1153 } 1154 } 1155 1156 1157 // Swiper 1158 if (plugins.swiper.length) { 1159 for (var i = 0; i < plugins.swiper.length; i++) { 1160 var s = $(plugins.swiper[i]); 1161 var pag = s.find(".swiper-pagination"), 1162 next = s.find(".swiper-button-next"), 1163 prev = s.find(".swiper-button-prev"), 1164 bar = s.find(".swiper-scrollbar"), 1165 swiperSlide = s.find(".swiper-slide"), 1166 autoplay = false; 1167 1168 for (var j = 0; j < swiperSlide.length; j++) { 1169 var $this = $(swiperSlide[j]), 1170 url; 1171 1172 if (url = $this.attr("data-slide-bg")) { 1173 $this.css({ 1174 "background-image": "url(" + url + ")", 1175 "background-size": "cover" 1176 }) 1177 } 1178 } 1179 1180 swiperSlide.end() 1181 .find("[data-caption-animate]") 1182 .addClass("not-animated") 1183 .end(); 1184 1185 s.swiper({ 1186 autoplay: s.attr('data-autoplay') ? s.attr('data-autoplay') === "false" ? undefined : s.attr('data-autoplay') : 5000, 1187 direction: s.attr('data-direction') ? s.attr('data-direction') : "horizontal", 1188 effect: s.attr('data-slide-effect') ? s.attr('data-slide-effect') : "slide", 1189 speed: s.attr('data-slide-speed') ? s.attr('data-slide-speed') : 600, 1190 keyboardControl: s.attr('data-keyboard') === "true", 1191 mousewheelControl: s.attr('data-mousewheel') === "true", 1192 mousewheelReleaseOnEdges: s.attr('data-mousewheel-release') === "true", 1193 nextButton: next.length ? next.get(0) : null, 1194 prevButton: prev.length ? prev.get(0) : null, 1195 pagination: pag.length ? pag.get(0) : null, 1196 paginationClickable: pag.length ? pag.attr("data-clickable") !== "false" : false, 1197 paginationBulletRender: pag.length ? pag.attr("data-index-bullet") === "true" ? function (swiper, index, className) { 1198 return '<span class="' + className + '">' + (index + 1) + '</span>'; 1199 } : null : null, 1200 scrollbar: bar.length ? bar.get(0) : null, 1201 scrollbarDraggable: bar.length ? bar.attr("data-draggable") !== "false" : true, 1202 scrollbarHide: bar.length ? bar.attr("data-draggable") === "false" : false, 1203 loop: isNoviBuilder ? false : s.attr('data-loop') !== "false", 1204 simulateTouch: s.attr('data-simulate-touch') && !isNoviBuilder ? s.attr('data-simulate-touch') === "true" : false, 1205 onTransitionStart: function (swiper) { 1206 toggleSwiperInnerVideos(swiper); 1207 }, 1208 onTransitionEnd: function (swiper) { 1209 toggleSwiperCaptionAnimation(swiper); 1210 }, 1211 onInit: (function (s) { 1212 return function (swiper) { 1213 toggleSwiperInnerVideos(swiper); 1214 toggleSwiperCaptionAnimation(swiper); 1215 1216 var $swiper = $(s); 1217 1218 var swiperCustomIndex = $swiper.find('.swiper-pagination__fraction-index').get(0), 1219 swiperCustomCount = $swiper.find('.swiper-pagination__fraction-count').get(0); 1220 1221 if (swiperCustomIndex && swiperCustomCount) { 1222 swiperCustomIndex.innerHTML = formatIndex(swiper.realIndex + 1); 1223 if (swiperCustomCount) { 1224 if (isNoviBuilder ? false : s.attr('data-loop') !== "false") { 1225 swiperCustomCount.innerHTML = formatIndex(swiper.slides.length - 2); 1226 } else { 1227 swiperCustomCount.innerHTML = formatIndex(swiper.slides.length); 1228 } 1229 } 1230 } 1231 } 1232 }(s)), 1233 onSlideChangeStart: (function (s) { 1234 return function (swiper) { 1235 var swiperCustomIndex = $(s).find('.swiper-pagination__fraction-index').get(0); 1236 1237 if (swiperCustomIndex) { 1238 swiperCustomIndex.innerHTML = formatIndex(swiper.realIndex + 1); 1239 } 1240 } 1241 }(s)) 1242 }); 1243 1244 $window.on("resize", (function (s) { 1245 return function () { 1246 var mh = getSwiperHeight(s, "min-height"), 1247 h = getSwiperHeight(s, "height"); 1248 if (h) { 1249 s.css("height", mh ? mh > h ? mh : h : h); 1250 } 1251 } 1252 })(s)).trigger("resize"); 1253 } 1254 } 1255 1256 function formatIndex(index) { 1257 return index < 10 ? '0' + index : index; 1258 } 1259 1260 1261 // Owl carousel 1262 if (plugins.owl.length) { 1263 for (var i = 0; i < plugins.owl.length; i++) { 1264 var c = $(plugins.owl[i]); 1265 plugins.owl[i].owl = c; 1266 1267 initOwlCarousel(c); 1268 } 1269 } 1270 1271 // Isotope 1272 if (plugins.isotope.length) { 1273 var isogroup = []; 1274 for (var i = 0; i < plugins.isotope.length; i++) { 1275 var isotopeItem = plugins.isotope[i], 1276 isotopeInitAttrs = { 1277 itemSelector: '.isotope-item', 1278 layoutMode: isotopeItem.getAttribute('data-isotope-layout') ? isotopeItem.getAttribute('data-isotope-layout') : 'masonry', 1279 filter: '*' 1280 }; 1281 1282 if (isotopeItem.getAttribute('data-column-width')) { 1283 isotopeInitAttrs.masonry = { 1284 columnWidth: parseFloat(isotopeItem.getAttribute('data-column-width')) 1285 }; 1286 } else if (isotopeItem.getAttribute('data-column-class')) { 1287 isotopeInitAttrs.masonry = { 1288 columnWidth: isotopeItem.getAttribute('data-column-class') 1289 }; 1290 } 1291 1292 var iso = new Isotope(isotopeItem, isotopeInitAttrs); 1293 isogroup.push(iso); 1294 } 1295 1296 1297 setTimeout(function () { 1298 for (var i = 0; i < isogroup.length; i++) { 1299 isogroup[i].element.className += " isotope--loaded"; 1300 isogroup[i].layout(); 1301 } 1302 }, 200); 1303 1304 var resizeTimout; 1305 1306 $("[data-isotope-filter]").on("click", function (e) { 1307 e.preventDefault(); 1308 var filter = $(this); 1309 clearTimeout(resizeTimout); 1310 filter.parents(".isotope-filters").find('.active').removeClass("active"); 1311 filter.addClass("active"); 1312 var iso = $('.isotope[data-isotope-group="' + this.getAttribute("data-isotope-group") + '"]'), 1313 isotopeAttrs = { 1314 itemSelector: '.isotope-item', 1315 layoutMode: iso.attr('data-isotope-layout') ? iso.attr('data-isotope-layout') : 'masonry', 1316 filter: this.getAttribute("data-isotope-filter") === '*' ? '*' : '[data-filter*="' + this.getAttribute("data-isotope-filter") + '"]' 1317 }; 1318 if (iso.attr('data-column-width')) { 1319 isotopeAttrs.masonry = { 1320 columnWidth: parseFloat(iso.attr('data-column-width')) 1321 }; 1322 } else if (iso.attr('data-column-class')) { 1323 isotopeAttrs.masonry = { 1324 columnWidth: iso.attr('data-column-class') 1325 }; 1326 } 1327 iso.isotope(isotopeAttrs); 1328 }).eq(0).trigger("click") 1329 } 1330 1331 // WOW 1332 if ($html.hasClass("wow-animation") && plugins.wow.length && !isNoviBuilder && isDesktop) { 1333 new WOW().init(); 1334 } 1335 1336 1337 // RD Input Label 1338 if (plugins.rdInputLabel.length) { 1339 plugins.rdInputLabel.RDInputLabel(); 1340 } 1341 1342 // Regula 1343 if (plugins.regula.length) { 1344 attachFormValidator(plugins.regula); 1345 } 1346 1347 1348 // Bootstrap tabs 1349 if (plugins.bootstrapTabs.length) { 1350 for (var i = 0; i < plugins.bootstrapTabs.length; i++) { 1351 var bootstrapTabsItem = $(plugins.bootstrapTabs[i]); 1352 1353 //If have slick carousel inside tab - resize slick carousel on click 1354 if (bootstrapTabsItem.find('.slick-slider').length) { 1355 bootstrapTabsItem.find('.tabs-custom-list > li > a').on('click', $.proxy(function () { 1356 var $this = $(this); 1357 var setTimeOutTime = isNoviBuilder ? 1500 : 300; 1358 1359 setTimeout(function () { 1360 $this.find('.tab-content .tab-pane.active .slick-slider').slick('setPosition'); 1361 }, setTimeOutTime); 1362 }, bootstrapTabsItem)); 1363 } 1364 } 1365 } 1366 1367 // MailChimp Ajax subscription 1368 if (plugins.mailchimp.length) { 1369 for (i = 0; i < plugins.mailchimp.length; i++) { 1370 var $mailchimpItem = $(plugins.mailchimp[i]), 1371 $email = $mailchimpItem.find('input[type="email"]'); 1372 1373 // Required by MailChimp 1374 $mailchimpItem.attr('novalidate', 'true'); 1375 $email.attr('name', 'EMAIL'); 1376 1377 $mailchimpItem.on('submit', $.proxy(function ($email, event) { 1378 event.preventDefault(); 1379 1380 var $this = this; 1381 1382 var data = {}, 1383 url = $this.attr('action').replace('/post?', '/post-json?').concat('&c=?'), 1384 dataArray = $this.serializeArray(), 1385 $output = $("#" + $this.attr("data-form-output")); 1386 1387 for (i = 0; i < dataArray.length; i++) { 1388 data[dataArray[i].name] = dataArray[i].value; 1389 } 1390 1391 $.ajax({
1392 data: data, 1393 url: url, 1394 dataType: 'jsonp', 1395 error: function (resp, text) { 1396 $output.html('Server error: ' + text); 1397 1398 setTimeout(function () { 1399 $output.removeClass("active"); 1400 }, 4000); 1401 }, 1402 success: function (resp) { 1403 $output.html(resp.msg).addClass('active'); 1404 $email[0].value = ''; 1405 var $label = $('[for="' + $email.attr('id') + '"]'); 1406 if ($label.length) $label.removeClass('focus not-empty'); 1407 1408 setTimeout(function () { 1409 $output.removeClass("active"); 1410 }, 6000); 1411 }, 1412 beforeSend: function (data) { 1413 var isNoviBuilder = window.xMode; 1414 1415 var isValidated = (function () { 1416 var results, errors = 0; 1417 var elements = $this.find('[data-constraints]'); 1418 var captcha = null; 1419 if (elements.length) { 1420 for (var j = 0; j < elements.length; j++) { 1421 1422 var $input = $(elements[j]); 1423 if ((results = $input.regula('validate')).length) { 1424 for (var k = 0; k < results.length; k++) { 1425 errors++; 1426 $input.siblings(".form-validation").text(results[k].message).parent().addClass("has-error"); 1427 } 1428 } else { 1429 $input.siblings(".form-validation").text("").parent().removeClass("has-error") 1430 } 1431 } 1432 1433 if (captcha) { 1434 if (captcha.length) { 1435 return validateReCaptcha(captcha) && errors === 0 1436 } 1437 } 1438 1439 return errors === 0; 1440 } 1441 return true; 1442 })(); 1443 1444 // Stop request if builder or inputs are invalide 1445 if (isNoviBuilder || !isValidated) 1446 return false; 1447 1448 $output.html('Submitting...').addClass('active'); 1449 } 1450 }); 1451 1452 return false; 1453 }, $mailchimpItem, $email)); 1454 } 1455 } 1456 1457 // Campaign Monitor ajax subscription 1458 if (plugins.campaignMonitor.length) { 1459 for (i = 0; i < plugins.campaignMonitor.length; i++) { 1460 var $campaignItem = $(plugins.campaignMonitor[i]); 1461 1462 $campaignItem.on('submit', $.proxy(function (e) { 1463 var data = {}, 1464 url = this.attr('action'), 1465 dataArray = this.serializeArray(), 1466 $output = $("#" + plugins.campaignMonitor.attr("data-form-output")), 1467 $this = $(this); 1468 1469 for (i = 0; i < dataArray.length; i++) { 1470 data[dataArray[i].name] = dataArray[i].value; 1471 } 1472 1473 $.ajax({
1474 data: data, 1475 url: url, 1476 dataType: 'jsonp', 1477 error: function (resp, text) { 1478 $output.html('Server error: ' + text); 1479 1480 setTimeout(function () { 1481 $output.removeClass("active"); 1482 }, 4000); 1483 }, 1484 success: function (resp) { 1485 $output.html(resp.Message).addClass('active'); 1486 1487 setTimeout(function () { 1488 $output.removeClass("active"); 1489 }, 6000); 1490 }, 1491 beforeSend: function (data) { 1492 // Stop request if builder or inputs are invalide 1493 if (isNoviBuilder || !isValidated($this.find('[data-constraints]'))) 1494 return false; 1495 1496 $output.html('Submitting...').addClass('active'); 1497 } 1498 }); 1499 1500 // Clear inputs after submit 1501 var inputs = $this[0].getElementsByTagName('input'); 1502 for (var i = 0; i < inputs.length; i++) { 1503 inputs[i].value = ''; 1504 var label = document.querySelector('[for="' + inputs[i].getAttribute('id') + '"]'); 1505 if (label) label.classList.remove('focus', 'not-empty'); 1506 } 1507 1508 return false; 1509 }, $campaignItem)); 1510 } 1511 } 1512 1513 // RD Mailform 1514 if (plugins.rdMailForm.length) { 1515 var i, j, k, 1516 msg = { 1517 'MF000': 'Successfully sent!', 1518 'MF001': 'Recipients are not set!', 1519 'MF002': 'Form will not work locally!', 1520 'MF003': 'Please, define email field in your form!', 1521 'MF004': 'Please, define type of your form!', 1522 'MF254': 'Something went wrong with PHPMailer!', 1523 'MF255': 'Aw, snap! Something went wrong.' 1524 }; 1525 1526 for (i = 0; i < plugins.rdMailForm.length; i++) { 1527 var $form = $(plugins.rdMailForm[i]), 1528 formHasCaptcha = false; 1529 1530 $form.attr('novalidate', 'novalidate').ajaxForm({ 1531 data: { 1532 "form-type": $form.attr("data-form-type") || "contact", 1533 "counter": i 1534 }, 1535 beforeSubmit: function (arr, $form, options) { 1536 if (isNoviBuilder) 1537 return; 1538 1539 var form = $(plugins.rdMailForm[this.extraData.counter]), 1540 inputs = form.find("[data-constraints]"), 1541 output = $("#" + form.attr("data-form-output")), 1542 captcha = form.find('.recaptcha'), 1543 captchaFlag = true; 1544 1545 output.removeClass("active error success"); 1546 1547 if (isValidated(inputs, captcha)) { 1548 1549 // veify reCaptcha 1550 if (captcha.length) { 1551 var captchaToken = captcha.find('.g-recaptcha-response').val(), 1552 captchaMsg = { 1553 'CPT001': 'Please, setup you "site key" and "secret key" of reCaptcha', 1554 'CPT002': 'Something wrong with google reCaptcha' 1555 }; 1556 1557 formHasCaptcha = true; 1558 1559 $.ajax({
1560 method: "POST", 1561 url: "bat/reCaptcha.php", 1562 data: { 'g-recaptcha-response': captchaToken }, 1563 async: false 1564 }) 1565 .done(function (responceCode) { 1566 if (responceCode !== 'CPT000') { 1567 if (output.hasClass("snackbars")) { 1568 output.html('<p><span class="icon text-middle mdi mdi-check icon-xxs"></span><span>' + captchaMsg[responceCode] + '</span></p>') 1569 1570 setTimeout(function () { 1571 output.removeClass("active"); 1572 }, 3500); 1573 1574 captchaFlag = false; 1575 } else { 1576 output.html(captchaMsg[responceCode]); 1577 } 1578 1579 output.addClass("active"); 1580 } 1581 }); 1582 } 1583 1584 if (!captchaFlag) { 1585 return false; 1586 } 1587 1588 form.addClass('form-in-process'); 1589 1590 if (output.hasClass("snackbars")) { 1591 output.html('<p><span class="icon text-middle fa fa-circle-o-notch fa-spin icon-xxs"></span><span>Sending</span></p>'); 1592 output.addClass("active"); 1593 } 1594 } else { 1595 return false; 1596 } 1597 }, 1598 error: function (result) { 1599 if (isNoviBuilder) 1600 return; 1601 1602 var output = $("#" + $(plugins.rdMailForm[this.extraData.counter]).attr("data-form-output")), 1603 form = $(plugins.rdMailForm[this.extraData.counter]); 1604 1605 output.text(msg[result]); 1606 form.removeClass('form-in-process'); 1607 1608 if (formHasCaptcha) { 1609 grecaptcha.reset(); 1610 } 1611 }, 1612 success: function (result) { 1613 if (isNoviBuilder) 1614 return; 1615 1616 var form = $(plugins.rdMailForm[this.extraData.counter]), 1617 output = $("#" + form.attr("data-form-output")), 1618 select = form.find('select'); 1619 1620 form 1621 .addClass('success') 1622 .removeClass('form-in-process'); 1623 1624 if (formHasCaptcha) { 1625 grecaptcha.reset(); 1626 } 1627 1628 result = result.length === 5 ? result : 'MF255'; 1629 output.text(msg[result]); 1630 1631 if (result === "MF000") { 1632 if (output.hasClass("snackbars")) { 1633 output.html('<p><span class="icon text-middle mdi mdi-check icon-xxs"></span><span>' + msg[result] + '</span></p>'); 1634 } else { 1635 output.addClass("active success"); 1636 } 1637 } else { 1638 if (output.hasClass("snackbars")) { 1639 output.html(' <p class="snackbars-left"><span class="icon icon-xxs mdi mdi-alert-outline text-middle"></span><span>' + msg[result] + '</span></p>'); 1640 } else { 1641 output.addClass("active error"); 1642 } 1643 } 1644 1645 form.clearForm(); 1646 1647 if (select.length) { 1648 select.select2("val", ""); 1649 } 1650 1651 form.find('input, textarea').trigger('blur'); 1652 1653 setTimeout(function () { 1654 output.removeClass("active error success"); 1655 form.removeClass('success'); 1656 }, 3500); 1657 } 1658 }); 1659 } 1660 } 1661 1662 /** 1663 * Select2 1664 * @description Enables select2 plugin 1665 */ 1666 if (plugins.selectFilter.length) { 1667 var i; 1668 for (i = 0; i < plugins.selectFilter.length; i++) { 1669 var select = $(plugins.selectFilter[i]); 1670 1671 select.select2({ 1672 placeholder: select.attr("data-placeholder") ? select.attr("data-placeholder") : false, 1673 minimumResultsForSearch: select.attr("data-minimum-results-search") ? select.attr("data-minimum-results-search") : -1, 1674 maximumSelectionSize: 3, 1675 dropdownCssClass: select.attr("data-dropdown-class") ? select.attr("data-dropdown-class") : '' 1676 }); 1677 } 1678 } 1679 1680 1681 // Custom Toggles 1682 if (plugins.customToggle.length) { 1683 for (var i = 0; i < plugins.customToggle.length; i++) { 1684 var $this = $(plugins.customToggle[i]); 1685 1686 $this.on('click', $.proxy(function (event) { 1687 event.preventDefault(); 1688 1689 var $ctx = $(this); 1690 $($ctx.attr('data-custom-toggle')).add(this).toggleClass('active'); 1691 }, $this)); 1692
1693 if ($this.attr("data-custom-toggle-hide-on-blur") === "true") { 1694 $body.on("click", $this, function (e) { 1695 if (e.target !== e.data[0] 1696 && $(e.data.attr('data-custom-toggle')).find($(e.target)).length 1697 && e.data.find($(e.target)).length === 0) { 1698 $(e.data.attr('data-custom-toggle')).add(e.data[0]).removeClass('active'); 1699 } 1700 }) 1701 } 1702 1703 if ($this.attr("data-custom-toggle-disable-on-blur") === "true") { 1704 $body.on("click", $this, function (e) { 1705 if (e.target !== e.data[0] && $(e.data.attr('data-custom-toggle')).find($(e.target)).length === 0 && e.data.find($(e.target)).length === 0) { 1706 $(e.data.attr('data-custom-toggle')).add(e.data[0]).removeClass('active'); 1707 } 1708 }) 1709 } 1710 } 1711 } 1712 1713 1714 // Google maps 1715 if (plugins.maps.length) { 1716 lazyInit(plugins.maps, initMaps); 1717 } 1718 1719 // Material Parallax 1720 if (plugins.materialParallax.length) { 1721 if (!isNoviBuilder && !isIE && !isMobile) { 1722 plugins.materialParallax.parallax(); 1723 1724 // heavy pages fix 1725 $window.on('load', function () { 1726 setTimeout(function () { 1727 $window.scroll(); 1728 }, 500); 1729 }); 1730 } else { 1731 for (var i = 0; i < plugins.materialParallax.length; i++) { 1732 var parallax = $(plugins.materialParallax[i]), 1733 imgPath = parallax.data("parallax-img"); 1734 1735 parallax.css({ 1736 "background-image": 'url(' + imgPath + ')', 1737 "background-size": "cover" 1738 }); 1739 } 1740 } 1741 } 1742 1743 // Countdown 1744 if (plugins.countdown.length) { 1745 for (var i = 0; i < plugins.countdown.length; i++) { 1746 var 1747 node = plugins.countdown[i], 1748 countdown = aCountdown({ 1749 node: node, 1750 from: node.getAttribute('data-from'), 1751 to: node.getAttribute('data-to'), 1752 count: node.getAttribute('data-count'), 1753 tick: 100, 1754 }); 1755 } 1756 } 1757 1758 }); 1759 1760}()); 1761 1762function MM_openBrWindow(theURL, winName, features) { //v2.0 1763 window.open(theURL, winName, features); 1764 return false; 1765}
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.