PageSourceSearch

https://conversationswithtyler.com/assets/js/build/app.js?v=1790238103

js conversationswithtyler.com collected 2026-09-24 08:50:02 UTC 33,329 bytes, 1,137 lines download raw bytes

1'use strict';
2
3/* globals Modernizr app reframe */
4
5// Our namespace
6window.app = app || {};
7app.utilities = {};
8
9app.state = {
10  menuActive: false
11};
12
13app.elements = {
14  body: document.body,
15  hero: document.querySelector('.hero'),
16  header: document.querySelector('.site-header')
17};
18
19app.constants = {
20  mediumBreakpoint: 730,
21  headerHeight: 80 // Sorry, magic number here which we need becuase otherwise we would sometimes need to get the height of the header while it is invisible, which is not a thing.
22};
23
24/*
25 * Browser Unsupported Page
26 * If we are not on the browser unsupported page already, check the site criteria
27 */
28
29if (window.location.pathname !== '/browser-unsupported/') {
30  // Perform the check based on this site’s criteria
31  if (Modernizr && !Modernizr.flexbox) {
32    window.location = '/browser-unsupported/';
33  }
34}
35
36/*
37 * Unified window event tracking method
38 */
39
40(function () {
41  var _checkPos, checkDimension;
42
43  // Utility function for adding different dimensions to the checkPos loop
44  checkDimension = function checkDimension(key, value, evName) {
45    if (app[key] !== value) {
46      app[key] = value;
47
48      if (evName) {
49        // Dispatch a related event
50        var event = new CustomEvent(evName);
51
52        window.dispatchEvent(event);
53      }
54    }
55  };
56
57  // Special method for keeping track of window height and window scroll position. These are frequently-used values within our various components. This RAF method ensures they are always up to date.
58  // If you need to do something that relies on winHeight or winScroll, bind to our custom events, not to the window’s normal scroll or resize events.
59  _checkPos = function checkPos() {
60    checkDimension('winHeight', window.innerHeight, 'cwtHeightChange');
61    checkDimension('winWidth', window.innerWidth, 'cwtWidthChange');
62    checkDimension('winScroll', window.scrollY, 'cwtScrollChange');
63    checkDimension('heroHeight', app.elements.hero.clientHeight, 'cwtHeroHeightChange');
64
65    window.requestAnimationFrame(_checkPos);
66  };
67
68  _checkPos();
69})();
70
71/*
72 * Menu State Tracking
73 */
74
75(function () {
76  window.addEventListener('cwtMenuStateChange', function () {
77    document.querySelector('body').setAttribute('data-site-menu-active', app.state.menuActive);
78  }, false);
79})();
80
81/*
82 * Responsive YouTube Embeds
83 */
84
85(function () {
86  reframe('iframe:not([src*="https://mercatuscenter.formstack.com"])');
87
88  reframe('iframe[src*="https://mercatuscenter.formstack.com"]', 'js-reframe-formstack');
89})();
90
91/*
92 * Manipulate Newsletter form to get the original styles
93 */
94
95var styleNewsletterForm = function styleNewsletterForm() {
96  var destination = document.querySelector('.fa-subscribe-form .wpforms-field-email'),
97    border = document.querySelector('.border-below-email-field'),
98    borderCopy = border.cloneNode(true);
99
100  borderCopy.classList.add('visible');
101
102  if (destination) {
103    destination.appendChild(borderCopy);
104  }
105};
106
107(function () {
108  styleNewsletterForm();
109})();
110'use strict';
111
112(function () {
113  var animatorInstances = [],
114    Animator;
115
116  // Class Definition
117  Animator = function Animator(element) {
118    var _this = this;
119
120    this.element = element;
121    this.settings = JSON.parse(this.element.dataset.animator);
122
123    this.handleResize();
124    this.handleScroll();
125
126    window.addEventListener('cwtHeightChange', function () {
127      _this.handleResize();
128      _this.handleScroll();
129    });
130
131    window.addEventListener('cwtWidthChange', function () {
132      _this.handleResize();
133      _this.handleScroll();
134    });
135
136    window.addEventListener('cwtScrollChange', function () {
137      _this.handleScroll();
138    });
139  };
140
141  Animator.prototype.handleResize = function () {
142    var rangeStart = window.app.winHeight * this.settings.range[0],
143      rangeFinish = window.app.winHeight * this.settings.range[1];
144
145    this.rangeValue = rangeFinish - rangeStart;
146  };
147
148  Animator.prototype.handleScroll = function () {
149    var elDiff = window.app.winHeight - this.element.getBoundingClientRect().top,
150      progress = Math.max(Math.min(elDiff / this.rangeValue, 1), 0); // outputs percentage as fraction of 1
151
152    this.updateOpacity(progress);
153    this.updateTransform(progress);
154  };
155
156  Animator.prototype.updateOpacity = function (progress) {
157    if (this.settings.opacity) {
158      var start = this.settings.opacity[0],
159        finish = this.settings.opacity[1],
160        value = start + (finish - start) * progress;
161
162      this.element.style.opacity = value;
163    }
164  };
165
166  Animator.prototype.updateTransform = function (progress) {
167    if (this.settings.transform) {
168      var start = parseInt(this.settings.transform[0].translateY, 10),
169        finish = parseInt(this.settings.transform[1].translateY, 10),
170        value = start + (finish - start) * progress;
171
172      this.element.style.transform = 'translateY(' + value + 'px)'; // Note that this will nuke any other transforms on the element. Beware.
173    }
174  };
175
176  // Instantiation
177  var elements = document.querySelectorAll('[data-animator]'); // eslint-disable-line one-var
178
179  for (var i = 0; i < elements.length; i++) {
180    animatorInstances[i] = new Animator(elements[i]);
181  }
182})();
183'use strict';
184
185(function () {
186  var suppressedElements = [];
187
188  document.addEventListener('mousedown', function (ev) {
189    var target = ev.target.closest('a, button, input, select');
190
191    if (target) {
192      target.style.outline = 'none';
193      suppressedElements.push(target);
194    }
195  });
196
197  document.addEventListener('keydown', function () {
198    for (var i = 0; i < suppressedElements.length; i++) {
199      suppressedElements[i].style.outline = null;
200    }
201  });
202})();
203'use strict';
204
205/* globals app TweenLite */
206
207(function () {
208  var animationDuration = 0.5,
209    body = document.getElementsByTagName('body')[0];
210
211  // Define some utilities
212  app.utilities.scrolling = {
213
214    // Scroll to a given hash by id
215    scrollToHash: function scrollToHash(hash, success) {
216      var el = document.getElementById(hash.slice(1));
217
218      if (el) {
219        var gap = Math.max(0, el.offsetTop - document.documentElement.scrollHeight + window.innerHeight); // At the furthest possible scroll position, what is the distance between this element’s top edge and the viewport top edge? Round negatives down to 0.
220
221        TweenLite.to(window, animationDuration, {
222          scrollTo: {
223            y: hash, // Includes the hash mark
224            offsetY: app.elements.header.clientHeight - gap, // Most of the time we want the offset to be the header height, but sometimes we want to account for the gap in how far the window can actually scroll to expose this element. If there is such a gap, use less offset so that the header still ends up aligned.
225            autoKill: false
226          },
227          onComplete: success
228        });
229      }
230    }
231  };
232
233  // On window load (i.e. all resources have loaded), if there is a hash in the URL,
234  // scroll to it with animation instead of simply allowing the browser "jump"
235  // additionally, if there is a data-scrollto attribute on body, override any hash and scroll there instead
236  if (window.location.hash || body.getAttribute('data-scrollto')) {
237    // Immediately reset the scroll position to counteract any automatic hash-based scrolling the browser is trying to do
238    setTimeout(function () {
239      window.scrollTo(0, 0);
240    }, 1);
241
242    window.addEventListener('load', function () {
243      setTimeout(function () {
244        app.utilities.scrolling.scrollToHash(body.getAttribute('data-scrollto') || window.location.hash);
245      }, 1); // Timeout solves layout delay issue in iOS: https://gist.github.com/mataspetrikas/431639
246    });
247  }
248
249  // Bind to scroll link triggers on this specific page.
250  document.addEventListener('click', function (ev) {
251    var link = ev.target.closest('a');
252
253    if (link) {
254      var location = app.utilities.strings.getLocationObject(link.href);
255
256      if (location.hash && location.pathname === window.location.pathname) {
257        app.utilities.scrolling.scrollToHash(location.hash);
258
259        ev.preventDefault();
260      }
261    }
262  });
263})();
264'use strict';
265
266/* globals app */
267
268// # String Manipulation functions
269// -------------------------------
270// Handy for moving keys from language to langage
271// Could even extend the string prototype if you wanted
272
273// _Restrict Scope_
274(function () {
275  app.utilities.strings = {
276    getLocationObject: function getLocationObject(url) {
277      var a = document.createElement('a');
278
279      a.href = url;
280
281      return {
282        href: a.href,
283        host: a.host,
284        hostname: a.hostname,
285        port: a.port,
286        pathname: a.pathname,
287        protocol: a.protocol,
288        hash: a.hash,
289        search: a.search
290      };
291    },
292    isInternalUrl: function isInternalUrl(url) {
293      var location = app.utilities.strings.getLocationObject(url);
294
295      return window.location.host === location.host;
296    },
297    getRelativeURL: function getRelativeURL(url) {
298      var location = app.utilities.strings.getLocationObject(url);
299
300      return location.pathname + location.search + location.hash;
301    },
302
303
304    /*
305     * Capitalize First Letter of String
306     * Ex. this-string => This-string
307     */
308
309    capitalizeFirstLetter: function capitalizeFirstLetter(string) {
310      return string.charAt(0).toUpperCase() + string.slice(1);
311    },
312
313
314    /*
315     * Convert dashed string to camel case string
316     * Ex. this-string => thisString
317     */
318
319    dashesToCamelCase: function dashesToCamelCase(string) {
320      return string.replace(/-([a-z])/g, function (g) {
321        return g[1].toUpperCase();
322      });
323    },
324
325
326    /*
327     * Convert dashed string to a capitalized method name for our JS
328     * Ex. this-string => ThisString
329     */
330
331    dashesToMethodName: function dashesToMethodName(string) {
332      return app.utilities.strings.capitalizeFirstLetter(app.utilities.strings.dashesToCamelCase(string));
333    },
334
335
336    /*
337     * Convert underscored string to camel case
338     * Ex. this_string => thisString
339     */
340
341    underscoreToCamelCase: function underscoreToCamelCase(string) {
342      return string.replace(/_([a-z])/g, function (g) {
343        return g[1].toUpperCase();
344      });
345    },
346
347
348    /*
349     * Convert dashed string to a capitalized method name for our JS
350     * Ex. this_string => ThisString
351     */
352
353    underscoreToMethodName: function underscoreToMethodName(string) {
354      return app.utilities.strings.capitalizeFirstLetter(app.utilities.strings.underscoreToCamelCase(string));
355    }
356  };
357})();
358'use strict';
359
360/* global dataLayer */
361
362(function () {
363  var domain = document.domain.split('.').reverse()[1] + '.' + document.domain.split('.').reverse()[0];
364
365  function success(url, target) {
366    if (target) {
367      window.open(url, target);
368    } else {
369      window.location.href = url;
370    }
371  }
372
373  function handleOutboundLink(url, id, target) {
374    var successful = void 0;
375
376    // Log event to Analytics, once done, go to the link
377
378    dataLayer.push({
379      event: 'User Event',
380      action: id,
381      category: 'outbound-link-click',
382      label: url,
383      eventCallback: function eventCallback() {
384        success(url, target);
385        successful = true;
386      }
387    });
388
389    // Set backup timeout in case it doesn’t work
390    setTimeout(function () {
391      !successful && success(url, target);
392    }, 500);
393  }
394
395  // Add event listener
396  document.addEventListener('click', function (ev) {
397    var link = ev.target.closest('a');
398
399    if (link) {
400      var url = link.getAttribute('href'),
401        id = link.getAttribute('data-click-id'),
402        target = link.getAttribute('target'),
403        myDomain = url.match(domain); // Query the href for the top level domain (xxxxx.com)
404
405      // If link is outbound
406      if (url.indexOf('http') === 0 && // Relative links can't be outbound
407        url.match(/^(https?:|\/\/)/i) && !myDomain // Only absolute links that aren't our domain
408        || url.match(/^mailto/i)) {
409        ev.preventDefault();
410        handleOutboundLink(url, id, target);
411      }
412    }
413  });
414})();
415'use strict';
416
417/* global dataLayer */
418
419// Form handling
420// Includes event tracking and bare-bones form validation
421// Only accounts for presence/absence of required fields.
422// Further validation occurs at the browser level, and in Pardot if all else fails.
423
424(function () {
425  var forms = document.getElementsByTagName('form:not("fsForm")'),
426    i;
427
428  var _loop = function _loop() {
429    var form = forms[i];
430
431    validate(form);
432    sendSuccessOrFailureEvent(form);
433
434    form.addEventListener('keyup', function () {
435      validate(form);
436    });
437
438    form.addEventListener('submit', function (ev) {
439      handleSubmission(ev, form);
440    });
441  };
442
443  for (i = 0; i < forms.length; i++) {
444    _loop();
445  }
446
447  // Callback to run on form submit
448  function handleSubmission(ev, form) {
449    ev.preventDefault();
450
451    fixURL();
452
453    dataLayer.push({
454      event: 'User Event',
455      action: 'submission',
456      category: 'forms',
457      label: form.id,
458      eventCallback: function eventCallback() {
459        form.submit();
460      }
461    });
462
463    // Set a timeout to submit just in case the above fails
464    setTimeout(function () {
465      form.submit();
466    }, 500);
467  }
468
469  // Pardot doesn't clear the form errors out of the URL properly on submit, so we do that here
470  function fixURL() {
471    var url = [location.protocol, '//', location.host, location.pathname].join('');
472
473    window.history.replaceState({}, '', url);
474  }
475
476  function sendSuccessOrFailureEvent(form) {
477    // If there is a form alert, that means we should issue a success or failure event. Track which one it is and send the appropriate response
478    if (form.dataset.alert) {
479      dataLayer.push({
480        event: 'User Event',
481        action: form.dataset.alert === 'success' ? 'success' : 'failure',
482        category: 'forms',
483        label: form.id
484      });
485    }
486  }
487
488  // Validation Utilities
489  function validate(form) {
490    var button = form.getElementsByTagName('button')[0],
491      isValid = isFormValid(form);
492
493    form.dataset.isValid = isValid;
494    button.disabled = !isValid;
495  }
496
497  function isFormValid(form) {
498    var valid = true,
499      inputs = form.getElementsByTagName('input'),
500      i;
501
502    for (i = 0; i < inputs.length; i++) {
503      if (inputs[i].required && !inputs[i].value) {
504        // If the input has a validitystate (meaning it is reqiured)
505        valid = false;
506      }
507    }
508
509    return valid;
510  }
511})();
512'use strict';
513
514/* global dataLayer */
515
516(function () {
517  var currentlyPlaying = undefined;
518
519  document.addEventListener('click', function (ev) {
520    var clickedButton = ev.target.closest('.card__audio-button'),
521      clickedCard = ev.target.closest('.card');
522
523    if (clickedButton) {
524      if (!clickedCard.getAttribute('state-audio-playing')) {
525        currentlyPlaying && pauseCard(currentlyPlaying);
526        playCard(clickedCard);
527
528        currentlyPlaying = clickedCard;
529      } else {
530        pauseCard(clickedCard);
531
532        currentlyPlaying = undefined;
533      }
534    } else if (clickedCard) {
535      var ctas = clickedCard.getElementsByClassName('card__cta'),
536        target = undefined;
537
538      for (var i = 0; i < ctas.length; i++) {
539        var displayValue = window.getComputedStyle(ctas[i].closest('span')).getPropertyValue('display');
540
541        if (displayValue !== 'none') {
542          target = ctas[i].href;
543        }
544      }
545
546      window.location = target;
547    }
548  });
549
550  function playCard(card) {
551    if (!card.audio) {
552      card.audio = new Audio(card.dataset.audio);
553    }
554
555    card.audio.play();
556    card.setAttribute('state-audio-playing', true);
557
558    dataLayer.push({
559      event: 'User Event',
560      action: 'play',
561      category: 'card-audio',
562      label: card.getElementsByTagName('h3')[0].textContent
563    });
564  }
565
566  function pauseCard(card) {
567    card.audio.pause();
568    card.removeAttribute('state-audio-playing');
569
570    dataLayer.push({
571      event: 'User Event',
572      action: 'pause',
573      category: 'card-audio',
574      label: card.getElementsByTagName('h3')[0].textContent
575    });
576  }
577})();
578'use strict';
579
580/* globals app */
581
582(function () {
583  var el = document.getElementsByClassName('site-menu-trigger')[0];
584
585  el.addEventListener('click', function () {
586    app.state.menuActive = !app.state.menuActive;
587
588    // Create a new event
589    var event = new CustomEvent('cwtMenuStateChange');
590
591    // Dispatch the event
592    window.dispatchEvent(event);
593  });
594
595  // We also want to be able to close the menu conditionally for some things
596  var closeButtons = document.querySelectorAll('[data-close-menu="1"]');
597
598  // If we have any close buttons
599  if (closeButtons.length) {
600
601    // iterate over the and add close functionality.
602    Array.from(closeButtons).map(function (v) {
603      v.addEventListener('click', function () {
604        app.state.menuActive = false;
605
606        // Create a new event
607        var event = new CustomEvent('cwtMenuStateChange');
608
609        // Dispatch the event
610        window.dispatchEvent(event);
611      });
612    });
613  }
614})();
615// (function() {
616//   var textBlockLinks = document.querySelectorAll('.text-block a[href^="mailto:"]');
617//
618//   textBlockLinks.forEach((link) => {
619//     var newLinkContent = `
620//       <main>${link.text}</main>
621//       <div class="secondary-cta__border" style="background-color: #9b26b6" role="presentation"></div>`;
622//
623//     link.classList.add('secondary-cta');
624//     link.innerHTML = newLinkContent;
625//   });
626//
627// })();
628"use strict";
629'use strict';
630
631/* globals TimelineLite app Power1 dataLayer */
632
633(function () {
634  var animationDuration = 0.3;
635
636  var el = document.querySelectorAll('.easter-egg'),
637    index = 0,
638    // Current easter egg index
639    closeButton,
640    backgroundSource,
641    backgroundImage,
642    video,
643    triggers,
644    progressLabel,
645    progressBar,
646    timeline = new TimelineLite();
647
648  /*
649   * Define functions
650   */
651
652  // Checker which looks at all the triggers to see which should be active
653  function updateTriggers() {
654    for (var i = 0; i < triggers.length; i++) {
655      triggers[i].dataset.available = i === index ? 'true' : 'false';
656      triggers[i].dataset.completed = i < index ? 'true' : 'false';
657    }
658  }
659
660  function showProgress() {
661    var currentIndex = index,
662      // Stash this so that we can use the current index inside the callback, not the future index.
663      progressPct = index / triggers.length;
664
665    // Kill any active animations
666    timeline.progress(1).kill();
667
668    // Bind the scroll cancelation event
669    bindCancelation();
670
671    // Set the right copy
672    progressLabel.innerHTML = triggers[index - 1].dataset.label; // The 0th label is for the 1th index, so subtract one
673
674    // Set a body attribute so that all views can react to the fact that the easter egg is showing
675    app.elements.body.dataset.showingEasterEggProgress = 'true';
676
677    // Run the animations
678    timeline.fromTo(progressBar, animationDuration * 6, {
679      opacity: 0,
680      width: (progressPct - 1 / triggers.length) * 100 + '%' // Prior trigger percentage width
681    }, {
682      opacity: 1,
683      ease: Power1.easeOut,
684      width: progressPct * 100 + '%'
685    }).fromTo(progressLabel, animationDuration, {
686      opacity: 0
687    }, {
688      opacity: 1,
689      onComplete: function onComplete() {
690        // Load the background image if we are at the n-1th trigger
691        if (currentIndex === triggers.length - 1) {
692          loadBackground();
693        }
694
695        // Run the success message if we are at the end
696        if (currentIndex === triggers.length) {
697          showReward();
698        }
699      }
700    }, '-=' + animationDuration * 4).to('.hero__easter-egg-progress', animationDuration, {
701      opacity: 0,
702      clearProps: 'all',
703      onComplete: function onComplete() {
704        // Remove the special body attribute
705        delete app.elements.body.dataset.showingEasterEggProgress;
706
707        // Unbind the backup scroll bind
708        unbindCancelation();
709      }
710    }, '+=' + animationDuration * 4);
711  }
712
713  // When the user scrolls while we are showing the progress bar, we want to check to see if we need to cancel the progress message.
714  function bindCancelation() {
715    document.addEventListener('scroll', cancelMessage);
716  }
717
718  function unbindCancelation() {
719    document.removeEventListener('scroll', cancelMessage);
720  }
721
722  function cancelMessage() {
723    if (!app.elements.hero.getAttribute('data-is-fixed')) {
724      timeline.progress(1).kill();
725    }
726  }
727
728  function loadBackground() {
729    for (var i = 0; i < backgroundSource.length; i++) {
730      backgroundSource[i].srcset = backgroundSource[i].dataset.srcset;
731
732      delete backgroundSource[i].dataset.srcset;
733    }
734
735    backgroundImage.src = backgroundImage.dataset.src;
736
737    delete backgroundImage.dataset.src;
738  }
739
740  function showReward() {
741    app.elements.body.dataset.showingEasterEgg = true;
742
743    timeline.fromTo('.easter-egg', animationDuration * 2, {
744      opacity: 0,
745      y: -32
746    }, {
747      opacity: 1,
748      y: 0
749    }).fromTo(video, animationDuration * 4, {
750      opacity: 0
751    }, {
752      opacity: 1,
753      onComplete: function onComplete() {
754        video.play();
755      }
756    }, '-=' + animationDuration * 2).fromTo('.easter-egg article', animationDuration * 4, {
757      opacity: 0
758    }, {
759      opacity: 1
760    }, '-=' + animationDuration * 2).fromTo('.easter-egg__tray', animationDuration * 4, {
761      opacity: 0
762    }, {
763      opacity: 1
764    }, '-=' + animationDuration * 2);
765  }
766
767  function hideReward() {
768    timeline.progress(1).kill().to('.easter-egg', animationDuration * 2, {
769      opacity: 0,
770      y: -32,
771      onComplete: function onComplete() {
772        video.pause();
773
774        delete app.elements.body.dataset.showingEasterEgg;
775      }
776    });
777  }
778
779  /*
780   * If the element exists, run all the stuff
781   */
782
783  if (el.length) {
784    closeButton = document.querySelectorAll('.easter-egg__close')[0];
785    backgroundSource = document.querySelectorAll('.easter-egg__bg source')[0];
786    backgroundImage = document.querySelectorAll('.easter-egg__bg img')[0];
787    video = document.querySelectorAll('.easter-egg video')[0];
788    triggers = document.getElementsByClassName('easter-egg-trigger');
789    progressLabel = document.querySelectorAll('.hero__easter-egg-progress label')[0];
790    progressBar = document.querySelectorAll('.hero__easter-egg-progress data')[0];
791
792    // Run an initial check
793    updateTriggers();
794
795    // Event listener for clicks on the triggers
796    document.addEventListener('click', function (ev) {
797      var trigger = ev.target.closest('.easter-egg-trigger');
798
799      if (trigger) {
800        if (trigger.dataset.available === 'true') {
801          // Remember that these are always strings
802          index++;
803
804          updateTriggers();
805
806          // If the hero is not docked, scroll down to make that happen
807          if (!app.elements.hero.getAttribute('data-is-fixed')) {
808            app.utilities.scrolling.scrollToHash('#main', showProgress);
809          } else {
810            showProgress();
811          }
812
813          dataLayer.push({
814            event: 'User Event',
815            action: 'trigger-click',
816            category: 'easter-egg',
817            label: trigger.textContent
818          });
819        }
820      }
821    });
822
823    closeButton.addEventListener('click', hideReward, true);
824
825    window.addEventListener('keyup', function (ev) {
826      if (ev.keyCode === 27 && app.elements.body.dataset.showingEasterEgg) {
827        hideReward();
828      }
829    });
830  }
831})();
832'use strict';
833
834/* globals TweenLite app */
835
836(function () {
837  var dampener = 0.5,
838    bgs = document.getElementsByClassName('geo__bg'),
839    squares = document.getElementsByClassName('geo__bg--squares'),
840    triangles = document.getElementsByClassName('geo__bg--triangles'),
841    circles = document.getElementsByClassName('geo__bg--circles');
842
843  var lastScrollDepth,
844    bodyHeight = app.elements.body.clientHeight;
845
846  function checkLocation() {
847    if (window.innerWidth > app.constants.mediumBreakpoint) {
848      var scrollDepthRaw = (app.winScroll + app.winHeight / 2) / bodyHeight - 0.5,
849        scrollDepth = Math.floor(scrollDepthRaw * dampener * 1000) / 1000; // Restrict to 3 significant digits
850
851      if (scrollDepth !== lastScrollDepth) {
852        lastScrollDepth = scrollDepth;
853
854        setLocation();
855      }
856    }
857  }
858
859  function setLocation() {
860    var scale = 1 + lastScrollDepth;
861
862    TweenLite.set(squares, {
863      rotation: lastScrollDepth * 100,
864      scale: scale
865    });
866
867    TweenLite.set(triangles, {
868      rotation: lastScrollDepth * -100,
869      scale: scale
870    });
871
872    TweenLite.set(circles, {
873      scale: scale
874    });
875  }
876
877  // Run and Bind
878  checkLocation();
879
880  window.addEventListener('cwtHeightChange', checkLocation);
881  window.addEventListener('cwtScrollChange', checkLocation);
882
883  // Perform a cross-browser set for transform origin and shape centering. This creates the right position but is resistant to window resize, unlike if we do this in CSS.
884  TweenLite.set(bgs, {
885    x: '-50%',
886    y: '-50%',
887    transformOrigin: '50% 50%'
888  });
889})();
890'use strict';
891
892/* globals app */
893
894(function () {
895  // Pull any potentially-needed elements into vars, so we never have to fetch them during a rAF
896  var shade = app.elements.hero.getElementsByClassName('hero__shade')[0];
897
898  var isFixed;
899
900  // Position setter function which writes to DOM and creates tweens when checker decides it’s time
901  // Be careful not to have any DOM queries or checks in here. This has to run in 16ms. It is just a setter.
902  function setPos() {
903    if (app.winScroll >= app.heroHeight - app.constants.headerHeight) {
904      // If the user has scrolled far enough that the visible pixel height of the hero is equal to the header height, make the hero stick in place using a transform, so that it can act as a background for the header.
905      // If the hero has not already been marked as fixed...
906      !isFixed && setFixed();
907    } else {
908      // If the hero should be in its normal position and the hero was previously fixed
909      isFixed && setStatic();
910
911      // Whether or not the header was previously fixed, set the shade to the right height given the current hero position on screen
912      shade.style.height = Math.max(app.heroHeight - app.winScroll, app.c
912onstants.headerHeight) + 'px';
913    }
914  }
915
916  // Utility to set the hero as 'fixed' when appropriate
917  function setFixed() {
918    isFixed = true;
919    app.elements.hero.setAttribute('data-is-fixed', 'true');
920
921    shade.style.height = app.constants.headerHeight;
922  }
923
924  // Utility function to set the hero as static when appropriate.
925  function setStatic() {
926    isFixed = false;
927    app.elements.hero.removeAttribute('data-is-fixed');
928  }
929
930  if (app.elements.hero.getAttribute('data-fixed') !== 'true') {
931    // Kick off the main positioning loop, tying into the global scroll handler
932    setPos();
933    window.addEventListener('cwtScrollChange', setPos);
934    window.addEventListener('cwtWidthChange', setPos);
935    window.addEventListener('cwtHeroHeightChange', setPos);
936
937    // Set a flag after the first time this runs so we know any subsequent runs are changes
938    app.elements.hero.dataset.isLoaded = true;
939  }
940})();
941'use strict';
942
943/* global app */
944
945(function () {
946  var heroBg = document.getElementsByClassName('hero__bg')[0],
947    body = document.querySelector('body');
948
949  // Hero height management
950  // Continually match the BG image height to the main area’s height. Can’t be done in CSS becuase the BG is not inside the normal hero container.
951  function setHeroHeight() {
952    heroBg.style.height = app.heroHeight + 'px';
953  }
954
955  if (['episode', 'archive-episode'].indexOf(body.getAttribute('data-template')) === -1) {
956    setHeroHeight();
957    window.addEventListener('cwtHeroHeightChange', setHeroHeight);
958  }
959})();
960'use strict';
961
962/* globals app TimelineLite Modernizr */
963
964(function () {
965  var isVideoFaded,
966    timeline = new TimelineLite(),
967    logoVideo = document.getElementsByClassName('hero__logo--video')[0],
968    logoImage = document.getElementsByClassName('hero__logo--image')[0],
969    animationDuration = 2;
970
971  // If the conditions are met, run the animtion
972  if (document.getElementsByTagName('body')[0].dataset.template === 'home' && app.isFirstLoad) {
973    handleAnimation();
974
975    if (Modernizr.backgroundblendmode && window.innerWidth >= app.constants.mediumBreakpoint) {
976      handleLogo();
977    } else {
978      logoImage.setAttribute('data-showing', true);
979      logoVideo.remove();
980    }
981  }
982
983  function handleAnimation() {
984    var timeline = new TimelineLite();
985
986    // Run primary animation
987    timeline.to('.hero__image', 1, {
988      opacity: 1
989    }, 0.25).to('.hero__title', 1, {
990      opacity: 1
991    }, 0.5).to('.hero__blurb', 1, {
992      opacity: 1
993    }, 1).to('.hero .primary-cta', 1, {
994      opacity: 1
995    }, 1).fromTo('.hero__alert', 1, {
996      opacity: 0,
997      y: '-40px'
998    }, {
999      opacity: 1,
1000      y: 0
1001    }, 1.75).fromTo('.hero__tray', 1, {
1002      opacity: 0,
1003      y: '40px'
1004    }, {
1005      opacity: 1,
1006      y: 0
1007    }, 1.75);
1008  }
1009
1010  // Very Magic-numbery logic to seamlessly transition between the moving video file and the logo SVG
1011  function handleLogo() {
1012    // Add the video logo source based on the screen size
1013    if (window.innerWidth >= window.app.constants.mediumBreakpoint && window.devicePixelRatio > 1) {
1014      logoVideo.innerHTML = '<source src="https://cwtstg.wpengine.com/wp-content/uploads/required/logo--retina.mp4" height="210" width="420" type="video/mp4">';
1015    } else if (window.innerWidth < window.app.constants.mediumBreakpoint && window.devicePixelRatio <= 1) {
1016      logoVideo.innerHTML = '<source src="https://cwtstg.wpengine.com/wp-content/uploads/required/logo--small.mp4" height="53" width="106" type="video/mp4">';
1017    } else {
1018      logoVideo.innerHTML = '<source src="https://cwtstg.wpengine.com/wp-content/uploads/required/logo.mp4" height="105" width="210" type="video/mp4">';
1019    }
1020
1021    // When the video has run, fade it out and fade in the solid logo (which looks nicer on most screens)
1022    logoVideo.addEventListener('ended', removeVideo);
1023
1024    // Or, if the user scrolls past the logo, remove the video right away
1025    window.addEventListener('cwtScrollChange', function () {
1026      removeVideo(false);
1027    });
1028  }
1029
1030  function removeVideo() {
1031    var animate = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
1032
1033    if (!isVideoFaded) {
1034      // Once the video has ended, animate it out and animate the static logo in.
1035      logoImage.setAttribute('data-showing', true);
1036
1037      timeline.fromTo(logoImage, animate ? animationDuration : 0, {
1038        opacity: 0
1039      }, {
1040        opacity: 1
1041      });
1042
1043      timeline.to(logoVideo, animate ? animationDuration : 0, {
1044        opacity: 0,
1045        onComplete: function onComplete() {
1046          logoVideo.remove();
1047        }
1048      }, '-=0.1');
1049    }
1050
1051    isVideoFaded = true;
1052  }
1053})();
1054'use strict';
1055
1056/* globals app */
1057
1058(function () {
1059  var el = document.getElementsByClassName('site-header')[0],
1060    topOffset = el.offsetTop; // Usually will be 0, but if there is a site alert, it will be non-zero.
1061
1062  // Create an instance variable that tracks the last Y position so that we can continually check against it
1063  var isFaded, elBelowTop, elBelowBottom;
1064
1065  function setPos() {
1066    var belowTop = app.winScroll > topOffset,
1067      belowBottom = app.winScroll >= app.heroHeight - app.constants.headerHeight;
1068
1069    // Set some state attributes so that CSS can react to the various situations
1070    if (elBelowTop !== belowTop) {
1071      el.setAttribute('data-below-top', belowTop);
1072      elBelowTop = belowTop; // Remember this to trigger future DOM attribute reads/writes only when necessary
1073    }
1074
1075    if (elBelowBottom !== belowBottom) {
1076      el.setAttribute('data-below-bottom', belowBottom);
1077      elBelowBottom = belowBottom; // Remember this to trigger future DOM attribute reads/writes only when necessary
1078    }
1079
1080    if (belowTop && !belowBottom && !isFaded) {
1081      // We are within the area in which the main element should disappear
1082      el.setAttribute('data-is-faded', true);
1083      isFaded = true;
1084    } else if ((!belowTop || belowBottom) && isFaded) {
1085      el.setAttribute('data-is-faded', false);
1086      isFaded = false;
1087    }
1088  }
1089
1090  setPos();
1091  window.addEventListener('cwtScrollChange', setPos);
1092  window.addEventListener('cwtWidthChange', setPos);
1093  window.addEventListener('cwtHeroHeightChange', setPos);
1094})();
1095'use strict';
1096
1097/* globals */
1098
1099(function () {
1100  var el = document.getElementsByClassName('tab-nav')[0];
1101  var state = false,
1102    pos;
1103
1104  if (document.getElementsByClassName('tab-nav').length) {
1105    pos = offset(el, 200);
1106    checkPos();
1107    window.addEventListener('cwtScrollChange', checkPos);
1108    window.addEventListener('resize', function () {
1109      this.clearTimeout(t);
1110      var t = setTimeout(function () {
1111        el.setAttribute('data-fixed', false);
1112        state = false;
1113        pos = offset(el, 200);
1114        checkPos();
1115      }, 200);
1116    });
1117  }
1118
1119  function offset(el, extra) {
1120    var rect = el.getBoundingClientRect(),
1121      scrollTop = window.pageYOffset || document.documentElement.scrollTop;
1122
1123    extra = extra || 60;
1124
1125    return rect.top + scrollTop - extra;
1126  }
1127
1128  function checkPos() {
1129    if (window.scrollY > pos && state === false) {
1130      state = true;
1131      el.setAttribute('data-fixed', true);
1132    } else if (window.scrollY <= pos && state === true) {
1133      state = false;
1134      el.setAttribute('data-fixed', false);
1135    }
1136  }
1137})();

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.