1(function ($, window, undefined) { 2 3 /* --- DETECT VIEWPORT SIZE --- */ 4 5 function browserSize() { 6 wh = $(window).height(); 7 ww = $(window).width(); 8 dh = $(document).height(); 9 ar = ww / wh; 10 } 11 12 13 /* --- DETECT PLATFORM --- */ 14 15 function platformDetect() { 16 $.support.touch = 'ontouchend' in document; 17 var navUA = navigator.userAgent.toLowerCase(), 18 navPlat = navigator.platform.toLowerCase(); 19 20 var isiPhone = navPlat.indexOf("iphone"), 21 isiPod = navPlat.indexOf("ipod"), 22 isAndroidPhone = navPlat.indexOf("android"), 23 safari = (navUA.indexOf('safari') != -1 && navUA.indexOf('chrome') == -1) ? true : false, 24 svgSupport = (window.SVGAngle) ? true : false, 25 svgSupportAlt = (document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1")) ? true : false, 26 ff3x = (/gecko/i.test(navUA) && /rv:1.9/i.test(navUA)) ? true : false; 27 28 ieMobile = navigator.userAgent.match(/Windows Phone/i) ? true : false; 29 phone = (isiPhone > -1 || isiPod > -1 || isAndroidPhone > -1) ? true : false; 30 touch = $.support.touch ? true : false; 31 ltie9 = $.support.leadingWhitespace ? false : true; 32 33 var $bod = $('body'); 34 35 if (touch) $('html').addClass('touch'); 36 if (ieMobile) $('html').addClass('is--winmob'); 37 if (is_android) $('html').addClass('is--ancient-android'); 38 if (safari) $bod.addClass('safari'); 39 if (phone) $bod.addClass('phone'); 40 } 41// /* ====== SHARED VARS ====== */ 42 43var phone, touch, ltie9, dh, ar, fonts, ieMobile; 44 45var ua = navigator.userAgent; 46var winLoc = window.location.toString(); 47 48var is_webkit = ua.match(/webkit/i); 49var is_firefox = ua.match(/gecko/i); 50var is_newer_ie = ua.match(/msie (9|([1-9][0-9]))/i); 51var is_older_ie = ua.match(/msie/i) && !is_newer_ie; 52var is_ancient_ie = ua.match(/msie 6/i); 53var is_ie = is_ancient_ie || is_older_ie || is_newer_ie; 54var is_mobile_ie = navigator.userAgent.indexOf('IEMobile') !== -1; 55var is_mobile = ua.match(/mobile/i) ? true : false; 56var is_OSX = ua.match(/(iPad|iPhone|iPod|Macintosh)/g) ? true : false; 57var iOS = getIOSVersion(ua); 58var is_EDGE = /Edge\/12./i.test(navigator.userAgent); 59 60var latestKnownScrollY = -1, 61 newScrollY = (window.pageYOffset || document.documentElement.scrollTop) - (document.documentElement.clientTop || 0), 62 ticking = false; 63 64if (is_EDGE) { 65 jQuery('body').addClass('is-edge'); 66} 67 68 69var nua = navigator.userAgent; 70var is_android = ((nua.indexOf('Mozilla/5.0') !== -1 && nua.indexOf('Android ') !== -1 && nua.indexOf('AppleWebKit') !== -1) && nua.indexOf('Chrome') === -1); 71var isAndroid = ua.indexOf("android") > -1; //&& ua.indexOf("mobile"); 72 73var useTransform = true; 74var use2DTransform = (ua.match(/msie 9/i) || winLoc.match(/transform\=2d/i)); 75var transform; 76 77// setting up transform prefixes 78var prefixes = { 79 webkit: 'webkitTransform', 80 firefox: 'MozTransform', 81 ie: 'msTransform', 82 w3c: 'transform' 83}; 84 85if (useTransform) { 86 if (is_webkit) { 87 transform = prefixes.webkit; 88 } else if (is_firefox) { 89 transform = prefixes.firefox; 90 } else if (is_newer_ie) { 91 transform = prefixes.ie; 92 } 93} 94 95var windowWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth, 96 windowHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight; 97 98/* --- To enable verbose debug add to Theme Options > Custom Code footer -> globalDebug=true; --- */ 99var globalDebug = false, 100 timestamp; 101 102/* --- 404 Page --- */ 103if ( typeof window.gifImages !== "undefined" && ! window.gifImages instanceof Array && window.gifImages.length !== 0 ) { 104 105 window.gifImages = [ 106 "ShiZM6m.gif", 107 "http://i.imgur.com/8ZYNp.gif", 108 "Xb4fq.gif", 109 "UYPLKwN.gif", 110 "d9e792a91d5391b8a7aa22689d4e2555/tumblr_inline_mwq1hmelce1qmoozl.gif", 111 "http://www.teen.com/wp-content/uploads/2013/10/world-without-jennifer-lawrence-gifs-food-uproxx-2.gif" 112 ]; 113 114} 115 116function getGif() { 117 return gifImages[Math.floor( Math.random() * gifImages.length )]; 118} 119 120function changeBackground() { 121 $( '.error404' ).css( 'background-image', 'url(' + getGif() + ')' ); 122} 123 124$( window ).on( 'load', function() { 125 if ( $( '.error404' ).length ) {
126 changeBackground(); 127 } 128} ); 129 130$( window ).keydown( function( e ) { 131 if ( e.keyCode === 32 ) { 132 changeBackground(); 133 } 134} ); 135 136/* --- Cover Animations Init --- */ 137 138var CoverAnimation = { 139 selector: '.article__header', 140 initialized: false, 141 animated: false, 142 143 initialize: function () { 144 145 if (is_EDGE) { 146 return; 147 } 148 149 var that = this; 150 151 $(this.selector).each(function(i, header) { 152 153 var $header = $(header), 154 $headline = $header.find('.article__headline'), 155 timeline = new TimelineMax({ paused: true }), 156 $title = $headline.find('.headline__primary'), 157 $subtitle = $headline.find('.headline__secondary'), 158 $description = $headline.find('.headline__description'), 159 $star = $headline.find('.star'), 160 $lines = $headline.find('.line'), 161 $arrows = $description.find('.arrow'), 162 $hr = $description.find('hr'), 163 headerTop = $header.offset().top, 164 headerHeight = $header.outerHeight(); 165 166 $header.find('.pixcode--separator').width($title.width()); 167 168 $description.css({opacity: 1}); 169 $description = $description.children().not('.pixcode--separator'); 170 $description.css({opacity: 0}); 171 172 // ------ A 173 174 if ( $title.length && $title.text().trim().length ) { 175 timeline.fromTo($title, 0.72, {'letter-spacing': '1em', 'margin-right': '-0.9em'}, {'letter-spacing': '0.2em', 'margin-right': '-0.1em', ease: Expo.easeOut}); 176 timeline.fromTo($title, 0.89, {opacity: 0}, {opacity: 1, ease: Expo.easeOut}, '-=0.72'); 177 timeline.fromTo($title, 1, {'y': 30}, {'y': 0, ease: Expo.easeOut}, '-=0.89'); 178 } 179 180 if ( $subtitle.length ) { 181 timeline.fromTo($subtitle, 0.65, {opacity: 0}, {opacity: 1, ease: Quint.easeOut}, '-=0.65'); 182 timeline.fromTo($subtitle, 0.9, {y: 30}, {y: 0, ease: Quint.easeOut}, '-=0.65'); 183 } 184 185 if ( $star.length ) { 186 timeline.fromTo($star, 0.15, {opacity: 0}, {opacity: 1, ease: Quint.easeOut}, '-=0.6'); 187 timeline.fromTo($star, 0.55, {rotation: -270}, {rotation: 0, ease: Back.easeOut}, '-=0.5'); 188 } 189 190 if ( $lines.length ) { 191 timeline.fromTo($lines, 0.6, {width: 0}, {width: '42%', opacity: 1, ease: Quint.easeOut}, '-=0.55'); 192 timeline.fromTo($hr, 0.6, {width: 0}, {width: '100%', opacity: 1, ease: Quint.easeOut}, '-=0.6'); 193 } 194 195 if ( $arrows.length ) { 196 timeline.fromTo($arrows, 0.2, {opacity: 0}, {opacity: 1, ease: Quint.easeOut}, '-=0.27'); 197 } 198 199 if ( $description.length ) { 200 timeline.fromTo($description, 0.5, {opacity: 0}, {opacity: 1, ease: Quint.easeOut}, '-=0.28'); 201 timeline.fromTo($description, 0.75, {y: -20}, {y: 0}, '-=0.5'); 202 } 203 204 // ------ B 205 timeline.addLabel("animatedIn"); 206 207 // if (i == 0) { 208 // timeline.fromTo($headline, 1.08, {y: 0}, {y: 150, ease: Linear.easeNone}); 209 // timeline.fromTo($title, 1.08, {y: 0}, {opacity: 0, y: -60, ease: Quad.easeIn}, '-=1.08'); 210 // } else { 211 timeline.fromTo($title, 1.08, {y: 0}, {opacity: 0, y: -60, ease: Quad.easeIn}); 212 // } 213 214 timeline.to($description, 1.08, {y: 60, opacity: 0, ease: Quad.easeIn}, '-=1.08'); 215 timeline.to($subtitle, 1.08, {opacity: 0, y: -90, ease: Quad.easeIn}, '-=1.08'); 216 timeline.to($lines, 0.86, {width: 0, opacity: 0, ease: Quad.easeIn}, '-=0.94'); 217 timeline.to($hr, 0.86, {width: 0, opacity: 0, ease: Quad.easeIn}, '-=0.86'); 218 timeline.to($star, 1, {rotation: 180}, '-=1.08'); 219 timeline.to($star, 0.11, {opacity: 0}, '-=0.03'); 220 timeline.to($arrows, 0.14, {opacity: 0}
220, '-=1.08'); 221 222 timeline.addLabel("animatedOut"); 223 224 // ------ C 225 226 var animatedInTime = timeline.getLabelTime("animatedIn"), 227 animatedOutTime = timeline.getLabelTime("animatedOut"), 228 start = headerTop + headerHeight / 2 - windowHeight / 2, 229 end = start + headerHeight / 2, 230 ab, bc; 231 232 if (i === 0) { 233 start = headerTop; 234 end = start + windowHeight / 2; 235 } 236 237 ab = animatedInTime / animatedOutTime; 238 bc = 1 - ab; 239 240 if (!that.initialized) { 241 242 timeline.tweenTo("animatedIn", { 243 onComplete: function () { 244 if (Modernizr.touchevents) { 245 $headline.data("animated", true); 246 } 247 } 248 }); 249 250 if (!Modernizr.touchevents) { 251 timeline.tweenTo("animatedOut", { 252 onComplete: function () { 253 $headline.data("animated", true); 254 }, 255 onUpdate: function () { 256 var progress = (1 / (end - start)) * (latestKnownScrollY - start), 257 partialProgress = progress < 0 ? ab : ab + bc * progress, 258 currentProgress = timeline.progress(); 259 260 if (Math.abs(partialProgress - currentProgress) < 0.01) { 261 $headline.data("animated", true); 262 this.kill(); 263 } 264 } 265 }); 266 } 267 } 268 269 $headline.data('tween', { 270 timeline: timeline, 271 ab: ab, 272 bc: bc, 273 start: start, 274 end: end 275 }); 276 277 }); 278 279 that.initialized = true; 280 that.update(); 281 }, 282 283 update: function () { 284 285 if (is_EDGE) { 286 return; 287 } 288 289 var that = this; 290 291 $(this.selector).each(function (i, element) { 292 293 var $headline = $(element).find('.article__headline'), 294 options = $headline.data('tween'), 295 progress = 0; 296 297 // some sanity check 298 // we wouldn't want to divide by 0 - the Universe might come to an end 299 if (! empty(options) && (options.end - options.start) !== 0) { 300 301 // progress on the total timeline (ac) 302 progress = (1 / (options.end - options.start)) * (latestKnownScrollY - options.start); 303 304 // progress on partial timeline (bc) 305 // point B being labeled as "animated" 306 var partialProgress = options.ab + options.bc * progress; 307 308 $headline.data('progress', partialProgress); 309 310 if (!$headline.data("animated")) { 311 return; 312 } 313 314 if (0 > progress) { 315 partialProgress = options.ab; 316 } 317 318 if (1 > partialProgress) { 319 options.timeline.progress(partialProgress); 320 return; 321 } 322 323 options.timeline.progress(1); 324 } 325 }); 326 } 327} 328var DownArrow = { 329 selector: '.down-arrow', 330 $arrow: null, 331 timeline: null, 332 start: 0, 333 end: 0, 334 bubble: false, 335 336 initialize: function () { 337 338 var that = this; 339 340 this.$arrow = $(this.selector); 341 342 if (empty(this.$arrow)) { 343 return; 344 } 345 346 this.start = 0; 347 this.end = this.start + 300; 348 this.timeline = new TimelineMax({ paused: true }); 349 this.$next = this.$arrow.closest('.article--page'); 350 351 if (!empty(this.$next)) { 352 this.nextTop = this.$next.offset().top; 353 this.nextHeight = this.$next.outerHeight(); 354 } 355 356 357 if (this.$arrow.hasClass('down-arrow--bubble')) { 358 this.timeline.to(this.$arrow, .2, {y: 10, opacity: 0, ease: Linear.easeNone, overwrite: "none"}); 359 this.timeline.to('.blurp--top', .3, {scaleY: 0, ease: Linear.easeNone, overwrite: "none"}); 360 this.bubble = true; 361 } else { 362 this.timeline.to(this.$arrow, 1, {y: 100, opacity: 0, ease: Linear.easeNone, overwrite: "none"}); 363 } 364 365 this.$arrow.on('click', function (e) { 366 e.preventDefault(); 367 368 if (empty(that.$next)) { 369 return; 370 } 371 372 if (that.$next.is('.article__header')) { 373 smoothScrollTo(that.nextTop - windowHeight/2 + that.nextHeight/2); 374 } else { 375 smoothScrollTo(that.nextTop - $('.site-header').height()); 376 } 377 378 }); 379 }, 380 381 update: function () { 382 383 if (empty(this.$arrow) || this.bubble) { 384 return; 385 } 386 387 if (Modernizr.touchevents && is_OSX) { 388 this.timeline.progress(0); 389 return; 390 } 391 392 setProgress(this.timeline, this.start, this.end); 393 } 394} 395// /* ====== HELPER FUNCTIONS ====== */ 396 397//similar to PHP's empty function 398function empty(data) { 399 if (typeof(data) == 'number' || typeof(data) == 'boolean') { 400 return false;
401 } 402 if (typeof(data) == 'undefined' || data === null) { 403 return true; 404 } 405 if (typeof(data.length) != 'undefined') { 406 return data.length === 0; 407 } 408 var count = 0; 409 for (var i in data) { 410 // if(data.hasOwnProperty(i)) 411 // 412 // This doesn't work in ie8/ie9 due the fact that hasOwnProperty works only on native objects. 413 // http://stackoverflow.com/questions/8157700/object-has-no-hasownproperty-method-i-e-its-undefined-ie8 414 // 415 // for hosts objects we do this 416 if (Object.prototype.hasOwnProperty.call(data, i)) { 417 count++; 418 } 419 } 420 return count === 0; 421} 422 423function extend(a, b) { 424 for (var key in b) { 425 if (b.hasOwnProperty(key)) { 426 a[key] = b[key]; 427 } 428 } 429 return a; 430} 431 432// taken from https://github.com/inuyaksa/jquery.nicescroll/blob/master/jquery.nicescroll.js 433function hasParent(e, id) { 434 if (!e) return false; 435 var el = e.target || e.srcElement || e || false; 436 while (el && el.id != id) { 437 el = el.parentNode || false; 438 } 439 return (el !== false); 440} 441 442function mobilecheck() { 443 var check = false; 444 (function (a) { 445 if (/(android|ipad|playbook|silk|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4)))check = true; 446 })(navigator.userAgent || navigator.vendor || window.opera); 447 return check; 448} 449 450/* --- Set Query Parameter--- */ 451function setQueryParameter(uri, key, value) { 452 var re = new RegExp("([?|&])" + key + "=.*?(&|$)", "i"); 453 separator = uri.indexOf('?') !== -1 ? "&" : "?"; 454 if (uri.match(re)) { 455 return uri.replace(re, '$1' + key + "=" + value + '$2'); 456 } 457 else { 458 return uri + separator + key + "=" + value; 459 } 460} 461 462// http://stackoverflow.com/a/7557433 463function isElementInViewport (el) { 464 465 //special bonus for those using jQuery 466 if (el instanceof jQuery) { 467 el = el[0]; 468 } 469 470 var rect = el.getBoundingClientRect(); 471 472 return ( 473 rect.top >= 0 && 474 rect.left >= 0 && 475 rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /*or $(window).height() */ 476 rect.right <= (window.innerWidth || document.documentElement.clientWidth) /*or $(window).width() */ 477 ); 478} 479 480function getIOSVersion(ua) { 481 ua = ua || navigator.userAgent; 482 return parseFloat( 483 ('' + (/CPU.*OS ([0-9_]{1,5})|(CPU like).*AppleWebKit.*Mobile/i.exec(ua) || [0,''])[1]) 484 .replace('undefined', '3_2').replace('_', '.').replace('_', '') 485 ) || false; 486} 487 488function setProgress(timeline, start, end) { 489 490 var progress = (latestKnownScrollY - start) / (end - start); 491 492 if (0 > progress) { 493 timeline.progress(0); 494 return; 495 } 496 497 if (1 < progress) { 498 timeline.progress(1); 499 return; 500 } 501 502 timeline.progress(progress); 503} 504 505/** 506 * Generic tree implementation 507 * 508 * This class represents any node in the tree. 509 */ 510var Node = function( val ) { 511 512 this.val = val; 513 this.children = []; 514 this.parent = null; 515 516 /** 517 * Sets the parent node of this node. 518 */ 519 this.setParentNode = function( node ) { 520 this.parent = node; 521 node.children[node.children.length] = this; 522 } 523 524 /** 525 * Gets the parent node of this node. 526 */ 527 this.getParentNode = function() { 528 return this.parent; 529 } 530 531 /** 532 * Adds a child node of this node. 533 */ 534 this.addChild = function( node ) { 535 node.parent = this; 536 this.children[this.children.length] = node; 537 } 538 539 /** 540 * Gets the array of child nodes of this node. 541 */ 542 this.getChildren = function() { 543 return this.children; 544 } 545 546 /** 547 * Removes all the children of this node. 548 */ 549 this.removeChildren = function() { 550 var child; 551 for ( var i = 0; i < this.children.length; i++ ) { 552 child = this.children[i]; 553 child.parent = null; 554 } 555 this.children = []; 556 } 557 558 /** 559 * Recursively counts the number of all descendants, from children down, and 560 * returns the total number. 561 */ 562 this.getTotalDescendantCount = function() { 563 var count = 0, 564 child; 565 for ( var i = 0; i < this.children.length; i++ ) { 566 child = this.children[i]; 567 count += child.getTotalDescendantCount(); 568 } 569 return count + this.children.length; 570 } 571} 572 573/** 574 * Protocol Buffer implementation, which extends the functionality of Node 575 * while specifically typing the stored value 576 */
577var PrBufNode = function( id, type, value ) { 578 this.val = { 579 id: id, 580 type: type, 581 value: value 582 }; 583 this.children = []; 584 this.parent = null; 585} 586 587PrBufNode.prototype = new Node(); 588PrBufNode.prototype.constructor = PrBufNode; 589 590PrBufNode.prototype.id = function() { 591 return this.val.id; 592} 593PrBufNode.prototype.type = function() { 594 return this.val.type; 595} 596PrBufNode.prototype.value = function() { 597 return this.val.value; 598} 599 600/** 601 * Compares the number of descendants with the value specified in the map element. 602 * If all the children have not yet been added, we continue adding to this element. 603 */ 604PrBufNode.prototype.findLatestIncompleteNode = function() { 605 606 //if it's a branch (map) node ('m') and has room, 607 //or if it's the root (identified by having a null parent), which has no element limit, 608 //then return this node 609 if ( ( 610 ( 611 this.val.type === 'm' 612 ) && ( 613 this.val.value > this.getTotalDescendantCount() 614 ) 615 ) 616 || ( 617 null === this.parent 618 ) ) { 619 return this; 620 } 621 else { 622 return this.parent.findLatestIncompleteNode(); 623 } 624} 625 626/** 627 * Parses the input URL 'data' protocol buffer parameter into a tree 628 */ 629PrBufNode.create = function( urlToParse ) { 630 var rootNode = null; 631 var re = /data=!([^?&]+)/; 632 var dataArray = urlToParse.match( re ); 633 if ( dataArray && dataArray.length >= 1 ) { 634 rootNode = new PrBufNode(); 635 var workingNode = rootNode; 636 //we iterate through each of the elements, creating a node for it, and 637 //deciding where to place it in the tree 638 var elemArray = dataArray[1].split( "!" ); 639 for ( var i = 0; i < elemArray.length; i ++ ) { 640 var elemRe = /^([0-9]+)([a-z])(.+)$/; 641 var elemValsArray = elemArray[i].match( elemRe ); 642 if ( elemValsArray && elemValsArray.length > 3 ) { 643 var elemNode = new PrBufNode( elemValsArray[1], elemValsArray[2], elemValsArray[3] ); 644 workingNode.addChild( elemNode ); 645 workingNode = elemNode.findLatestIncompleteNode(); 646 } 647 } 648 } 649 return rootNode; 650} 651 652 653/** 654 * Represents a basic waypoint, with latitude and longitude. 655 * 656 * If both are not specified, the waypoint is considered to be valid 657 * but empty waypoint (these can exist in the data parameter, where 658 * the coordinates have been specified in the URL path. 659 */ 660var GmdpWaypoint = function( lat, lng, primary ) { 661 this.lat = lat; 662 this.lng = lng; 663 this.primary = primary ? true : false; 664} 665 666/** 667 * Represents a basic route, comprised of an ordered list of 668 * GmdpWaypoint objects. 669 */ 670var GmdpRoute = function() { 671 this.route = new Array(); 672} 673 674/** 675 * Pushes a GmdpWaypoint on to the end of this GmdpRoute. 676 */ 677GmdpRoute.prototype.pushWaypoint = function( wpt ) { 678 if ( wpt instanceof GmdpWaypoint ) { 679 this.route.push( wpt ); 680 } 681} 682 683/** 684 * Sets the mode of transportation. 685 * If the passed parameter represents one of the integers normally used by Google Maps, 686 * it will be interpreted as the relevant transport mode, and set as a string: 687 * "car", "bike", "foot", "transit", "flight" 688 */ 689GmdpRoute.prototype.setTransportation = function( transportation ) { 690 switch ( transportation ) { 691 case '0': 692 this.transportation = "car"; 693 break; 694 case '1': 695 this.transportation = "bike"; 696 break; 697 case '2': 698 this.transportation = "foot"; 699 break; 700 case '3': 701 this.transportation = "transit"; 702 break; 703 case '4': 704 this.transportation = "flight"; 705 break; 706 default: 707 this.transportation = transportation; 708 break; 709 } 710} 711 712/** 713 * Returns the mode of transportation (if any) for the route. 714 */ 715GmdpRoute.prototype.getTransportation = function() { 716 return this.transportation; 717} 718 719GmdpRoute.prototype.setUnit = function( unit ) { 720 switch ( unit ) { 721 case '0': 722 this.unit = "km"; 723 break; 724 case '1': 725 this.unit = "miles"; 726 break; 727 } 728} 729 730GmdpRoute.prototype.getUnit = function() { 731 return this.unit; 732} 733 734GmdpRoute.prototype.setRoutePref = function( routePref ) { 735 switch ( routePref ) { 736 case '0': 737 case '1': 738 this.routePref = "best route"; 739 break; 740 case '2': 741 this.routePref = "fewer transfers"; 742 break; 743 case '3': 744 this.routePref = "less walking"; 745 break; 746 } 747} 748 749GmdpRoute.prototype.getRoutePref = function() { 750 return this.routePref; 751} 752 753GmdpRoute.prototype.setArrDepTimeType = function( arrDepTimeType ) { 754 switch ( arrDepTimeType ) { 755 case '0': 756 this.arrDepTimeType = "depart at"; 757 break; 758 case '1': 759 this.arrDepTimeType = "arrive by"; 760 break; 761 case '2': 762 this.arrDepTimeType = "last available"; 763 break; 764 } 765} 766 767GmdpRoute.prototype.getArrDepTimeType = function() { 768 return this.arrDepTimeType; 769} 770 771GmdpRoute.prototype.addTransitModePref = function( transitModePref ) { 772 //there can be multiple preferred transit modes, so we store them in an array 773 //we assume there will be no duplicate values, but it probably doesn't matter 774 //even if there are 775 switch ( transitModePref ) { 776 case '0': 777 this.transitModePref.push( "bus" ); 778 break; 779 case '1': 780 this.transitModePref.push( "subway" ); 781 break; 782 case '2': 783 this.transitModePref.push( "train" ); 784 break; 785 case '3': 786 this.transitModePref.push( "tram / light rail" ); 787 break; 788 } 789} 790 791GmdpRoute.prototype.getTransitModePref = function() { 792 return this.transitModePref; 793} 794 795 796/**
797 * Returns the list of all waypoints belonging to this route. 798 */ 799GmdpRoute.prototype.getAllWaypoints = function() { 800 return this.route; 801} 802 803 804function GmdpException( message ) { 805 this.message = message; 806 // Use V8's native method if available, otherwise fallback 807 if ( "captureStackTrace" in Error ) { 808 Error.captureStackTrace( this, GmdpException ); 809 } else { 810 this.stack = ( 811 new Error() 812 ).stack; 813 } 814} 815 816GmdpException.prototype = Object.create( Error.prototype ); 817GmdpException.prototype.name = "GmdpException"; 818 819/** 820 * Represents a google maps data parameter, constructed from the passed URL. 821 * 822 * Utility methods defined below allow the user to easily extract interesting 823 * information from the data parameter. 824 */ 825var Gmdp = function( url ) { 826 this.prBufRoot = PrBufNode.create( url ); 827 this.mapType = "map"; 828 829 if ( this.prBufRoot == null ) { 830 throw new GmdpException( "no parsable data parameter found" ); 831 } 832 833 //the main top node for routes is 4m; other urls (eg. streetview) feature 3m etc. 834 var routeTop = null; 835 var streetviewTop = null; 836 var rootChildren = this.prBufRoot.getChildren(), 837 child; 838 839 for ( var i = 0; i < rootChildren.length; i++ ) { 840 child = rootChildren[i]; 841 if ( child.id() == 3 && child.type() == 'm' ) { 842 var mapTypeChildren = child.getChildren(); 843 if ( mapTypeChildren && mapTypeChildren.length >= 1 ) { 844 if ( mapTypeChildren[0].id() == 1 && mapTypeChildren[0].type() == 'e' ) { 845 switch ( mapTypeChildren[0].value() ) { 846 case '1': 847 this.mapType = "streetview"; 848 streetviewTop = child; 849 break; 850 case '3': 851 this.mapType = "earth"; 852 break; 853 } 854 } 855 } 856 } else if ( child.id() == 4 && child.type() == 'm' ) { 857 routeTop = child; 858 } 859 } 860 if ( routeTop ) { 861 var directions = null, 862 routeChildren = routeTop.getChildren(); 863 864 for ( var i = 0; i < routeChildren.length; i++ ) { 865 child = routeChildren[i]; 866 if ( child.id() == 4 && child.type() == 'm' ) { 867 directions = child; 868 } 869 } 870 if ( directions ) { 871 this.route = new GmdpRoute(); 872 this.route.arrDepTimeType = "leave now"; //default if no value is specified 873 this.route.avoidHighways = false; 874 this.route.avoidTolls = false; 875 this.route.avoidFerries = false; 876 this.route.transitModePref = []; 877 878 var directionsChildren = directions.getChildren(); 879 880 for ( var i = 0; i < directionsChildren.length; i++ ) { 881 child = directionsChildren[i]; 882 if ( primaryChild.id() == 1 && primaryChild.type() == 'm' ) { 883 if ( primaryChild.value() == 0 ) { 884 this.route.pushWaypoint( new GmdpWaypoint( undefined, undefined, true ) ); 885 } 886 else { 887 var addedPrimaryWpt = false; 888 var wptNodes = primaryChild.getChildren(), 889 wptNode; 890 for ( var i = 0; i < wptNodes.length; i++ ) { 891 wptNode = wptNodes[i]; 892 if ( wptNode.id() == 2 ) { 893 //this is the primary wpt, add coords 894 var coordNodes = wptNode.getChildren(); 895 if ( coordNodes && 896 coordNodes.length >= 2 && 897 coordNodes[0].id() == 1 && 898 coordNodes[0].type() == 'd' && 899 coordNodes[1].id() == 2 && 900 coordNodes[1].type() == 'd' ) { 901 this.route.pushWaypoint( 902 new GmdpWaypoint( coordNodes[1].value(), 903 coordNodes[0].value(), 904 true ) ); 905 } 906 addedPrimaryWpt = true; 907 } else if ( wptNode.id() == 3 ) { 908 //this is a secondary (unnamed) wpt 909 // 910 //but first, if we haven't yet added the primary wpt, 911 //then the coordinates are apparently not specified, 912 //so we should add an empty wpt 913 if ( ! addedPrimaryWpt ) { 914 this.route.pushWaypoint( new GmdpWaypoint( undefined, undefined, true ) ); 915 addedPrimaryWpt = true; 916 } 917 918 //now proceed with the secondary wpt itself 919 var secondaryWpts = wptNode.getChildren(); 920 if ( secondaryWpts && secondaryWpts.length > 1 ) { 921 var coordNodes = secondaryWpts[0].getChildren(); 922 if ( coordNodes && 923 coordNodes.length >= 2 && 924 coordNodes[0].id() == 1 && 925 coordNodes[0].type() == 'd' &&
926 coordNodes[1].id() == 2 && 927 coordNodes[1].type() == 'd' ) { 928 this.route.pushWaypoint( 929 new GmdpWaypoint( coordNodes[1].value(), 930 coordNodes[0].value(), 931 false ) ); 932 } 933 } 934 } 935 } 936 } 937 } else if ( primaryChild.id() == 2 && primaryChild.type() == 'm' ) { 938 var routeOptions = primaryChild.getChildren(), 939 routeOption; 940 for ( var i = 0; i < routeOptions.length; i++ ) { 941 routeOption = routeOptions[i]; 942 943 if ( routeOption.id() == 1 && routeOption.type() == 'b' ) { 944 this.route.avoidHighways = true; 945 } 946 else if ( routeOption.id() == 2 && routeOption.type() == 'b' ) { 947 this.route.avoidTolls = true; 948 } 949 else if ( routeOption.id() == 3 && routeOption.type() == 'b' ) { 950 this.route.avoidFerries = true; 951 } 952 else if ( routeOption.id() == 4 && routeOption.type() == 'e' ) { 953 this.route.setRoutePref( routeOption.value() ); 954 } 955 else if ( routeOption.id() == 5 && routeOption.type() == 'e' ) { 956 this.route.addTransitModePref( routeOption.value() ); 957 } 958 else if ( routeOption.id() == 6 && routeOption.type() == 'e' ) { 959 this.route.setArrDepTimeType( routeOption.value() ); 960 } 961 if ( routeOption.id() == 8 && routeOption.type() == 'j' ) { 962 this.route.arrDepTime = routeOption.value(); //as a unix timestamp 963 } 964 } 965 } else if ( primaryChild.id() == 3 && primaryChild.type() == 'e' ) { 966 this.route.setTransportation( primaryChild.value() ); 967 } else if ( primaryChild.id() == 4 && primaryChild.type() == 'e' ) { 968 this.route.setUnit( primaryChild.value() ); 969 } 970 } 971 } 972 } 973 if ( streetviewTop ) { 974 var streetviewChildren = streetviewTop.getChildren(), 975 streetviewChild; 976 for ( var i = 0; i < streetviewChildren.length; i++ ) { 977 streetviewChild = streetviewChildren[i]; 978 if ( streetviewChild.id() == 3 && streetviewChild.type() == 'm' ) { 979 var svInfos = streetviewChild.getChildren(), 980 svInfo; 981 for ( var i = 0; i < svInfos.length; i++ ) { 982 svInfo = svInfos[i]; 983 if ( svInfo.id() == 2 && svInfo.type() == 'e' ) { 984 if ( svInfo.value() == 4 ) { 985 //!2e4!3e11 indicates a photosphere, rather than standard streetview 986 //but the 3e11 doesn't seem to matter too much (?) 987 this.mapType = "photosphere"; 988 } 989 } 990 if ( svInfo.id() == 6 && svInfo.type() == 's' ) { 991 this.svURL = decodeURIComponent( svInfo.value() ); 992 } 993 } 994 } 995 } 996 } 997} 998 999/** 1000 * Returns the route defined by this data parameter. 1001 */ 1002Gmdp.prototype.getRoute = function() { 1003 return this.route; 1004} 1005 1006/** 1007 * Returns the main map type ("map", "earth"). 1008 */ 1009Gmdp.prototype.getMapType = function() { 1010 return this.mapType; 1011} 1012 1013/** 1014 * Returns the main map type ("map", "earth"). 1015 */ 1016Gmdp.prototype.getStreetviewURL = function() { 1017 return this.svURL; 1018} 1019/* --- Magnific Popup Initialization --- */ 1020 1021function magnificPopupInit() { 1022 if ( globalDebug ) { 1023 console.log( "Magnific Popup - Init" ); 1024 } 1025 1026 $( '.js-post-gallery' ).each( function () { // the containers for all your galleries should have the class gallery 1027 $( this ).magnificPopup( { 1028 tPrev: rosaStrings.tPrev, 1029 tNext: rosaStrings.tNext, 1030 tCounter: rosaStrings.tCounter, 1031 delegate: 'a[href*=".jpg"], a[href*=".jpeg"], a[href*=".png"], a[href*=".gif"]', // the container for each your gallery items 1032 type: 'image', 1033 closeOnContentClick: false, 1034 closeBtnInside: false, 1035 closeOnBgClick: false, 1036 fixedContentPos: true, 1037 removalDelay: 500, 1038 mainClass: 'mfp-fade', 1039 image: { 1040 markup: '<div class="mfp-figure">' + 1041 '<div class="mfp-close"></div>' + 1042 '<div class="mfp-img"></div>' + 1043 '<div class="mfp-bottom-bar">' + 1044 '<div class="mfp-title"></div>' + 1045 '<div class="mfp-counter"></div>' + 1046 '</div>' + 1047 '</div>', 1048 titleSrc: function ( item ) { 1049 var output = ''; 1050 if ( typeof item.el.attr( 'data-alt' ) !== "undefined" && item.el.attr( 'data-alt' ) !== "" ) { 1051 output += '<small>' + item.el.attr( 'data-alt' ) + '</small>'; 1052 } 1053 return output; 1054 } 1055 }, 1056 gallery: { 1057 enabled: true, 1058 navigateByImgClick: true 1059 //arrowMarkup: '<a href="#" class="gallery-arrow gallery-arrow--%dir% control-item arrow-button arrow-button--%dir%">%dir%</a>' 1060 }, 1061 callbacks: { 1062 elementParse: function ( item ) { 1063 1064 if ( this.currItem != undefined ) { 1065 item = this.currItem; 1066 } 1067 1068 var output = ''; 1069 if ( typeof item.el.attr( 'data-alt' ) !== "undefined" && item.el.attr( 'data-alt' ) !== "" ) { 1070 output += '<small>' + item.el.attr( 'data-alt' ) + '</small>'; 1071 } 1072 1073 $( '.mfp-title' ).html( output ); 1074 }, 1075 change: function ( item ) { 1076 var output = ''; 1077 if ( typeof item.el.attr( 'data-alt' ) !== "undefined" && item.el.attr( 'data-alt' ) !== "" ) { 1078 output += '<small>' + item.el.attr( 'data-alt' ) + '</small>'; 1079 } 1080 1081 $( '.mfp-title' ).html( output ); 1082 }, 1083 beforeClose: function () { 1084 $( '.mfp-arrow, .mfp-close' ).hide(); 1085 } 1086 } 1087 } ); 1088 } ); 1089} 1090 1091var GMap = function() { 1092 this.pinIconMarkup = $( '.js-map-pin' ).html(); 1093}; 1094 1095GMap.prototype.init = function( $container ) { 1096 var that = this; 1097 var $body = $( 'body' ); 1098 1099 $container = typeof $container !== "undefined" ? $container : $body; 1100 1101 $container.find( '.c-hero__map' ).each( function( i, obj ) { 1102 var $map = $( obj ); 1103 that.initializeMap( $map ); 1104 } ); 1105}; 1106 1107GMap.prototype.initializeMap = function( $map ) { 1108 var that = this; 1109 1110 if ( typeof google !== 'undefined' ) { 1111 1112 var url = $map.data( 'url' ), 1113 style = typeof $map.data( 'customstyle' ) !== "undefined" ? "rosa" : google.maps.MapTypeId.ROADMAP, 1114 markerContent = $map.data( 'markercontent' ), 1115 coordinates, 1116 pins = []; 1117 1118 if ( typeof url === "string" ) { 1119 1120 coordinates = that.getCenterFrom( url ); 1121 pins = that.getPinsFrom( url, markerContent ); 1122 1123 // if there are no markers encoded in the url 1124 // place a pin the center of the map 1125 if ( pins.length === 0 && typeof coordinates !== "undefined" ) { 1126 pins.push( { 1127 position: [coordinates.latitude, coordinates.longitude], 1128 content: that.getPinMarkup( markerContent ), 1129 x: 0, 1130 y: 4 1131 } ); 1132 } else { 1133 var pinPosition = pins[0]['position']; 1134 1135 if ( typeof pinPosition !== "undefined" ) { 1136 coordinates.latitude = pinPosition[0]; 1137 coordinates.longitude = pinPosition[1]; 1138 } 1139 } 1140 } else { 1141 var pinsData = $map.data( 'pins' ); 1142 1143 $.each( pinsData, function( label, url ) { 1144 coordinates = that.getCenterFrom( url ); 1145 1146 pins.push( { 1147 position: [coordinates['latitude'], coordinates['longitude']], 1148 content: that.getPinMarkup( label, 'pin' ), 1149 x: 0, 1150 y: 4 1151 } ); 1152 1153 } ); 1154 } 1155 1156 $map 1157 .gmap3( { 1158 center: [coordinates.latitude, coordinates.longitude], 1159 zoom: parseInt( coordinates.zoom ), 1160 mapTypeId: style, 1161 scrollwheel: false, 1162 mapTypeControl: false, 1163 zoomControl: true, 1164 zoomControlOptions: { 1165 position: google.maps.ControlPosition.LEFT_CENTER 1166 }, 1167 scaleControl: true, 1168 streetViewControl: true, 1169 streetViewControlOptions: { 1170 position: google.maps.ControlPosition.LEFT_CENTER 1171 }, 1172 fullscreenControl: true 1173 } ) 1174 .styledmaptype( "rosa", that.customStyle, {name: "Rosa"} ) 1175 .overlay( pins ); 1176
1177 $body.on( 'rosa:update-map-color', function(e, color) { 1178 that.customStyle[1].stylers[0].hue = color; 1179 $map.gmap3().styledmaptype( "rosa", that.customStyle, {name: "Rosa"} ); 1180 }); 1181 1182 if ( pins.length > 1 ) { 1183 $map.gmap3().fit(); 1184 } 1185 1186 } 1187 1188}; 1189 1190GMap.prototype.getCenterFrom = function( url ) { 1191 var split = url.split( '@' )[1].split( '/' )[0].split( 'z' )[0].split( ',' ), 1192 coordinates = {}, 1193 urlCheck = false; 1194 1195 function parseChildren( obj ) { 1196 var coord = []; 1197 $.each( obj.getChildren(), function( i, child ) { 1198 if ( child.type() == "d" ) { 1199 coord.push( child.value() ); 1200 } 1201 parseChildren( child ); 1202 } ); 1203 1204 if ( coord.length === 2 ) { 1205 urlCheck = true; 1206 1207 coordinates.latitude = parseFloat(coord[0]); 1208 coordinates.longitude = parseFloat(coord[1]); 1209 coordinates.zoom = parseFloat( split[2] ); 1210 } 1211 } 1212 1213 if ( url.indexOf( 'data=' ) > - 1 ) { 1214 parseChildren( new Gmdp( url ).prBufRoot ); 1215 } 1216 1217 1218 if ( urlCheck === false && ( 2 === split.length || 3 === split.length ) ) { 1219 1220 coordinates.latitude = parseFloat( split[0] ); 1221 coordinates.longitude = parseFloat( split[1] ); 1222 1223 if ( 3 === split.length ) { 1224 coordinates.zoom = parseFloat( split[2] ); 1225 } 1226 } 1227 1228 return coordinates; 1229}; 1230 1231GMap.prototype.getPinsFrom = function( url, markerContent ) { 1232 var that = this, 1233 coordinates = [], 1234 pins = []; 1235 1236 function parseChildren( obj ) { 1237 var coord = []; 1238 $.each( obj.getChildren(), function( i, child ) { 1239 if ( child.type() == "d" ) { 1240 coord.push( child.value() ); 1241 } 1242 parseChildren( child ); 1243 } ); 1244 1245 if ( coord.length === 2 ) { 1246 coordinates.push( coord ); 1247 } 1248 } 1249 1250 if ( url.indexOf( 'data=' ) > - 1 ) { 1251 parseChildren( new Gmdp( url ).prBufRoot ); 1252 } 1253 1254 $.each( coordinates, function( i, coord ) { 1255 pins.push( { 1256 position: [coord[0], coord[1]], 1257 content: that.getPinMarkup( markerContent, 'tooltip' ), 1258 x: 0, 1259 y: 4 1260 } ); 1261 } ); 1262 1263 return pins; 1264}; 1265 1266GMap.prototype.getPinMarkup = function( content, type ) { 1267 type = type || 'tooltip'; 1268 1269 if ( type === 'tooltip' ) { 1270 return '<div class="map-tooltip"><div class="map-tooltip__content">' + content + '</div></div>'; 1271 } else { 1272 return '<div class="map-pin"><div class="map-pin__text">' + content + '</div>' + this.pinIconMarkup + '</div>' 1273 } 1274}; 1275 1276GMap.prototype.customStyle = [ 1277 { 1278 "stylers": [ 1279 {"saturation": - 100}, 1280 {"gamma": 3.00}, 1281 {"visibility": "simplified"} 1282 ] 1283 }, { 1284 "featureType": "road", 1285 "stylers": [ 1286 {"hue": $( "body" ).data( "color" ) ? $( "body" ).data( "color" ) : "#ffaa00"}, 1287 {"saturation": 48}, 1288 {"gamma": 0.40}, 1289 {"visibility": "on"} 1290 ] 1291 }, { 1292 "featureType": "administrative", 1293 "stylers": [ 1294 {"saturation": - 30}, 1295 {"gamma": 0.6}, 1296 {"visibility": "on"} 1297 ] 1298 }, { 1299 "featureType": "administrative.neighborhood", 1300 "stylers": [ 1301 {"visibility": "off"} 1302 ] 1303 } 1304]; 1305 1306var Parallax = function( selector, options ) { 1307 this.disabled = false; 1308 this.selector = selector; 1309 this.options = options; 1310}; 1311 1312Parallax.prototype.init = function( $container ) { 1313 $container = $container || $( 'body' ); 1314 if ( this.disabled === false ) { 1315 $container.find( this.selector ).rellax( this.options ); 1316 } 1317}; 1318 1319Parallax.prototype.disable = function() { 1320 this.disabled = true; 1321 this.destroy(); 1322}; 1323 1324Parallax.prototype.destroy = function() { 1325 $( this.selector ).rellax( "destroy" ); 1326}; 1327 1328Parallax.prototype.enable = function() { 1329 this.disabled = false; 1330 $( this.selector ).rellax( this.options ); 1331}; 1332 1333(function($) { 1334 1335 function observe( $container ) { 1336 var MutationObserver = window.MutationObserver, 1337 observer, config; 1338 1339 if ( typeof MutationObserver === "undefined" ) { 1340 return; 1341 } 1342 1343 observer = new MutationObserver( function() { 1344 $( window ).trigger( 'rellax' ); 1345 } ); 1346 1347 config = { 1348 childList: true, 1349 characterData: false, 1350 attributes: false, 1351 subtree: true 1352 }; 1353 1354 $container.each( function() { 1355 observer.observe( this, config ); 1356 } ); 1357 } 1358 1359 observe( $('.article__content') ); 1360 1361})(jQuery); 1362/* --- Royal Slider Init --- */ 1363 1364function royalSliderInit( $container ) { 1365 if ( globalDebug ) { 1366 console.log( "Royal Slider - Init" ); 1367 } 1368 1369 $container = typeof $container !== 'undefined' ? $container : $( 'body' ); 1370 1371 // Transform Wordpress Galleries to Sliders 1372 $container.find( '.wp-gallery' ).each( function () { 1373 sliderMarkupGallery( $( this ) ); 1374 } ); 1375 1376 // Find and initialize each slider 1377 $container.find( '.js-pixslider' ).each( function () { 1378 var $slider = $( this ); 1379 $slider.imagesLoaded( function () { 1380 sliderInit( $slider ); 1381 } ); 1382 } ); 1383 1384} 1385 1386/* 1387 * Slider Initialization 1388 */ 1389function sliderInit( $slider ) { 1390
1391 $slider.find( 'img' ).removeClass( 'invisible' ); 1392 1393 var $children = $( this ).children(), 1394 rs_arrows = typeof $slider.data( 'arrows' ) !== "undefined", 1395 rs_bullets = typeof $slider.data( 'bullets' ) !== "undefined" ? "bullets" : "none", 1396 rs_autoheight = typeof $slider.data( 'autoheight' ) !== "undefined", 1397 rs_autoScaleSlider = false, 1398 rs_autoScaleSliderWidth = $slider.data( 'autoscalesliderwidth' ), 1399 rs_autoScaleSliderHeight = $slider.data( 'autoscalesliderheight' ), 1400 rs_customArrows = typeof $slider.data( 'customarrows' ) !== "undefined", 1401 rs_slidesSpacing = typeof $slider.data( 'slidesspacing' ) !== "undefined" ? parseInt( $slider.data( 'slidesspacing' ) ) : 0, 1402 rs_keyboardNav = typeof $slider.data( 'fullscreen' ) !== "undefined", 1403 rs_imageScale = $slider.data( 'imagescale' ), 1404 rs_visibleNearby = typeof $slider.data( 'visiblenearby' ) !== "undefined", 1405 rs_imageAlignCenter = typeof $slider.data( 'imagealigncenter' ) !== "undefined", 1406 rs_transition = typeof $slider.data( 'slidertransition' ) !== "undefined" && $slider.data( 'slidertransition' ) !== '' ? $slider.data( 'slidertransition' ) : 'move', 1407 rs_autoPlay = typeof $slider.data( 'sliderautoplay' ) !== "undefined", 1408 rs_delay = typeof $slider.data( 'sliderdelay' ) !== "undefined" && $slider.data( 'sliderdelay' ) !== '' ? $slider.data( 'sliderdelay' ) : '1000', 1409 rs_drag = true, 1410 rs_globalCaption = typeof $slider.data( 'showcaptions' ) !== "undefined", 1411 is_headerSlider = $slider.hasClass( 'header--slideshow' ), 1412 hoverArrows = typeof $slider.data( 'hoverarrows' ) !== "undefined"; 1413 1414 // Single slide case 1415 if ( $children.length === 1 ) { 1416 rs_arrows = false; 1417 rs_bullets = 'none'; 1418 rs_customArrows = false; 1419 rs_keyboardNav = false;
1420 rs_drag = false; 1421 rs_transition = 'fade'; 1422 } 1423 // make sure default arrows won't appear if customArrows is set 1424 if ( rs_customArrows ) { 1425 rs_arrows = false; 1426 } 1427 1428 //the main params for Royal Slider 1429 var royalSliderParams = { 1430 autoHeight: rs_autoheight, 1431 autoScaleSlider: rs_autoScaleSlider, 1432 loop: true, 1433 autoScaleSliderWidth: rs_autoScaleSliderWidth, 1434 autoScaleSliderHeight: rs_autoScaleSliderHeight, 1435 imageScaleMode: rs_imageScale, 1436 imageAlignCenter: rs_imageAlignCenter, 1437 slidesSpacing: rs_slidesSpacing, 1438 arrowsNav: rs_arrows, 1439 controlNavigation: rs_bullets, 1440 keyboardNavEnabled: rs_keyboardNav, 1441 arrowsNavAutoHide: false, 1442 sliderDrag: rs_drag, 1443 transitionType: rs_transition, 1444 autoPlay: { 1445 enabled: rs_autoPlay, 1446 stopAtAction: true, 1447 pauseOnHover: true, 1448 delay: rs_delay 1449 }, 1450 globalCaption: rs_globalCaption, 1451 numImagesToPreload: 4 1452 }; 1453 1454 if ( rs_visibleNearby ) { 1455 royalSliderParams['visibleNearby'] = { 1456 enabled: true, 1457 //centerArea: 0.8, 1458 center: true, 1459 breakpoint: 0, 1460 //breakpointCenterArea: 0.64, 1461 navigateByCenterClick: false 1462 } 1463 } 1464 1465 1466 // lets fire it up 1467 1468 $slider.royalSlider( royalSliderParams ); 1469 $slider.addClass( 'slider--loaded' ); 1470 1471 var royalSlider = $slider.data( 'royalSlider' ); 1472 var slidesNumber = royalSlider.numSlides; 1473 1474 royalSlider.ev.on( 'rsAfterSlideChange rsAfterContentSet', function ( event ) { 1475 $( window ).trigger( 'rellax' ); 1476 }); 1477 1478 // create the markup for the customArrows 1479 if ( royalSlider && rs_customArrows ) { 1480 1481 var classes = 'slider__custom-arrows'; 1482 1483 if ( is_headerSlider ) { 1484 classes = 'slider-arrows-header'; 1485 } 1486 1487 if ( hoverArrows && ! Modernizr.touchevents ) { 1488 classes += ' arrows--hover '; 1489 } 1490 1491 $slider.find( '.slider__custom-arrows' ).off( 'click' ).remove(); 1492 1493 var $gallery_control = $( 1494 '<div class="' + classes + '">' + 1495 '<div class="rsArrow rsArrowLeft js-arrow-left" style="display: block;"><div class="rsArrowIcn"></div></div>' + 1496 '<div class="rsArrow rsArrowRight js-arrow-right" style="display: block;"><div class="rsArrowIcn"></div></div>' + 1497 '</div>' 1498 ); 1499 1500 if ( $slider.data( 'customarrows' ) === "left" ) { 1501 $gallery_control.addClass( 'gallery-control--left' ); 1502 } 1503 1504 $gallery_control.insertBefore( $slider ); 1505 1506 $gallery_control.on( 'click', '.js-arrow-left', function ( event ) { 1507 event.preventDefault(); 1508 royalSlider.prev(); 1509 } ); 1510 1511 $gallery_control.on( 'click', '.js-arrow-right', function ( event ) { 1512 event.preventDefault(); 1513 royalSlider.next(); 1514 } ); 1515 } 1516 1517 if ( hoverArrows && ! Modernizr.touchevents ) { 1518 hoverArrow( $gallery_control.find( '.rsArrow' ) ); 1519 1520 } 1521 1522 if ( slidesNumber === 1 ) { 1523 $slider.addClass( 'single-slide' ); 1524 } 1525 1526 $slider.addClass( 'slider--loaded' ); 1527} 1528 1529/* 1530 * Wordpress Galleries to Sliders 1531 * Create the markup for the slider from the gallery shortcode 1532 * take all the images and insert them in the .gallery <div> 1533 */ 1534function sliderMarkupGallery( $gallery ) { 1535 var $old_gallery = $gallery, 1536 gallery_data = $gallery.data(), 1537 $images = $old_gallery.find( 'img' ), 1538 $new_gallery = $( '<div class="pixslider js-pixslider">' ); 1539 1540 $images.prependTo( $new_gallery ).addClass( 'rsImg' ); 1541 1542 //add the data attributes 1543 $.each( gallery_data, function ( key, value ) { 1544 $new_gallery.attr( 'data-' + key, value ); 1545 } ) 1546 1547 $old_gallery.replaceWith( $new_gallery ); 1548} 1549 1550/* 1551 Get slider arrows to hover, following the cursor 1552 */ 1553 1554function hoverArrow( $arrow ) { 1555 1556 $arrow.each(function(i, obj) { 1557 1558 var $arrow = $(obj), 1559 update = false, 1560 offset = $arrow.offset(), 1561 $icon = $arrow.find( '.rsArrowIcn' ), 1562 mouseX, 1563 mouseY; 1564 1565 $arrow.mouseenter( function ( e ) { 1566 offset = $arrow.offset(); 1567 $( this ).addClass( 'visible' ); 1568 update = true; 1569 }); 1570 1571 $arrow.mousemove( function ( e ) { 1572 mouseX = e.pageX - offset.left; 1573 mouseY = e.pageY - offset.top; 1574 }); 1575 1576 $arrow.mouseleave( function ( e ) { 1577 $( this ).removeClass( 'visible' ); 1578 update = false; 1579 }); 1580 1581 function loop() { 1582 if ( update ) { 1583 TweenMax.to( $icon, 0, {x: mouseX, y: mouseY, z: 0.01, force3D: true} ); 1584 } 1585 requestAnimationFrame(loop); 1586 } 1587 1588 loop(); 1589 }); 1590} 1591var ScrollToTop = (function() { 1592 1593 var start = 0, 1594 end = 0, 1595 timeline = null, 1596 played = false, 1597 footerHeight; 1598 1599 function initialize() { 1600 1601 var $button = $('.btn--top'), 1602 offsetTop = 0, 1603 start = offsetTop - windowHeight + footerHeight * 3 / 4; 1604 1605 footerHeight = $('.copyright-area').outerHeight(); 1606 1607 if (empty($button)) { 1608 return; 1609 } 1610 1611 offsetTop = $button.offset().top; 1612 $button.data('offsetTop', offsetTop); 1613 1614 this.timeline = new TimelineMax({ paused: true }); 1615 1616 this.timeline.fromTo('.blurp--bottom', .6, { 1617 y: 40, 1618 scale: 0.5 1619 }, { 1620 y: 0, 1621 scale: 1, 1622 ease: Power3.easeOut, 1623 force3D: true 1624 1625 }); 1626 1627 this.timeline.fromTo($('.btn__arrow--top'), .4, { 1628 y: 15, 1629 opacity: 0 1630 }, { 1631 y: 0, 1632 scale: 1, 1633 opacity: 1, 1634 ease: Back.easeOut 1635 }, '-=0.1'); 1636 1637 this.timeline.fromTo($('.btn__arrow--bottom'),.4, { 1638 y: 15, 1639 opacity: 0 1640 }, { 1641 y: 0, 1642 scale: 1, 1643 opacity: 1, 1644 ease: Back.easeOut 1645 }, '-=0.25'); 1646 1647 $button.on('click', function (e) { 1648 e.preventDefault(); 1649 smoothScrollTo(0); 1650 }); 1651 1652 this.update(); 1653 } 1654
1655 function update() { 1656 1657 var $button = $('.btn--top'), 1658 offsetTop = $button.data('offsetTop'), 1659 start = offsetTop - windowHeight + footerHeight * 3 / 4, 1660 end = start + windowHeight; 1661 1662 if (empty($button) || this.timeline == null) { 1663 return; 1664 } 1665 1666 if (Modernizr.touchevents && is_OSX) { 1667 this.timeline.progress(1); 1668 return; 1669 } 1670 1671 if (start < latestKnownScrollY) { 1672 if (!this.played) { 1673 this.timeline.play(); 1674 this.played = true; 1675 } 1676 } else { 1677 if (this.played) { 1678 this.timeline.reverse(); 1679 this.played = false; 1680 } 1681 } 1682 } 1683 1684 return { 1685 initialize: initialize, 1686 update: update 1687 } 1688 1689})(); 1690 1691/* --- Sticky Header Init --- */ 1692 1693var StickyHeader = (function() { 1694 1695 var headerSelector = '.site-header', 1696 $header = $( headerSelector ), 1697 headerHeight, 1698 $headers; 1699 1700 function init() { 1701 headerHeight = $header.outerHeight(); 1702 $headers = $( '.article__header' ).first(); 1703 } 1704 1705 function update() { 1706 var inversed = false, 1707 adminBarHeight = $( '#wpadminbar' ).outerHeight(), 1708 headerHeight = $header.outerHeight(); 1709 1710 $headers.each( function( i, obj ) { 1711 var $obj = $( obj ), 1712 start = $obj.offset().top, 1713 end = start + $obj.outerHeight(); 1714 1715 if ( latestKnownScrollY >= start - adminBarHeight && latestKnownScrollY <= end - headerHeight - adminBarHeight ) { 1716 inversed = true; 1717 } 1718 } ); 1719 1720 if ( ! inversed ) { 1721 $header.removeClass( 'headroom--top' ).addClass( 'headroom--not-top' ); 1722 } else { 1723 $header.removeClass( 'headroom--not-top' ).addClass( 'headroom--top' ); 1724 } 1725 } 1726 1727 return { 1728 init: init, 1729 update: update 1730 } 1731 1732})(); 1733 1734// http://paulirish.com/2011/requestanimationframe-for-smart-animating/ 1735// http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating 1736 1737// requestAnimationFrame polyfill by Erik Möller. fixes from Paul Irish and Tino Zijdel 1738 1739// MIT license 1740 1741(function() { 1742 var lastTime = 0; 1743 var vendors = ['ms', 'moz', 'webkit', 'o']; 1744 for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { 1745 window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame']; 1746 window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] 1747 || window[vendors[x]+'CancelRequestAnimationFrame']; 1748 } 1749 1750 if (!window.requestAnimationFrame) 1751 window.requestAnimationFrame = function(callback, element) { 1752 var currTime = new Date().getTime(); 1753 var timeToCall = Math.max(0, 16 - (currTime - lastTime)); 1754 var id = window.setTimeout(function() { callback(currTime + timeToCall); }, 1755 timeToCall); 1756 lastTime = currTime + timeToCall; 1757 return id; 1758 }; 1759 1760 if (!window.cancelAnimationFrame) 1761 window.cancelAnimationFrame = function(id) { 1762 clearTimeout(id); 1763 }; 1764}()); 1765 1766//here we change the link of the Edit button in the Admin Bar 1767//to make sure it reflects the current page 1768function adminBarEditFix(id) { 1769 //get the admin ajax url and clean it 1770 var baseURL = rosaStrings.ajaxurl.replace('admin-ajax.php', 'post.php'); 1771 1772 $('#wp-admin-bar-edit a').attr('href', baseURL + '?post=' + id + '&action=edit'); 1773} 1774 1775/* --- Load AddThis Async --- */ 1776function loadAddThisScript() { 1777 if (window.addthis) { 1778 if (globalDebug) { 1779 console.log("AddThis Load Script"); 1780 } 1781 // Listen for the ready event 1782 addthis.addEventListener('addthis.ready', addthisReady); 1783 addthis.init(); 1784 } 1785} 1786 1787/* --- AddThis On Ready - The API is fully loaded --- */ 1788//only fire this the first time we load the AddThis API - even when using ajax 1789function addthisReady() { 1790 if (globalDebug) { 1791 console.log("AddThis Ready"); 1792 } 1793 addThisInit(); 1794} 1795 1796/* --- AddThis Init --- */ 1797function addThisInit() { 1798 if (window.addthis) { 1799 if (globalDebug) { 1800 console.log("AddThis Toolbox INIT"); 1801 } 1802 1803 addthis.toolbox('.addthis_toolbox'); 1804 } 1805} 1806 1807var HandleSubmenusOnTouch = (function() { 1808 1809 var isInitiated = false;
1810 1811 function init() { 1812 if( isInitiated ) return; 1813 1814 // Make sure there are no open menu items 1815 $('.menu-item-has-children').removeClass('hover'); 1816 1817 // Add a class so we know the items to handle 1818 $('.menu-item-has-children > a').each(function () { 1819 $(this).addClass('prevent-one'); 1820 }); 1821 1822 $('a.prevent-one').on('click', function (e) { 1823 e.preventDefault(); 1824 e.stopPropagation(); 1825 1826 if( $(this).hasClass('active') ) { 1827 window.location.href = $(this).attr('href'); 1828 } 1829 1830 $('a.prevent-one').removeClass('active'); 1831 $(this).addClass('active'); 1832 1833 // When a parent menu item is activated, 1834 // close other menu items on the same level 1835 $(this).parent().siblings().removeClass('hover'); 1836 1837 // Open the sub menu of this parent item 1838 $(this).parent().addClass('hover'); 1839 }); 1840 1841 isInitiated = true; 1842 } 1843 1844 function release() { 1845 $('a.prevent-one').unbind(); 1846 isInitiated = false; 1847 } 1848 1849 return { 1850 init: init, 1851 release: release 1852 } 1853}()); 1854 1855function getIEversion() { 1856 var ua = window.navigator.userAgent; 1857 1858 // Test values; Uncomment to check result … 1859 1860 // IE 10 1861 // ua = 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)'; 1862 1863 // IE 11 1864 // ua = 'Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko'; 1865 1866 // Edge 12 (Spartan) 1867 // ua = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36 Edge/12.0'; 1868 1869 // Edge 13 1870 // ua = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Safari/537.36 Edge/13.10586'; 1871 1872 var msie = ua.indexOf('MSIE '); 1873 if (msie > 0) { 1874 // IE 10 or older => return version number 1875 return parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10); 1876 } 1877 1878 var trident = ua.indexOf('Trident/'); 1879 if (trident > 0) { 1880 // IE 11 => return version number 1881 var rv = ua.indexOf('rv:'); 1882 return parseInt(ua.substring(rv + 3, ua.indexOf('.', rv)), 10); 1883 } 1884 1885 var edge = ua.indexOf('Edge/'); 1886 if (edge > 0) { 1887 // Edge (IE 12+) => return version number 1888 return parseInt(ua.substring(edge + 5, ua.indexOf('.', edge)), 10); 1889 } 1890 1891 // other browser 1892 return false; 1893} 1894 1895/* ====== INTERNAL FUNCTIONS ====== */ 1896 1897/* --- NICESCROLL --- */ 1898 1899var $body = $( 'body' ), 1900 $html = $( 'html' ), 1901 $window = $( window ), 1902 $document = $( document ), 1903 documentHeight = $document.height(), 1904 aspectRatio = windowWidth / windowHeight, 1905 orientation = getOrientation(), 1906 isTouch = ! ! ( ( "ontouchstart" in window ) || window.DocumentTouch && document instanceof DocumentTouch ); 1907 1908var $target = $( window.location.hash ).filter( '.article--page' ); 1909 1910if ( $target.length ) { 1911 requestAnimationFrame( function() { 1912 window.scrollTo( 0, $target.offset().top - $( '.site-header' ).height() ); 1913 } ); 1914} 1915 1916function niceScrollInit() { 1917 if ( globalDebug ) { 1918 console.log( "NiceScroll Init" ); 1919 } 1920 1921 var smoothScroll = $( 'body' ).data( 'smoothscrolling' ) !== undefined, 1922 root = document.documentElement; 1923 1924 if ( smoothScroll && ! is_EDGE && ! Modernizr.touchevents && ! is_mobile_ie && ! is_OSX ) { 1925 1926 var $window = $( window ); // Window object 1927 1928 $window.on( "mousewheel DOMMouseScroll", function( event ) { 1929 1930 var scrollTo, 1931 scrollDistance = 400, 1932 delta; 1933 1934 if ( event.type == 'mousewheel' ) { 1935 delta = event.originalEvent.wheelDelta / 120; 1936 } 1937 else if ( event.type == 'DOMMouseScroll' ) { 1938 delta = - event.originalEvent.detail / 3; 1939 } 1940 1941 scrollTo = latestKnownScrollY - delta * scrollDistance; 1942 1943 if ( scrollTo ) { 1944 1945 event.preventDefault(); 1946 1947 TweenMax.to( $window, .6, { 1948 scrollTo: { 1949 y: scrollTo, 1950 autoKill: true 1951 }, 1952 ease: Power1.easeOut, // For more easing functions see http://api.greensock.com/js/com/greensock/easing/package-detail.html 1953 autoKill: true, 1954 overwrite: 5 1955 } ); 1956 1957 } 1958 1959 } ); 1960 1961 } 1962 1963} 1964 1965 1966function smoothScrollTo( y, speed ) { 1967 1968 speed = typeof speed === "undefined" ? 1 : speed; 1969 1970 var distance = Math.abs( latestKnownScrollY - y ), 1971 time = speed * distance / 2000; 1972 1973 TweenMax.to( $( window ), time, {scrollTo: {y: y, autoKill: false, ease: Quint.easeInOut}} ); 1974} 1975 1976 1977function menuTrigger() { 1978 1979 $( '.js-nav-trigger' ).on( 'click', function( e ) { 1980 1981 e.preventDefault(); 1982 e.stopPropagation(); 1983 1984 var $html = $( 'html' ); 1985 1986 if ( $html.hasClass( 'navigation--is-visible' ) ) { 1987 $html.removeClass( 'navigation--is-visible' ); 1988 } else { 1989 $html.addClass( 'navigation--is-visible' ); 1990
1991 if ( $html.is( '.is--ancient-android, .is--winmob, .is--ie' ) ) { 1992 $( '.navigation--main' ).height( windowHeight ); 1993 } 1994 } 1995 } ); 1996} 1997 1998function cartOnMobile() { 1999 if ( $('.js-open-cart').length) { 2000 var cartNav = $('.mobile-cart'), 2001 cartMenu = $('.menu-item--cart'), 2002 icon = $('.js-open-cart').detach(); 2003 2004 if ( windowWidth < 900 ) { 2005 icon.appendTo(cartNav); 2006 } else { 2007 icon.appendTo(cartMenu); 2008 } 2009 } 2010} 2011 2012/* --- $VIDEOS --- */ 2013 2014function initVideos() { 2015 2016 var videos = $( 'iframe, video' ); 2017 2018 // Figure out and save aspect ratio for each video 2019 videos.each( function() { 2020 $( this ).data( 'aspectRatio', this.width / this.height ) 2021 // and remove the hard coded width/height 2022 .removeAttr( 'height' ) 2023 .removeAttr( 'width' ); 2024 } ); 2025 2026 // Firefox Opacity Video Hack 2027 $( '#page iframe' ).each( function() { 2028 var url = $( this ).attr( "src" ); 2029 if ( ! empty( url ) ) { 2030 $( this ).attr( "src", setQueryParameter( url, "wmode", "transparent" ) ); 2031 } 2032 } ); 2033} 2034 2035 2036function resizeVideos() { 2037 2038 var videos = $( 'iframe, video' ); 2039 2040 videos.each( function() { 2041 var video = $( this ), 2042 ratio = video.data( 'aspectRatio' ), 2043 w = video.css( 'width', '100%' ).width(), 2044 h = w / ratio; 2045 video.height( h ); 2046 } ); 2047} 2048 2049 2050/* ====== INTERNAL FUNCTIONS END ====== */ 2051 2052function init() { 2053 if ( globalDebug ) { 2054 console.group( "Init" ); 2055 } 2056 2057 // /* GLOBAL VARS */ 2058 touch = false; 2059 2060 if ( typeof ( isIe ) !== 'undefined' || ( ! ( window.ActiveXObject ) && "ActiveXObject" in window ) ) { 2061 $( 'html' ).addClass( 'is--ie' ); 2062 } 2063 2064 if ( is_EDGE ) { 2065 $( 'html' ).addClass( 'is--ie-edge' ); 2066 } 2067 2068 // GET BROWSER DIMENSIONS 2069 browserSize(); 2070 2071 // /* DETECT PLATFORM */ 2072 platformDetect(); 2073 2074 loadAddThisScript(); 2075 2076 if ( is_android || window.opera ) { 2077 $( 'html' ).addClass( 'android-browser' ).removeClass( 'no-android-browser' ); 2078 } 2079 2080 /* ONE TIME EVENT HANDLERS */ 2081 eventHandlersOnce(); 2082 2083 /* INSTANTIATE EVENT HANDLERS */ 2084 eventHandlers(); 2085 updateHeaderPadding(); 2086 2087 var $borderTemplate = $( '.border-waves-template' ); 2088 2089 $( '.border-waves' ).each( function(i, obj) { 2090 var $obj = $(obj), 2091 $before = $borderTemplate.clone().removeClass( 'border-waves-template' ).addClass( 'border-waves-before' ), 2092 $after = $borderTemplate.clone().removeClass( 'border-waves-template' ).addClass( 'border-waves-after' ); 2093 2094 $before.appendTo( $obj ); 2095 $after.appendTo( $obj ); 2096 }); 2097 2098 $( '.navigation--main' ).on( 'DOMMouseScroll mousewheel', function( ev ) { 2099 var $this = $( this ), 2100 scrollTop = this.scrollTop, 2101 scrollHeight = this.scrollHeight, 2102 height = $this.height(), 2103 delta = ( 2104 ev.type == 'DOMMouseScroll' ? 2105 ev.originalEvent.detail * - 40 : 2106 ev.originalEvent.wheelDelta 2107 ), 2108 up = delta > 0; 2109 2110 var prevent = function() { 2111 ev.stopPropagation(); 2112 ev.preventDefault(); 2113 ev.returnValue = false; 2114 return false; 2115 }; 2116 2117 if ( ! up && - delta > scrollHeight - height - scrollTop ) { 2118 // Scrolling down, but this will take us past the bottom. 2119 $this.scrollTop( scrollHeight ); 2120 return prevent(); 2121 } else if ( up && delta > scrollTop ) { 2122 // Scrolling up, but this will take us past the top. 2123 $this.scrollTop( 0 ); 2124 return prevent(); 2125 } 2126 } ); 2127 2128 cartOnMobile(); 2129 2130 if ( globalDebug ) { 2131 console.groupEnd(); 2132 } 2133} 2134 2135/* ====== EVENT HANDLERS ====== */ 2136 2137function eventHandlersOnce() { 2138 if ( globalDebug ) { 2139 console.group( "Event Handlers Once" ); 2140 } 2141 2142 menuTrigger(); 2143 2144 if ( globalDebug ) { 2145 console.groupEnd(); 2146 } 2147} 2148 2149function eventHandlers() { 2150 if ( globalDebug ) { 2151 console.group( "Event Handlers" ); 2152 } 2153 2154 2155 //Magnific Popup arrows 2156 $( 'body' ).off( 'click', '.js-arrow-popup-prev', magnificPrev ).on( 'click', '.js-arrow-popup-prev', magnificPrev ); 2157 $( 'body' ).off( 'click', '.js-arrow-popup-next', magnificNext ).on( 'click', '.js-arrow-popup-next', magnificNext ); 2158 2159 $( document ).on( 'spam.wpcf7 invalid.wpcf7 mailsent.wpcf7 mailfailed.wpcf7', function() { 2160 setTimeout( function() { 2161 CoverAnimation.initialize(); 2162 }, 300 ); 2163 } ); 2164 2165 var filterHandler; 2166 2167 if ( touch ) { 2168 filterHandler = 'click'; 2169 } else { 2170 filterHandler = 'hover'; 2171 } 2172 2173 if ( touch && windowWidth < 900 ) { 2174 HandleSubmenusOnTouch.init(); 2175 } 2176 2177 if ( ieMobile ) { 2178 filterHandler = 'click'; 2179 } 2180 2181 $( '.categories__menu' ).on( filterHandler, function( e ) { 2182 e.stopPropagation(); 2183 2184 $( this ).toggleClass( 'active' ); 2185 } ); 2186 2187 if ( globalDebug ) { 2188 console.groupEnd(); 2189 } 2190} 2191 2192 2193/* --- GLOBAL EVENT HANDLERS --- */ 2194 2195function magnificPrev( e ) { 2196 if ( globalDebug ) { 2197 console.log( "Magnific Popup Prev" ); 2198 } 2199 2200 e.preventDefault(); 2201 var magnificPopup = $.magnificPopup.instance; 2202 magnificPopup.prev(); 2203 return false;
2204} 2205 2206function magnificNext( e ) { 2207 if ( globalDebug ) { 2208 console.log( "Magnific Popup Next" ); 2209 } 2210 2211 e.preventDefault(); 2212 var magnificPopup = $.magnificPopup.instance; 2213 magnificPopup.next(); 2214 return false; 2215} 2216 2217 2218// $(window).bind('beforeunload', function(event) { 2219// if (globalDebug) {console.log("ON BEFORE UNLOAD");} 2220 2221// event.stopPropagation(); 2222 2223// animateBlog('out'); 2224// }); 2225 2226 2227/* ====== ON DOCUMENT READY ====== */ 2228 2229$( document ).ready( function() { 2230 2231 if ( globalDebug ) { 2232 console.group( "OnDocumentReady" ); 2233 } 2234 2235 /* --- INITIALIZE --- */ 2236 init(); 2237 2238 if ( globalDebug ) { 2239 console.groupEnd(); 2240 } 2241 2242} ); 2243 2244 2245/* ====== ON WINDOW LOAD ====== */ 2246 2247$( window ).load( function() { 2248 2249 if ( globalDebug ) { 2250 console.group( "OnWindowLoad" ); 2251 } 2252 2253 StickyHeader.init(); 2254 2255 if ( is_mobile_ie ) { 2256 $( "html" ).addClass( "mobile-ie" ); 2257 } 2258 2259 //Set textarea from contact page to autoresize 2260 if ( $( "textarea" ).length ) { 2261 $( "textarea" ).autosize(); 2262 } 2263 2264 if ( ! $( 'html' ).is( '.ie9, .lt-ie9' ) ) { 2265 setTimeout( function() { 2266 CoverAnimation.initialize(); 2267 }, 600 ); 2268 } else { 2269 setTimeout( function() { 2270 CoverAnimation.initialize(); 2271 }, 400 ); 2272 } 2273 2274 niceScrollInit(); 2275 2276 magnificPopupInit(); 2277 initVideos(); 2278 resizeVideos(); 2279 2280 var Map = new GMap(); 2281 Map.init(); 2282 2283 if ( ! empty( $( '#date-otreservations' ) ) ) { 2284 var dateFormat = $( '#date-otreservations' ).closest( '.otw-wrapper' ).children( '.txtDateFormat' ).attr( 'value' ).toUpperCase(); 2285 2286 function disabledWeekends() { 2287 2288 if($('.pixcode--otreservations').hasClass('disable-weekends')) { 2289 return true; 2290 } 2291 2292 return false; 2293 } 2294 2295 // Pikaday 2296 var picker = new Pikaday( { 2297 field: document.getElementById( 'date-otreservations' ), 2298 format: dateFormat, 2299 minDate: moment().toDate(), 2300 defaultDate: moment().toDate(), 2301 setDefaultDate: true, 2302 disableWeekends: disabledWeekends() 2303 } ) 2304 } 2305 2306 $( '.pixcode--tabs' ).organicTabs(); 2307 DownArrow.initialize(); 2308 2309 setTimeout( function() { 2310 ScrollToTop.initialize(); 2311 }, 60 ); 2312 2313 royalSliderInit(); 2314 updateHeaderPadding(); 2315 2316 loop(); 2317 2318 var $bulletedSections = $('[data-bully]'); 2319 2320 if ( $bulletedSections.length > 1 ) { 2321 2322 $bulletedSections.bully(); 2323 2324 $('.c-bully__bullet').each(function (i, obj) { 2325 2326 var stagger = i * 400, 2327 $obj = $(obj); 2328 2329 setTimeout(function () { 2330 $obj.addClass('c-bully__bullet--pop'); 2331 }, stagger); 2332 }); 2333 } 2334 2335 Rosa.Parallax.init(); 2336 $html.addClass( 'is--loaded' ); 2337} ); 2338 2339function getOrientation() { 2340 return windowWidth > windowHeight ? "landscape" : "portrait"; 2341} 2342 2343function updateHeaderPadding() { 2344 var $header = $( '.site-header' ), 2345 headerHeight = $header.outerHeight(); 2346 2347 if ( ! $header.next().is( '.c-hero' ) ) { 2348 $('#page').css('paddingTop', headerHeight); 2349 } 2350} 2351 2352$window.on( 'resize', function() { 2353 windowWidth = window.innerWidth; 2354 windowHeight = window.innerHeight; 2355} ); 2356 2357$( window ).on( "debouncedresize", onResize ); 2358 2359$( window ).on( "rellax:restart", function() { 2360 $( '.js-pixslider' ).each(function(i, obj) { 2361 var rs = $(obj).data('royalSlider'); 2362 2363 if (typeof rs !== "undefined") { 2364 rs.updateSliderSize(true); 2365 } 2366 }); 2367}); 2368 2369function onResize() { 2370 var neworientation = getOrientation(); 2371 2372 if ( neworientation !== orientation ) { 2373 orientation = neworientation; 2374 $( window ).trigger( "debouncedorientationchange" ); 2375 } 2376 2377 resizeVideos(); 2378 cartOnMobile(); 2379 2380 if ( touch && windowWidth < 900 ) { 2381 HandleSubmenusOnTouch.init(); 2382 } else { 2383 HandleSubmenusOnTouch.release(); 2384 } 2385 2386 requestAnimationFrame( refreshStuff ); 2387} 2388 2389function refreshStuff() { 2390 CoverAnimation.initialize(); 2391 ScrollToTop.initialize(); 2392 $window.trigger( 'rellax' ); 2393} 2394 2395 2396function updateStuff() { 2397 ScrollToTop.update(); 2398 DownArrow.update(); 2399 CoverAnimation.update(); 2400 2401 if ( windowWidth >= 900 ) { 2402 StickyHeader.update(); 2403 } 2404} 2405 2406$( window ).on( "organicTabsChange", function() { 2407 onResize(); 2408 refreshStuff(); 2409 $window.trigger( 'rellax' ); 2410} ); 2411 2412$window.scroll( function() { 2413 newScrollY = (window.pageYOffset || document.documentElement.scrollTop) - (document.documentElement.clientTop || 0); 2414} ); 2415 2416function loop() { 2417 // Avoid calculations if not needed 2418 if ( latestKnownScrollY !== newScrollY ) { 2419 latestKnownScrollY = newScrollY; 2420 updateStuff(); 2421 } 2422 requestAnimationFrame( loop ); 2423} 2424 2425if ( navigator.userAgent.match( /iPad;.*CPU.*OS 7_\d/i ) && window.innerHeight != document.documentElement.clientHeight ) { 2426
2427 var fixViewportHeight = function() { 2428 $( 'html, body' ).outerHeight( window.innerHeight ); 2429 }; 2430 2431 window.addEventListener( "scroll", fixViewportHeight, false ); 2432 window.addEventListener( "orientationchange", fixViewportHeight, false ); 2433 fixViewportHeight(); 2434} 2435 2436function detectIE() { 2437 var ua = window.navigator.userAgent; 2438 2439 var msie = ua.indexOf( 'MSIE ' ); 2440 if ( msie > 0 ) { 2441 // IE 10 or older => return version number 2442 return parseInt( ua.substring( msie + 5, ua.indexOf( '.', msie ) ), 10 ); 2443 } 2444 2445 var trident = ua.indexOf( 'Trident/' ); 2446 if ( trident > 0 ) { 2447 // IE 11 => return version number 2448 var rv = ua.indexOf( 'rv:' ); 2449 return parseInt( ua.substring( rv + 3, ua.indexOf( '.', rv ) ), 10 ); 2450 } 2451 2452 var edge = ua.indexOf( 'Edge/' ); 2453 if ( edge > 0 ) { 2454 // IE 12 => return version number 2455 return parseInt( ua.substring( edge + 5, ua.indexOf( '.', edge ) ), 10 ); 2456 } 2457 2458 // other browser 2459 return false; 2460} 2461 2462 2463// smooth scrolling to anchors 2464$( function() { 2465 2466 var $header = $( '.site-header' ), 2467 headerHeight = parseInt( $header.outerHeight(), 10 ), 2468 $html = $( 'html' ); 2469 2470 $( '.site-header a[href*="#"]:not([href="#"])' ).click( function() { 2471 2472 var timeout = 0; 2473 2474 if ( $html.hasClass( 'navigation--is-visible' ) ) { 2475 $( 'body' ).css( 'overflow', '' ); 2476 $html.removeClass( 'navigation--is-visible' ); 2477 timeout = 600; 2478 } 2479 2480 2481 if ( location.pathname.replace( /^\//, '' ) == this.pathname.replace( /^\//, '' ) && location.hostname == this.hostname ) { 2482 var target = $( this.hash ); 2483 target = target.length ? target : $( '[name=' + this.hash.slice( 1 ) + ']' ); 2484 if ( target.length ) { 2485 setTimeout( function() { 2486 $( 'html,body' ).animate( { 2487 scrollTop: target.offset().top - headerHeight 2488 }, 1000 ); 2489 }, timeout ); 2490 return false; 2491 } 2492 } 2493 2494 } ); 2495} ); 2496 2497var ieVersion = getIEversion(); 2498var Rosa = {}; 2499 2500Rosa.Parallax = new Parallax( '[data-rellax]', { 2501 bleed: 60, 2502 container: '[data-rellax-container]' 2503} ); 2504 2505Rosa.Parallax.disabled = is_mobile || ieVersion && ieVersion < 12; 2506 2507// returns the depth of the element "e" relative to element with id=id 2508// for this calculation only parents with classname = waypoint are considered 2509function getLevelDepth(e, id, waypoint, cnt) { 2510 cnt = cnt || 0; 2511 if (e.id.indexOf(id) >= 0) return cnt; 2512 if ($(e).hasClass(waypoint)) { 2513 ++cnt; 2514 } 2515 return e.parentNode && getLevelDepth(e.parentNode, id, waypoint, cnt); 2516} 2517 2518// returns the closest element to 'e' that has class "classname" 2519function closest(e, classname) { 2520 if ($(e).hasClass(classname)) { 2521 return e; 2522 } 2523 return e.parentNode && closest(e.parentNode, classname); 2524} 2525 2526}) (jQuery, window);
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.