/* Minification failed. Returning unminified contents. (1855,15-16): run-time error JS1010: Expected identifier: . (1855,15-16): run-time error JS1195: Expected expression: . (2604,19-20): run-time error JS1010: Expected identifier: . (2604,19-20): run-time error JS1195: Expected expression: . (5125,13-14): run-time error JS1010: Expected identifier: . (5125,13-14): run-time error JS1195: Expected expression: . */ (function () { 'use strict'; /*! LAB.js (LABjs :: Loading And Blocking JavaScript) v2.0.3 (c) Kyle Simpson MIT License */ (function (o) { var K = o.$LAB, y = "UseLocalXHR", z = "AlwaysPreserveOrder", u = "AllowDuplicates", A = "CacheBust", B = "BasePath", C = /^[^?#]*\//.exec(location.href)[0], D = /^\w+\:\/\/\/?[^\/]+/.exec(C)[0], i = document.head || document.getElementsByTagName("head"), L = o.opera && Object.prototype.toString.call(o.opera) == "[object Opera]" || "MozAppearance" in document.documentElement.style, q = document.createElement("script"), E = typeof q.preload == "boolean", r = E || q.readyState && q.readyState == "uninitialized", F = !r && q.async === true, M = !r && !F && !L;function G(a) { return Object.prototype.toString.call(a) == "[object Function]"; }function H(a) { return Object.prototype.toString.call(a) == "[object Array]"; }function N(a, c) { var b = /^\w+\:\/\//;if (/^\/\/\/?/.test(a)) { a = location.protocol + a; } else if (!b.test(a) && a.charAt(0) != "/") { a = (c || "") + a; }return b.test(a) ? a : (a.charAt(0) == "/" ? D : C) + a; }function s(a, c) { for (var b in a) { if (a.hasOwnProperty(b)) { c[b] = a[b]; } }return c; }function O(a) { var c = false;for (var b = 0; b < a.scripts.length; b++) { if (a.scripts[b].ready && a.scripts[b].exec_trigger) { c = true;a.scripts[b].exec_trigger();a.scripts[b].exec_trigger = null; } }return c; }function t(a, c, b, d) { a.onload = a.onreadystatechange = function () { if (a.readyState && a.readyState != "complete" && a.readyState != "loaded" || c[b]) return;a.onload = a.onreadystatechange = null;d(); }; }function I(a) { a.ready = a.finished = true;for (var c = 0; c < a.finished_listeners.length; c++) { a.finished_listeners[c](); }a.ready_listeners = [];a.finished_listeners = []; }function P(d, f, e, g, h) { setTimeout(function () { var a, c = f.real_src, b;if ("item" in i) { if (!i[0]) { setTimeout(arguments.callee, 25);return; }i = i[0]; }a = document.createElement("script");if (f.type) a.type = f.type;if (f.charset) a.charset = f.charset;if (h) { if (r) { e.elem = a;if (E) { a.preload = true;a.onpreload = g; } else { a.onreadystatechange = function () { if (a.readyState == "loaded") g(); }; }a.src = c; } else if (h && c.indexOf(D) == 0 && d[y]) { b = new XMLHttpRequest();b.onreadystatechange = function () { if (b.readyState == 4) { b.onreadystatechange = function () {};e.text = b.responseText + "\n//@ sourceURL=" + c;g(); } };b.open("GET", c);b.send(); } else { a.type = "text/cache-script";t(a, e, "ready", function () { i.removeChild(a);g(); });a.src = c;i.insertBefore(a, i.firstChild); } } else if (F) { a.async = false;t(a, e, "finished", g);a.src = c;i.insertBefore(a, i.firstChild); } else { t(a, e, "finished", g);a.src = c;i.insertBefore(a, i.firstChild); } }, 0); }function J() { var l = {}, Q = r || M, n = [], p = {}, m;l[y] = true;l[z] = false;l[u] = false;l[A] = false;l[B] = "";function R(a, c, b) { var d;function f() { if (d != null) { d = null;I(b); } }if (p[c.src].finished) return;if (!a[u]) p[c.src].finished = true;d = b.elem || document.createElement("script");if (c.type) d.type = c.type;if (c.charset) d.charset = c.charset;t(d, b, "finished", f);if (b.elem) { b.elem = null; } else if (b.text) { d.onload = d.onreadystatechange = null;d.text = b.text; } else { d.src = c.real_src; }i.insertBefore(d, i.firstChild);if (b.text) { f(); } }function S(c, b, d, f) { var e, g, h = function h() { b.ready_cb(b, function () { R(c, b, e); }); }, j = function j() { b.finished_cb(b, d); };b.src = N(b.src, c[B]);b.real_src = b.src + (c[A] ? (/\?.*$/.test(b.src) ? "&_" : "?_") + ~~(Math.random() * 1E9) + "=" : "");if (!p[b.src]) p[b.src] = { items: [], finished: false };g = p[b.src].items;if (c[u] || g.length == 0) { e = g[g.length] = { ready: false, finished: false, ready_listeners: [h], finished_listeners: [j] };P(c, b, e, f ? function () { e.ready = true;for (var a = 0; a < e.ready_listeners.length; a++) { e.ready_listeners[a](); }e.ready_listeners = []; } : function () { I(e); }, f); } else { e = g[0];if (e.finished) { j(); } else { e.finished_listeners.push(j); } } }function v() { var e, g = s(l, {}), h = [], j = 0, w = false, k;function T(a, c) { a.ready = true;a.exec_trigger = c;x(); }function U(a, c) { a.ready = a.finished = true;a.exec_trigger = null;for (var b = 0; b < c.scripts.length; b++) { if (!c.scripts[b].finished) return; }c.finished = true;x(); }function x() { while (j < h.length) { if (G(h[j])) { try { h[j++](); } catch (err) {}continue; } else if (!h[j].finished) { if (O(h[j])) continue;break; }j++; }if (j == h.length) { w = false;k = false; } }function V() { if (!k || !k.scripts) { h.push(k = { scripts: [], finished: true }); } }e = { script: function script() { for (var f = 0; f < arguments.length; f++) { (function (a, c) { var b;if (!H(a)) { c = [a]; }for (var d = 0; d < c.length; d++) { V();a = c[d];if (G(a)) a = a();if (!a) continue;if (H(a)) { b = [].slice.call(a);b.unshift(d, 1);[].splice.apply(c, b);d--;continue; }if (typeof a == "string") a = { src: a };a = s(a, { ready: false, ready_cb: T, finished: false, finished_cb: U });k.finished = false;k.scripts.push(a);S(g, a, k, Q && w);w = true;if (g[z]) e.wait(); } })(arguments[f], arguments[f]); }return e; }, wait: function wait() { if (arguments.length > 0) { for (var a = 0; a < arguments.length; a++) { h.push(arguments[a]); }k = h[h.length - 1]; } else k = false;x();return e; } };return { script: e.script, wait: e.wait, setOptions: function setOptions(a) { s(a, g);return e; } }; }m = { setGlobalDefaults: function setGlobalDefaults(a) { s(a, l);return m; }, setOptions: function setOptions() { return v().setOptions.apply(null, arguments); }, script: function script() { return v().script.apply(null, arguments); }, wait: function wait() { return v().wait.apply(null, arguments); }, queueScript: function queueScript() { n[n.length] = { type: "script", args: [].slice.call(arguments) };return m; }, queueWait: function queueWait() { n[n.length] = { type: "wait", args: [].slice.call(arguments) };return m; }, runQueue: function runQueue() { var a = m, c = n.length, b = c, d;for (; --b >= 0;) { d = n.shift();a = a[d.type].apply(null, d.args); }return a; }, noConflict: function noConflict() { o.$LAB = K;return m; }, sandbox: function sandbox() { return J(); } };return m; }o.$LAB = J();(function (a, c, _b) { if (document.readyState == null && document[a]) { document.readyState = "loading";document[a](c, _b = function b() { document.removeEventListener(c, _b, false);document.readyState = "complete"; }, false); } })("addEventListener", "DOMContentLoaded"); })(window); // Set default LABjs options window.$LAB.setGlobalDefaults({ AllowDuplicates: false }); /** Utils * A collection of utility functions. */ // Triggers a custom event on the given element. function emit(el, eventName) { var event = document.createEvent('Event'); event.initEvent(eventName, true, true); el.dispatchEvent(event); } // Creates and sends an XMLHttpRequest; requires an options object be passed which may include: // - url (required) // - method // - params // - success // - error function ajax(options) { var opts = Object.assign({ method: 'GET', params: {} }, options); opts.method = opts.method.toUpperCase(); if (opts.method === 'GET') { // Build query string var queryString = Object.keys(opts.params).map(function (key) { return key + '=' + opts.params[key]; }).join('&'); opts.url += '?' + queryString; } var request = new XMLHttpRequest(); request.open(opts.method, opts.url, true); if (opts.success && typeof opts.success === 'function') { request.addEventListener('load', function () { if (request.status >= 200 && request.status < 400) { opts.success(request.responseText); } else if (opts.error && typeof opts.error === 'function') { opts.error(); } }); } if (opts.error && typeof opts.error === 'function') { request.addEventListener('error', opts.error); } if (opts.contentType) { request.setRequestHeader('Content-Type', opts.contentType); } if (opts.method === 'POST') { if (!opts.contentType) { request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=utf-8'); } request.send(opts.params); } else { request.send(); } } // Find closest ancestor of an element that matches the given selector function findAncestor(el, selector) { // eslint-disable-next-line while ((el = el.parentElement) && !el.matches(selector)) {} return el; } // Loads a stylesheet given a URL function loadCSS(url) { var link = document.createElement('link'); link.rel = 'stylesheet'; link.href = url; document.head.appendChild(link); } // https://davidwalsh.name/javascript-debounce-function function debounce(fn, wait, immediate) { var _this = this; var timeout = void 0; return function () { var context = _this; var args = [fn, wait, immediate]; var later = function later() { timeout = null; if (!immediate) fn.apply(context, args); }; var callNow = immediate && !timeout; clearTimeout(timeout); timeout = setTimeout(later, wait); if (callNow) fn.apply(context, args); }; } function queryAll(node, selector) { var result = void 0; if (selector.length && selector[0] === '>') { var uniqueClass = 'qa-' + Date.now(); node.classList.add(uniqueClass); result = document.querySelectorAll('.' + uniqueClass + ' ' + selector); node.classList.remove(uniqueClass); } else { result = node.querySelectorAll(selector); } return Array.prototype.slice.call(result); } function focusOnce(el) { el.setAttribute('tabindex', -1); el.focus(); el.addEventListener('blur', function () { el.removeAttribute('tabindex'); }); } var easings = { /* eslint-disable */ linear: function linear(t, b, c, d) { return c * t / d + b; }, easeInOutQuad: function easeInOutQuad(t, b, c, d) { t /= d / 2; if (t < 1) return c / 2 * t * t + b; t--; return -c / 2 * (t * (t - 2) - 1) + b; }, easeInOutCubic: function easeInOutCubic(t, b, c, d) { t /= d / 2; if (t < 1) return c / 2 * t * t * t + b; t -= 2; return c / 2 * (t * t * t + 2) + b; } /* eslint-enable */ }; var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; function createCommonjsModule(fn, module) { return module = { exports: {} }, fn(module, module.exports), module.exports; } var blazy = createCommonjsModule(function (module, exports) { (function(root, blazy) { { // Node. Does not work with strict CommonJS, but // only CommonJS-like environments that support module.exports, // like Node. module.exports = blazy(); } })(commonjsGlobal, function() { //private vars var _source, _viewport, _isRetina, _supportClosest, _attrSrc = 'src', _attrSrcset = 'srcset'; // constructor return function Blazy(options) { //IE7- fallback for missing querySelectorAll support if (!document.querySelectorAll) { var s = document.createStyleSheet(); document.querySelectorAll = function(r, c, i, j, a) { a = document.all, c = [], r = r.replace(/\[for\b/gi, '[htmlFor').split(','); for (i = r.length; i--;) { s.addRule(r[i], 'k:v'); for (j = a.length; j--;) a[j].currentStyle.k && c.push(a[j]); s.removeRule(0); } return c; }; } //options and helper vars var scope = this; var util = scope._util = {}; util.elements = []; util.destroyed = true; scope.options = options || {}; scope.options.error = scope.options.error || false; scope.options.offset = scope.options.offset || 100; scope.options.root = scope.options.root || document; scope.options.success = scope.options.success || false; scope.options.selector = scope.options.selector || '.b-lazy'; scope.options.separator = scope.options.separator || '|'; scope.options.containerClass = scope.options.container; scope.options.container = scope.options.containerClass ? document.querySelectorAll(scope.options.containerClass) : false; scope.options.errorClass = scope.options.errorClass || 'b-error'; scope.options.breakpoints = scope.options.breakpoints || false; scope.options.loadInvisible = scope.options.loadInvisible || false; scope.options.successClass = scope.options.successClass || 'b-loaded'; scope.options.validateDelay = scope.options.validateDelay || 25; scope.options.saveViewportOffsetDelay = scope.options.saveViewportOffsetDelay || 50; scope.options.srcset = scope.options.srcset || 'data-srcset'; scope.options.src = _source = scope.options.src || 'data-src'; _supportClosest = Element.prototype.closest; _isRetina = window.devicePixelRatio > 1; _viewport = {}; _viewport.top = 0 - scope.options.offset; _viewport.left = 0 - scope.options.offset; /* public functions */ scope.revalidate = function() { initialize(scope); }; scope.load = function(elements, force) { var opt = this.options; if (elements && elements.length === undefined) { loadElement(elements, force, opt); } else { each(elements, function(element) { loadElement(element, force, opt); }); } }; scope.destroy = function() { var util = scope._util; if (scope.options.container) { each(scope.options.container, function(object) { unbindEvent(object, 'scroll', util.validateT); }); } unbindEvent(window, 'scroll', util.validateT); unbindEvent(window, 'resize', util.validateT); unbindEvent(window, 'resize', util.saveViewportOffsetT); util.count = 0; util.elements.length = 0; util.destroyed = true; }; //throttle, ensures that we don't call the functions too often util.validateT = throttle(function() { validate(scope); }, scope.options.validateDelay, scope); util.saveViewportOffsetT = throttle(function() { saveViewportOffset(scope.options.offset); }, scope.options.saveViewportOffsetDelay, scope); saveViewportOffset(scope.options.offset); //handle multi-served image src (obsolete) each(scope.options.breakpoints, function(object) { if (object.width >= window.screen.width) { _source = object.src; return false; } }); // start lazy load setTimeout(function() { initialize(scope); }); // "dom ready" fix }; /* Private helper functions */ function initialize(self) { var util = self._util; // First we create an array of elements to lazy load util.elements = toArray(self.options); util.count = util.elements.length; // Then we bind resize and scroll events if not already binded if (util.destroyed) { util.destroyed = false; if (self.options.container) { each(self.options.container, function(object) { bindEvent(object, 'scroll', util.validateT); }); } bindEvent(window, 'resize', util.saveViewportOffsetT); bindEvent(window, 'resize', util.validateT); bindEvent(window, 'scroll', util.validateT); } // And finally, we start to lazy load. validate(self); } function validate(self) { var util = self._util; for (var i = 0; i < util.count; i++) { var element = util.elements[i]; if (elementInView(element, self.options) || hasClass(element, self.options.successClass)) { self.load(element); util.elements.splice(i, 1); util.count--; i--; } } if (util.count === 0) { self.destroy(); } } function elementInView(ele, options) { var rect = ele.getBoundingClientRect(); if(options.container && _supportClosest){ // Is element inside a container? var elementContainer = ele.closest(options.containerClass); if(elementContainer){ var containerRect = elementContainer.getBoundingClientRect(); // Is container in view? if(inView(containerRect, _viewport)){ var top = containerRect.top - options.offset; var right = containerRect.right + options.offset; var bottom = containerRect.bottom + options.offset; var left = containerRect.left - options.offset; var containerRectWithOffset = { top: top > _viewport.top ? top : _viewport.top, right: right < _viewport.right ? right : _viewport.right, bottom: bottom < _viewport.bottom ? bottom : _viewport.bottom, left: left > _viewport.left ? left : _viewport.left }; // Is element in view of container? return inView(rect, containerRectWithOffset); } else { return false; } } } return inView(rect, _viewport); } function inView(rect, viewport){ // Intersection return rect.right >= viewport.left && rect.bottom >= viewport.top && rect.left <= viewport.right && rect.top <= viewport.bottom; } function loadElement(ele, force, options) { // if element is visible, not loaded or forced if (!hasClass(ele, options.successClass) && (force || options.loadInvisible || (ele.offsetWidth > 0 && ele.offsetHeight > 0))) { var dataSrc = getAttr(ele, _source) || getAttr(ele, options.src); // fallback to default 'data-src' if (dataSrc) { var dataSrcSplitted = dataSrc.split(options.separator); var src = dataSrcSplitted[_isRetina && dataSrcSplitted.length > 1 ? 1 : 0]; var srcset = getAttr(ele, options.srcset); var isImage = equal(ele, 'img'); var parent = ele.parentNode; var isPicture = parent && equal(parent, 'picture'); // Image or background image if (isImage || ele.src === undefined) { var img = new Image(); // using EventListener instead of onerror and onload // due to bug introduced in chrome v50 // (https://productforums.google.com/forum/#!topic/chrome/p51Lk7vnP2o) var onErrorHandler = function() { if (options.error) options.error(ele, "invalid"); addClass(ele, options.errorClass); unbindEvent(img, 'error', onErrorHandler); unbindEvent(img, 'load', onLoadHandler); }; var onLoadHandler = function() { // Is element an image if (isImage) { if(!isPicture) { handleSources(ele, src, srcset); } // or background-image } else { ele.style.backgroundImage = 'url("' + src + '")'; } itemLoaded(ele, options); unbindEvent(img, 'load', onLoadHandler); unbindEvent(img, 'error', onErrorHandler); }; // Picture element if (isPicture) { img = ele; // Image tag inside picture element wont get preloaded each(parent.getElementsByTagName('source'), function(source) { handleSource(source, _attrSrcset, options.srcset); }); } bindEvent(img, 'error', onErrorHandler); bindEvent(img, 'load', onLoadHandler); handleSources(img, src, srcset); // Preload } else { // An item with src like iframe, unity games, simpel video etc ele.src = src; itemLoaded(ele, options); } } else { // video with child source if (equal(ele, 'video')) { each(ele.getElementsByTagName('source'), function(source) { handleSource(source, _attrSrc, options.src); }); ele.load(); itemLoaded(ele, options); } else { if (options.error) options.error(ele, "missing"); addClass(ele, options.errorClass); } } } } function itemLoaded(ele, options) { addClass(ele, options.successClass); if (options.success) options.success(ele); // cleanup markup, remove data source attributes removeAttr(ele, options.src); removeAttr(ele, options.srcset); each(options.breakpoints, function(object) { removeAttr(ele, object.src); }); } function handleSource(ele, attr, dataAttr) { var dataSrc = getAttr(ele, dataAttr); if (dataSrc) { setAttr(ele, attr, dataSrc); removeAttr(ele, dataAttr); } } function handleSources(ele, src, srcset){ if(srcset) { setAttr(ele, _attrSrcset, srcset); //srcset } ele.src = src; //src } function setAttr(ele, attr, value){ ele.setAttribute(attr, value); } function getAttr(ele, attr) { return ele.getAttribute(attr); } function removeAttr(ele, attr){ ele.removeAttribute(attr); } function equal(ele, str) { return ele.nodeName.toLowerCase() === str; } function hasClass(ele, className) { return (' ' + ele.className + ' ').indexOf(' ' + className + ' ') !== -1; } function addClass(ele, className) { if (!hasClass(ele, className)) { ele.className += ' ' + className; } } function toArray(options) { var array = []; var nodelist = (options.root).querySelectorAll(options.selector); for (var i = nodelist.length; i--; array.unshift(nodelist[i])) {} return array; } function saveViewportOffset(offset) { _viewport.bottom = (window.innerHeight || document.documentElement.clientHeight) + offset; _viewport.right = (window.innerWidth || document.documentElement.clientWidth) + offset; } function bindEvent(ele, type, fn) { if (ele.attachEvent) { ele.attachEvent && ele.attachEvent('on' + type, fn); } else { ele.addEventListener(type, fn, { capture: false, passive: true }); } } function unbindEvent(ele, type, fn) { if (ele.detachEvent) { ele.detachEvent && ele.detachEvent('on' + type, fn); } else { ele.removeEventListener(type, fn, { capture: false, passive: true }); } } function each(object, fn) { if (object && fn) { var l = object.length; for (var i = 0; i < l && fn(object[i], i) !== false; i++) {} } } function throttle(fn, minDelay, scope) { var lastCall = 0; return function() { var now = +new Date(); if (now - lastCall < minDelay) { return; } lastCall = now; fn.apply(scope, arguments); }; } }); }); /** Carousel * Creates instances of Carousel based on a CSS selector. * * Example use: Any card landing page on Fusion with a carousel * e.g. http://www.gallup.com/education/227657/improve-k-12.aspx */ var blazyInstance = new blazy(); if (window.gel && window.gel.Carousel) { queryAll(document, '.c-carousel').forEach(function (el) { queryAll(el, '.c-carousel__container > .c-item').forEach(function (item) { return item.classList.add('c-carousel__item'); }); el.classList.add('js-carousel--theme-auto'); // create carousel if (el.classList.contains('c-carousel--tile')) { // create carousel with per page breakpoints new window.gel.Carousel(el, { siemaOptions: { perPage: { 1270: 3, 650: 2 } } }); // eslint-disable-line no-new, max-len } else { new window.gel.Carousel(el); // eslint-disable-line no-new } }); } queryAll(document, '.c-carousel').forEach(function (el) { el.addEventListener('gel.carousel.change', function () { setTimeout(function () { blazyInstance.revalidate(); }, 100); }); }); /** Mosaic (layout) * Displays child elements in a Carousel on mobile and a Mosaic on non-mobile. See implementations * of either layout in GEL Bootstrap for more specifics on how they work. * * Example use: Gallup.com homepage (http://www.gallup.com/) */ var MOBILE_BREAKPOINT = 650; var mosaicContainers = []; var carousels = []; function update(el, index) { // on mobile, initialize a carousel if (window.innerWidth < MOBILE_BREAKPOINT && !carousels[index]) { carousels[index] = new window.gel.Carousel(el.querySelector('.c-carousel')); queryAll(el, '.c-dot-paging').forEach(function (paging) { return paging.classList.add('c-dot-paging--dark'); }); // on non-mobile, destroy the carousel } else if (window.innerWidth >= MOBILE_BREAKPOINT && carousels[index]) { carousels[index].destroy(); carousels[index] = null; } } function updateAll() { mosaicContainers.forEach(update); } if (window.gel && window.gel.Mosaic) { queryAll(document, '.l-mosaic').forEach(function (el) { // create mosaic new window.gel.Mosaic(el, { // eslint-disable-line no-new blockSelector: '.l-mosaic__block', sizes: [{ suffix: 'sm', width: 2, fillLast: 2, maxWidth: 2 }, { suffix: 'md', width: 2, fillLast: 2, maxWidth: 2 }, { suffix: 'lg', width: 3, fillLast: 3, maxWidth: 2 }] }); // do some prep work in case we need to show these items as a carousel on mobile var carousel = document.createElement('div'); carousel.className = 'c-carousel'; el.appendChild(carousel); var container = document.createElement('div'); container.className = 'c-carousel__container'; carousel.appendChild(container); queryAll(el, '.l-mosaic__block').forEach(function (item) { if (!item.hasAttribute('data-carousel-exclude')) { item.classList.add('c-carousel__item'); container.appendChild(item); } }); mosaicContainers.push(el); }); if (window.gel.Carousel) { window.addEventListener('resize', debounce(updateAll, 50)); updateAll(); } } var classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; var createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var toConsumableArray = function (arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } }; /** Masonry (layout) * Lays out child elements of the specified container element in a masonry layout * (i.e. grid of items with nonuniform height). * * Example use: ÓÅÃÛ´«Ã½News homepage (http://news.gallup.com/) */ var DATA_ATTR = 'data-masonry'; var CLS_ACTIVE = 'js-masonry-active'; var CLS_ITEM = 'js-masonry-item'; var CLS_PREPOSITIONED = 'js-masonry-prepositioned'; var CLS_MEASURE = 'js-masonry-measure'; var CLS_SPACER = 'js-masonry-spacer'; var instances = []; var Masonry = function () { function Masonry(container) { var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; classCallCheck(this, Masonry); this.container = typeof container === 'string' ? document.querySelector(container) : container; if (!container) { throw Error('Masonry: Cannot find specified container element.'); } Object.assign(this, { itemSelector: '> section', updateOnResize: true, columnWidth: 310, gutter: 0, useTransforms: true }, options); this.cache = { columnCount: 1 }; this.container.masonry = this; instances.push(this); this.update(); } createClass(Masonry, [{ key: 'getItems', value: function getItems() { if (this.itemSelector.length && this.itemSelector[0] === '>') { var tempCls = 'masonry-container-' + instances.indexOf(this); this.container.classList.add(tempCls); var items = queryAll(document, '.' + tempCls + ' ' + this.itemSelector); this.container.classList.remove(tempCls); return items; } return queryAll(this.container, this.itemSelector); } // Returns number of columns that the container can fit }, { key: 'getColumnCount', value: function getColumnCount() { var available = this.container.offsetWidth + this.gutter; var perColumn = this.columnWidth + this.gutter; return Math.max(Math.floor(available / perColumn), 1); } // Returns which column an x coordinate would be in }, { key: 'xToCol', value: function xToCol(x) { return Math.min(Math.floor(x / this.columnWidth), this.cache.columnCount); } // Returns number of columns an item spans }, { key: 'getColumnsSpanned', value: function getColumnsSpanned(el) { return Math.max(Math.ceil(el.offsetWidth / this.columnWidth), 1); } // Does the actual positioning of items in masonry layout }, { key: 'layout', value: function layout() { var items = this.getItems(); // Abort if there aren't any eligible items in the container if (!items.length) { return; } this.container.classList.add(CLS_ACTIVE); // Find out how many columns we can fit, make a 0'd array of that length var cols = []; for (var i = 0; i < this.cache.columnCount; i++) { cols.push(0); } // Account for prepositioned items var prepositioned = this.container.querySelectorAll('.masonry-container > .' + CLS_PREPOSITIONED); for (var _i = 0; _i < prepositioned.length; _i++) { var el = prepositioned[_i]; var leftCol = this.xToCol(el.offsetLeft); var rightCol = this.xToCol(el.offsetLeft + el.offsetWidth - 1); // Add the tile's height to the affected columns for (var j = leftCol; j <= rightCol; j++) { cols[j] = Math.max(el.offsetTop + el.offsetHeight, cols[j]); } } // Layout the rest of the items for (var _i2 = 0; _i2 < items.length; _i2++) { var _el = items[_i2]; _el.classList.add(CLS_ITEM); // Ignore prepositioned items if (!_el.classList.contains(CLS_PREPOSITIONED)) { // Find the shortest column var col = 0; for (var _j = 1; _j < cols.length; _j++) { if (cols[col] > cols[_j]) { col = _j; } } // Assume standard width initially var colsSpanned = 1; // If it has the `js-masonry-measure` class, actually measure the width if (_el.classList.contains(CLS_MEASURE)) { colsSpanned = Math.min(this.getColumnsSpanned(_el), cols.length); // If it's too wide to fit, place it in the first column if (colsSpanned > cols.length - col) { col = 0; } } // Position the tile _el.style.top = cols[col] + 'px'; _el.style.left = this.columnWidth * col + 'px'; // Account for the space it occupies for (var _j2 = 0; _j2 < colsSpanned; _j2++) { cols[col + _j2] += _el.offsetHeight; } // Spacer/"clearing" logic if (_el.classList.contains(CLS_SPACER)) { (function () { var clearHeight = Math.max.apply(Math, toConsumableArray(cols)); cols = cols.map(function (currentValue) { return Math.max(clearHeight, currentValue); }); })(); } } } // Set appropriate height on the container so all items are visible this.container.style.height = Math.max.apply(Math, toConsumableArray(cols)) + 'px'; } // Disables masonry and restores positioning defaults }, { key: 'reset', value: function reset() { var fullReset = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; this.container.classList.remove(CLS_ACTIVE); this.container.style.height = ''; if (fullReset) { this.getItems().forEach(function (el) { el.classList.remove(CLS_ITEM); el.style.top = ''; el.style.left = ''; }); } } // Checks to see if we need to re-layout or disable the masonry }, { key: 'update', value: function update() { var forceUpdate = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; var cols = this.getColumnCount(); // Only do update if we're forcing an update or the column count has changed var doUpdate = forceUpdate === true || this.cache.columnCount !== cols; // Update cached column count for next update this.cache.columnCount = cols; if (doUpdate) { if (cols > 1) { this.layout(); } else { this.reset(); } } } }, { key: 'destroy', value: function destroy() { this.reset(true); instances.splice(instances.indexOf(this), 1); } }]); return Masonry; }(); var style = document.createElement('style'); style.innerHTML = '\n .' + CLS_ACTIVE + ' {\n position: relative;\n }\n .' + CLS_ACTIVE + ' .' + CLS_ITEM + ' {\n position: absolute;\n }\n'; style.appendChild(document.createTextNode('')); // Webkit hack document.head.appendChild(style); /* ** Event Listeners */ var updateAll$1 = function updateAll() { var force = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; return instances.forEach(function (i) { return i.update(force); }); }; var resetAll = function resetAll() { return instances.forEach(function (i) { return i.reset(); }); }; // Update masonry instances on window resize if updateOnResize == true window.addEventListener('resize', debounce(function () { instances.forEach(function (i) { return i.updateOnResize && i.update(); }); }, 50)); // Update masonry instances when TypeKit loads document.body.addEventListener('typekitLoaded', updateAll$1.bind(null, true)); // Disable masonry (call reset()) on print and re-enable after (call layout()) if ('onbeforeprint' in window) { window.addEventListener('beforeprint', resetAll); window.addEventListener('afterprint', updateAll$1.bind(null, false)); } else if (window.matchMedia) { window.matchMedia('print').addListener(function (mql) { if (mql.matches) { resetAll(); } else { updateAll$1(); } }); } /* ** Auto-initialize elements with [data-masonry] attribute */ queryAll(document, '[' + DATA_ATTR + ']').forEach(function (el) { var options = {}; var itemSelector = el.getAttribute(DATA_ATTR); if (itemSelector) { options.itemSelector = itemSelector; } new Masonry(el, options); // eslint-disable-line no-new }); window.masonry = instances; /** Typekit * Adobe-provided script for loading webfonts from Typekit. */ // TypeKit loader script from Adobe // This has been modified as little as possible to make future upgrades easy (function (d) { var kits = { 'en': 'svt7wsh', 'ja': 'wzr4sie', 'zh': 'lsv0hxq' }; var config = { kitId: kits[document.documentElement.lang.toLowerCase().split('-')[0] || "en"], scriptTimeout: 3000, async: true, active: function active() { document.fonts.ready.then(function () { emit(document.body, 'typekitLoaded'); }); } }, h = d.documentElement, t = setTimeout(function () { h.className = h.className.replace(/\bwf-loading\b/g, "") + " wf-inactive"; }, config.scriptTimeout), tk = d.createElement("script"), f = false, s = d.getElementsByTagName("script")[0], a; h.className += " wf-loading"; tk.src = 'https://use.typekit.net/' + config.kitId + '.js'; tk.async = true; tk.onload = tk.onreadystatechange = function () { a = this.readyState; if (f || a && a != "complete" && a != "loaded") return; f = true; clearTimeout(t); try { Typekit.load(config); } catch (e) {} }; s.parentNode.insertBefore(tk, s); })(document); /** Max lines * Essentially implements `text-overflow-y` (if it were a thing) -- prevents text in * elements with `data-overflow="ellipsis"` from overflowing its container by inserting * an ellipsis at the clipping point and hiding the remainder of the text. * * Example use: tiles on any Fusion site (e.g. ÓÅÃÛ´«Ã½News homepage -- http://news.gallup.com/) */ // Looks for elements with the data attribute data-overflow="ellipsis" // Determines whether that element has text that has been hidden by overflow // Adds an ellipsis to the end of the text that is visible // Set update to true if you have new elements on the page to check var fontCache = {}; function setup() { // Add temporary styles var style = document.createElement('style'); // Hack for Webkit -- http://davidwalsh.name/add-rules-stylesheets style.appendChild(document.createTextNode('')); document.head.appendChild(style); style.id = 'maxlines-styles'; style.sheet.insertRule('.font-baseline { visibility: hidden; height: 100px; }', 0); style.sheet.insertRule('.font-baseline span:after { content: \'\'; height: 100%; display: inline-block; }', 1); } function reset() { // Remove temporary styles document.head.removeChild(document.getElementById('maxlines-styles')); } // Recursively get all textnodes that are children of a node. // Previously we used the treewalker API but there were some // browser-specific bugs with the API function textNodesUnder(node) { var all = []; var cursor = node; for (cursor = cursor.firstChild; cursor; cursor = cursor.nextSibling) { if (cursor.nodeType === 3) all.push(cursor);else all = all.concat(textNodesUnder(cursor)); } return all; } // Calculate a number of font metrics needed for the work // Most importantly the baseline and the width of an ellipsis // for a specific element function fontMetrics(_container) { var div = document.createElement('div'); var strut = document.createElement('span'); var lineHeight = void 0; var container = _container || document.body; var containerStyle = window.getComputedStyle(container); var hash = [containerStyle.fontFamily, containerStyle.fontSize, containerStyle.fontWeight, containerStyle.lineHeight, containerStyle.letterSpacing].join('-'); if (fontCache[hash]) { return fontCache[hash]; } else if (containerStyle.display === 'none') { return null; } // Make an ellipsis for this element offscreen so we can measure it var ellipsis = document.createElement('div'); ellipsis.setAttribute('aria-hidden', true); ellipsis.style.position = 'absolute'; ellipsis.style.left = '-99999999px'; ellipsis.innerHTML = '…'; container.appendChild(ellipsis); // Measure it so we can test if an ellipsis fits in letious spots. var elipWidth = ellipsis.getBoundingClientRect().width * 2; container.removeChild(ellipsis); // Thanks to Alan Stearns for the hack! // http://blogs.adobe.com/webplatform/2014/08/13/one-weird-trick-to-baseline-align-text/ strut.textContent = 'T'; div.appendChild(strut); div.classList.add('font-baseline'); container.appendChild(div); var computedStyle = window.getComputedStyle(strut); lineHeight = parseInt(computedStyle.lineHeight, 10); strut.style.lineHeight = 0; var strutHeight = strut.offsetHeight; var baselineHeight = strut.offsetTop + strutHeight - div.offsetHeight - div.offsetTop; lineHeight = lineHeight || strutHeight; div.parentNode.removeChild(div); // Cache the result before returning it fontCache[hash] = { elipWidth: elipWidth, offset: (lineHeight - strutHeight) / 2 + baselineHeight }; return fontCache[hash]; } function maxLines(update) { setup(); // We are going to process everything which means removing old ellipses. if (!update) { // Clean up previous pass. If we are calling this again something has changed. queryAll(document, '[data-overflow="ellipsis"] .overflow-ellipsis').forEach(function (el) { el.parentNode.removeChild(el); }); } // We only want to check new items var els = update ? queryAll(document, '[data-overflow="ellipsis"]:not([data-overflow-checked="1"])') : queryAll(document, '[data-overflow="ellipsis"]'); var range = document.createRange(); // Reusable range object // For each data-overflow element, check to see // if we need ellipsis and add one if we do els.forEach(function (el) { el.normalize(); // Measure the font metrics so we can find the baseline offset for this text var metrics = fontMetrics(el); if (!metrics) { return; } // Do we have any overflowing text? var elRect = el.getBoundingClientRect(); var elBottom = elRect.bottom; // Measure the position of the last baseline in the element // Because scrollHeight is an integer and the clientRect is not // it could be off by as much as a pixel, so subtract 1 from the scrollHeight // So that we don't inadvertantly try and ellipsis something that actually fits. var contentBottom = Math.max(elRect.bottom, elRect.top + el.scrollHeight - 1) - metrics.offset; range.selectNodeContents(el); // See if the last baseline is being cropped by a parent var parentBottom = elBottom; var parentNode = el.parentNode; // We could save time by caching this, perhaps? while (parentNode && parentNode.nodeType === 1) { if (window.getComputedStyle(parentNode).overflow !== 'visible') { parentBottom = parentNode.getBoundingClientRect().bottom; if (parentBottom <= elBottom) { elBottom = parentBottom; } } parentNode = parentNode.parentNode; // eslint-disable-line prefer-destructuring } // Mark the element so we can skip it during update calls later el.setAttribute('data-overflow-checked', 1); // If this elment is not overflowing, we are done. if (elBottom >= contentBottom) { return; } // Go through the text nodes to find the last visible text in the element. var textNodes = textNodesUnder(el); textNodes.reverse(); // Stop returning true when we've found our match textNodes.every(function (tn) { // Find all the whitespace indices in the element. var result = []; tn.textContent.replace(/([.,\s]+)/g, function (a, b, index) { result.push(index); }); result.reverse(); // Find all the bounding rectangles for the character preceeding // whitepsace from last to first. for (var i = 0; i < result.length; i++) { // If the whitespace character is the first character in the text node, ignore it // We don't want to put an ellipsis there anyway if (result[i] !== 0) { range.setStart(tn, result[i] - 1); range.setEnd(tn, result[i]); // Find the position of this whitespace character on the page var gapRect = range.getBoundingClientRect(); var gapBottom = gapRect.bottom; var gapRight = gapRect.right; // IE uses logical pixels for the dimensions reported by range.getBoundingClientRect // so we need to convert these to match the dimensions reported by the element version if (window.screen.deviceXDPI) { gapBottom /= window.screen.deviceXDPI / window.screen.logicalXDPI; gapRight /= window.screen.deviceXDPI / window.screen.logicalXDPI; } // Find the baseline for this character gapBottom -= metrics.offset; // If the whitespace character's baseline is visible and there is room // to the right for an ellipsis, put a span containing the // ellipsis and some line breaks right before the whitespace. // The line breaks push the rest of the text to be outside // of the visible area so that the ellipsis is the last text. if (gapBottom <= elBottom && gapRight + metrics.elipWidth < elRect.right) { var newNode = document.createElement('span'); newNode.className = 'overflow-ellipsis'; newNode.setAttribute('aria-hidden', true); range.setStart(tn, result[i]); range.setEnd(tn, result[i]); range.surroundContents(newNode); newNode.innerHTML = '\u2026


' + newNode.innerHTML; return false; } } } return true; }); }); reset(); } // Check for [data-overflow="ellipsis"] and run maxLines() if needed if (document.querySelector('[data-overflow="ellipsis"]')) { maxLines(); document.body.addEventListener('typekitLoaded', function () { return maxLines(); }); } window.wwwV8 = window.wwwV8 || {}; window.wwwV8.maxLines = maxLines; /** Tiles * Encapsulates functionality required by Fusion tiles. Adds lazy loading for * tile images and vertical text overflow handling. * * Example use: ÓÅÃÛ´«Ã½News homepage (http://news.gallup.com/) */ // Create bLazy instance to lazy load tile images var blazyInstance$1 = new blazy(); var tiles = { maxLines: maxLines, blazyInstance: blazyInstance$1 }; /** Scroll to element * Smoothly scrolls to the specified element. Supports easing functions. * * Example use: modules/jump-link */ // Easing functions -- http://gizma.com/easing/ var easings$1 = { /* eslint-disable */ linear: function linear(t, b, c, d) { return c * t / d + b; }, easeInOutQuad: function easeInOutQuad(t, b, c, d) { t /= d / 2; if (t < 1) return c / 2 * t * t + b; t--; return -c / 2 * (t * (t - 2) - 1) + b; }, easeInOutCubic: function easeInOutCubic(t, b, c, d) { t /= d / 2; if (t < 1) return c / 2 * t * t * t + b; t -= 2; return c / 2 * (t * t * t + 2) + b; } /* eslint-enable */ }; function scrollToElement(el) { var cb = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; var duration = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 500; var ease = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : easings$1.easeInOutCubic; // Start point var start = document.documentElement.scrollTop || document.body.parentNode.scrollTop || document.body.scrollTop; var distance = el.getBoundingClientRect().top; // Distance to scroll queryAll(document, '.navbar-sticky-placeholder, .c-gmn-overlay, .item-pinned').forEach(function (item) { distance -= item.clientHeight; }); var time = 0; // Current time in ms var lastDraw = void 0; // Time of last draw var animate = function animate() { // Update time var now = new Date().getTime(); time += now - (lastDraw || now); lastDraw = now; // Get next scroll point var scrollTop = ease(time, start, distance, duration); // Update scrollTop document.documentElement.scrollTop = scrollTop; document.body.parentNode.scrollTop = scrollTop; document.body.scrollTop = scrollTop; // If the animation isn't over call animate() for next frame, otherwise run the callback if (time < duration) { requestAnimationFrame(animate); } else if (cb && typeof cb === 'function') { cb(el); } }; // Animate first frame animate(); // Update focus to first focusable link after animation if (el.querySelector('a')) { el.querySelector('a').focus(); } } queryAll(document, '[data-scroll-to]').forEach(function (el) { var target = document.querySelector(el.getAttribute('data-scroll-to')); if (target) { el.addEventListener('click', function (e) { scrollToElement(target); if (target.tagName === 'A') { e.preventDefault(); } }); } }); window.wwwV8 = window.wwwV8 || {}; window.wwwV8.scrollToElement = scrollToElement; /** JumpLink * Basically a fancy anchor -- smoothly scrolls to designated element on page. * Auto-initializes elements with the `data-jump-target` attribute. * * Example use: http://www.gallup.com/workplace/215381/gallup-leadership-development.aspx */ var ATTRIBUTE_TARGET = 'data-jump-target'; var ATTRIBUTE_STATUS = 'data-jump-link'; var STATUS_INITIALIZED = 'initialized'; var defaultToLast = !!document.querySelectorAll('body.jump2form, main.jump2form').length; var eventHandlers = { click: function click(e) { this.jump(); e.preventDefault(); } }; var JumpLink = function () { function JumpLink(el) { var target = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : JumpLink.resolveTarget(el); var focusOnJump = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; classCallCheck(this, JumpLink); this.el = el; this.target = target; this.focusOnJump = focusOnJump; this.el.addEventListener('click', eventHandlers.click.bind(this)); this.el.setAttribute(ATTRIBUTE_STATUS, STATUS_INITIALIZED); } createClass(JumpLink, [{ key: 'jump', value: function jump() { if (this.focusOnJump) { scrollToElement(this.target, focusOnce); } else { scrollToElement(this.target); } } }], [{ key: 'resolveTarget', value: function resolveTarget(el) { var card = findAncestor(el, ['.article-cards > *', '.article--cards > *', '.article-cards > .inner > *', '.article--cards > .inner > *'].join(', ')); if (!card) return null; var attr = el.getAttribute(ATTRIBUTE_TARGET); var href = el.getAttribute('href') || ''; var anchor = href.indexOf('#') > -1 ? href.substring(href.lastIndexOf('#') + 1) : null; if (attr) { if (attr === 'next') { return card.nextElementSibling; } else if (attr === 'last') { return card.parentElement.lastElementChild; } else if (document.querySelector(attr)) { return document.querySelector(attr); } return null; } else if (anchor) { return document.getElementById(anchor); } else if (defaultToLast) { return card.parentElement.lastElementChild; } return card.nextElementSibling; } }]); return JumpLink; }(); queryAll(document, '[' + ATTRIBUTE_TARGET + ']').forEach(function (el) { // Prevent repeat initialization if (el.getAttribute(ATTRIBUTE_STATUS) !== STATUS_INITIALIZED) { new JumpLink(el); // eslint-disable-line no-new } }); /** Pager * Automatically paginates the contents of the given container element. Default is * one child element per page but it is configurable. * * Example use: http://www.gallup.com/workplace/215381/gallup-leadership-development.aspx */ var Pager = function () { function Pager(element) { var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; classCallCheck(this, Pager); this.element = element; this.options = Object.assign({ // Default values itemsPerPage: 1, itemSelector: null }, options); this.pages = []; this.selectedIndex = -1; this.create(); } createClass(Pager, [{ key: 'create', value: function create() { var _this = this; var element = this.element, options = this.options, pages = this.pages; var items = options.itemSelector ? queryAll(element, options.itemSelector) : element.children; // Make `element` the first page this.pages.push(this.createPage(element)); this.selectedIndex = 0; var currentPage = void 0; for (var i = options.itemsPerPage; i < items.length; i++) { if (i % options.itemsPerPage === 0) { currentPage = this.createPage(); this.pages.push(currentPage); } currentPage.appendChild(items[i]); } this.controls = document.createElement('div'); this.controls.className = 'c-dot-paging c-dot-paging--centered'; this.controls.innerHTML = '\n \n
\n ' + this.pages.map(function (el, i) { return '\n \n '; }).join('') + '\n
\n \n '; element.parentElement.appendChild(this.controls); // hook up click events this.controls.addEventListener('click', function (e) { var el = e.target; if (el.matches('.c-dot-paging__indicator')) { _this.showPage(parseInt(el.getAttribute('data-index'), 10)); } else if (el.matches('.c-dot-paging__prev-btn, .c-dot-paging__prev-btn *')) { _this.showPage(_this.selectedIndex - 1); } else if (el.matches('.c-dot-paging__next-btn, .c-dot-paging__next-btn *')) { _this.showPage(_this.selectedIndex + 1); } }); this.prevBtn = this.controls.querySelector('.c-dot-paging__prev-btn'); this.nextBtn = this.controls.querySelector('.c-dot-paging__next-btn'); // Show first page this.showPage(0); if (pages.length < 2) { this.controls.classList.add('hidden'); } } }, { key: 'createPage', value: function createPage() { var _page = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; var page = _page; if (!page) { // Create a new page page = document.createElement('div'); page.className = this.element.className; page.classList.add('hidden'); this.element.parentElement.insertBefore(page, this.element.nextSiblingElement); } page.setAttribute('data-index', this.pages.length); return page; } }, { key: 'showPage', value: function showPage(index) { if (this.selectedIndex > -1) { this.pages[this.selectedIndex].classList.remove('active'); this.pages[this.selectedIndex].classList.add('hidden'); queryAll(this.controls, '.c-dot-paging__indicator.is-active').forEach(function (el) { return el.classList.remove('is-active'); }); } this.pages[index].classList.remove('hidden'); this.pages[index].classList.add('active'); var indicator = this.controls.querySelector('[data-index="' + index + '"]'); if (indicator) { indicator.classList.add('is-active'); } this.selectedIndex = index; this.prevBtn.disabled = this.selectedIndex === 0; this.nextBtn.disabled = this.selectedIndex === this.pages.length - 1; } }]); return Pager; }(); /** Card landing page * Encapsulates functionality required by the card landing page template. Creates * instances of JumpLink and Pager based on CSS selectors. * * Example use: Any card landing page on Fusion * e.g. http://www.gallup.com/workplace/215381/gallup-leadership-development.aspx */ // Wire up jump links queryAll(document, '.jump-link > a').forEach(function (el) { return new JumpLink(el); }); // Create pagers queryAll(document, '.article-cards [class*="tabitems-"], .article--cards [class*="tabitems-"]').forEach(function (card) { var itemsPerPage = void 0; Array.prototype.forEach.call(card.classList, function (cls) { if (cls.indexOf('tabitems-') === 0) { itemsPerPage = parseInt(cls.substring(9), 10); } }); if (!itemsPerPage) return; var parent = card.querySelector('.flex-wrapper'); if (!parent) return; // eslint-disable-next-line no-new new Pager(parent, { itemsPerPage: itemsPerPage, itemSelector: '.flex-item' }); }); var evEmitter = createCommonjsModule(function (module) { /** * EvEmitter v2.1.1 * Lil' event emitter * MIT License */ ( function( global, factory ) { // universal module definition if ( module.exports ) { // CommonJS - Browserify, Webpack module.exports = factory(); } else { // Browser globals global.EvEmitter = factory(); } }( typeof window != 'undefined' ? window : commonjsGlobal, function() { function EvEmitter() {} let proto = EvEmitter.prototype; proto.on = function( eventName, listener ) { if ( !eventName || !listener ) return this; // set events hash let events = this._events = this._events || {}; // set listeners array let listeners = events[ eventName ] = events[ eventName ] || []; // only add once if ( !listeners.includes( listener ) ) { listeners.push( listener ); } return this; }; proto.once = function( eventName, listener ) { if ( !eventName || !listener ) return this; // add event this.on( eventName, listener ); // set once flag // set onceEvents hash let onceEvents = this._onceEvents = this._onceEvents || {}; // set onceListeners object let onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || {}; // set flag onceListeners[ listener ] = true; return this; }; proto.off = function( eventName, listener ) { let listeners = this._events && this._events[ eventName ]; if ( !listeners || !listeners.length ) return this; let index = listeners.indexOf( listener ); if ( index != -1 ) { listeners.splice( index, 1 ); } return this; }; proto.emitEvent = function( eventName, args ) { let listeners = this._events && this._events[ eventName ]; if ( !listeners || !listeners.length ) return this; // copy over to avoid interference if .off() in listener listeners = listeners.slice( 0 ); args = args || []; // once stuff let onceListeners = this._onceEvents && this._onceEvents[ eventName ]; for ( let listener of listeners ) { let isOnce = onceListeners && onceListeners[ listener ]; if ( isOnce ) { // remove listener // remove before trigger to prevent recursion this.off( eventName, listener ); // unset once flag delete onceListeners[ listener ]; } // trigger listener listener.apply( this, args ); } return this; }; proto.allOff = function() { delete this._events; delete this._onceEvents; return this; }; return EvEmitter; } ) ); }); var imagesloaded = createCommonjsModule(function (module) { /*! * imagesLoaded v5.0.0 * JavaScript is all like "You images are done yet or what?" * MIT License */ ( function( window, factory ) { // universal module definition if ( module.exports ) { // CommonJS module.exports = factory( window, evEmitter ); } else { // browser global window.imagesLoaded = factory( window, window.EvEmitter ); } } )( typeof window !== 'undefined' ? window : commonjsGlobal, function factory( window, EvEmitter ) { let $ = window.jQuery; let console = window.console; // -------------------------- helpers -------------------------- // // turn element or nodeList into an array function makeArray( obj ) { // use object if already an array if ( Array.isArray( obj ) ) return obj; let isArrayLike = typeof obj == 'object' && typeof obj.length == 'number'; // convert nodeList to array if ( isArrayLike ) return [ ...obj ]; // array of single index return [ obj ]; } // -------------------------- imagesLoaded -------------------------- // /** * @param {[Array, Element, NodeList, String]} elem * @param {[Object, Function]} options - if function, use as callback * @param {Function} onAlways - callback function * @returns {ImagesLoaded} */ function ImagesLoaded( elem, options, onAlways ) { // coerce ImagesLoaded() without new, to be new ImagesLoaded() if ( !( this instanceof ImagesLoaded ) ) { return new ImagesLoaded( elem, options, onAlways ); } // use elem as selector string let queryElem = elem; if ( typeof elem == 'string' ) { queryElem = document.querySelectorAll( elem ); } // bail if bad element if ( !queryElem ) { console.error(`Bad element for imagesLoaded ${queryElem || elem}`); return; } this.elements = makeArray( queryElem ); this.options = {}; // shift arguments if no options set if ( typeof options == 'function' ) { onAlways = options; } else { Object.assign( this.options, options ); } if ( onAlways ) this.on( 'always', onAlways ); this.getImages(); // add jQuery Deferred object if ( $ ) this.jqDeferred = new $.Deferred(); // HACK check async to allow time to bind listeners setTimeout( this.check.bind( this ) ); } ImagesLoaded.prototype = Object.create( EvEmitter.prototype ); ImagesLoaded.prototype.getImages = function() { this.images = []; // filter & find items if we have an item selector this.elements.forEach( this.addElementImages, this ); }; const elementNodeTypes = [ 1, 9, 11 ]; /** * @param {Node} elem */ ImagesLoaded.prototype.addElementImages = function( elem ) { // filter siblings if ( elem.nodeName === 'IMG' ) { this.addImage( elem ); } // get background image on element if ( this.options.background === true ) { this.addElementBackgroundImages( elem ); } // find children // no non-element nodes, #143 let { nodeType } = elem; if ( !nodeType || !elementNodeTypes.includes( nodeType ) ) return; let childImgs = elem.querySelectorAll('img'); // concat childElems to filterFound array for ( let img of childImgs ) { this.addImage( img ); } // get child background images if ( typeof this.options.background == 'string' ) { let children = elem.querySelectorAll( this.options.background ); for ( let child of children ) { this.addElementBackgroundImages( child ); } } }; const reURL = /url\((['"])?(.*?)\1\)/gi; ImagesLoaded.prototype.addElementBackgroundImages = function( elem ) { let style = getComputedStyle( elem ); // Firefox returns null if in a hidden iframe https://bugzil.la/548397 if ( !style ) return; // get url inside url("...") let matches = reURL.exec( style.backgroundImage ); while ( matches !== null ) { let url = matches && matches[2]; if ( url ) { this.addBackground( url, elem ); } matches = reURL.exec( style.backgroundImage ); } }; /** * @param {Image} img */ ImagesLoaded.prototype.addImage = function( img ) { let loadingImage = new LoadingImage( img ); this.images.push( loadingImage ); }; ImagesLoaded.prototype.addBackground = function( url, elem ) { let background = new Background( url, elem ); this.images.push( background ); }; ImagesLoaded.prototype.check = function() { this.progressedCount = 0; this.hasAnyBroken = false; // complete if no images if ( !this.images.length ) { this.complete(); return; } /* eslint-disable-next-line func-style */ let onProgress = ( image, elem, message ) => { // HACK - Chrome triggers event before object properties have changed. #83 setTimeout( () => { this.progress( image, elem, message ); } ); }; this.images.forEach( function( loadingImage ) { loadingImage.once( 'progress', onProgress ); loadingImage.check(); } ); }; ImagesLoaded.prototype.progress = function( image, elem, message ) { this.progressedCount++; this.hasAnyBroken = this.hasAnyBroken || !image.isLoaded; // progress event this.emitEvent( 'progress', [ this, image, elem ] ); if ( this.jqDeferred && this.jqDeferred.notify ) { this.jqDeferred.notify( this, image ); } // check if completed if ( this.progressedCount === this.images.length ) { this.complete(); } if ( this.options.debug && console ) { console.log( `progress: ${message}`, image, elem ); } }; ImagesLoaded.prototype.complete = function() { let eventName = this.hasAnyBroken ? 'fail' : 'done'; this.isComplete = true; this.emitEvent( eventName, [ this ] ); this.emitEvent( 'always', [ this ] ); if ( this.jqDeferred ) { let jqMethod = this.hasAnyBroken ? 'reject' : 'resolve'; this.jqDeferred[ jqMethod ]( this ); } }; // -------------------------- -------------------------- // function LoadingImage( img ) { this.img = img; } LoadingImage.prototype = Object.create( EvEmitter.prototype ); LoadingImage.prototype.check = function() { // If complete is true and browser supports natural sizes, // try to check for image status manually. let isComplete = this.getIsImageComplete(); if ( isComplete ) { // report based on naturalWidth this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' ); return; } // If none of the checks above matched, simulate loading on detached element. this.proxyImage = new Image(); // add crossOrigin attribute. #204 if ( this.img.crossOrigin ) { this.proxyImage.crossOrigin = this.img.crossOrigin; } this.proxyImage.addEventListener( 'load', this ); this.proxyImage.addEventListener( 'error', this ); // bind to image as well for Firefox. #191 this.img.addEventListener( 'load', this ); this.img.addEventListener( 'error', this ); this.proxyImage.src = this.img.currentSrc || this.img.src; }; LoadingImage.prototype.getIsImageComplete = function() { // check for non-zero, non-undefined naturalWidth // fixes Safari+InfiniteScroll+Masonry bug infinite-scroll#671 return this.img.complete && this.img.naturalWidth; }; LoadingImage.prototype.confirm = function( isLoaded, message ) { this.isLoaded = isLoaded; let { parentNode } = this.img; // emit progress with parent or self let elem = parentNode.nodeName === 'PICTURE' ? parentNode : this.img; this.emitEvent( 'progress', [ this, elem, message ] ); }; // ----- events ----- // // trigger specified handler for event type LoadingImage.prototype.handleEvent = function( event ) { let method = 'on' + event.type; if ( this[ method ] ) { this[ method ]( event ); } }; LoadingImage.prototype.onload = function() { this.confirm( true, 'onload' ); this.unbindEvents(); }; LoadingImage.prototype.onerror = function() { this.confirm( false, 'onerror' ); this.unbindEvents(); }; LoadingImage.prototype.unbindEvents = function() { this.proxyImage.removeEventListener( 'load', this ); this.proxyImage.removeEventListener( 'error', this ); this.img.removeEventListener( 'load', this ); this.img.removeEventListener( 'error', this ); }; // -------------------------- Background -------------------------- // function Background( url, element ) { this.url = url; this.element = element; this.img = new Image(); } // inherit LoadingImage prototype Background.prototype = Object.create( LoadingImage.prototype ); Background.prototype.check = function() { this.img.addEventListener( 'load', this ); this.img.addEventListener( 'error', this ); this.img.src = this.url; // check if image is already complete let isComplete = this.getIsImageComplete(); if ( isComplete ) { this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' ); this.unbindEvents(); } }; Background.prototype.unbindEvents = function() { this.img.removeEventListener( 'load', this ); this.img.removeEventListener( 'error', this ); }; Background.prototype.confirm = function( isLoaded, message ) { this.isLoaded = isLoaded; this.emitEvent( 'progress', [ this, this.element, message ] ); }; // -------------------------- jQuery -------------------------- // ImagesLoaded.makeJQueryPlugin = function( jQuery ) { jQuery = jQuery || window.jQuery; if ( !jQuery ) return; // set local variable $ = jQuery; // $().imagesLoaded() $.fn.imagesLoaded = function( options, onAlways ) { let instance = new ImagesLoaded( this, options, onAlways ); return instance.jqDeferred.promise( $( this ) ); }; }; // try making plugin ImagesLoaded.makeJQueryPlugin(); // -------------------------- -------------------------- // return ImagesLoaded; } ); }); /** Topics page * Encapsulates the functionality required by the topics page template. * * Example use: http://news.gallup.com/topic/politics.aspx */ var tilesContainer = document.querySelector('.masonry-container'); var contentMorePanel = document.querySelector('.content-more'); var loadMoreButton = document.querySelector('[data-load-more]') || document.querySelector('.search-load-more'); var loadMoreCount = -1; var handlers = { tilesAdded: function tilesAdded() { if (tilesContainer.masonry) { tilesContainer.masonry.update(true); } tiles.maxLines(true); }, tileImagesLoaded: function tileImagesLoaded() { if (tilesContainer.masonry) { tilesContainer.masonry.update(true); } tiles.maxLines(); emit(tilesContainer, 'gel.tiles.imagesloaded'); } }; // Load more tiles into the masonry function loadTiles() { var url = loadMoreButton.getAttribute('data-load-more') || '/Search/raw.aspx'; var startPage = parseInt(loadMoreButton.getAttribute('data-startpage'), 10); var totalPages = parseInt(loadMoreButton.getAttribute('data-totalpages'), 10); var currentPage = parseInt(loadMoreButton.getAttribute('data-currentpage'), 10); var nextPage = currentPage + 1; var queryString = loadMoreButton.getAttribute('data-qs') || window.location.href.slice(window.location.href.indexOf('?') + 1); if (startPage && nextPage <= totalPages && nextPage > loadMoreCount) { loadMoreButton.disabled = true; loadMoreCount = nextPage; ajax({ method: 'GET', url: url + '?' + queryString.replace('&p=' + startPage, '&p=' + nextPage), success: function success(response) { loadMoreButton.setAttribute('data-currentpage', nextPage); if (nextPage + 1 > totalPages) { contentMorePanel.style.position = 'absolute'; contentMorePanel.style.opacity = 0; loadMoreButton.addEventListener('blur', function () { contentMorePanel.style.position = ''; contentMorePanel.style.opacity = ''; contentMorePanel.style.display = 'none'; }); } var lastItem = tilesContainer.lastElementChild; tilesContainer.insertAdjacentHTML('beforeend', response); if (lastItem.nextElementSibling && lastItem.nextElementSibling.querySelector('a[href]')) { loadMoreButton.focusNext = lastItem.nextElementSibling.querySelector('a[href]'); } tiles.blazyInstance.revalidate(); loadMoreButton.disabled = false; loadMoreButton.focus(); imagesloaded(tilesContainer, handlers.tileImagesLoaded); emit(tilesContainer, 'gel.tiles.added'); }, error: function error() { contentMorePanel.style.display = 'none'; } }); } else { contentMorePanel.style.display = 'none'; } } // Hook up masonry and max lines updates whenever tiles are added or images finish loading if (tilesContainer) { tilesContainer.addEventListener('gel.tiles.added', handlers.tilesAdded); imagesloaded(tilesContainer, handlers.tileImagesLoaded); } // Hook up Load More button to load additional tiles when clicked if (loadMoreButton) { if (loadMoreButton.getAttribute('data-startpage')) { loadMoreButton.addEventListener('click', loadTiles); } else { contentMorePanel.style.display = 'none'; } loadMoreButton.addEventListener('keydown', function (e) { if (e.keyCode === 9) { // tab if (loadMoreButton.focusNext) { loadMoreButton.focusNext.focus(); loadMoreButton.focusNext = null; e.preventDefault(); } } }); } /** Interactives * Loads additional stylesheets and scripts for interactives on ÓÅÃÛ´«Ã½News. * Looks up files to load based on a hard-coded hash table. * * Example use: Presidential Job Approval Center * http://news.gallup.com/interactives/185273/presidential-job-approval-center.aspx */ // Lazy load additional resources for interactive pages var LOCAL_JS_PATH = '/Site-NewsV9/JavaScript/Interactives'; var LOCAL_CSS_PATH = '/Site-NewsV9/CSS/Interactives'; var JQUERY = ['//ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js', '//ajax.googleapis.com/ajax/libs/jqueryui/1.11.0/jquery-ui.min.js']; function appendVersion(url) { if (!window.gfwVersion) return url; return url + '?v=' + window.gfwVersion; } function standardDependencies(codename) { var loadStyles = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; var loadJquery = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; var deps = loadJquery ? [].concat(JQUERY) : []; if (loadStyles) { deps.push(appendVersion(LOCAL_CSS_PATH + '/interactive-' + codename + '.css')); } deps.push(appendVersion(LOCAL_JS_PATH + '/interactive-' + codename + '.js')); return deps; } // This is somewhat nasty but right now, we're looking up interactives by their ID in spaces. var interactives = { 'poll/125066': [].concat(toConsumableArray(standardDependencies('stateofstates'))), 'poll/142631': [].concat(toConsumableArray(standardDependencies('usleadership', true, true))), 'poll/145913': [].concat(toConsumableArray(standardDependencies('communitywellbeing', true, true))), 'poll/145487': [].concat(toConsumableArray(standardDependencies('employment', false, true))), 'poll/154559': [].concat(toConsumableArray(standardDependencies('electioncenter'))), 'interactives/185273': [appendVersion('/Gel-Github/dataviz/dataviz.js')].concat(toConsumableArray(standardDependencies('pjac', false))) }; var pathbits = document.location.pathname.split('/'); if (pathbits.length >= 2) { (interactives[pathbits[1] + '/' + pathbits[2]] || []).forEach(function (dep) { if (/\.css(\?.*)?$/i.test(dep)) { loadCSS(dep); } else { $LAB.script(dep); } }); } /** Embeddable * Moves an element with the `data-embeddable` attribute to the position marked * by an accompanying element with the `data-embeddable-marker` attribute. (The * latter element is replaced by the former.) */ var markers = document.querySelectorAll('[data-embeddable-marker]'); var embeddables = document.querySelectorAll('[data-embeddable] > div'); if (markers && embeddables) { for (var i = 0; i < markers.length && i < embeddables.length; i++) { markers[i].parentElement.replaceChild(embeddables[i], markers[i]); } } /** Speedbump * Moves an element with the `data-speedbump` attribute to the position marked * by an accompanying element with the `data-speedbump-marker` attribute. (The * latter element is replaced by the former.) * * Example use: ÓÅÃÛ´«Ã½News articles * e.g. http://news.gallup.com/businessjournal/232736/elon-musk-start.aspx */ var markers$1 = document.querySelectorAll('[data-speedbump-marker]'); var speedbumps = document.querySelectorAll('[data-speedbump] > div'); if (markers$1 && speedbumps) { for (var i$1 = 0; i$1 < markers$1.length && i$1 < speedbumps.length; i$1++) { markers$1[i$1].parentElement.replaceChild(speedbumps[i$1], markers$1[i$1]); } } /** Flexchart * If `window.wwwV8.flexchart` is set, loads XML data set and Dataviz library. * Renders line chart with time period zoom options to the DOM element specified * by `window.wwwV8.flexchart.container`. * * Example use: ÓÅÃÛ´«Ã½Daily charts * e.g. http://news.gallup.com/poll/201617/gallup-daily-trump-job-approval.aspx */ var DEFAULT_CHART_SOURCE = 'ÓÅÃÛ´«Ã½Daily Tracking'; var datavizLoaded = false; function createZoomControls(flexchartObject) { var chart = flexchartObject.chart; var container = document.querySelector(flexchartObject.container); var timePeriodSelector = document.createElement('ul'); timePeriodSelector.className = 'time-period-selector'; container.insertBefore(timePeriodSelector, container.firstChild); // TODO: refactor/remove // This is a temporary workaround to get around the fact that, for example, // 30 data points does not equal 30 days of data var ONE_DAY_IN_MILLISECONDS = 24 * 60 * 60 * 1000; var MIN_DATA_POINTS = 3; var firstDate = new Date(chart.data.labels[0].text); var lastDate = new Date(chart.data.labels[chart.data.labels.length - 1].text); var numDays = (lastDate.getTime() - firstDate.getTime()) / ONE_DAY_IN_MILLISECONDS; var dataDensity = chart.metadata.axisX.axisRange / numDays; var createControl = function createControl(rangeStart, label) { var li = document.createElement('li'); var el = document.createElement('button'); el.setAttribute('data-zoom-control', ''); el.textContent = label; el.addEventListener('click', function () { if (rangeStart === 0) { chart.zoom(1); } else { chart.zoomToRange(Math.floor(rangeStart * dataDensity)); } [].concat(toConsumableArray(timePeriodSelector.querySelectorAll('.active'))).forEach(function (t) { t.classList.remove('active'); }); el.classList.add('active'); }); li.appendChild(el); timePeriodSelector.appendChild(li); return el; }; var controls = [[-7, '1 Week'], [-30, '1 Month'], [-90, '3 Months'], [-180, '6 Months'], [-365, '1 Year'], [-365 * 2, '2 Years'], [0, 'All']].map(function (el) { return el[0] !== 0 && MIN_DATA_POINTS / Math.abs(el[0]) > dataDensity ? null : createControl(el[0], el[1]); }).filter(function (el) { return el !== null; }); // Pre-select 'All' option -- chart is zoomed out by default controls[controls.length - 1].classList.add('active'); } function createSrChart(flexchartObject) { var srTableContainer = document.createElement('div'); srTableContainer.className = 'sr-only srTableContainer'; flexchartObject.chart.container.appendChild(srTableContainer); var srTable = document.createElement('table'); srTableContainer.appendChild(srTable); var tableCaption = document.createElement('caption'); var tableCaptionText = void 0; if (document.body.classList.contains('sys-flexchart')) { tableCaptionText = document.createTextNode(document.querySelector('h1').innerText); } else { var chartTitles = document.querySelectorAll('.feat--list__header'); chartTitles.forEach(function (element) { if (element.parentElement.contains(flexchartObject.chart.container)) { tableCaptionText = document.createTextNode(element.querySelector('h2').innerText); } }); } tableCaption.appendChild(tableCaptionText); srTable.appendChild(tableCaption); flexchartObject.chart.data.lines.forEach(function (chart) { var rowHeader = document.createElement('th'); rowHeader.setAttribute('scope', 'row'); var rowHeaderText = document.createTextNode(chart.title); rowHeader.appendChild(rowHeaderText); var lineRow = document.createElement('tr'); srTable.appendChild(lineRow); lineRow.appendChild(rowHeader); chart.points.forEach(function (dataPointValue) { var dataPoint = document.createElement('td'); var dataPointUnits = flexchartObject.chart.options.unitFormat.includes('%') ? '%' : ''; var dataPointDate = flexchartObject.chart.data.labelsLookup[dataPointValue.x]; var dataPointText = document.createTextNode('' + dataPointValue.y + dataPointUnits + ' on ' + dataPointDate); dataPoint.appendChild(dataPointText); lineRow.appendChild(dataPoint); }); }); } function createChart(flexchartObject) { var LineChart = window.gel.dataviz.LineChart; var parser = new DOMParser(); var dom = parser.parseFromString(flexchartObject.datasetXml, 'text/xml'); var dataset = dom.querySelector('data set'); var codename = dom.querySelector('visualization').getAttribute('codename'); var prefix = dataset.querySelector('c sc pre'); var suffix = dataset.querySelector('c sc suf'); var unitFormat = (prefix ? prefix.textContent : '') + '{y}' + (suffix ? suffix.textContent : ''); var labels = queryAll(dataset, 'rs r').map(function (r) { return ( // Prefer "ed" (end date) over "sd" (start date) -- DOTCOMF-3771 r.getAttribute('ed') || r.getAttribute('sd') ); }); var lines = []; queryAll(dataset, 'c').forEach(function (c) { var id = c.getAttribute('ci'); var points = []; queryAll(dataset, 'rs p[ci="' + id + '"]').forEach(function (p) { var y = parseFloat(p.textContent); points.push(isNaN(y) ? null : y); // eslint-disable-line no-restricted-globals }); lines.push({ id: id, points: points, title: c.querySelector('l').textContent }); }); if (codename === 'USCONSPDNG112723') { var getRange = function getRange(values) { return Math.max.apply(null, values) - Math.min.apply(null, values); }; lines.sort(function (a, b) { return getRange(b.points.map(function (p) { return p.y; })) - getRange(a.points.map(function (p) { return p.y; })); }); } else { lines.sort(function (a, b) { return a.id - b.id; }); } var container = document.querySelector(flexchartObject.container); var chartContainer = document.createElement('div'); chartContainer.className = 'chart-container'; container.appendChild(chartContainer); flexchartObject.chart = new LineChart(chartContainer, { labels: labels, lines: lines, source: flexchartObject.source || DEFAULT_CHART_SOURCE }, { unitFormat: unitFormat, mode: LineChart.MODE_CUSTOM, height: 300, showHeader: false, showFooter: codename !== 'CN482' }); createSrChart(flexchartObject); createZoomControls(flexchartObject); } function callAjax(flexchartObject) { // Load flex chart data set ajax({ method: 'GET', url: flexchartObject.datasetUrl, success: function success(response) { flexchartObject.datasetLoaded = true; flexchartObject.datasetXml = response; if (datavizLoaded) createChart(flexchartObject); } }); } // Check global namespace for flexchart data set URL if (window.wwwV8.flexchart) { // Load dataviz library $LAB.script('/Gel-Github/dataviz/dataviz.js').wait(function () { datavizLoaded = true; if (Array.isArray(window.wwwV8.flexchart)) { window.wwwV8.flexchart.forEach(function (flexchart) { if (flexchart.datasetLoaded) { createChart(flexchart); } }); } else if (window.wwwV8.flexchart.datasetLoaded) { createChart(window.wwwV8.flexchart); } }); if (Array.isArray(window.wwwV8.flexchart)) { window.wwwV8.flexchart.forEach(function (flexchart) { callAjax(flexchart); }); } else { callAjax(window.wwwV8.flexchart); } } var gelAutocomplete = createCommonjsModule(function (module) { (function (root, factory) { if (module.exports) { // Node. Does not work with strict CommonJS, but // only CommonJS-like enviroments that support module.exports, // like Node. module.exports = factory(); } else { // Browser globals root.gel = root.gel || {}; root.gel.autocomplete = factory(); } }(commonjsGlobal, function () { /* ** Constructor */ return function Autocomplete(options) { // Some error checking if (!options) { console.log('Error: No options object passed'); return; } if (!options.hasOwnProperty('element') || !(options.element instanceof Element)) { console.log('Error: Invalid input element provided'); return; } if (!options.hasOwnProperty('source') || (!Array.isArray(options.source) && typeof options.source !== 'function')) { console.log('Error: Invalid source provided -- must be an array or function'); return; } /* ** Private variables */ var self = this; var cache; var cachedQuery; var isHidden; var suggestionsCount; var delayTimeout; // DOM elements self.element = options.element; self.container = options.hasOwnProperty('container') && options.container instanceof Element ? options.container : null; self.suggestionsList = document.createElement('ul'); // Data source self.source = options.source; self.sourceIsStatic = Array.isArray(options.source); // Options self.cssClass = options.hasOwnProperty('cssClass') ? options.cssClass : null; self.delay = options.hasOwnProperty('delay') ? options.delay : (self.sourceIsStatic ? 0 : 250); self.minCharacters = options.hasOwnProperty('minCharacters') ? options.minCharacters : 1; self.hideOnOutsideClick = options.hasOwnProperty('hideOnOutsideClick') ? options.hideOnOutsideClick : true; self.maxSuggestions = options.hasOwnProperty('maxSuggestions') ? options.maxSuggestions : -1; self.maxSuggestionsDisplayed = options.hasOwnProperty('maxSuggestionsDisplayed') ? options.maxSuggestionsDisplayed : -1; self.exactMatch = options.hasOwnProperty('exactMatch') ? options.exactMatch : true; self.selfPosition = options.hasOwnProperty('selfPosition') ? options.selfPosition : false; // Read-only properties Object.defineProperty(self, 'isHidden', { get: function () { return isHidden; } }); Object.defineProperty(self, 'suggestionsCount', { get: function () { return suggestionsCount; } }); /* ** Public methods */ self.init = function() { // Initialize private variables cache = {}; cachedQuery = ''; suggestionsCount = 0; // Wire up element event listeners self.element.addEventListener('keydown', keydown); self.element.addEventListener('keyup', keyup); self.element.addEventListener('focus', focus); if (self.hideOnOutsideClick) { document.addEventListener('click', documentClick); } // If we're self-positioning, ignore any specified container (we need to attach to the

ÓÅÃÛ´«Ã½

) if (self.selfPosition) { self.container = document.createElement('div'); document.body.appendChild(self.container); self.container.style.position = 'absolute'; self.reposition(); window.addEventListener('resize', windowResize); } // Otherwise, if no container was specified, create one else if (!self.container) { var wrapper = document.createElement('div'); wrapper.className = 'gel-autocomplete-wrapper'; self.element.parentElement.insertBefore(wrapper, self.element); wrapper.appendChild(self.element); self.container = document.createElement('div'); wrapper.appendChild(self.container); } self.container.classList.add('gel-autocomplete'); if (typeof self.cssClass === 'string') { self.container.classList.add(self.cssClass); } self.container.appendChild(self.suggestionsList); self.hide(); }; self.destroy = function() { // Remove event listeners self.element.removeEventListener('keydown', keydown); self.element.removeEventListener('keyup', keyup); self.element.removeEventListener('focus', focus); document.removeEventListener('click', documentClick); // Remove suggestions list element self.container.removeChild(self.suggestionsList); }; // Displays suggestions list self.show = function() { if (!isHidden || suggestionsCount < 1) return; self.suggestionsList.style.display = ''; self.suggestionsList.setAttribute('aria-hidden', false); isHidden = false; self.reposition(); fireEvent(self.suggestionsList, 'gel.ac.show'); }; // Hides suggestions list self.hide = function() { if (isHidden) return; self.suggestionsList.style.display = 'none'; self.suggestionsList.setAttribute('aria-hidden', true); isHidden = true; fireEvent(self.suggestionsList, 'gel.ac.hide'); }; // Updates suggestions list with suggestions array passed as a parameter self.update = function(suggestions) { if (!suggestions || suggestions.length < 1) { self.clearSuggestions(); return; } if (!Array.isArray(suggestions)) { console.log('Error: Invalid suggestions array'); return; } // Update cache cache[cachedQuery] = suggestions; if (self.maxSuggestionsDisplayed > 0) { suggestions = suggestions.slice(0, self.maxSuggestionsDisplayed); } var objectArray = typeof suggestions[0] === 'object'; // Clear the current suggestions self.suggestionsList.innerHTML = ''; // Build the markup for each suggestion suggestions.forEach(function(suggestion) { var li = document.createElement('li'); if (objectArray) { li.setAttribute('data-autocomplete-value', suggestion.value); if (suggestion.hasOwnProperty('domain')) { li.setAttribute('data-companyDomain',suggestion.domain); } if (suggestion.hasOwnProperty('href')) { var anchor = document.createElement('a'); anchor.href = suggestion.href; anchor.innerHTML = suggestion.label; li.appendChild(anchor); } else { li.innerHTML = suggestion.label; } } else { li.setAttribute('data-autocomplete-value', suggestion); li.innerHTML = suggestion; } li.addEventListener('click', function(e) { self.select(this); }); li.addEventListener('mouseenter', function(e) { self.highlight(this); }); self.suggestionsList.appendChild(li); }); suggestionsCount = suggestions.length; if (document.activeElement === self.element) { self.show(); } fireEvent(self.suggestionsList, 'gel.ac.update'); }; // Selects a suggestion self.select = function(item) { var anchor = item.querySelector('a[href]'); var domain = item.getAttribute('data-companyDomain'); if (anchor) { window.location = anchor.href; } else { if (domain) { self.element.value = item.getAttribute('data-autocomplete-value'); cachedQuery = item.getAttribute('data-autocomplete-value'); self.clearSuggestions(); document.getElementById('companyDomain').value = domain; } self.element.value = item.getAttribute('data-autocomplete-value'); cachedQuery = item.getAttribute('data-autocomplete-value'); self.clearSuggestions(); } fireEvent(item, 'gel.ac.itemselect'); }; // Highlights a suggestion self.highlight = function(item) { self.clearHighlighted(); item.classList.add('highlighted'); fireEvent(item, 'gel.ac.itemhighlight'); }; // Clears highlighted suggestion self.clearHighlighted = function() { Array.prototype.forEach.call(self.suggestionsList.querySelectorAll('.highlighted'), function (el) { el.classList.remove('highlighted'); }); }; // Clears suggestions list self.clearSuggestions = function() { self.suggestionsList.innerHTML = ''; suggestionsCount = 0; self.hide(); }; self.reposition = function() { if (!self.selfPosition || isHidden) return; var offset = getPageOffset(self.element); self.container.style.left = offset.left + 'px'; self.container.style.top = (offset.top + self.element.offsetHeight) + 'px'; self.container.style.width = self.element.offsetWidth + 'px'; fireEvent(self.container, 'gel.ac.reposition'); }; /* ** Private methods */ // onkeydown listener for the input element -- handles navigating suggestions with the keyboard function keydown(e) { if (suggestionsCount < 1 || [38, 40, 13, 9].indexOf(e.which) < 0) { return; } var highlighted = self.suggestionsList.querySelector('.highlighted'); if (e.which === 38) { // up arrow if (highlighted && highlighted.previousElementSibling) { self.highlight(highlighted.previousElementSibling); } else { self.highlight(self.suggestionsList.lastElementChild); } e.preventDefault(); } else if (e.which === 40) { // down arrow if (highlighted && highlighted.nextElementSibling) { self.highlight(highlighted.nextElementSibling); } else { self.highlight(self.suggestionsList.firstElementChild); } e.preventDefault(); } else if (e.which === 13) { // enter if (highlighted) { self.select(highlighted); e.preventDefault(); } } else if (e.which == 9) { // tab self.hide(); } } // onkeyup listener for the input element -- gets new suggestions if the user input has changed function keyup(e) { var q = self.element.value; // Don't do anything if the query hasn't changed if (cachedQuery === q) { return; } cachedQuery = q; if (q.length >= self.minCharacters) { // If we have this query cached, use the cache var suggestions = getCachedSuggestions(q); if (suggestions) { self.update(suggestions); } else { clearTimeout(delayTimeout); delayTimeout = setTimeout(function () { if (self.sourceIsStatic) { self.update(getSuggestions(q)); } else { self.source(q, self.update); } }, self.delay); } } else { self.update(); } } // onfocus listener for the input element function focus(e) { self.show(); } // onclick listener for the document function documentClick(e) { if (e.target !== self.element && !self.container.contains(e.target)) { self.hide(); } } // onresize listener for the window var windowResize = debounce(function() { self.reposition(); }, 100); // Searches source array for matches for a given query -- only used if source is a static array function getSuggestions(q, source) { var source = source || self.source; if (source.length < 1) { return []; } var regex = new RegExp(q, 'i'); if (typeof source[0] === 'string') { return source.filter(function (value) { return regex.test(value); }); } else { return source.filter(function (value) { return regex.test(value.label); }); } } // Returns cached suggestions for the given query if a relevant cache can be found function getCachedSuggestions(q) { // If we've run this exact query before, reuse the suggestions if (cache[q]) { return cache[q]; } // If the server doesn't return only exact matches, we can't emulate it using the cache if (!self.exactMatch) { return null; } // Otherwise, try to find a cached superset of suggestions var tempCache; var prevLength; var lastRelevantCache; for (var i = 0; i < q.length; i++) { tempCache = cache[q.slice(0, i + 1)]; if (!tempCache) break; // Only use the cached suggestions if the length is less than the max the server returns // or less than the length of the previous cache (which would mean it must be less than the // max returned by the server). This ensures there are not additional suggestions that are // not in the cache. if (tempCache.length < self.maxSuggestions || tempCache.length < prevLength) { lastRelevantCache = tempCache; prevLength = tempCache.length; } else if (typeof prevLength === 'undefined') { prevLength = tempCache.length; } else { break; } } return lastRelevantCache ? getSuggestions(q, lastRelevantCache) : null; } // Auto-initialize self.init(); }; /* ** Private helper functions */ function fireEvent(el, eventName) { var event = document.createEvent('Event'); event.initEvent(eventName, true, true); el.dispatchEvent(event); } function getPageOffset(el) { var top = 0; var left = 0; if (el.offsetParent) { do { top += el.offsetTop; left += el.offsetLeft; } while (el = el.offsetParent); } return { top: top, left: left }; } // https://davidwalsh.name/javascript-debounce-function function debounce(func, wait, immediate) { var timeout; return function() { var context = this, args = arguments; var later = function() { timeout = null; if (!immediate) func.apply(context, args); }; var callNow = immediate && !timeout; clearTimeout(timeout); timeout = setTimeout(later, wait); if (callNow) func.apply(context, args); }; } })); }); /** Autocomplete * Looks for elements with `data-autocomplete-source` attribute. Sets up an instance of * GEL Autocomplete using the URL speficied by the value of `data-autocomplete-source` as * a data source for suggestions. * * Also creates instance of GEL Autocomplete for search on ÓÅÃÛ´«Ã½News to display suggested * topics. * * Example uses: * - The "organization" field on many contact forms (e.g. http://www.gallup.com/contact.aspx) * - The suggested topics feature of search on ÓÅÃÛ´«Ã½News (http://news.gallup.com/) */ function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string } function getSuggestions(url, params, callback) { ajax({ url: url, method: 'POST', contentType: 'application/json; charset=utf-8', params: JSON.stringify(params), success: function success(response) { var suggestions = JSON.parse(response).d; callback(suggestions); } }); } function getClearbitSuggestions(url, params, callback) { ajax({ url: url, method: 'GET', contentType: 'application/json; charset=utf-8', params: params, success: function success(response) { var suggestions = JSON.parse(response); suggestions = suggestions.map(function (e) { return { value: e.name, label: e.name, domain: e.domain }; }); callback(suggestions); } }); } function setup$1(el) { if (el.hasAttribute('data-autocomplete-simple')) { el.addEventListener('focus', function () { if (!el.hasAttribute('data-autocomplete-initialized')) { getSuggestions(el.getAttribute('data-autocomplete-source'), {}, function (topics) { var suggestions = topics.map(function (topic) { return { value: topic.label, label: topic.label, href: '/topic/' + topic.value + '.aspx' }; }); // eslint-disable-next-line no-new new gelAutocomplete({ element: el, container: document.querySelector(el.getAttribute('data-autocomplete-container')), source: suggestions, maxSuggestionsDisplayed: 15 }); el.setAttribute('data-autocomplete-initialized', true); }); } }); } else if (el.hasAttribute('data-autocomplete-clearbit')) { // eslint-disable-next-line no-new new gelAutocomplete({ element: el, selfPosition: true, cssClass: 'form-autocomplete', source: function source(query, callback) { getClearbitSuggestions(el.getAttribute('data-autocomplete-source'), { query: query }, callback); } }); } else { // eslint-disable-next-line no-new new gelAutocomplete({ element: el, selfPosition: true, cssClass: 'form-autocomplete', source: function source(q, callback) { getSuggestions(el.getAttribute('data-autocomplete-source'), { q: q }, callback); } }); } } queryAll(document, '[data-autocomplete-source]').forEach(setup$1); // Set up suggested topics for search overlay var searchOverlay = document.querySelector('.c-search-overlay'); if (searchOverlay && (document.body.classList.contains('sit-newsv9') || document.body.classList.contains('sit-wwwv9'))) { var loadedSuggestedTopics = false; searchOverlay.addEventListener('gel.search.show', function () { if (loadedSuggestedTopics) return; getSuggestions('/Search/topics.aspx', {}, function (topics) { window.gel.search.setSuggestionsProvider(function (q, cb) { if (q.length < 2) { cb(''); } else { var regex = new RegExp(escapeRegExp(q), 'i'); var suggestions = topics.filter(function (topic) { return regex.test(topic.label); }).map(function (item) { return '\n
  • \n \n ' + item.label.replace(regex, '$&') + '\n \n
  • \n '; }).slice(0, 15).join(''); cb(suggestions); } }); loadedSuggestedTopics = true; }); }); } /** Accordion tabs * Looks for cards matching `.rel-cardsrvc`. For any accordions (series of Bootstrap collapses) * found inside the card, creates a second toggle for it and adds it to a row of tab headers. * * Example use: http://www.gallup.com/workplace/215375/gallup-analytics-based-hiring.aspx */ function updateActiveTab(tabs, active, toggle) { // Remove active class from current tab var current = tabs.querySelector('.active'); if (current) { current.classList.remove('active'); current.querySelector('[aria-expanded]').setAttribute('aria-expanded', 'false'); } if (toggle.classList.contains('collapsed')) { active.classList.add('active'); active.querySelector('[aria-expanded]').setAttribute('aria-expanded', 'true'); } else { active.classList.remove('active'); } } queryAll(document, '.rel-cardsrvc').forEach(function (card) { var tabs = document.createElement('ul'); tabs.className = 'cardsrvc-tabs'; var inlineHeader = card.querySelector('.cardsrvc-inline__header'); if (card.classList.contains('cardsrvc-inline') && inlineHeader) { inlineHeader.appendChild(tabs); } else { card.insertBefore(tabs, card.querySelector('.cardsrvc-content')); } var verticalTabs = queryAll(card, '.cardsrvc-vertical-tab'); if (verticalTabs.length > 0) { card.classList.add('cardsrvc-vertical'); var listItem1 = document.createElement('li'); var tabHeader = card.querySelector('.cardsrvc-title'); if (tabHeader !== null) { tabs.appendChild(listItem1); listItem1.appendChild(tabHeader.cloneNode(true)); } } var accordionToggles = queryAll(card, '.cardsrvc-acc-tab [data-toggle="collapse"]'); accordionToggles.forEach(function (toggle, index) { var isSideNavScroll = card.classList.contains('c-tabs-vertical--sidenav--scroll'); var listItem = document.createElement('li'); var tab = toggle.cloneNode(true); tabs.appendChild(listItem); listItem.appendChild(tab); if (isSideNavScroll) { var contentCard = document.querySelector('#' + tab.attributes['aria-controls'].value); document.addEventListener('scroll', function () { var boundingBox = contentCard.getBoundingClientRect(); if (boundingBox.top < 70 && boundingBox.bottom > 70 && !listItem.classList.contains('active')) { tabs.querySelectorAll('li').forEach(function (tabItem) { tabItem.classList.remove('active'); }); listItem.classList.add('active'); } }, false); tab.removeAttribute('data-toggle'); tab.removeAttribute('data-duration'); tab.removeAttribute('data-parent'); tab.addEventListener('click', function (e) { e.preventDefault(); scrollToElement(contentCard); }); } else { // Add unique ID's to both accordion toggle and tab header // for Google Analytics tracking purposes var title = toggle.textContent.replace(/[^a-z0-9]/gi, ''); var cmsID = (toggle.getAttribute('aria-controls') || '').replace('cardsrvc-', ''); toggle.id = 'Accord-' + title + '-' + cmsID; // eslint-disable-line no-param-reassign tab.id = 'Tab-' + title + '-' + cmsID; var ariaID = 'AriaTab-' + title + '-' + cmsID; tab.setAttribute('aria-describedby', ariaID); var tabDesctiption = document.querySelector('#cardsrvc-' + cmsID + ' .cardsrvc-main'); tabDesctiption.id = ariaID; tab.addEventListener('click', function (e) { // Prevent scrolling to anchor e.preventDefault(); // Don't do anything if the tab is already selected if (listItem.classList.contains('active')) return; toggle.click(); updateActiveTab(tabs, listItem, toggle); tiles.blazyInstance.revalidate(); }); } // Show first tab by default if (index === 0) { toggle.click(); updateActiveTab(tabs, listItem, toggle); } toggle.addEventListener('click', function () { // Scroll content into view on mobile if (toggle.classList.contains('collapsed') && document.documentElement.clientWidth < 960) { var _toggle$getBoundingCl = toggle.getBoundingClientRect(), top = _toggle$getBoundingCl.top; var _document$querySelect = document.querySelector('#' + toggle.getAttribute('aria-controls')).getBoundingClientRect(), bottom = _document$querySelect.bottom; if (top < 0 || bottom > document.documentElement.clientHeight) { setTimeout(function () { scrollToElement(toggle); }, 10); } } accordionToggles.forEach(function (t) { if (toggle !== t) { t.classList.remove('collapsed'); } }); updateActiveTab(tabs, listItem, toggle); tiles.blazyInstance.revalidate(); }); }); }); /** Timeline tabs * Creates a timeline from a collection of Bootstrap collapses on a card landing page. * * Example use: http://www.gallup.com/education/227672/about.aspx */ function createTabTimelineControls(tabTimelineControls, tabButtons, currentIndex) { // Creates the previous button var prevControl = document.createElement('button'); var prevControlSr = tabButtons[Math.max(currentIndex - 1, 0)]; prevControlSr = prevControlSr.querySelector('h2').textContent; prevControl.className = 'tab-timeline__control-prev'; prevControl.innerHTML = '\n Go to ' + prevControlSr + ''; // Creates the next button var nextControl = document.createElement('button'); var nextControlSr = tabButtons[Math.min(currentIndex + 1, tabButtons.length - 1)]; nextControlSr = nextControlSr.querySelector('h2').textContent; nextControl.className = 'tab-timeline__control-next'; nextControl.innerHTML = '\n Go to ' + nextControlSr + ''; // Assign on click prevControl.addEventListener('click', function () { tabButtons[currentIndex - 1].click(); }); // Assign on click nextControl.addEventListener('click', function () { tabButtons[currentIndex + 1].click(); }); tabTimelineControls.textContent = ''; if (currentIndex !== 0) { tabTimelineControls.appendChild(prevControl); } if (currentIndex !== tabButtons.length - 1) { tabTimelineControls.appendChild(nextControl); } } function timelineProgressHandler(elm, i, progress) { elm.setAttribute('data-current-index', i); elm.addEventListener('click', function () { progress.setAttribute('data-current-index', i); emit(progress, 'CHANGE_INDEX'); }); } if (document.querySelector('.l-clp--tab-timeline') !== null) { // Find the accordions sections on the page queryAll(document, '.rel-cardsrvc').forEach(function (section) { var sectionCurrentIndex = 0; // ul tabs section var tabSection = section.querySelector('.cardsrvc-tabs'); // anchors inside of the tab section var tabButtons = queryAll(tabSection, '.cardsrvc-accordion'); // toggle links inside of section var accordionToggles = queryAll(section, '.cardsrvc-acc-tab [data-toggle="collapse"]'); // new div var tabTimelineLine = document.createElement('div'); // new div var tabTimelineLineProgress = document.createElement('div'); // new div var tabTimelineControls = document.createElement('div'); // Adds timeline specific class names tabSection.classList.add('cardsrvc-tabs--timeline'); tabTimelineLine.classList.add('tab-timeline__line'); tabTimelineLineProgress.classList.add('tab-timeline__line-progress'); tabTimelineControls.classList.add('tab-timeline__controls'); tabTimelineLineProgress.addEventListener('CHANGE_INDEX', function (e) { var currentIndex = Number(e.target.dataset.currentIndex); var tabSectionWidth = tabSection.offsetWidth; var tabButtonWidth = tabButtons[currentIndex].offsetWidth; var spaceBetween = (tabSectionWidth - tabButtonWidth * tabButtons.length) / (tabButtons.length - 1); var progressWidth = void 0; sectionCurrentIndex = currentIndex; if (tabSectionWidth === 0 || tabButtonWidth === 0) { // TabSection and tabButtonWidth are hidden because of mobile view progressWidth = currentIndex / tabButtons.length * 100; } else if (currentIndex === 0) { progressWidth = 0; } else if (currentIndex + 1 === tabButtons.length) { progressWidth = 100; } else { progressWidth = tabButtonWidth * currentIndex + spaceBetween * currentIndex + tabButtonWidth / 2; progressWidth = progressWidth / tabSectionWidth * 100; } e.target.style.width = progressWidth + '%'; tabButtons.forEach(function (button) { if (button.dataset.currentIndex < currentIndex) { button.classList.add('past-date'); } else { button.classList.remove('past-date'); } }); createTabTimelineControls(tabTimelineControls, tabButtons, currentIndex); }); // Append progress inside of the tabtimeLine tabTimelineLine.appendChild(tabTimelineLineProgress); // Insert tabtimeLine after tabs tabSection.insertAdjacentElement('afterend', tabTimelineLine); // Create TimelineControls createTabTimelineControls(tabTimelineControls, tabButtons, sectionCurrentIndex); // Insert controls after tabtimeline tabTimelineLine.insertAdjacentElement('afterend', tabTimelineControls); // attach handler to each button tabButtons.forEach(function (tab, i) { timelineProgressHandler(tab, i, tabTimelineLineProgress); }); // attach handler to each toggle accordionToggles.forEach(function (toggle, i) { timelineProgressHandler(toggle, i, tabTimelineLineProgress); }); }); } /** * Checks if `value` is the * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an object, else `false`. * @example * * _.isObject({}); * // => true * * _.isObject([1, 2, 3]); * // => true * * _.isObject(_.noop); * // => true * * _.isObject(null); * // => false */ function isObject(value) { var type = typeof value; return value != null && (type == 'object' || type == 'function'); } var isObject_1 = isObject; /** Detect free variable `global` from Node.js. */ var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal; var _freeGlobal = freeGlobal; /** Detect free variable `self`. */ var freeSelf = typeof self == 'object' && self && self.Object === Object && self; /** Used as a reference to the global object. */ var root = _freeGlobal || freeSelf || Function('return this')(); var _root = root; /** * Gets the timestamp of the number of milliseconds that have elapsed since * the Unix epoch (1 January 1970 00:00:00 UTC). * * @static * @memberOf _ * @since 2.4.0 * @category Date * @returns {number} Returns the timestamp. * @example * * _.defer(function(stamp) { * console.log(_.now() - stamp); * }, _.now()); * // => Logs the number of milliseconds it took for the deferred invocation. */ var now = function() { return _root.Date.now(); }; var now_1 = now; /** Used to match a single whitespace character. */ var reWhitespace = /\s/; /** * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace * character of `string`. * * @private * @param {string} string The string to inspect. * @returns {number} Returns the index of the last non-whitespace character. */ function trimmedEndIndex(string) { var index = string.length; while (index-- && reWhitespace.test(string.charAt(index))) {} return index; } var _trimmedEndIndex = trimmedEndIndex; /** Used to match leading whitespace. */ var reTrimStart = /^\s+/; /** * The base implementation of `_.trim`. * * @private * @param {string} string The string to trim. * @returns {string} Returns the trimmed string. */ function baseTrim(string) { return string ? string.slice(0, _trimmedEndIndex(string) + 1).replace(reTrimStart, '') : string; } var _baseTrim = baseTrim; /** Built-in value references. */ var Symbol$1 = _root.Symbol; var _Symbol = Symbol$1; /** Used for built-in method references. */ var objectProto = Object.prototype; /** Used to check objects for own properties. */ var hasOwnProperty = objectProto.hasOwnProperty; /** * Used to resolve the * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) * of values. */ var nativeObjectToString = objectProto.toString; /** Built-in value references. */ var symToStringTag = _Symbol ? _Symbol.toStringTag : undefined; /** * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. * * @private * @param {*} value The value to query. * @returns {string} Returns the raw `toStringTag`. */ function getRawTag(value) { var isOwn = hasOwnProperty.call(value, symToStringTag), tag = value[symToStringTag]; try { value[symToStringTag] = undefined; } catch (e) {} var result = nativeObjectToString.call(value); { if (isOwn) { value[symToStringTag] = tag; } else { delete value[symToStringTag]; } } return result; } var _getRawTag = getRawTag; /** Used for built-in method references. */ var objectProto$1 = Object.prototype; /** * Used to resolve the * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) * of values. */ var nativeObjectToString$1 = objectProto$1.toString; /** * Converts `value` to a string using `Object.prototype.toString`. * * @private * @param {*} value The value to convert. * @returns {string} Returns the converted string. */ function objectToString(value) { return nativeObjectToString$1.call(value); } var _objectToString = objectToString; /** `Object#toString` result references. */ var nullTag = '[object Null]', undefinedTag = '[object Undefined]'; /** Built-in value references. */ var symToStringTag$1 = _Symbol ? _Symbol.toStringTag : undefined; /** * The base implementation of `getTag` without fallbacks for buggy environments. * * @private * @param {*} value The value to query. * @returns {string} Returns the `toStringTag`. */ function baseGetTag(value) { if (value == null) { return value === undefined ? undefinedTag : nullTag; } return (symToStringTag$1 && symToStringTag$1 in Object(value)) ? _getRawTag(value) : _objectToString(value); } var _baseGetTag = baseGetTag; /** * Checks if `value` is object-like. A value is object-like if it's not `null` * and has a `typeof` result of "object". * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is object-like, else `false`. * @example * * _.isObjectLike({}); * // => true * * _.isObjectLike([1, 2, 3]); * // => true * * _.isObjectLike(_.noop); * // => false * * _.isObjectLike(null); * // => false */ function isObjectLike(value) { return value != null && typeof value == 'object'; } var isObjectLike_1 = isObjectLike; /** `Object#toString` result references. */ var symbolTag = '[object Symbol]'; /** * Checks if `value` is classified as a `Symbol` primitive or object. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. * @example * * _.isSymbol(Symbol.iterator); * // => true * * _.isSymbol('abc'); * // => false */ function isSymbol(value) { return typeof value == 'symbol' || (isObjectLike_1(value) && _baseGetTag(value) == symbolTag); } var isSymbol_1 = isSymbol; /** Used as references for various `Number` constants. */ var NAN = 0 / 0; /** Used to detect bad signed hexadecimal string values. */ var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; /** Used to detect binary string values. */ var reIsBinary = /^0b[01]+$/i; /** Used to detect octal string values. */ var reIsOctal = /^0o[0-7]+$/i; /** Built-in method references without a dependency on `root`. */ var freeParseInt = parseInt; /** * Converts `value` to a number. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to process. * @returns {number} Returns the number. * @example * * _.toNumber(3.2); * // => 3.2 * * _.toNumber(Number.MIN_VALUE); * // => 5e-324 * * _.toNumber(Infinity); * // => Infinity * * _.toNumber('3.2'); * // => 3.2 */ function toNumber(value) { if (typeof value == 'number') { return value; } if (isSymbol_1(value)) { return NAN; } if (isObject_1(value)) { var other = typeof value.valueOf == 'function' ? value.valueOf() : value; value = isObject_1(other) ? (other + '') : other; } if (typeof value != 'string') { return value === 0 ? value : +value; } value = _baseTrim(value); var isBinary = reIsBinary.test(value); return (isBinary || reIsOctal.test(value)) ? freeParseInt(value.slice(2), isBinary ? 2 : 8) : (reIsBadHex.test(value) ? NAN : +value); } var toNumber_1 = toNumber; /** Error message constants. */ var FUNC_ERROR_TEXT = 'Expected a function'; /* Built-in method references for those with the same name as other `lodash` methods. */ var nativeMax = Math.max, nativeMin = Math.min; /** * Creates a debounced function that delays invoking `func` until after `wait` * milliseconds have elapsed since the last time the debounced function was * invoked. The debounced function comes with a `cancel` method to cancel * delayed `func` invocations and a `flush` method to immediately invoke them. * Provide `options` to indicate whether `func` should be invoked on the * leading and/or trailing edge of the `wait` timeout. The `func` is invoked * with the last arguments provided to the debounced function. Subsequent * calls to the debounced function return the result of the last `func` * invocation. * * **Note:** If `leading` and `trailing` options are `true`, `func` is * invoked on the trailing edge of the timeout only if the debounced function * is invoked more than once during the `wait` timeout. * * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred * until to the next tick, similar to `setTimeout` with a timeout of `0`. * * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) * for details over the differences between `_.debounce` and `_.throttle`. * * @static * @memberOf _ * @since 0.1.0 * @category Function * @param {Function} func The function to debounce. * @param {number} [wait=0] The number of milliseconds to delay. * @param {Object} [options={}] The options object. * @param {boolean} [options.leading=false] * Specify invoking on the leading edge of the timeout. * @param {number} [options.maxWait] * The maximum time `func` is allowed to be delayed before it's invoked. * @param {boolean} [options.trailing=true] * Specify invoking on the trailing edge of the timeout. * @returns {Function} Returns the new debounced function. * @example * * // Avoid costly calculations while the window size is in flux. * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); * * // Invoke `sendMail` when clicked, debouncing subsequent calls. * jQuery(element).on('click', _.debounce(sendMail, 300, { * 'leading': true, * 'trailing': false * })); * * // Ensure `batchLog` is invoked once after 1 second of debounced calls. * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 }); * var source = new EventSource('/stream'); * jQuery(source).on('message', debounced); * * // Cancel the trailing debounced invocation. * jQuery(window).on('popstate', debounced.cancel); */ function debounce$1(func, wait, options) { var lastArgs, lastThis, maxWait, result, timerId, lastCallTime, lastInvokeTime = 0, leading = false, maxing = false, trailing = true; if (typeof func != 'function') { throw new TypeError(FUNC_ERROR_TEXT); } wait = toNumber_1(wait) || 0; if (isObject_1(options)) { leading = !!options.leading; maxing = 'maxWait' in options; maxWait = maxing ? nativeMax(toNumber_1(options.maxWait) || 0, wait) : maxWait; trailing = 'trailing' in options ? !!options.trailing : trailing; } function invokeFunc(time) { var args = lastArgs, thisArg = lastThis; lastArgs = lastThis = undefined; lastInvokeTime = time; result = func.apply(thisArg, args); return result; } function leadingEdge(time) { // Reset any `maxWait` timer. lastInvokeTime = time; // Start the timer for the trailing edge. timerId = setTimeout(timerExpired, wait); // Invoke the leading edge. return leading ? invokeFunc(time) : result; } function remainingWait(time) { var timeSinceLastCall = time - lastCallTime, timeSinceLastInvoke = time - lastInvokeTime, timeWaiting = wait - timeSinceLastCall; return maxing ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke) : timeWaiting; } function shouldInvoke(time) { var timeSinceLastCall = time - lastCallTime, timeSinceLastInvoke = time - lastInvokeTime; // Either this is the first call, activity has stopped and we're at the // trailing edge, the system time has gone backwards and we're treating // it as the trailing edge, or we've hit the `maxWait` limit. return (lastCallTime === undefined || (timeSinceLastCall >= wait) || (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait)); } function timerExpired() { var time = now_1(); if (shouldInvoke(time)) { return trailingEdge(time); } // Restart the timer. timerId = setTimeout(timerExpired, remainingWait(time)); } function trailingEdge(time) { timerId = undefined; // Only invoke if we have `lastArgs` which means `func` has been // debounced at least once. if (trailing && lastArgs) { return invokeFunc(time); } lastArgs = lastThis = undefined; return result; } function cancel() { if (timerId !== undefined) { clearTimeout(timerId); } lastInvokeTime = 0; lastArgs = lastCallTime = lastThis = timerId = undefined; } function flush() { return timerId === undefined ? result : trailingEdge(now_1()); } function debounced() { var time = now_1(), isInvoking = shouldInvoke(time); lastArgs = arguments; lastThis = this; lastCallTime = time; if (isInvoking) { if (timerId === undefined) { return leadingEdge(lastCallTime); } if (maxing) { // Handle invocations in a tight loop. clearTimeout(timerId); timerId = setTimeout(timerExpired, wait); return invokeFunc(lastCallTime); } } if (timerId === undefined) { timerId = setTimeout(timerExpired, wait); } return result; } debounced.cancel = cancel; debounced.flush = flush; return debounced; } var debounce_1 = debounce$1; /** Error message constants. */ var FUNC_ERROR_TEXT$1 = 'Expected a function'; /** * Creates a throttled function that only invokes `func` at most once per * every `wait` milliseconds. The throttled function comes with a `cancel` * method to cancel delayed `func` invocations and a `flush` method to * immediately invoke them. Provide `options` to indicate whether `func` * should be invoked on the leading and/or trailing edge of the `wait` * timeout. The `func` is invoked with the last arguments provided to the * throttled function. Subsequent calls to the throttled function return the * result of the last `func` invocation. * * **Note:** If `leading` and `trailing` options are `true`, `func` is * invoked on the trailing edge of the timeout only if the throttled function * is invoked more than once during the `wait` timeout. * * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred * until to the next tick, similar to `setTimeout` with a timeout of `0`. * * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) * for details over the differences between `_.throttle` and `_.debounce`. * * @static * @memberOf _ * @since 0.1.0 * @category Function * @param {Function} func The function to throttle. * @param {number} [wait=0] The number of milliseconds to throttle invocations to. * @param {Object} [options={}] The options object. * @param {boolean} [options.leading=true] * Specify invoking on the leading edge of the timeout. * @param {boolean} [options.trailing=true] * Specify invoking on the trailing edge of the timeout. * @returns {Function} Returns the new throttled function. * @example * * // Avoid excessively updating the position while scrolling. * jQuery(window).on('scroll', _.throttle(updatePosition, 100)); * * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes. * var throttled = _.throttle(renewToken, 300000, { 'trailing': false }); * jQuery(element).on('click', throttled); * * // Cancel the trailing throttled invocation. * jQuery(window).on('popstate', throttled.cancel); */ function throttle(func, wait, options) { var leading = true, trailing = true; if (typeof func != 'function') { throw new TypeError(FUNC_ERROR_TEXT$1); } if (isObject_1(options)) { leading = 'leading' in options ? !!options.leading : leading; trailing = 'trailing' in options ? !!options.trailing : trailing; } return debounce_1(func, wait, { 'leading': leading, 'maxWait': wait, 'trailing': trailing }); } var throttle_1 = throttle; /** InfiniteCarousel * A from scratch implementation of a basic carousel with infinite wrap around * Auto initializes based on the c-carousel-inf class and stores the class * object on the outermost parent * * Example use: https://www.gallup.com/home.aspx */ var CLASS_CAROUSEL = 'c-carousel-inf'; var ATTRIBUTE_STATUS$1 = 'data-infinite-carousel'; var STATUS_INITIALIZED$1 = 'initialized'; var carouselCount = 0; var activeCar = void 0; var eventHandlers$1 = { dragStart: function dragStart(e) { var evt = e || window.event; if (('buttons' in evt && evt.buttons === 1 || e.type === 'touchstart') && !this.animating) { this.slider.style.cursor = 'grabbing'; if (e.type === 'touchstart') { this.initialX = e.touches[0].clientX; this.currentX = this.initialX; this.initialY = e.touches[0].clientY; this.currentY = this.initialY; } else { e.preventDefault(); this.initialX = e.clientX; this.currentX = this.initialX; } this.active = true; this.dragEnabled = null; activeCar = this.el.infiniteCarousel; this.dragTotalH = 0; document.addEventListener('touchend', eventHandlers$1.dragEnd, false); document.addEventListener('touchmove', throttle_1(eventHandlers$1.drag, 30), { passive: false }); document.addEventListener('mouseup', eventHandlers$1.dragEnd, false); document.addEventListener('mousemove', throttle_1(eventHandlers$1.drag, 30), false); } }, drag: function drag(e) { if (activeCar && activeCar.active) { if (e.type !== 'touchmove') { activeCar.dragEnabled = true; } else if (activeCar.dragEnabled === null) { activeCar.dragEnabled = Math.abs(activeCar.initialY - e.touches[0].clientY) < Math.abs(activeCar.initialX - e.touches[0].clientX); } if (activeCar && activeCar.active && activeCar.dragEnabled) { e.preventDefault(); if (e.type === 'touchmove') { activeCar.currentX = e.touches[0].clientX; } else { activeCar.currentX = e.clientX; } activeCar.translateCarousel(activeCar.currentX - activeCar.initialX); activeCar.dragTotalH += Math.abs(activeCar.currentX - activeCar.initialX); activeCar.initialX = activeCar.currentX; } } }, dragEnd: function dragEnd(e) { if (activeCar && activeCar.active) { if (this.dragTotalH > 3) { e.preventDefault(); } if (activeCar.currentX - activeCar.initialX) { activeCar.currentOffset = activeCar.currentOffset + activeCar.currentX - activeCar.initialX; } activeCar.slider.style.cursor = 'grab'; activeCar.active = false; activeCar.dragEnabled = null; activeCar.snapCarousel(); document.removeEventListener('touchend', eventHandlers$1.dragEnd, false); document.removeEventListener('touchmove', eventHandlers$1.drag, { passive: false }); document.removeEventListener('mouseup', eventHandlers$1.dragEnd, false); document.removeEventListener('mousemove', eventHandlers$1.drag, false); } }, itemFocus: function itemFocus(e) { e.preventDefault(); var externalFocus = true; this.items.forEach(function (item) { if (item.contains(e.relatedTarget)) { externalFocus = false; } }); if (!externalFocus || this.order !== 1) { this.animateCarousel(-this.itemWidth, 50); tiles.blazyInstance.revalidate(); } this.slider.scrollLeft = 0; }, windowResize: function windowResize() { if (this.itemWidth !== this.items[0].offsetWidth || this.containerWidth !== this.innerContainer.offsetWidth) { this.itemWidth = this.items[0].offsetWidth; this.containerWidth = this.innerContainer.offsetWidth; if (this.itemWidth * this.itemOffsetCount > this.containerWidth) { this.itemOffsetCount -= Math.ceil((this.itemWidth * this.itemOffsetCount - this.containerWidth) / this.itemWidth); } else if (this.itemWidth * (this.itemOffsetCount + 1) < this.containerWidth) { this.itemOffsetCount += Math.floor((this.containerWidth - this.itemWidth * this.itemOffsetCount) / this.itemWidth); } this.translateCarousel(0); } } }; var InfiniteCarousel = function () { function InfiniteCarousel(el) { var _this = this; classCallCheck(this, InfiniteCarousel); this.el = el; this.active = false; this.dragEnabled = null; this.animating = false; this.currentOffset = 0; this.slider = this.el.querySelector('.c-carousel-inf__container'); this.innerContainer = this.slider.cloneNode(false); this.innerContainer.appendChild(this.slider); this.slider.className = 'c-carousel-inf__slider'; var footer = this.el.querySelector('.rel--cardcarinf_foot'); if (footer) { this.el.insertBefore(this.innerContainer, footer); } else { this.el.appendChild(this.innerContainer); } this.items = queryAll(this.slider, '.c-carousel-inf__item'); this.items[this.items.length - 1].style.order = -1; this.order = 1; this.items.forEach(function (item) { item.addEventListener('focusin', eventHandlers$1.itemFocus.bind(_this), false); }); this.itemWidth = this.items[0].offsetWidth; this.slider.style.width = this.itemWidth * this.items.length + 'px'; if (this.el.classList.contains('c-carousel--tile')) { this.itemOffsetCount = 3; } else { this.itemOffsetCount = 1; } window.addEventListener('resize', eventHandlers$1.windowResize.bind(this)); this.containerWidth = this.innerContainer.offsetWidth; if (this.itemWidth * this.itemOffsetCount > this.containerWidth) { this.itemOffsetCount -= Math.ceil((this.itemWidth * this.itemOffsetCount - this.containerWidth) / this.itemWidth); } else if (this.itemWidth * (this.itemOffsetCount + 1) < this.containerWidth) { this.itemOffsetCount += Math.floor((this.containerWidth - this.itemWidth * this.itemOffsetCount) / this.itemWidth); } this.translateCarousel(0); this.btnLeft = document.createElement('button'); this.btnLeft.classList.add('c-carousel-inf__btn--left'); this.btnLeft.innerHTML = 'Navigate Carousel ' + carouselCount + ' Left'; this.btnRight = document.createElement('button'); this.btnRight.classList.add('c-carousel-inf__btn--right'); this.btnRight.innerHTML = 'Navigate Carousel ' + carouselCount + ' Right'; this.innerContainer.appendChild(this.btnLeft); this.innerContainer.appendChild(this.btnRight); this.btnLeft.addEventListener('click', function () { _this.animateCarousel(_this.itemWidth); }, false); this.btnRight.addEventListener('click', function () { _this.animateCarousel(-_this.itemWidth); }, false); this.slider.addEventListener('touchstart', eventHandlers$1.dragStart.bind(this), false); this.slider.addEventListener('mousedown', eventHandlers$1.dragStart.bind(this), false); queryAll(this.slider, 'a').forEach(function (anchor) { anchor.addEventListener('click', function (e) { if (_this.dragTotalH > 3) { e.preventDefault(); } }); }); this.el.setAttribute(ATTRIBUTE_STATUS$1, STATUS_INITIALIZED$1); } createClass(InfiniteCarousel, [{ key: 'translateCarousel', value: function translateCarousel(deltaX) { var checkOffset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; var translateValue = this.currentOffset + deltaX + this.containerWidth / 2 - this.itemWidth - this.itemWidth * this.itemOffsetCount / 2; this.slider.style.transform = 'translateX(' + translateValue + 'px)'; this.currentOffset += deltaX; if (checkOffset) { this.checkOffset(); } } }, { key: 'animateCarousel', value: function animateCarousel(deltaX, animateDuration) { var _this2 = this; if (!this.animating) { this.animating = true; var duration = animateDuration || 500; // duration of animation in ms var ease = easings.easeInOutQuad; // easing function var time = 0; // Current time in ms var lastDraw = void 0; // Time of last draw var deltaXProgress = 0; var animate = function animate() { // Update time var now = new Date().getTime(); time += now - (lastDraw || now); lastDraw = now; // Get next scroll point var tempDeltaX = ease(time, 0, deltaX, duration); tempDeltaX -= deltaXProgress; deltaXProgress += tempDeltaX; // Update scrollTop _this2.translateCarousel(tempDeltaX); // If the animation isn't over call animate() for next frame if (time < duration) { requestAnimationFrame(animate); } else { _this2.animating = false; _this2.translateCarousel(-_this2.currentOffset); tiles.blazyInstance.revalidate(); } }; // Animate first frame animate(); } } }, { key: 'snapCarousel', value: function snapCarousel() { var rounded = Math.round(this.currentOffset % this.itemWidth / this.itemWidth); var snapped = void 0; if (rounded === 0) { snapped = -(this.currentOffset % this.itemWidth); } else { snapped = (360 - Math.abs(this.currentOffset % this.itemWidth)) * rounded; } this.animateCarousel(snapped); this.checkOffset(); } }, { key: 'checkOffset', value: function checkOffset() { var tempOffset = this.currentOffset; var direction = 0; if (this.active) { tempOffset += this.currentX - this.initialX; } if (tempOffset >= this.itemWidth / 2) { direction = -1; } else if (tempOffset <= -this.itemWidth / 2) { direction = 1; } if (direction !== 0) { this.translateCarousel(this.itemWidth * direction, false); this.updateOrder(direction * -1); tiles.blazyInstance.revalidate(); } } }, { key: 'updateOrder', value: function updateOrder(direction) { this.order = (this.order + direction + this.items.length) % this.items.length; if (this.order === 0) { this.items.forEach(function (item) { item.style.order = 0; }); } else if (this.order === this.items.length - 1) { for (var i = 1; i < this.items.length; i++) { this.items[i].style.order = -1; } } else if (direction === 1) { this.items[this.items.length - this.order].style.order = -1; } else { this.items[this.items.length - this.order - 1].style.order = 0; } } }]); return InfiniteCarousel; }(); queryAll(document, '.' + CLASS_CAROUSEL).forEach(function (el) { // Prevent repeat initialization if (el.getAttribute(ATTRIBUTE_STATUS$1) !== STATUS_INITIALIZED$1) { carouselCount += 1; el.infiniteCarousel = new InfiniteCarousel(el); // eslint-disable-line no-new } }); /*! * Stickyfill -- `position: sticky` polyfill * v. 1.1.1 | https://github.com/wilddeer/stickyfill * Copyright Oleg Korsunsky | http://wd.dizaina.net/ * * MIT License */ var stickyfill = (function(doc, win) { if (!doc) { doc = document; } if (!win) { win = window; } var watchArray = [], scroll, initialized = false, html = doc.documentElement, noop = function() {}, checkTimer, //visibility API strings hiddenPropertyName = 'hidden', visibilityChangeEventName = 'visibilitychange'; //fallback to prefixed names in old webkit browsers if (doc.webkitHidden !== undefined) { hiddenPropertyName = 'webkitHidden'; visibilityChangeEventName = 'webkitvisibilitychange'; } //test getComputedStyle if (!win.getComputedStyle) { seppuku(); } //test for native support var prefixes = ['', '-webkit-', '-moz-', '-ms-'], block = document.createElement('div'); for (var i = prefixes.length - 1; i >= 0; i--) { try { block.style.position = prefixes[i] + 'sticky'; } catch(e) {} if (block.style.position != '') { seppuku(); } } updateScrollPos(); //commit seppuku! function seppuku() { init = add = rebuild = pause = stop = kill = noop; } function mergeObjects(targetObj, sourceObject) { for (var key in sourceObject) { if (sourceObject.hasOwnProperty(key)) { targetObj[key] = sourceObject[key]; } } } function parseNumeric(val) { return parseFloat(val) || 0; } function updateScrollPos() { scroll = { top: win.pageYOffset, left: win.pageXOffset }; } function onScroll() { if (win.pageXOffset != scroll.left) { updateScrollPos(); rebuild(); return; } if (win.pageYOffset != scroll.top) { updateScrollPos(); recalcAllPos(); } } //fixes flickering function onWheel(event) { setTimeout(function() { if (win.pageYOffset != scroll.top) { scroll.top = win.pageYOffset; recalcAllPos(); } }, 0); } function recalcAllPos() { for (var i = watchArray.length - 1; i >= 0; i--) { recalcElementPos(watchArray[i]); } } function recalcElementPos(el) { if (!el.inited) return; var currentMode = (scroll.top <= el.limit.start? 0: scroll.top >= el.limit.end? 2: 1); if (el.mode != currentMode) { switchElementMode(el, currentMode); } } //checks whether stickies start or stop positions have changed function fastCheck() { for (var i = watchArray.length - 1; i >= 0; i--) { if (!watchArray[i].inited) continue; var deltaTop = Math.abs(getDocOffsetTop(watchArray[i].clone) - watchArray[i].docOffsetTop), deltaHeight = Math.abs(watchArray[i].parent.node.offsetHeight - watchArray[i].parent.height); if (deltaTop >= 2 || deltaHeight >= 2) return false; } return true; } function initElement(el) { if (isNaN(parseFloat(el.computed.top)) || el.isCell) return; el.inited = true; if (!el.clone) clone(el); if (el.parent.computed.position != 'absolute' && el.parent.computed.position != 'relative') el.parent.node.style.position = 'relative'; recalcElementPos(el); el.parent.height = el.parent.node.offsetHeight; el.docOffsetTop = getDocOffsetTop(el.clone); } function deinitElement(el) { var deinitParent = true; el.clone && killClone(el); mergeObjects(el.node.style, el.css); //check whether element's parent is used by other stickies for (var i = watchArray.length - 1; i >= 0; i--) { if (watchArray[i].node !== el.node && watchArray[i].parent.node === el.parent.node) { deinitParent = false; break; } } if (deinitParent) el.parent.node.style.position = el.parent.css.position; el.mode = -1; } function initAll() { for (var i = watchArray.length - 1; i >= 0; i--) { initElement(watchArray[i]); } } function deinitAll() { for (var i = watchArray.length - 1; i >= 0; i--) { deinitElement(watchArray[i]); } } function switchElementMode(el, mode) { var nodeStyle = el.node.style; switch (mode) { case 0: nodeStyle.position = 'absolute'; nodeStyle.left = el.offset.left + 'px'; nodeStyle.right = el.offset.right + 'px'; nodeStyle.top = el.offset.top + 'px'; nodeStyle.bottom = 'auto'; nodeStyle.width = 'auto'; nodeStyle.marginLeft = 0; nodeStyle.marginRight = 0; nodeStyle.marginTop = 0; break; case 1: nodeStyle.position = 'fixed'; nodeStyle.left = el.box.left + 'px'; nodeStyle.right = el.box.right + 'px'; nodeStyle.top = el.css.top; nodeStyle.bottom = 'auto'; nodeStyle.width = 'auto'; nodeStyle.marginLeft = 0; nodeStyle.marginRight = 0; nodeStyle.marginTop = 0; break; case 2: nodeStyle.position = 'absolute'; nodeStyle.left = el.offset.left + 'px'; nodeStyle.right = el.offset.right + 'px'; nodeStyle.top = 'auto'; nodeStyle.bottom = 0; nodeStyle.width = 'auto'; nodeStyle.marginLeft = 0; nodeStyle.marginRight = 0; break; } el.mode = mode; } function clone(el) { el.clone = document.createElement('div'); var refElement = el.node.nextSibling || el.node, cloneStyle = el.clone.style; cloneStyle.height = el.height + 'px'; cloneStyle.width = el.width + 'px'; cloneStyle.marginTop = el.computed.marginTop; cloneStyle.marginBottom = el.computed.marginBottom; cloneStyle.marginLeft = el.computed.marginLeft; cloneStyle.marginRight = el.computed.marginRight; cloneStyle.padding = cloneStyle.border = cloneStyle.borderSpacing = 0; cloneStyle.fontSize = '1em'; cloneStyle.position = 'static'; cloneStyle.cssFloat = el.computed.cssFloat; el.node.parentNode.insertBefore(el.clone, refElement); } function killClone(el) { el.clone.parentNode.removeChild(el.clone); el.clone = undefined; } function getElementParams(node) { var computedStyle = getComputedStyle(node), parentNode = node.parentNode, parentComputedStyle = getComputedStyle(parentNode), cachedPosition = node.style.position; node.style.position = 'relative'; var computed = { top: computedStyle.top, marginTop: computedStyle.marginTop, marginBottom: computedStyle.marginBottom, marginLeft: computedStyle.marginLeft, marginRight: computedStyle.marginRight, cssFloat: computedStyle.cssFloat }, numeric = { top: parseNumeric(computedStyle.top), marginBottom: parseNumeric(computedStyle.marginBottom), paddingLeft: parseNumeric(computedStyle.paddingLeft), paddingRight: parseNumeric(computedStyle.paddingRight), borderLeftWidth: parseNumeric(computedStyle.borderLeftWidth), borderRightWidth: parseNumeric(computedStyle.borderRightWidth) }; node.style.position = cachedPosition; var css = { position: node.style.position, top: node.style.top, bottom: node.style.bottom, left: node.style.left, right: node.style.right, width: node.style.width, marginTop: node.style.marginTop, marginLeft: node.style.marginLeft, marginRight: node.style.marginRight }, nodeOffset = getElementOffset(node), parentOffset = getElementOffset(parentNode), parent = { node: parentNode, css: { position: parentNode.style.position }, computed: { position: parentComputedStyle.position }, numeric: { borderLeftWidth: parseNumeric(parentComputedStyle.borderLeftWidth), borderRightWidth: parseNumeric(parentComputedStyle.borderRightWidth), borderTopWidth: parseNumeric(parentComputedStyle.borderTopWidth), borderBottomWidth: parseNumeric(parentComputedStyle.borderBottomWidth) } }, el = { node: node, box: { left: nodeOffset.win.left, right: html.clientWidth - nodeOffset.win.right }, offset: { top: nodeOffset.win.top - parentOffset.win.top - parent.numeric.borderTopWidth, left: nodeOffset.win.left - parentOffset.win.left - parent.numeric.borderLeftWidth, right: -nodeOffset.win.right + parentOffset.win.right - parent.numeric.borderRightWidth }, css: css, isCell: computedStyle.display == 'table-cell', computed: computed, numeric: numeric, width: nodeOffset.win.right - nodeOffset.win.left, height: nodeOffset.win.bottom - nodeOffset.win.top, mode: -1, inited: false, parent: parent, limit: { start: nodeOffset.doc.top - numeric.top, end: parentOffset.doc.top + parentNode.offsetHeight - parent.numeric.borderBottomWidth - node.offsetHeight - numeric.top - numeric.marginBottom } }; return el; } function getDocOffsetTop(node) { var docOffsetTop = 0; while (node) { docOffsetTop += node.offsetTop; node = node.offsetParent; } return docOffsetTop; } function getElementOffset(node) { var box = node.getBoundingClientRect(); return { doc: { top: box.top + win.pageYOffset, left: box.left + win.pageXOffset }, win: box }; } function startFastCheckTimer() { checkTimer = setInterval(function() { !fastCheck() && rebuild(); }, 500); } function stopFastCheckTimer() { clearInterval(checkTimer); } function handlePageVisibilityChange() { if (!initialized) return; if (document[hiddenPropertyName]) { stopFastCheckTimer(); } else { startFastCheckTimer(); } } function init() { if (initialized) return; updateScrollPos(); initAll(); win.addEventListener('scroll', onScroll); win.addEventListener('wheel', onWheel); //watch for width changes win.addEventListener('resize', rebuild); win.addEventListener('orientationchange', rebuild); //watch for page visibility doc.addEventListener(visibilityChangeEventName, handlePageVisibilityChange); startFastCheckTimer(); initialized = true; } function rebuild() { if (!initialized) return; deinitAll(); for (var i = watchArray.length - 1; i >= 0; i--) { watchArray[i] = getElementParams(watchArray[i].node); } initAll(); } function pause() { win.removeEventListener('scroll', onScroll); win.removeEventListener('wheel', onWheel); win.removeEventListener('resize', rebuild); win.removeEventListener('orientationchange', rebuild); doc.removeEventListener(visibilityChangeEventName, handlePageVisibilityChange); stopFastCheckTimer(); initialized = false; } function stop() { pause(); deinitAll(); } function kill() { stop(); //empty the array without loosing the references, //the most performant method according to http://jsperf.com/empty-javascript-array while (watchArray.length) { watchArray.pop(); } } function add(node) { //check if Stickyfill is already applied to the node for (var i = watchArray.length - 1; i >= 0; i--) { if (watchArray[i].node === node) return; } var el = getElementParams(node); watchArray.push(el); if (!initialized) { init(); } else { initElement(el); } } function remove(node) { for (var i = watchArray.length - 1; i >= 0; i--) { if (watchArray[i].node === node) { deinitElement(watchArray[i]); watchArray.splice(i, 1); } } } //expose Stickyfill return { stickies: watchArray, add: add, remove: remove, init: init, rebuild: rebuild, pause: pause, stop: stop, kill: kill }; }); /** Position sticky * Polyfills `position: sticky` using Stickyfill. */ var stickyfill$1 = stickyfill(); queryAll(document, '.position-sticky').forEach(function (el) { return stickyfill$1.add(el); }); /** Pin to top * Emulates the behavior of `position: sticky` but also adds a `.item-pinned` * class when "stuck" to the top to allow styling that state separately. * * Example use: http://news.gallup.com/reports/199961/state-american-workplace-report-2017.aspx?ays=1 */ var items = []; var pinnedTopPosition = function () { var stickyNavbar = document.querySelector('.navbar-sticky'); return stickyNavbar ? stickyNavbar.clientHeight : 0; }(); function update$1() { for (var i = 0; i < items.length; i++) { var el = items[i]; var rect = el.placeholder.getBoundingClientRect(); if (rect.top < pinnedTopPosition) { el.classList.add('item-pinned'); el.style.position = 'fixed'; el.style.top = pinnedTopPosition + 'px'; el.style.left = 0; el.style.width = '100%'; el.style.height = ''; el.style.zIndex = 1; el.placeholder.style.height = el.clientHeight + 'px'; } else { el.classList.remove('item-pinned'); el.style.position = 'absolute'; el.style.top = el.placeholder.offsetTop + 'px'; el.style.left = el.placeholder.offsetLeft + 'px'; el.style.width = rect.width + 'px'; el.style.height = el.originalHeight; el.style.zIndex = ''; el.placeholder.style.height = el.originalHeight; } } } function createPlaceholder(el) { var rect = el.getBoundingClientRect(); var cs = window.getComputedStyle(el); var placeholder = document.createElement('div'); var ps = placeholder.style; placeholder.className = 'item-pinnable-placeholder'; el.originalHeight = rect.height + 'px'; ps.height = rect.height + 'px'; ps.marginTop = cs.marginTop; ps.marginLeft = cs.marginLeft; ps.marginBottom = cs.marginBottom; ps.marginRight = cs.marginRight; ps.cssFloat = cs.cssFloat; ps.fontSize = '1em'; ps.position = 'static'; ps.padding = 0; ps.border = 0; ps.borderSpacing = 0; return placeholder; } function pin(el) { el.placeholder = createPlaceholder(el); el.parentNode.insertBefore(el.placeholder, el.nextSibling); el.parentNode.style.position = 'relative'; items.push(el); update$1(); } // Automatically pin any items with `item-pinnable` class window.onload = function loadPins() { [].concat(toConsumableArray(document.querySelectorAll('.item-pinnable'))).forEach(pin); }; // Register event listeners document.addEventListener('scroll', throttle_1(update$1, 30)); window.addEventListener('resize', throttle_1(update$1, 30)); /** Progress Bar * Shows / hides a header element when reading a gallup news article then sets a * dynamic width for a progress bar to show users reading progress * * Example use: ÓÅÃÛ´«Ã½News & WWW articles * e.g. https://www.gallup.com/workplace/236078/elon-musk-start.aspx */ var progressHeader = document.querySelector('.c-progress-header'); var socialIcons = document.querySelector('.section-flex--share'); var scrolling = false; function updateProgress() { var progressBar = document.querySelector('.c-progress-bar'); var articleContent = null; var articleRect = null; var articleContentDivs = document.querySelectorAll('.article-content'); articleContentDivs.forEach(function (el) { var clientRect = el.getBoundingClientRect(); if (-clientRect.top > -100 && -clientRect.top < clientRect.height) { articleContent = el; articleRect = clientRect; } }); if (articleContent !== null) { progressHeader.style.transform = 'none'; var progressStatus = -articleRect.top / (articleRect.height - 400) * 100; // always start progress width at 0% if (progressStatus < 0) { progressStatus = 0; } else if (progressStatus >= 100) { progressStatus = 100; } // update progress bar width progressBar.style.width = progressStatus + '%'; socialIcons.style.display = 'block'; } else { progressHeader.style.transform = 'translateY(-100px)'; socialIcons.style.display = 'none'; } scrolling = false; } // check for progress element and fire event listener if needed if (progressHeader) { progressHeader.style.transform = 'translateY(-100px)'; progressHeader.style.display = 'block'; socialIcons.style.display = 'none'; // if we don't have sticky/fixed nav(s) pin progress header to top of page if (!document.querySelector('.navbar-sticky') && !document.querySelector('.header-metanav-only')) { progressHeader.style.top = 0; } window.addEventListener('scroll', function () { if (!scrolling) { // update progress status before next repaint requestAnimationFrame(updateProgress); scrolling = true; } }); } /** Pop Banner * Looks for items with a data-banner attribute then extracts its value as an ID and * determines if a banner ad should be shown based on if that particular ID has * already been set in local storage (local storage gets set on dismissal or CTA click). * * Example use: https://www.gallup.com/workplace/242252/employee-experience.aspx */ var banner = document.querySelectorAll('[data-banner]'); var addSubscribePanel = function addSubscribePanel() { var popBannerContainer = document.querySelector('[data-banner-content]'); if (popBannerContainer) { popBannerContainer.classList.add('c-pop-banner'); var subscribePanelContent = document.querySelector('#' + popBannerContainer.dataset.bannerContent); popBannerContainer.appendChild(subscribePanelContent); } }; function setStorage(i) { var STORAGE_KEY = 'banner- + ' + banner[i].getAttribute('data-banner'); window.localStorage.setItem(STORAGE_KEY, true); } function showBanner(i) { banner[i].style.display = 'block'; // fade banner in setTimeout(function () { banner[i].style.opacity = 1; // blazy check tiles.blazyInstance.revalidate(); }, 3000); // use gel-bootstrap banner.js to dismiss banner and set storage banner[i].addEventListener('gel.banner.dismiss', function () { setStorage(i); document.querySelector('#skipToPopUpModal').style.display = 'none'; }); // dismiss banner upon CTA click var ctaLinks = banner[i].querySelectorAll('a:not([data-dismiss])'); for (var j = 0; j < ctaLinks.length; j++) { ctaLinks[j].addEventListener('click', setStorage(i)); } } var popBannerElement = document.querySelector('#pop-banner'); var focusOnNav = function focusOnNav(e) { if (!popBannerElement.contains(e.relatedTarget)) { // Corporate nav link element var navLink = document.querySelector('#navbar-collapse-corporate > ul > li > a'); navLink.focus(); popBannerElement.removeEventListener('focusout', focusOnNav); } }; // Adding skip to modal link as a first option among skip nav links var addSkipNavLink = function addSkipNavLink() { var skipToContentDiv = document.querySelector('#skiptocontent'); var skipToModalLink = document.createElement('a'); skipToModalLink.setAttribute('id', 'skipToPopUpModal'); skipToModalLink.setAttribute('href', '#pop-banner'); // getting link text from the data attribute value skipToModalLink.innerText = popBannerElement.dataset.skipText; skipToContentDiv.appendChild(skipToModalLink); var skipToMainLink = document.querySelector('#skipToMain'); skipToMainLink.before(skipToModalLink); }; var onSkipNavLinkClick = function onSkipNavLinkClick() { var skipToModalLink = document.querySelector('#skipToPopUpModal'); if (skipToModalLink) { skipToModalLink.addEventListener('click', function () { popBannerElement.addEventListener('focusout', focusOnNav); }); } }; function init() { addSubscribePanel(); for (var i = 0; i < banner.length; i++) { var STORAGE_KEY = 'banner- + ' + banner[i].getAttribute('data-banner'); if (typeof gcb === 'undefined' || gcb.status() === 'loaded') { // eslint-disable-line no-undef // we could show banner, only do if user hasn't already dismissed if (!window.localStorage.getItem(STORAGE_KEY)) { showBanner(i); addSkipNavLink(); onSkipNavLinkClick(); break; } } } } // check for banner element and initialize if (banner.length > 0) { if (document.readyState === 'complete') { init(); } else { window.addEventListener('load', init); } } var blazyInstance$2 = new blazy(); var rearrangeItems = document.querySelectorAll('[data-rearrange-id]'); if (rearrangeItems) { Array.prototype.forEach.call(rearrangeItems, function (el) { var targetContainer = document.querySelector('[data-itemid="' + el.dataset.rearrangeId + '"] .rearrange-target') || document.querySelector('[data-itemid="' + el.dataset.rearrangeId + '"] .card-item'); if (targetContainer) { targetContainer.appendChild(el); } document.addEventListener('shown.bs.collapse', function () { blazyInstance$2.revalidate(); }); }); } var ready = createCommonjsModule(function (module) { /*! * domready (c) Dustin Diaz 2014 - License MIT */ !function (name, definition) { module.exports = definition(); }('domready', function () { var fns = [], listener , doc = document , hack = doc.documentElement.doScroll , domContentLoaded = 'DOMContentLoaded' , loaded = (hack ? /^loaded|^c/ : /^loaded|^i|^c/).test(doc.readyState); if (!loaded) doc.addEventListener(domContentLoaded, listener = function () { doc.removeEventListener(domContentLoaded, listener); loaded = 1; while (listener = fns.shift()) listener(); }); return function (fn) { loaded ? setTimeout(fn, 0) : fns.push(fn); } }); }); var stickyfill$2 = stickyfill(); var activeEl = void 0; function makeSticky() { // Make chapter headers sticky queryAll(document, '.chapter-header').forEach(function (sticky) { stickyfill$2.add(sticky); }); } function init$1() { // Enable stickyfill if needed makeSticky(); // Scroll to chapter header when clicked queryAll(document, '.chapter-accordion').forEach(function (el) { el.addEventListener('click', function (e) { var chapterSection = findAncestor(el, '.rel-chapter'); queryAll(chapterSection, '.chapter-img--active').forEach(function (chapterImage) { chapterImage.classList.remove('chapter-img--active'); }); var image = findAncestor(e.target, '.rel--chapter').querySelector('.chapter-img'); if (image && el.classList.contains('collapsed')) { image.classList.add('chapter-img--active'); } activeEl = activeEl === el.parentElement ? null : el.parentElement; // If we are closing a chapter that is not sticky, don't scroll if (!activeEl && el.parentElement.getBoundingClientRect().top > 0) { return; } var accordion = findAncestor(e.target, '.chapter-header'); setTimeout(function () { scrollToElement(accordion); }, 10); }); }); } ready(init$1); /** vh Fix for css variable * certain mobile devices do not mesh well with 100vh elements * in order to get around this, we can use a css variable * that is set to the innerHeight of the window * * Example use: https://www.gallup.com/home.aspx */ function setInnerHeightVar() { document.documentElement.style.setProperty('--vh', window.innerHeight + 'px'); } window.addEventListener('resize', setInnerHeightVar); window.addEventListener('orientationchange', setInnerHeightVar); setInnerHeightVar(); var preventFocus = function preventFocus(linkElements) { Array.prototype.forEach.call(linkElements, function (link) { link.addEventListener('mousedown', function () { link.classList.add('c-focus-hide'); }); link.addEventListener('focusout', function () { link.classList.remove('c-focus-hide'); }); }); }; var navbarLinks = document.querySelectorAll('.navbar a, .navbar button'); preventFocus(navbarLinks); var imageLogos = document.querySelectorAll('.c-image__logo a'); preventFocus(imageLogos); var footerNavLinks = document.querySelectorAll('.c-sitemap a, .c-legal-banner a'); preventFocus(footerNavLinks); /** Modal * Used for the video, podcast, and map webpart modals * * Example use: https://www.gallup.com/certifiedcoach/ */ document.addEventListener('show.bs.modal', function () { tiles.blazyInstance.revalidate(); }); ready(function () { var firstScrollEl = document.querySelector('[data-initial-scroll]'); if (firstScrollEl) { var scrollTop = firstScrollEl.getBoundingClientRect().top - 200; document.documentElement.scrollTop = scrollTop; document.body.parentNode.scrollTop = scrollTop; document.body.scrollTop = scrollTop; } }); var tables = document.querySelectorAll('.figure-table table'); if (tables) { for (var i$2 = 0; i$2 < tables.length; i$2++) { if (tables[i$2].querySelector('[colspan="100"]') && !tables[i$2].classList.contains('no-fixed')) { tables[i$2].classList.add('no-fixed'); } } } var createExitModalBackdrop = function createExitModalBackdrop() { var exitModalBackdrop = document.createElement('div'); exitModalBackdrop.classList.add('c-exit-modal__backdrop'); document.body.appendChild(exitModalBackdrop); }; var exitModal = document.querySelector('[data-exit-modal]'); var dismissModal = function dismissModal() { var backdrop = document.querySelector('.c-exit-modal__backdrop'); var localStorageKey = 'exitModal-' + exitModal.getAttribute('data-exit-modal'); window.localStorage.setItem(localStorageKey, true); exitModal.style.display = 'none'; backdrop.style.display = 'none'; }; var showExitModal = function showExitModal() { var backdrop = document.querySelector('.c-exit-modal__backdrop'); exitModal.style.display = 'block'; backdrop.style.display = 'block'; // fade modal in and focus directly on email input field setTimeout(function () { exitModal.style.opacity = 1; document.querySelector('.c-exit-modal__input').focus(); }, 100); // dismiss modal upon 'close' button click exitModal.addEventListener('gel.banner.dismiss', function () { dismissModal(); }); // dismiss modal upon CTA button click Array.prototype.forEach.call(exitModal.querySelectorAll('a'), function (link) { link.addEventListener('click', dismissModal); }); }; var mouseEvent = function mouseEvent(e) { var shouldShowExitPopUp = e.clientY < 0; var localStorageKey = 'exitModal-' + exitModal.getAttribute('data-exit-modal'); var isModalDismissed = window.localStorage.getItem(localStorageKey); if (shouldShowExitPopUp && !isModalDismissed) { document.removeEventListener('mouseout', mouseEvent); showExitModal(); } }; // store email value in session storage var storeEmailValue = function storeEmailValue() { var emailValue = btoa(document.querySelector('.c-exit-modal__input').value); sessionStorage.setItem('em-email', emailValue); }; // get email value from session storage and populate in form var populateEmailValueInForm = function populateEmailValueInForm() { var formEmail = document.querySelector('input[name="emailAddress"]'); var sessionValue = sessionStorage.getItem('em-email'); if (!exitModal && formEmail && sessionValue) { formEmail.value = atob(sessionValue || ''); } sessionStorage.removeItem('em-email'); }; var init$2 = function init() { createExitModalBackdrop(); setTimeout(function () { document.addEventListener('mouseout', mouseEvent); }, 6000); var email = document.querySelector('.c-exit-modal__input'); email.addEventListener('input', storeEmailValue); }; if (exitModal) { if (document.readyState === 'complete') { init$2(); } else { window.addEventListener('load', init$2); } } populateEmailValueInForm(); var v11ShowOnceCards = document.querySelectorAll('[data-v11-card]'); // For "show-before" and all other cms items if (v11ShowOnceCards.length > 0) { for (var i$3 = 0; i$3 < v11ShowOnceCards.length; i$3++) { var dataCardVisibilityAttribute = v11ShowOnceCards[i$3].getAttribute('data-card-visibility'); var localStorageKey = v11ShowOnceCards[i$3].getAttribute('data-v11-card'); if (dataCardVisibilityAttribute === 'show-after') { // eslint-disable-next-line no-continue continue; } if (!window.localStorage.getItem(localStorageKey)) { v11ShowOnceCards[i$3].style.display = 'block'; window.localStorage.setItem(localStorageKey, true); } } } var handleShowAfterCards = function handleShowAfterCards() { var dynamicReportAfterClass = document.querySelector('.g-after'); if (dynamicReportAfterClass) { v11ShowOnceCards.forEach(function (card) { var dataCardVisibilityAttribute = card.getAttribute('data-card-visibility'); var localStorageKey = card.getAttribute('data-v11-card'); if (dataCardVisibilityAttribute === 'show-after' && !window.localStorage.getItem(localStorageKey)) { card.style.display = 'block'; window.localStorage.setItem(localStorageKey, true); } }); } }; // Only for "show-after" cms items // Using MutationObserver interface to watch for changes being made to the DOM var observer = new MutationObserver(function (mutations, obs) { var dynamicReportAfterClass = document.querySelector('.g-after'); if (dynamicReportAfterClass) { handleShowAfterCards(); obs.disconnect(); } }); observer.observe(document, { childList: true, subtree: true }); var blazyRevalidate = function blazyRevalidate() { tiles.blazyInstance.revalidate(); }; var navDropdowns = document.querySelectorAll('.c-global-nav__dropdown-flex'); if (navDropdowns) { Array.prototype.forEach.call(navDropdowns, function (el) { el.addEventListener('mouseover', blazyRevalidate); el.addEventListener('click', blazyRevalidate); }); } function showGroupFades(fadeGroup) { var index = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; fadeGroup[index].classList.add('in'); if (index + 1 < fadeGroup.length) { setTimeout(function () { showGroupFades(fadeGroup, index + 1); }, 100); } } var observer$1 = new IntersectionObserver(function (entries, obs) { entries.forEach(function (entry) { if (entry.isIntersecting) { if (entry.target.classList.contains('c-anim-group')) { var fadeElementsInGroup = entry.target.querySelectorAll('[class*=c-fade-anim]'); showGroupFades(fadeElementsInGroup); obs.unobserve(entry.target); } else { entry.target.classList.add('in'); obs.unobserve(entry.target); } } }); }, { threshold: 0.7 }); var fades = document.querySelectorAll('[class*=c-fade-anim]'); fades.forEach(function (fadeEl) { observer$1.observe(fadeEl); }); var fadeGroups = document.querySelectorAll('.c-anim-group'); fadeGroups.forEach(function (fadeGroup) { observer$1.observe(fadeGroup); var fadeElementsInGroup = fadeGroup.querySelectorAll('[class*=c-fade-anim]'); fadeElementsInGroup.forEach(function (fadeEl) { observer$1.unobserve(fadeEl); }); }); /* eslint-disable */ /** Collapse * Fusion specic behavior for the gel collapse functionality * Example use: https://www.gallup.com/learning/310019/accelerated-strengths-coaching.aspx */ document.addEventListener('shown.bs.collapse', function (e) { var expandTextParent = e.target.nextElementSibling; if (expandTextParent && expandTextParent.classList.contains('c-expansionText')) { var expandTextShow = expandTextParent.children[0].children[1]; var expandTextHide = expandTextParent.children[0].children[0]; expandTextShow.style.display = 'initial'; expandTextHide.style.display = 'none'; } }); document.addEventListener('hide.bs.collapse', function (e) { var expandTextParent = e.target.nextElementSibling; if (expandTextParent && expandTextParent.classList.contains('c-expansionText')) { var expandTextShow = expandTextParent.children[0].children[0]; var expandTextHide = expandTextParent.children[0].children[1]; expandTextShow.style.display = 'initial'; expandTextHide.style.display = 'none'; } }); // Leading with Strengths collapse feature var showMoreDivs = document.querySelectorAll('.c-show-more'); showMoreDivs.forEach(function (showMoreDiv) { document.addEventListener('shown.bs.collapse', function (e) { var button = e.target.nextElementSibling.querySelector('a[data-toggle="collapse"]'); var collapseBtnText = button.getAttribute('data-btn-collapse'); button.innerHTML = collapseBtnText; }); document.addEventListener('hide.bs.collapse', function (e) { var button = e.target.nextElementSibling.querySelector('a[data-toggle="collapse"]'); var expandBtnText = button.getAttribute('data-btn-expand'); button.innerHTML = expandBtnText; }); }); var tooltipItems = document.querySelectorAll('.c-tooltip'); // Handling screen reader class var srOnly = function srOnly(tooltiptext) { var srOnlyCheck = tooltiptext.classList.contains('sr-only'); if (srOnlyCheck) { tooltiptext.classList.remove('sr-only'); } }; var moveCaretPosition = function moveCaretPosition(remainingWidthLeft, tooltipTextRemainingWidthLeft) { var style = document.createElement('style'); style.appendChild(document.createTextNode('')); document.head.appendChild(style); var arrowStyle = '.c-tooltip__text--bottom-caret:before, .c-tooltip__text--bottom-caret:after { left: ' + (remainingWidthLeft - tooltipTextRemainingWidthLeft) + 'px }'; style.sheet.insertRule(arrowStyle, 0); }; // Calculating Remaining Width var remainingWidth = function remainingWidth(tooltiptext, tooltip) { var tooltipRect = tooltip.getBoundingClientRect(); var bodyElem = document.querySelector('body'); var bodyElemRect = bodyElem.getBoundingClientRect(); var remainingWidthRight = bodyElemRect.right - tooltipRect.left; var remainingWidthLeft = tooltipRect.left - bodyElemRect.left; if (remainingWidthRight >= 340) { tooltiptext.className = 'c-tooltip__text c-tooltip__text--right'; } else if (remainingWidthRight < 340 && remainingWidthLeft > 340) { tooltiptext.className = 'c-tooltip__text c-tooltip__text--left'; tooltiptext.style.right = tooltipRect.width + 'px'; } else if (remainingWidthLeft < 340 && remainingWidthRight < 340) { tooltiptext.className = 'c-tooltip__text c-tooltip__text--bottom c-tooltip__text--bottom-caret'; tooltiptext.style.display = 'table'; var tooltipTextRect = tooltip.querySelector('.c-tooltip__text--bottom').getBoundingClientRect(); var tooltipTextRemainingWidthLeft = tooltipTextRect.left; moveCaretPosition(remainingWidthLeft, tooltipTextRemainingWidthLeft); } }; if (tooltipItems) { var clickOnTooltip = function clickOnTooltip(el) { var tooltiptext = el.querySelector('.c-tooltip__text'); srOnly(tooltiptext); tooltiptext.style.display = 'inline-block'; remainingWidth(tooltiptext, el); }; var clickOutsideTooltip = function clickOutsideTooltip(el) { var tooltiptext = el.querySelector('.c-tooltip__text'); tooltiptext.style.display = 'none'; tooltiptext.style.right = 'unset'; tooltiptext.className = 'sr-only c-tooltip__text'; }; Array.prototype.forEach.call(tooltipItems, function (el) { var tooltiptext = el.querySelector('.c-tooltip__text'); tooltiptext.classList.add('sr-only'); el.setAttribute('tabindex', '0'); el.addEventListener('keydown', function (e) { if (e.key === 'Enter') { if (el.classList) { if (tooltiptext.classList.contains('sr-only')) clickOnTooltip(el);else clickOutsideTooltip(el); } } }); el.addEventListener('focusout', function () { setTimeout(function () { var newFocus = document.activeElement.parentElement; if (newFocus.classList.contains('c-tooltip__text')) return; clickOutsideTooltip(el); }, 0); }); el.addEventListener('mouseover', function () { clickOnTooltip(el); }); el.addEventListener('mouseout', function () { clickOutsideTooltip(el); }); document.body.addEventListener('touchmove', function () { tooltiptext.style.right = 'unset'; tooltiptext.className = 'sr-only c-tooltip__text'; }, false); el.addEventListener('touchstart', function () { clickOnTooltip(el); }); }); } /* eslint-disable no-plusplus */ var blazyInstance$3 = new blazy(); var SLIDER_COMPONENT = 'slider__items'; var activeSlider = void 0; var eventHandlers$2 = { touchStart: function touchStart(e) { this.isDragging = true; this.startX = e.touches[0].clientX - this.sliderOffset.left; this.translateX = 0; activeSlider = this.slider; document.addEventListener('touchmove', throttle_1(eventHandlers$2.touchMove.bind(this), 30), { passive: false }); document.addEventListener('touchend', eventHandlers$2.touchEnd.bind(this), false); }, touchMove: function touchMove(e) { if (!this.isDragging) return; blazyInstance$3.revalidate(); var currentX = e.touches[0].clientX - this.sliderOffset.left; this.translateX = currentX - this.startX; activeSlider.style.transform = 'translateX(' + (this.currentPosition + this.translateX) + 'px)'; activeSlider.style.transition = 'none'; this.handleNextButtonState(); }, touchEnd: function touchEnd(e) { var _this = this; if (!this.isDragging) return; this.isDragging = false; this.endX = e.changedTouches[0].clientX - this.sliderOffset.left; var deltaX = this.endX - this.startX; activeSlider.style.transition = 'transform 0.3s ease'; setTimeout(function () { // Snap to the nearest slide _this.currentPosition += _this.translateX; var targetX = Math.round(_this.currentPosition / _this.tileWidth) * _this.tileWidth; var maxIndex = Math.min(Math.abs(targetX), _this.lastEndingSlidesIndex * _this.tileWidth); activeSlider.style.transform = 'translateX(' + -maxIndex + 'px)'; _this.currentPosition = -maxIndex; // check if first slide is in view, and if swiping right if (targetX >= 0 && deltaX > 0) { var minIndex = 0; activeSlider.style.transform = 'translateX(' + minIndex + 'px)'; _this.currentPosition = minIndex; } _this.handlePreviousButtonState(); _this.handleNextButtonState(); }, 300); document.removeEventListener('touchend', eventHandlers$2.touchEnd.bind(this), false); document.removeEventListener('touchmove', eventHandlers$2.touchMove.bind(this), false); }, windowResize: function windowResize() { this.updateButtonStates(); } }; var SliderComponent = function () { function SliderComponent(el) { var _this2 = this; classCallCheck(this, SliderComponent); this.slider = el; this.sliderContainer = el.parentElement; this.currentSlide = 0; this.currentPosition = 0; this.totalSlides = el.querySelectorAll('.slider__item').length; this.lastSlide = el.querySelector('.slider__item:last-child'); this.tileWidth = el.querySelector('.slider__item').offsetWidth + 20; this.prevBtn = this.sliderContainer.previousElementSibling.querySelector('.slider__btn--prev'); this.nextBtn = this.sliderContainer.previousElementSibling.querySelector('.slider__btn--next'); this.sliderOffset = this.slider.getBoundingClientRect(); this.lastSlideOffsetRight = 0; // To calculate how many slides to be shown in slider at the end this.lastSlidesToShow = Math.floor(this.sliderContainer.offsetWidth / this.tileWidth); this.lastVisibleSlidesWidth = this.lastSlidesToShow * this.tileWidth; this.lastEndingSlidesIndex = this.totalSlides - this.lastSlidesToShow; // Touch events variables this.isDragging = false; this.startX = 0; this.endX = 0; this.translateX = 0; this.updateButtonStates(); window.addEventListener('resize', throttle_1(eventHandlers$2.windowResize.bind(this), 30)); this.nextBtn.addEventListener('click', function () { _this2.currentSlide = Math.abs(_this2.currentPosition) / _this2.tileWidth; var maxSlideWidth = _this2.lastEndingSlidesIndex * _this2.tileWidth; if (Math.abs(_this2.currentPosition) < maxSlideWidth) { _this2.currentSlide++; _this2.slideTilesOnClick(); } else { _this2.updateButtonStates(); } }); this.prevBtn.addEventListener('click', function () { _this2.currentSlide = Math.abs(_this2.currentPosition) / _this2.tileWidth; if (_this2.currentSlide > 0) { _this2.currentSlide--; _this2.slideTilesOnClick(); } }); this.sliderContainer.addEventListener('touchstart', eventHandlers$2.touchStart.bind(this), false); } createClass(SliderComponent, [{ key: 'slideTilesOnClick', value: function slideTilesOnClick() { var _this3 = this; blazyInstance$3.revalidate(); var newPosition = -this.currentSlide * this.tileWidth; this.slider.style.transform = 'translateX(' + newPosition + 'px)'; this.currentPosition = newPosition; setTimeout(function () { _this3.updateButtonStates(); }, 300); } }, { key: 'updateButtonStates', value: function updateButtonStates() { this.handlePreviousButtonState(); this.handleNextButtonState(); } }, { key: 'handlePreviousButtonState', value: function handlePreviousButtonState() { if (this.currentPosition === 0) { this.prevBtn.disabled = true; this.prevBtn.classList.add('slider__btn--disabled'); } else { this.prevBtn.disabled = false; this.prevBtn.classList.remove('slider__btn--disabled'); } } }, { key: 'handleNextButtonState', value: function handleNextButtonState() { this.lastSlideOffsetRight = this.lastSlide.getBoundingClientRect().right; var sliderViewportSize = this.sliderContainer.offsetWidth + this.sliderOffset.left; if (this.lastSlideOffsetRight <= sliderViewportSize) { this.nextBtn.disabled = true; this.nextBtn.classList.add('slider__btn--disabled'); } else { this.nextBtn.disabled = false; this.nextBtn.classList.remove('slider__btn--disabled'); } } }]); return SliderComponent; }(); queryAll(document, '.' + SLIDER_COMPONENT).forEach(function (el) { el.slider = new SliderComponent(el); }); // only grab the first sticky footer as we only allow one on a page var stickyFooter = document.querySelector('.c-v12-sticky-footer'); var siteFooter = document.querySelector('.footer-default'); var displayFooter = function displayFooter() { stickyFooter.querySelector('.c-v12-sticky-footer__content').style.height = 'auto'; stickyFooter.style.display = 'block'; siteFooter.style.paddingBottom = stickyFooter.offsetHeight + 'px'; }; var hideFooter = function hideFooter() { stickyFooter.style.display = 'none'; siteFooter.style.paddingBottom = '0'; }; var init$3 = function init() { if (typeof gcb === 'undefined' || window.gcb.status() === 'loaded') { displayFooter(); } document.addEventListener('gcb.banner.closed', function () { setTimeout(function () { displayFooter(); }, 3000); }); document.addEventListener('gcb.banner.hidden', function () { setTimeout(function () { displayFooter(); }, 3000); }); document.addEventListener('gcb.banner.full', function () { hideFooter(); }); document.addEventListener('gcb.banner.open', function () { hideFooter(); }); var submitBtn = stickyFooter.querySelector('.c-v12-sticky-footer__btn'); var emailInput = stickyFooter.querySelector('.c-v12-sticky-footer__email'); submitBtn.addEventListener('click', function () { var enteredText = emailInput.value; document.cookie = 'fusionSubscribeEmail=' + enteredText + ';domain=gallup.com;path=/;'; window.location.pathname = '/subscribe.aspx'; }); // Check if there are any pop banners on the page and add extra space to them var banners = document.querySelectorAll('.c-banner'); var toggle = stickyFooter.querySelector('.c-v12-sticky-footer__toggle'); if (banners) { banners.forEach(function (banner) { banner.style.marginBottom = stickyFooter.offsetHeight + 'px'; banner.style.maxHeight = 'calc(84vh - ' + stickyFooter.offsetHeight + 'px'; banner.style.transition = 'margin 0.5s'; toggle.addEventListener('click', function () { setTimeout(function () { banner.style.marginBottom = stickyFooter.offsetHeight + 'px'; banner.style.maxHeight = 'calc(84vh - ' + stickyFooter.offsetHeight + 'px'; }, 100); }); }); } }; // check for banner element and initialize if (stickyFooter && siteFooter) { if (document.readyState === 'complete') { init$3(); } else { window.addEventListener('load', init$3); } } /** Google Analytics * Hooks up "click" event listeners for GA tracking based on the * `data-ga-category` attribute. */ // Google analytics events tracking using data attributes queryAll(document, '[data-ga-category]').forEach(function (link) { link.addEventListener('click', function () { var attr = link.dataset; var action = attr.gaAction ? attr.gaAction : 'Click'; window.ga('send', 'event', attr.gaCategory, action, attr.gaLabel, { hitCallback: function hitCallback() {// Execute default action } }); }); }); // GTM YouTube videos tracking var iFrames = document.querySelectorAll('iframe.b-lazy'); if (iFrames) { Array.prototype.forEach.call(iFrames, function (iFrame) { var reinitializeGTMLoadEvent = function reinitializeGTMLoadEvent() { // eslint-disable-next-line no-undef dataLayer.push({ event: 'gtm.load' }); }; // Calling on iFrame src value change iFrame.addEventListener('load', reinitializeGTMLoadEvent); }); } // Script bundle for ÓÅÃÛ´«Ã½News (news.gallup.com) }()); //# sourceMappingURL=site-news.js.map ;