1/** 2 * Comment Likes - JavaScript 3 * 4 * This handles liking and unliking comments, as well as viewing who has 5 * liked a particular comment. 6 * 7 * @dependency Swipe (dynamically loaded when needed) 8 * 9 * @package Comment_Likes 10 * @subpackage JavaScript 11 */ 12(function () { 13 function init() { 14 let extWin; 15 let extWinCheck; 16 let commentLikeEvent; 17 18 // Only run once. 19 if (window.comment_likes_loaded) { 20 return; 21 } 22 window.comment_likes_loaded = true; 23 24 // Client-side cache of who liked a particular comment to avoid 25 // having to hit the server multiple times for the same data. 26 const commentLikeCache = {}; 27 28 let swipeLibPromise; 29 30 // Load the Swipe library, if it's not already loaded. 31 function swipeLibLoader() { 32 if (!swipeLibPromise) { 33 swipeLibPromise = new Promise((resolve, reject) => { 34 if (window.Swipe) { 35 resolve(window.Swipe); 36 } else { 37 const swipeScript = document.createElement('script'); 38 swipeScript.src = comment_like_text.swipeUrl; 39 swipeScript.async = true; 40 document.body.appendChild(swipeScript); 41 swipeScript.addEventListener('load', () => resolve(window.Swipe)); 42 swipeScript.addEventListener('error', error => reject(error)); 43 } 44 }); 45 } 46 return swipeLibPromise; 47 } 48 49 /** 50 * Parse the comment ID from a comment like link. 51 */ 52 function getCommentId(link) { 53 const commentId = 54 link && link.getAttribute('href') && link.getAttribute('href').split('like_comment='); 55 return commentId[1].split('&_wpnonce=')[0]; 56 } 57 58 /** 59 * Handle an ajax action on the comment like link. 60 */ 61 function handleLinkAction(link, action, commentId, callback) { 62 const nonce = 63 link && link.getAttribute('href') && link.getAttribute('href').split('_wpnonce=')[1]; 64 65 fetch('/wp-admin/admin-ajax.php', { 66 method: 'POST', 67 body: new URLSearchParams({ 68 action: action, 69 _wpnonce: nonce, 70 like_comment: commentId, 71 blog_id: Number(link.dataset.blog), 72 }), 73 headers: { 74 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', 75 'X-Requested-With': 'XMLHttpRequest', 76 Accept: 'application/json', 77 'cache-control': 'no-cache', 78 pragma: 'no-cache', 79 }, 80 }) 81 .then(response => response.json()) 82 .then(callback); 83 } 84 85 function startPolling() { 86 // Append cookie polling login iframe to this window to wait for user to finish logging in (or cancel) 87 const loginIframe = document.createElement('iframe'); 88 loginIframe.id = 'wp-login-polling-iframe'; 89 loginIframe.src = 'https://wordpress.com/public.api/connect/?iframe=true'; 90 document.body.appendChild(loginIframe); 91 loginIframe.style.display = 'none'; 92 } 93 94 function stopPolling() { 95 const iframe = document.querySelector('#wp-login-polling-iframe'); 96 if (iframe) { 97 iframe.remove(); 98 } 99 } 100 101 function hide(el) { 102 if (el && el.style) { 103 el.style.display = 'none'; 104 } 105 } 106 107 function show(el) { 108 if (el && el.style) { 109 el.style.removeProperty('display'); 110 } 111 } 112 113 // Overlay used for displaying comment like info. 114 class Overlay { 115 constructor() { 116 // Overlay element. 117 this.el = document.createElement('div'); 118 this.el.classList.add('comment-likes-overlay'); 119 document.body.appendChild(this.el); 120 hide(this.el); 121 122 this.el.addEventListener('mouseenter', () => { 123 // Don't hide the overlay if the user is mousing over it. 124 overlay.cancelHide(); 125 }); 126 127 this.el.addEventListener('mouseleave', () => overlay.requestHide()); 128 129 // Inner contents of overlay. 130 this.innerEl = null; 131 132 // Instance of the Swipe library. 133 this.swipe = null; 134 135 // Timeout used for hiding the overlay. 136 this.hideTimeout = null; 137 } 138 139 // Initialise the overlay for use, removing any old content. 140 clear() { 141 // Unload any previous instance of Swipe (to avoid leaking a global 142 // event handler). This is done before clearing the contents of the 143 // overlay because Swipe expects the slides to still be present. 144 if (this.swipe) { 145 this.swipe.kill(); 146 this.swipe = null; 147 } 148 this.el.innerHTML = ''; 149 this.innerEl = document.createElement('div'); 150 this.innerEl.classList.add('inner'); 151 this.el.appendChild(this.innerEl); 152 } 153 154 /** 155 * Construct a list (<ul>) of user (gravatar, name) details. 156 * 157 * @param data liker data returned from the server 158 * @param klass CSS class to apply to the <ul> element 159 * @param start index of user to start at 160 * @param length number of users to include in the list 161 * 162 * @return A container element with the list 163 */ 164 getUserBits(data, klass, start, length) { 165 start = start || 0; 166 let last = start + (length || data.length); 167 last = last > data.length ? data.length : last; 168 const container = document.createElement('div'); 169 container.classList.add('liker-list'); 170 let html = `<ul class="${klass || ''}">`; 171 for (let i = start; i < last; ++i) { 172 const user = data[i]; 173 html += ` 174 <li> 175 <a rel="nofollow" title="${user.display_name_esc}" href="${user.profile_url_esc}"> 176 <img src="${user.avatar_url_esc}" alt="${user.display_name_esc}" /> 177 <span class="user-name">${user.display_name_esc}</span> 178 </a> 179 </li> 180 `; 181 } 182 html += '</ul>'; 183 container.innerHTML = html; 184 return container; 185 } 186 187 /** 188 * Render the display of who has liked this comment. The type of 189 * display depends on how many people have liked the comment. 190 * If more than 10 people have liked the comment, this function 191 * renders navigation controls and sets up the Swipe library for 192 * changing between pages. 193 * 194 * @param link the element over which the user is hovering 195 * @param data the results retrieved from the server 196 */ 197 showLikes(link, data) { 198 this.clear(); 199 200 link.dataset.likeCount = data.length; 201 if (data.length === 0) { 202 // No likers after all. 203 hide(this.el); 204 return; 205 } 206 207 this.innerEl.style.padding = '12px'; 208 209 if (data.length < 6) { 210 // Only one column needed. 211 this.innerEl.style.maxWidth = '200px'; 212 this.innerEl.innerHTML = ''; 213 this.innerEl.appendChild(this.getUserBits(data, 'single')); 214 this.setPosition(link); 215 } else if (data.length < 11) { 216 // Two columns, but only one page. 217 this.innerEl.innerHTML = ''; 218 this.innerEl.appendChild(this.getUserBits(data, 'double')); 219 this.setPosition(link); 220 } else { 221 // Multiple pages. 222 this.renderLikesWithPagination(data, link); 223 } 224 } 225 226 /**
227 * Render multiple pages of likes with pagination controls. 228 * This function is intended to be called by `showLikes` above. 229 * 230 * @param data the results retrieved from the server 231 */ 232 renderLikesWithPagination(data, link) { 233 swipeLibLoader().then(() => { 234 const page_count = Math.ceil(data.length / 10); 235 // Swipe requires two nested containers. 236 const swipe = document.createElement('div'); 237 swipe.classList.add('swipe'); 238 this.innerEl.appendChild(swipe); 239 240 const wrap = document.createElement('div'); 241 wrap.classList.add('swipe-wrap'); 242 swipe.appendChild(wrap); 243 244 for (let i = 0; i < page_count; ++i) { 245 wrap.appendChild(this.getUserBits(data, 'double', i * 10, 10)); 246 } 247 248 /** 249 * Navigation controls. 250 * This is based on the Newdash controls found in 251 * reader/recommendations-templates.php 252 */ 253 const nav = document.createElement('nav'); 254 nav.classList.add('slider-nav'); 255 256 let navContents = ` 257 <a href="#" class="prev"> 258 <span class="noticon noticon-previous" title="Previous" alt="<"></span> 259 </a> 260 <span class="position"> 261 `; 262 for (let i = 0; i < page_count; ++i) { 263 navContents += `<em data-page="${i}" class="${i === 0 ? 'on' : ''}">•</em>`; 264 } 265 navContents += ` 266 </span> 267 <a href="#" class="next"> 268 <span class="noticon noticon-next" title="Next" alt=">"></span> 269 </a> 270 `; 271 this.innerEl.appendChild(nav); 272 nav.innerHTML = navContents; 273 274 /** Set up Swipe. **/ 275 // Swipe cannot be set up successfully unless its container 276 // is visible, so we show it now. 277 show(this.el); 278 this.setPosition(link); 279 280 this.swipe = new Swipe(swipe, { 281 callback: function (pos) { 282 // Update the pagination indicators. 283 // 284 // If there are exactly two pages, Swipe has a weird 285 // special case where it duplicates both pages and 286 // can return index 2 and 3 even though those aren't 287 // real pages (see swipe.js, line 47). To deal with 288 // this, we use the expression `pos % page_count`. 289 pos = pos % page_count; 290 nav.querySelectorAll('em').forEach(em => { 291 const page = Number(em.dataset.page); 292 em.setAttribute('class', pos === page ? 'on' : ''); 293 }); 294 }, 295 }); 296 297 nav.querySelectorAll('em').forEach(em => { 298 em.addEventListener('click', e => { 299 // Go to the page corresponding to the indicator clicked. 300 this.swipe.slide(Number(em.dataset.page)); 301 e.preventDefault(); 302 }); 303 }); 304 // Previous and next buttons. 305 nav.querySelector('.prev').addEventListener('click', e => { 306 this.swipe.prev(); 307 e.preventDefault(); 308 }); 309 nav.querySelector('.next').addEventListener('click', e => { 310 this.swipe.next(); 311 e.preventDefault(); 312 }); 313 }); 314 } 315 316 /** 317 * Open the overlay and show a loading message. 318 */ 319 showLoadingMessage(link) { 320 this.clear(); 321 this.innerEl.textContent = comment_like_text.loading; 322 this.setPosition(link); 323 } 324 325 /** 326 * Position the overlay near the current comment. 327 * 328 * @param link element near which to position the overlay 329 */ 330 setPosition(link) { 331 // Prepare a down arrow icon for the bottom of the overlay. 332 const icon = document.createElement('span'); 333 this.el.appendChild(icon); 334 icon.classList.add('icon', 'noticon', 'noticon-downarrow'); 335 icon.style.textShadow = '0px 1px 1px rgb(223, 223, 223)'; 336 337 const rect = link.getBoundingClientRect(); 338 const win = document.defaultView; 339 const offset = { 340 top: rect.top + win.scrollY, 341 left: rect.left + win.scrollX, 342 }; 343 344 // Take measurements with the element fully visible. 345 show(this.el); 346 let left = offset.left - (this.el.offsetWidth - link.offsetWidth) / 2; 347 left = left < 5 ? 5 : left; 348 let top = offset.top - this.el.offsetHeight + 5; 349 hide(this.el); 350 351 const adminBar = document.querySelector('#wpadminbar'); 352 353 // Check if the overlay would appear off the screen. 354 if (top < win.scrollY + ((adminBar && adminBar.offsetHeight) || 0)) { 355 // We'll display the overlay beneath the link instead. 356 top = offset.top + link.offsetHeight; 357 // Instead of using the down arrow icon, use an up arrow. 358 icon.remove(); 359 this.el.prepend(icon); 360 icon.classList.remove('noticon-downarrow'); 361 icon.classList.add('noticon-uparrow'); 362 icon.style.textShadow = '0px -1px 1px rgb(223, 223, 223)'; 363 icon.style.verticalAlign = 'bottom'; 364 } 365 366 this.el.style.left = `${left}px`; 367 this.el.style.top = `${top}px`; 368 show(this.el); 369 370 // The height of the arrow icon differs slightly between browsers, 371 // so we compute the margin here to make sure it isn't disjointed 372 // from the overlay. 373 icon.style.marginTop = `${icon.scrollHeight - 26}px`; 374 icon.style.marginBottom = `${20 - icon.scrollHeight}px`; 375 376 // Position the arrow to be horizontally centred on the link. 377 icon.style.paddingLeft = `${ 378 offset.left - left + (link.offsetWidth - icon.scrollWidth) / 2 379 }px`; 380 } 381 382 /** 383 * Return whether the overlay is visible. 384 */ 385 isVisible() { 386 return this.el.style.getPropertyValue('display') !== 'none'; 387 } 388 389 /** 390 * Request that the overlay be hidden after a short delay. 391 */ 392 requestHide() { 393 if (this.hideTimeout !== null) { 394 return; 395 } 396 this.hideTimeout = setTimeout(() => { 397 hide(this.el); 398 this.clear(); 399 }, 300); 400 } 401 402 /** 403 * Cancel a request to hide the overlay. 404 */ 405 cancelHide() { 406 if (this.hideTimeout !== null) { 407 clearTimeout(this.hideTimeout); 408 this.hideTimeout = null; 409 } 410 } 411 } 412 413 // Overlay used for displaying comment like info.
414 const overlay = new Overlay(); 415 416 // The most recent comment for which the user has requested to see 417 // who liked it. 418 var relevantComment; 419 420 // Precache after this timeout. 421 var precacheTimeout = null; 422 423 /** 424 * Fetch the like data for a particular comment. 425 */ 426 function fetchLikeData(link, commentId) { 427 commentLikeCache[commentId] = null; 428 429 const container = link && link.parentElement && link.parentElement.parentElement; 430 const star = container.querySelector('a.comment-like-link'); 431 star && 432 handleLinkAction(star, 'view_comment_likes', commentId, data => { 433 // Populate the cache. 434 commentLikeCache[commentId] = data; 435 436 // Only show the overlay if the user is interested. 437 if (overlay.isVisible() && relevantComment === commentId) { 438 overlay.showLikes(link, data); 439 } 440 }); 441 } 442 443 function readCookie(c) { 444 const nameEQ = c + '='; 445 const cookieStrings = document.cookie.split(';'); 446 447 for (let i = 0; i < cookieStrings.length; i++) { 448 let cookieString = cookieStrings[i]; 449 while (cookieString.charAt(0) === ' ') { 450 cookieString = cookieString.substring(1, cookieString.length); 451 } 452 if (cookieString.indexOf(nameEQ) === 0) { 453 const chunk = cookieString.substring(nameEQ.length, cookieString.length); 454 const pairs = chunk.split('&'); 455 const cookieData = {}; 456 for (let num = pairs.length - 1; num >= 0; num--) { 457 const pair = pairs[num].split('='); 458 cookieData[pair[0]] = decodeURIComponent(pair[1]); 459 } 460 return cookieData; 461 } 462 } 463 return null; 464 } 465 466 function getServiceData() { 467 const data = readCookie('wpc_wpc'); 468 if (data === null || typeof data.access_token === 'undefined' || !data.access_token) { 469 return false; 470 } 471 return data; 472 } 473 474 function readMessage(msg) { 475 const event = msg.data; 476 477 if (typeof event.event === 'undefined') { 478 return; 479 } 480 481 if (event.event === 'login' && event.success) { 482 extWinCheck = setInterval(function () { 483 if (!extWin || extWin.closed) { 484 clearInterval(extWinCheck); 485 if (getServiceData()) { 486 // Load page in an iframe to get the current comment nonce 487 const nonceIframe = document.createElement('iframe'); 488 nonceIframe.id = 'wp-login-comment-nonce-iframe'; 489 nonceIframe.style.display = 'none'; 490 nonceIframe.src = commentLikeEvent + ''; 491 document.body.appendChild(nonceIframe); 492 493 const commentLikeId = (commentLikeEvent + '') 494 .split('like_comment=')[1] 495 .split('&_wpnonce=')[0]; 496 let c; 497 498 // Set a 5 second timeout to redirect to the comment page without doing the Like as a fallback 499 const commentLikeTimeout = setTimeout(() => { 500 window.location = commentLikeEvent; 501 }, 5000); 502 503 // Check for a new nonced redirect and use that if available before timing out 504 const commentLikeCheck = setInterval(() => { 505 const iframe = document.querySelector('#wp-login-comment-nonce-iframe'); 506 if (iframe) { 507 c = iframe.querySelector(`#comment-like-${commentLikeId} .comment-like-link`); 508 } 509 if (c && typeof c.href !== 'undefined') { 510 clearTimeout(commentLikeTimeout); 511 clearInterval(commentLikeCheck); 512 window.location = c.href; 513 } 514 }, 100); 515 } 516 } 517 }, 100); 518 519 if (extWin) { 520 if (!extWin.closed) { 521 extWin.close(); 522 } 523 extWin = false; 524 } 525 526 stopPolling(); 527 } 528 } 529 530 if (typeof window.postMessage !== 'undefined') { 531 window.addEventListener('message', e => { 532 let message = e && e.data; 533 if (typeof message === 'string') { 534 try { 535 message = JSON.parse(message); 536 } catch (err) { 537 return; 538 } 539 } 540 541 const type = message && message.type; 542 if (type === 'loginMessage') { 543 readMessage(message); 544 } 545 }); 546 } 547 548 document.body.addEventListener('click', e => { 549 let target = e.target; 550 551 // Don't do anything when clicking on the "X people" link. 552 if (target.matches('p.comment-likes a.view-likers')) { 553 e.preventDefault(); 554 return; 555 } 556 557 // Retrieve the surrounding paragraph to the star, if it hasn't been liked. 558 const notLikedPar = target.closest('p.comment-not-liked'); 559 560 // Return if not clicking on star or surrounding paragraph. 561 if (!target.matches('a.comment-like-link') && !notLikedPar) { 562 return; 563 } 564 565 // When a comment hasn't been liked, make the text clickable, too. 566 if (notLikedPar) { 567 target = notLikedPar.querySelector('a.comment-like-link'); 568 if (!target) { 569 return; 570 } 571 } 572 573 if (target.classList.contains('needs-login')) { 574 e.preventDefault(); 575 commentLikeEvent = target; 576 if (extWin) { 577 if (!extWin.closed) { 578 extWin.close(); 579 } 580 extWin = false;
581 } 582 583 stopPolling(); 584 585 const url = 'https://wordpress.com/public.api/connect/?action=request&service=wordpress'; 586 extWin = window.open( 587 url, 588 'likeconn', 589 'status=0,toolbar=0,location=1,menubar=0,directories=0,resizable=1,scrollbars=1,height=560,width=500' 590 ); 591 592 startPolling(); 593 594 return false; 595 } 596 597 // Record that the user likes or does not like this comment. 598 const commentId = getCommentId(target); 599 target.classList.add('loading'); 600 601 let commentEl = document.querySelector(`p#comment-like-${commentId}`); 602 // Determine whether to like or unlike based on whether the comment is 603 // currently liked. 604 const action = 605 commentEl && commentEl.dataset.liked === 'comment-liked' 606 ? 'unlike_comment' 607 : 'like_comment'; 608 handleLinkAction(target, action, commentId, data => { 609 // Invalidate the like cache for this comment. 610 delete commentLikeCache[commentId]; 611 612 const countEl = document.querySelector(`#comment-like-count-${data.context}`); 613 if (countEl) { 614 countEl.innerHTML = data.display; 615 } 616 617 commentEl = document.querySelector(`p#comment-like-${data.context}`); 618 if (action === 'like_comment') { 619 commentEl.classList.remove('comment-not-liked'); 620 commentEl.classList.add('comment-liked'); 621 commentEl.dataset.liked = 'comment-liked'; 622 } else { 623 commentEl.classList.remove('comment-liked'); 624 commentEl.classList.add('comment-not-liked'); 625 commentEl.dataset.liked = 'comment-not-liked'; 626 } 627 628 // Prefetch new data for this comment (if there are likers left). 629 const parent = target.closest('.comment-likes'); 630 const link = parent && parent.querySelector('a.view-likers'); 631 if (link) { 632 fetchLikeData(link, commentId); 633 } 634 635 target.classList.remove('loading'); 636 }); 637 e.preventDefault(); 638 e.stopPropagation(); 639 }); 640 641 document.body.addEventListener( 642 'mouseenter', 643 function (e) { 644 if (!e.target.matches('p.comment-likes a.view-likers')) { 645 return; 646 } 647 // Show the user a list of who has liked this comment. 648 649 const link = e.target; 650 if (Number(link.dataset.likeCount || 0) === 0) { 651 // No one has liked this comment. 652 return; 653 } 654 655 // Don't hide the overlay. 656 overlay.cancelHide(); 657 658 // Get the comment ID. 659 const container = link.parentElement && link.parentElement.parentElement; 660 const star = container && container.querySelector('a.comment-like-link'); 661 const commentId = star && getCommentId(star); 662 relevantComment = commentId; 663 664 // Check if the list of likes for this comment is already in 665 // the cache. 666 if (commentId in commentLikeCache) { 667 const entry = commentLikeCache[commentId];
668 // Only display the likes if the ajax request is 669 // actually done. 670 if (entry !== null) { 671 overlay.showLikes(link, entry); 672 } else { 673 // Make sure the overlay is visible (in case 674 // the user moved the mouse away while loading 675 // but then came back before it finished 676 // loading). 677 overlay.showLoadingMessage(link); 678 } 679 return; 680 } 681 682 // Position the "Loading..." overlay. 683 overlay.showLoadingMessage(link); 684 685 // Fetch the data. 686 fetchLikeData(link, commentId); 687 }, 688 true 689 ); 690 691 document.body.addEventListener( 692 'mouseleave', 693 e => { 694 if (!e.target.matches('p.comment-likes a.view-likers')) { 695 return; 696 } 697 // User has moved cursor away - hide the overlay. 698 overlay.requestHide(); 699 }, 700 true 701 ); 702 703 document.body.addEventListener( 704 'mouseenter', 705 e => { 706 if (!e.target.matches('.comment') || !e.target.querySelector('a.comment-like-link')) { 707 return; 708 } 709 // User is moving over a comment - precache the comment like data.
710 if (precacheTimeout !== null) { 711 clearTimeout(precacheTimeout); 712 precacheTimeout = null; 713 } 714 715 const star = e.target.querySelector('a.comment-like-link'); 716 const parent = star.closest('.comment-likes'); 717 const link = parent && parent.querySelector('a.view-likers'); 718 if (!link || Number(link.dataset.likeCount || 0) === 0) { 719 // No likes. 720 return; 721 } 722 const commentId = getCommentId(star); 723 if (commentId in commentLikeCache) { 724 // Already in cache. 725 return; 726 } 727 728 precacheTimeout = setTimeout(() => { 729 precacheTimeout = null; 730 if (commentId in commentLikeCache) { 731 // Was cached in the interim. 732 return; 733 } 734 fetchLikeData(link, commentId); 735 }, 1000); 736 }, 737 true 738 ); 739 } 740 741 if (document.readyState !== 'loading') { 742 init(); 743 } else { 744 document.addEventListener('DOMContentLoaded', init); 745 } 746})(); 747; 748/*! 749 * imagesLoaded PACKAGED v3.1.8 750 * JavaScript is all like "You images are done yet or what?" 751 * MIT License 752 */ 753 754/*! 755 * EventEmitter v4.2.6 - git.io/ee 756 * Oliver Caldwell 757 * MIT license 758 * @preserve 759 */ 760 761( function () { 762 763 /** 764 * Class for managing events. 765 * Can be extended to provide event functionality in other classes. 766 * 767 * @class EventEmitter Manages event registering and emitting. 768 */ 769 function EventEmitter() {} 770 771 // Shortcuts to improve speed and size 772 var proto = EventEmitter.prototype; 773 var exports = this; 774 var originalGlobalValue = exports.EventEmitter; 775 776 /** 777 * Finds the index of the listener for the event in it's storage array. 778 * 779 * @param {Function[]} listeners Array of listeners to search through. 780 * @param {Function} listener Method to look for. 781 * @return {Number} Index of the specified listener, -1 if not found 782 * @api private 783 */ 784 function indexOfListener( listeners, listener ) { 785 var i = listeners.length; 786 while ( i-- ) { 787 if ( listeners[i].listener === listener ) { 788 return i; 789 } 790 } 791 792 return -1; 793 } 794 795 /** 796 * Alias a method while keeping the context correct, to allow for overwriting of target method. 797 * 798 * @param {String} name The name of the target method. 799 * @return {Function} The aliased method 800 * @api private 801 */ 802 function alias( name ) { 803 return function aliasClosure() { 804 return this[ name ].apply( this, arguments ); 805 }; 806 } 807 808 /** 809 * Returns the listener array for the specified event. 810 * Will initialise the event object and listener arrays if required. 811 * Will return an object if you use a regex search. The object contains keys for each matched event. So /ba[rz]/ might return an object c
vendor: 10,956 bytes, lines 811-1104
811ontaining bar and baz. But only if you have either defined them with defineEvent or added some listeners to them. 812 * Each property in the object response is an array of listener functions. 813 * 814 * @param {String|RegExp} evt Name of the event to return the listeners from. 815 * @return {Function[]|Object} All listener functions for the event. 816 */ 817 proto.getListeners = function getListeners( evt ) { 818 var events = this._getEvents(); 819 var response; 820 var key; 821 822 // Return a concatenated array of all matching events if 823 // the selector is a regular expression. 824 if ( typeof evt === 'object' ) { 825 response = {}; 826 for ( key in events ) { 827 if ( events.hasOwnProperty( key ) && evt.test( key ) ) { 828 response[ key ] = events[ key ]; 829 } 830 } 831 } 832 else { 833 response = events[ evt ] || ( events[ evt ] = [] ); 834 } 835 836 return response; 837 }; 838 839 /** 840 * Takes a list of listener objects and flattens it into a list of listener functions. 841 * 842 * @param {Object[]} listeners Raw listener objects. 843 * @return {Function[]} Just the listener functions. 844 */ 845 proto.flattenListeners = function flattenListeners( listeners ) { 846 var flatListeners = []; 847 var i; 848 849 for ( i = 0; i < listeners.length; i += 1 ) { 850 flatListeners.push( listeners[i].listener ); 851 } 852 853 return flatListeners; 854 }; 855 856 /** 857 * Fetches the requested listeners via getListeners but will always return the results inside an object. This is mainly for internal use but others may find it useful. 858 * 859 * @param {String|RegExp} evt Name of the event to return the listeners from. 860 * @return {Object} All listener functions for an event in an object. 861 */ 862 proto.getListenersAsObject = function getListenersAsObject( evt ) { 863 var listeners = this.getListeners( evt ); 864 var response; 865 866 if ( listeners instanceof Array ) { 867 response = {}; 868 response[ evt ] = listeners; 869 } 870 871 return response || listeners; 872 }; 873 874 /** 875 * Adds a listener function to the specified event. 876 * The listener will not be added if it is a duplicate. 877 * If the listener returns true then it will be removed after it is called. 878 * If you pass a regular expression as the event name then the listener will be added to all events that match it. 879 * 880 * @param {String|RegExp} evt Name of the event to attach the listener to. 881 * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling. 882 * @return {Object} Current instance of EventEmitter for chaining. 883 */ 884 proto.addListener = function addListener( evt, listener ) { 885 var listeners = this.getListenersAsObject( evt ); 886 var listenerIsWrapped = typeof listener === 'object'; 887 var key; 888 889 for ( key in listeners ) { 890 if ( listeners.hasOwnProperty( key ) && indexOfListener( listeners[ key ], listener ) === -1 ) { 891 listeners[ key ].push( listenerIsWrapped ? listener : { 892 listener: listener, 893 once: false 894 } ); 895 } 896 } 897 898 return this; 899 }; 900 901 /** 902 * Alias of addListener 903 */ 904 proto.on = alias( 'addListener' ); 905 906 /** 907 * Semi-alias of addListener. It will add a listener that will be 908 * automatically removed after it's first execution. 909 * 910 * @param {String|RegExp} evt Name of the event to attach the listener to. 911 * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling. 912 * @return {Object} Current instance of EventEmitter for chaining. 913 */ 914 proto.addOnceListener = function addOnceListener( evt, listener ) { 915 return this.addListener( evt, { 916 listener: listener, 917 once: true 918 } ); 919 }; 920 921 /** 922 * Alias of addOnceListener. 923 */ 924 proto.once = alias( 'addOnceListener' ); 925 926 /** 927 * Defines an event name. This is required if you want to use a regex to add a listener to multiple events at once. If you don't do this then how do you expect it to know what event to add to? Should it just add to every possible match for a regex? No. That is scary and bad. 928 * You need to tell it what event names should be matched by a regex. 929 * 930 * @param {String} evt Name of the event to create. 931 * @return {Object} Current instance of EventEmitter for chaining. 932 */ 933 proto.defineEvent = function defineEvent( evt ) { 934 this.getListeners( evt ); 935 return this; 936 }; 937 938 /** 939 * Uses defineEvent to define multiple events. 940 * 941 * @param {String[]} evts An array of event names to define. 942 * @return {Object} Current instance of EventEmitter for chaining. 943 */ 944 proto.defineEvents = function defineEvents( evts ) { 945 for ( var i = 0; i < evts.length; i += 1 ) { 946 this.defineEvent( evts[i] ); 947 } 948 return this; 949 }; 950 951 /** 952 * Removes a listener function from the specified event. 953 * When passed a regular expression as the event name, it will remove the listener from all events that match it. 954 * 955 * @param {String|RegExp} evt Name of the event to remove the listener from. 956 * @param {Function} listener Method to remove from the event. 957 * @return {Object} Current instance of EventEmitter for chaining. 958 */ 959 proto.removeListener = function removeListener( evt, listener ) { 960 var listeners = this.getListenersAsObject( evt ); 961 var index; 962 var key; 963 964 for ( key in listeners ) { 965 if ( listeners.hasOwnProperty( key ) ) { 966 index = indexOfListener( listeners[ key ], listener ); 967 968 if ( index !== -1 ) { 969 listeners[ key ].splice( index, 1 ); 970 } 971 } 972 } 973 974 return this; 975 }; 976 977 /** 978 * Alias of removeListener 979 */ 980 proto.off = alias( 'removeListener' ); 981 982 /** 983 * Adds listeners in bulk using the manipulateListeners method. 984 * If you pass an object as the second argument you can add to multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. You can also pass it an event name and an array of listeners to be added. 985 * You can also pass it a regular expression to add the array of listeners to all events that match it. 986 * Yeah, this function does quite a bit. That's probably a bad thing. 987 * 988 * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add to multiple events at once. 989 * @param {Function[]} [listeners] An optional array of listener functions to add. 990 * @return {Object} Current instance of EventEmitter for chaining. 991 */ 992 proto.addListeners = function addListeners( evt, listeners ) { 993 // Pass through to manipulateListeners 994 return this.manipulateListeners( false, evt, listeners ); 995 }; 996 997 /** 998 * Removes listeners in bulk using the manipulateListeners method. 999 * If you pass an object as the second argument you can remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. 1000 * You can also pass it an event name and an array of listeners to be removed. 1001 * You can also pass it a regular expression to remove the listeners from all events that match it. 1002 * 1003 * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to remove from multiple events at once. 1004 * @param {Function[]} [listeners] An optional array of listener functions to remove. 1005 * @return {Object} Current instance of EventEmitter for chaining. 1006 */ 1007 proto.removeListeners = function removeListeners( evt, listeners ) { 1008 // Pass through to manipulateListeners 1009 return this.manipulateListeners( true, evt, listeners ); 1010 }; 1011 1012 /** 1013 * Edits listeners in bulk. The addListeners and removeListeners methods both use this to do their job. You should really use those instead, this is a little lower level. 1014 * The first argument will determine if the listeners are removed (true) or added (false). 1015 * If you pass an object as the second argument you can add/remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. 1016 * You can also pass it an event name and an array of listeners to be added/removed. 1017 * You can also pass it a regular expression to manipulate the listeners of all events that match it. 1018 * 1019 * @param {Boolean} remove True if you want to remove listeners, false if you want to add. 1020 * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add/remove from multiple events at once. 1021 * @param {Function[]} [listeners] An optional array of listener functions to add/remove. 1022 * @return {Object} Current instance of EventEmitter for chaining. 1023 */ 1024 proto.manipulateListeners = function manipulateListeners( remove, evt, listeners ) { 1025 var i; 1026 var value; 1027 var single = remove ? this.removeListener : this.addListener; 1028 var multiple = remove ? this.removeListeners : this.addListeners; 1029 1030 // If evt is an object then pass each of it's properties to this method 1031 if ( typeof evt === 'object' && !( evt instanceof RegExp ) ) { 1032 for ( i in evt ) { 1033 if ( evt.hasOwnProperty(i) && ( value = evt[i] ) ) { 1034 // Pass the single listener straight through to the singular method 1035 if ( typeof value === 'function' ) { 1036 single.call( this, i, value ); 1037 } 1038 else { 1039 // Otherwise pass back to the multiple function 1040 multiple.call( this, i, value ); 1041 } 1042 } 1043 } 1044 } 1045 else { 1046 // So evt must be a string 1047 // And listeners must be an array of listeners 1048 // Loop over it and pass each one to the multiple method 1049 i = listeners.length; 1050 while (i--) { 1051 single.call( this, evt, listeners[i] ); 1052 } 1053 } 1054 1055 return this; 1056 }; 1057 1058 /** 1059 * Removes all listeners from a specified event. 1060 * If you do not specify an event then all listeners will be removed. 1061 * That means every event will be emptied. 1062 * You can also pass a regex to remove all events that match it. 1063 * 1064 * @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed. 1065 * @return {Object} Current instance of EventEmitter for chaining. 1066 */ 1067 proto.removeEvent = function removeEvent( evt ) { 1068 var type = typeof evt; 1069 var events = this._getEvents(); 1070 var key; 1071 1072 // Remove different things depending on the state of evt 1073 if ( type === 'string' ) { 1074 // Remove all listeners for the specified event 1075 delete events[ evt ]; 1076 } 1077 else if ( type === 'object' ) { 1078 // Remove all events matching the regex. 1079 for ( key in events ) { 1080 if ( events.hasOwnProperty( key ) && evt.test( key ) ) { 1081 delete events[ key ]; 1082 } 1083 } 1084 } 1085 else { 1086 // Remove all listeners in all events 1087 delete this._events; 1088 } 1089 1090 return this; 1091 }; 1092 1093 /** 1094 * Alias of removeEvent. 1095 * 1096 * Added to mirror the node API. 1097 */ 1098 proto.removeAllListeners = alias( 'removeEvent' ); 1099 1100 /** 1101 * Emits an event of your choice. 1102 * When emitted, every listener attached to that event will be executed. 1103 * If you pass the optional argument array then those arguments will be passed to every listener upon execution. 1104 * Because it uses `apply`, your array of arguments will be passed as if you wrote them out separately.
1105 * So they will not arrive within the array on the other side, they will be separate. 1106 * You can also pass a regular expression to emit to all events that match it. 1107 * 1108 * @param {String|RegExp} evt Name of the event to emit and execute listeners for. 1109 * @param {Array} [args] Optional array of arguments to be passed to each listener. 1110 * @return {Object} Current instance of EventEmitter for chaining. 1111 */ 1112 proto.emitEvent = function emitEvent( evt, args ) { 1113 var listeners = this.getListenersAsObject( evt ); 1114 var listener; 1115 var i; 1116 var key; 1117 var response; 1118 1119 for ( key in listeners ) { 1120 if ( listeners.hasOwnProperty( key ) ) { 1121 i = listeners[ key ].length; 1122 1123 while (i--) { 1124 // If the listener returns true then it shall be removed from the event 1125 // The function is executed either with a basic call or an apply if there is an args array 1126 listener = listeners[ key ][i]; 1127 1128 if ( listener.once === true ) { 1129 this.removeListener( evt, listener.listener ); 1130 } 1131 1132 response = listener.listener.apply( this, args || [] ); 1133 1134 if ( response === this._getOnceReturnValue() ) { 1135 this.removeListener( evt, listener.listener ); 1136 } 1137 } 1138 } 1139 } 1140 1141 return this; 1142 }; 1143 1144 /** 1145 * Alias of emitEvent 1146 */ 1147 proto.trigger = alias( 'emitEvent' ); 1148 1149 /** 1150 * Subtly different from emitEvent in that it will pass its arguments on to the listeners, as opposed to taking a single array of arguments to pass on. 1151 * As with emitEvent, you can pass a regex in place of the event name to emit to all events that match it. 1152 * 1153 * @param {String|RegExp} evt Name of the event to emit and execute listeners for. 1154 * @param {...*} Optional additional arguments to be passed to each listener. 1155 * @return {Object} Current instance of EventEmitter for chaining. 1156 */ 1157 proto.emit = function emit( evt ) { 1158 var args = Array.prototype.slice.call( arguments, 1 ); 1159 return this.emitEvent( evt, args ); 1160 }; 1161 1162 /** 1163 * Sets the current value to check against when executing listeners. If a 1164 * listeners return value matches the one set here then it will be removed 1165 * after execution. This value defaults to true. 1166 * 1167 * @param {*} value The new value to check for when executing listeners. 1168 * @return {Object} Current instance of EventEmitter for chaining. 1169 */ 1170 proto.setOnceReturnValue = function setOnceReturnValue( value ) { 1171 this._onceReturnValue = value; 1172 return this; 1173 }; 1174 1175 /** 1176 * Fetches the current value to check against when executing listeners. If 1177 * the listeners return value matches this one then it should be removed 1178 * automatically. It will return true by default. 1179 * 1180 * @return {*|Boolean} The current value to check for or the default, true. 1181 * @api private 1182 */ 1183 proto._getOnceReturnValue = function _getOnceReturnValue() { 1184 if ( this.hasOwnProperty( '_onceReturnValue' ) ) { 1185 return this._onceReturnValue; 1186 } 1187 else { 1188 return true; 1189 } 1190 }; 1191 1192 /** 1193 * Fetches the events object and creates one if required. 1194 * 1195 * @return {Object} The events storage object. 1196 * @api private 1197 */ 1198 proto._getEvents = function _getEvents() { 1199 return this._events || ( this._events = {} ); 1200 }; 1201 1202 /** 1203 * Reverts the global {@link EventEmitter} to its previous value and returns a reference to this version. 1204 * 1205 * @return {Function} Non conflicting EventEmitter class. 1206 */ 1207 EventEmitter.noConflict = function noConflict() { 1208 exports.EventEmitter = originalGlobalValue; 1209 return EventEmitter; 1210 }; 1211 1212 // Expose the class either via AMD, CommonJS or the global object 1213 if ( typeof define === 'function' && define.amd ) { 1214 define( 'eventEmitter/EventEmitter', [], function () { 1215 return EventEmitter; 1216 } ); 1217 } 1218 else if ( typeof module === 'object' && module.exports ) { 1219 module.exports = EventEmitter; 1220 } 1221 else { 1222 this.EventEmitter = EventEmitter; 1223 } 1224}.call( this ) ); 1225 1226/*! 1227 * eventie v1.0.4 1228 * event binding helper 1229 * eventie.bind( elem, 'click', myFn ) 1230 * eventie.unbind( elem, 'click', myFn ) 1231 */ 1232 1233/*jshint browser: true, undef: true, unused: true */ 1234/*global define: false */ 1235 1236( function( window ) { 1237 1238 var docElem = document.documentElement; 1239 1240 var bind = function() {}; 1241 1242 function getIEEvent( obj ) { 1243 var event = window.event; 1244 // add event.target 1245 event.target = event.target || event.srcElement || obj; 1246 return event; 1247 } 1248 1249 if ( docElem.addEventListener ) { 1250 bind = function( obj, type, fn ) { 1251 obj.addEventListener( type, fn, false ); 1252 }; 1253 } else if ( docElem.attachEvent ) { 1254 bind = function( obj, type, fn ) { 1255 obj[ type + fn ] = fn.handleEvent ? 1256 function() { 1257 var event = getIEEvent( obj ); 1258 fn.handleEvent.call( fn, event ); 1259 } : 1260 function() { 1261 var event = getIEEvent( obj ); 1262 fn.call( obj, event ); 1263 }; 1264 obj.attachEvent( "on" + type, obj[ type + fn ] ); 1265 }; 1266 } 1267 1268 var unbind = function() {}; 1269 1270 if ( docElem.removeEventListener ) { 1271 unbind = function( obj, type, fn ) { 1272 obj.removeEventListener( type, fn, false ); 1273 }; 1274 } else if ( docElem.detachEvent ) { 1275 unbind = function( obj, type, fn ) { 1276 obj.detachEvent( "on" + type, obj[ type + fn ] ); 1277 try { 1278 delete obj[ type + fn ]; 1279 } catch ( err ) { 1280 // can't delete window object properties 1281 obj[ type + fn ] = undefined; 1282 } 1283 }; 1284 } 1285 1286 var eventie = { 1287 bind: bind, 1288 unbind: unbind 1289 }; 1290 1291 // transport 1292 if ( typeof define === 'function' && define.amd ) { 1293 // AMD 1294 define( 'eventie/eventie',eventie ); 1295 } else { 1296 // browser global 1297 window.eventie = eventie; 1298 } 1299 1300} )( this ); 1301 1302/*! 1303 * imagesLoaded v3.1.8 1304 * JavaScript is all like "You images are done yet or what?" 1305 * MIT License 1306 */ 1307 1308( function( window, factory ) { 1309 // universal module definition 1310 1311 /*global define: false, module: false, require: false */ 1312 1313 if ( typeof define === 'function' && define.amd ) { 1314 // AMD 1315 define( [ 1316 'eventEmitter/EventEmitter', 1317 'eventie/eventie' 1318 ], function( EventEmitter, eventie ) { 1319 return factory( window, EventEmitter, eventie ); 1320 }); 1321 } else if ( typeof exports === 'object' ) { 1322 // CommonJS 1323 module.exports = factory( 1324 window, 1325 require('wolfy87-eventemitter'), 1326 require('eventie') 1327 ); 1328 } else { 1329 // browser global 1330 window.imagesLoaded = factory( 1331 window, 1332 window.EventEmitter, 1333 window.eventie 1334 ); 1335 } 1336 1337})( window, 1338 1339 // -------------------------- factory -------------------------- // 1340 1341 function factory( window, EventEmitter, eventie ) { 1342 1343 var $ = window.jQuery; 1344 var console = window.console; 1345 var hasConsole = typeof console !== 'undefined'; 1346 1347 // -------------------------- helpers -------------------------- // 1348 1349 // extend objects 1350 function extend( a, b ) { 1351 for ( var prop in b ) { 1352 a[ prop ] = b[ prop ]; 1353 } 1354 return a; 1355 } 1356 1357 var objToString = Object.prototype.toString; 1358 function isArray( obj ) { 1359 return objToString.call( obj ) === '[object Array]'; 1360 } 1361 1362 // turn element or nodeList into an array 1363 function makeArray( obj ) { 1364 var ary = []; 1365 if ( isArray( obj ) ) { 1366 // use object if already an array 1367 ary = obj; 1368 } else if ( typeof obj.length === 'number' ) { 1369 // convert nodeList to array 1370 for ( var i=0, len = obj.length; i < len; i++ ) { 1371 ary.push( obj[i] ); 1372 } 1373 } else { 1374 // array of single index 1375 ary.push( obj ); 1376 } 1377 return ary; 1378 } 1379 1380 // -------------------------- imagesLoaded -------------------------- // 1381 1382 /** 1383 * @param {Array, Element, NodeList, String} elem 1384 * @param {Object or Function} options - if function, use as callback 1385 * @param {Function} onAlways - callback function 1386 */ 1387 function ImagesLoaded( elem, options, onAlways ) { 1388 // coerce ImagesLoaded() without new, to be new ImagesLoaded() 1389 if ( !( this instanceof ImagesLoaded ) ) { 1390 return new ImagesLoaded( elem, options ); 1391 } 1392 // use elem as selector string 1393 if ( typeof elem === 'string' ) { 1394 elem = document.querySelectorAll( elem ); 1395 } 1396 1397 this.elements = makeArray( elem ); 1398 this.options = extend( {}, this.options ); 1399 1400 if ( typeof options === 'function' ) { 1401 onAlways = options; 1402 } else { 1403 extend( this.options, options ); 1404 } 1405 1406 if ( onAlways ) { 1407 this.on( 'always', onAlways ); 1408 } 1409 1410 this.getImages(); 1411 1412 if ( $ ) { 1413 // add jQuery Deferred object 1414 this.jqDeferred = new $.Deferred(); 1415 } 1416 1417 // HACK check async to allow time to bind listeners 1418 var _this = this; 1419 setTimeout( function() { 1420 _this.check(); 1421 }); 1422 } 1423 1424 ImagesLoaded.prototype = new EventEmitter(); 1425 1426 ImagesLoaded.prototype.options = {}; 1427 1428 ImagesLoaded.prototype.getImages = function() { 1429 this.images = []; 1430 1431 // filter & find items if we have an item selector 1432 for ( var i=0, len = this.elements.length; i < len; i++ ) { 1433 var elem = this.elements[i]; 1434 // filter siblings 1435 if ( elem.nodeName === 'IMG' ) { 1436 this.addImage( elem ); 1437 } 1438 // find children 1439 // no non-element nodes, #143 1440 var nodeType = elem.nodeType; 1441 if ( !nodeType || !( nodeType === 1 || nodeType === 9 || nodeType === 11 ) ) { 1442 continue; 1443 } 1444 var childElems = elem.querySelectorAll('img'); 1445 // concat childElems to filterFound array 1446 for ( var j=0, jLen = childElems.length; j < jLen; j++ ) { 1447 var img = childElems[j]; 1448 this.addImage( img ); 1449 } 1450 } 1451 }; 1452 1453 /** 1454 * @param {Image} img 1455 */ 1456 ImagesLoaded.prototype.addImage = function( img ) { 1457 var loadingImage = new LoadingImage( img ); 1458 this.images.push( loadingImage ); 1459 }; 1460
1461 ImagesLoaded.prototype.check = function() { 1462 var _this = this; 1463 var checkedCount = 0; 1464 var length = this.images.length; 1465 this.hasAnyBroken = false; 1466 // complete if no images 1467 if ( !length ) { 1468 this.complete(); 1469 return; 1470 } 1471 1472 function onConfirm( image, message ) { 1473 if ( _this.options.debug && hasConsole ) { 1474 console.log( 'confirm', image, message ); 1475 } 1476 1477 _this.progress( image ); 1478 checkedCount++; 1479 if ( checkedCount === length ) { 1480 _this.complete(); 1481 } 1482 return true; // bind once 1483 } 1484 1485 for ( var i=0; i < length; i++ ) { 1486 var loadingImage = this.images[i]; 1487 loadingImage.on( 'confirm', onConfirm ); 1488 loadingImage.check(); 1489 } 1490 }; 1491 1492 ImagesLoaded.prototype.progress = function( image ) { 1493 this.hasAnyBroken = this.hasAnyBroken || !image.isLoaded; 1494 // HACK - Chrome triggers event before object properties have changed. #83 1495 var _this = this; 1496 setTimeout( function() { 1497 _this.emit( 'progress', _this, image ); 1498 if ( _this.jqDeferred && _this.jqDeferred.notify ) { 1499 _this.jqDeferred.notify( _this, image ); 1500 } 1501 } ); 1502 }; 1503 1504 ImagesLoaded.prototype.complete = function() { 1505 var eventName = this.hasAnyBroken ? 'fail' : 'done'; 1506 this.isComplete = true; 1507 var _this = this; 1508 // HACK - another setTimeout so that confirm happens after progress 1509 setTimeout( function() { 1510 _this.emit( eventName, _this ); 1511 _this.emit( 'always', _this ); 1512 if ( _this.jqDeferred ) { 1513 var jqMethod = _this.hasAnyBroken ? 'reject' : 'resolve'; 1514 _this.jqDeferred[ jqMethod ]( _this ); 1515 } 1516 } ); 1517 }; 1518 1519 // -------------------------- jquery -------------------------- // 1520 1521 if ( $ ) { 1522 $.fn.imagesLoaded = function( options, callback ) { 1523 var instance = new ImagesLoaded( this, options, callback ); 1524 return instance.jqDeferred.promise( $(this) ); 1525 }; 1526 } 1527 1528 1529 // -------------------------- -------------------------- // 1530 1531 function LoadingImage( img ) { 1532 this.img = img; 1533 } 1534 1535 LoadingImage.prototype = new EventEmitter(); 1536 1537 LoadingImage.prototype.check = function() { 1538 // first check cached any previous images that have same src 1539 var resource = cache[ this.img.src ] || new Resource( this.img.src ); 1540 if ( resource.isConfirmed ) { 1541 this.confirm( resource.isLoaded, 'cached was confirmed' ); 1542 return; 1543 } 1544 1545 // If complete is true and browser supports natural sizes, 1546 // try to check for image status manually. 1547 if ( this.img.complete && this.img.naturalWidth !== undefined ) { 1548 // report based on naturalWidth 1549 this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' ); 1550 return; 1551 } 1552 1553 // If none of the checks above matched, simulate loading on detached element. 1554 var _this = this; 1555 resource.on( 'confirm', function( resrc, message ) { 1556 _this.confirm( resrc.isLoaded, message ); 1557 return true; 1558 } ); 1559 1560 resource.check(); 1561 }; 1562 1563 LoadingImage.prototype.confirm = function( isLoaded, message ) { 1564 this.isLoaded = isLoaded; 1565 this.emit( 'confirm', this, message ); 1566 }; 1567 1568 // -------------------------- Resource -------------------------- // 1569 1570 // Resource checks each src, only once 1571 // separate class from LoadingImage to prevent memory leaks. See #115 1572 1573 var cache = {}; 1574 1575 function Resource( src ) { 1576 this.src = src; 1577 // add to cache 1578 cache[ src ] = this; 1579 } 1580 1581 Resource.prototype = new EventEmitter(); 1582 1583 Resource.prototype.check = function() { 1584 // only trigger checking once 1585 if ( this.isChecked ) { 1586 return; 1587 } 1588 // simulate loading on detached element 1589 var proxyImage = new Image(); 1590 eventie.bind( proxyImage, 'load', this ); 1591 eventie.bind( proxyImage, 'error', this ); 1592 proxyImage.src = this.src; 1593 // set flag 1594 this.isChecked = true; 1595 }; 1596 1597 // ----- events ----- // 1598 1599 // trigger specified handler for event type 1600 Resource.prototype.handleEvent = function( event ) { 1601 var method = 'on' + event.type; 1602 if ( this[ method ] ) { 1603 this[ method ]( event ); 1604 } 1605 }; 1606 1607 Resource.prototype.onload = function( event ) { 1608 this.confirm( true, 'onload' ); 1609 this.unbindProxyEvents( event ); 1610 }; 1611 1612 Resource.prototype.onerror = function( event ) { 1613 this.confirm( false, 'onerror' ); 1614 this.unbindProxyEvents( event ); 1615 }; 1616 1617 // ----- confirm ----- // 1618 1619 Resource.prototype.confirm = function( isLoaded, message ) { 1620 this.isConfirmed = true; 1621 this.isLoaded = isLoaded;
vendor: 4,692 bytes, lines 1622-1742
1622 this.emit( 'confirm', this, message ); 1623 }; 1624 1625 Resource.prototype.unbindProxyEvents = function( event ) { 1626 eventie.unbind( event.target, 'load', this ); 1627 eventie.unbind( event.target, 'error', this ); 1628 }; 1629 1630 // ----- ----- // 1631 1632 return ImagesLoaded; 1633 1634} ); 1635; 1636/* 1637 * jQuery FlexSlider v2.2.2 1638 * http://www.woothemes.com/flexslider/ 1639 * 1640 * Copyright 2012 WooThemes 1641 * Free to use under the GPLv2 license. 1642 * http://www.gnu.org/licenses/gpl-2.0.html 1643 * 1644 * Contributing author: Tyler Smith (@mbmufffin) 1645 */ 1646 1647; 1648(function ($) { 1649 1650 //FlexSlider: Object Instance 1651 $.flexslider = function(el, options) { 1652 var slider = $(el); 1653 1654 // making variables public 1655 slider.vars = $.extend({}, $.flexslider.defaults, options); 1656 1657 var namespace = slider.vars.namespace, 1658 msGesture = window.navigator && window.navigator.msPointerEnabled && window.MSGesture, 1659 touch = (( "ontouchstart" in window ) || msGesture || window.DocumentTouch && document instanceof DocumentTouch) && slider.vars.touch, 1660 // depricating this idea, as devices are being released with both of these events 1661 //eventType = (touch) ? "touchend" : "click", 1662 eventType = "click touchend MSPointerUp", 1663 watchedEvent = "", 1664 watchedEventClearTimer, 1665 vertical = slider.vars.direction === "vertical", 1666 reverse = slider.vars.reverse, 1667 carousel = (slider.vars.itemWidth > 0), 1668 fade = slider.vars.animation === "fade", 1669 asNav = slider.vars.asNavFor !== "", 1670 methods = {}, 1671 focused = true; 1672 1673 // Store a reference to the slider object 1674 $.data(el, "flexslider", slider); 1675 1676 // Private slider methods 1677 methods = { 1678 init: function() { 1679 slider.animating = false; 1680 // Get current slide and make sure it is a number 1681 slider.currentSlide = parseInt( ( slider.vars.startAt ? slider.vars.startAt : 0), 10 ); 1682 if ( isNaN( slider.currentSlide ) ) slider.currentSlide = 0; 1683 slider.animatingTo = slider.currentSlide; 1684 slider.atEnd = (slider.currentSlide === 0 || slider.currentSlide === slider.last); 1685 slider.containerSelector = slider.vars.selector.substr(0,slider.vars.selector.search(' ')); 1686 slider.slides = $(slider.vars.selector, slider); 1687 slider.container = $(slider.containerSelector, slider); 1688 slider.count = slider.slides.length; 1689 // SYNC: 1690 slider.syncExists = $(slider.vars.sync).length > 0; 1691 // SLIDE: 1692 if (slider.vars.animation === "slide") slider.vars.animation = "swing"; 1693 slider.prop = (vertical) ? "top" : "marginLeft"; 1694 slider.args = {}; 1695 // SLIDESHOW: 1696 slider.manualPause = false; 1697 slider.stopped = false; 1698 //PAUSE WHEN INVISIBLE 1699 slider.started = false; 1700 slider.startTimeout = null; 1701 // TOUCH/USECSS: 1702 slider.transitions = !slider.vars.video && !fade && slider.vars.useCSS && (function() { 1703 var obj = document.createElement('div'), 1704 props = ['perspectiveProperty', 'WebkitPerspective', 'MozPerspective', 'OPerspective', 'msPerspective']; 1705 for (var i in props) { 1706 if ( obj.style[ props[i] ] !== undefined ) { 1707 slider.pfx = props[i].replace('Perspective','').toLowerCase(); 1708 slider.prop = "-" + slider.pfx + "-transform"; 1709 return true; 1710 } 1711 } 1712 return false; 1713 }()); 1714 // CONTROLSCONTAINER: 1715 if (slider.vars.controlsContainer !== "") slider.controlsContainer = $(slider.vars.controlsContainer).length > 0 && $(slider.vars.controlsContainer); 1716 // MANUAL: 1717 if (slider.vars.manualControls !== "") slider.manualControls = $(slider.vars.manualControls).length > 0 && $(slider.vars.manualControls); 1718 1719 // RANDOMIZE: 1720 if (slider.vars.randomize) { 1721 slider.slides.sort(function() { return (Math.round(Math.random())-0.5); }); 1722 slider.container.empty().append(slider.slides); 1723 } 1724 1725 slider.doMath(); 1726 1727 // INIT 1728 slider.setup("init"); 1729 1730 // CONTROLNAV: 1731 if (slider.vars.controlNav) methods.controlNav.setup(); 1732 1733 // DIRECTIONNAV: 1734 if (slider.vars.directionNav) methods.directionNav.setup(); 1735 1736 // KEYBOARD: 1737 if (slider.vars.keyboard && ($(slider.containerSelector).length === 1 || slider.vars.multipleKeyboard)) { 1738 $(document).bind('keyup', function(event) { 1739 var keycode = event.keyCode; 1740 if (!slider.animating && (keycode === 39 || keycode === 37)) { 1741 var target = (keycode === 39) ? slider.getTarget('next') : 1742 (keycode === 37) ? slider.getTarget('prev') : false;
1743 slider.flexAnimate(target, slider.vars.pauseOnAction); 1744 } 1745 }); 1746 } 1747 // MOUSEWHEEL: 1748 if (slider.vars.mousewheel) { 1749 slider.bind('mousewheel', function(event, delta, deltaX, deltaY) { 1750 event.preventDefault(); 1751 var target = (delta < 0) ? slider.getTarget('next') : slider.getTarget('prev'); 1752 slider.flexAnimate(target, slider.vars.pauseOnAction); 1753 }); 1754 } 1755 1756 // PAUSEPLAY 1757 if (slider.vars.pausePlay) methods.pausePlay.setup(); 1758 1759 //PAUSE WHEN INVISIBLE 1760 if (slider.vars.slideshow && slider.vars.pauseInvisible) methods.pauseInvisible.init(); 1761 1762 // SLIDSESHOW 1763 if (slider.vars.slideshow) { 1764 if (slider.vars.pauseOnHover) { 1765 slider.hover(function() { 1766 if (!slider.manualPlay && !slider.manualPause) slider.pause(); 1767 }, function() { 1768 if (!slider.manualPause && !slider.manualPlay && !slider.stopped) slider.play(); 1769 }); 1770 } 1771 // initialize animation 1772 //If we're visible, or we don't use PageVisibility API 1773 if(!slider.vars.pauseInvisible || !methods.pauseInvisible.isHidden()) { 1774 (slider.vars.initDelay > 0) ? slider.startTimeout = setTimeout(slider.play, slider.vars.initDelay) : slider.play(); 1775 } 1776 } 1777 1778 // ASNAV: 1779 if (asNav) methods.asNav.setup(); 1780 1781 // TOUCH 1782 if (touch && slider.vars.touch) methods.touch(); 1783 1784 // FADE&&SMOOTHHEIGHT || SLIDE: 1785 if (!fade || (fade && slider.vars.smoothHeight)) $(window).bind("resize orientationchange focus", methods.resize); 1786 1787 slider.find("img").attr("draggable", "false"); 1788 1789 // API: start() Callback 1790 setTimeout(function(){ 1791 slider.vars.start(slider); 1792 }, 200); 1793 }, 1794 asNav: { 1795 setup: function() { 1796 slider.asNav = true; 1797 slider.animatingTo = Math.floor(slider.currentSlide/slider.move); 1798 slider.currentItem = slider.currentSlide; 1799 slider.slides.removeClass(namespace + "active-slide").eq(slider.currentItem).addClass(namespace + "active-slide"); 1800 if(!msGesture){ 1801 slider.slides.on(eventType, function(e){ 1802 e.preventDefault(); 1803 var $slide = $(this), 1804 target = $slide.index(); 1805 var posFromLeft = $slide.offset().left - $(slider).scrollLeft(); // Find position of slide relative to left of slider container 1806 if( posFromLeft <= 0 && $slide.hasClass( namespace + 'active-slide' ) ) { 1807 slider.flexAnimate(slider.getTarget("prev"), true); 1808 } else if (!$(slider.vars.asNavFor).data('flexslider').animating && !$slide.hasClass(namespace + "active-slide")) { 1809 slider.direction = (slider.currentItem < target) ? "next" : "prev"; 1810 slider.flexAnimate(target, slider.vars.pauseOnAction, false, true, true); 1811 } 1812 }); 1813 }else{ 1814 el._slider = slider; 1815 slider.slides.each(function (){ 1816 var that = this; 1817 that._gesture = new MSGesture(); 1818 that._gesture.target = that; 1819 that.addEventListener("MSPointerDown", function (e){ 1820 e.preventDefault(); 1821 if(e.currentTarget._gesture) 1822 e.currentTarget._gesture.addPointer(e.pointerId); 1823 }, false); 1824 that.addEventListener("MSGestureTap", function (e){ 1825 e.preventDefault(); 1826 var $slide = $(this), 1827 target = $slide.index(); 1828 if (!$(slider.vars.asNavFor).data('flexslider').animating && !$slide.hasClass('active')) { 1829 slider.direction = (slider.currentItem < target) ? "next" : "prev"; 1830 slider.flexAnimate(target, slider.vars.pauseOnAction, false, true, true); 1831 } 1832 }); 1833 }); 1834 } 1835 } 1836 }, 1837 controlNav: { 1838 setup: function() { 1839 if (!slider.manualControls) {
1840 methods.controlNav.setupPaging(); 1841 } else { // MANUALCONTROLS: 1842 methods.controlNav.setupManual(); 1843 } 1844 }, 1845 setupPaging: function() { 1846 var type = (slider.vars.controlNav === "thumbnails") ? 'control-thumbs' : 'control-paging', 1847 j = 1, 1848 item, 1849 slide; 1850 1851 slider.controlNavScaffold = $('<ol class="'+ namespace + 'control-nav ' + namespace + type + '"></ol>'); 1852 1853 if (slider.pagingCount > 1) { 1854 for (var i = 0; i < slider.pagingCount; i++) { 1855 slide = slider.slides.eq(i); 1856 item = (slider.vars.controlNav === "thumbnails") ? '<img src="' + slide.attr( 'data-thumb' ) + '"/>' : '<a>' + j + '</a>'; 1857 if ( 'thumbnails' === slider.vars.controlNav && true === slider.vars.thumbCaptions ) { 1858 var captn = slide.attr( 'data-thumbcaption' ); 1859 if ( '' != captn && undefined != captn ) item += '<span class="' + namespace + 'caption">' + captn + '</span>'; 1860 } 1861 slider.controlNavScaffold.append('<li>' + item + '</li>'); 1862 j++; 1863 } 1864 } 1865 1866 // CONTROLSCONTAINER: 1867 (slider.controlsContainer) ? $(slider.controlsContainer).append(slider.controlNavScaffold) : slider.append(slider.controlNavScaffold); 1868 methods.controlNav.set(); 1869 1870 methods.controlNav.active(); 1871 1872 slider.controlNavScaffold.delegate('a, img', eventType, function(event) { 1873 event.preventDefault(); 1874 1875 if (watchedEvent === "" || watchedEvent === event.type) { 1876 var $this = $(this), 1877 target = slider.controlNav.index($this); 1878 1879 if (!$this.hasClass(namespace + 'active')) { 1880 slider.direction = (target > slider.currentSlide) ? "next" : "prev"; 1881 slider.flexAnimate(target, slider.vars.pauseOnAction); 1882 } 1883 } 1884 1885 // setup flags to prevent event duplication 1886 if (watchedEvent === "") { 1887 watchedEvent = event.type; 1888 } 1889 methods.setToClearWatchedEvent(); 1890 1891 }); 1892 }, 1893 setupManual: function() { 1894 slider.controlNav = slider.manualControls; 1895 methods.controlNav.active(); 1896 1897 slider.controlNav.bind(eventType, function(event) { 1898 event.preventDefault(); 1899 1900 if (watchedEvent === "" || watchedEvent === event.type) { 1901 var $this = $(this), 1902 target = slider.controlNav.index($this); 1903 1904 if (!$this.hasClass(namespace + 'active')) { 1905 (target > slider.currentSlide) ? slider.direction = "next" : slider.direction = "prev"; 1906 slider.flexAnimate(target, slider.vars.pauseOnAction); 1907 } 1908 } 1909 1910 // setup flags to prevent event duplication 1911 if (watchedEvent === "") { 1912 watchedEvent = event.type; 1913 } 1914 methods.setToClearWatchedEvent(); 1915 }); 1916 }, 1917 set: function() { 1918 var selector = (slider.vars.controlNav === "thumbnails") ? 'img' : 'a'; 1919 slider.controlNav = $('.' + namespace + 'control-nav li ' + selector, (slider.controlsContainer) ? slider.controlsContainer : slider); 1920 }, 1921 active: function() { 1922 slider.controlNav.removeClass(namespace + "active").eq(slider.animatingTo).addClass(namespace + "active"); 1923 }, 1924 update: function(action, pos) { 1925 if (slider.pagingCount > 1 && action === "add") { 1926 slider.controlNavScaffold.append($('<li><a>' + slider.count + '</a></li>')); 1927 } else if (slider.pagingCount === 1) { 1928 slider.controlNavScaffold.find('li').remove(); 1929 } else { 1930 slider.controlNav.eq(pos).closest('li').remove(); 1931 } 1932 methods.controlNav.set(); 1933 (slider.pagingCount > 1 && slider.pagingCount !== slider.controlNav.length) ? slider.update(pos, action) : methods.controlNav.active(); 1934 } 1935 }, 1936 directionNav: { 1937 setup: function() { 1938 var directionNavScaffold = $('<ul class="' + namespace + 'direction-nav"><li><a class="' + namespace + 'prev" href="#">
vendor: 9,047 bytes, lines 1938-2141
1938' + slider.vars.prevText + '</a></li><li><a class="' + namespace + 'next" href="#">' + slider.vars.nextText + '</a></li></ul>'); 1939 1940 // CONTROLSCONTAINER: 1941 if (slider.controlsContainer) { 1942 $(slider.controlsContainer).append(directionNavScaffold); 1943 slider.directionNav = $('.' + namespace + 'direction-nav li a', slider.controlsContainer); 1944 } else { 1945 slider.append(directionNavScaffold); 1946 slider.directionNav = $('.' + namespace + 'direction-nav li a', slider); 1947 } 1948 1949 methods.directionNav.update(); 1950 1951 slider.directionNav.bind(eventType, function(event) { 1952 event.preventDefault(); 1953 var target; 1954 1955 if (watchedEvent === "" || watchedEvent === event.type) { 1956 target = ($(this).hasClass(namespace + 'next')) ? slider.getTarget('next') : slider.getTarget('prev'); 1957 slider.flexAnimate(target, slider.vars.pauseOnAction); 1958 } 1959 1960 // setup flags to prevent event duplication 1961 if (watchedEvent === "") { 1962 watchedEvent = event.type; 1963 } 1964 methods.setToClearWatchedEvent(); 1965 }); 1966 }, 1967 update: function() { 1968 var disabledClass = namespace + 'disabled'; 1969 if (slider.pagingCount === 1) { 1970 slider.directionNav.addClass(disabledClass).attr('tabindex', '-1'); 1971 } else if (!slider.vars.animationLoop) { 1972 if (slider.animatingTo === 0) { 1973 slider.directionNav.removeClass(disabledClass).filter('.' + namespace + "prev").addClass(disabledClass).attr('tabindex', '-1'); 1974 } else if (slider.animatingTo === slider.last) { 1975 slider.directionNav.removeClass(disabledClass).filter('.' + namespace + "next").addClass(disabledClass).attr('tabindex', '-1'); 1976 } else { 1977 slider.directionNav.removeClass(disabledClass).removeAttr('tabindex'); 1978 } 1979 } else { 1980 slider.directionNav.removeClass(disabledClass).removeAttr('tabindex'); 1981 } 1982 } 1983 }, 1984 pausePlay: { 1985 setup: function() { 1986 var pausePlayScaffold = $('<div class="' + namespace + 'pauseplay"><a></a></div>'); 1987 1988 // CONTROLSCONTAINER: 1989 if (slider.controlsContainer) { 1990 slider.controlsContainer.append(pausePlayScaffold); 1991 slider.pausePlay = $('.' + namespace + 'pauseplay a', slider.controlsContainer); 1992 } else { 1993 slider.append(pausePlayScaffold); 1994 slider.pausePlay = $('.' + namespace + 'pauseplay a', slider); 1995 } 1996 1997 methods.pausePlay.update((slider.vars.slideshow) ? namespace + 'pause' : namespace + 'play'); 1998 1999 slider.pausePlay.bind(eventType, function(event) { 2000 event.preventDefault(); 2001 2002 if (watchedEvent === "" || watchedEvent === event.type) { 2003 if ($(this).hasClass(namespace + 'pause')) { 2004 slider.manualPause = true; 2005 slider.manualPlay = false; 2006 slider.pause(); 2007 } else { 2008 slider.manualPause = false; 2009 slider.manualPlay = true; 2010 slider.play(); 2011 } 2012 } 2013 2014 // setup flags to prevent event duplication 2015 if (watchedEvent === "") { 2016 watchedEvent = event.type; 2017 } 2018 methods.setToClearWatchedEvent(); 2019 }); 2020 }, 2021 update: function(state) { 2022 (state === "play") ? slider.pausePlay.removeClass(namespace + 'pause').addClass(namespace + 'play').html(slider.vars.playText) : slider.pausePlay.removeClass(namespace + 'play').addClass(namespace + 'pause').html(slider.vars.pauseText); 2023 } 2024 }, 2025 touch: function() { 2026 var startX, 2027 startY, 2028 offset, 2029 cwidth, 2030 dx, 2031 startT, 2032 scrolling = false, 2033 localX = 0, 2034 localY = 0, 2035 accDx = 0; 2036 2037 if(!msGesture){ 2038 el.addEventListener('touchstart', onTouchStart, false); 2039 2040 function onTouchStart(e) { 2041 if (slider.animating) { 2042 e.preventDefault(); 2043 } else if ( ( window.navigator.msPointerEnabled ) || e.touches.length === 1 ) { 2044 slider.pause(); 2045 // CAROUSEL: 2046 cwidth = (vertical) ? slider.h : slider. w; 2047 startT = Number(new Date()); 2048 // CAROUSEL: 2049 2050 // Local vars for X and Y points. 2051 localX = e.touches[0].pageX; 2052 localY = e.touches[0].pageY; 2053 2054 offset = (carousel && reverse && slider.animatingTo === slider.last) ? 0 : 2055 (carousel && reverse) ? slider.limit - (((slider.itemW + slider.vars.itemMargin) * slider.move) * slider.animatingTo) : 2056 (carousel && slider.currentSlide === slider.last) ? slider.limit : 2057 (carousel) ? ((slider.itemW + slider.vars.itemMargin) * slider.move) * slider.currentSlide : 2058 (reverse) ? (slider.last - slider.currentSlide + slider.cloneOffset) * cwidth : (slider.currentSlide + slider.cloneOffset) * cwidth; 2059 startX = (vertical) ? localY : localX; 2060 startY = (vertical) ? localX : localY; 2061 2062 el.addEventListener('touchmove', onTouchMove, false); 2063 el.addEventListener('touchend', onTouchEnd, false); 2064 } 2065 } 2066 2067 function onTouchMove(e) { 2068 // Local vars for X and Y points. 2069 2070 localX = e.touches[0].pageX; 2071 localY = e.touches[0].pageY; 2072 2073 dx = (vertical) ? startX - localY : startX - localX; 2074 scrolling = (vertical) ? (Math.abs(dx) < Math.abs(localX - startY)) : (Math.abs(dx) < Math.abs(localY - startY)); 2075 2076 var fxms = 500; 2077 2078 if ( ! scrolling || Number( new Date() ) - startT > fxms ) { 2079 e.preventDefault(); 2080 if (!fade && slider.transitions) { 2081 if (!slider.vars.animationLoop) { 2082 dx = dx/((slider.currentSlide === 0 && dx < 0 || slider.currentSlide === slider.last && dx > 0) ? (Math.abs(dx)/cwidth+2) : 1); 2083 } 2084 slider.setProps(offset + dx, "setTouch"); 2085 } 2086 } 2087 } 2088 2089 function onTouchEnd(e) { 2090 // finish the touch by undoing the touch session 2091 el.removeEventListener('touchmove', onTouchMove, false); 2092 2093 if (slider.animatingTo === slider.currentSlide && !scrolling && !(dx === null)) { 2094 var updateDx = (reverse) ? -dx : dx, 2095 target = (updateDx > 0) ? slider.getTarget('next') : slider.getTarget('prev'); 2096 2097 if (slider.canAdvance(target) && (Number(new Date()) - startT < 550 && Math.abs(updateDx) > 50 || Math.abs(updateDx) > cwidth/2)) { 2098 slider.flexAnimate(target, slider.vars.pauseOnAction); 2099 } else { 2100 if (!fade) slider.flexAnimate(slider.currentSlide, slider.vars.pauseOnAction, true); 2101 } 2102 } 2103 el.removeEventListener('touchend', onTouchEnd, false); 2104 2105 startX = null; 2106 startY = null; 2107 dx = null; 2108 offset = null; 2109 } 2110 }else{ 2111 el.style.msTouchAction = "none"; 2112 el._gesture = new MSGesture(); 2113 el._gesture.target = el; 2114 el.addEventListener("MSPointerDown", onMSPointerDown, false); 2115 el._slider = slider; 2116 el.addEventListener("MSGestureChange", onMSGestureChange, false); 2117 el.addEventListener("MSGestureEnd", onMSGestureEnd, false); 2118 2119 function onMSPointerDown(e){ 2120 e.stopPropagation(); 2121 if (slider.animating) { 2122 e.preventDefault(); 2123 }else{ 2124 slider.pause(); 2125 el._gesture.addPointer(e.pointerId); 2126 accDx = 0; 2127 cwidth = (vertical) ? slider.h : slider. w; 2128 startT = Number(new Date()); 2129 // CAROUSEL: 2130 2131 offset = (carousel && reverse && slider.animatingTo === slider.last) ? 0 : 2132 (carousel && reverse) ? slider.limit - (((slider.itemW + slider.vars.itemMargin) * slider.move) * slider.animatingTo) : 2133 (carousel && slider.currentSlide === slider.last) ? slider.limit : 2134 (carousel) ? ((slider.itemW + slider.vars.itemMargin) * slider.move) * slider.currentSlide : 2135 (reverse) ? (slider.last - slider.currentSlide + slider.cloneOffset) * cwidth : (slider.currentSlide + slider.cloneOffset) * cwidth; 2136 } 2137 } 2138 2139 function onMSGestureChange(e) { 2140 e.stopPropagation(); 2141 var slider = e.target._slider;
2142 if(!slider){ 2143 return; 2144 } 2145 var transX = -e.translationX, 2146 transY = -e.translationY; 2147 2148 //Accumulate translations. 2149 accDx = accDx + ((vertical) ? transY : transX); 2150 dx = accDx; 2151 scrolling = (vertical) ? (Math.abs(accDx) < Math.abs(-transX)) : (Math.abs(accDx) < Math.abs(-transY)); 2152 2153 if(e.detail === e.MSGESTURE_FLAG_INERTIA){ 2154 setImmediate(function (){ 2155 el._gesture.stop(); 2156 }); 2157 2158 return; 2159 } 2160 2161 if (!scrolling || Number(new Date()) - startT > 500) { 2162 e.preventDefault(); 2163 if (!fade && slider.transitions) { 2164 if (!slider.vars.animationLoop) { 2165 dx = accDx / ((slider.currentSlide === 0 && accDx < 0 || slider.currentSlide === slider.last && accDx > 0) ? (Math.abs(accDx) / cwidth + 2) : 1); 2166 } 2167 slider.setProps(offset + dx, "setTouch"); 2168 } 2169 } 2170 } 2171 2172 function onMSGestureEnd(e) { 2173 e.stopPropagation(); 2174 var slider = e.target._slider; 2175 if(!slider){ 2176 return; 2177 } 2178 if (slider.animatingTo === slider.currentSlide && !scrolling && !(dx === null)) { 2179 var updateDx = (reverse) ? -dx : dx, 2180 target = (updateDx > 0) ? slider.getTarget('next') : slider.getTarget('prev'); 2181 2182 if (slider.canAdvance(target) && (Number(new Date()) - startT < 550 && Math.abs(updateDx) > 50 || Math.abs(updateDx) > cwidth/2)) { 2183 slider.flexAnimate(target, slider.vars.pauseOnAction); 2184 } else { 2185 if (!fade) slider.flexAnimate(slider.currentSlide, slider.vars.pauseOnAction, true); 2186 } 2187 } 2188 2189 startX = null; 2190 startY = null; 2191 dx = null; 2192 offset = null; 2193 accDx = 0; 2194 } 2195 } 2196 }, 2197 resize: function() { 2198 if (!slider.animating && slider.is(':visible')) { 2199 if (!carousel) slider.doMath(); 2200 2201 if (fade) { 2202 // SMOOTH HEIGHT: 2203 methods.smoothHeight(); 2204 } else if (carousel) { //CAROUSEL: 2205 slider.slides.width(slider.computedW); 2206 slider.update(slider.pagingCount); 2207 slider.setProps(); 2208 } 2209 else if (vertical) { //VERTICAL: 2210 slider.viewport.height(slider.h); 2211 slider.setProps(slider.h, "setTotal"); 2212 } else { 2213 // SMOOTH HEIGHT: 2214 if (slider.vars.smoothHeight) methods.smoothHeight(); 2215 slider.newSlides.width(slider.computedW); 2216 slider.setProps(slider.computedW, "setTotal"); 2217 } 2218 } 2219 }, 2220 smoothHeight: function(dur) { 2221 if (!vertical || fade) { 2222 var $obj = (fade) ? slider : slider.viewport; 2223 (dur) ? $obj.animate({"height": slider.slides.eq(slider.animatingTo).height()}, dur) : $obj.height(slider.slides.eq(slider.animatingTo).height()); 2224 } 2225 }, 2226 sync: function(action) { 2227 var $obj = $(slider.vars.sync).data("flexslider"), 2228 target = slider.animatingTo; 2229 2230 switch (action) { 2231 case "animate": $obj.flexAnimate(target, slider.vars.pauseOnAction, false, true); break; 2232 case "play": if (!$obj.playing && !$obj.asNav) { $obj.play(); } break; 2233 case "pause": $obj.pause(); break; 2234 } 2235 }, 2236 uniqueID: function($clone) { 2237 $clone.find( '[id]' ).each(function() { 2238 var $this = $(this); 2239 $this.attr( 'id', $this.attr( 'id' ) + '_clone' ); 2240 }); 2241 return $clone; 2242 }, 2243 pauseInvisible: { 2244 visProp: null, 2245 init: function() { 2246 var prefixes = ['webkit','moz','ms','o']; 2247 2248 if ('hidden' in document) return 'hidden'; 2249 for (var i = 0; i < prefixes.length; i++) { 2250 if ((prefixes[i] + 'Hidden') in document) 2251 methods.pauseInvisible.visProp = prefixes[i] + 'Hidden'; 2252 } 2253 if (methods.pauseInvisible.visProp) { 2254 var evtname = methods.pauseInvisible.visProp.replace(/[H|h]idden/,'') + 'visibilitychange'; 2255 document.addEventListener(evtname, function() { 2256 if (methods.pauseInvisible.isHidden()) { 2257 if(slider.startTimeout) clearTimeout(slider.startTimeout); //If clock is ticking, stop timer and prevent from starting while invisible 2258 else slider.pause(); //Or just pause 2259 } 2260 else { 2261 if(slider.started) slider.play(); //Initiated before, just play 2262 else (slider.vars.initDelay > 0) ? setTimeout(slider.play, slider.vars.initDelay) : slider.play(); //Didn't init before: simply init or wait for it 2263 } 2264 }); 2265 } 2266 }, 2267 isHidden: function() { 2268 return document[methods.pauseInvisible.visProp] || false; 2269 } 2270 }, 2271 setToClearWatchedEvent: function() { 2272 clearTimeout(watchedEventClearTimer); 2273 watchedEventClearTimer = setTimeout(function() { 2274 watchedEvent = ""; 2275 }, 3000); 2276 } 2277 }; 2278 2279 // public methods 2280 slider.flexAnimate = function(target, pause, override, withSync, fromNav) { 2281 if (!slider.vars.animationLoop && target !== slider.currentSlide) { 2282 slider.direction = (target > slider.currentSlide) ? "next" : "prev"; 2283 } 2284 2285 if (asNav && slider.pagingCount === 1) slider.direction = (slider.currentItem < target) ? "next" : "prev"; 2286
vendor: 5,334 bytes, lines 2287-2399
2287 if (!slider.animating && (slider.canAdvance(target, fromNav) || override) && slider.is(":visible")) { 2288 if (asNav && withSync) { 2289 var master = $(slider.vars.asNavFor).data('flexslider'); 2290 slider.atEnd = target === 0 || target === slider.count - 1; 2291 master.flexAnimate(target, true, false, true, fromNav); 2292 slider.direction = (slider.currentItem < target) ? "next" : "prev"; 2293 master.direction = slider.direction; 2294 2295 if (Math.ceil((target + 1)/slider.visible) - 1 !== slider.currentSlide && target !== 0) { 2296 slider.currentItem = target; 2297 slider.slides.removeClass(namespace + "active-slide").eq(target).addClass(namespace + "active-slide"); 2298 target = Math.floor(target/slider.visible); 2299 } else { 2300 slider.currentItem = target; 2301 slider.slides.removeClass(namespace + "active-slide").eq(target).addClass(namespace + "active-slide"); 2302 return false; 2303 } 2304 } 2305 2306 slider.animating = true; 2307 slider.animatingTo = target; 2308 2309 // SLIDESHOW: 2310 if (pause) slider.pause(); 2311 2312 // API: before() animation Callback 2313 slider.vars.before(slider); 2314 2315 // SYNC: 2316 if (slider.syncExists && !fromNav) methods.sync("animate"); 2317 2318 // CONTROLNAV 2319 if (slider.vars.controlNav) methods.controlNav.active(); 2320 2321 // !CAROUSEL: 2322 // CANDIDATE: slide active class (for add/remove slide) 2323 if (!carousel) slider.slides.removeClass(namespace + 'active-slide').eq(target).addClass(namespace + 'active-slide'); 2324 2325 // INFINITE LOOP: 2326 // CANDIDATE: atEnd 2327 slider.atEnd = target === 0 || target === slider.last; 2328 2329 // DIRECTIONNAV: 2330 if (slider.vars.directionNav) methods.directionNav.update(); 2331 2332 if (target === slider.last) { 2333 // API: end() of cycle Callback 2334 slider.vars.end(slider); 2335 // SLIDESHOW && !INFINITE LOOP: 2336 if (!slider.vars.animationLoop) slider.pause(); 2337 } 2338 2339 // SLIDE: 2340 if (!fade) { 2341 var dimension = (vertical) ? slider.slides.filter(':first').height() : slider.computedW, 2342 margin, slideString, calcNext; 2343 2344 // INFINITE LOOP / REVERSE: 2345 if (carousel) { 2346 //margin = (slider.vars.itemWidth > slider.w) ? slider.vars.itemMargin * 2 : slider.vars.itemMargin; 2347 margin = slider.vars.itemMargin; 2348 calcNext = ((slider.itemW + margin) * slider.move) * slider.animatingTo; 2349 slideString = (calcNext > slider.limit && slider.visible !== 1) ? slider.limit : calcNext; 2350 } else if (slider.currentSlide === 0 && target === slider.count - 1 && slider.vars.animationLoop && slider.direction !== "next") { 2351 slideString = (reverse) ? (slider.count + slider.cloneOffset) * dimension : 0; 2352 } else if (slider.currentSlide === slider.last && target === 0 && slider.vars.animationLoop && slider.direction !== "prev") { 2353 slideString = (reverse) ? 0 : (slider.count + 1) * dimension; 2354 } else { 2355 slideString = (reverse) ? ((slider.count - 1) - target + slider.cloneOffset) * dimension : (target + slider.cloneOffset) * dimension; 2356 } 2357 slider.setProps(slideString, "", slider.vars.animationSpeed); 2358 if (slider.transitions) { 2359 if (!slider.vars.animationLoop || !slider.atEnd) { 2360 slider.animating = false; 2361 slider.currentSlide = slider.animatingTo; 2362 } 2363 slider.container.unbind("webkitTransitionEnd transitionend"); 2364 slider.container.bind("webkitTransitionEnd transitionend", function() { 2365 slider.wrapup(dimension); 2366 }); 2367 } else { 2368 slider.container.animate(slider.args, slider.vars.animationSpeed, slider.vars.easing, function(){ 2369 slider.wrapup(dimension); 2370 }); 2371 } 2372 } else { // FADE: 2373 if (!touch) { 2374 //slider.slides.eq(slider.currentSlide).fadeOut(slider.vars.animationSpeed, slider.vars.easing); 2375 //slider.slides.eq(target).fadeIn(slider.vars.animationSpeed, slider.vars.easing, slider.wrapup); 2376 2377 slider.slides.eq(slider.currentSlide).css({"zIndex": 1}).animate({"opacity": 0}, slider.vars.animationSpeed, slider.vars.easing); 2378 slider.slides.eq(target).css({"zIndex": 2}).animate({"opacity": 1}, slider.vars.animationSpeed, slider.vars.easing, slider.wrapup); 2379 2380 } else { 2381 slider.slides.eq(slider.currentSlide).css({ "opacity": 0, "zIndex": 1 }); 2382 slider.slides.eq(target).css({ "opacity": 1, "zIndex": 2 }); 2383 slider.wrapup(dimension); 2384 } 2385 } 2386 // SMOOTH HEIGHT: 2387 if (slider.vars.smoothHeight) methods.smoothHeight(slider.vars.animationSpeed); 2388 } 2389 }; 2390 slider.wrapup = function(dimension) { 2391 // SLIDE: 2392 if (!fade && !carousel) { 2393 if (slider.currentSlide === 0 && slider.animatingTo === slider.last && slider.vars.animationLoop) { 2394 slider.setProps(dimension, "jumpEnd"); 2395 } else if (slider.currentSlide === slider.last && slider.animatingTo === 0 && slider.vars.animationLoop) { 2396 slider.setProps(dimension, "jumpStart"); 2397 } 2398 } 2399 slider.animating = false;
2400 slider.currentSlide = slider.animatingTo; 2401 // API: after() animation Callback 2402 slider.vars.after(slider); 2403 }; 2404 2405 // SLIDESHOW: 2406 slider.animateSlides = function() { 2407 if (!slider.animating && focused ) slider.flexAnimate(slider.getTarget("next")); 2408 }; 2409 // SLIDESHOW: 2410 slider.pause = function() { 2411 clearInterval(slider.animatedSlides); 2412 slider.animatedSlides = null; 2413 slider.playing = false; 2414 // PAUSEPLAY: 2415 if (slider.vars.pausePlay) methods.pausePlay.update("play"); 2416 // SYNC: 2417 if (slider.syncExists) methods.sync("pause"); 2418 }; 2419 // SLIDESHOW: 2420 slider.play = function() { 2421 if (slider.playing) clearInterval(slider.animatedSlides); 2422 slider.animatedSlides = slider.animatedSlides || setInterval(slider.animateSlides, slider.vars.slideshowSpeed); 2423 slider.started = slider.playing = true; 2424 // PAUSEPLAY: 2425 if (slider.vars.pausePlay) methods.pausePlay.update("pause"); 2426 // SYNC: 2427 if (slider.syncExists) methods.sync("play"); 2428 }; 2429 // STOP: 2430 slider.stop = function () { 2431 slider.pause(); 2432 slider.stopped = true; 2433 }; 2434 slider.canAdvance = function(target, fromNav) { 2435 // ASNAV: 2436 var last = (asNav) ? slider.pagingCount - 1 : slider.last; 2437 return (fromNav) ? true : 2438 (asNav && slider.currentItem === slider.count - 1 && target === 0 && slider.direction === "prev") ? true : 2439 (asNav && slider.currentItem === 0 && target === slider.pagingCount - 1 && slider.direction !== "next") ? false : 2440 (target === slider.currentSlide && !asNav) ? false : 2441 (slider.vars.animationLoop) ? true : 2442 (slider.atEnd && slider.currentSlide === 0 && target === last && slider.direction !== "next") ? false : 2443 (slider.atEnd && slider.currentSlide === last && target === 0 && slider.direction === "next") ? false : 2444 true; 2445 }; 2446 slider.getTarget = function(dir) { 2447 slider.direction = dir; 2448 if (dir === "next") { 2449 return (slider.currentSlide === slider.last) ? 0 : slider.currentSlide + 1; 2450 } else { 2451 return (slider.currentSlide === 0) ? slider.last : slider.currentSlide - 1; 2452 } 2453 }; 2454 2455 // SLIDE: 2456 slider.setProps = function(pos, special, dur) { 2457 var target = (function() { 2458 var posCheck = (pos) ? pos : ((slider.itemW + slider.vars.itemMargin) * slider.move) * slider.animatingTo, 2459 posCalc = (function() { 2460 if (carousel) { 2461 return (special === "setTouch") ? pos : 2462 (reverse && slider.animatingTo === slider.last) ? 0 : 2463 (reverse) ? slider.limit - (((slider.itemW + slider.vars.itemMargin) * slider.move) * slider.animatingTo) : 2464 (slider.animatingTo === slider.last) ? slider.limit : posCheck; 2465 } else { 2466 switch (special) { 2467 case "setTotal": return (reverse) ? ((slider.count - 1) - slider.currentSlide + slider.cloneOffset) * pos : (slider.currentSlide + slider.cloneOffset) * pos; 2468 case "setTouch": return (reverse) ? pos : pos; 2469 case "jumpEnd": return (reverse) ? pos : slider.count * pos; 2470 case "jumpStart": return (reverse) ? slider.count * pos : pos; 2471 default: return pos; 2472 } 2473 } 2474 }()); 2475 2476 return (posCalc * -1) + "px"; 2477 }()); 2478 2479 if (slider.transitions) { 2480 target = (vertical) ? "translate3d(0," + target + ",0)" : "translate3d(" + target + ",0,0)"; 2481 dur = (dur !== undefined) ? (dur/1000) + "s" : "0s"; 2482 slider.container.css("-" + slider.pfx + "-transition-duration", dur); 2483 slider.container.css("transition-duration", dur); 2484 } 2485 2486 slider.args[slider.prop] = target; 2487 if (slider.transitions || dur === undefined) slider.container.css(slider.args); 2488 2489 slider.container.css('transform',target); 2490 }; 2491 2492 slider.setup = function(type) { 2493 // SLIDE: 2494 if (!fade) { 2495 var sliderOffset, arr; 2496 2497 if (type === "init") {
2498 slider.viewport = $('<div class="' + namespace + 'viewport"></div>').css({"overflow": "hidden", "position": "relative"}).appendTo(slider).append(slider.container); 2499 // INFINITE LOOP: 2500 slider.cloneCount = 0; 2501 slider.cloneOffset = 0; 2502 // REVERSE: 2503 if (reverse) { 2504 arr = $.makeArray(slider.slides).reverse(); 2505 slider.slides = $(arr); 2506 slider.container.empty().append(slider.slides); 2507 } 2508 } 2509 // INFINITE LOOP && !CAROUSEL: 2510 if (slider.vars.animationLoop && !carousel) { 2511 slider.cloneCount = 2; 2512 slider.cloneOffset = 1; 2513 // clear out old clones 2514 if (type !== "init") slider.container.find('.clone').remove(); 2515 slider.container.append(slider.slides.first().clone().addClass('clone').attr('aria-hidden', 'true')).prepend(slider.slides.last().clone().addClass('clone').attr('aria-hidden', 'true')); 2516 methods.uniqueID( slider.slides.first().clone().addClass('clone') ).appendTo( slider.container ); 2517 methods.uniqueID( slider.slides.last().clone().addClass('clone') ).prependTo( slider.container ); 2518 } 2519 slider.newSlides = $(slider.vars.selector, slider); 2520 2521 sliderOffset = (reverse) ? slider.count - 1 - slider.currentSlide + slider.cloneOffset : slider.currentSlide + slider.cloneOffset; 2522 // VERTICAL: 2523 if (vertical && !carousel) { 2524 slider.container.height((slider.count + slider.cloneCount) * 200 + "%").css("position", "absolute").width("100%"); 2525 setTimeout(function(){ 2526 slider.newSlides.css({"display": "block"}); 2527 slider.doMath(); 2528 slider.viewport.height(slider.h); 2529 slider.setProps(sliderOffset * slider.h, "init"); 2530 }, (type === "init") ? 100 : 0); 2531 } else { 2532 slider.container.width((slider.count + slider.cloneCount) * 200 + "%"); 2533 slider.setProps(sliderOffset * slider.computedW, "init"); 2534 setTimeout(function(){ 2535 slider.doMath(); 2536 slider.newSlides.css({"width": slider.computedW, "float": "left", "display": "block"}); 2537 // SMOOTH HEIGHT: 2538 if (slider.vars.smoothHeight) methods.smoothHeight(); 2539 }, (type === "init") ? 100 : 0); 2540 } 2541 } else { // FADE: 2542 slider.slides.css({"width": "100%", "float": "left", "marginRight": "-100%", "position": "relative"}); 2543 if (type === "init") { 2544 if (!touch) { 2545 //slider.slides.eq(slider.currentSlide).fadeIn(slider.vars.animationSpeed, slider.vars.easing); 2546 slider.slides.css({ "opacity": 0, "display": "block", "zIndex": 1 }).eq(slider.currentSlide).css({"zIndex": 2}).animate({"opacity": 1},slider.vars.animationSpeed,slider.vars.easing); 2547 } else { 2548 slider.slides.css({ "opacity": 0, "display": "block", "webkitTransition": "opacity " + slider.vars.animationSpeed / 1000 + "s ease", "zIndex": 1 }).eq(slider.currentSlide).css({ "opacity": 1, "zIndex": 2}); 2549 } 2550 } 2551 // SMOOTH HEIGHT: 2552 if (slider.vars.smoothHeight) methods.smoothHeight(); 2553 } 2554 // !CAROUSEL: 2555 // CANDIDATE: active slide 2556 if (!carousel) slider.slides.removeClass(namespace + "active-slide").eq(slider.currentSlide).addClass(namespace + "active-slide"); 2557 2558 //FlexSlider: init() Callback 2559 slider.vars.init(slider); 2560 }; 2561 2562 slider.doMath = function() { 2563 var slide = slider.slides.first(), 2564 slideMargin = slider.vars.itemMargin, 2565 minItems = slider.vars.minItems, 2566 maxItems = slider.vars.maxItems; 2567 2568 slider.w = (slider.viewport===undefined) ? slider.width() : slider.viewport.width(); 2569 slider.h = slide.height(); 2570 slider.boxPadding = slide.outerWidth() - slide.width(); 2571 2572 // CAROUSEL: 2573 if (carousel) { 2574 slider.itemT = slider.vars.itemWidth + slideMargin; 2575 slider.minW = (minItems) ? minItems * slider.itemT : slider.w; 2576 slider.maxW = (maxItems) ? (maxItems * slider.itemT) - slideMargin : slider.w; 2577 slider.itemW = (slider.minW > slider.w) ? (slider.w - (slideMargin * (minItems - 1)))/minItems : 2578 (slider.maxW < slider.w) ? (slider.w - (slideMargin * (maxItems - 1)))/maxItems : 2579 (slider.vars.itemWidth > slider.w) ? slider.w : slider.vars.itemWidth; 2580 2581 slider.visible = Math.floor(slider.w/(slider.itemW)); 2582 slider.move = (slider.vars.move > 0 && slider.vars.move < slider.visible ) ? slider.vars.move : slider.visible;
vendor: 5,363 bytes, lines 2583-2706
2583 slider.pagingCount = Math.ceil(((slider.count - slider.visible)/slider.move) + 1); 2584 slider.last = slider.pagingCount - 1; 2585 slider.limit = (slider.pagingCount === 1) ? 0 : 2586 (slider.vars.itemWidth > slider.w) ? (slider.itemW * (slider.count - 1)) + (slideMargin * (slider.count - 1)) : ((slider.itemW + slideMargin) * slider.count) - slider.w - slideMargin; 2587 } else { 2588 slider.itemW = slider.w; 2589 slider.pagingCount = slider.count; 2590 slider.last = slider.count - 1; 2591 } 2592 slider.computedW = slider.itemW - slider.boxPadding; 2593 }; 2594 2595 slider.update = function(pos, action) { 2596 slider.doMath(); 2597 2598 // update currentSlide and slider.animatingTo if necessary 2599 if (!carousel) { 2600 if (pos < slider.currentSlide) { 2601 slider.currentSlide += 1; 2602 } else if (pos <= slider.currentSlide && pos !== 0) { 2603 slider.currentSlide -= 1; 2604 } 2605 slider.animatingTo = slider.currentSlide; 2606 } 2607 2608 // update controlNav 2609 if (slider.vars.controlNav && !slider.manualControls) { 2610 if ((action === "add" && !carousel) || slider.pagingCount > slider.controlNav.length) { 2611 methods.controlNav.update("add"); 2612 } else if ((action === "remove" && !carousel) || slider.pagingCount < slider.controlNav.length) { 2613 if (carousel && slider.currentSlide > slider.last) { 2614 slider.currentSlide -= 1; 2615 slider.animatingTo -= 1; 2616 } 2617 methods.controlNav.update("remove", slider.last); 2618 } 2619 } 2620 // update directionNav 2621 if (slider.vars.directionNav) methods.directionNav.update(); 2622 2623 }; 2624 2625 slider.addSlide = function(obj, pos) { 2626 var $obj = $(obj); 2627 2628 slider.count += 1; 2629 slider.last = slider.count - 1; 2630 2631 // append new slide 2632 if (vertical && reverse) { 2633 (pos !== undefined) ? slider.slides.eq(slider.count - pos).after($obj) : slider.container.prepend($obj); 2634 } else { 2635 (pos !== undefined) ? slider.slides.eq(pos).before($obj) : slider.container.append($obj); 2636 } 2637 2638 // update currentSlide, animatingTo, controlNav, and directionNav 2639 slider.update(pos, "add"); 2640 2641 // update slider.slides 2642 slider.slides = $(slider.vars.selector + ':not(.clone)', slider); 2643 // re-setup the slider to accomdate new slide 2644 slider.setup(); 2645 2646 //FlexSlider: added() Callback 2647 slider.vars.added(slider); 2648 }; 2649 slider.removeSlide = function(obj) { 2650 var pos = (isNaN(obj)) ? slider.slides.index($(obj)) : obj; 2651 2652 // update count 2653 slider.count -= 1; 2654 slider.last = slider.count - 1; 2655 2656 // remove slide 2657 if (isNaN(obj)) { 2658 $(obj, slider.slides).remove(); 2659 } else { 2660 (vertical && reverse) ? slider.slides.eq(slider.last).remove() : slider.slides.eq(obj).remove(); 2661 } 2662 2663 // update currentSlide, animatingTo, controlNav, and directionNav 2664 slider.doMath(); 2665 slider.update(pos, "remove"); 2666 2667 // update slider.slides 2668 slider.slides = $(slider.vars.selector + ':not(.clone)', slider); 2669 // re-setup the slider to accomdate new slide 2670 slider.setup(); 2671 2672 // FlexSlider: removed() Callback 2673 slider.vars.removed(slider); 2674 }; 2675 2676 //FlexSlider: Initialize 2677 methods.init(); 2678 }; 2679 2680 // Ensure the slider isn't focussed if the window loses focus. 2681 $( window ).blur( function ( e ) { 2682 focused = false; 2683 }).focus( function ( e ) { 2684 focused = true; 2685 }); 2686 2687 //FlexSlider: Default Settings 2688 $.flexslider.defaults = { 2689 namespace: "flex-", //{NEW} String: Prefix string attached to the class of every element generated by the plugin 2690 selector: ".slides > li", //{NEW} Selector: Must match a simple pattern. '{container} > {slide}' -- Ignore pattern at your own peril 2691 animation: "fade", //String: Select your animation type, "fade" or "slide" 2692 easing: "swing", //{NEW} String: Determines the easing method used in jQuery transitions. jQuery easing plugin is supported! 2693 direction: "horizontal", //String: Select the sliding direction, "horizontal" or "vertical" 2694 reverse: false, //{NEW} Boolean: Reverse the animation direction 2695 animationLoop: true, //Boolean: Should the animation loop? If false, directionNav will received "disable" classes at either end 2696 smoothHeight: false, //{NEW} Boolean: Allow height of the slider to animate smoothly in horizontal mode 2697 startAt: 0, //Integer: The slide that the slider should start on. Array notation (0 = first slide) 2698 slideshow: true, //Boolean: Animate slider automatically 2699 slideshowSpeed: 7000, //Integer: Set the speed of the slideshow cycling, in milliseconds 2700 animationSpeed: 600, //Integer: Set the speed of animations, in milliseconds 2701 initDelay: 0, //{NEW} Integer: Set an initialization delay, in milliseconds 2702 randomize: false, //Boolean: Randomize slide order 2703 thumbCaptions: false, //Boolean: Whether or not to put captions on thumbnails when using the "thumbnails" controlNav. 2704 2705 // Usability features 2706 pauseOnAction: true, //Boolean: Pause the slideshow when interacting with control elements, highly recommended.
2707 pauseOnHover: false, //Boolean: Pause the slideshow when hovering over slider, then resume when no longer hovering 2708 pauseInvisible: true, //{NEW} Boolean: Pause the slideshow when tab is invisible, resume when visible. Provides better UX, lower CPU usage. 2709 useCSS: true, //{NEW} Boolean: Slider will use CSS3 transitions if available 2710 touch: true, //{NEW} Boolean: Allow touch swipe navigation of the slider on touch-enabled devices 2711 video: false, //{NEW} Boolean: If using video in the slider, will prevent CSS3 3D Transforms to avoid graphical glitches 2712 2713 // Primary Controls 2714 controlNav: true, //Boolean: Create navigation for paging control of each clide? Note: Leave true for manualControls usage 2715 directionNav: true, //Boolean: Create navigation for previous/next navigation? (true/false) 2716 prevText: "Previous", //String: Set the text for the "previous" directionNav item 2717 nextText: "Next", //String: Set the text for the "next" directionNav item 2718 2719 // Secondary Navigation 2720 keyboard: true, //Boolean: Allow slider navigating via keyboard left/right keys 2721 multipleKeyboard: false, //{NEW} Boolean: Allow keyboard navigation to affect multiple sliders. Default behavior cuts out keyboard navigation with more than one slider present. 2722 mousewheel: false, //{UPDATED} Boolean: Requires jquery.mousewheel.js (https://github.com/brandonaaron/jquery-mousewheel) - Allows slider navigating via mousewheel 2723 pausePlay: false, //Boolean: Create pause/play dynamic element 2724 pauseText: "Pause", //String: Set the text for the "pause" pausePlay item 2725 playText: "Play", //String: Set the text for the "play" pausePlay item 2726 2727 // Special properties 2728 controlsContainer: "", //{UPDATED} jQuery Object/Selector: Declare which container the navigation elements should be appended too. Default container is the FlexSlider element. Example use would be $(".flexslider-container"). Property is ignored if given element is not found. 2729 manualControls: "", //{UPDATED} jQuery Object/Selector: Declare custom control navigation. Examples would be $(".flex-control-nav li") or "#tabs-nav li img", etc. The number of elements in your controlNav should match the number of slides/tabs. 2730 sync: "", //{NEW} Selector: Mirror the actions performed on this slider with another slider. Use with care. 2731 asNavFor: "", //{NEW} Selector: Internal property exposed for turning the slider into a thumbnail navigation for another slider 2732 2733 // Carousel Options 2734 itemWidth: 0, //{NEW} Integer: Box-model width of individual carousel items, including horizontal borders and padding. 2735 itemMargin: 0, //{NEW} Integer: Margin between carousel items. 2736 minItems: 1, //{NEW} Integer: Minimum number of carousel items that should be visible. Items will resize fluidly when below this. 2737 maxItems: 0, //{NEW} Integer: Maxmimum number of carousel items that should be visible. Items will resize fluidly when above this limit. 2738 move: 0, //{NEW} Integer: Number of carousel items that should move on animation. If 0, slider will move all visible items. 2739 allowOneSlide: true, //{NEW} Boolean: Whether or not to allow a slider comprised of a single slide 2740 2741 // Callback API 2742 start: function(){}, //Callback: function(slider) - Fires when the slider loads the first slide 2743 before: function(){}, //Callback: function(slider) - Fires asynchronously with each slider animation 2744 after: function(){}, //Callback: function(slider) - Fires after each slider animation completes 2745 end: function(){}, //Callback: function(slider) - Fires when the slider reaches the last slide (asynchronous) 2746 added: function(){}, //{NEW} Callback: function(slider) - Fires after a slide is added 2747 removed: function(){}, //{NEW} Callback: function(slider) - Fires after a slide is removed 2748 init: function() {} //{NEW}
2748 Callback: function(slider) - Fires after the slider is initially setup 2749 }; 2750 2751 //FlexSlider: Plugin Function 2752 $.fn.flexslider = function(options) { 2753 if (options === undefined) options = {}; 2754 2755 if (typeof options === "object") { 2756 return this.each(function() { 2757 var $this = $(this), 2758 selector = (options.selector) ? options.selector : ".slides > li", 2759 $slides = $this.find(selector); 2760 2761 if ( ( $slides.length === 1 && options.allowOneSlide === true ) || $slides.length === 0 ) { 2762 $slides.fadeIn(400); 2763 if (options.start) options.start($this); 2764 } else if ($this.data('flexslider') === undefined) { 2765 new $.flexslider(this, options); 2766 } 2767 }); 2768 } else { 2769 // Helper strings to quickly perform functions on the slider 2770 var $slider = $(this).data('flexslider'); 2771 switch (options) { 2772 case "play": $slider.play(); break; 2773 case "pause": $slider.pause(); break; 2774 case "stop": $slider.stop(); break; 2775 case "next": $slider.flexAnimate($slider.getTarget("next"), true); break; 2776 case "prev": 2777 case "previous": $slider.flexAnimate($slider.getTarget("prev"), true); break; 2778 default: if (typeof options === "number") $slider.flexAnimate(options, true); 2779 } 2780 } 2781 }; 2782})(jQuery); 2783; 2784/*! This file is auto-generated */ 2785/*! 2786 * imagesLoaded PACKAGED v5.0.0 2787 * JavaScript is all like "You images are done yet or what?" 2788 * MIT License 2789 */ 2790!function(t,e){"object"==typeof module&&module.exports?module.exports=e():t.EvEmitter=e()}("undefined"!=typeof window?window:this,(function(){function t(){}let e=t.prototype;return e.on=function(t,e){if(!t||!e)return this;let i=this._events=this._events||{},s=i[t]=i[t]||[];return s.includes(e)||s.push(e),this},e.once=function(t,e){if(!t||!e)return this;this.on(t,e);let i=this._onceEvents=this._onceEvents||{};return(i[t]=i[t]||{})[e]=!0,this},e.off=function(t,e){let i=this._events&&this._events[t];if(!i||!i.length)return this;let s=i.indexOf(e);return-1!=s&&i.splice(s,1),this},e.emitEvent=function(t,e){let i=this._events&&this._events[t];if(!i||!i.length)return this;i=i.slice(0),e=e||[];let s=this._onceEvents&&this._onceEvents[t];for(let n of i){s&&s[n]&&(this.off(t,n),delete s[n]),n.apply(this,e)}return this},e.allOff=function(){return delete this._events,delete this._onceEvents,this},t})), 2791/*! 2792 * imagesLoaded v5.0.0 2793 * JavaScript is all like "You images are done yet or what?" 2794 * MIT License 2795 */ 2796function(t,e){"object"==typeof module&&module.exports?module.exports=e(t,require("ev-emitter")):t.imagesLoaded=e(t,t.EvEmitter)}("undefined"!=typeof window?window:this,(function(t,e){let i=t.jQuery,s=t.console;
vendor: 4,185 bytes, lines 2796-2797
2796function n(t,e,o){if(!(this instanceof n))return new n(t,e,o);let r=t;var h;("string"==typeof t&&(r=document.querySelectorAll(t)),r)?(this.elements=(h=r,Array.isArray(h)?h:"object"==typeof h&&"number"==typeof h.length?[...h]:[h]),this.options={},"function"==typeof e?o=e:Object.assign(this.options,e),o&&this.on("always",o),this.getImages(),i&&(this.jqDeferred=new i.Deferred),setTimeout(this.check.bind(this))):s.error(`Bad element for imagesLoaded ${r||t}`)}n.prototype=Object.create(e.prototype),n.prototype.getImages=function(){this.images=[],this.elements.forEach(this.addElementImages,this)};const o=[1,9,11];n.prototype.addElementImages=function(t){"IMG"===t.nodeName&&this.addImage(t),!0===this.options.background&&this.addElementBackgroundImages(t);let{nodeType:e}=t;if(!e||!o.includes(e))return;let i=t.querySelectorAll("img");for(let t of i)this.addImage(t);if("string"==typeof this.options.background){let e=t.querySelectorAll(this.options.background);for(let t of e)this.addElementBackgroundImages(t)}};const r=/url\((['"])?(.*?)\1\)/gi;function h(t){this.img=t}function d(t,e){this.url=t,this.element=e,this.img=new Image}return n.prototype.addElementBackgroundImages=function(t){let e=getComputedStyle(t);if(!e)return;let i=r.exec(e.backgroundImage);for(;null!==i;){let s=i&&i[2];s&&this.addBackground(s,t),i=r.exec(e.backgroundImage)}},n.prototype.addImage=function(t){let e=new h(t);this.images.push(e)},n.prototype.addBackground=function(t,e){let i=new d(t,e);this.images.push(i)},n.prototype.check=function(){if(this.progressedCount=0,this.hasAnyBroken=!1,!this.images.length)return void this.complete();let t=(t,e,i)=>{setTimeout((()=>{this.progress(t,e,i)}))};this.images.forEach((function(e){e.once("progress",t),e.check()}))},n.prototype.progress=function(t,e,i){this.progressedCount++,this.hasAnyBroken=this.hasAnyBroken||!t.isLoaded,this.emitEvent("progress",[this,t,e]),this.jqDeferred&&this.jqDeferred.notify&&this.jqDeferred.notify(this,t),this.progressedCount===this.images.length&&this.complete(),this.options.debug&&s&&s.log(`progress: ${i}`,t,e)},n.prototype.complete=function(){let t=this.hasAnyBroken?"fail":"done";if(this.isComplete=!0,this.emitEvent(t,[this]),this.emitEvent("always",[this]),this.jqDeferred){let t=this.hasAnyBroken?"reject":"resolve";this.jqDeferred[t](this)}},h.prototype=Object.create(e.prototype),h.prototype.check=function(){this.getIsImageComplete()?this.confirm(0!==this.img.naturalWidth,"naturalWidth"):(this.proxyImage=new Image,this.img.crossOrigin&&(this.proxyImage.crossOrigin=this.img.crossOrigin),this.proxyImage.addEventListener("load",this),this.proxyImage.addEventListener("error",this),this.img.addEventListener("load",this),this.img.addEventListener("error",this),this.proxyImage.src=this.img.currentSrc||this.img.src)},h.prototype.getIsImageComplete=function(){return this.img.complete&&this.img.naturalWidth},h.prototype.confirm=function(t,e){this.isLoaded=t;let{parentNode:i}=this.img,s="PICTURE"===i.nodeName?i:this.img;this.emitEvent("progress",[this,s,e])},h.prototype.handleEvent=function(t){let e="on"+t.type;this[e]&&this[e](t)},h.prototype.onload=function(){this.confirm(!0,"onload"),this.unbindEvents()},h.prototype.onerror=function(){this.confirm(!1,"onerror"),this.unbindEvents()},h.prototype.unbindEvents=function(){this.proxyImage.removeEventListener("load",this),this.proxyImage.removeEventListener("error",this),this.img.removeEventListener("load",this),this.img.removeEventListener("error",this)},d.prototype=Object.create(h.prototype),d.prototype.check=function(){this.img.addEventListener("load",this),this.img.addEventListener("error",this),this.img.src=this.url,this.getIsImageComplete()&&(this.confirm(0!==this.img.naturalWidth,"naturalWidth"),this.unbindEvents())},d.prototype.unbindEvents=function(){this.img.removeEventListener("load",this),this.img.removeEventListener("error",this)},d.prototype.confirm=function(t,e){this.isLoaded=t,this.emitEvent("progress",[this,this.element,e])},n.makeJQueryPlugin=function(e){(e=e||t.jQuery)&&(i=e,i.fn.imagesLoaded=function(t,e){return new n(this,t,e).jqDeferred.promise(i(this))})},n.makeJQueryPlugin(),n}));; 2797/*! This file is auto-generated */
vendor: 24,103 bytes, lines 2798-2806
2798/*! 2799 * Masonry PACKAGED v4.2.2 2800 * Cascading grid layout library 2801 * https://masonry.desandro.com 2802 * MIT License 2803 * by David DeSandro 2804 */ 2805 2806!function(t,e){"function"==typeof define&&define.amd?define("jquery-bridget/jquery-bridget",["jquery"],function(i){return e(t,i)}):"object"==typeof module&&module.exports?module.exports=e(t,require("jquery")):t.jQueryBridget=e(t,t.jQuery)}(window,function(t,e){"use strict";function i(i,r,a){function h(t,e,n){var o,r="$()."+i+'("'+e+'")';return t.each(function(t,h){var u=a.data(h,i);if(!u)return void s(i+" not initialized. Cannot call methods, i.e. "+r);var d=u[e];if(!d||"_"==e.charAt(0))return void s(r+" is not a valid method");var l=d.apply(u,n);o=void 0===o?l:o}),void 0!==o?o:t}function u(t,e){t.each(function(t,n){var o=a.data(n,i);o?(o.option(e),o._init()):(o=new r(n,e),a.data(n,i,o))})}a=a||e||t.jQuery,a&&(r.prototype.option||(r.prototype.option=function(t){a.isPlainObject(t)&&(this.options=a.extend(!0,this.options,t))}),a.fn[i]=function(t){if("string"==typeof t){var e=o.call(arguments,1);return h(this,t,e)}return u(this,t),this},n(a))}function n(t){!t||t&&t.bridget||(t.bridget=i)}var o=Array.prototype.slice,r=t.console,s="undefined"==typeof r?function(){}:function(t){r.error(t)};return n(e||t.jQuery),i}),function(t,e){"function"==typeof define&&define.amd?define("ev-emitter/ev-emitter",e):"object"==typeof module&&module.exports?module.exports=e():t.EvEmitter=e()}("undefined"!=typeof window?window:this,function(){function t(){}var e=t.prototype;return e.on=function(t,e){if(t&&e){var i=this._events=this._events||{},n=i[t]=i[t]||[];return-1==n.indexOf(e)&&n.push(e),this}},e.once=function(t,e){if(t&&e){this.on(t,e);var i=this._onceEvents=this._onceEvents||{},n=i[t]=i[t]||{};return n[e]=!0,this}},e.off=function(t,e){var i=this._events&&this._events[t];if(i&&i.length){var n=i.indexOf(e);return-1!=n&&i.splice(n,1),this}},e.emitEvent=function(t,e){var i=this._events&&this._events[t];if(i&&i.length){i=i.slice(0),e=e||[];for(var n=this._onceEvents&&this._onceEvents[t],o=0;o<i.length;o++){var r=i[o],s=n&&n[r];s&&(this.off(t,r),delete n[r]),r.apply(this,e)}return this}},e.allOff=function(){delete this._events,delete this._onceEvents},t}),function(t,e){"function"==typeof define&&define.amd?define("get-size/get-size",e):"object"==typeof module&&module.exports?module.exports=e():t.getSize=e()}(window,function(){"use strict";function t(t){var e=parseFloat(t),i=-1==t.indexOf("%")&&!isNaN(e);return i&&e}function e(){}function i(){for(var t={width:0,height:0,innerWidth:0,innerHeight:0,outerWidth:0,outerHeight:0},e=0;u>e;e++){var i=h[e];t[i]=0}return t}function n(t){var e=getComputedStyle(t);return e||a("Style returned "+e+". Are you running this code in a hidden iframe on Firefox? See https://bit.ly/getsizebug1"),e}function o(){if(!d){d=!0;var e=document.createElement("div");e.style.width="200px",e.style.padding="1px 2px 3px 4px",e.style.borderStyle="solid",e.style.borderWidth="1px 2px 3px 4px",e.style.boxSizing="border-box";var i=document.body||document.documentElement;i.appendChild(e);var o=n(e);s=200==Math.round(t(o.width)),r.isBoxSizeOuter=s,i.removeChild(e)}}function r(e){if(o(),"string"==typeof e&&(e=document.querySelector(e)),e&&"object"==typeof e&&e.nodeType){var r=n(e);if("none"==r.display)return i();var a={};a.width=e.offsetWidth,a.height=e.offsetHeight;for(var d=a.isBorderBox="border-box"==r.boxSizing,l=0;u>l;l++){var c=h[l],f=r[c],m=parseFloat(f);a[c]=isNaN(m)?0:m}var p=a.paddingLeft+a.paddingRight,g=a.paddingTop+a.paddingBottom,y=a.marginLeft+a.marginRight,v=a.marginTop+a.marginBottom,_=a.borderLeftWidth+a.borderRightWidth,z=a.borderTopWidth+a.borderBottomWidth,E=d&&s,b=t(r.width);b!==!1&&(a.width=b+(E?0:p+_));var x=t(r.height);return x!==!1&&(a.height=x+(E?0:g+z)),a.innerWidth=a.width-(p+_),a.innerHeight=a.height-(g+z),a.outerWidth=a.width+y,a.outerHeight=a.height+v,a}}var s,a="undefined"==typeof console?e:function(t){console.error(t)},h=["paddingLeft","paddingRight","paddingTop","paddingBottom","marginLeft","marginRight","marginTop","marginBottom","borderLeftWidth","borderRightWidth","borderTopWidth","borderBottomWidth"],u=h.length,d=!1;return r}),function(t,e){"use strict";"function"==typeof define&&define.amd?define("desandro-matches-selector/matches-selector",e):"object"==typeof module&&module.exports?module.exports=e():t.matchesSelector=e()}(window,function(){"use strict";var t=function(){var t=window.Element.prototype;if(t.matches)return"matches";if(t.matchesSelector)return"matchesSelector";for(var e=["webkit","moz","ms","o"],i=0;i<e.length;i++){var n=e[i],o=n+"MatchesSelector";if(t[o])return o}}();return function(e,i){return e[t](i)}}),function(t,e){"function"==typeof define&&define.amd?define("fizzy-ui-utils/utils",["desandro-matches-selector/matches-selector"],function(i){return e(t,i)}):"object"==typeof module&&module.exports?module.exports=e(t,require("desandro-matches-selector")):t.fizzyUIUtils=e(t,t.matchesSelector)}(window,function(t,e){var i={};i.extend=function(t,e){for(var i in e)t[i]=e[i];return t},i.modulo=function(t,e){return(t%e+e)%e};var n=Array.prototype.slice;i.makeArray=function(t){if(Array.isArray(t))return t;if(null===t||void 0===t)return[];var e="object"==typeof t&&"number"==typeof t.length;return e?n.call(t):[t]},i.removeFrom=function(t,e){var i=t.indexOf(e);-1!=i&&t.splice(i,1)},i.getParent=function(t,i){for(;t.parentNode&&t!=document.body;)if(t=t.parentNode,e(t,i))return t},i.getQueryElement=function(t){return"string"==typeof t?document.querySelector(t):t},i.handleEvent=function(t){var e="on"+t.type;this[e]&&this[e](t)},i.filterFindElements=function(t,n){t=i.makeArray(t);var o=[];return t.forEach(function(t){if(t instanceof HTMLElement){if(!n)return void o.push(t);e(t,n)&&o.push(t);for(var i=t.querySelectorAll(n),r=0;r<i.length;r++)o.push(i[r])}}),o},i.debounceMethod=function(t,e,i){i=i||100;var n=t.prototype[e],o=e+"Timeout";t.prototype[e]=function(){var t=this[o];clearTimeout(t);var e=arguments,r=this;this[o]=setTimeout(function(){n.apply(r,e),delete r[o]},i)}},i.docReady=function(t){var e=document.readyState;"complete"==e||"interactive"==e?setTimeout(t):document.addEventListener("DOMContentLoaded",t)},i.toDashed=function(t){return t.replace(/(.)([A-Z])/g,function(t,e,i){return e+"-"+i}).toLowerCase()};var o=t.console;return i.htmlInit=function(e,n){i.docReady(function(){var r=i.toDashed(n),s="data-"+r,a=document.querySelectorAll("["+s+"]"),h=document.querySelectorAll(".js-"+r),u=i.makeArray(a).concat(i.makeArray(h)),d=s+"-options",l=t.jQuery;u.forEach(function(t){var i,r=t.getAttribute(s)||t.getAttribute(d);try{i=r&&JSON.parse(r)}catch(a){return void(o&&o.error("Error parsing "+s+" on "+t.className+": "+a))}var h=new e(t,i);l&&l.data(t,n,h)})})},i}),function(t,e){"function"==typeof define&&define.amd?define("outlayer/item",["ev-emitter/ev-emitter","get-size/get-size"],e):"object"==typeof module&&module.exports?module.exports=e(require("ev-emitter"),require("get-size")):(t.Outlayer={},t.Outlayer.Item=e(t.EvEmitter,t.getSize))}(window,function(t,e){"use strict";function i(t){for(var e in t)return!1;return e=null,!0}function n(t,e){t&&(this.element=t,this.layout=e,this.position={x:0,y:0},this._create())}function o(t){return t.replace(/([A-Z])/g,function(t){return"-"+t.toLowerCase()})}var r=document.documentElement.style,s="string"==typeof r.transition?"transition":"WebkitTransition",a="string"==typeof r.transform?"transform":"WebkitTransform",h={WebkitTransition:"webkitTransitionEnd",transition:"transitionend"}[s],u={transform:a,transition:s,transitionDuration:s+"Duration",transitionProperty:s+"Property",transitionDelay:s+"Delay"},d=n.prototype=Object.create(t.prototype);d.constructor=n,d._create=function(){this._transn={ingProperties:{},clean:{},onEnd:{}},this.css({position:"absolute"})},d.handleEvent=function(t){var e="on"+t.type;this[e]&&this[e](t)},d.getSize=function(){this.size=e(this.element)},d.css=function(t){var e=this.element.style;for(var i in t){var n=u[i]||i;e[n]=t[i]}},d.getPosition=function(){var t=getComputedStyle(this.element),e=this.layout._getOption("originLeft"),i=this.layout._getOption("originTop"),n=t[e?"left":"right"],o=t[i?"top":"bottom"],r=parseFloat(n),s=parseFloat(o),a=this.layout.size;-1!=n.indexOf("%")&&(r=r/100*a.width),-1!=o.indexOf("%")&&(s=s/100*a.height),r=isNaN(r)?0:r,s=isNaN(s)?0:s,r-=e?a.paddingLeft:a.paddingRight,s-=i?a.paddingTop:a.paddingBottom,this.position.x=r,this.position.y=s},d.layoutPosition=function(){var t=this.layout.size,e={},i=this.layout._getOption("originLeft"),n=this.layout._getOption("originTop"),o=i?"paddingLeft":"paddingRight",r=i?"left":"right",s=i?"right":"left",a=this.position.x+t[o];e[r]=this.getXValue(a),e[s]="";var h=n?"paddingTop":"paddingBottom",u=n?"top":"bottom",d=n?"bottom":"top",l=this.position.y+t[h];e[u]=this.getYValue(l),e[d]="",this.css(e),this.emitEvent("layout",[this])},d.getXValue=function(t){var e=this.layout._getOption("horizontal");return this.layout.options.percentPosition&&!e?t/this.layout.size.width*100+"%":t+"px"},d.getYValue=function(t){var e=this.layout._getOption("horizontal");return this.layout.options.percentPosition&&e?t/this.layout.size.height*100+"%":t+"px"},d._transitionTo=function(t,e){this.getPosition();var i=this.position.x,n=this.position.y,o=t==this.position.x&&e==this.position.y;if(this.setPosition(t,e),o&&!this.isTransitioning)return void this.layoutPosition();var r=t-i,s=e-n,a={};a.transform=this.getTranslate(r,s),this.transition({to:a,onTransitionEnd:{transform:this.layoutPosition},isCleaning:!0})},d.getTranslate=function(t,e){var i=this.layout._getOption("originLeft"),n=this.layout._getOption("originTop");return t=i?t:-t,e=n?e:-e,"translate3d("+t+"px, "+e+"px, 0)"},d.goTo=function(t,e){this.setPosition(t,e),this.layoutPosition()},d.moveTo=d._transitionTo,d.setPosition=function(t,e){this.position.x=parseFloat(t),this.position.y=parseFloat(e)},d._nonTransition=function(t){this.css(t.to),t.isCleaning&&this._removeStyles(t.to);for(var e in t.onTransitionEnd)t.onTransitionEnd[e].call(this)},d.transition=function(t){if(!parseFloat(this.layout.options.transitionDuration))return void this._nonTransition(t);var e=this._transn;for(var i in t.onTransitionEnd)e.onEnd[i]=t.onTransitionEnd[i];for(i in t.to)e.ingProperties[i]=!0,t.isCleaning&&(e.clean[i]=!0);if(t.from){this.css(t.from);var n=this.element.offsetHeight;n=null}this.enableTransition(t.to),this.css(t.to),this.isTransitioning=!0};var l="opacity,"+o(a);d.enableTransition=function(){if(!this.isTransitioning){var t=this.layout.options.transitionDuration;t="number"==typeof t?t+"ms":t,this.css({transitionProperty:l,transitionDuration:t,transitionDelay:this.staggerDelay||0}),this.element.addEventListener(h,this,!1)}},d.onwebkitTransitionEnd=function(t){this.ontransitionend(t)},d.onotransitionend=function(t){this.ontransitionend(t)};var c={"-webkit-transform":"transform"};d.ontransitionend=function(t){if(t.target===this.element){var e=this._transn,n=c[t.propertyName]||t.propertyName;if(delete e.ingProperties[n],i(e.ingProperties)&&this.disableTransition(),n in e.clean&&(this.element.style[t.propertyName]="",delete e.clean[n]),n in e.onEnd){var o=e.onEnd[n];o.call(this),delete e.onEnd[n]}this.emitEvent("transitionEnd",[this])}},d.disableTransition=function(){this.removeTransitionStyles(),this.element.removeEventListener(h,this,!1),this.isTransitioning=!1},d._removeStyles=function(t){var e={};for(var i in t)e[i]="";this.css(e)};var f={transitionProperty:"",transitionDuration:"",transitionDelay:""};return d.removeTransitionStyles=function(){this.css(f)},d.stagger=function(t){t=isNaN(t)?0:t,this.staggerDelay=t+"ms"},d.removeElem=function(){this.element.parentNode.removeChild(this.element),this.css({display:""}),this.emitEvent("remove",[this])},d.remove=function(){return s&&parseFloat(this.layout.options.transitionDuration)?(this.once("transitionEnd",function(){this.removeElem()}),void this.hide()):void this.removeElem()},d.reveal=function(){delete this.isHidden,this.css({display:""});var t=this.layout.options,e={},i=this.getHideRevealTransitionEndProperty("visibleStyle");e[i]=this.onRevealTransitionEnd,this.transition({from:t.hiddenStyle,to:t.visibleStyle,isCleaning:!0,onTransitionEnd:e})},d.onRevealTransitionEnd=function(){this.isHidden||this.emitEvent("reveal")},d.getHideRevealTransitionEndProperty=function(t){var e=this.layout.options[t];if(e.opacity)return"opacity";for(var i in e)return i},d.hide=function(){this.isHidden=!0,this.css({display:""});var t=this.layout.options,e={},i=this.getHideRevealTransitionEndProperty("hiddenStyle");e[i]=this.onHideTransitionEnd,this.transition({from:t.visibleStyle,to:t.hiddenStyle,isCleaning:!0,onTransitionEnd:e})},d.onHideTransitionEnd=function(){this.isHidden&&(this.css({display:"none"}),this.emitEvent("hide"))},d.destroy=function(){this.css({position:"",left:"",right:"",top:"",bottom:"",transition:"",transform:""})},n}),function(t,e){"use strict";"function"==typeof define&&define.amd?define("outlayer/outlayer",["ev-emitter/ev-emitter","get-size/get-size","fizzy-ui-utils/utils","./item"],function(i,n,o,r){return e(t,i,n,o,r)}):"object"==typeof module&&module.exports?module.exports=e(t,require("ev-emitter"),require("get-size"),require("fizzy-ui-utils"),require("./item")):t.Outlayer=e(t,t.EvEmitter,t.getSize,t.fizzyUIUtils,t.Outlayer.Item)}(window,function(t,e,i,n,o){"use strict";function r(t,e){var i=n.getQueryElement(t);if(!i)return void(h&&h.error("Bad element for "+this.constructor.namespace+": "+(i||t)));this.element=i,u&&(this.$element=u(this.element)),this.options=n.extend({},this.constructor.defaults),this.option(e);var o=++l;this.element.outlayerGUID=o,c[o]=this,this._create();var r=this._getOption("initLayout");r&&this.layout()}function s(t){function e(){t.apply(this,arguments)}return e.prototype=Object.create(t.prototype),e.prototype.constructor=e,e}function a(t){if("number"==typeof t)return t;var e=t.match(/(^\d*\.?\d*)(\w*)/),i=e&&e[1],n=e&&e[2];if(!i.length)return 0;i=parseFloat(i);var o=m[n]||1;return i*o}var h=t.console,u=t.jQuery,d=function(){},l=0,c={};r.namespace="outlayer",r.Item=o,r.defaults={containerStyle:{position:"relative"},initLayout:!0,originLeft:!0,originTop:!0,resize:!0,resizeContainer:!0,transitionDuration:"0.4s",hiddenStyle:{opacity:0,transform:"scale(0.001)"},visibleStyle:{opacity:1,transform:"scale(1)"}};var f=r.prototype;n.extend(f,e.prototype),f.option=function(t){n.extend(this.options,t)},f._getOption=function(t){var e=this.constructor.compatOptions[t];return e&&void 0!==this.options[e]?this.options[e]:this.options[t]},r.compatOptions={initLayout:"isInitLayout",horizontal:"isHorizontal",layoutInstant:"isLayoutInstant",originLeft:"isOriginLeft",originTop:"isOriginTop",resize:"isResizeBound",resizeContainer:"isResizingContainer"},f._create=function(){this.reloadItems(),this.stamps=[],this.stamp(this.options.stamp),n.extend(this.element.style,this.options.containerStyle);var t=this._getOption("resize");t&&this.bindResize()},f.reloadItems=function(){this.items=this._itemize(this.element.children)},f._itemize=function(t){for(var e=this._filterFindItemElements(t),i=this.constructor.Item,n=[],o=0;o<e.length;o++){var r=e[o],s=new i(r,this);n.push(s)}return n},f._filterFindItemElements=function(t){return n.filterFindElements(t,this.options.itemSelector)},f.getItemElements=function(){return this.items.map(function(t){return t.element})},f.layout=function(){this._resetLayout(),this._manageStamps();var t=this._getOption("layoutInstant"),e=void 0!==t?t:!this._isLayoutInited;this.layoutItems(this.items,e),this._isLayoutInited=!0},f._init=f.layout,f._resetLayout=function(){this.getSize()},f.getSize=function(){this.size=i(this.element)},f._getMeasurement=function(t,e){var n,o=this.options[t];o?("string"==typeof o?n=this.element.querySelector(o):o instanceof HTMLElement&&(n=o),this[t]=n?i(n)[e]:o):this[t]=0},f.layoutItems=function(t,e){t=this._getItemsForLayout(t),this._layoutItems(t,e),this._postLayout()},f._getItemsForLayout=function(t){return t.filter(function(t){return!t.isIgnored})},f._layoutItems=function(t,e){if(this._emitCompleteOnItems("layout",t),t&&t.length){var i=[];t.forEach(function(t){var n=this._getItemLayoutPosition(t);n.item=t,n.isInstant=e||t.isLayoutInstant,i.push(n)},this),this._processLayoutQueue(i)}},f._getItemLayoutPosition=function(){return{x:0,y:0}},f._processLayoutQueue=function(t){this.updateStagger(),t.forEach(function(t,e){this._positionItem(t.item,t.x,t.y,t.isInstant,e)},this)},f.updateStagger=function(){var t=this.options.stagger;return null===t||void 0===t?void(this.stagger=0):(this.stagger=a(t),this.stagger)},f._positionItem=function(t,e,i,n,o){n?t.goTo(e,i):(t.stagger(o*this.stagger),t.moveTo(e,i))},f._postLayout=function(){this.resizeContainer()},f.resizeContainer=function(){var t=this._getOption("resizeContainer");if(t){var e=this._getContainerSize();e&&(this._setContainerMeasure(e.width,!0),this._setContainerMeasure(e.height,!1))}},f._getContainerSize=d,f._setContainerMeasure=function(t,e){if(void 0!==t){var i=this.size;i.isBorderBox&&(t+=e?i.paddingLeft+i.paddingRight+i.borderLeftWidth+i.borderRightWidth:i.paddingBottom+i.paddingTop+i.borderTopWidth+i.borderBottomWidth),t=Math.max(t,0),this.element.style[e?"width":"height"]=t+"px"}},f._emitCompleteOnItems=function(t,e){function i(){o.dispatchEvent(t+"Complete",null,[e])}function n(){s++,s==r&&i()}var o=this,r=e.length;if(!e||!r)return void i();var s=0;e.forEach(function(e){e.once(t,n)})},f.dispatchEvent=function(t,e,i){var n=e?[e].concat(i):i;if(this.emitEvent(t,n),u)if(this.$element=this.$element||u(this.element),e){var o=u.Event(e);o.type=t,this.$element.trigger(o,i)}else this.$element.trigger(t,i)},f.ignore=function(t){var e=this.getItem(t);e&&(e.isIgnored=!0)},f.unignore=function(t){var e=this.getItem(t);e&&delete e.isIgnored},f.stamp=function(t){t=this._find(t),t&&(this.stamps=this.stamps.concat(t),t.forEach(this.ignore,this))},f.unstamp=function(t){t=this._find(t),t&&t.forEach(function(t){n.removeFrom(this.stamps,t),this.unignore(t)},this)},f._find=function(t){return t?("string"==typeof t&&(t=this.element.querySelectorAll(t)),t=n.makeArray(t)):void 0},f._manageStamps=function(){this.stamps&&this.stamps.length&&(this._getBoundingRect(),this.stamps.forEach(this._manageStamp,this))},f._getBoundingRect=function(){var t=this.element.getBoundingClientRect(),e=this.size;this._boundingRect={left:t.left+e.paddingLeft+e.borderLeftWidth,top:t.top+e.paddingTop+e.borderTopWidth,right:t.right-(e.paddingRight+e.borderRightWidth),bottom:t.bottom-(e.paddingBottom+e.borderBottomWidth)}},f._manageStamp=d,f._getElementOffset=function(t){var e=t.getBoundingClientRect(),n=this._boundingRect,o=i(t),r={left:e.left-n.left-o.marginLeft,top:e.top-n.top-o.marginTop,right:n.right-e.right-o.marginRight,bottom:n.bottom-e.bottom-o.marginBottom};return r},f.handleEvent=n.handleEvent,f.bindResize=function(){t.addEventListener("resize",this),this.isResizeBound=!0},f.unbindResize=function(){t.removeEventListener("resize",this),this.isResizeBound=!1},f.onresize=function(){this.resize()},n.debounceMethod(r,"onresize",100),f.resize=function(){this.isResizeBound&&this.needsResizeLayout()&&this.layout()},f.needsResizeLayout=function(){var t=i(this.element),e=this.size&&t;return e&&t.innerWidth!==this.size.innerWidth},f.addItems=function(t){var e=this._itemize(t);return e.length&&(this.items=this.items.concat(e)),e},f.appended=function(t){var e=this.addItems(t);e.length&&(this.layoutItems(e,!0),this.reveal(e))},f.prepended=function(t){var e=this._itemize(t);if(e.length){var i=this.items.slice(0);this.items=e.concat(i),this._resetLayout(),this._manageStamps(),this.layoutItems(e,!0),this.reveal(e),this.layoutItems(i)}},f.reveal=function(t){if(this._emitCompleteOnItems("reveal",t),t&&t.length){var e=this.updateStagger();t.forEach(function(t,i){t.stagger(i*e),t.reveal()})}},f.hide=function(t){if(this._emitCompleteOnItems("hide",t),t&&t.length){var e=this.updateStagger();t.forEach(function(t,i){t.stagger(i*e),t.hide()})}},f.revealItemElements=function(t){var e=this.getItems(t);this.reveal(e)},f.hideItemElements=function(t){var e=this.getItems(t);this.hide(e)},f.getItem=function(t){for(var e=0;e<this.items.length;e++){var i=this.items[e];if(i.element==t)return i}},f.getItems=function(t){t=n.makeArray(t);var e=[];return t.forEach(function(t){var i=this.getItem(t);i&&e.push(i)},this),e},f.remove=function(t){var e=this.getItems(t);this._emitCompleteOnItems("remove",e),e&&e.length&&e.forEach(function(t){t.remove(),n.removeFrom(this.items,t)},this)},f.destroy=function(){var t=this.element.style;t.height="",t.position="",t.width="",this.items.forEach(function(t){t.destroy()}),this.unbindResize();var e=this.element.outlayerGUID;delete c[e],delete this.element.outlayerGUID,u&&u.removeData(this.element,this.constructor.namespace)},r.data=function(t){t=n.getQueryElement(t);var e=t&&t.outlayerGUID;return e&&c[e]},r.create=function(t,e){var i=s(r);return i.defaults=n.extend({},r.defaults),n.extend(i.defaults,e),i.compatOptions=n.extend({},r.compatOptions),i.namespace=t,i.data=r.data,i.Item=s(o),n.htmlInit(i,t),u&&u.bridget&&u.bridget(t,i),i};var m={ms:1,s:1e3};return r.Item=o,r}),function(t,e){"function"==typeof define&&define.amd?define(["outlayer/outlayer","get-size/get-size"],e):"object"==typeof module&&module.exports?module.exports=e(require("outlayer"),require("get-size")):t.Masonry=e(t.Outlayer,t.getSize)}(window,function(t,e){var i=t.create("masonry");i.compatOptions.fitWidth="isFitWidth";var n=i.prototype;return n._resetLayout=function(){this.getSize(),this._getMeasurement("columnWidth","outerWidth"),this._getMeasurement("gutter","outerWidth"),this.measureColumns(),this.colYs=[];for(var t=0;t<this.cols;t++)this.colYs.push(0);this.maxY=0,this.horizontalColIndex=0},n.measureColumns=function(){if(this.getContainerWidth(),!this.columnWidth){var t=this.items[0],i=t&&t.element;this.columnWidth=i&&e(i).outerWidth||this.containerWidth}var n=this.columnWidth+=this.gutter,o=this.containerWidth+this.gutter,r=o/n,s=n-o%n,a=s&&1>s?"round":"floor";r=Math[a](r),this.cols=Math.max(r,1)},n.getContainerWidth=function(){var t=this._getOption("fitWidth"),i=t?this.element.parentNode:this.element,n=e(i);this.containerWidth=n&&n.innerWidth},n._getItemLayoutPosition=function(t){t.getSize();var e=t.size.outerWidth%this.columnWidth,i=e&&1>e?"round":"ceil",n=Math[i](t.size.outerWidth/this.columnWidth);n=Math.min(n,this.cols);for(var o=this.options.horizontalOrder?"_getHorizontalColPosition":"_getTopColPosition",r=this[o](n,t),s={x:this.columnWidth*r.col,y:r.y},a=r.y+t.size.outerHeight,h=n+r.col,u=r.col;h>u;u++)this.colYs[u]=a;return s},n._getTopColPosition=function(t){var e=this._getTopColGroup(t),i=Math.min.apply(Math,e);return{col:e.indexOf(i),y:i}},n._getTopColGroup=function(t){if(2>t)return this.colYs;for(var e=[],i=this.cols+1-t,n=0;i>n;n++)e[n]=this._getColGroupY(n,t);return e},n._getColGroupY=function(t,e){if(2>e)return this.colYs[t];var i=this.colYs.slice(t,t+e);return Math.max.apply(Math,i)},n._getHorizontalColPosition=function(t,e){var i=this.horizontalColIndex%this.cols,n=t>1&&i+t>this.cols;i=n?0:i;var o=e.size.outerWidth&&e.size.outerHeight;return this.horizontalColIndex=o?i+t:this.horizontalColIndex,{col:i,y:this._getColGroupY(i,t)}},n._manageStamp=function(t){var i=e(t),n=this._getElementOffset(t),o=this._getOption("originLeft"),r=o?n.left:n.right,s=r+i.outerWidth,a=Math.floor(r/this.columnWidth);a=Math.max(0,a);var h=Math.floor(s/this.columnWidth);h-=s%this.columnWidth?0:1,h=Math.min(this.cols-1,h);for(var u=this._getOption("originTop"),d=(u?n.top:n.bottom)+i.outerHeight,l=a;h>=l;l++)this.colYs[l]=Math.max(d,this.colYs[l])},n._getContainerSize=function(){this.maxY=Math.max.apply(Math,this.colYs);var t={height:this.maxY};return this._getOption("fitWidth")&&(t.width=this._getContainerFitWidth()),t},n._getContainerFitWidth=function(){for(var t=0,e=this.cols;--e&&0===this.colYs[e];)t++;return(this.cols-t)*this.columnWidth-this.gutter},n.needsResizeLayout=function(){var t=this.containerWidth;return this.getContainerWidth(),t!=this.containerWidth},i});
2806; 2807/** 2808 * Theme functions file 2809 * 2810 * 2811 */ 2812 2813(function($) { 2814 2815 // posts block for Masonry 2816 var $blocks = $('#posts'); 2817 2818 $( window ).load( function() { 2819 /** 2820 * Initial Masonry setup 2821 */ 2822 2823 // Determine text direction 2824 var ltr = true; 2825 if ( $('html' ).attr( 'dir' ) == 'rtl') { 2826 ltr = false; 2827 } 2828 2829 // fire up Masonry! 2830 $blocks.imagesLoaded( function() { 2831 $blocks.masonry({ 2832 columnWidth: 1, 2833 itemSelector: '.post-container', 2834 transitionDuration: 0, 2835 isOriginLeft: ltr, 2836 } ).masonry( 'layout' ); 2837 2838 var masonryChild = $blocks.find( '.post-container' ); 2839 2840 // Animating JS based off Huntt theme 2841 masonryChild.each( function( i ) { 2842 // Show content 2843 setTimeout( function() { 2844 masonryChild.eq( i ).addClass( 'post-loaded fade-in' ); 2845 }, 100 * ( i + 1 ) ); 2846 } ); 2847 2848 $( '#spinner' ).fadeOut( 250, function() { 2849 $( this ).remove(); 2850 } ); 2851 } ); 2852 } ); 2853 2854 2855 $( document ).ready( function( $ ) { 2856 2857 // Flexslider for Gallery posts 2858 $( ".flexslider" ).flexslider( { 2859 animation: "slide", 2860 controlNav: false, 2861 prevText: "Previous", 2862 nextText: "Next", 2863 smoothHeight: false, 2864 startAt : 1, // make sure order reflects order in gallery format 2865 } ); 2866 2867 /** 2868 * Masonry update after Infinte Scroll 2869 * JS based off Huntt theme 2870 */ 2871 2872 $( document.body ).on( 'post-load', function() { 2873 2874 // make sure we're only grabbing new posts 2875 var newEl = $blocks.children().not( '.post-loaded, span.infinite-loader' ).addClass( 'post-loaded' ); 2876 2877 // create function for refreshing Masonry 2878 function refreshMasonry() { 2879 $blocks.masonry( 'layout' ); 2880 } 2881 2882 // check if images loaded in these new posts 2883 newEl.imagesLoaded( function () { 2884 // if images loaded, add new posts and update masonry layout 2885 $blocks.masonry( 'appended', newEl, true ).masonry( 'layout' ); 2886 2887 // reinitialize flexslider for new posts, and re-run masonry when complete 2888 $( ".flexslider" ).flexslider( { 2889 animation: "slide", 2890 controlNav: false, 2891 prevText: "Previous", 2892 nextText: "Next", 2893 smoothHeight: false, 2894 startAt : 1, 2895 start: refreshMasonry, // reload masonry layout on finish, just in case flexslider was slow 2896 } ); 2897 2898 } ).delay( 500 ).each( function( i ) { 2899 // then have a small delay between displaying each post 2900 setTimeout( function() { 2901 newEl.eq( i ).addClass( 'fade-in' ); 2902 }, 200 * ( i + 1 ) ); 2903 } ); 2904 2905 // reloading masonry layout again, after delay 2906 // fixes edge case issue with Facebook embed reloading and messing up layout 2907 setTimeout( refreshMasonry, 3000 ); 2908 } ); 2909 2910 2911 /** 2912 * Enables menu toggle for small screens 2913 */ 2914 2915 ( function() { 2916 var nav = $( '.navigation' ), button, menu; 2917 if ( ! nav ) { 2918 return; 2919 } 2920 2921 button = nav.find( '.nav-toggle' ); 2922 if ( ! button ) { 2923 return; 2924 } 2925 2926 // Hide button if menu is missing or empty. 2927 menu = nav.find( '.main-navigation' ); 2928 if ( ! menu || ! menu.children().length ) { 2929 button.hide(); 2930 return; 2931 } 2932 2933 button.on( 'click.baskerville', function() { 2934 nav.toggleClass( 'toggled-on' ); 2935 $( this ).toggleClass( "active" ); 2936 $( ".main-navigation" ).slideToggle(); 2937 } ); 2938 2939 // Fix sub-menus for touch devices. 2940 if ( 'ontouchstart' in window ) { 2941 menu.find( '.has-children > a, .page_item_has_children a' ).on( 'touchstart.baskerville', function( e ) { 2942 var el = $( this ).parent( 'li' ); 2943 2944 if ( ! el.hasClass( 'focus' ) ) { 2945 e.preventDefault(); 2946 el.toggleClass( 'focus' ); 2947 el.siblings( '.focus' ).removeClass( 'focus' ); 2948 } 2949 } ); 2950 } 2951 2952 // Better focus for hidden submenu items for accessibility. 2953 menu.find( 'a' ).on( 'focus.baskerville blur.baskerville', function() { 2954 $( this ).parents( '.menu-item, .page_item' ).toggleClass( 'focus' ); 2955 } ); 2956 2957 } )(); 2958 2959 2960 // Makes "skip to content" link work correctly in IE9 and Chrome for better 2961 // accessibility. 2962 2963 // @link http://www.nczonline.net/blog/2013/01/15/fixing-skip-to-content-links/ 2964 2965 $( window ).on( 'hashchange.baskerville', function() { 2966 var hash = location.hash.substring( 1 ), element; 2967 if ( ! hash ) { 2968 return; 2969 } 2970 element = document.getElementById( hash ); 2971 if ( element ) { 2972 if ( ! /^(?:a|select|input|button|textarea)$/i.test( element.tagName ) ) { 2973 element.tabIndex = -1; 2974 } 2975 element.focus(); 2976 // Repositions the window on jump-to-anchor to account for header height. 2977 window.scrollBy( 0, -80 ); 2978 } 2979 } ); 2980 2981 2982 // Toggle search form 2983 $( ".search-toggle" ).on( "click", function() { 2984 $( this ).toggleClass( "active" ); 2985 $( ".header-search-block" ).slideToggle(); 2986 $( ".header-search-block .search-field" ).focus(); 2987 return false;
2988 } ); 2989 2990 2991 // Smooth scroll to header 2992 $( '.tothetop' ).click( function() { 2993 $( 'html, body' ).animate( { 2994 scrollTop: 0 2995 }, 500 ); 2996 $( this ).unbind( "mouseenter mouseleave" ); 2997 return false; 2998 } ); 2999 3000 3001 // Add 'focus' style to search bar and comment inputs 3002 $('.wrapper .search-form input, .footer .search-form input').focus( function() { 3003 $( this ).closest( 'form' ).addClass( 'focus' ); 3004 } ).blur( function() { 3005 $( this ).closest( 'form' ).removeClass( 'focus' ); 3006 } ); 3007 3008 $('.comment-form-author input, .comment-form-email input, .comment-form-url input').focus( function() { 3009 $( this ).parent().addClass( 'focus' ); 3010 } ).blur( function() { 3011 $( this ).parent().removeClass( 'focus' ); 3012 } ); 3013 3014 3015 // Detect CSS3 Transform support in browsers 3016 var supports = ( function() { 3017 var div = document.createElement( 'div' ), 3018 vendors = 'Khtml Ms O Moz Webkit'.split( ' ' ), 3019 len = vendors.length; 3020 3021 return function( prop ) { 3022 if ( prop in div.style ) { 3023 return true; 3024 } 3025 3026 prop = prop.replace( /^[a-z]/, function( val ) { 3027 return val.toUpperCase(); 3028 } ); 3029 3030 while ( len-- ) { 3031 if ( vendors[len] + prop in div.style ) { 3032 return true; 3033 } 3034 } 3035 return false; 3036 }; 3037 } ) (); 3038 3039 if ( supports( 'transform' ) ) { 3040 // Add a css-transform class to the html element 3041 document.documentElement.className += ' css-transform'; 3042 } 3043 3044 3045 // To add placeholder text to header search in IE9 3046 // based on https://gist.github.com/samgro/823300 3047 if ( navigator.appVersion.indexOf( "MSIE 9." ) !=-1 ) { 3048 $( '[placeholder]' ).focus( function() { 3049 var input = $( this ); 3050 if ( input.hasClass( 'placeholder' ) ) { 3051 input.val( '' ); 3052 input.removeClass( 'placeholder' ); 3053 } 3054 } ).blur( function() { 3055 var input = $( this ); 3056 if ( input.val() === '' ) { 3057 input.addClass( 'placeholder' ); 3058 input.val( input.attr( 'placeholder' ) ); 3059 } 3060 } ).blur().parents( 'form' ).submit( function() { 3061 $( this ).find( '[placeholder]' ).each( function() { 3062 var input = $( this ); 3063 if ( input.hasClass( 'placeholder' ) ) { 3064 input.val( '' ); 3065 } 3066 } ); 3067 } ); 3068 3069 // Clear input on refresh so that the placeholder class gets added back 3070 $( window ).unload( function() { 3071 $( '[placeholder]' ).val( '' ); 3072 } ); 3073 } 3074 } ); 3075} )( jQuery ); 3076; 3077/*! This file is auto-generated */ 3078window.addComment=function(v){var I,C,h,E=v.document,b={commentReplyClass:"comment-reply-link",commentReplyTitleId:"reply-title",cancelReplyId:"cancel-comment-reply-link",commentFormId:"commentform",temporaryFormId:"wp-temp-form-div",parentIdFieldId:"comment_parent",postIdFieldId:"comment_post_ID"},e=v.MutationObserver||v.WebKitMutationObserver||v.MozMutationObserver,i="querySelector"in E&&"addEventListener"in v,n=!!E.documentElement.dataset;function t(){o(),e&&new e(d).observe(E.body,{childList:!0,subtree:!0})}function o(e){if(i&&(I=g(b.cancelReplyId),C=g(b.commentFormId),I)){I.addEventListener("click",l);function t(e){if((e.metaKey||e.ctrlKey)&&13===e.keyCode&&"a"!==E.activeElement.tagName.toLowerCase())return C.removeEventListener("keydown",t),e.preventDefault(),C.submit.click(),!1}C&&C.addEventListener("keydown",t);for(var n=function(e){var t=b.commentReplyClass;e&&e.childNodes||(e=E);e=E.getElementsByClassName?e.getElementsByClassName(t):e.querySelectorAll("."+t);return e}(e),o=0,d=n.length;o<d;o++)n[o].addEventListener("click",r)}}function l(e){var t,n,o=g(b.temporaryFormId);o&&h&&(g(b.parentIdFieldId).value="0",t=o.textContent,o.parentNode.replaceChild(h,o),this.style.display="none",n=(o=(o=g(b.commentReplyTitleId))&&o.firstChild)&&o.nextSibling,o&&o.nodeType===Node.TEXT_NODE&&t&&(n&&"A"===n.nodeName&&n.id!==b.cancelReplyId&&(n.style.display=""),o.textContent=t),e.preventDefault())}function r(e){var t=g(b.commentReplyTitleId),t=t&&t.firstChild.textContent,n=this,o=a(n,"belowelement"),d=a(n,"commentid"),i=a(n,"respondelement"),l=a(n,"postid"),n=a(n,"replyto")||t;o&&d&&i&&l&&!1===v.addComment.moveForm(o,d,i,l,n)&&e.preventDefault()}function d(e){for(var t=e.length;t--;)if(e[t].addedNodes.length)return void o()}function a(e,t){return n?e.dataset[t]:e.getAttribute("data-"+t)}function g(e){return E.getElementById(e)}return i&&"loading"!==E.readyState?t():i&&v.addEventListener("DOMContentLoaded",t,!1),{init:o,moveForm:function(e,t,n,o,d){var i,l,r,a,m,c,s,e=g(e),n=(h=g(n),g(b.parentIdFieldId)),y=g(b.postIdFieldId),p=g(b.commentReplyTitleId),u=(p=p&&p.firstChild)&&p.nextSibling;if(e&&h&&n){void 0===d&&(d=p&&p.textContent),a=h,m=b.temporaryFormId,c=g(m),s=(s=g(b.commentReplyTitleId))?s.firstChild.textContent:"",c||((c=E.createElement("div")).id=m,c.style.display="none",c.textContent=s,a.parentNode.insertBefore(c,a)),o&&y&&(y.value=o),n.value=t,I.style.display="",e.parentNode.insertBefore(h,e.nextSibling),p&&p.nodeType===Node.TEXT_NODE&&(u&&"A"===u.nodeName&&u.id!==b.cancelReplyId&&(u.style.display="none"),p.textContent=d),I.onclick=function(){return!1};try{for(var f=0;f<C.elements.length;f++)if(i=C.elements[f],l=!1,"getComputedStyle"in v?r=v.getComputedStyle(i):E.documentElement.currentStyle&&(r=i.currentStyle),(i.offsetWidth<=0&&i.offsetHeight<=0||"hidden"===r.visibility)&&(l=!0),"hidden"
3078!==i.type&&!i.disabled&&!l){i.focus();break}}catch(e){}return!1}}}}(window);; 3079!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.JetpackScriptDataModule=t():e.JetpackScriptDataModule=t()}(globalThis,()=>(()=>{"use strict";var e={729(e,t,r){r.d(t,{$8:()=>n.$8,IT:()=>n.IT,KS:()=>n.KS,L2:()=>n.L2,Sy:()=>n.Sy,au:()=>n.au,d_:()=>n.d_,e5:()=>n.e5,hT:()=>n.hT,lI:()=>n.lI,mH:()=>n.mH,oQ:()=>n.oQ,sV:()=>n.sV});var n=r(336)},336(e,t,r){function n(){return window.JetpackScriptData}function o(){return n()?.site}function i(e=""){return`${n()?.site.admin_url}${e}`}function u(e=""){return i(`admin.php?page=jetpack${e}`)}function a(e=""){return i(`admin.php?page=my-jetpack${e}`)}function c(){return n()?.site.plan?.features?.active??[]}function s(e){return-1!==c().indexOf(e)}function p(){return"wpcom"===n()?.site?.host}function f(){return"woa"===n()?.site?.host}function d(){return n()?.site?.is_wpcom_platform}function l(){return"unknown"===n()?.site?.host}function m(){return p()?"simple":f()?"woa":"jetpack"}function S(e){return n()?.user.current_user.capabilities[e]}r.d(t,{$8:()=>d,IT:()=>s,KS:()=>m,L2:()=>l,Sy:()=>p,au:()=>n,d_:()=>S,e5:()=>a,hT:()=>i,lI:()=>f,mH:()=>c,oQ:()=>u,sV:()=>o})}};const t={};function r(n){const o=t[n];if(void 0!==o)return o.exports;const i=t[n]={exports:{}};return e[n](i,i.exports,r),i.exports}r.d=(e,t)=>{for(var n in t)r.o(t,n)&&!r.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},r.o=(e,t)=>Object.hasOwn(e,t),r.r=e=>{Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};let n={};r.r(n),r.d(n,{currentUserCan:()=>o.d_,getActiveFeatures:()=>o.mH,getAdminUrl:()=>o.hT,getJetpackAdminPageUrl:()=>o.oQ,getMyJetpackUrl:()=>o.e5,getScriptData:()=>o.au,getSiteData:()=>o.sV,getSiteType:()=>o.KS,isJetpackSelfHostedSite:()=>o.L2,isSimpleSite:()=>o.Sy,isWoASite:()=>o.lI,isWpcomPlatformSite:()=>o.$8,siteHasFeature:()=>o.IT});var o=r(729);return n})());; 3080/** 3081 * Observe how the user enters content into the comment form in order to determine whether it's a bot or not. 3082 * 3083 * Note that no actual input is being saved here, only counts and timings between events. 3084 */ 3085 3086( function() { 3087 // Passive event listeners are guaranteed to never call e.preventDefault(), 3088 // but they're not supported in all browsers. Use this feature detection 3089 // to determine whether they're available for use. 3090 var supportsPassive = false; 3091 3092 try { 3093 var opts = Object.defineProperty( {}, 'passive', { 3094 get : function() { 3095 supportsPassive = true; 3096 } 3097 } ); 3098 3099 window.addEventListener( 'testPassive', null, opts ); 3100 window.removeEventListener( 'testPassive', null, opts ); 3101 } catch ( e ) {} 3102 3103 function init() { 3104 var input_begin = ''; 3105 3106 var keydowns = {}; 3107 var lastKeyup = null; 3108 var lastKeydown = null; 3109 var keypresses = []; 3110 3111 var modifierKeys = []; 3112 var correctionKeys = []; 3113 3114 var lastMouseup = null; 3115 var lastMousedown = null; 3116 var mouseclicks = []; 3117 var mouseclickCoordinates = []; 3118 3119 var mousemoveTimer = null; 3120 var lastMousemoveX = null; 3121 var lastMousemoveY = null; 3122 var lastMousemoveTime = null; 3123 var mousemoveStart = null; 3124 var mousemoves = []; 3125 var intervalsBetweenMousemovesAndClicks = []; 3126 3127 var touchmoveCountTimer = null; 3128 var touchmoveCount = 0; 3129 3130 var lastTouchEnd = null; 3131 var lastTouchStart = null; 3132 var touchEvents = []; 3133 3134 var scrollCountTimer = null; 3135 var scrollCount = 0; 3136 3137 var correctionKeyCodes = [ 'Backspace', 'Delete', 'ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'Home', 'End', 'PageUp', 'PageDown' ]; 3138 var modifierKeyCodes = [ 'Shift', 'CapsLock' ]; 3139 3140 var forms = document.querySelectorAll( 'form[method=post]' ); 3141 3142 for ( var i = 0; i < forms.length; i++ ) { 3143 var form = forms[i]; 3144 3145 var formAction = form.getAttribute( 'action' ); 3146 3147 // Ignore forms that POST directly to other domains; these could be things like payment forms. 3148 if ( formAction ) { 3149 // Check that the form is posting to an external URL, not a path. 3150 if ( formAction.indexOf( 'http://' ) == 0 || formAction.indexOf( 'https://' ) == 0 ) { 3151 if ( formAction.indexOf( 'http://' + window.location.hostname + '/' ) != 0 && formAction.indexOf( 'https://' + window.location.hostname + '/' ) != 0 ) { 3152 continue; 3153 } 3154 } 3155 } 3156 3157 form.addEventListener( 'submit', function () { 3158 var ak_bkp = prepare_array_for_request( keypresses ); 3159 var ak_bmc = prepare_array_for_request( mouseclicks ); 3160 var ak_bte = prepare_array_for_request( touchEvents ); 3161 var ak_bmm = prepare_array_for_request( mousemoves ); 3162 var ak_bcc = prepare_array_for_request( mouseclickCoordinates ); 3163 var ak_bibmac = intervalsBetweenMousemovesAndClicks.slice( 0, 100 ).join( ';' ); 3164 3165 var input_fields = { 3166 // When did the user begin entering any input? 3167 'bib': input_begin, 3168 3169 // When was the form submitted? 3170 'bfs': Date.now(), 3171 3172 // How many keypresses did they make? 3173 'bkpc': keypresses.length, 3174
3175 // How quickly did they press a sample of keys, and how long between them? 3176 'bkp': ak_bkp, 3177 3178 // How quickly did they click the mouse, and how long between clicks? 3179 'bmc': ak_bmc, 3180 3181 // How many mouseclicks did they make? 3182 'bmcc': mouseclicks.length, 3183 3184 // When did they press modifier keys (like Shift or Capslock)? 3185 'bmk': modifierKeys.join( ';' ), 3186 3187 // When did they correct themselves? e.g., press Backspace, or use the arrow keys to move the cursor back 3188 'bck': correctionKeys.join( ';' ), 3189 3190 // How many times did they move the mouse? 3191 'bmmc': mousemoves.length, 3192 3193 // How many times did they move around using a touchscreen? 3194 'btmc': touchmoveCount, 3195 3196 // How many times did they scroll? 3197 'bsc': scrollCount, 3198 3199 // How quickly did they perform touch events, and how long between them? 3200 'bte': ak_bte, 3201 3202 // How many touch events were there? 3203 'btec' : touchEvents.length, 3204 3205 // How quickly did they move the mouse, and how long between moves? 3206 'bmm' : ak_bmm, 3207 3208 // Click coordinates 3209 'bcc' : ak_bcc, 3210 3211 // Milliseconds between last mouse movement and each click 3212 'bibmac' : ak_bibmac 3213 }; 3214 3215 var akismet_field_prefix = 'ak_'; 3216 3217 if ( this.getElementsByClassName ) { 3218 // Check to see if we've used an alternate field name prefix. We store this as an attribute of the container around some of the Akismet fields. 3219 var possible_akismet_containers = this.getElementsByClassName( 'akismet-fields-container' ); 3220 3221 for ( var containerIndex = 0; containerIndex < possible_akismet_containers.length; containerIndex++ ) { 3222 var container = possible_akismet_containers.item( containerIndex ); 3223 3224 if ( container.getAttribute( 'data-prefix' ) ) { 3225 akismet_field_prefix = container.getAttribute( 'data-prefix' ); 3226 break; 3227 } 3228 } 3229 } 3230 3231 for ( var field_name in input_fields ) { 3232 var field = document.createElement( 'input' ); 3233 field.setAttribute( 'type', 'hidden' ); 3234 field.setAttribute( 'name', akismet_field_prefix + field_name ); 3235 field.setAttribute( 'value', input_fields[ field_name ] ); 3236 this.appendChild( field ); 3237 } 3238 }, supportsPassive ? { passive: true } : false ); 3239 3240 form.addEventListener( 'keydown', function ( e ) { 3241 // If you hold a key down, some browsers send multiple keydown events in a row. 3242 // Ignore any keydown events for a key that hasn't come back up yet. 3243 if ( e.key in keydowns ) { 3244 return; 3245 } 3246 3247 var keydownTime = ( new Date() ).getTime(); 3248 keydowns[ e.key ] = [ keydownTime ]; 3249 3250 if ( ! input_begin ) { 3251 input_begin = keydownTime; 3252 } 3253 3254 // In some situations, we don't want to record an interval since the last keypress -- for example, 3255 // on the first keypress, or on a keypress after focus has changed to another element. Normally, 3256 // we want to record the time between the last keyup and this keydown. But if they press a 3257 // key while already pressing a key, we want to record the time between the two keydowns. 3258 3259 var lastKeyEvent = Math.max( lastKeydown, lastKeyup ); 3260 3261 if ( lastKeyEvent ) { 3262 keydowns[ e.key ].push( keydownTime - lastKeyEvent ); 3263 } 3264 3265 lastKeydown = keydownTime; 3266 }, supportsPassive ? { passive: true } : false ); 3267 3268 form.addEventListener( 'keyup', function ( e ) { 3269 if ( ! ( e.key in keydowns ) ) { 3270 // This key was pressed before this script was loaded, or a mouseclick happened during the keypress, or... 3271 return; 3272 } 3273 3274 var keyupTime = ( new Date() ).getTime(); 3275 3276 if ( 'TEXTAREA' === e.target.nodeName || 'INPUT' === e.target.nodeName ) { 3277 if ( -1 !== modifierKeyCodes.indexOf( e.key ) ) { 3278 modifierKeys.push( keypresses.length - 1 ); 3279 } else if ( -1 !== correctionKeyCodes.indexOf( e.key ) ) { 3280 correctionKeys.push( keypresses.length - 1 ); 3281 } else { 3282 // ^ Don't record timings for keys like Shift or backspace, since they 3283 // typically get held down for longer than regular typing. 3284 3285 var keydownTime = keydowns[ e.key ][0]; 3286 3287 var keypress = []; 3288 3289 // Keypress duration. 3290 keypress.push( keyupTime - keydownTime ); 3291 3292 // Amount of time between this keypress and the previous keypress. 3293 if ( keydowns[ e.key ].length > 1 ) { 3294 keypress.push( keydowns[ e.key ][1] ); 3295 } 3296 3297 keypresses.push( keypress ); 3298 } 3299 } 3300
3301 delete keydowns[ e.key ]; 3302 3303 lastKeyup = keyupTime; 3304 }, supportsPassive ? { passive: true } : false ); 3305 3306 form.addEventListener( "focusin", function ( e ) { 3307 lastKeydown = null; 3308 lastKeyup = null; 3309 keydowns = {}; 3310 }, supportsPassive ? { passive: true } : false ); 3311 3312 form.addEventListener( "focusout", function ( e ) { 3313 lastKeydown = null; 3314 lastKeyup = null; 3315 keydowns = {}; 3316 }, supportsPassive ? { passive: true } : false ); 3317 } 3318 3319 document.addEventListener( 'mousedown', function ( e ) { 3320 lastMousedown = ( new Date() ).getTime(); 3321 3322 if ( lastMousemoveTime ) { 3323 intervalsBetweenMousemovesAndClicks.push( lastMousedown - lastMousemoveTime ); 3324 } 3325 3326 var mouseclickCoordinate = []; 3327 3328 var rect = e.target.getBoundingClientRect(); 3329 var relativeX = e.clientX - rect.left; 3330 var relativeY = e.clientY - rect.top; 3331 3332 // Pixel offset of the click within the target element. 3333 mouseclickCoordinate.push( Math.round( relativeX ) ); 3334 mouseclickCoordinate.push( Math.round( relativeY ) ); 3335 3336 // Percentage offset of the click within the target element. 3337 mouseclickCoordinate.push( rect.width > 0 ? Math.round( relativeX / rect.width * 100 ) : 0 ); 3338 mouseclickCoordinate.push( rect.height > 0 ? Math.round( relativeY / rect.height * 100 ) : 0 ); 3339 3340 mouseclickCoordinates.push( mouseclickCoordinate ); 3341 }, supportsPassive ? { passive: true } : false ); 3342 3343 document.addEventListener( 'mouseup', function ( e ) { 3344 if ( ! lastMousedown ) { 3345 // If the mousedown happened before this script was loaded, but the mouseup happened after... 3346 return; 3347 } 3348 3349 var now = ( new Date() ).getTime(); 3350 3351 var mouseclick = []; 3352 mouseclick.push( now - lastMousedown ); 3353 3354 if ( lastMouseup ) { 3355 mouseclick.push( lastMousedown - lastMouseup ); 3356 } 3357 3358 mouseclicks.push( mouseclick ); 3359 3360 lastMouseup = now; 3361 3362 // If the mouse has been clicked, don't record this time as an interval between keypresses. 3363 lastKeydown = null; 3364 lastKeyup = null; 3365 keydowns = {}; 3366 }, supportsPassive ? { passive: true } : false ); 3367 3368 document.addEventListener( 'mousemove', function ( e ) { 3369 lastMousemoveTime = ( new Date() ).getTime(); 3370 3371 if ( mousemoveTimer ) { 3372 clearTimeout( mousemoveTimer ); 3373 mousemoveTimer = null; 3374 } 3375 else { 3376 mousemoveStart = lastMousemoveTime; 3377 lastMousemoveX = e.offsetX; 3378 lastMousemoveY = e.offsetY; 3379 } 3380 3381 mousemoveTimer = setTimeout( function ( theEvent, originalMousemoveStart ) { 3382 var now = ( new Date() ).getTime() - 500; // To account for the timer delay. 3383 3384 var mousemove = []; 3385 mousemove.push( now - originalMousemoveStart ); 3386 mousemove.push( 3387 Math.round( 3388 Math.sqrt( 3389 Math.pow( theEvent.offsetX - lastMousemoveX, 2 ) + 3390 Math.pow( theEvent.offsetY - lastMousemoveY, 2 ) 3391 ) 3392 ) 3393 ); 3394 3395 if ( mousemove[1] > 0 ) { 3396 // If there was no measurable distance, then it wasn't really a move. 3397 mousemoves.push( mousemove ); 3398 } 3399 3400 mousemoveStart = null; 3401 mousemoveTimer = null; 3402 }, 500, e, mousemoveStart ); 3403 }, supportsPassive ? { passive: true } : false ); 3404 3405 document.addEventListener( 'touchmove', function ( e ) { 3406 if ( touchmoveCountTimer ) { 3407 clearTimeout( touchmoveCountTimer ); 3408 } 3409 3410 touchmoveCountTimer = setTimeout( function () { 3411 touchmoveCount++; 3412 }, 500 ); 3413 }, supportsPassive ? { passive: true } : false ); 3414 3415 document.addEventListener( 'touchstart', function ( e ) { 3416 lastTouchStart = ( new Date() ).getTime(); 3417 }, supportsPassive ? { passive: true } : false ); 3418 3419 document.addEventListener( 'touchend', function ( e ) { 3420 if ( ! lastTouchStart ) { 3421 // If the touchstart happened before this script was loaded, but the touchend happened after... 3422 return; 3423 } 3424 3425 var now = ( new Date() ).getTime(); 3426 3427 var touchEvent = []; 3428 touchEvent.push( now - lastTouchStart ); 3429 3430 if ( lastTouchEnd ) { 3431 touchEvent.push( lastTouchStart - lastTouchEnd ); 3432 } 3433 3434 touchEvents.push( touchEvent ); 3435 3436 lastTouchEnd = now; 3437 3438 // Don't record this time as an interval between keypresses. 3439 lastKeydown = null; 3440 lastKeyup = null; 3441 keydowns = {}; 3442 }, supportsPassive ? { passive: true } : false ); 3443 3444 document.addEventListener( 'scroll', function ( e ) {
3445 if ( scrollCountTimer ) { 3446 clearTimeout( scrollCountTimer ); 3447 } 3448 3449 scrollCountTimer = setTimeout( function () { 3450 scrollCount++; 3451 }, 500 ); 3452 }, supportsPassive ? { passive: true } : false ); 3453 } 3454 3455 /** 3456 * For the timing/coordinate data that is collected, don't send more than `limit` data points in the request. 3457 * Choose a random slice and send those, with each batch separated by semicolons and the items in each batch 3458 * separated by commas. 3459 */ 3460 function prepare_array_for_request( a, limit ) { 3461 if ( ! limit ) { 3462 limit = 100; 3463 } 3464 3465 var rv = ''; 3466 3467 if ( a.length > 0 ) { 3468 var random_starting_point = Math.max( 0, Math.floor( Math.random() * a.length - limit ) ); 3469 3470 for ( var i = 0; i < limit && i < a.length; i++ ) { 3471 var entry = a[ random_starting_point + i ]; 3472 rv += entry.join( ',' ) + ';'; 3473 } 3474 } 3475 3476 return rv; 3477 } 3478 3479 if ( document.readyState !== 'loading' ) { 3480 init(); 3481 } else { 3482 document.addEventListener( 'DOMContentLoaded', init ); 3483 } 3484})();; 3485void ( function ( d, s, id ) { 3486 var js, 3487 fjs = d.getElementsByTagName( s )[ 0 ], 3488 p = /^http:/.test( d.location ) ? 'http' : 'https'; 3489 if ( ! d.getElementById( id ) ) { 3490 js = d.createElement( s ); 3491 js.id = id; 3492 js.src = p + '://platform.twitter.com/widgets.js'; 3493 fjs.parentNode.insertBefore( js, fjs ); 3494 } 3495} )( document, 'script', 'twitter-wjs' ); 3496; 3497!function(){var e=document.currentScript;function t(t){var n=document.createElement("script"),o=e||document.getElementsByTagName("script")[0];n.setAttribute("async",!0),n.setAttribute("src",t),o.parentNode.insertBefore(n,o)}function n(e,t){return Element.prototype.matches?e.matches(t):Element.prototype.msMatchesSelector?e.msMatchesSelector(t):void 0}function o(e,t){if(e.closest)return e.closest(t);var o=e;do{if(n(o,t))return o;o=o.parentElement||o.parentNode}while(null!==o&&1===o.nodeType);return null}function i(e,t){for(var n=0;n<e.length;n++)t(e[n],n,e)}var r,s=".sharing-hidden .inner",a="data-sharing-more-button-id";function c(e){this.button=e,this.pane=o(e,"div").querySelector(s),this.openedBy=null,this.recentlyOpenedByHover=!1,c.instances.push(this),this.pane.setAttribute(a,c.instances.length-1),this.attachHandlers()}if(c.instances=[],c.hoverOpenDelay=200,c.recentOpenDelay=400,c.hoverCloseDelay=300,c.instantiateOrReuse=function(e){var t=o(e,"div").querySelector(s),n=t&&t.getAttribute(a),i=c.instances[n];return i||new c(e)},c.getButtonInstanceFromPane=function(e){var t=e&&e.getAttribute(a);return c.instances[t]},c.closeAll=function(){for(var e=0;e<c.instances.length;e++)c.instances[e].close()},c.prototype.open=function(){var e,t,n=[0,0];function o(e){var t=e.getBoundingClientRect();return[t.left+(window.scrollX||window.pageXOffset||0),t.top+(window.scrollY||window.pageYOffset||0)]}function i(e,t){return parseInt(getComputedStyle(e).getPropertyValue(t)||0)}for(e=o(this.button),t=this.button.offsetParent||document.documentElement;t&&(t===document.body||t===document.documentElement)&&"static"===getComputedStyle(t).getPropertyValue("position");)t=t.parentNode;t&&t!==this.button&&1===t.nodeType&&(n=[(n=o(t))[0]+i(t,"border-left-width"),n[1]+i(t,"border-top-width")]);var r,s=e[0]-n[0]-i(this.button,"margin-left"),a=e[1]-n[1]-i(this.button,"margin-top");this.pane.style.left=s+"px",this.pane.style.top=a+this.button.offsetHeight+3+"px",(r=this.pane)&&r.style.removeProperty("display")},c.prototype.close=function(){var e;(e=this.pane)&&(e.style.display="none"),this.openedBy=null},c.prototype.toggle=function(){var e;(e=this.pane)&&"none"!==e.style.display?this.close():this.open()},c.prototype.nonHoverOpen=function(){clearTimeout(this.openTimer),clearTimeout(this.closeTimer),this.recentlyOpenedByHover?(this.recentlyOpenedByHover=!1,clearTimeout(this.hoverOpenTimer),this.open()):this.toggle()},c.prototype.resetCloseTimer=function(){clearTimeout(this.closeTimer),this.closeTimer=setTimeout(this.close.bind(this),c.hoverCloseDelay)},c.prototype.attachHandlers=function(){this.buttonClick=function(e){e.preventDefault(),e.stopPropagation(),this.openedBy="click",this.nonHoverOpen()}.bind(this),this.buttonKeydown=function(e){13!==e.keyCode&&32!==e.keyCode||(e.preventDefault(),e.stopPropagation(),this.openedBy="keydown",this.nonHoverOpen())}.bind(this),this.buttonEnter=function(){this.openedBy||(this.openTimer=setTimeout(function(){this.open(),this.openedBy="hover",this.recentlyOpenedByHover=!0,this.hoverOpenTimer=setTimeout(function(){this.recentlyOpenedByHover=!1}.bind(this),c.recentOpenDelay)}.bind(this),c.hoverOpenDelay)),clearTimeout(this.closeTimer)}.bind(this),this.buttonLeave=function(){"hover"===this.openedBy&&this.resetCloseTimer(),clearTimeout(this.openTimer)}.bind(this),this.paneEnter=function(){clearTimeout(this.closeTimer)}.bind(this),this.paneLeave=function(){"hover"===this.openedBy&&this.resetCloseTimer()}.bind(this),this.documentClick=function(){this.close()}.bind(this),this.button.addEventListener("click",this.buttonClick),this.button.addEventListener("keydown",this.buttonKeydown),document.addEventListener("click",this.documentClick),void 0===document.ontouchstart&&(this.button.addEventListener("mouseenter",this.buttonEnter),this.button.addEventListener("mouseleave",this.buttonLeave),this.pane.addEventListener("mouseenter",this.paneEnter),this.pane.addEventListener("mouseleave",this.paneLeave))},window.sharing_js_options&&window.sharing_js_options.counts){var u={done_urls:[],get_counts:function(){var e,n,o,i,r;if("undefined"!=typeof WPCOM_sharing_counts)for(e in WPCOM_sharing_counts)if(o=WPCOM_sharing_counts[e],void 0===u.done_urls[o]){for(i in n={pinterest:[window.location.protocol+"//api.pinterest.com/v1/urls/count.json?callback=WPCOMSharing.update_pinterest_count&url="+encodeURIComponent(e)]})if(document.querySelector("a[data-shared=sharing-"+i+"-"+o+"]")){for(;r=n[i].pop();)t(r);window.sharing_js_options.is_stats_active&&u.bump_sharing_count_stat(i)}u.done_urls[o]=!0}},update_pinterest_count:function(e){void 0!==e.count&&1*e.count>0&&u.inject_share_count("sharing-pinterest-"+WPCOM_sharing_counts[e.url],e.count)},inject_share_count:function(e,t){i(document.querySelectorAll("a[data-shared="+e+"] > span"),function(e){var n,o=e.querySelector(".share-count");(n=o)&&n.parentNode&&n.parentNode.removeChild(n);var i=document.createElement("span");
3497i.className="share-count",i.textContent=u.format_count(t),e.appendChild(i)})},format_count:function(e){return e<1e3?e:e>=1e3&&e<1e4?String(e).substring(0,1)+"K+":"10K+"},bump_sharing_count_stat:function(e){(new Image).src=document.location.protocol+"//pixel.wp.com/g.gif?v=wpcom-no-pv&x_sharing-count-request="+e+"&r="+Math.random()}};window.WPCOMSharing=u}function d(e,t){e.setAttribute("jetpack-share-click-count",t)}function l(e){var t=e.getAttribute("jetpack-share-click-count");return null===t?0:parseInt(t,10)}function h(e,t){var n,o=new XMLHttpRequest;o.open("POST",e,!0),o.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8"),o.setRequestHeader("x-requested-with","XMLHttpRequest"),o.send((n=t,(encodeURIComponent("email-share-nonce")+"="+encodeURIComponent(n)).replace(/%20/g,"+")))}function p(){m()}function m(){window.WPCOMSharing&&window.WPCOMSharing.get_counts(),i(document.querySelectorAll(".sharedaddy a"),function(e){var t=e.getAttribute("href");t&&-1!==t.indexOf("share=")&&-1===t.indexOf("&nb=1")&&e.setAttribute("href",t+"&nb=1")}),i(document.querySelectorAll(".sharedaddy a.sharing-anchor"),function(e){c.instantiateOrReuse(e)}),void 0!==document.ontouchstart&&document.body.classList.add("jp-sharing-input-touch"),i(document.querySelectorAll(".sharedaddy ul"),function(e){"true"!==e.getAttribute("data-sharing-events-added")&&(e.setAttribute("data-sharing-events-added","true"),i(e.querySelectorAll("a.share-print"),function(e){e.addEventListener("click",function(t){t.preventDefault(),t.stopPropagation();var n=e.getAttribute("href")||"",i=function(){if(-1===n.indexOf("#print")){var e=(new Date).getTime();t=e,o=n,(i=document.createElement("iframe")).setAttribute("style","position:fixed; top:100; left:100; height:1px; width:1px; border:none;"),i.setAttribute("id","printFrame-"+t),i.setAttribute("name",i.getAttribute("id")),i.setAttribute("src",o),i.setAttribute("onload",'frames["printFrame-'+t+'"].focus();frames["printFrame-'+t+'"].print();'),document.body.appendChild(i)}else window.print();var t,o,i},r=o(e,s);if(r){var a=c.getButtonInstanceFromPane(r);a&&(a.close(),i())}else i()})}),i(e.querySelectorAll("a.share-press-this"),function(e){var t="wp-press-this-"+Math.random().toString(36).slice(2);e.addEventListener("click",function(n){n.preventDefault(),n.stopPropagation();var o="";if(window.getSelection?o=window.getSelection():document.getSelection?o=document.getSelection():document.selection&&(o=document.selection.createRange().text),o){var i=e.getAttribute("href");e.setAttribute("href",i+"&sel="+encodeURI(o))}window.open(e.getAttribute("href"),t,"toolbar=0,resizable=1,scrollbars=1,status=1,width=720,height=570")||(document.location.href=e.getAttribute("href"))})}),i(e.querySelectorAll("a.share-email"),function(t){d(t,0);var n,o,r=t.getAttribute("data-email-share-nonce"),s=t.getAttribute("data-email-share-track-url");r&&s&&(n=s,o=window.location.protocol+"//"+window.location.hostname+"/",0===String(n).indexOf(o))&&t.addEventListener("click",function(){var n;d(n=t,l(n)+1),l(t)>2&&function(e,t){var n=t.parentElement;if(n.classList.contains("sd-content")){i(n.querySelectorAll(".share-email-error"),function(e){e.parentElement.removeChild(e)});var o=document.createElement("div");o.className="share-email-error";var r=document.createElement("h6");r.className="share-email-error-title",r.innerText=e.getAttribute("data-email-share-error-title"),o.appendChild(r);var s=document.createElement("p");s.className="share-email-error-text",s.innerText=e.getAttribute("data-email-share-error-text"),o.appendChild(s),n.appendChild(o)}}(t,e),h(s,r)})}))}),i(document.querySelectorAll("li.share-email, li.share-custom a.sharing-anchor"),function(e){e.classList.add("share-service-visible")})}"loading"!==document.readyState?p():document.addEventListener("DOMContentLoaded",p),document.body.addEventListener("is.post-load",m);var f={};!0!==window.WPCOM_sharing_popups_bound&&(document.body.addEventListener("click",function(e){var t=e.target;if(t&&1===t.nodeType){var n=function(e){if("A"===e.nodeName)return e;var t=e.parentNode;return t&&"A"===t.nodeName?t:null}(t);if(n){var o=function(e){var t=window.WPCOM_sharing_popups;if(!t)return null;for(var n="share-",o=(e.getAttribute("class")||"").split(/\s+/),i=0;i<o.length;i++)if(0===o[i].indexOf(n)){var r=o[i].slice(6);if("string"==typeof t[r])return r}return null}(n);o&&(e.preventDefault(),r&&r.close(),r=window.open(n.getAttribute("href"),function(e){return"string"!=typeof f[e]&&(f[e]="wpcom"+e+"-"+Math.random().toString(36).slice(2)),f[e]}(o),window.WPCOM_sharing_popups[o]))}}}
3497),window.WPCOM_sharing_popups_bound=!0)}();;
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.