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