1(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ 2'use strict'; 3 4/*! 5 * Webflow: Front-end site library 6 * @license MIT 7 * Inline scripts may access the api using an async handler: 8 * var Webflow = Webflow || []; 9 * Webflow.push(readyFunction); 10 */ 11 12var Webflow = require('./webflow-lib'); 13window.Webflow = Webflow; 14var define = Webflow.define; 15 16/** 17 * Webflow: Front-end modules 18 */ 19define('ix' , require('./webflow-ix')); 20define('touch' , require('./webflow-touch')); 21define('forms' , require('./webflow-forms')); 22define('maps' , require('./webflow-maps')); 23define('gplus' , require('./webflow-gplus')); 24define('scroll' , require('./webflow-scroll')); 25define('links' , require('./webflow-links')); 26define('slider' , require('./webflow-slider')); 27define('lightbox' , require('./webflow-lightbox')); 28define('navbar' , require('./webflow-navbar')); 29define('dropdown' , require('./webflow-dropdown')); 30define('tabs' , require('./webflow-tabs')); 31define('brand' , require('./webflow-brand')); 32 33 34 35},{"./webflow-brand":2,"./webflow-dropdown":3,"./webflow-forms":4,"./webflow-gplus":5,"./webflow-ix":6,"./webflow-lib":7,"./webflow-lightbox":8,"./webflow-links":9,"./webflow-maps":10,"./webflow-navbar":11,"./webflow-scroll":12,"./webflow-slider":13,"./webflow-tabs":14,"./webflow-touch":15}],2:[function(require,module,exports){ 36'use strict'; 37 38/** 39 * Webflow: Brand pages on the subdomain 40 */ 41 42var Webflow = require('./webflow-lib'); 43 44module.exports = function($, _) { 45 var api = {}; 46 var $html = $('html'); 47 var $body = $('body'); 48 var location = window.location; 49 var inApp = Webflow.env(); 50 51 // ----------------------------------- 52 // Module methods 53 54 api.ready = function() { 55 var doBranding = $html.attr("data-wf-status"); 56 57 if (doBranding) { 58 var $branding = $('<div></div>'); 59 var $link = $('<a></a>'); 60 $link.attr('href', 'http://webflow.com?utm_campaign=brandjs'); 61 62 $branding.css({ 63 position: 'fixed', 64 bottom: 0, 65 right: 0, 66 borderTop: '5px solid #2b3239', 67 borderLeft: '5px solid #2b3239', 68 borderTopLeftRadius: '5px', 69 backgroundColor: '#2b3239', 70 padding: '5px 5px 5px 10px', 71 fontFamily: 'Arial', 72 fontSize: '10px', 73 textTransform: 'uppercase', 74 opacity: '0', 75 transition: 'opacity 0.50s ease-in-out' 76 }); 77 78 $link.css({ 79 color: '#AAADB0', 80 textDecoration: 'none' 81 }); 82 83 var $webflowLogo = $('<img>'); 84 $webflowLogo.attr('src', 'https://daks2k3a4ib2z.cloudfront.net/54153e6a3d25f2755b1f14ed/5445a4b1944ecdaa4df86d3e_subdomain-brand.svg'); 85 $webflowLogo.css({ 86 opacity: 0.9, 87 width: '55px', 88 verticalAlign: 'middle', 89 paddingLeft: '4px', 90 paddingBottom: '3px' 91 }); 92 93 $branding.text('Built with'); 94 $branding.append($webflowLogo); 95 $link.append($branding); 96 97 $body.append($link); 98 99 if (/PhantomJS/.test(window.navigator.userAgent)) { 100 return; 101 } 102 103 $branding.css({ 104 opacity: '1.0' 105 }); 106 } 107 }; 108 109 // Export module 110 return api; 111}; 112 113},{"./webflow-lib":7}],3:[function(require,module,exports){ 114'use strict'; 115 116/** 117 * Webflow: Dropdown component 118 */ 119 120var Webflow = require('./webflow-lib'); 121 122module.exports = function($, _) { 123 var api = {}; 124 var tram = $.tram; 125 var $doc = $(document); 126 var $dropdowns; 127 var designer; 128 var inApp = Webflow.env(); 129 var namespace = '.w-dropdown'; 130 var stateOpen = 'w--open'; 131 var closeEvent = 'w-close' + namespace; 132 var ix = Webflow.ixEvents(); 133 134 // ----------------------------------- 135 // Module methods 136 137 api.ready = api.design = api.preview = init; 138 139 // ----------------------------------- 140 // Private methods 141
142 function init() { 143 designer = inApp && Webflow.env('design'); 144 145 // Find all instances on the page 146 $dropdowns = $doc.find(namespace); 147 $dropdowns.each(build); 148 } 149 150 function build(i, el) { 151 var $el = $(el); 152 153 // Store state in data 154 var data = $.data(el, namespace); 155 if (!data) data = $.data(el, namespace, { open: false, el: $el, config: {} }); 156 data.list = $el.children('.w-dropdown-list'); 157 data.toggle = $el.children('.w-dropdown-toggle'); 158 data.links = data.list.children('.w-dropdown-link'); 159 data.outside = outside(data); 160 data.complete = complete(data); 161 162 // Remove old events 163 $el.off(namespace); 164 data.toggle.off(namespace); 165 166 // Set config from data attributes 167 configure(data); 168 169 if (data.nav) data.nav.off(namespace); 170 data.nav = $el.closest('.w-nav'); 171 data.nav.on(closeEvent, handler(data)); 172 173 // Add events based on mode 174 if (designer) { 175 $el.on('setting' + namespace, handler(data)); 176 } else { 177 data.toggle.on('tap' + namespace, toggle(data)); 178 $el.on(closeEvent, handler(data)); 179 // Close in preview mode 180 inApp && close(data); 181 } 182 } 183 184 function configure(data) { 185 data.config = { 186 hover: +data.el.attr('data-hover'), 187 delay: +data.el.attr('data-delay') || 0 188 }; 189 } 190 191 function handler(data) { 192 return function(evt, options) { 193 options = options || {}; 194 195 if (evt.type == 'w-close') { 196 return close(data); 197 } 198 199 if (evt.type == 'setting') { 200 configure(data); 201 options.open === true && open(data, true); 202 options.open === false && close(data, true); 203 return; 204 } 205 }; 206 } 207 208 function toggle(data) { 209 return _.debounce(function(evt) { 210 data.open ? close(data) : open(data); 211 }); 212 } 213 214 function open(data, immediate) { 215 if (data.open) return; 216 closeOthers(data); 217 data.open = true; 218 data.list.addClass(stateOpen); 219 data.toggle.addClass(stateOpen); 220 ix.intro(0, data.el[0]); 221 Webflow.redraw.up(); 222 223 // Listen for tap outside events 224 if (!designer) $doc.on('tap' + namespace, data.outside); 225 226 // Clear previous delay 227 window.clearTimeout(data.delayId); 228 } 229 230 function close(data, immediate) { 231 if (!data.open) return; 232 data.open = false; 233 var config = data.config; 234 ix.outro(0, data.el[0]); 235 236 // Stop listening for tap outside events 237 $doc.off('tap' + namespace, data.outside); 238 239 // Clear previous delay 240 window.clearTimeout(data.delayId); 241 242 // Skip delay during immediate 243 if (!config.delay || immediate) return data.complete(); 244 245 // Optionally wait for delay before close 246 data.delayId = window.setTimeout(data.complete, config.delay); 247 } 248 249 function closeOthers(data) { 250 var self = data.el[0]; 251 $dropdowns.each(function(i, other) { 252 var $other = $(other); 253 if ($other.is(self) || $other.has(self).length) return; 254 $other.triggerHandler(closeEvent); 255 }); 256 } 257 258 function outside(data) { 259 // Unbind previous tap handler if it exists 260 if (data.outside) $doc.off('tap' + namespace, data.outside); 261 262 // Close menu when tapped outside 263 return _.debounce(function(evt) { 264 if (!data.open) return; 265 var $target = $(evt.target); 266 if ($target.closest('.w-dropdown-toggle').length) return; 267 if (!data.el.is($target.closest(namespace))) { 268 close(data); 269 } 270 }); 271 } 272 273 function complete(data) { 274 return function() { 275 data.list.removeClass(stateOpen); 276 data.toggle.removeClass(stateOpen); 277 }; 278 } 279 280 // Export module 281 return api; 282}; 283 284},{"./webflow-lib":7}],4:[function(require,module,exports){ 285'use strict'; 286 287/** 288 * Webflow: Forms 289 */ 290 291var Webflow = require('./webflow-lib'); 292 293module.exports = function($, _) { 294 var api = {}; 295 296 // Cross-Domain AJAX for IE8 297 require('../plugins/xdomain-min'); 298 299 var FORM_API_HOST = 'https://webflow.com'; 300 var FORM_SUBMIT_HOST = 'https://webflow.com'; 301 var FORM_OLDIE_HOST = 'http://formdata.webflow.com'; 302 303 var $doc = $(document); 304 var $forms; 305 var loc = window.location; 306 var retro = window.XDomainRequest && !window.atob; 307 var namespace = '.w-form'; 308 var siteId; 309 var emailField = /e(\-)?mail/i; 310 var emailValue = /^\S+@\S+$/; 311 var alert = window.alert; 312 var listening; 313 314 // MailChimp domains: list-manage.com + mirrors 315 var chimpRegex = /list-manage[1-9]?.com/i; 316 317 api.ready = function() { 318 // Init forms 319 init(); 320 321 // Wire document events once 322 if (!listening) addListeners(); 323 }; 324 325 api.preview = api.design = function() { 326 init(); 327 }; 328
329 function init() { 330 siteId = $('html').attr('data-wf-site'); 331 332 $forms = $(namespace + ' form'); 333 if (!$forms.length) return; 334 $forms.each(build); 335 } 336 337 function build(i, el) { 338 // Store form state using namespace 339 var $el = $(el); 340 var data = $.data(el, namespace); 341 if (!data) data = $.data(el, namespace, { form: $el }); // data.form 342 343 reset(data); 344 var wrap = $el.closest('div.w-form'); 345 data.done = wrap.find('> .w-form-done'); 346 data.fail = wrap.find('> .w-form-fail'); 347 348 var action = data.action = $el.attr('action'); 349 data.handler = null; 350 data.redirect = $el.attr('data-redirect'); 351 352 // MailChimp form 353 if (chimpRegex.test(action)) { data.handler = submitMailChimp; return; } 354 355 // Custom form action 356 if (action) return; 357 358 // Webflow form 359 if (siteId) { data.handler = submitWebflow; return; } 360 361 // Alert for disconnected Webflow forms 362 disconnected(); 363 } 364 365 function addListeners() { 366 listening = true; 367 368 // Handle form submission for Webflow forms 369 $doc.on('submit', namespace + ' form', function(evt) { 370 var data = $.data(this, namespace); 371 if (data.handler) { 372 data.evt = evt; 373 data.handler(data); 374 } 375 }); 376 } 377 378 // Reset data common to all submit handlers 379 function reset(data) { 380 var btn = data.btn = data.form.find(':input[type="submit"]'); 381 data.wait = data.btn.attr('data-wait') || null; 382 data.success = false; 383 btn.prop('disabled', false); 384 data.label && btn.val(data.label); 385 } 386 387 // Disable submit button 388 function disableBtn(data) { 389 var btn = data.btn; 390 var wait = data.wait; 391 btn.prop('disabled', true); 392 // Show wait text and store previous label 393 if (wait) { 394 data.label = btn.val(); 395 btn.val(wait); 396 } 397 } 398 399 // Find form fields, validate, and set value pairs 400 function findFields(form, result) { 401 var status = null; 402 result = result || {}; 403 404 // The ":input" selector is a jQuery shortcut to select all inputs, selects, textareas 405 form.find(':input:not([type="submit"])').each(function(i, el) { 406 var field = $(el); 407 var type = field.attr('type'); 408 var name = field.attr('data-name') || field.attr('name') || ('Field ' + (i + 1)); 409 var value = field.val(); 410 411 if (type == 'checkbox') { 412 value = field.is(':checked'); 413 } if (type == 'radio') { 414 // Radio group value already processed 415 if (result[name] === null || typeof result[name] == 'string') { 416 return; 417 } 418 419 value = form.find('input[name="' + field.attr('name') + '"]:checked').val() || null; 420 } 421 422 if (typeof value == 'string') value = $.trim(value); 423 result[name] = value; 424 status = status || getStatus(field, name, value); 425 }); 426 427 return status; 428 } 429 430 function getStatus(field, name, value) { 431 var status = null; 432 if (!field.attr('required')) return null; 433 if (!value) status = 'Please fill out the required field: ' + name; 434 else if (emailField.test(name) || emailField.test(field.attr('type'))) { 435 if (!emailValue.test(value)) status = 'Please enter a valid email address for: ' + name; 436 } 437 return status; 438 } 439 440 // Submit form to Webflow 441 function submitWebflow(data) { 442 reset(data); 443 444 var form = data.form; 445 var payload = { 446 name: form.attr('data-name') || form.attr('name') || 'Untitled Form', 447 source: loc.href, 448 test: Webflow.env(), 449 fields: {} 450 }; 451 452 preventDefault(data); 453 454 // Find & populate all fields 455 var status = findFields(form, payload.fields); 456 if (status) return alert(status); 457 458 // Disable submit button 459 disableBtn(data); 460 461 // Read site ID 462 // NOTE: If this site is exported, the HTML tag must retain the data-wf-site attribute for forms to work 463 if (!siteId) { afterSubmit(data); return; } 464 var url = FORM_API_HOST + '/api/v1/form/' + siteId; 465 466 // Work around same-protocol IE XDR limitation - without this IE9 and below forms won't submit 467 if (retro && url.indexOf(FORM_SUBMIT_HOST) >= 0) { 468 url = url.replace(FORM_SUBMIT_HOST, FORM_OLDIE_HOST); 469 } 470 471 $.ajax({
472 url: url, 473 type: 'POST', 474 data: payload, 475 dataType: 'json', 476 crossDomain: true 477 }).done(function() { 478 data.success = true; 479 afterSubmit(data); 480 }).fail(function() { 481 afterSubmit(data); 482 }); 483 } 484 485 // Submit form to MailChimp 486 function submitMailChimp(data) { 487 reset(data); 488 489 var form = data.form; 490 var payload = {}; 491 492 // Skip Ajax submission if http/s mismatch, fallback to POST instead 493 if (/^https/.test(loc.href) && !/^https/.test(data.action)) { 494 form.attr('method', 'post'); 495 return; 496 } 497 498 preventDefault(data); 499 500 // Find & populate all fields 501 var status = findFields(form, payload); 502 if (status) return alert(status); 503 504 // Disable submit button 505 disableBtn(data); 506 507 // Use special format for MailChimp params 508 var fullName; 509 _.each(payload, function(value, key) { 510 if (emailField.test(key)) payload.EMAIL = value; 511 if (/^((full[ _-]?)?name)$/i.test(key)) fullName = value; 512 if (/^(first[ _-]?name)$/i.test(key)) payload.FNAME = value; 513 if (/^(last[ _-]?name)$/i.test(key)) payload.LNAME = value; 514 }); 515 516 if (fullName && !payload.FNAME) { 517 fullName = fullName.split(' '); 518 payload.FNAME = fullName[0]; 519 payload.LNAME = payload.LNAME || fullName[1]; 520 } 521 522 // Use the (undocumented) MailChimp jsonp api 523 var url = data.action.replace('/post?', '/post-json?') + '&c=?'; 524 // Add special param to prevent bot signups 525 var userId = url.indexOf('u=')+2; 526 userId = url.substring(userId, url.indexOf('&', userId)); 527 var listId = url.indexOf('id=')+3; 528 listId = url.substring(listId, url.indexOf('&', listId)); 529 payload['b_' + userId + '_' + listId] = ''; 530 531 $.ajax({
532 url: url, 533 data: payload, 534 dataType: 'jsonp' 535 }).done(function(resp) { 536 data.success = (resp.result == 'success' || /already/.test(resp.msg)); 537 if (!data.success) console.info('MailChimp error: ' + resp.msg); 538 afterSubmit(data); 539 }).fail(function() { 540 afterSubmit(data); 541 }); 542 } 543 544 // Common callback which runs after all Ajax submissions 545 function afterSubmit(data) { 546 var form = data.form; 547 var wrap = form.closest('div.w-form'); 548 var redirect = data.redirect; 549 var success = data.success; 550 551 // Redirect to a success url if defined 552 if (success && redirect) { 553 Webflow.location(redirect); 554 return; 555 } 556 557 // Show or hide status divs 558 data.done.toggle(success); 559 data.fail.toggle(!success); 560 561 // Hide form on success 562 form.toggle(!success); 563 564 // Reset data and enable submit button 565 reset(data); 566 } 567 568 function preventDefault(data) { 569 data.evt && data.evt.preventDefault(); 570 data.evt = null; 571 } 572 573 var disconnected = _.debounce(function() { 574 alert('Oops! This page has improperly configured forms. Please contact your website administrator to fix this issue.'); 575 }, 100); 576 577 // Export module 578 return api; 579}; 580 581},{"../plugins/xdomain-min":18,"./webflow-lib":7}],5:[function(require,module,exports){ 582'use strict'; 583 584/** 585 * Webflow: Google+ widget 586 */ 587 588var Webflow = require('./webflow-lib'); 589 590module.exports = function($, _) { 591 var $doc = $(document); 592 var api = {}; 593 var loaded; 594 595 api.ready = function() { 596 // Load Google+ API on the front-end 597 if (!Webflow.env() && !loaded) init(); 598 }; 599 600 function init() { 601 $doc.find('.w-widget-gplus').length && load(); 602 } 603 604 function load() { 605 loaded = true; 606 $.getScript('https://apis.google.com/js/plusone.js'); 607 } 608 609 // Export module 610 return api; 611}; 612 613},{"./webflow-lib":7}],6:[function(require,module,exports){ 614'use strict'; 615 616/** 617 * Webflow: Interactions 618 */ 619 620var Webflow = require('./webflow-lib'); 621 622module.exports = function($, _) { 623 var api = {}; 624 var designer; 625 var $win = $(window); 626 var namespace = '.w-ix'; 627 var tram = $.tram; 628 var env = Webflow.env; 629 var inApp = env(); 630 var emptyFix = env.chrome && env.chrome < 35; 631 var transNone = 'none 0s ease 0s'; 632 var introEvent = 'w-ix-intro' + namespace; 633 var outroEvent = 'w-ix-outro' + namespace; 634 var fallbackProps = /width|height/; 635 var eventQueue = []; 636 var $subs = $(); 637 var config = {}; 638 var anchors = []; 639 var loads = []; 640 var readys = []; 641 var destroyed; 642 643 // Component types and proxy selectors 644 var components = { 645 tabs: '.w-tab-link, .w-tab-pane', 646 dropdown: '.w-dropdown', 647 slider: '.w-slide', 648 navbar: '.w-nav' 649 }; 650 651 // ----------------------------------- 652 // Module methods 653 654 api.init = function(list) { 655 setTimeout(function() { configure(list); }, 1); 656 }; 657 658 api.preview = function() { 659 designer = false; 660 setTimeout(function() { configure(window.__wf_ix); }, 1); 661 }; 662 663 api.design = function() { 664 designer = true; 665 api.destroy(); 666 }; 667 668 api.destroy = function() { 669 destroyed = true; 670 $subs.each(teardown); 671 Webflow.scroll.off(scroll); 672 asyncEvents(); 673 anchors = []; 674 loads = []; 675 readys = []; 676 }; 677 678 api.ready = function() { 679 // Ready should only be used after destroy, as a way to re-init 680 if (config && destroyed) { 681 destroyed = false; 682 init(); 683 } 684 }; 685 686 api.run = run; 687 api.events = {}; 688 api.style = inApp ? styleApp : stylePub; 689 690 // ----------------------------------- 691 // Private methods 692 693 function configure(list) { 694 if (!list) return; 695 696 // Map all interactions by slug 697 config = {}; 698 _.each(list, function(item) { 699 config[item.slug] = item.value; 700 }); 701 702 // Init ix after config 703 init(); 704 } 705 706 function init() { 707 // Build each element's interaction keying from data attribute 708 var els = $('[data-ix]'); 709 if (!els.length) return; 710 els.each(teardown); 711 els.each(build);
712 713 // Listen for scroll events if any anchors exist 714 if (anchors.length) { 715 Webflow.scroll.on(scroll); 716 setTimeout(scroll, 1); 717 } 718 719 // Handle loads or readys if they exist 720 if (loads.length) Webflow.load(runLoads); 721 if (readys.length) setTimeout(runReadys, 1); 722 723 // Trigger queued events, must happen after init 724 initEvents(); 725 } 726 727 function build(i, el) { 728 var $el = $(el); 729 var id = $el.attr('data-ix'); 730 var ix = config[id]; 731 if (!ix) return; 732 var triggers = ix.triggers; 733 if (!triggers) return; 734 735 // Set styles immediately to provide tram with starting transform values 736 api.style($el, ix.style); 737 738 _.each(triggers, function(trigger) { 739 var state = {}; 740 var type = trigger.type; 741 var stepsB = trigger.stepsB && trigger.stepsB.length; 742 743 function runA() { run(trigger, $el, { group: 'A' }); } 744 function runB() { run(trigger, $el, { group: 'B' }); } 745 746 if (type == 'load') { 747 (trigger.preload && !inApp) ? loads.push(runA) : readys.push(runA); 748 return; 749 } 750 751 if (type == 'click') { 752 $el.on('click' + namespace, function(evt) { 753 // Avoid late clicks on touch devices 754 if (!Webflow.validClick(evt.currentTarget)) return; 755 756 // Prevent default on empty hash urls 757 if ($el.attr('href') === '#') evt.preventDefault(); 758 759 run(trigger, $el, { group: state.clicked ? 'B' : 'A' }); 760 if (stepsB) state.clicked = !state.clicked; 761 }); 762 $subs = $subs.add($el); 763 return; 764 } 765 766 if (type == 'hover') { 767 $el.on('mouseenter' + namespace, runA); 768 $el.on('mouseleave' + namespace, runB); 769 $subs = $subs.add($el); 770 return; 771 } 772 773 if (type == 'scroll') { 774 anchors.push({ 775 el: $el, trigger: trigger, state: { active: false }, 776 offsetTop: convert(trigger.offsetTop), 777 offsetBot: convert(trigger.offsetBot) 778 }); 779 return; 780 } 781 782 // Check for a proxy component selector 783 // type == [tabs, dropdown, slider, navbar] 784 var proxy = components[type]; 785 if (proxy) { 786 var $proxy = $el.closest(proxy); 787 $proxy.on(introEvent, runA).on(outroEvent, runB); 788 $subs = $subs.add($proxy); 789 return; 790 } 791 }); 792 } 793 794 function convert(offset) { 795 if (!offset) return 0; 796 offset = offset + ''; 797 var result = parseInt(offset, 10); 798 if (result !== result) return 0; 799 if (offset.indexOf('%') > 0) { 800 result = result / 100; 801 if (result >= 1) result = 0.999; 802 } 803 return result; 804 } 805 806 function teardown(i, el) { 807 $(el).off(namespace); 808 } 809 810 function scroll() { 811 var viewTop = $win.scrollTop(); 812 var viewHeight = $win.height(); 813 814 // Check each anchor for a valid scroll trigger 815 var count = anchors.length; 816 for (var i = 0; i < count; i++) { 817 var anchor = anchors[i]; 818 var $el = anchor.el; 819 var trigger = anchor.trigger; 820 var stepsB = trigger.stepsB && trigger.stepsB.length; 821 var state = anchor.state; 822 var top = $el.offset().top; 823 var height = $el.outerHeight(); 824 var offsetTop = anchor.offsetTop; 825 var offsetBot = anchor.offsetBot; 826 if (offsetTop < 1 && offsetTop > 0) offsetTop *= viewHeight; 827 if (offsetBot < 1 && offsetBot > 0) offsetBot *= viewHeight; 828 var active = (top + height - offsetTop >= viewTop && top + offsetBot <= viewTop + viewHeight); 829 if (active === state.active) continue; 830 if (active === false && !stepsB) continue; 831 state.active = active; 832 run(trigger, $el, { group: active ? 'A' : 'B' }); 833 } 834 } 835 836 function runLoads() { 837 var count = loads.length; 838 for (var i = 0; i < count; i++) { 839 loads[i](); 840 } 841 } 842 843 function runReadys() { 844 var count = readys.length; 845 for (var i = 0; i < count; i++) { 846 readys[i](); 847 } 848 } 849 850 function run(trigger, $el, opts, replay) { 851 opts = opts || {}; 852 var done = opts.done; 853
854 // Do not run in designer unless forced 855 if (designer && !opts.force) return; 856 857 // Operate on a set of grouped steps 858 var group = opts.group || 'A'; 859 var loop = trigger['loop' + group]; 860 var steps = trigger['steps' + group]; 861 if (!steps || !steps.length) return; 862 if (steps.length < 2) loop = false; 863 864 // One-time init before any loops 865 if (!replay) { 866 867 // Find selector within element descendants, siblings, or query whole document 868 var selector = trigger.selector; 869 if (selector) { 870 $el = ( 871 trigger.descend ? $el.find(selector) : 872 trigger.siblings ? $el.siblings(selector) : 873 $(selector) 874 ); 875 if (inApp) $el.attr('data-ix-affect', 1); 876 } 877 878 // Apply empty fix for certain Chrome versions 879 if (emptyFix) $el.addClass('w-ix-emptyfix'); 880 } 881 882 var _tram = tram($el); 883 884 // Add steps 885 var meta = {}; 886 for (var i = 0; i < steps.length; i++) { 887 addStep(_tram, steps[i], meta); 888 } 889 890 function fin() { 891 // Run trigger again if looped 892 if (loop) return run(trigger, $el, opts, true); 893 894 // Reset any 'auto' values 895 if (meta.width == 'auto') _tram.set({ width: 'auto' }); 896 if (meta.height == 'auto') _tram.set({ height: 'auto' }); 897 898 // Run callback 899 done && done(); 900 } 901 902 // Add final step to queue if tram has started 903 meta.start ? _tram.then(fin) : fin(); 904 } 905 906 function addStep(_tram, step, meta) { 907 var addMethod = 'add'; 908 var startMethod = 'start'; 909 910 // Once the transition has started, we will always use then() to add to the queue. 911 if (meta.start) addMethod = startMethod = 'then'; 912 913 // Parse transitions string on the current step 914 var transitions = step.transition; 915 if (transitions) { 916 transitions = transitions.split(','); 917 for (var i = 0; i < transitions.length; i++) { 918 var transition = transitions[i]; 919 var options = fallbackProps.test(transition) ? { fallback: true } : null; 920 _tram[addMethod](transition, options); 921 } 922 } 923 924 // Build a clean object to pass to the tram method 925 var clean = tramify(step) || {}; 926 927 // Store last width and height values 928 if (clean.width != null) meta.width = clean.width; 929 if (clean.height != null) meta.height = clean.height; 930 931 // When transitions are not present, set values immediately and continue queue. 932 if (transitions == null) { 933 934 // If we have started, wrap set() in then() and reset queue 935 if (meta.start) { 936 _tram.then(function() { 937 var queue = this.queue; 938 this.set(clean); 939 if (clean.display) { 940 _tram.redraw(); 941 Webflow.redraw.up(); 942 } 943 this.queue = queue; 944 this.next(); 945 }); 946 } else { 947 _tram.set(clean); 948 949 // Always redraw after setting display 950 if (clean.display) { 951 _tram.redraw(); 952 Webflow.redraw.up(); 953 } 954 } 955 956 // Use the wait() method to kick off queue in absence of transitions. 957 var wait = clean.wait; 958 if (wait != null) { 959 _tram.wait(wait); 960 meta.start = true; 961 } 962 963 // Otherwise, when transitions are present 964 } else { 965 966 // If display is present, handle it separately 967 if (clean.display) { 968 var display = clean.display; 969 delete clean.display; 970 971 // If we've already started, we need to wrap it in a then() 972 if (meta.start) { 973 _tram.then(function() { 974 var queue = this.queue; 975 this.set({ display: display }).redraw(); 976 Webflow.redraw.up(); 977 this.queue = queue; 978 this.next(); 979 }); 980 } else { 981 _tram.set({ display: display }).redraw(); 982 Webflow.redraw.up(); 983 } 984 } 985 986 // Otherwise, start a transition using the current start method. 987 _tram[startMethod](clean); 988 meta.start = true; 989 } 990 } 991 992 // (In app) Set styles immediately and manage upstream transition
993 function styleApp(el, data) { 994 var _tram = tram(el); 995 996 // Get computed transition value 997 el.css('transition', ''); 998 var computed = el.css('transition'); 999 1000 // If computed is set to none, clear upstream 1001 if (computed === transNone) computed = _tram.upstream = null; 1002 1003 // Set upstream transition to none temporarily 1004 _tram.upstream = transNone; 1005 1006 // Set values immediately 1007 _tram.set(tramify(data)); 1008 1009 // Only restore upstream in preview mode 1010 _tram.upstream = computed; 1011 } 1012 1013 // (Published) Set styles immediately on specified jquery element 1014 function stylePub(el, data) { 1015 tram(el).set(tramify(data)); 1016 } 1017 1018 // Build a clean object for tram 1019 function tramify(obj) { 1020 var result = {}; 1021 var found = false; 1022 for (var x in obj) { 1023 if (x === 'transition') continue; 1024 result[x] = obj[x]; 1025 found = true; 1026 } 1027 // If empty, return null for tram.set/stop compliance 1028 return found ? result : null; 1029 } 1030 1031 // Events used by other webflow modules 1032 var events = { 1033 reset: function(i, el) { 1034 el.__wf_intro = null; 1035 }, 1036 intro: function(i, el) { 1037 if (el.__wf_intro) return; 1038 el.__wf_intro = true; 1039 $(el).triggerHandler(introEvent); 1040 }, 1041 outro: function(i, el) { 1042 if (!el.__wf_intro) return; 1043 el.__wf_intro = null; 1044 $(el).triggerHandler(outroEvent); 1045 } 1046 }; 1047 1048 // Trigger events in queue + point to sync methods 1049 function initEvents() { 1050 var count = eventQueue.length; 1051 for (var i = 0; i < count; i++) { 1052 var memo = eventQueue[i]; 1053 memo[0](0, memo[1]); 1054 } 1055 eventQueue = []; 1056 $.extend(api.events, events); 1057 } 1058 1059 // Replace events with async methods prior to init 1060 function asyncEvents() { 1061 _.each(events, function(func, name) { 1062 api.events[name] = function(i, el) { 1063 eventQueue.push([func, el]); 1064 }; 1065 }); 1066 } 1067 1068 asyncEvents(); 1069 1070 // Export module 1071 return api; 1072}; 1073 1074},{"./webflow-lib":7}],7:[function(require,module,exports){ 1075'use strict'; 1076 1077/** 1078 * Webflow: Core site library 1079 */ 1080 1081var Webflow = {}; 1082var modules = {}; 1083var primary = []; 1084var secondary = window.Webflow || []; 1085var $ = window.jQuery; 1086var $win = $(window); 1087var $doc = $(document); 1088var isFunction = $.isFunction; 1089var _ = Webflow._ = require('../plugins/underscore-custom'); 1090var tram = require('../plugins/tram-min') && $.tram; 1091var domready = false; 1092var Modernizr = window.Modernizr; 1093var noop = function() {}; 1094tram.config.hideBackface = false; 1095tram.config.keepInherited = true; 1096 1097/** 1098 * Webflow.define - Define a named module 1099 * @param {string} name 1100 * @param {function} factory 1101 * @return {object} 1102 */ 1103Webflow.define = function(name, factory) { 1104 if (modules[name]) unbindModule(modules[name]); 1105 var instance = modules[name] = factory($, _) || {}; 1106 bindModule(instance); 1107 return instance; 1108}; 1109 1110/** 1111 * Webflow.require - Require a named module 1112 * @param {string} name 1113 * @return {object} 1114 */ 1115Webflow.require = function(name) { 1116 return modules[name]; 1117}; 1118 1119function bindModule(module) { 1120 // If running in Webflow app, subscribe to design/preview events 1121 if (Webflow.env()) { 1122 isFunction(module.design) && $win.on('__wf_design', module.design); 1123 isFunction(module.preview) && $win.on('__wf_preview', module.preview); 1124 } 1125 // Subscribe to front-end destroy event 1126 isFunction(module.destroy) && $win.on('__wf_destroy', module.destroy); 1127 // Look for a ready method on module 1128 if (module.ready && isFunction(module.ready)) { 1129 // If domready has already happened, call ready method 1130 if (domready) module.ready(); 1131 // Otherwise push ready method into primary queue 1132 else primary.push(module.ready); 1133 } 1134} 1135 1136function unbindModule(module) { 1137 // Unsubscribe module from window events 1138 isFunction(module.design) && $win.off('__wf_design', module.design); 1139 isFunction(module.preview) && $win.off('__wf_preview', module.preview); 1140 isFunction(module.destroy) && $win.off('__wf_destroy', module.destroy); 1141 1142 // Remove from primary queue if domready hasn't happened 1143 if (!domready) { 1144 primary = _.filter(primary, function(readyFn) { 1145 return readyFn !== module.ready; 1146 });
1147 } 1148} 1149 1150/** 1151 * Webflow.push - Add a ready handler into secondary queue 1152 * @param {function} ready Callback to invoke on domready 1153 */ 1154Webflow.push = function(ready) { 1155 // If domready has already happened, invoke handler 1156 if (domready) { 1157 isFunction(ready) && ready(); 1158 return; 1159 } 1160 // Otherwise push into secondary queue 1161 secondary.push(ready); 1162}; 1163 1164/** 1165 * Webflow.env - Get the state of the Webflow app 1166 * @param {string} mode [optional] 1167 * @return {boolean} 1168 */ 1169Webflow.env = function(mode) { 1170 var designFlag = window.__wf_design; 1171 var inApp = typeof designFlag != 'undefined'; 1172 if (!mode) return inApp; 1173 if (mode == 'design') return inApp && designFlag; 1174 if (mode == 'preview') return inApp && !designFlag; 1175 if (mode == 'slug') return inApp && window.__wf_slug; 1176 if (mode == 'editor') return window.WebflowEditor; 1177 if (mode == 'test') return window.__wf_test; 1178}; 1179 1180// Feature detects + browser sniffs à ² _à ² 1181var userAgent = navigator.userAgent.toLowerCase(); 1182var appVersion = navigator.appVersion.toLowerCase(); 1183var touch = Webflow.env.touch = ('ontouchstart' in window) || window.DocumentTouch && document instanceof window.DocumentTouch; 1184var chrome = Webflow.env.chrome = /chrome/.test(userAgent) && /Google/.test(navigator.vendor) && parseInt(appVersion.match(/chrome\/(\d+)\./)[1], 10); 1185var ios = Webflow.env.ios = Modernizr && Modernizr.ios; 1186Webflow.env.safari = /safari/.test(userAgent) && !chrome && !ios; 1187 1188// Maintain current touch target to prevent late clicks on touch devices 1189var touchTarget; 1190// Listen for both events to support touch/mouse hybrid devices 1191touch && $doc.on('touchstart mousedown', function(evt) { 1192 touchTarget = evt.target; 1193}); 1194 1195/** 1196 * Webflow.validClick - validate click target against current touch target 1197 * @param {HTMLElement} clickTarget Element being clicked 1198 * @return {Boolean} True if click target is valid (always true on non-touch) 1199 */ 1200Webflow.validClick = touch ? function(clickTarget) { 1201 return clickTarget === touchTarget || $.contains(clickTarget, touchTarget); 1202} : function() { return true; }; 1203 1204/** 1205 * Webflow.resize, Webflow.scroll - throttled event proxies 1206 */ 1207var resizeEvents = 'resize.webflow orientationchange.webflow load.webflow'; 1208var scrollEvents = 'scroll.webflow ' + resizeEvents; 1209Webflow.resize = eventProxy($win, resizeEvents); 1210Webflow.scroll = eventProxy($win, scrollEvents); 1211Webflow.redraw = eventProxy(); 1212 1213// Create a proxy instance for throttled events 1214function eventProxy(target, types) { 1215 1216 // Set up throttled method (using custom frame-based _.throttle) 1217 var handlers = []; 1218 var proxy = {}; 1219 proxy.up = _.throttle(function(evt) { 1220 _.each(handlers, function(h) { h(evt); }); 1221 }); 1222 1223 // Bind events to target 1224 if (target && types) target.on(types, proxy.up); 1225 1226 /** 1227 * Add an event handler 1228 * @param {function} handler 1229 */ 1230 proxy.on = function(handler) { 1231 if (typeof handler != 'function') return; 1232 if (_.contains(handlers, handler)) return; 1233 handlers.push(handler); 1234 }; 1235 1236 /** 1237 * Remove an event handler 1238 * @param {function} handler 1239 */ 1240 proxy.off = function(handler) { 1241 // If no arguments supplied, clear all handlers 1242 if (!arguments.length) { 1243 handlers = []; 1244 return; 1245 } 1246 // Otherwise, remove handler from the list 1247 handlers = _.filter(handlers, function(h) { 1248 return h !== handler; 1249 }); 1250 }; 1251 1252 return proxy; 1253} 1254 1255// Provide optional IX events to components 1256Webflow.ixEvents = function() { 1257 var ix = Webflow.require('ix'); 1258 return (ix && ix.events) || { 1259 reset: noop, 1260 intro: noop, 1261 outro: noop 1262 }; 1263}; 1264 1265// Webflow.location - Wrap window.location in api 1266Webflow.location = function(url) { 1267 window.location = url; 1268}; 1269 1270// Webflow.app - Designer-specific methods 1271Webflow.app = Webflow.env() ? {} : null; 1272if (Webflow.app) { 1273 1274 // Trigger redraw for specific elements 1275 var redraw = new Event('__wf_redraw'); 1276 Webflow.app.redrawElement = function(i, el) { el.dispatchEvent(redraw); }; 1277 1278 // Webflow.location - Re-route location change to trigger an event 1279 Webflow.location = function(url) { 1280 window.dispatchEvent(new CustomEvent('__wf_location', { detail: url })); 1281 }; 1282} 1283 1284// Webflow.ready - Call primary and secondary handlers 1285Webflow.ready = function() { 1286 domready = true; 1287 _.each(primary.concat(secondary), callReady);
1288 // Trigger resize 1289 Webflow.resize.up(); 1290}; 1291 1292function callReady(readyFn) { 1293 isFunction(readyFn) && readyFn(); 1294} 1295 1296/** 1297 * Webflow.load - Add a window load handler that will run even if load event has already happened 1298 * @param {function} handler 1299 */ 1300var deferLoad; 1301Webflow.load = function(handler) { 1302 deferLoad.then(handler); 1303}; 1304 1305function bindLoad() { 1306 // Reject any previous deferred (to support destroy) 1307 if (deferLoad) { 1308 deferLoad.reject(); 1309 $win.off('load', deferLoad.resolve); 1310 } 1311 // Create deferred and bind window load event 1312 deferLoad = new $.Deferred(); 1313 $win.on('load', deferLoad.resolve); 1314} 1315 1316// Webflow.destroy - Trigger a destroy event for all modules 1317Webflow.destroy = function() { 1318 $win.triggerHandler('__wf_destroy'); 1319 1320 // Unbind and clear modules 1321 _.each(modules, unbindModule); 1322 modules = {}; 1323 1324 // Clear any proxy event handlers 1325 Webflow.resize.off(); 1326 Webflow.scroll.off(); 1327 Webflow.redraw.off(); 1328 1329 // If load event has not yet fired, replace the deferred 1330 if (deferLoad.state() == 'pending') bindLoad(); 1331}; 1332 1333// Listen for domready 1334$(Webflow.ready); 1335 1336// Listen for window.onload and resolve deferred 1337bindLoad(); 1338 1339// Export commonjs module 1340module.exports = Webflow; 1341 1342},{"../plugins/tram-min":16,"../plugins/underscore-custom":17}],8:[function(require,module,exports){ 1343'use strict'; 1344 1345/** 1346 * Webflow: Lightbox component 1347 */ 1348 1349var Webflow = require('./webflow-lib'); 1350 1351function createLightbox(window, document, $, undefined) { 1352 var tram = $.tram; 1353 var isArray = Array.isArray; 1354 var namespace = 'w-lightbox'; 1355 var prefix = namespace + '-'; 1356 var prefixRegex = /(^|\s+)/g; 1357 1358 // Array of objects describing items to be displayed. 1359 var items = []; 1360 1361 // Index of the currently displayed item. 1362 var currentIndex; 1363 1364 // Object holding references to jQuery wrapped nodes. 1365 var $refs; 1366 1367 // Instance of Spinner 1368 var spinner; 1369 1370 function lightbox(thing, index) { 1371 items = isArray(thing) ? thing : [thing]; 1372 1373 if (!$refs) { 1374 lightbox.build(); 1375 } 1376 1377 if (items.length > 1) { 1378 $refs.items = $refs.empty; 1379 1380 items.forEach(function (item) { 1381 var $thumbnail = dom('thumbnail'); 1382 var $item = dom('item').append($thumbnail); 1383 1384 $refs.items = $refs.items.add($item); 1385 1386 loadImage(item.thumbnailUrl || item.url, function ($image) { 1387 if ($image.prop('width') > $image.prop('height')) { 1388 addClass($image, 'wide'); 1389 } else { 1390 addClass($image, 'tall'); 1391 } 1392 $thumbnail.append(addClass($image, 'thumbnail-image')); 1393 }); 1394 }); 1395 1396 $refs.strip.empty().append($refs.items); 1397 addClass($refs.content, 'group'); 1398 } 1399 1400 tram( 1401 // Focus the lightbox to receive keyboard events. 1402 removeClass($refs.lightbox, 'hide').focus() 1403 ) 1404 .add('opacity .3s') 1405 .start({opacity: 1}); 1406 1407 // Prevent document from scrolling while lightbox is active. 1408 addClass($refs.html, 'noscroll'); 1409 1410 return lightbox.show(index || 0); 1411 } 1412 1413 /** 1414 * Creates the DOM structure required by the lightbox. 1415 */ 1416 lightbox.build = function () { 1417 // In case `build` is called more than once. 1418 lightbox.destroy(); 1419 1420 $refs = { 1421 html: $(document.documentElement), 1422 // Empty jQuery object can be used to build new ones using `.add`. 1423 empty: $() 1424 }; 1425 1426 $refs.arrowLeft = dom('control left inactive'); 1427 $refs.arrowRight = dom('control right inactive'); 1428 $refs.close = dom('control close'); 1429 1430 $refs.spinner = dom('spinner'); 1431 $refs.strip = dom('strip'); 1432 1433 spinner = new Spinner($refs.spinner, prefixed('hide')); 1434 1435 $refs.content = dom('content') 1436 .append($refs.spinner, $refs.arrowLeft, $refs.arrowRight, $refs.close); 1437 1438 $refs.container = dom('container') 1439 .append($refs.content, $refs.strip); 1440 1441 $refs.lightbox = dom('backdrop hide') 1442 .append($refs.container); 1443 1444 // We are delegating events for performance reasons and also 1445 // to not have to reattach handlers when images change. 1446 $refs.strip.on('tap', selector('item'), itemTapHandler); 1447 $refs.content 1448 .on('swipe', swipeHandler) 1449 .on('tap', selector('left'), handlerPrev) 1450 .on('tap', selector('right'), handlerNext) 1451 .on('tap', selector('close'), handlerHide) 1452 .on('tap', selector('image, caption'), handlerNext); 1453 $refs.container 1454 .on('tap', selector('view, strip'), handlerHide) 1455 // Prevent images from being dragged around. 1456 .on('dragstart', selector('img'), preventDefault); 1457 $refs.lightbox 1458 .on('keydown', keyHandler) 1459 // IE loses focus to inner nodes without letting us know. 1460 .on('focusin', focusThis); 1461 1462 // The `tabindex` attribute is needed to enable non-input elements 1463 // to receive keyboard events. 1464 $('body').append($refs.lightbox.prop('tabIndex', 0)); 1465 1466 return lightbox; 1467 }; 1468 1469 /** 1470 * Dispose of DOM nodes created by the lightbox. 1471 */ 1472 lightbox.destroy = function () { 1473 if (!$refs) { 1474 return; 1475 } 1476 1477 // Event handlers are also removed. 1478 $refs.lightbox.remove(); 1479 $refs = undefined; 1480 }; 1481 1482 /** 1483 * Show a specific item. 1484 */ 1485 lightbox.show = function (index) { 1486 // Bail if we are already showing this item. 1487 if (index === currentIndex) { 1488 return; 1489 } 1490 1491 var item = items[index]; 1492 if (!item) { return lightbox.hide(); } 1493 1494 var previousIndex = currentIndex; 1495 currentIndex = index; 1496 spinner.show(); 1497 1498 // For videos, load an empty SVG with the video dimensions to preserve 1499 // the video’s aspect ratio while being responsive. 1500 var url = item.html && svgDataUri(item.width, item.height) || item.url; 1501 loadImage(url, function ($image) { 1502 // Make sure this is the last item requested to be shown since 1503 // images can finish loading in a different order than they were 1504 // requested in. 1505 if (index != currentIndex) { 1506 return; 1507 } 1508 1509 var $figure = dom('figure', 'figure').append(addClass($image, 'image'));
1510 var $frame = dom('frame').append($figure); 1511 var $newView = dom('view').append($frame); 1512 var $html, isIframe; 1513 1514 if (item.html) { 1515 $html = $(item.html); 1516 isIframe = $html.is('iframe'); 1517 1518 if (isIframe) { 1519 $html.on('load', transitionToNewView); 1520 } 1521 1522 $figure.append(addClass($html, 'embed')); 1523 } 1524 1525 if (item.caption) { 1526 $figure.append(dom('caption', 'figcaption').text(item.caption)); 1527 } 1528 1529 $refs.spinner.before($newView); 1530 1531 if (!isIframe) { 1532 transitionToNewView(); 1533 } 1534 1535 function transitionToNewView() { 1536 spinner.hide(); 1537 1538 if (index != currentIndex) { 1539 $newView.remove(); 1540 return; 1541 } 1542 1543 1544 toggleClass($refs.arrowLeft, 'inactive', index <= 0); 1545 toggleClass($refs.arrowRight, 'inactive', index >= items.length - 1); 1546 1547 if ($refs.view) { 1548 tram($refs.view) 1549 .add('opacity .3s') 1550 .start({opacity: 0}) 1551 .then(remover($refs.view)); 1552 1553 tram($newView) 1554 .add('opacity .3s') 1555 .add('transform .3s') 1556 .set({x: index > previousIndex ? '80px' : '-80px'}) 1557 .start({opacity: 1, x: 0}); 1558 } else { 1559 $newView.css('opacity', 1); 1560 } 1561 1562 $refs.view = $newView; 1563 1564 if ($refs.items) { 1565 // Mark proper thumbnail as active 1566 addClass(removeClass($refs.items, 'active').eq(index), 'active'); 1567 } 1568 } 1569 }); 1570 1571 return lightbox; 1572 }; 1573 1574 /** 1575 * Hides the lightbox. 1576 */ 1577 lightbox.hide = function () { 1578 tram($refs.lightbox) 1579 .add('opacity .3s') 1580 .start({opacity: 0}) 1581 .then(hideLightbox); 1582 1583 return lightbox; 1584 }; 1585 1586 lightbox.prev = function () { 1587 if (currentIndex > 0) { 1588 lightbox.show(currentIndex - 1); 1589 } 1590 }; 1591 1592 lightbox.next = function () { 1593 if (currentIndex < items.length - 1) { 1594 lightbox.show(currentIndex + 1); 1595 } 1596 }; 1597 1598 function createHandler(action) { 1599 return function (event) { 1600 // We only care about events triggered directly on the bound selectors. 1601 if (this != event.target) { 1602 return; 1603 } 1604 1605 event.stopPropagation(); 1606 event.preventDefault(); 1607 1608 action(); 1609 }; 1610 } 1611 1612 var handlerPrev = createHandler(lightbox.prev); 1613 var handlerNext = createHandler(lightbox.next); 1614 var handlerHide = createHandler(lightbox.hide); 1615 1616 var itemTapHandler = function(event) { 1617 var index = $(this).index(); 1618 1619 event.preventDefault(); 1620 lightbox.show(index); 1621 }; 1622 1623 var swipeHandler = function (event, data) { 1624 // Prevent scrolling. 1625 event.preventDefault(); 1626 1627 if (data.direction == 'left') { 1628 lightbox.next(); 1629 } else if (data.direction == 'right') { 1630 lightbox.prev(); 1631 } 1632 }; 1633 1634 var focusThis = function () { 1635 this.focus(); 1636 }; 1637 1638 function preventDefault(event) { 1639 event.preventDefault(); 1640 } 1641 1642 function keyHandler(event) { 1643 var keyCode = event.keyCode; 1644 1645 // [esc] 1646 if (keyCode == 27) { 1647 lightbox.hide(); 1648 } 1649 1650 // [◀] 1651 else if (keyCode == 37) { 1652 lightbox.prev(); 1653 } 1654 1655 // [▶] 1656 else if (keyCode == 39) { 1657 lightbox.next(); 1658 } 1659 } 1660 1661 function hideLightbox() { 1662 removeClass($refs.html, 'noscroll'); 1663 addClass($refs.lightbox, 'hide'); 1664 $refs.strip.empty(); 1665 $refs.view && $refs.view.remove(); 1666 1667 // Reset some stuff 1668 removeClass($refs.content, 'group'); 1669 addClass($refs.arrowLeft, 'inactive'); 1670 addClass($refs.arrowRight, 'inactive'); 1671 1672 currentIndex = $refs.view = undefined; 1673 } 1674 1675 function loadImage(url, callback) { 1676 var $image = dom('img', 'img'); 1677 1678 $image.one('load', function () { 1679 callback($image); 1680 }); 1681 1682 // Start loading image. 1683 $image.attr('src', url); 1684 1685 return $image; 1686 } 1687 1688 function remover($element) { 1689 return function () { 1690 $element.remove(); 1691 }; 1692 } 1693 1694 /** 1695 * Spinner 1696 */ 1697 function Spinner($spinner, className, delay) { 1698 this.$element = $spinner; 1699 this.className = className; 1700 this.delay = delay || 200; 1701 this.hide(); 1702 } 1703 1704 Spinner.prototype.show = function () { 1705 var spinner = this; 1706 1707 // Bail if we are already showing the spinner. 1708 if (spinner.timeoutId) { 1709 return; 1710 } 1711 1712 spinner.timeoutId = setTimeout(function () { 1713 spinner.$element.removeClass(spinner.className); 1714 delete spinner.timeoutId; 1715 }, spinner.delay); 1716 }; 1717 1718 Spinner.prototype.hide = function () { 1719 var spinner = this; 1720 if (spinner.timeoutId) { 1721 clearTimeout(spinner.timeoutId); 1722 delete spinner.timeoutId; 1723 return; 1724 } 1725 1726 spinner.$element.addClass(spinner.className); 1727 }; 1728 1729 function prefixed(string, isSelector) { 1730 return string.replace(prefixRegex, (isSelector ? ' .' : ' ') + prefix); 1731 } 1732 1733 function selector(string) { 1734 return prefixed(string, true); 1735 } 1736 1737 /** 1738 * jQuery.addClass with auto-prefixing 1739 * @param {jQuery} Element to add class to 1740 * @param {string}
1740 Class name that will be prefixed and added to element 1741 * @return {jQuery} 1742 */ 1743 function addClass($element, className) { 1744 return $element.addClass(prefixed(className)); 1745 } 1746 1747 /** 1748 * jQuery.removeClass with auto-prefixing 1749 * @param {jQuery} Element to remove class from 1750 * @param {string} Class name that will be prefixed and removed from element 1751 * @return {jQuery} 1752 */ 1753 function removeClass($element, className) { 1754 return $element.removeClass(prefixed(className)); 1755 } 1756 1757 /** 1758 * jQuery.toggleClass with auto-prefixing 1759 * @param {jQuery} Element where class will be toggled 1760 * @param {string} Class name that will be prefixed and toggled 1761 * @param {boolean} Optional boolean that determines if class will be added or removed 1762 * @return {jQuery} 1763 */ 1764 function toggleClass($element, className, shouldAdd) { 1765 return $element.toggleClass(prefixed(className), shouldAdd); 1766 } 1767 1768 /** 1769 * Create a new DOM element wrapped in a jQuery object, 1770 * decorated with our custom methods. 1771 * @param {string} className 1772 * @param {string} [tag] 1773 * @return {jQuery} 1774 */ 1775 function dom(className, tag) { 1776 return addClass($(document.createElement(tag || 'div')), className); 1777 } 1778 1779 function isObject(value) { 1780 return typeof value == 'object' && null != value && !isArray(value); 1781 } 1782 1783 function svgDataUri(width, height) { 1784 var svg = '<svg xmlns="http://www.w3.org/2000/svg" width="' + width + '" height="' + height + '"/>'; 1785 return 'data:image/svg+xml;charset=utf-8,' + encodeURI(svg); 1786 } 1787 1788 // Compute some dimensions manually for iOS, because of buggy support for VH. 1789 // Also, Android built-in browser does not support viewport units. 1790 (function () { 1791 var ua = window.navigator.userAgent; 1792 var iOS = /(iPhone|iPod|iPad).+AppleWebKit/i.test(ua); 1793 var android = ua.indexOf('Android ') > -1 && ua.indexOf('Chrome') == -1; 1794 1795 if (!iOS && !android) { 1796 return; 1797 } 1798 1799 var styleNode = document.createElement('style'); 1800 document.head.appendChild(styleNode); 1801 window.addEventListener('orientationchange', refresh, true); 1802 1803 function refresh() { 1804 var vh = window.innerHeight; 1805 var vw = window.innerWidth; 1806 var content = 1807 '.w-lightbox-content, .w-lightbox-view, .w-lightbox-view:before {' + 1808 'height:' + vh + 'px' + 1809 '}' + 1810 '.w-lightbox-view {' + 1811 'width:' + vw + 'px' + 1812 '}' + 1813 '.w-lightbox-group, .w-lightbox-group .w-lightbox-view, .w-lightbox-group .w-lightbox-view:before {' + 1814 'height:' + (0.86 * vh) + 'px' + 1815 '}' + 1816 '.w-lightbox-image {' + 1817 'max-width:' + vw + 'px;' + 1818 'max-height:' + vh + 'px' + 1819 '}' + 1820 '.w-lightbox-group .w-lightbox-image {' + 1821 'max-height:' + (0.86 * vh) + 'px' + 1822 '}' + 1823 '.w-lightbox-strip {' + 1824 'padding: 0 ' + (0.01 * vh) + 'px' + 1825 '}' + 1826 '.w-lightbox-item {' + 1827 'width:' + (0.1 * vh) + 'px;' + 1828 'padding:' + (0.02 * vh) + 'px ' + (0.01 * vh) + 'px' + 1829 '}' + 1830 '.w-lightbox-thumbnail {' + 1831 'height:' + (0.1 * vh) + 'px' + 1832 '}' + 1833 '@media (min-width: 768px) {' + 1834 '.w-lightbox-content, .w-lightbox-view, .w-lightbox-view:before {' + 1835 'height:' + (0.96 * vh) + 'px' + 1836 '}' + 1837 '.w-lightbox-content {' + 1838 'margin-top:' + (0.02 * vh) + 'px' + 1839 '}' + 1840 '.w-lightbox-group, .w-lightbox-group .w-lightbox-view, .w-lightbox-group .w-lightbox-view:before {' + 1841 'height:' + (0.84 * vh) + 'px' + 1842 '}' + 1843 '.w-lightbox-image {' + 1844 'max-width:' + (0.96 * vw) + 'px;' + 1845 'max-height:' + (0.96 * vh) + 'px' + 1846 '}' + 1847 '.w-lightbox-group .w-lightbox-image {' + 1848 'max-width:' + (0.823 * vw) + 'px;' + 1849 'max-height:' + (0.84 * vh) + 'px' + 1850 '}' + 1851 '}'; 1852 1853 styleNode.textContent = content; 1854 } 1855 1856 refresh();
1857 })(); 1858 1859 return lightbox; 1860} 1861 1862module.exports = function($, _) { 1863 var api = {}; 1864 var lightbox = createLightbox(window, document, $); 1865 var $doc = $(document); 1866 var $body; 1867 var $lightboxes; 1868 var designer; 1869 var inApp = Webflow.env(); 1870 var namespace = '.w-lightbox'; 1871 var groups; 1872 1873 // ----------------------------------- 1874 // Module methods 1875 1876 api.ready = api.design = api.preview = init; 1877 1878 // ----------------------------------- 1879 // Private methods 1880 1881 function init() { 1882 designer = inApp && Webflow.env('design'); 1883 $body = $(document.body); 1884 1885 // Reset Lightbox 1886 lightbox.destroy(); 1887 1888 // Reset groups 1889 groups = {}; 1890 1891 // Find all instances on the page 1892 $lightboxes = $doc.find(namespace); 1893 1894 // Instantiate all lighboxes 1895 $lightboxes.webflowLightBox(); 1896 } 1897 1898 jQuery.fn.extend({ 1899 webflowLightBox: function() { 1900 var $el = this; 1901 $.each($el, function(i, el) { 1902 // Store state in data 1903 var data = $.data(el, namespace); 1904 if (!data) data = $.data(el, namespace, { 1905 el: $(el), 1906 mode: 'images', 1907 images: [], 1908 embed: '' 1909 }); 1910 1911 // Remove old events 1912 data.el.off(namespace); 1913 1914 // Set config from json script tag 1915 configure(data); 1916 1917 // Add events based on mode 1918 if (designer) { 1919 data.el.on('setting' + namespace, configure.bind(null, data)); 1920 } else { 1921 data.el 1922 .on('tap' + namespace, tapHandler(data)) 1923 // Prevent page scrolling to top when clicking on lightbox triggers. 1924 .on('click' + namespace, function (e) { e.preventDefault(); }); 1925 } 1926 }); 1927 } 1928 }); 1929 1930 function configure(data) { 1931 var json = data.el.children('.w-json').html(); 1932 var groupName, groupItems; 1933 1934 if (!json) { 1935 data.items = []; 1936 return; 1937 } 1938 1939 try { 1940 json = JSON.parse(json); 1941 1942 supportOldLightboxJson(json); 1943 1944 groupName = json.group; 1945 1946 if (groupName) { 1947 groupItems = groups[groupName]; 1948 if (!groupItems) { 1949 groupItems = groups[groupName] = []; 1950 } 1951 1952 data.items = groupItems; 1953 1954 if (json.items.length) { 1955 data.index = groupItems.length; 1956 groupItems.push.apply(groupItems, json.items); 1957 } 1958 } else { 1959 data.items = json.items; 1960 } 1961 } 1962 catch (e) { 1963 console.error('Malformed lightbox JSON configuration.', e.message); 1964 } 1965 } 1966 1967 function tapHandler(data) { 1968 return function () { 1969 data.items.length && lightbox(data.items, data.index || 0); 1970 }; 1971 } 1972 1973 function supportOldLightboxJson(data) { 1974 if (data.images) { 1975 data.images.forEach(function (item) { 1976 item.type = 'image'; 1977 }); 1978 data.items = data.images; 1979 } 1980 1981 if (data.embed) { 1982 data.embed.type = 'video'; 1983 data.items = [data.embed]; 1984 } 1985 1986 if (data.groupId) { 1987 data.group = data.groupId; 1988 } 1989 } 1990 1991 // Export module 1992 return api; 1993}; 1994 1995},{"./webflow-lib":7}],9:[function(require,module,exports){ 1996'use strict'; 1997 1998/** 1999 * Webflow: Auto-select links to current page or section 2000 */ 2001 2002var Webflow = require('./webflow-lib'); 2003 2004module.exports = function($, _) { 2005 var api = {}; 2006 var $win = $(window); 2007 var designer; 2008 var inApp = Webflow.env(); 2009 var location = window.location; 2010 var tempLink = document.createElement('a'); 2011 var linkCurrent = 'w--current'; 2012 var validHash = /^#[a-zA-Z][\w:.-]*$/; 2013 var indexPage = /index\.(html|php)$/; 2014 var dirList = /\/$/; 2015 var anchors; 2016 var slug; 2017 2018 // ----------------------------------- 2019 // Module methods 2020 2021 api.ready = api.design = api.preview = init; 2022 2023 // ----------------------------------- 2024 // Private methods 2025 2026 function init() { 2027 designer = inApp && Webflow.env('design'); 2028 slug = Webflow.env('slug') || location.pathname || ''; 2029 2030 // Reset scroll listener, init anchors 2031 Webflow.scroll.off(scroll); 2032 anchors = []; 2033 2034 // Test all links for a selectable href 2035 var links = document.links; 2036 for (var i = 0; i < links.length; ++i) { 2037 select(links[i]); 2038 } 2039 2040 // Listen for scroll if any anchors exist 2041 if (anchors.length) { 2042 Webflow.scroll.on(scroll); 2043 scroll(); 2044 } 2045 } 2046 2047 function select(link) { 2048 var href = (designer && link.getAttribute('href-disabled')) || link.getAttribute('href'); 2049 tempLink.href = href; 2050 2051 // Ignore any hrefs with a colon to safely avoid all uri schemes 2052 if (href.indexOf(':') >= 0) return; 2053 2054 var $link = $(link); 2055 2056 // Check for valid hash links w/ sections and use scroll anchor 2057 if (href.indexOf('#') === 0 && validHash.test(href)) { 2058 var $section = $(href); 2059 $section.length && anchors.push({ link: $link, sec: $section, active: false }); 2060 return; 2061 } 2062 2063 // Ignore empty # links 2064 if (href === '#') return; 2065 2066 // Determine whether the link should be selected 2067 var match = (tempLink.href === location.href) || (href === slug) || (indexPage.test(href) && dirList.test(slug));
2068 setClass($link, linkCurrent, match); 2069 } 2070 2071 function scroll() { 2072 var viewTop = $win.scrollTop(); 2073 var viewHeight = $win.height(); 2074 2075 // Check each anchor for a section in view 2076 _.each(anchors, function(anchor) { 2077 var $link = anchor.link; 2078 var $section = anchor.sec; 2079 var top = $section.offset().top; 2080 var height = $section.outerHeight(); 2081 var offset = viewHeight * 0.5; 2082 var active = ($section.is(':visible') && 2083 top + height - offset >= viewTop && 2084 top + offset <= viewTop + viewHeight); 2085 if (anchor.active === active) return; 2086 anchor.active = active; 2087 setClass($link, linkCurrent, active); 2088 if (designer) $link[0].__wf_current = active; 2089 }); 2090 } 2091 2092 function setClass($elem, className, add) { 2093 var exists = $elem.hasClass(className); 2094 if (add && exists) return; 2095 if (!add && !exists) return; 2096 add ? $elem.addClass(className) : $elem.removeClass(className); 2097 } 2098 2099 // Export module 2100 return api; 2101}; 2102 2103},{"./webflow-lib":7}],10:[function(require,module,exports){ 2104'use strict'; 2105 2106/** 2107 * Webflow: Maps widget 2108 */ 2109 2110var Webflow = require('./webflow-lib'); 2111 2112module.exports = function($, _) { 2113 var api = {}; 2114 var $doc = $(document); 2115 var google = null; 2116 var $maps; 2117 var namespace = '.w-widget-map'; 2118 2119 // ----------------------------------- 2120 // Module methods 2121 2122 api.ready = function() { 2123 // Init Maps on the front-end 2124 if (!Webflow.env()) initMaps(); 2125 }; 2126 2127 api.preview = function() { 2128 // Update active map nodes 2129 $maps = $doc.find(namespace); 2130 // Listen for resize events 2131 Webflow.resize.off(triggerRedraw); 2132 if ($maps.length) { 2133 Webflow.resize.on(triggerRedraw); 2134 triggerRedraw(); 2135 } 2136 }; 2137 2138 api.design = function(evt) { 2139 // Update active map nodes 2140 $maps = $doc.find(namespace); 2141 // Stop listening for resize events 2142 Webflow.resize.off(triggerRedraw); 2143 // Redraw to account for page changes 2144 $maps.length && _.defer(triggerRedraw); 2145 }; 2146 2147 api.destroy = removeListeners; 2148 2149 // ----------------------------------- 2150 // Private methods 2151 2152 // Trigger redraw in designer or preview mode 2153 function triggerRedraw() { 2154 if ($maps.length && Webflow.app) { 2155 $maps.each(Webflow.app.redrawElement); 2156 } 2157 } 2158 2159 function initMaps() { 2160 $maps = $doc.find(namespace); 2161 if (!$maps.length) return; 2162 2163 if (google === null) { 2164 $.getScript('https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&callback=_wf_maps_loaded'); 2165 window._wf_maps_loaded = mapsLoaded; 2166 } else { 2167 mapsLoaded(); 2168 } 2169 2170 function mapsLoaded() { 2171 window._wf_maps_loaded = function() {}; 2172 google = window.google; 2173 $maps.each(renderMap); 2174 removeListeners(); 2175 addListeners(); 2176 } 2177 } 2178 2179 function removeListeners() { 2180 Webflow.resize.off(resizeMaps); 2181 Webflow.redraw.off(resizeMaps); 2182 } 2183 2184 function addListeners() { 2185 Webflow.resize.on(resizeMaps); 2186 Webflow.redraw.on(resizeMaps); 2187 } 2188 2189 // Render map onto each element 2190 function renderMap(i, el) { 2191 var data = $(el).data(); 2192 getState(el, data); 2193 } 2194 2195 function resizeMaps() { 2196 $maps.each(resizeMap); 2197 } 2198 2199 // Resize map when window changes 2200 function resizeMap(i, el) { 2201 var state = getState(el); 2202 google.maps.event.trigger(state.map, 'resize'); 2203 state.setMapPosition(); 2204 } 2205 2206 // Store state on element data 2207 var store = 'w-widget-map'; 2208 function getState(el, data) { 2209 2210 var state = $.data(el, store); 2211 if (state) return state; 2212 2213 var $el = $(el); 2214 state = $.data(el, store, { 2215 // Default options 2216 latLng: '51.511214,-0.119824', 2217 tooltip: '', 2218 style: 'roadmap', 2219 zoom: 12, 2220 2221 // Marker 2222 marker: new google.maps.Marker({ 2223 draggable: false 2224 }), 2225 2226 // Tooltip infowindow 2227 infowindow: new google.maps.InfoWindow({ 2228 disableAutoPan: true 2229 }) 2230 }); 2231 2232 // LatLng center point 2233 var latLng = data.widgetLatlng || state.latLng; 2234 state.latLng = latLng; 2235 var coords = latLng.split(','); 2236 var latLngObj = new google.maps.LatLng(coords[0], coords[1]); 2237 state.latLngObj = latLngObj; 2238 2239 // Disable touch events 2240 var mapDraggable = (Webflow.env.touch && data.disableTouch) ? false : true; 2241 2242 // Map instance 2243 state.map = new google.maps.Map(el, { 2244 center: state.latLngObj, 2245 zoom: state.zoom, 2246 maxZoom: 18, 2247 mapTypeControl: false, 2248 panControl: false, 2249 streetViewControl: false, 2250 scrollwheel: !data.disableScroll, 2251 draggable: mapDraggable, 2252 zoomControl: true, 2253 zoomControlOptions: { 2254 style: google.maps.ZoomControlStyle.SMALL 2255 }, 2256 mapTypeId: state.style 2257 });
2258 state.marker.setMap(state.map); 2259 2260 // Set map position and offset 2261 state.setMapPosition = function() { 2262 state.map.setCenter(state.latLngObj); 2263 var offsetX = 0; 2264 var offsetY = 0; 2265 var padding = $el.css(['paddingTop', 'paddingRight', 'paddingBottom', 'paddingLeft']); 2266 offsetX -= parseInt(padding.paddingLeft, 10); 2267 offsetX += parseInt(padding.paddingRight, 10); 2268 offsetY -= parseInt(padding.paddingTop, 10); 2269 offsetY += parseInt(padding.paddingBottom, 10); 2270 if (offsetX || offsetY) { 2271 state.map.panBy(offsetX, offsetY); 2272 } 2273 $el.css('position', ''); // Remove injected position 2274 }; 2275 2276 // Fix position after first tiles have loaded 2277 google.maps.event.addListener(state.map, 'tilesloaded', function() { 2278 google.maps.event.clearListeners(state.map, 'tilesloaded'); 2279 state.setMapPosition(); 2280 }); 2281 2282 // Set initial position 2283 state.setMapPosition(); 2284 state.marker.setPosition(state.latLngObj); 2285 state.infowindow.setPosition(state.latLngObj); 2286 2287 // Draw tooltip 2288 var tooltip = data.widgetTooltip; 2289 if (tooltip) { 2290 state.tooltip = tooltip; 2291 state.infowindow.setContent(tooltip); 2292 if (!state.infowindowOpen) { 2293 state.infowindow.open(state.map, state.marker); 2294 state.infowindowOpen = true; 2295 } 2296 } 2297 2298 // Map style - options.style 2299 var style = data.widgetStyle; 2300 if (style) { 2301 state.map.setMapTypeId(style); 2302 } 2303 2304 // Zoom - options.zoom 2305 var zoom = data.widgetZoom; 2306 if (zoom != null) { 2307 state.zoom = zoom; 2308 state.map.setZoom(+zoom); 2309 } 2310 2311 // Click marker to open in google maps 2312 google.maps.event.addListener(state.marker, 'click', function() { 2313 window.open('https://maps.google.com/?z=' + state.zoom + '&daddr=' + state.latLng); 2314 }); 2315 2316 return state; 2317 } 2318 2319 // Export module 2320 return api; 2321}; 2322 2323},{"./webflow-lib":7}],11:[function(require,module,exports){ 2324'use strict'; 2325 2326/** 2327 * Webflow: Navbar component 2328 */ 2329 2330var Webflow = require('./webflow-lib'); 2331 2332module.exports = function($, _) { 2333 var api = {}; 2334 var tram = $.tram; 2335 var $win = $(window); 2336 var $doc = $(document); 2337 var $body; 2338 var $navbars; 2339 var designer; 2340 var inApp = Webflow.env(); 2341 var overlay = '<div class="w-nav-overlay" data-wf-ignore />'; 2342 var namespace = '.w-nav'; 2343 var buttonOpen = 'w--open'; 2344 var menuOpen = 'w--nav-menu-open'; 2345 var linkOpen = 'w--nav-link-open'; 2346 var ix = Webflow.ixEvents(); 2347 2348 // ----------------------------------- 2349 // Module methods 2350 2351 api.ready = api.design = api.preview = init; 2352 api.destroy = removeListeners; 2353 2354 // ----------------------------------- 2355 // Private methods 2356 2357 function init() { 2358 designer = inApp && Webflow.env('design'); 2359 $body = $(document.body); 2360 2361 // Find all instances on the page 2362 $navbars = $doc.find(namespace); 2363 if (!$navbars.length) return; 2364 $navbars.each(build); 2365 2366 // Wire events 2367 removeListeners(); 2368 addListeners(); 2369 } 2370 2371 function removeListeners() { 2372 Webflow.resize.off(resizeAll); 2373 } 2374 2375 function addListeners() { 2376 Webflow.resize.on(resizeAll); 2377 } 2378 2379 function resizeAll() { 2380 $navbars.each(resize); 2381 } 2382 2383 function build(i, el) { 2384 var $el = $(el); 2385 2386 // Store state in data 2387 var data = $.data(el, namespace); 2388 if (!data) data = $.data(el, namespace, { open: false, el: $el, config: {} }); 2389 data.menu = $el.find('.w-nav-menu'); 2390 data.links = data.menu.find('.w-nav-link'); 2391 data.dropdowns = data.menu.find('.w-dropdown'); 2392 data.button = $el.find('.w-nav-button'); 2393 data.container = $el.find('.w-container'); 2394 data.outside = outside(data); 2395 2396 // Remove old events 2397 data.el.off(namespace); 2398 data.button.off(namespace); 2399 data.menu.off(namespace); 2400 2401 // Set config from data attributes 2402 configure(data); 2403 2404 // Add events based on mode 2405 if (designer) { 2406 removeOverlay(data); 2407 data.el.on('setting' + namespace, handler(data)); 2408 } else { 2409 addOverlay(data); 2410 data.button.on('tap' + namespace, toggle(data));
2411 data.menu.on('click' + namespace, 'a', navigate(data)); 2412 } 2413 2414 // Trigger initial resize 2415 resize(i, el); 2416 } 2417 2418 function removeOverlay(data) { 2419 if (!data.overlay) return; 2420 close(data, true); 2421 data.overlay.remove(); 2422 data.overlay = null; 2423 } 2424 2425 function addOverlay(data) { 2426 if (data.overlay) return; 2427 data.overlay = $(overlay).appendTo(data.el); 2428 data.parent = data.menu.parent(); 2429 close(data, true); 2430 } 2431 2432 function configure(data) { 2433 var config = {}; 2434 var old = data.config || {}; 2435 2436 // Set config options from data attributes 2437 var animation = config.animation = data.el.attr('data-animation') || 'default'; 2438 config.animOver = /^over/.test(animation); 2439 config.animDirect = /left$/.test(animation) ? -1 : 1; 2440 2441 // Re-open menu if the animation type changed 2442 if (old.animation != animation) { 2443 data.open && _.defer(reopen, data); 2444 } 2445 2446 config.easing = data.el.attr('data-easing') || 'ease'; 2447 config.easing2 = data.el.attr('data-easing2') || 'ease'; 2448 2449 var duration = data.el.attr('data-duration'); 2450 config.duration = duration != null ? +duration : 400; 2451 2452 config.docHeight = data.el.attr('data-doc-height'); 2453 2454 // Store config in data 2455 data.config = config; 2456 } 2457 2458 function handler(data) { 2459 return function(evt, options) { 2460 options = options || {}; 2461 var winWidth = $win.width(); 2462 configure(data); 2463 options.open === true && open(data, true); 2464 options.open === false && close(data, true); 2465 // Reopen if media query changed after setting 2466 data.open && _.defer(function() { 2467 if (winWidth != $win.width()) reopen(data); 2468 }); 2469 }; 2470 } 2471 2472 function reopen(data) { 2473 if (!data.open) return; 2474 close(data, true); 2475 open(data, true); 2476 } 2477 2478 function toggle(data) { 2479 // Debounce toggle to wait for accurate open state 2480 return _.debounce(function(evt) { 2481 data.open ? close(data) : open(data); 2482 }); 2483 } 2484 2485 function navigate(data) { 2486 return function(evt) { 2487 var link = $(this); 2488 var href = link.attr('href'); 2489 2490 // Avoid late clicks on touch devices 2491 if (!Webflow.validClick(evt.currentTarget)) { 2492 evt.preventDefault(); 2493 return; 2494 } 2495 2496 // Close when navigating to an in-page anchor 2497 if (href && href.indexOf('#') === 0 && data.open) { 2498 close(data); 2499 } 2500 }; 2501 } 2502 2503 function outside(data) { 2504 // Unbind previous tap handler if it exists 2505 if (data.outside) $doc.off('tap' + namespace, data.outside); 2506 2507 // Close menu when tapped outside, debounced to wait for state 2508 return _.debounce(function(evt) { 2509 if (!data.open) return; 2510 var menu = $(evt.target).closest('.w-nav-menu'); 2511 if (!data.menu.is(menu)) { 2512 close(data); 2513 } 2514 }); 2515 } 2516 2517 function resize(i, el) { 2518 var data = $.data(el, namespace);
2519 // Check for collapsed state based on button display 2520 var collapsed = data.collapsed = data.button.css('display') != 'none'; 2521 // Close menu if button is no longer visible (and not in designer) 2522 if (data.open && !collapsed && !designer) close(data, true); 2523 // Set max-width of links + dropdowns to match container 2524 if (data.container.length) { 2525 var updateEachMax = updateMax(data); 2526 data.links.each(updateEachMax); 2527 data.dropdowns.each(updateEachMax); 2528 } 2529 // If currently open, update height to match body 2530 if (data.open) { 2531 setOverlayHeight(data); 2532 } 2533 } 2534 2535 var maxWidth = 'max-width'; 2536 function updateMax(data) { 2537 // Set max-width of each element to match container 2538 var containMax = data.container.css(maxWidth); 2539 if (containMax == 'none') containMax = ''; 2540 return function(i, link) { 2541 link = $(link); 2542 link.css(maxWidth, ''); 2543 // Don't set the max-width if an upstream value exists 2544 if (link.css(maxWidth) == 'none') link.css(maxWidth, containMax); 2545 }; 2546 } 2547 2548 function open(data, immediate) { 2549 if (data.open) return; 2550 data.open = true; 2551 data.menu.addClass(menuOpen); 2552 data.links.addClass(linkOpen); 2553 data.button.addClass(buttonOpen); 2554 var config = data.config; 2555 var animation = config.animation; 2556 if (animation == 'none' || !tram.support.transform) immediate = true; 2557 var bodyHeight = setOverlayHeight(data); 2558 var menuHeight = data.menu.outerHeight(true); 2559 var menuWidth = data.menu.outerWidth(true); 2560 var navHeight = data.el.height(); 2561 var navbarEl = data.el[0]; 2562 resize(0, navbarEl); 2563 ix.intro(0, navbarEl); 2564 Webflow.redraw.up(); 2565 2566 // Listen for tap outside events 2567 if (!designer) $doc.on('tap' + namespace, data.outside); 2568 2569 // No transition for immediate 2570 if (immediate) return; 2571 2572 var transConfig = 'transform ' + config.duration + 'ms ' + config.easing; 2573 2574 // Add menu to overlay 2575 if (data.overlay) { 2576 data.overlay.show().append(data.menu); 2577 } 2578 2579 // Over left/right 2580 if (config.animOver) { 2581 tram(data.menu) 2582 .add(transConfig) 2583 .set({ x: config.animDirect * menuWidth, height: bodyHeight }).start({ x: 0 }); 2584 data.overlay && data.overlay.width(menuWidth); 2585 return; 2586 } 2587 2588 // Drop Down 2589 var offsetY = navHeight + menuHeight; 2590 tram(data.menu) 2591 .add(transConfig) 2592 .set({ y: -offsetY }).start({ y: 0 }); 2593 } 2594 2595 function setOverlayHeight(data) { 2596 var config = data.config; 2597 var bodyHeight = config.docHeight ? $doc.height() : $body.height(); 2598 if (config.animOver) { 2599 data.menu.height(bodyHeight); 2600 } else if (data.el.css('position') != 'fixed') { 2601 bodyHeight -= data.el.height(); 2602 } 2603 data.overlay && data.overlay.height(bodyHeight); 2604 return bodyHeight; 2605 } 2606 2607 function close(data, immediate) { 2608 if (!data.open) return; 2609 data.open = false; 2610 data.button.removeClass(buttonOpen); 2611 var config = data.config; 2612 if (config.animation == 'none' || !tram.support.transform) immediate = true; 2613 var animation = config.animation; 2614 ix.outro(0, data.el[0]); 2615 2616 // Stop listening for tap outside events 2617 $doc.off('tap' + namespace, data.outside); 2618 2619 if (immediate) { 2620 tram(data.menu).stop(); 2621 complete(); 2622 return; 2623 } 2624 2625 var transConfig = 'transform ' + config.duration + 'ms ' + config.easing2; 2626 var menuHeight = data.menu.outerHeight(true); 2627 var menuWidth = data.menu.outerWidth(true); 2628 var navHeight = data.el.height(); 2629 2630 // Over left/right 2631 if (config.animOver) { 2632 tram(data.menu) 2633 .add(transConfig) 2634 .start({ x: menuWidth * config.animDirect }).then(complete); 2635 return; 2636 } 2637 2638 // Drop Down 2639 var offsetY = navHeight + menuHeight; 2640 tram(data.menu) 2641 .add(transConfig) 2642 .start({ y: -offsetY }).then(complete); 2643 2644 function complete() { 2645 data.menu.height(''); 2646 tram(data.menu).set({ x: 0, y: 0 }); 2647 data.menu.removeClass(menuOpen); 2648 data.links.removeClass(linkOpen); 2649 if (data.overlay && data.overlay.children().length) { 2650 // Move menu back to parent 2651 data.menu.appendTo(data.parent); 2652 data.overlay.attr('style', '').hide(); 2653 } 2654 2655 // Trigger event so other components can hook in (dropdown) 2656 data.el.triggerHandler('w-close'); 2657 } 2658 } 2659 2660 // Export module 2661 return api; 2662}; 2663 2664},{"./webflow-lib":7}],12:[function(require,module,exports){ 2665'use strict'; 2666 2667/** 2668 * Webflow: Smooth scroll 2669 */ 2670 2671var Webflow = require('./webflow-lib'); 2672 2673module.exports = function($, _) { 2674 var $doc = $(document); 2675 var win = window; 2676 var loc = win.location; 2677 var history = inIframe() ? null : win.history;
2678 var validHash = /^[a-zA-Z][\w:.-]*$/; 2679 2680 function inIframe() { 2681 try { 2682 return !!win.frameElement; 2683 } catch (e) { 2684 return true; 2685 } 2686 } 2687 2688 function ready() { 2689 // If hash is already present on page load, scroll to it right away 2690 if (loc.hash) { 2691 findEl(loc.hash.substring(1)); 2692 } 2693 2694 // When clicking on a link, check if it links to another part of the page 2695 $doc.on('click', 'a', function(e) { 2696 if (Webflow.env('design')) { 2697 return; 2698 } 2699 2700 // Ignore links being used by jQuery mobile 2701 if (window.$.mobile && $(e.currentTarget).hasClass('ui-link')) return; 2702 2703 // Ignore empty # links 2704 if (this.getAttribute('href') === '#') { 2705 e.preventDefault(); 2706 return; 2707 } 2708 2709 var hash = this.hash ? this.hash.substring(1) : null; 2710 if (hash) { 2711 findEl(hash, e); 2712 } 2713 }); 2714 } 2715 2716 function findEl(hash, e) { 2717 if (!validHash.test(hash)) return; 2718 2719 var el = $('#' + hash); 2720 if (!el.length) { 2721 return; 2722 } 2723 2724 if (e) { 2725 e.preventDefault(); 2726 e.stopPropagation(); 2727 } 2728 2729 // Push new history state 2730 if (loc.hash !== hash && history && history.pushState) { 2731 var oldHash = history.state && history.state.hash; 2732 if (oldHash !== hash) { 2733 history.pushState({ hash: hash }, '', '#' + hash); 2734 } 2735 } 2736 2737 // If a fixed header exists, offset for the height 2738 var header = $('header, body > .header, body > .w-nav:not([data-no-scroll])'); 2739 var offset = header.css('position') === 'fixed' ? header.outerHeight() : 0; 2740 2741 win.setTimeout(function() { 2742 scroll(el, offset); 2743 }, e ? 0 : 300); 2744 } 2745 2746 function scroll(el, offset){ 2747 var start = $(win).scrollTop(); 2748 var end = el.offset().top - offset; 2749 2750 // If specified, scroll so that the element ends up in the middle of the viewport 2751 if (el.data('scroll') == 'mid') { 2752 var available = $(win).height() - offset; 2753 var elHeight = el.outerHeight(); 2754 if (elHeight < available) { 2755 end -= Math.round((available - elHeight) / 2); 2756 } 2757 } 2758 2759 var mult = 1; 2760 2761 // Check for custom time multiplier on the body and the element 2762 $('body').add(el).each(function(i) { 2763 var time = parseFloat($(this).attr('data-scroll-time'), 10); 2764 if (!isNaN(time) && (time === 0 || time > 0)) { 2765 mult = time; 2766 } 2767 }); 2768 2769 // Shim for IE8 and below 2770 if (!Date.now) { 2771 Date.now = function() { return new Date().getTime(); }; 2772 } 2773 2774 var clock = Date.now(); 2775 var animate = win.requestAnimationFrame || win.mozRequestAnimationFrame || win.webkitRequestAnimationFrame || function(fn) { win.setTimeout(fn, 15); }; 2776 var duration = (472.143 * Math.log(Math.abs(start - end) +125) - 2000) * mult; 2777 2778 var step = function() { 2779 var elapsed = Date.now() - clock; 2780 win.scroll(0, getY(start, end, elapsed, duration)); 2781 2782 if (elapsed <= duration) { 2783 animate(step); 2784 } 2785 }; 2786 2787 step(); 2788 } 2789 2790 function getY(start, end, elapsed, duration) { 2791 if (elapsed > duration) { 2792 return end; 2793 } 2794 2795 return start + (end - start) * ease(elapsed / duration); 2796 } 2797 2798 function ease(t) { 2799 return t<0.5 ? 4*t*t*t : (t-1)*(2*t-2)*(2*t-2)+1; 2800 } 2801 2802 // Export module 2803 return { ready: ready }; 2804}; 2805 2806},{"./webflow-lib":7}],13:[function(require,module,exports){ 2807'use strict'; 2808 2809/** 2810 * Webflow: Slider component 2811 */ 2812 2813var Webflow = require('./webflow-lib'); 2814 2815module.exports = function($, _) { 2816 var api = {}; 2817 var tram = $.tram; 2818 var $doc = $(document); 2819 var $sliders; 2820 var designer; 2821 var inApp = Webflow.env(); 2822 var namespace = '.w-slider'; 2823 var dot = '<div class="w-slider-dot" data-wf-ignore />'; 2824 var ix = Webflow.ixEvents(); 2825 var fallback; 2826 var redraw; 2827 2828 // ----------------------------------- 2829 // Module methods 2830 2831 api.ready = function() { 2832 init(); 2833 }; 2834 2835 api.design = function() { 2836 designer = true; 2837 init(); 2838 }; 2839 2840 api.preview = function() { 2841 designer = false; 2842 init(); 2843 }; 2844 2845 api.redraw = function() { 2846 redraw = true; 2847 init(); 2848 }; 2849 2850 api.destroy = removeListeners; 2851 2852 // ----------------------------------- 2853 // Private methods 2854
2855 function init() { 2856 // Find all sliders on the page 2857 $sliders = $doc.find(namespace); 2858 if (!$sliders.length) return; 2859 $sliders.filter(':visible').each(build); 2860 redraw = null; 2861 if (fallback) return; 2862 2863 // Wire events 2864 removeListeners(); 2865 addListeners(); 2866 } 2867 2868 function removeListeners() { 2869 Webflow.resize.off(renderAll); 2870 Webflow.redraw.off(api.redraw); 2871 } 2872 2873 function addListeners() { 2874 Webflow.resize.on(renderAll); 2875 Webflow.redraw.on(api.redraw); 2876 } 2877 2878 function renderAll() { 2879 $sliders.filter(':visible').each(render); 2880 } 2881 2882 function build(i, el) { 2883 var $el = $(el); 2884 2885 // Store slider state in data 2886 var data = $.data(el, namespace); 2887 if (!data) data = $.data(el, namespace, { 2888 index: 0, 2889 depth: 1, 2890 el: $el, 2891 config: {} 2892 }); 2893 data.mask = $el.children('.w-slider-mask'); 2894 data.left = $el.children('.w-slider-arrow-left'); 2895 data.right = $el.children('.w-slider-arrow-right'); 2896 data.nav = $el.children('.w-slider-nav'); 2897 data.slides = data.mask.children('.w-slide'); 2898 data.slides.each(ix.reset); 2899 if (redraw) data.maskWidth = 0; 2900 2901 // Disable in old browsers 2902 if (!tram.support.transform) { 2903 data.left.hide(); 2904 data.right.hide(); 2905 data.nav.hide(); 2906 fallback = true; 2907 return; 2908 } 2909 2910 // Remove old events 2911 data.el.off(namespace); 2912 data.left.off(namespace); 2913 data.right.off(namespace); 2914 data.nav.off(namespace); 2915 2916 // Set config from data attributes 2917 configure(data); 2918 2919 // Add events based on mode 2920 if (designer) { 2921 data.el.on('setting' + namespace, handler(data)); 2922 stopTimer(data); 2923 data.hasTimer = false; 2924 } else { 2925 data.el.on('swipe' + namespace, handler(data)); 2926 data.left.on('tap' + namespace, previous(data)); 2927 data.right.on('tap' + namespace, next(data)); 2928 2929 // Start timer if autoplay is true, only once 2930 if (data.config.autoplay && !data.hasTimer) { 2931 data.hasTimer = true; 2932 data.timerCount = 1; 2933 startTimer(data); 2934 } 2935 } 2936 2937 // Listen to nav events 2938 data.nav.on('tap' + namespace, '> div', handler(data)); 2939 2940 // Remove gaps from formatted html (for inline-blocks) 2941 if (!inApp) { 2942 data.mask.contents().filter(function() { 2943 return this.nodeType === 3; 2944 }).remove(); 2945 } 2946 2947 // Run first render 2948 render(i, el); 2949 } 2950 2951 function configure(data) { 2952 var config = {}; 2953 2954 config.crossOver = 0; 2955 2956 // Set config options from data attributes 2957 config.animation = data.el.attr('data-animation') || 'slide'; 2958 if (config.animation == 'outin') { 2959 config.animation = 'cross'; 2960 config.crossOver = 0.5; 2961 } 2962 config.easing = data.el.attr('data-easing') || 'ease'; 2963 2964 var duration = data.el.attr('data-duration'); 2965 config.duration = duration != null ? +duration : 500; 2966 2967 if (+data.el.attr('data-infinite')) config.infinite = true; 2968 2969 if (+data.el.attr('data-hide-arrows')) { 2970 config.hideArrows = true; 2971 } else if (data.config.hideArrows) { 2972 data.left.show(); 2973 data.right.show(); 2974 } 2975 2976 if (+data.el.attr('data-autoplay')) { 2977 config.autoplay = true; 2978 config.delay = +data.el.attr('data-delay') || 2000; 2979 config.timerMax = +data.el.attr('data-autoplay-limit'); 2980 // Disable timer on first touch or mouse down 2981 var touchEvents = 'mousedown' + namespace + ' touchstart' + namespace; 2982 if (!designer) data.el.off(touchEvents).one(touchEvents, function() { 2983 stopTimer(data); 2984 }); 2985 } 2986 2987 // Use edge buffer to help calculate page count 2988 var arrowWidth = data.right.width(); 2989 config.edge = arrowWidth ? arrowWidth + 40 : 100; 2990 2991 // Store config in data 2992 data.config = config; 2993 } 2994 2995 function previous(data) { 2996 return function(evt) { 2997 change(data, { index: data.index - 1, vector: -1 }); 2998 }; 2999 } 3000 3001 function next(data) { 3002 return function(evt) { 3003 change(data, { index: data.index + 1, vector: 1 }); 3004 }; 3005 } 3006 3007 function select(data, value) { 3008 // Select page based on slide element index 3009 var found = null; 3010 if (value === data.slides.length) { 3011 init(); layout(data); // Rebuild and find new slides 3012 } 3013 _.each(data.anchors, function(anchor, index) { 3014 $(anchor.els).each(function(i, el) { 3015 if ($(el).index() === value) found = index; 3016 }); 3017 });
3018 if (found != null) change(data, { index: found, immediate: true }); 3019 } 3020 3021 function startTimer(data) { 3022 stopTimer(data); 3023 var config = data.config; 3024 var timerMax = config.timerMax; 3025 if (timerMax && data.timerCount++ > timerMax) return; 3026 data.timerId = window.setTimeout(function() { 3027 if (data.timerId == null || designer) return; 3028 next(data)(); 3029 startTimer(data); 3030 }, config.delay); 3031 } 3032 3033 function stopTimer(data) { 3034 window.clearTimeout(data.timerId); 3035 data.timerId = null; 3036 } 3037 3038 function handler(data) { 3039 return function(evt, options) { 3040 options = options || {}; 3041 3042 // Designer settings 3043 if (designer && evt.type == 'setting') { 3044 if (options.select == 'prev') return previous(data)(); 3045 if (options.select == 'next') return next(data)(); 3046 configure(data); 3047 layout(data); 3048 if (options.select == null) return; 3049 select(data, options.select); 3050 return; 3051 } 3052 3053 // Swipe event 3054 if (evt.type == 'swipe') { 3055 if (Webflow.env('editor')) return; 3056 if (options.direction == 'left') return next(data)(); 3057 if (options.direction == 'right') return previous(data)(); 3058 return; 3059 } 3060 3061 // Page buttons 3062 if (data.nav.has(evt.target).length) { 3063 change(data, { index: $(evt.target).index() }); 3064 } 3065 }; 3066 } 3067 3068 function change(data, options) { 3069 options = options || {}; 3070 var config = data.config; 3071 var anchors = data.anchors; 3072 3073 // Set new index 3074 data.previous = data.index; 3075 var index = options.index; 3076 var shift = {}; 3077 if (index < 0) { 3078 index = anchors.length-1; 3079 if (config.infinite) { 3080 // Shift first slide to the end 3081 shift.x = -data.endX; 3082 shift.from = 0; 3083 shift.to = anchors[0].width; 3084 } 3085 } else if (index >= anchors.length) { 3086 index = 0; 3087 if (config.infinite) { 3088 // Shift last slide to the start 3089 shift.x = anchors[anchors.length-1].width; 3090 shift.from = -anchors[anchors.length-1].x; 3091 shift.to = shift.from - shift.x; 3092 } 3093 } 3094 data.index = index; 3095 3096 // Select page nav 3097 var active = data.nav.children().eq(data.index).addClass('w-active'); 3098 data.nav.children().not(active).removeClass('w-active'); 3099 3100 // Hide arrows 3101 if (config.hideArrows) { 3102 data.index === anchors.length-1 ? data.right.hide() : data.right.show(); 3103 data.index === 0 ? data.left.hide() : data.left.show(); 3104 } 3105 3106 // Get page offset from anchors 3107 var lastOffsetX = data.offsetX || 0; 3108 var offsetX = data.offsetX = -anchors[data.index].x; 3109 var resetConfig = { x: offsetX, opacity: 1, visibility: '' }; 3110 3111 // Transition slides 3112 var targets = $(anchors[data.index].els); 3113 var previous = $(anchors[data.previous] && anchors[data.previous].els); 3114 var others = data.slides.not(targets); 3115 var animation = config.animation; 3116 var easing = config.easing; 3117 var duration = Math.round(config.duration); 3118 var vector = options.vector || (data.index > data.previous ? 1 : -1); 3119 var fadeRule = 'opacity ' + duration + 'ms ' + easing; 3120 var slideRule = 'transform ' + duration + 'ms ' + easing; 3121 3122 // Trigger IX events 3123 if (!designer) { 3124 targets.each(ix.intro); 3125 others.each(ix.outro); 3126 } 3127 3128 // Set immediately after layout changes (but not during redraw) 3129 if (options.immediate && !redraw) { 3130 tram(targets).set(resetConfig); 3131 resetOthers(); 3132 return; 3133 } 3134 3135 // Exit early if index is unchanged 3136 if (data.index == data.previous) return; 3137 3138 // Cross Fade / Out-In 3139 if (animation == 'cross') { 3140 var reduced = Math.round(duration - duration * config.crossOver); 3141 var wait = Math.round(duration - reduced); 3142 fadeRule = 'opacity ' + reduced + 'ms ' + easing; 3143 tram(previous) 3144 .set({ visibility: '' }) 3145 .add(fadeRule) 3146 .start({ opacity: 0 }); 3147 tram(targets) 3148 .set({ visibility: '', x: offsetX, opacity: 0, zIndex: data.depth++ }) 3149 .add(fadeRule) 3150 .wait(wait) 3151 .then({ opacity: 1 }) 3152 .then(resetOthers); 3153 return; 3154 } 3155 3156 // Fade Over 3157 if (animation == 'fade') { 3158 tram(previous) 3159 .set({ visibility: '' }) 3160 .stop(); 3161 tram(targets) 3162 .set({ visibility: '', x: offsetX, opacity: 0, zIndex: data.depth++ }) 3163 .add(fadeRule) 3164 .start({ opacity: 1 }) 3165 .then(resetOthers); 3166 return; 3167 } 3168 3169 // Slide Over 3170 if (animation == 'over') { 3171 resetConfig = { x: data.endX }; 3172 tram(previous) 3173 .set({ visibility: '' }) 3174 .stop(); 3175 tram(targets) 3176 .set({ visibility: '', zIndex: data.depth++, x: offsetX + anchors[data.index].width * vector }) 3177 .add(slideRule) 3178 .start({ x: offsetX }) 3179 .then(resetOthers); 3180 return; 3181 } 3182 3183 // Slide - infinite scroll 3184 if (config.infinite && shift.x) { 3185 tram(data.slides.not(previous)) 3186 .set({ visibility: '', x: shift.x }) 3187 .add(slideRule) 3188 .start({ x: offsetX }); 3189 tram(previous) 3190 .set({ visibility: '', x: shift.from }) 3191 .add(slideRule) 3192 .start({ x: shift.to }); 3193 data.shifted = previous; 3194 3195 } else { 3196 if (config.infinite && data.shifted) { 3197 tram(data.shifted).set({ visibility: '', x: lastOffsetX }); 3198 data.shifted = null; 3199 } 3200 3201 // Slide - basic scroll 3202 tram(data.slides) 3203 .set({ visibility: '' }) 3204 .add(slideRule) 3205 .start({ x: offsetX }); 3206 } 3207 3208 // Helper to move others out of view 3209 function resetOthers() { 3210 var targets = $(anchors[data.index].els); 3211 var others = data.slides.not(targets); 3212 if (animation != 'slide') resetConfig.visibility = 'hidden'; 3213 tram(others).set(resetConfig); 3214 } 3215 } 3216 3217 function render(i, el) { 3218 var data = $.data(el, namespace); 3219 if (maskChanged(data)) return layout(data); 3220 if (designer && slidesChanged(data)) layout(data); 3221 } 3222 3223 function layout(data) { 3224 // Determine page count from width of slides 3225 var pages = 1; 3226 var offset = 0; 3227 var anchor = 0; 3228 var width = 0; 3229 var maskWidth = data.maskWidth; 3230 var threshold = maskWidth - data.config.edge; 3231 if (threshold < 0) threshold = 0; 3232 data.anchors = [{ els: [], x: 0, width: 0 }]; 3233 data.slides.each(function(i, el) { 3234 if (anchor - offset > threshold) { 3235 pages++; 3236 offset += maskWidth; 3237 // Store page anchor for transition 3238 data.anchors[pages-1] = { els: [], x: anchor, width: 0 }; 3239 } 3240 // Set next anchor using current width + margin 3241 width = $(el).outerWidth(true); 3242 anchor += width; 3243 data.anchors[pages-1].width += width; 3244 data.anchors[pages-1].els.push(el); 3245 });
3246 data.endX = anchor; 3247 3248 // Build dots if nav exists and needs updating 3249 if (designer) data.pages = null; 3250 if (data.nav.length && data.pages !== pages){ 3251 data.pages = pages; 3252 buildNav(data); 3253 } 3254 3255 // Make sure index is still within range and call change handler 3256 var index = data.index; 3257 if (index >= pages) index = pages-1; 3258 change(data, { immediate: true, index: index }); 3259 } 3260 3261 function buildNav(data) { 3262 var dots = []; 3263 var $dot; 3264 var spacing = data.el.attr('data-nav-spacing'); 3265 if (spacing) spacing = parseFloat(spacing) + 'px'; 3266 for (var i=0; i<data.pages; i++) { 3267 $dot = $(dot); 3268 if (data.nav.hasClass('w-num')) $dot.text(i+1); 3269 if (spacing != null) $dot.css({ 3270 'margin-left': spacing, 3271 'margin-right': spacing 3272 }); 3273 dots.push($dot); 3274 } 3275 data.nav.empty().append(dots); 3276 } 3277 3278 function maskChanged(data) { 3279 var maskWidth = data.mask.width(); 3280 if (data.maskWidth !== maskWidth) { 3281 data.maskWidth = maskWidth; 3282 return true; 3283 } 3284 return false; 3285 } 3286 3287 function slidesChanged(data) { 3288 var slidesWidth = 0; 3289 data.slides.each(function(i, el) { 3290 slidesWidth += $(el).outerWidth(true); 3291 }); 3292 if (data.slidesWidth !== slidesWidth) { 3293 data.slidesWidth = slidesWidth; 3294 return true; 3295 } 3296 return false; 3297 } 3298 3299 // Export module 3300 return api; 3301}; 3302 3303},{"./webflow-lib":7}],14:[function(require,module,exports){ 3304'use strict'; 3305 3306/** 3307 * Webflow: Tabs component 3308 */ 3309 3310var Webflow = require('./webflow-lib'); 3311 3312module.exports = function($, _) { 3313 var api = {}; 3314 var tram = $.tram; 3315 var $win = $(window); 3316 var $doc = $(document); 3317 var $tabs; 3318 var design; 3319 var env = Webflow.env; 3320 var safari = env.safari; 3321 var inApp = env(); 3322 var tabAttr = 'data-w-tab'; 3323 var namespace = '.w-tabs'; 3324 var linkCurrent = 'w--current'; 3325 var tabActive = 'w--tab-active'; 3326 var ix = Webflow.ixEvents(); 3327 3328 // ----------------------------------- 3329 // Module methods 3330 3331 api.ready = api.design = api.preview = init; 3332 3333 // ----------------------------------- 3334 // Private methods 3335 3336 function init() { 3337 design = inApp && Webflow.env('design'); 3338 3339 // Find all instances on the page 3340 $tabs = $doc.find(namespace); 3341 if (!$tabs.length) return; 3342 $tabs.each(build); 3343 } 3344 3345 function build(i, el) { 3346 var $el = $(el); 3347 3348 // Store state in data 3349 var data = $.data(el, namespace); 3350 if (!data) data = $.data(el, namespace, { el: $el, config: {} }); 3351 data.current = null; 3352 data.menu = $el.children('.w-tab-menu'); 3353 data.links = data.menu.children('.w-tab-link'); 3354 data.content = $el.children('.w-tab-content'); 3355 data.panes = data.content.children('.w-tab-pane'); 3356 3357 // Remove old events 3358 data.el.off(namespace); 3359 data.links.off(namespace); 3360 3361 // Set config from data attributes 3362 configure(data); 3363 3364 // Wire up events when not in design mode 3365 if (!design) { 3366 data.links.on('click' + namespace, linkSelect(data)); 3367 3368 // Trigger first intro event from current tab 3369 var $link = data.links.filter('.' + linkCurrent); 3370 var tab = $link.attr(tabAttr); 3371 tab && changeTab(data, { tab: tab, immediate: true }); 3372 } 3373 } 3374 3375 function configure(data) { 3376 var config = {}; 3377 var old = data.config || {}; 3378 3379 // Set config options from data attributes 3380 config.easing = data.el.attr('data-easing') || 'ease'; 3381 3382 var intro = +data.el.attr('data-duration-in'); 3383 intro = config.intro = intro === intro ? intro : 0; 3384 3385 var outro = +data.el.attr('data-duration-out'); 3386 outro = config.outro = outro === outro ? outro : 0; 3387 3388 config.immediate = !intro && !outro; 3389 3390 // Store config in data 3391 data.config = config; 3392 } 3393 3394 function linkSelect(data) { 3395 return function(evt) { 3396 var tab = evt.currentTarget.getAttribute(tabAttr); 3397 tab && changeTab(data, { tab: tab }); 3398 }; 3399 } 3400 3401 function changeTab(data, options) { 3402 options = options || {}; 3403 3404 var config = data.config; 3405 var easing = config.easing; 3406 var tab = options.tab; 3407 3408 // Don't select the same tab twice 3409 if (tab === data.current) return; 3410 data.current = tab; 3411 3412 // Select the current link 3413 data.links.each(function(i, el) { 3414 var $el = $(el); 3415 if (el.getAttribute(tabAttr) === tab) $el.addClass(linkCurrent).each(ix.intro); 3416 else if ($el.hasClass(linkCurrent)) $el.removeClass(linkCurrent).each(ix.outro);
3417 }); 3418 3419 // Find the new tab panes and keep track of previous 3420 var targets = []; 3421 var previous = []; 3422 data.panes.each(function(i, el) { 3423 var $el = $(el); 3424 if (el.getAttribute(tabAttr) === tab) { 3425 targets.push(el); 3426 } else if ($el.hasClass(tabActive)) { 3427 previous.push(el); 3428 } 3429 }); 3430 3431 var $targets = $(targets); 3432 var $previous = $(previous); 3433 3434 // Switch tabs immediately and bypass transitions 3435 if (options.immediate || config.immediate) { 3436 $targets.addClass(tabActive).each(ix.intro); 3437 $previous.removeClass(tabActive); 3438 Webflow.redraw.up(); 3439 return; 3440 } 3441 3442 // Fade out the currently active tab before intro 3443 if ($previous.length && config.outro) { 3444 $previous.each(ix.outro); 3445 tram($previous) 3446 .add('opacity ' + config.outro + 'ms ' + easing, { fallback: safari }) 3447 .start({ opacity: 0 }) 3448 .then(intro); 3449 } else { 3450 // Skip the outro and play intro 3451 intro(); 3452 } 3453 3454 // Fade in the new target 3455 function intro() { 3456 // Clear previous active class + inline style 3457 $previous.removeClass(tabActive).removeAttr('style'); 3458 3459 // Add active class to new target 3460 $targets.addClass(tabActive).each(ix.intro); 3461 Webflow.redraw.up(); 3462 3463 // Set opacity immediately if intro is zero 3464 if (!config.intro) return tram($targets).set({ opacity: 1 }); 3465 3466 // Otherwise fade in opacity 3467 tram($targets) 3468 .set({ opacity: 0 }) 3469 .redraw() 3470 .add('opacity ' + config.intro + 'ms ' + easing, { fallback: safari }) 3471 .start({ opacity: 1 }); 3472 } 3473 } 3474 3475 // Export module 3476 return api; 3477}; 3478 3479},{"./webflow-lib":7}],15:[function(require,module,exports){ 3480'use strict'; 3481 3482/** 3483 * Webflow: Touch events 3484 */ 3485 3486module.exports = function($, _) { 3487 var api = {}; 3488 var fallback = !document.addEventListener; 3489 var getSelection = window.getSelection; 3490 3491 // Fallback to click events in old IE 3492 if (fallback) { 3493 $.event.special.tap = { bindType: 'click', delegateType: 'click' }; 3494 } 3495 3496 api.init = function(el) { 3497 if (fallback) return null; 3498 el = typeof el === 'string' ? $(el).get(0) : el; 3499 return el ? new Touch(el) : null; 3500 }; 3501 3502 function Touch(el) { 3503 var active = false; 3504 var dirty = false; 3505 var useTouch = false; 3506 var thresholdX = Math.min(Math.round(window.innerWidth * 0.04), 40); 3507 var startX, startY, lastX; 3508 3509 el.addEventListener('touchstart', start, false); 3510 el.addEventListener('touchmove', move, false); 3511 el.addEventListener('touchend', end, false); 3512 el.addEventListener('touchcancel', cancel, false); 3513 el.addEventListener('mousedown', start, false); 3514 el.addEventListener('mousemove', move, false); 3515 el.addEventListener('mouseup', end, false); 3516 el.addEventListener('mouseout', cancel, false); 3517 3518 function start(evt) { 3519 // We don’t handle multi-touch events yet. 3520 var touches = evt.touches; 3521 if (touches && touches.length > 1) { 3522 return; 3523 } 3524 3525 active = true; 3526 dirty = false; 3527 3528 if (touches) { 3529 useTouch = true; 3530 startX = touches[0].clientX; 3531 startY = touches[0].clientY; 3532 } else { 3533 startX = evt.clientX; 3534 startY = evt.clientY; 3535 } 3536 3537 lastX = startX; 3538 } 3539 3540 function move(evt) { 3541 if (!active) return; 3542 3543 if (useTouch && evt.type === 'mousemove') { 3544 evt.preventDefault(); 3545 evt.stopPropagation(); 3546 return; 3547 } 3548 3549 var touches = evt.touches; 3550 var x = touches ? touches[0].clientX : evt.clientX; 3551 var y = touches ? touches[0].clientY : evt.clientY; 3552 3553 var velocityX = x - lastX; 3554 lastX = x; 3555 3556 // Allow swipes while pointer is down, but prevent them during text selection 3557 if (Math.abs(velocityX) > thresholdX && getSelection && getSelection() + '' === '') { 3558 triggerEvent('swipe', evt, { direction: velocityX > 0 ? 'right' : 'left' }); 3559 cancel(); 3560 } 3561 3562 // If pointer moves more than 10px flag to cancel tap 3563 if (Math.abs(x - startX) > 10 || Math.abs(y - startY) > 10) { 3564 dirty = true; 3565 } 3566 } 3567 3568 function end(evt) { 3569 if (!active) return; 3570 active = false; 3571 3572 if (useTouch && evt.type === 'mouseup') { 3573 evt.preventDefault(); 3574 evt.stopPropagation(); 3575 useTouch = false; 3576 return; 3577 } 3578 3579 if (!dirty) triggerEvent('tap', evt); 3580 } 3581 3582 function cancel(evt) { 3583 active = false; 3584 } 3585 3586 function destroy() { 3587 el.removeEventListener('touchstart', start, false); 3588 el.removeEventListener('touchmove', move, false); 3589 el.removeEventListener('touchend', end, false); 3590 el.removeEventListener('touchcancel', cancel, false); 3591 el.removeEventListener('mousedown', start, false); 3592 el.removeEventListener('mousemove', move, false); 3593 el.removeEventListener('mouseup', end, false);
3594 el.removeEventListener('mouseout', cancel, false); 3595 el = null; 3596 } 3597 3598 // Public instance methods 3599 this.destroy = destroy; 3600 } 3601 3602 // Wrap native event to supoprt preventdefault + stopPropagation 3603 function triggerEvent(type, evt, data) { 3604 var newEvent = $.Event(type, { originalEvent: evt }); 3605 $(evt.target).trigger(newEvent, data); 3606 } 3607 3608 // Listen for touch events on all nodes by default. 3609 api.instance = api.init(document); 3610 3611 // Export module 3612 return api; 3613}; 3614 3615},{}],16:[function(require,module,exports){ 3616/*! 3617 * tram.js v0.8.1-global 3618 * Cross-browser CSS3 transitions in JavaScript 3619 * https://github.com/bkwld/tram 3620 * MIT License 3621 */ 3622window.tram=function(a){function b(a,b){var c=new L.Bare;return c.init(a,b)}function c(a){return a.replace(/[A-Z]/g,function(a){return"-"+a.toLowerCase()})}function d(a){var b=parseInt(a.slice(1),16),c=b>>16&255,d=b>>8&255,e=255&b;return[c,d,e]}function e(a,b,c){return"#"+(1<<24|a<<16|b<<8|c).toString(16).slice(1)}function f(){}function g(a,b){_("Type warning: Expected: ["+a+"] Got: ["+typeof b+"] "+b)}function h(a,b,c){_("Units do not match ["+a+"]: "+b+", "+c)}function i(a,b,c){if(void 0!==b&&(c=b),void 0===a)return c;var d=c;return Z.test(a)||!$.test(a)?d=parseInt(a,10):$.test(a)&&(d=1e3*parseFloat(a)),0>d&&(d=0),d===d?d:c}function j(a){for(var b=-1,c=a?a.length:0,d=[];++b<c;){var e=a[b];e&&d.push(e)}return d}var k=function(a,b,c){function d(a){return"object"==typeof a}function e(a){return"function"==typeof a}function f(){}function g(h,i){function j(){var a=new k;return e(a.init)&&a.init.apply(a,arguments),a}function k(){}i===c&&(i=h,h=Object),j.Bare=k;var l,m=f[a]=h[a],n=k[a]=j[a]=new f;return n.constructor=j,j.mixin=function(b){return k[a]=j[a]=g(j,b)[a],j},j.open=function(a){if(l={}
3622,e(a)?l=a.call(j,n,m,j,h):d(a)&&(l=a),d(l))for(var c in l)b.call(l,c)&&(n[c]=l[c]);return e(n.init)||(n.init=h),j},j.open(i)}return g}("prototype",{}.hasOwnProperty),l={ease:["ease",function(a,b,c,d){var e=(a/=d)*a,f=e*a;return b+c*(-2.75*f*e+11*e*e+-15.5*f+8*e+.25*a)}],"ease-in":["ease-in",function(a,b,c,d){var e=(a/=d)*a,f=e*a;return b+c*(-1*f*e+3*e*e+-3*f+2*e)}],"ease-out":["ease-out",function(a,b,c,d){var e=(a/=d)*a,f=e*a;return b+c*(.3*f*e+-1.6*e*e+2.2*f+-1.8*e+1.9*a)}],"ease-in-out":["ease-in-out",function(a,b,c,d){var e=(a/=d)*a,f=e*a;return b+c*(2*f*e+-5*e*e+2*f+2*e)}],linear:["linear",function(a,b,c,d){return c*a/d+b}],"ease-in-quad":["cubic-bezier(0.550, 0.085, 0.680, 0.530)",function(a,b,c,d){return c*(a/=d)*a+b}],"ease-out-quad":["cubic-bezier(0.250, 0.460, 0.450, 0.940)",function(a,b,c,d){return-c*(a/=d)*(a-2)+b}],"ease-in-out-quad":["cubic-bezier(0.455, 0.030, 0.515, 0.955)",function(a,b,c,d){return(a/=d/2)<1?c/2*a*a+b:-c/2*(--a*(a-2)-1)+b}],"ease-in-cubic":["cubic-bezier(0.550, 0.055, 0.675, 0.190)",function(a,b,c,d){return c*(a/=d)*a*a+b}],"ease-out-cubic":["cubic-bezier(0.215, 0.610, 0.355, 1)",function(a,b,c,d){return c*((a=a/d-1)*a*a+1)+b}],"ease-in-out-cubic":["cubic-bezier(0.645, 0.045, 0.355, 1)",function(a,b,c,d){return(a/=d/2)<1?c/2*a*a*a+b:c/2*((a-=2)*a*a+2)+b}],"ease-in-quart":["cubic-bezier(0.895, 0.030, 0.685, 0.220)",function(a,b,c,d){return c*(a/=d)*a*a*a+b}],"ease-out-quart":["cubic-bezier(0.165, 0.840, 0.440, 1)",function(a,b,c,d){return-c*((a=a/d-1)*a*a*a-1)+b}],"ease-in-out-quart":["cubic-bezier(0.770, 0, 0.175, 1)",function(a,b,c,d){return(a/=d/2)<1?c/2*a*a*a*a+b:-c/2*((a-=2)*a*a*a-2)+b}],"ease-in-quint":["cubic-bezier(0.755, 0.050, 0.855, 0.060)",function(a,b,c,d){return c*(a/=d)*a*a*a*a+b}],"ease-out-quint":["cubic-bezier(0.230, 1, 0.320, 1)",function(a,b,c,d){return c*((a=a/d-1)*a*a*a*a+1)+b}],"ease-in-out-quint":["cubic-bezier(0.860, 0, 0.070, 1)",function(a,b,c,d){return(a/=d/2)<1?c/2*a*a*a*a*a+b:c/2*((a-=2)*a*a*a*a+2)+b}],"ease-in-sine":["cubic-bezier(0.470, 0, 0.745, 0.715)",function(a,b,c,d){return-c*Math.cos(a/d*(Math.PI/2))+c+b}],"ease-out-sine":["cubic-bezier(0.390, 0.575, 0.565, 1)",function(a,b,c,d){return c*Math.sin(a/d*(Math.PI/2))+b}],"ease-in-out-sine":["cubic-bezier(0.445, 0.050, 0.550, 0.950)",function(a,b,c,d){return-c/2*(Math.cos(Math.PI*a/d)-1)+b}],"ease-in-expo":["cubic-bezier(0.950, 0.050, 0.795, 0.035)",function(a,b,c,d){return 0===a?b:c*Math.pow(2,10*(a/d-1))+b}],"ease-out-expo":["cubic-bezier(0.190, 1, 0.220, 1)",function(a,b,c,d){return a===d?b+c:c*(-Math.pow(2,-10*a/d)+1)+b}],"ease-in-out-expo":["cubic-bezier(1, 0, 0, 1)",function(a,b,c,d){return 0===a?b:a===d?b+c:(a/=d/2)<1?c/2*Math.pow(2,10*(a-1))+b:c/2*(-Math.pow(2,-10*--a)+2)+b}],"ease-in-circ":["cubic-bezier(0.600, 0.040, 0.980, 0.335)",function(a,b,c,d){return-c*(Math.sqrt(1-(a/=d)*a)-1)+b}],"ease-out-circ":["cubic-bezier(0.075, 0.820, 0.165, 1)",function(a,b,c,d){return c*Math.sqrt(1-(a=a/d-1)*a)+b}],"ease-in-out-circ":["cubic-bezier(0.785, 0.135, 0.150, 0.860)",function(a,b,c,d){return(a/=d/2)<1?-c/2*(Math.sqrt(1-a*a)-1)+b:c/2*(Math.sqrt(1-(a-=2)*a)+1)+b}],"ease-in-back":["cubic-bezier(0.600, -0.280, 0.735, 0.045)",function(a,b,c,d,e){return void 0===e&&(e=1.70158),c*(a/=d)*a*((e+1)*a-e)+b}],"ease-out-back":["cubic-bezier(0.175, 0.885, 0.320, 1.275)",function(a,b,c,d,e){return void 0===e&&(e=1.70158),c*((a=a/d-1)*a*((e+1)*a+e)+1)+b}],"ease-in-out-back":["cubic-bezier(0.680, -0.550, 0.265, 1.550)",function(a,b,c,d,e){return void 0===e&&(e=1.70158),(a/=d/2)<1?c/2*a*a*(((e*=1.525)+1)*a-e)+b:c/2*((a-=2)*a*(((e*=1.525)+1)*a+e)+2)+b}]},m={"ease-in-back":"cubic-bezier(0.600, 0, 0.735, 0.045)","ease-out-back":"cubic-bezier(0.175, 0.885, 0.320, 1)","ease-in-out-back":"cubic-bezier(0.680, 0, 0.265, 1)"},n=document,o=window,p="bkwld-tram",q=/[\-\.0-9]/g,r=/[A-Z]/,s="number",t=/^(rgb|#)/,u=/(em|cm|mm|in|pt|pc|px)$/,v=/(em|cm|mm|in|pt|pc|px|%)$/,w=/(deg|rad|turn)$/,x="unitless",y=/(all|none) 0s ease 0s/,z=/^(width|height)$/,A=" ",B=n.createElement("a"),C=["Webkit","Moz","O","ms"],D=["-webkit-","-moz-","-o-","-ms-"],E=function(a){if
3622(a in B.style)return{dom:a,css:a};var b,c,d="",e=a.split("-");for(b=0;b<e.length;b++)d+=e[b].charAt(0).toUpperCase()+e[b].slice(1);for(b=0;b<C.length;b++)if(c=C[b]+d,c in B.style)return{dom:c,css:D[b]+a}},F=b.support={bind:Function.prototype.bind,transform:E("transform"),transition:E("transition"),backface:E("backface-visibility"),timing:E("transition-timing-function")};if(F.transition){var G=F.timing.dom;if(B.style[G]=l["ease-in-back"][0],!B.style[G])for(var H in m)l[H][0]=m[H]}var I=b.frame=function(){var a=o.requestAnimationFrame||o.webkitRequestAnimationFrame||o.mozRequestAnimationFrame||o.oRequestAnimationFrame||o.msRequestAnimationFrame;return a&&F.bind?a.bind(o):function(a){o.setTimeout(a,16)}}(),J=b.now=function(){var a=o.performance,b=a&&(a.now||a.webkitNow||a.msNow||a.mozNow);return b&&F.bind?b.bind(a):Date.now||function(){return+new Date}}(),K=k(function(b){function d(a,b){var c=j((""+a).split(A)),d=c[0];b=b||{};var e=X[d];if(!e)return _("Unsupported property: "+d);if(!b.weak||!this.props[d]){var f=e[0],g=this.props[d];return g||(g=this.props[d]=new f.Bare),g.init(this.$el,c,e,b),g}}function e(a,b,c){if(a){var e=typeof a;if(b||(this.timer&&this.timer.destroy(),this.queue=[],this.active=!1),"number"==e&&b)return this.timer=new R({duration:a,context:this,complete:h}),void(this.active=!0);if("string"==e&&b){switch(a){case"hide":n.call(this);break;case"stop":k.call(this);break;case"redraw":o.call(this);break;default:d.call(this,a,c&&c[1])}return h.call(this)}if("function"==e)return void a.call(this,this);if("object"==e){var f=0;t.call(this,a,function(a,b){a.span>f&&(f=a.span),a.stop(),a.animate(b)},function(a){"wait"in a&&(f=i(a.wait,0))}),s.call(this),f>0&&(this.timer=new R({duration:f,context:this}),this.active=!0,b&&(this.timer.complete=h));var g=this,j=!1,l={};I(function(){t.call(g,a,function(a){a.active&&(j=!0,l[a.name]=a.nextStyle)}),j&&g.$el.css(l)})}}}function f(a){a=i(a,0),this.active?this.queue.push({options:a}):(this.timer=new R({duration:a,context:this,complete:h}),this.active=!0)}function g(a){return this.active?(this.queue.push({options:a,args:arguments}),void(this.timer.complete=h)):_("No active transition timer. Use start() or wait() before then().")}function h(){if(this.timer&&this.timer.destroy(),this.active=!1,this.queue.length){var a=this.queue.shift();e.call(this,a.options,!0,a.args)}}function k(a){this.timer&&this.timer.destroy(),this.queue=[],this.active=!1;var b;"string"==typeof a?(b={},b[a]=1):b="object"==typeof a&&null!=a?a:this.props,t.call(this,b,u),s.call(this)}function l(a){k.call(this,a),t.call(this,a,v,w)}function m(a){"string"!=typeof a&&(a="block"),this.el.style.display=a}function n(){k.call(this),this.el.style.display="none"}function o(){this.el.offsetHeight}function q(){k.call(this),a.removeData(this.el,p),this.$el=this.el=null}function s(){var a,b,c=[];this.upstream&&c.push(this.upstream);for(a in this.props)b=this.props[a],b.active&&c.push(b.string);c=c.join(","),this.style!==c&&(this.style=c,this.el.style[F.transition.dom]=c)}function t(a,b,e){var f,g,h,i,j=b!==u,k={};for(f in a)h=a[f],f in Y?(k.transform||(k.transform={}),k.transform[f]=h):(r.test(f)&&(f=c(f)),f in X?k[f]=h:(i||(i={}),i[f]=h));for(f in k){if(h=k[f],g=this.props[f],!g){if(!j)continue;g=d.call(this,f)}b.call(this,g,h)}e&&i&&e.call(this,i)}function u(a){a.stop()}function v(a,b){a.set(b)}function w(a){this.$el.css(a)}function x(a,c){b[a]=function(){return this.children?z.call(this,c,arguments):(this.el&&c.apply(this,arguments),this)}}function z(a,b){var c,d=this.children.length;for(c=0;d>c;c++)a.apply(this.children[c],b);return this}b.init=function(b){if(this.$el=a(b),this.el=this.$el[0],this.props={},this.queue=[],this.style="",this.active=!1,T.keepInherited&&!T.fallback){var c=V(this.el,"transition");c&&!y.test(c)&&(this.upstream=c)}F.backface&&T.hideBackface&&U(this.el,F.backface.css,"hidden")},x("add",d),x("start",e),x("wait",f),x("then",g),x("next",h),x("stop",k),x("set",l),x("show",m),x("hide",n),x("redraw",o),x("destroy",q)}),L=k(K,function(b){function c(b,c){var d=a.data(b,p)||a.data(b,p,new K.Bare);return d.el||d.init(b),c?d.start(c):d}b.init=function(b,d){var e=a(b);if(!e.length)return this;if(1===e.length)return c(e[0],d);var f=[];return e.each(function(a,b){f.push(c(b,d))}),this.children=f,this}}),M=k(function(a){function b(){var a=this.get();this.update("auto");var b=this.get();return this.update(a),b}function c(a,b,c){return void 0!==b&&(c=b),a in l?a:c}function d(a){var b=/rgba?\((\d+),\s*(\d+),\s*(\d+)/.exec(a);return(b?e(b[1],b[2],b[3]):a).replace(/#(\w)(\w)(\w)$/,"#$1$1$2$2$3$3")}var f={duration:500,ease:"ease",delay:0};a.init=function(a,b,d,e){this.$el=a,this.el=a[0];var g=b[0];d[2]&&(g=d[2]),W[g]&&(g=W[g]),this.name=g,this.type=d[1],this.duration=i(b[1],this.duration,f.duration),this.ease=c(b[2],this.ease,f.ease),this.delay=i(b[3],this.delay,f.delay),this.span=this.duration+this.delay,this.active=!1,this.nextStyle=null,this.auto=z.test(this.name),this.unit=e.unit||this.unit||T.defaultUnit,this.angle=e.angle||this.angle||T.defaultAngle,T.fallback||e.fallback?this.animate=this.fallback:(this.animate=this.transition,this.string=this.name+A+this.duration+"ms"+("ease"!=this.ease?A+l[this.ease][0]:"")+(this.delay?A+this.delay+"ms":""))},a.set=function(a){a=this.convert(a,this.type),this.update(a),this.redraw()},a.transition=function(a){this.active=!0,a=this.convert(a,this.type),this.auto&&("auto"==this.el.style[this.name]&&(this.update(this.get()),this.redraw()),"auto"==a&&(a=b.call(this))),this.nextStyle=a},a.fallback=function(a){var c=this.el.style[this.name]||this.convert(this.get(),this.type);a=this.convert(a,this.type),this.auto&&("auto"==c&&(c=this.convert(this.get(),this.type)),"auto"==a&&(a=b.call(this))),this.tween=new Q({from:c,to:a,duration:this.duration,delay:this.delay,ease:this.ease,update:this.update,context:this})},a.get=function(){return V(this.el,this.name)},a.update=function(a){U(this.el,this.name,a)},a.stop=function(){(this.active||this.nextStyle)&&(this.active=!1,this.nextStyle=null,U(this.el,this.name,this.get()));var a=this.tween;a&&a.context&&a.destroy()},a.convert=function(a,b){if("auto"==a&&this.auto)return a;var c,e="number"==typeof a,f="string"==typeof a;switch(b){case s:if(e)return a;
3622if(f&&""===a.replace(q,""))return+a;c="number(unitless)";break;case t:if(f){if(""===a&&this.original)return this.original;if(b.test(a))return"#"==a.charAt(0)&&7==a.length?a:d(a)}c="hex or rgb string";break;case u:if(e)return a+this.unit;if(f&&b.test(a))return a;c="number(px) or string(unit)";break;case v:if(e)return a+this.unit;if(f&&b.test(a))return a;c="number(px) or string(unit or %)";break;case w:if(e)return a+this.angle;if(f&&b.test(a))return a;c="number(deg) or string(angle)";break;case x:if(e)return a;if(f&&v.test(a))return a;c="number(unitless) or string(unit or %)"}return g(c,a),a},a.redraw=function(){this.el.offsetHeight}}),N=k(M,function(a,b){a.init=function(){b.init.apply(this,arguments),this.original||(this.original=this.convert(this.get(),t))}}),O=k(M,function(a,b){a.init=function(){b.init.apply(this,arguments),this.animate=this.fallback},a.get=function(){return this.$el[this.name]()},a.update=function(a){this.$el[this.name](a)}}),P=k(M,function(a,b){function c(a,b){var c,d,e,f,g;for(c in a)f=Y[c],e=f[0],d=f[1]||c,g=this.convert(a[c],e),b.call(this,d,g,e)}a.init=function(){b.init.apply(this,arguments),this.current||(this.current={},Y.perspective&&T.perspective&&(this.current.perspective=T.perspective,U(this.el,this.name,this.style(this.current)),this.redraw()))},a.set=function(a){c.call(this,a,function(a,b){this.current[a]=b}),U(this.el,this.name,this.style(this.current)),this.redraw()},a.transition=function(a){var b=this.values(a);this.tween=new S({current:this.current,values:b,duration:this.duration,delay:this.delay,ease:this.ease});var c,d={};for(c in this.current)d[c]=c in b?b[c]:this.current[c];this.active=!0,this.nextStyle=this.style(d)},a.fallback=function(a){var b=this.values(a);this.tween=new S({current:this.current,values:b,duration:this.duration,delay:this.delay,ease:this.ease,update:this.update,context:this})},a.update=function(){U(this.el,this.name,this.style(this.current))},a.style=function(a){var b,c="";for(b in a)c+=b+"("+a[b]+") ";return c},a.values=function(a){var b,d={};return c.call(this,a,function(a,c,e){d[a]=c,void 0===this.current[a]&&(b=0,~a.indexOf("scale")&&(b=1),this.current[a]=this.convert(b,e))}),d}}),Q=k(function(b){function c(a){1===n.push(a)&&I(g)}function g(){var a,b,c,d=n.length;if(d)for(I(g),b=J(),a=d;a--;)c=n[a],c&&c.render(b)}function i(b){var c,d=a.inArray(b,n);d>=0&&(c=n.slice(d+1),n.length=d,c.length&&(n=n.concat(c)))}function j(a){return Math.round(a*o)/o}function k(a,b,c){return e(a[0]+c*(b[0]-a[0]),a[1]+c*(b[1]-a[1]),a[2]+c*(b[2]-a[2]))}var m={ease:l.ease[1],from:0,to:1};b.init=function(a){this.duration=a.duration||0,this.delay=a.delay||0;var b=a.ease||m.ease;l[b]&&(b=l[b][1]),"function"!=typeof b&&(b=m.ease),this.ease=b,this.update=a.update||f,this.complete=a.complete||f,this.context=a.context||this,this.name=a.name;var c=a.from,d=a.to;void 0===c&&(c=m.from),void 0===d&&(d=m.to),this.unit=a.unit||"","number"==typeof c&&"number"==typeof d?(this.begin=c,this.change=d-c):this.format(d,c),this.value=this.begin+this.unit,this.start=J(),a.autoplay!==!1&&this.play()},b.play=function(){this.active||(this.start||(this.start=J()),this.active=!0,c(this))},b.stop=function(){this.active&&(this.active=!1,i(this))},b.render=function(a){var b,c=a-this.start;if(this.delay){if(c<=this.delay)return;c-=this.delay}if(c<this.duration){var d=this.ease(c,0,1,this.duration);return b=this.startRGB?k(this.startRGB,this.endRGB,d):j(this.begin+d*this.change),this.value=b+this.unit,void this.update.call(this.context,this.value)}b=this.endHex||this.begin+this.change,this.value=b+this.unit,this.update.call(this.context,this.value),this.complete.call(this.context),this.destroy()},b.format=function(a,b){if(b+="",a+="","#"==a.charAt(0))return this.startRGB=d(b),this.endRGB=d(a),this.endHex=a,this.begin=0,void(this.change=1);if(!this.unit){var c=b.replace(q,""),e=a.replace(q,"");c!==e&&h("tween",b,a),this.unit=c}b=parseFloat(b),a=parseFloat(a),this.begin=this.value=b,this.change=a-b},b.destroy=function(){this.stop(),this.context=null,this.ease=this.update=this.complete=f};var n=[],o=1e3}),R=k(Q,function(a){a.init=function(a){this.duration=a.duration||0,this.complete=a.complete||f,this.context=a.context,this.play()},a.render=function(a){var b=a-this.start;b<this.duration||(this.complete.call(this.context),this.destroy())}}),S=k(Q,function(a,b){a.init=function(a){this.context=a.context,this.update=a.update,this.tweens=[],this.current=a.current;var b,c;for(b in a.values)c=a.values[b],this.current[b]!==c&&this.tweens.push(new Q({name:b,from:this.current[b],to:c,duration:a.duration,delay:a.delay,ease:a.ease,autoplay:!1}));this.play()},a.render=function(a){var b,c,d=this.tweens.length,e=!1;for(b=d;b--;)c=this.tweens[b],c.context&&(c.render(a),this.current[c.name]=c.value,e=!0);return e?void(this.update&&this.update.call(this.context)):this.destroy()},a.destroy=function(){if(b.destroy.call(this),this.tweens){var a,c=this.tweens.length;for(a=c;a--;)this.tweens[a].destroy();this.tweens=null,this.current=null}}}),T=b.config={defaultUnit:"px",defaultAngle:"deg",keepInherited:!1,hideBackface:!1,perspective:"",fallback:!F.transition,agentTests:[]};
3622b.fallback=function(a){if(!F.transition)return T.fallback=!0;T.agentTests.push("("+a+")");var b=new RegExp(T.agentTests.join("|"),"i");T.fallback=b.test(navigator.userAgent)},b.fallback("6.0.[2-5] Safari"),b.tween=function(a){return new Q(a)},b.delay=function(a,b,c){return new R({complete:b,duration:a,context:c})},a.fn.tram=function(a){return b.call(null,this,a)};var U=a.style,V=a.css,W={transform:F.transform&&F.transform.css},X={color:[N,t],background:[N,t,"background-color"],"outline-color":[N,t],"border-color":[N,t],"border-top-color":[N,t],"border-right-color":[N,t],"border-bottom-color":[N,t],"border-left-color":[N,t],"border-width":[M,u],"border-top-width":[M,u],"border-right-width":[M,u],"border-bottom-width":[M,u],"border-left-width":[M,u],"border-spacing":[M,u],"letter-spacing":[M,u],margin:[M,u],"margin-top":[M,u],"margin-right":[M,u],"margin-bottom":[M,u],"margin-left":[M,u],padding:[M,u],"padding-top":[M,u],"padding-right":[M,u],"padding-bottom":[M,u],"padding-left":[M,u],"outline-width":[M,u],opacity:[M,s],top:[M,v],right:[M,v],bottom:[M,v],left:[M,v],"font-size":[M,v],"text-indent":[M,v],"word-spacing":[M,v],width:[M,v],"min-width":[M,v],"max-width":[M,v],height:[M,v],"min-height":[M,v],"max-height":[M,v],"line-height":[M,x],"scroll-top":[O,s,"scrollTop"],"scroll-left":[O,s,"scrollLeft"]},Y={};F.transform&&(X.transform=[P],Y={x:[v,"translateX"],y:[v,"translateY"],rotate:[w],rotateX:[w],rotateY:[w],scale:[s],scaleX:[s],scaleY:[s],skew:[w],skewX:[w],skewY:[w]}),F.transform&&F.backface&&(Y.z=[v,"translateZ"],Y.rotateZ=[w],Y.scaleZ=[s],Y.perspective=[u]);var Z=/ms/,$=/s|\./,_=function(){var a="warn",b=window.console;return b&&b[a]?function(c){b[a](c)}:f}();return a.tram=b}(window.jQuery); 3623 3624},{}],17:[function(require,module,exports){ 3625'use strict'; 3626 3627/*jshint -W054 */ 3628 3629// Include tram for frame-throttling 3630var $ = window.$; 3631var tram = require('../plugins/tram-min') && $.tram; 3632 3633/*! 3634 * Webflow._ (aka) Underscore.js 1.6.0 (custom build) 3635 * _.each 3636 * _.map 3637 * _.find 3638 * _.filter 3639 * _.any 3640 * _.contains 3641 * _.delay 3642 * _.defer 3643 * _.throttle (webflow) 3644 * _.debounce 3645 * _.keys 3646 * _.has 3647 * _.now 3648 * 3649 * http://underscorejs.org 3650 * (c) 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors 3651 * Underscore may be freely distributed under the MIT license. 3652 * @license MIT 3653 */ 3654module.exports = (function() { 3655 var _ = {}; 3656 3657 // Current version. 3658 _.VERSION = '1.6.0-Webflow'; 3659 3660 // Establish the object that gets returned to break out of a loop iteration. 3661 var breaker = {}; 3662 3663 // Save bytes in the minified (but not gzipped) version: 3664 var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype; 3665 3666 // Create quick reference variables for speed access to core prototypes. 3667 var 3668 push = ArrayProto.push, 3669 slice = ArrayProto.slice, 3670 concat = ArrayProto.concat, 3671 toString = ObjProto.toString, 3672 hasOwnProperty = ObjProto.hasOwnProperty; 3673 3674 // All **ECMAScript 5** native function implementations that we hope to use 3675 // are declared here. 3676 var 3677 nativeForEach = ArrayProto.forEach, 3678 nativeMap = ArrayProto.map, 3679 nativeReduce = ArrayProto.reduce, 3680 nativeReduceRight = ArrayProto.reduceRight, 3681 nativeFilter = ArrayProto.filter, 3682 nativeEvery = ArrayProto.every, 3683 nativeSome = ArrayProto.some, 3684 nativeIndexOf = ArrayProto.indexOf, 3685 nativeLastIndexOf = ArrayProto.lastIndexOf, 3686 nativeIsArray = Array.isArray, 3687 nativeKeys = Object.keys, 3688 nativeBind = FuncProto.bind; 3689 3690 // Collection Functions 3691 // -------------------- 3692 3693 // The cornerstone, an `each` implementation, aka `forEach`. 3694 // Handles objects with the built-in `forEach`, arrays, and raw objects. 3695 // Delegates to **ECMAScript 5**'s native `forEach` if available. 3696 var each = _.each = _.forEach = function(obj, iterator, context) { 3697 /* jshint shadow:true */ 3698 if (obj == null) return obj;
3699 if (nativeForEach && obj.forEach === nativeForEach) { 3700 obj.forEach(iterator, context); 3701 } else if (obj.length === +obj.length) { 3702 for (var i = 0, length = obj.length; i < length; i++) { 3703 if (iterator.call(context, obj[i], i, obj) === breaker) return; 3704 } 3705 } else { 3706 var keys = _.keys(obj); 3707 for (var i = 0, length = keys.length; i < length; i++) { 3708 if (iterator.call(context, obj[keys[i]], keys[i], obj) === breaker) return; 3709 } 3710 } 3711 return obj; 3712 }; 3713 3714 // Return the results of applying the iterator to each element. 3715 // Delegates to **ECMAScript 5**'s native `map` if available. 3716 _.map = _.collect = function(obj, iterator, context) { 3717 var results = []; 3718 if (obj == null) return results; 3719 if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context); 3720 each(obj, function(value, index, list) { 3721 results.push(iterator.call(context, value, index, list)); 3722 }); 3723 return results; 3724 }; 3725 3726 // Return the first value which passes a truth test. Aliased as `detect`. 3727 _.find = _.detect = function(obj, predicate, context) { 3728 var result; 3729 any(obj, function(value, index, list) { 3730 if (predicate.call(context, value, index, list)) { 3731 result = value; 3732 return true; 3733 } 3734 }); 3735 return result; 3736 }; 3737 3738 // Return all the elements that pass a truth test. 3739 // Delegates to **ECMAScript 5**'s native `filter` if available. 3740 // Aliased as `select`. 3741 _.filter = _.select = function(obj, predicate, context) { 3742 var results = []; 3743 if (obj == null) return results; 3744 if (nativeFilter && obj.filter === nativeFilter) return obj.filter(predicate, context); 3745 each(obj, function(value, index, list) { 3746 if (predicate.call(context, value, index, list)) results.push(value); 3747 }); 3748 return results; 3749 }; 3750 3751 // Determine if at least one element in the object matches a truth test. 3752 // Delegates to **ECMAScript 5**'s native `some` if available. 3753 // Aliased as `any`. 3754 var any = _.some = _.any = function(obj, predicate, context) { 3755 predicate || (predicate = _.identity); 3756 var result = false; 3757 if (obj == null) return result; 3758 if (nativeSome && obj.some === nativeSome) return obj.some(predicate, context); 3759 each(obj, function(value, index, list) { 3760 if (result || (result = predicate.call(context, value, index, list))) return breaker; 3761 }); 3762 return !!result; 3763 }; 3764 3765 // Determine if the array or object contains a given value (using `===`). 3766 // Aliased as `include`. 3767 _.contains = _.include = function(obj, target) { 3768 if (obj == null) return false; 3769 if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1; 3770 return any(obj, function(value) { 3771 return value === target; 3772 }); 3773 }; 3774 3775 // Function (ahem) Functions 3776 // -------------------- 3777 3778 // Delays a function for the given number of milliseconds, and then calls 3779 // it with the arguments supplied. 3780 _.delay = function(func, wait) { 3781 var args = slice.call(arguments, 2); 3782 return setTimeout(function(){ return func.apply(null, args); }, wait); 3783 }; 3784 3785 // Defers a function, scheduling it to run after the current call stack has 3786 // cleared. 3787 _.defer = function(func) { 3788 return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1))); 3789 }; 3790 3791 // Returns a function, that, when invoked, will only be triggered once every 3792 // browser animation frame - using tram's requestAnimationFrame polyfill. 3793 _.throttle = function(func) { 3794 var wait, args, context; 3795 return function() { 3796 if (wait) return; 3797 wait = true; 3798 args = arguments; 3799 context = this; 3800 tram.frame(function() { 3801 wait = false; 3802 func.apply(context, args); 3803 }); 3804 }; 3805 }; 3806 3807 // Returns a function, that, as long as it continues to be invoked, will not 3808 // be triggered. The function will be called after it stops being called for 3809 // N milliseconds. If `immediate` is passed, trigger the function on the 3810 // leading edge, instead of the trailing. 3811 _.debounce = function(func, wait, immediate) { 3812 var timeout, args, context, timestamp, result; 3813 3814 var later = function() { 3815 var last = _.now() - timestamp; 3816 if (last < wait) { 3817 timeout = setTimeout(later, wait - last); 3818 } else { 3819 timeout = null; 3820 if (!immediate) {
vendor: 4,768 bytes, lines 3821-3970
3821 result = func.apply(context, args); 3822 context = args = null; 3823 } 3824 } 3825 }; 3826 3827 return function() { 3828 context = this; 3829 args = arguments; 3830 timestamp = _.now(); 3831 var callNow = immediate && !timeout; 3832 if (!timeout) { 3833 timeout = setTimeout(later, wait); 3834 } 3835 if (callNow) { 3836 result = func.apply(context, args); 3837 context = args = null; 3838 } 3839 3840 return result; 3841 }; 3842 }; 3843 3844 // Object Functions 3845 // ---------------- 3846 3847 // Fill in a given object with default properties. 3848 _.defaults = function(obj) { 3849 if (!_.isObject(obj)) return obj; 3850 for (var i = 1, length = arguments.length; i < length; i++) { 3851 var source = arguments[i]; 3852 for (var prop in source) { 3853 if (obj[prop] === void 0) obj[prop] = source[prop]; 3854 } 3855 } 3856 return obj; 3857 }; 3858 3859 // Retrieve the names of an object's properties. 3860 // Delegates to **ECMAScript 5**'s native `Object.keys` 3861 _.keys = function(obj) { 3862 if (!_.isObject(obj)) return []; 3863 if (nativeKeys) return nativeKeys(obj); 3864 var keys = []; 3865 for (var key in obj) if (_.has(obj, key)) keys.push(key); 3866 return keys; 3867 }; 3868 3869 // Shortcut function for checking if an object has a given property directly 3870 // on itself (in other words, not on a prototype). 3871 _.has = function(obj, key) { 3872 return hasOwnProperty.call(obj, key); 3873 }; 3874 3875 // Is a given variable an object? 3876 _.isObject = function(obj) { 3877 return obj === Object(obj); 3878 }; 3879 3880 // Utility Functions 3881 // ----------------- 3882 3883 // A (possibly faster) way to get the current timestamp as an integer. 3884 _.now = Date.now || function() { return new Date().getTime(); }; 3885 3886 // By default, Underscore uses ERB-style template delimiters, change the 3887 // following template settings to use alternative delimiters. 3888 _.templateSettings = { 3889 evaluate : /<%([\s\S]+?)%>/g, 3890 interpolate : /<%=([\s\S]+?)%>/g, 3891 escape : /<%-([\s\S]+?)%>/g 3892 }; 3893 3894 // When customizing `templateSettings`, if you don't want to define an 3895 // interpolation, evaluation or escaping regex, we need one that is 3896 // guaranteed not to match. 3897 var noMatch = /(.)^/; 3898 3899 // Certain characters need to be escaped so that they can be put into a 3900 // string literal. 3901 var escapes = { 3902 "'": "'", 3903 '\\': '\\', 3904 '\r': 'r', 3905 '\n': 'n', 3906 '\u2028': 'u2028', 3907 '\u2029': 'u2029' 3908 }; 3909 3910 var escaper = /\\|'|\r|\n|\u2028|\u2029/g; 3911 3912 var escapeChar = function(match) { 3913 return '\\' + escapes[match]; 3914 }; 3915 3916 // JavaScript micro-templating, similar to John Resig's implementation. 3917 // Underscore templating handles arbitrary delimiters, preserves whitespace, 3918 // and correctly escapes quotes within interpolated code. 3919 // NB: `oldSettings` only exists for backwards compatibility. 3920 _.template = function(text, settings, oldSettings) { 3921 if (!settings && oldSettings) settings = oldSettings; 3922 settings = _.defaults({}, settings, _.templateSettings); 3923 3924 // Combine delimiters into one regular expression via alternation. 3925 var matcher = RegExp([ 3926 (settings.escape || noMatch).source, 3927 (settings.interpolate || noMatch).source, 3928 (settings.evaluate || noMatch).source 3929 ].join('|') + '|$', 'g'); 3930 3931 // Compile the template source, escaping string literals appropriately. 3932 var index = 0; 3933 var source = "__p+='"; 3934 text.replace(matcher, function(match, escape, interpolate, evaluate, offset) { 3935 source += text.slice(index, offset).replace(escaper, escapeChar); 3936 index = offset + match.length; 3937 3938 if (escape) { 3939 source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'"; 3940 } else if (interpolate) { 3941 source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'"; 3942 } else if (evaluate) { 3943 source += "';\n" + evaluate + "\n__p+='"; 3944 } 3945 3946 // Adobe VMs need the match returned to produce the correct offest. 3947 return match; 3948 }); 3949 source += "';\n"; 3950 3951 // If a variable is not specified, place data values in local scope. 3952 if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n'; 3953 3954 source = "var __t,__p='',__j=Array.prototype.join," + 3955 "print=function(){__p+=__j.call(arguments,'');};\n" + 3956 source + 'return __p;\n'; 3957 3958 try { 3959 var render = new Function(settings.variable || 'obj', '_', source); 3960 } catch (e) { 3961 e.source = source; 3962 throw e; 3963 } 3964 3965 var template = function(data) { 3966 return render.call(this, data, _); 3967 }; 3968 3969 // Provide the compiled source as a convenience for precompilation. 3970 var argument = settings.variable || 'obj';
3971 template.source = 'function(' + argument + '){\n' + source + '}'; 3972 3973 return template; 3974 }; 3975 3976 // Export underscore 3977 return _; 3978}()); 3979 3980},{"../plugins/tram-min":16}],18:[function(require,module,exports){ 3981/*! 3982 * jQuery-ajaxTransport-XDomainRequest - v1.0.3 3983 * 2014-12-16 WEBFLOW - Removed UMD wrapper 3984 * https://github.com/MoonScript/jQuery-ajaxTransport-XDomainRequest 3985 * Copyright (c) 2014 Jason Moon (@JSONMOON) 3986 * @license MIT (/blob/master/LICENSE.txt) 3987 */ 3988module.exports=function($){if($.support.cors||!$.ajaxTransport||!window.XDomainRequest){return}var httpRegEx=/^https?:\/\//i;var getOrPostRegEx=/^get|post$/i;var sameSchemeRegEx=new RegExp("^"+location.protocol,"i");$.ajaxTransport("* text html xml json",function(options,userOptions,jqXHR){if(!options.crossDomain||!options.async||!getOrPostRegEx.test(options.type)||!httpRegEx.test(options.url)||!sameSchemeRegEx.test(options.url)){return}var xdr=null;return{send:function(headers,complete){var postData="";var userType=(userOptions.dataType||"").toLowerCase();xdr=new XDomainRequest;if(/^\d+$/.test(userOptions.timeout)){xdr.timeout=userOptions.timeout}xdr.ontimeout=function(){complete(500,"timeout")};xdr.onload=function(){var allResponseHeaders="Content-Length: "+xdr.responseText.length+"\r\nContent-Type: "+xdr.contentType;var status={code:200,message:"success"};var responses={text:xdr.responseText};try{if(userType==="html"||/text\/html/i.test(xdr.contentType)){responses.html=xdr.responseText}else if(userType==="json"||userType!=="text"&&/\/json/i.test(xdr.contentType)){try{responses.json=$.parseJSON(xdr.responseText)}catch(e){status.code=500;status.message="parseerror"}}else if(userType==="xml"||userType!=="text"&&/\/xml/i.test(xdr.contentType)){var doc=new ActiveXObject("Microsoft.XMLDOM");doc.async=false;try{doc.loadXML(xdr.responseText)}catch(e){doc=undefined}if(!doc||!doc.documentElement||doc.getElementsByTagName("parsererror").length){status.code=500;status.message="parseerror";throw"Invalid XML: "+xdr.responseText}responses.xml=doc}}catch(parseMessage){throw parseMessage}finally{complete(status.code,status.message,responses,allResponseHeaders)}};xdr.onprogress=function(){};xdr.onerror=function(){complete(500,"error",{text:xdr.responseText})};if(userOptions.data){postData=$.type(userOptions.data)==="string"?userOptions.data:$.param(userOptions.data)}xdr.open(options.type,options.url);xdr.send(postData)},abort:function(){if(xdr){xdr.abort()}}}})}(window.jQuery); 3989},{}]},{},[1]); 3990/** 3991 * ---------------------------------------------------------------------- 3992 * Webflow: Interactions: Init 3993 */ 3994Webflow.require('ix').init([ 3995 {"slug":"nav-dropdown-toggle","name":"Nav Dropdown Toggle","value":{"style":{},"triggers":[{"type":"hover","selector":".nav-dropdown-list","siblings":true,"stepsA":[{"display":"block"}],"stepsB":[{"display":"none"}]}]}}, 3996 {"slug":"nav-dropdown-list","name":"Nav Dropdown List","value":{"style":{},"triggers":[{"type":"hover","stepsA":[{"display":"block"}],"stepsB":[{"display":"none"}]}]}} 3997]);
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.