{ "version": 3, "sources": ["../js/components/utils.js", "../js/components/slider.js", "../js/components/tooltip-image.js", "../js/components/qa-accordion.js", "../js/components/body-guide.js", "../js/components/guitar-guide-filter.js", "../js/Utility/Dom.js", "../js/components/accessibility.js", "../js/components/modal.js", "../js/components/nav.js", "../js/components/oversized-headings.js", "../js/components/audio-controls.js", "../js/components/svg-animations.js", "../js/components/timeline.js", "../js/components/fixed-sidebar.js", "../js/main.js"], "sourcesContent": ["// used for window resize/scroll functions to reduce function calls\nexport function debouncer(func, timeout) {\n var timeoutID, timeout = timeout || 20;\n return function () {\n var scope = this, args = arguments;\n clearTimeout(timeoutID);\n timeoutID = setTimeout(function () {\n func.apply(scope, Array.prototype.slice.call(args));\n }, timeout);\n };\n}\n\n// fires once, at the end of an event.\n// e.g. if used in a window resize event, it will only fire after you have finished resizing.\nexport function waitForFinalEvents(callback, ms, uniqueID = null){\n let id = uniqueID;\n if (!id) {\n id = \"Don't call this twice without a uniqueId\";\n }\n clearTimeout (id);\n id = setTimeout(callback, ms);\n}\n\nexport function setCookie(cname, cvalue, exdays) {\n let expires = '';\n if(exdays){\n var d = new Date();\n d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));\n expires = \"expires=\"+d.toUTCString()+';';\n }\n document.cookie = cname + \"=\" + cvalue + \";\" + expires + \"path=/\";\n}\n\nexport function getCookie(cname) {\n var name = cname + \"=\";\n var ca = document.cookie.split(';');\n for(var i = 0; i < ca.length; i++) {\n var c = ca[i];\n while (c.charAt(0) == ' ') {\n c = c.substring(1);\n }\n if (c.indexOf(name) == 0) {\n return c.substring(name.length, c.length);\n }\n }\n return \"\";\n}\n\nexport function checkCookie(cname) {\n if (getCookie(cname) != \"\") {\n return true;\n }\n}\n\n// Check if Element is on screen\n$.fn.isOnScreen = function(){\n if($(this).length) {\n\n // Percentage of screen height to offset the trigger. e.g. 2 equals 50% or mid-screen\n var offsetTriggerAmount = 6;\n\n var top = $(this).offset().top;\n var bottom = top + $(this).outerHeight();\n var windowTop = $(window).scrollTop();\n var windowBottom = windowTop + $(window).height();\n var triggerTop = windowTop + ($(window).height() / offsetTriggerAmount);\n var triggerBottom = windowBottom - ($(window).height() / offsetTriggerAmount);\n\n\n return ((top < triggerBottom && bottom > triggerBottom) || (top < triggerTop && bottom > triggerTop) || (top > windowTop && bottom < windowBottom));\n }\n else {\n return false;\n }\n};\n", "import {debouncer} from './utils';\n\n$(document).ready(() => {\n // check the language set for the page, and set the \"Back\" and \"Next\" buttons accordingly.\n const lang = $('html').attr('lang');\n let back = '';\n let next = '';\n\n if(lang == 'es-MX'){\n back = 'Atr\u00E1s';\n next = 'Siguiente';\n }\n else if(lang == 'fr-FR'){\n back = 'Retour';\n next = 'Suivant';\n }\n else if(lang == 'de-DE'){\n back = 'Zur\u00FCck';\n next = 'N\u00E4chste';\n }\n else if(lang == 'it-IT'){\n back = 'Indietro';\n next = 'Avanti';\n }\n else {\n back = 'Back';\n next = 'Next';\n }\n\n const nextBtn = '';\n const prevBtn = '';\n const nextCircBtn = '';\n const prevCircBtn = '';\n\n $('.tn_col__slider').each(function(){\n const slider = $(this);\n let isModel = slider.closest('.guitar_models').length;\n let slideCount = slider.attr('data-slide-count');\n let slideLimit = isModel ? 4 : 5;\n if(slideCount > slideLimit){\n slideCount = slideLimit;\n }\n let slidesToScroll = isModel ? slideCount : 1;\n let arrows = isModel ? true : false;\n\n slider.slick({\n 'arrows' : arrows,\n 'infinite' : true,\n 'autoplay' : true,\n 'autoplaySpeed' : 7000,\n 'slidesToShow' : slideCount,\n 'slidesToScroll' : slidesToScroll,\n 'prevArrow' : prevCircBtn,\n 'nextArrow' : nextCircBtn,\n responsive: [\n {\n breakpoint: 1200,\n settings: {\n slidesToShow:4,\n 'slidesToScroll' : 4,\n }\n },\n {\n breakpoint: 990,\n settings: {\n slidesToShow:2,\n 'slidesToScroll' : 2,\n }\n },\n {\n breakpoint: 767,\n settings: {\n slidesToShow:1,\n 'slidesToScroll' : 1,\n }\n }\n ]\n });\n\n slider.find('.slick-arrow').click(function(e){\n $(this).blur();\n })\n });\n\n\n $('.body_guide__slider').each(function(){\n const slider = $(this);\n const nav = slider.closest('.body_guide__shape__right').find('.body_guide__slider_nav');\n\n slider.slick({\n 'arrows' : true,\n 'dots' : true,\n 'infinite' : true,\n 'autoplay' : false,\n 'prevArrow' : prevCircBtn,\n 'nextArrow' : nextCircBtn,\n 'appendArrows' : nav,\n 'appendDots' : nav\n });\n });\n\n\n $('.post_slider').each(function(){\n const slider = $(this);\n const sliderNav = slider.closest('.post_slider__wrap').find('.post_slider__nav');\n\n slider.slick({\n 'infinite' : false,\n 'autoplay' : false,\n 'autoplaySpeed' : 7000,\n 'slidesToShow' : 3,\n 'slidesToScroll' : 3,\n 'arrows' : true,\n 'appendArrows' : sliderNav,\n 'prevArrow' : prevBtn,\n 'nextArrow' : nextBtn,\n responsive: [\n {\n breakpoint: 990,\n settings: {\n slidesToShow:2,\n 'slidesToScroll' : 2,\n }\n },\n {\n breakpoint: 767,\n settings: {\n slidesToShow:1,\n 'slidesToScroll' : 1,\n }\n }\n ]\n });\n });\n\n $('.block_slider').each(function(){\n\n const slider = $(this);\n const wrapper = slider.closest('.block_slider__wrap');\n const slider_nav = slider.prev('.block_slider__nav');\n let isFullWidth = wrapper.hasClass('fullWidth');\n let prev = isFullWidth ? prevCircBtn : prevBtn;\n let next = isFullWidth ? nextCircBtn : nextBtn;\n let infinite = isFullWidth ? true : false;\n\n let args = {\n 'arrows' : true,\n 'infinite' : infinite,\n 'autoplay' : false,\n 'autoplaySpeed' : 7000,\n 'appendArrows' : slider_nav,\n 'prevArrow' : prev,\n 'nextArrow' : next,\n }\n\n // if the slider has an align-right class, start on the last slide\n if(slider.closest('.block_slider__wrap').hasClass('align-right')){\n const count = slider.find('.block_slider__slide').length;\n args['initialSlide'] = count;\n args['responsive'] = [\n {\n breakpoint: 767,\n settings: {\n 'initialSlide' : 0,\n }\n },\n ];\n }\n\n slider.slick(args);\n\n $(slider).find('.slick-slide').click(function(){\n if($(this).hasClass('slick-current')){\n return;\n }\n\n const index = $(this).index();\n slider.slick('slickGoTo', index);\n });\n\n // Handle fullscreen option\n $(slider).find('.block_slider__expand_btn').click(function(){\n $(this).blur();\n const isFullScreen = wrapper.hasClass('fullScreen');\n\n // open fullscreen view\n if(!isFullScreen){\n wrapper.addClass('fullScreen');\n block_slider_fullscreen_positioning(slider, wrapper);\n slider.slick(\"setPosition\");\n }\n // else, set back to normal size\n else {\n wrapper.removeClass('fullScreen');\n wrapper.css({'left':''});\n slider.slick(\"setPosition\");\n }\n });\n\n $(window).resize(function(){\n block_slider_fullscreen_positioning(slider, wrapper);\n });\n });\n\n\n $('.playlist__slider').each(function(){\n const slider = $(this);\n\n // Set up the playlist slider\n slider.slick({\n 'arrows' : true,\n 'infinite' : false,\n 'autoplay' : false,\n 'slidesToShow' : 3,\n 'swipe' : false,\n 'slidesToScroll' : 1,\n 'prevArrow' : prevBtn,\n 'nextArrow' : nextBtn,\n responsive: [\n {\n breakpoint: 1199,\n settings: {\n slidesToShow:2,\n 'centerMode' : false,\n // 'slidesToScroll' : 2,\n }\n },\n {\n breakpoint: 767,\n settings: {\n slidesToShow:1,\n 'centerMode' : true,\n // 'slidesToScroll' : 1,\n }\n }\n ]\n });\n\n // Handle the slider specific audio player js\n // Note: Base audio control js is found in audio-controls.js\n const player = slider.closest('.playlist__wrap').find('audio');\n const controls = slider.closest('.playlist__wrap').find('.audio_controls__wrap');\n const control_button = controls.find('.audio_controls__play');\n const progress_bar = controls.find('.audio_controls__progress .bar');\n\n slider.on('click', '.playlist__trigger', function(e){\n e.preventDefault();\n $(this).blur();\n const current_src = player.find('source').attr('src');\n const new_src = $(this).attr('data-preview');\n\n if(new_src){\n // if it's a new track, change the song and play.\n if(new_src != current_src){\n const track_title = $(this).attr('data-track');\n const full_url = $(this).attr('data-external');\n controls.find('.audio_controls__track').html(track_title);\n controls.find('.audio_controls__external').attr('href', full_url);\n player.trigger('pause');\n player.find('source').attr('src', new_src);\n player.trigger('load');\n player.trigger('play');\n control_button.addClass('pause');\n slider.find('.track.active').removeClass('active');\n $(this).closest('.track').addClass('active');\n const new_index = $(this).closest('.slick-slide').index();\n slider.slick('slickGoTo', new_index);\n\n // add class to progress bar to prevent css transition while the bar resets, then remove it to resume transitions\n progress_bar.addClass('no_transition').css('width', '0');\n setTimeout(function(){\n progress_bar.removeClass('no_transition');\n }, 100);\n }\n // else, if this track is already active, toggle play/pause.\n else {\n if (player[0].paused) {\n player.trigger('play');\n }\n else {\n player.trigger('pause');\n }\n\n control_button.toggleClass('pause');\n }\n }\n });\n\n // when track is complete\n player.bind('ended', function(){\n // get current track (that just ended)\n const current_track = slider.find('.track.active').closest('.slick-slide');\n\n // check if there are more tracks or if we're at the end\n if(!current_track.is(':last-child')){\n const following_tracks = current_track.nextAll('.slick-slide');\n let next_track = false;\n following_tracks.each(function(){\n if(!$(this).find('.no_track').length && !next_track){\n next_track = $(this).find('.playlist__trigger');\n }\n });\n\n if(next_track){\n const next_track_index = next_track.closest('.slick-slide').index();\n next_track.trigger('click');\n slider.slick('slickGoTo', next_track_index);\n }\n }\n });\n });\n\n $('body').on('click', '.arrow_btn', function(){\n $(this).blur();\n });\n});\n\nfunction block_slider_fullscreen_positioning(slider, sliderWrap){\n const isFullScreen = sliderWrap.hasClass('fullScreen');\n\n // if in fullscreen view, position accordinly\n if(isFullScreen){\n const parent = sliderWrap.parent();\n const parentLeft = parent.offset().left;\n const left = parentLeft * -1;\n sliderWrap.css('left', left);\n }\n}\n", "import {debouncer} from './utils';\n\n$(document).ready(() => {\n\n // Handle horizontal drag-drop scrolling\n var elements = document.querySelectorAll('.has_tooltips .itt__overflow');\n Array.prototype.forEach.call(elements, function(el, i){\n const slider = el;\n let isDown = false;\n let startX;\n let scrollLeft;\n\n slider.addEventListener('mousedown', (e) => {\n isDown = true;\n slider.classList.add('active');\n startX = e.pageX - slider.offsetLeft;\n scrollLeft = slider.scrollLeft;\n });\n slider.addEventListener('mouseleave', () => {\n isDown = false;\n slider.classList.remove('active');\n });\n slider.addEventListener('mouseup', () => {\n isDown = false;\n slider.classList.remove('active');\n });\n slider.addEventListener('mousemove', (e) => {\n if(!isDown) return;\n e.preventDefault();\n const x = e.pageX - slider.offsetLeft;\n const walk = (x - startX) * 1.5; //scroll-fast\n slider.scrollLeft = scrollLeft - walk;\n });\n });\n\n\n // Center the scrollbar if on tablet/mobile\n function center_itt(){\n const window_width = $(window).innerWidth();\n if(window_width > 768) return;\n\n $('.has_tooltips .itt__overflow').each(function(){\n const image_width = $(this).find('.itt__image__wrap').outerWidth();\n $(this).scrollLeft((image_width - window_width) / 2);\n });\n }\n\n $('.itt__image').imagesLoaded().done( function( instance ) {\n center_itt();\n });\n\n\n\n // Ensure the tooltip content stays within view, and adjust accordingly if not.\n function itt_content_position(){\n setTimeout(function(){\n $('.itt__image__wrap').each(function(){\n const container_width = $(this).innerWidth();\n const container_height = $(this).innerHeight();\n\n $(this).find('.itt__item_content').each(function(){\n const img = $(this).prev('.itt__item_img');\n $(this).css('transform', '');\n img.css('transform', '');\n\n const item_left = $(this).closest('.itt__item').position().left + $(this).position().left;\n const item_width = $(this).outerWidth();\n const item_edge_right = item_left + item_width;\n const item_top = $(this).closest('.itt__item').position().top + $(this).position().top;\n const item_height = $(this).outerHeight();\n const item_edge_top = item_top + item_height;\n let dif_x;\n let dif_y;\n let is_changed = false;\n\n // add class to reduce font size if this item is too large\n if(item_height >= container_height){\n $(this).addClass('oversized');\n }\n\n // determine if element is horizontally out of view, and by how much.\n if(item_edge_right > container_width){\n is_changed = true;\n dif_x = Math.round(((item_edge_right - container_width + 10) * -1)) + 'px';\n } else {\n dif_x = '0px';\n }\n\n // determine if element is vertically out of view, and by how much.\n if(item_edge_top > container_height){\n is_changed = true;\n dif_y = Math.round(((item_edge_top - container_height + 10) * -1)) + 'px';\n } else {\n dif_y = '0px';\n }\n\n if(is_changed){\n $(this).css('transform', 'translate(' + dif_x + ', ' + dif_y + ')');\n img.css('transform', 'translate(' + dif_x + ', ' + dif_y + ')');\n }\n\n });\n });\n }, 100);\n }\n itt_content_position();\n\n\n // Ensure overlay content stays within it's allotted safe space\n function itt_safe_space(){\n $('.itt__content__safe.desktop_only').each(function(){\n const wrapper = $(this).closest('.itt__wrap');\n const content = $(this).find('.itt__content');\n\n // remove classes and styles to get correct measurements and positions\n wrapper.removeClass('oversized_content');\n content.css('transform', '').removeClass('height_boundry');\n\n const safe_height = $(this).outerHeight();\n const safe_width = $(this).outerWidth();\n let content_top = content.position().top;\n let content_bottom = content_top + content.outerHeight();\n let content_height = content.outerHeight();\n let content_width = content.outerWidth();\n let content_right = content.position().left + content_width;\n let dif_y;\n let dif_x;\n\n if(content_height > safe_height && content_width > safe_width){\n wrapper.addClass('oversized_content');\n }\n else {\n // First, check if the content is taller than it's safe area, but not full width. If so, set the content left position to 0 to allow for more horizontal room.\n if(content_height > safe_height && content_width <= safe_width){\n content.addClass('height_boundry');\n }\n\n // After making the content full width, recheck if the height is within the safe area.\n if(content.hasClass('height_boundry') && content.outerHeight() > safe_height){\n wrapper.addClass('oversized_content');\n }\n // Else, check the vertical and horizontal positions and adjust accordingly\n else {\n content_top = content.position().top;\n content_bottom = content_top + content.outerHeight();\n content_height = content.outerHeight();\n content_width = content.outerWidth();\n content_right = content.position().left + content_width;\n\n // only determin vertical transform if it's not centered by default\n if(content.parent().hasClass('centered_vertically')){\n dif_y = '-50%';\n }\n else if(content_bottom > safe_height){\n dif_y = Math.round((content_bottom - safe_height) * -1) + 'px';\n } else {\n dif_y = 0;\n }\n\n if(content_right > safe_width){\n dif_x = Math.round((content_right - safe_width) * -1) + 'px';\n } else {\n dif_x = 0;\n }\n\n content.css('transform', 'translate(' + dif_x + ', ' + dif_y);\n }\n }\n });\n }\n itt_safe_space();\n\n\n // For mobile, make sure when clicking a tooltip the image slides to the content of that tooltip, if it is scrollable.\n $('.itt__item').click(function(){\n const window_width = $(window).innerWidth();\n if(window_width > 768) {\n return;\n }\n const item = $(this);\n const figure = item.find('figure');\n const content = item.find('.itt__item_content');\n const container = item.closest('.itt__overflow');\n let contentWidth;\n if(figure){\n contentWidth = content.outerWidth() + (figure.outerWidth() * .66);\n } else {\n contentWidth = content.outerWidth();\n }\n const scrollLeft = item.position().left - (window_width / 2) + (contentWidth / 2);\n container.animate({scrollLeft: scrollLeft}, 500);\n });\n\n\n $( window ).resize(debouncer(function ( e ) {\n center_itt();\n itt_content_position();\n itt_safe_space();\n }, 15 ) );\n});\n", "$(document).ready(() => {\n $('.qa__trigger').click(function(e){\n e.preventDefault();\n $(this).blur();\n const parent = $(this).closest('.qa__block');\n const target = $(this).attr('data-target');\n const active = $('.qa__block.active').not(parent);\n let scrollPos = parent.offset().top;\n let activeHeight = 0;\n\n if(active.length){\n // to better track the scroll position of the new element, calculate any element height that will close above it.\n if(active.index() < parent.index()){\n activeHeight = active.find('.qa__reveal').outerHeight();\n scrollPos = scrollPos - activeHeight;\n }\n // Close previously open element\n active.removeClass('active').find('.qa__reveal').attr('aria-hidden', 'true').slideUp();\n }\n\n if(parent.hasClass('active')){\n $(target).attr('aria-hidden', 'true').slideUp(700);\n }\n else {\n $(target).attr('aria-hidden', 'false').slideDown(700);\n\n // Prevent header from sliding down when scrolling\n $('body').addClass('qa__scrolling');\n $('html,body').animate(\n {scrollTop: scrollPos},\n 700,\n $.bez([.52,.01,.22,1]),\n function(){\n setTimeout(function(){\n $('body').removeClass('qa__scrolling');\n $('body').addClass('header_hidden');\n }, 300);\n }\n );\n }\n parent.toggleClass('active');\n });\n});\n", "$(document).ready(() => {\n $('.body_guide__trigger').click(function(e){\n e.preventDefault();\n $(this).blur();\n\n const wrapper = $(this).closest('.body_guide');\n const target = $(this).closest('.body_guide__accordion_item').find('.body_guide__accordion_content');\n\n if($(this).hasClass('active')){\n $(this).removeClass('active');\n target.slideUp().attr('aria-hidden', 'true');\n return;\n }\n\n const prevActive = wrapper.find('.body_guide__trigger.active');\n prevActive.removeClass('active');\n prevActive.closest('.body_guide__accordion_item').find('.body_guide__accordion_content').slideUp().attr('aria-hidden', 'true');\n\n $(this).addClass('active');\n target.slideDown().attr('aria-hidden', 'false');\n });\n});\n", "import {debouncer} from './utils';\n\n$(document).ready(() => {\n if($('body').find('.gg_search').length){\n // Add selected names to the select button\n function selectedNames(paramWrap){\n const id = paramWrap.attr('id');\n const select = $('.gg_search__select[data-target=\"#'+id+'\"]').find('.selected');\n let selected\n let i = 0;\n paramWrap.find('.selected').each(function(){\n const selectedName = $(this).attr('data-term-name');\n if(i == 0){\n selected = selectedName;\n }\n else {\n selected += ', ' + selectedName;\n }\n i++;\n });\n select.html(selected);\n }\n\n // Add selected names to Search Button href variables\n function searchButtonVariables(){\n const series = $('#gg_search__series_params').find('.selected');\n const shapes = $('#gg_search__shapes_params').find('.selected');\n const tonewoods = $('#gg_search__tonewood_params').find('.selected');\n\n const seriesIDs = getParamIDs(series);\n const shapesIDs = getParamIDs(shapes);\n const tonewoodsIDs = getParamIDs(tonewoods);\n\n let urlParams;\n\n urlParams = '?ggs=' + seriesIDs.join(',');\n urlParams += '&ggsh=' + shapesIDs.join(',');\n urlParams += '&ggt=' + tonewoodsIDs.join(',');\n\n $('.gg_search__submit').attr({ href: '/guitar-guide-filter' + urlParams });\n }\n searchButtonVariables();\n\n function getParamIDs(params){\n let id_array = [];\n\n params.each(function(){\n if($(this).hasClass('all')){\n id_array.push('all');\n }\n else {\n id_array.push($(this).attr('data-term-id'));\n }\n });\n\n return id_array;\n }\n\n // places the filters inside the mobile modal if at mobile size\n function gg_search_responsive(){\n const isMobile = $('body').find('.gg_search_modal_trigger').is(':visible');\n const mobileLayout = $('body').find('.gg_search__mobile_modal .gg_search__params ').length;\n\n // if it's at a mobile size and the layout hasn't already been changed\n if(isMobile && !mobileLayout){\n $('.gg_search__params').appendTo($('body').find('.gg_search__mobile_content'));\n $('.gg_search__select').removeClass('active');\n $('.gg_search__params').removeClass('active').attr('aria-hidden', 'true').fadeOut();\n }\n\n // if it's at a desktop size, and the layout is still in mobile\n if(!isMobile && mobileLayout){\n $('.gg_search__mobile_modal').removeClass('param_open');\n $('.gg_search__params').appendTo($('body').find('.gg_search'));\n $('.gg_search__mobile_modal').removeClass('params_open active').attr('aria-hidden', 'true');\n $('.gg_search__params').removeClass('active').attr('aria-hidden', 'true').fadeOut();\n }\n }\n gg_search_responsive();\n\n $('body').on('click', '.gg_search [data-target]', function(e){\n const button = $(this);\n const target = $('body').find(button.attr('data-target'));\n let isMobile = $('.gg_search__mobile_open').is(':visible') ? true : false;\n\n if(!target.length){\n return;\n }\n\n button.blur();\n\n $('.gg_search__select').not(button).removeClass('active');\n $('.gg_search__params').not(target).removeClass('active').attr('aria-hidden', 'true').fadeOut();\n\n if(button.hasClass('active')){\n button.removeClass('active');\n target.removeClass('active').attr('aria-hidden', 'true').fadeOut();\n\n if(isMobile){\n $('.gg_search__mobile_modal').removeClass('param_open');\n }\n }\n else {\n button.addClass('active');\n target.addClass('active').attr('aria-hidden', 'false').fadeIn();\n target.find('.all').focus().blur();\n\n if(isMobile){\n $('.gg_search__mobile_modal').addClass('param_open');\n }\n }\n });\n\n\n $('body').on('click', '.gg_search__params_inner button', function(){\n const button = $(this);\n const parent = button.closest('.gg_search__params');\n const all = parent.find('.all');\n\n button.blur();\n\n // Toggle this button\n button.toggleClass('selected');\n\n // Handle toggling the 'All' button\n if(!parent.find('.selected').not(all).length){\n all.addClass('selected');\n }\n else {\n all.removeClass('selected');\n }\n\n selectedNames(parent);\n searchButtonVariables();\n });\n\n $('body').on('click', '.gg_search__params_footer .clear, .gg_search__params .all', function(e){\n e.preventDefault();\n $(this).blur();\n\n const parent = $(this).closest('.gg_search__params');\n const selected = parent.find('.selected');\n const all = parent.find('.all');\n\n selected.removeClass('selected');\n all.addClass('selected');\n\n selectedNames(parent);\n searchButtonVariables();\n });\n\n $('body').on('click', '.gg_search__clearAll, .gg_search__mobile_footer .gg_search__clear', function(e){\n e.preventDefault();\n $(this).blur();\n\n $('body').find('.gg_search__params_footer .clear').trigger('click');\n });\n\n $('body').on('click', '.gg_search_modal_trigger', function(e){\n e.preventDefault();\n $(this).blur();\n $('body').find('.gg_search__mobile_modal').addClass('active').attr('aria-hidden', 'false');\n });\n\n $('body').on('click', '.gg_search__mobile_close', function(e){\n e.preventDefault();\n $(this).blur();\n $('body').find('.gg_search__mobile_modal').removeClass('active').attr('aria-hidden', 'true');\n $('body').find('.gg_search__params.active').removeClass('active').attr('aria-hidden', 'true').fadeOut();\n $('body').find('.gg_search__mobile_trigger.active').removeClass('active');\n });\n\n $('body').on('click', '.gg_search__mobile_back', function(e){\n e.preventDefault();\n $(this).blur();\n $('body').find('.gg_search__params.active').removeClass('active').attr('aria-hidden', 'true').fadeOut();\n $('body').find('.gg_search__mobile_modal').removeClass('param_open');\n $('body').find('.gg_search__mobile_trigger.active').removeClass('active');\n });\n\n $(window).resize(debouncer(function(){\n gg_search_responsive();\n }, 30));\n }\n});\n", "const Dom = {\n 'body' : $('body'),\n\n // accesibility\n 'focusable' : [\"a[href]:not([data-notabchange])\", \" area[href]\", \" input:not([disabled])\", \" select:not([disabled])\", \" textarea:not([disabled])\", \" button:not([disabled])\", \"object\", \"embed\", \"iframe\", \" *[tabindex]\", \" *[contenteditable]\", '*[data-notab]', \"*[data-notabchange]\"],\n\n // Accordion\n 'accordionHeader' : $('.accordion__header'),\n 'accordionBody' : $('.accordion__body'),\n 'toggleVidSrc' : $('[data-toggle-src]'),\n\n // menu trigger\n 'menuModal' : $('#menuPanelOverlay'),\n 'menuTrigger' : $('[menu-target]'),\n 'closeMenu' : $('[data-dismiss=\"menu\"]'),\n 'closeMenuButton' : $('[close-menu-button]'),\n 'menuGroup' : $('.screen-overlay__content'),\n // 'menuLinks' : $('.menu-link__item'),\n 'menuLinks' : $('.has-dropdown-link'),\n\n // Modal\n 'modalTrigger' : $('[modal-target]'),\n 'closeModal' : $('[data-dismiss=\"modal\"]'),\n 'closeAnyModal' : $('[data-dismiss=\"allModal\"]'),\n 'btnGroup' : $('.close-btn-group'),\n 'closeButton' : $('[close-button]'),\n\n // Slider\n 'instructorsSlider' : $('[js-instructors-slider]'),\n}\n\nexport default Dom;\n", "// Add [data-notab] to any html element you don't want to be tabbable\nimport Dom from '../Utility/Dom';\n\nconst Modal = {\n open: function(target){\n for (let element of Dom.focusable) {\n if(element !== '*[data-notab]'){\n $(element).attr('tabindex', '-1');\n target.find(element).attr('tabindex', '1');\n } else {\n $(element).attr('tabindex', '1');\n }\n }\n },\n close: function(target){\n for (let element of Dom.focusable) {\n element !== '*[data-notab]'\n ? $(element).attr('tabindex', '1')\n : $(element).attr('tabindex', '-1');\n\n target.find(element).attr('tabindex', '-1');\n }\n }\n}\n\n\nexport default Modal;\n", "import Modal from './accessibility';\nimport Dom from '../Utility/Dom';\nimport {debouncer, setCookie, getCookie, checkCookie} from '../components/utils';\n$(document).ready(() => {\n // MODAL\n const modalTrigger = $(Dom.modalTrigger);\n const closeModal = $('[data-dismiss=\"modal\"]');\n const btnGroup = $(Dom.btnGroup);\n const closeButton = $(Dom.closeButton);\n const bodyElem = $(Dom.body);\n Dom.modalTrigger.on('click keypress', e => {\n e.preventDefault();\n if(e.type === 'click' || e.key === 'Enter' ){\n let target = $(e.currentTarget).attr('modal-target');\n $(`#${target}`).addClass('active').attr('aria-hidden', 'false').attr('tabindex','1');\n bodyElem.addClass('scroll-lock modal-active');\n\n // Handles trapping focus in modal\n Modal.open($(`#${target}`))\n\n if ($(`#${target}`).find('iframe').length) {\n var _modalFrame = $(`#${target}`).find('iframe');\n _modalFrame[0].src += '&autoplay=1';\n }\n }\n });\n\n closeModal.on('click keypress', e => {\n if(e.key === 'Enter' || e.type === 'click'){\n e.preventDefault();\n let target = $(e.currentTarget).data('target');\n $(`${target}`).removeClass('active').attr('aria-hidden', 'true');\n bodyElem.removeClass('scroll-lock modal-active');\n\n // Handles un-trapping focus in modal\n Modal.close($(`${target}`));\n\n if(e.key === 'Enter'){\n const dataTarget = target.split('#')[1];\n $(`[modal-target=\"${dataTarget}\"]`).focus();\n }\n if ($(`${target}`).find('iframe').length) {\n // reset the iframe src to stop iframe playing\n var _modalFrame = $(`${target}`).find('iframe');\n var src = _modalFrame.attr('src');\n\n var newsrc = src.replace('&autoplay=1', '');\n $(`${target}`).find('iframe').attr('src', newsrc);\n }\n\n const menu = $('.main-nav__menu');\n menu.removeClass('archive_scrolled');\n }\n });\n\n // Handles focus states\n btnGroup.focus((e) => { $(e.currentTarget).find(closeButton).addClass('hover-active') });\n btnGroup.focusout((e) => { $(e.currentTarget).find(closeButton).removeClass('hover-active') });\n\n btnGroup.hover(\n // On hover add this class\n (e) => { $(e.currentTarget).find(closeButton).addClass('hover-active'); },\n // on hover exit remove this class\n (e) => {\n $(e.currentTarget).find(closeButton).removeClass('hover-active');\n }\n )\n\n // Issues Archive\n $('.issues_trigger').click(function(e){\n e.preventDefault();\n $(this).blur();\n\n const window_width = $(window).innerWidth();\n const modal = $('#issues_archive');\n modal.attr('aria-hidden', 'false');\n $('body').addClass('scroll-lock modal-active');\n\n if(window_width > 1199){\n // close any menus that may be open\n $('body').removeClass('nav-open');\n $('#primary-menu, .main-nav__toggle, .main-nav__contents').removeClass('active mb_active');\n $('.main-nav__toggle, .main-nav__contents').attr('aria-expanded', false);\n modal.addClass('active');\n }\n else {\n $('#primary-menu').addClass('archive_open').animate({scrollTop: 0}, 300);\n size_mobile_issues_archive();\n modal.css({'opacity' : '0', 'right' : '100vw'}).addClass('active');\n setTimeout(function(){\n modal.css({'opacity' : '', 'right' : ''});\n }, 1);\n }\n\n // Handles trapping focus in modal\n Modal.open($('#issues_archive'));\n\n if($(this).closest('.main-nav__mb_menu').length){\n $('.main-nav__toggle, .issue_nav .left a, .main-nav__mb_menu .search-field').attr('tabindex', 1);\n }\n });\n\n function size_mobile_issues_archive(){\n const modal = $('#issues_archive');\n const window_width = $(window).innerWidth();\n const search_bottom = $('.main-nav__mb_menu .search_wrap').position().top + $('.main-nav__mb_menu .search_wrap').outerHeight();\n\n if(window_width < 1199){\n if(!$('.main-nav__mb_menu').find(modal).length){\n modal.appendTo('#page');\n }\n modal.appendTo('.main-nav__mb_menu');\n modal.css({'padding-top': search_bottom + 30});\n } else {\n if($('.main-nav__mb_menu').find(modal).length){\n modal.appendTo('#page');\n }\n modal.css({'padding-top': ''});\n }\n\n if(modal.hasClass('active')){\n $('body').removeClass('nav-open scroll-lock modal-active');\n $('#primary-menu, .main-nav__toggle, .main-nav__contents').removeClass('active mb_active dt_active archive_open');\n $('.main-nav__toggle, .main-nav__contents').attr('aria-expanded', false);\n modal.removeClass('active').attr('aria-hidden', 'true');\n setTimeout(function(){\n modal.scrollTop(0);\n }, 300);\n Modal.close($('#issues_archive'));\n\n const menu = $('.main-nav__menu');\n menu.removeClass('archive_scrolled');\n }\n }\n size_mobile_issues_archive();\n\n $(window).resize(debouncer(function(){\n size_mobile_issues_archive();\n }, 20 ));\n\n function issues_archive_scroll() {\n const modal = $('#issues_archive');\n const scroll_pos = modal.scrollTop();\n if(scroll_pos > 150){\n modal.addClass('scrolled');\n } else {\n modal.removeClass('scrolled');\n }\n\n // handle hiding / showing the back & search for mobile.\n const window_width = $(window).innerWidth();\n const menu = $('.main-nav__menu');\n if(window_width > 1199){\n menu.removeClass('archive_scrolled');\n } else {\n const scrollUp = scroll_pos - 10;\n const scrollDown = scroll_pos + 10;\n setTimeout(function(){\n let newScroll = modal.scrollTop();\n if(newScroll < scrollUp){\n menu.removeClass('archive_scrolled');\n } else if(newScroll > scrollDown){\n menu.addClass('archive_scrolled');\n }\n }, 200);\n }\n }\n\n $('#issues_archive').scroll(debouncer(function(){\n issues_archive_scroll();\n }, 12));\n\n $('body').on('click', '.main-nav__toggle, .issues_close, .issues_modal__close a, a.main-nav__contents', function(e){\n e.preventDefault();\n $(this).blur();\n\n const modal = $('#issues_archive');\n if(modal.hasClass('active')){\n modal.removeClass('active').attr('aria-hidden', 'true');\n $('#primary-menu').removeClass('archive_open');\n setTimeout(function(){\n modal.scrollTop(0);\n }, 300);\n\n // Handles un-trapping focus in modal\n Modal.close($('#issues_archive'));\n\n const menu = $('.main-nav__menu');\n menu.removeClass('archive_scrolled');\n\n if($(this).hasClass('main-nav__contents')){\n $('body').removeClass('modal-active');\n Modal.open($('.main-nav__mb_menu'));\n } else if($(this).hasClass('issues_close')){\n $('body').removeClass('modal-active');\n Modal.open($('#primary-menu'));\n $('.main-nav__toggle').attr('tabindex', 1);\n } else {\n $('body').removeClass('scroll-lock modal-active');\n }\n }\n });\n\n // display editor's note modal if on issue page and not already viewed\n function editors_note(){\n if($('.newest_issue').length && !checkCookie('editors_note') && $('.modal__editor_note').length){\n const modal = $('.modal__editor_note');\n var timer = setInterval(function(){\n if(!$('body').hasClass('animate-intro')\n && !$('body').hasClass('tooltip-guide-active')\n && !$('body').hasClass('loading')){\n modal.addClass('active');\n // Handles trapping focus in modal\n Modal.open(modal);\n setCookie('STYXKEY_editors_note', 'true', 20);\n\n clearInterval(timer);\n }\n }, 3000);\n }\n }\n editors_note();\n\n // Tooltip User Guide Modal - Show users how to navigate the site on first visit\n function tooltip_guide_check(){\n if($('.tooltip_guide').length && !checkCookie('tooltip-guide')){\n var timer = setInterval(function(){\n if(!$('body').hasClass('animate-intro') && !$('body').hasClass('loading')){\n activate_tooltip_guide();\n clearInterval(timer);\n }\n }, 1000);\n }\n }\n tooltip_guide_check();\n\n function activate_tooltip_guide(){\n const tooltipGuide = $('.tooltip_guide');\n if(tooltipGuide.length){\n tooltipGuide.css({\n 'opacity' : 0,\n 'display' : 'block'\n });\n position_tooltip_guide();\n $('body').addClass('tooltip-guide-active');\n Modal.open(tooltipGuide);\n }\n setCookie('STYXKEY_tooltip-guide', 'true', 60);\n }\n\n function position_tooltip_guide(){\n if(!$('.tooltip_guide').length){\n return;\n }\n\n const active = $('.tooltip_guide__thumbs .active');\n const selector = $('#' + active.attr('data-target'));\n const tooltip = $('.tooltip_guide__content');\n const pointer = $('.tooltip_guide__pointer');\n let left = selector.offset().left + (selector.width() / 2);\n const windowWidth = $(window).innerWidth();\n const tooltipWidth = $('.tooltip_guide__tooltip').outerWidth() / 2;\n let dif;\n let pointerLeft;\n\n // // ensure tooltip stays in window\n if((left + tooltipWidth) > windowWidth) {\n dif = windowWidth - (left + tooltipWidth);\n left = left + dif - 20;\n pointerLeft = tooltipWidth - dif + 20;\n }\n else if((left - tooltipWidth) < 0) {\n dif = left - tooltipWidth;\n left = left - dif + 20;\n pointerLeft = tooltipWidth + dif - 20;\n }\n else {\n pointerLeft = '50%';\n }\n\n $('.tooltip_guide__tooltip').css({\n 'left' : left\n });\n pointer.css({\n 'left' : pointerLeft,\n });\n }\n\n function tooltipContent() {\n const active = $('.tooltip_guide__thumbs .active');\n const header = active.attr('data-heading');\n const content = active.attr('data-content');\n const elHeader = $('.tooltip_guide h2');\n const p = $('.tooltip_guide p');\n console.log(p);\n\n elHeader.text(header);\n p.text(content);\n }\n\n function show_hide_next(){\n const active = $('.tooltip_guide__thumbs .active').parent();\n const next = $('.tooltip_guide__next');\n const text = {\n 'next' : next.attr('data-next'),\n 'done' : next.attr('data-done')\n }\n\n if(!active.length){\n return;\n }\n\n if(active.is(':last-child')){\n next.addClass('finished');\n next.find('span.text').text(text.done);\n } else {\n next.removeClass('finished');\n next.find('span.text').text(text.next);\n }\n }\n\n function closeTooltipGuide(){\n const tooltip = $('.tooltip_guide');\n Modal.close(tooltip);\n tooltip.fadeOut();\n $('body').removeClass('tooltip-guide-active');\n }\n\n $('body').on('click', '.tooltip_guide__thumbs a', function(e){\n e.preventDefault();\n if($(this).hasClass('active')){\n return;\n }\n\n $('.tooltip_guide__thumbs .active').removeClass('active');\n $(this).addClass('active').blur();\n tooltipContent();\n position_tooltip_guide();\n show_hide_next();\n });\n\n $('body').on('click', '.tooltip_guide__next', function(e){\n e.preventDefault();\n // $(this).blur();\n if($(this).hasClass('finished')){\n closeTooltipGuide();\n }\n else {\n const active = $('.tooltip_guide__thumbs a.active');\n active.removeClass('active').parent().next().find('a').addClass('active');\n tooltipContent();\n position_tooltip_guide();\n show_hide_next();\n }\n });\n\n $('.tooltip_guide__close a').click(function(e){\n e.preventDefault();\n $(this).blur();\n closeTooltipGuide();\n });\n\n $('body').on('click', '.tooltip_guide', function(e){\n if($(e.target).hasClass('tooltip_guide')){\n closeTooltipGuide();\n }\n });\n\n $(window).resize(debouncer(function(){\n position_tooltip_guide();\n }, 20));\n});\n", "import Modal from './accessibility';\nimport Dom from '../Utility/Dom';\nimport {debouncer} from './utils';\n\n$(document).ready(() => {\n function bodyScrollLock(){\n const nav = $('#primary-menu');\n\n if(nav.find('.main-nav__mb_menu').css('display') == 'block' && (nav.hasClass('active') || nav.hasClass('mb_active'))){\n $('body').addClass('scroll-lock nav-open');\n }else if($('body').hasClass('modal-active') && $('body').hasClass('nav-open')){\n $('body').removeClass('nav-open');\n } else if($('body').hasClass('nav-open')) {\n $('body').removeClass('scroll-lock nav-open');\n }\n }\n\n const toggle = $('.main-nav__toggle');\n const menu = $('#primary-menu');\n\n toggle.click(function(e){\n e.preventDefault();\n toggle.blur();\n toggle.toggleClass('active');\n menu.toggleClass('active').removeClass('mb_active');\n\n if(toggle.hasClass('active')){\n toggle.attr('aria-expanded', 'true');\n Modal.open(menu);\n toggle.attr('tabindex', 1);\n } else {\n toggle.attr('aria-expanded', 'false');\n Modal.close(menu);\n setTimeout(function(){\n menu.scrollTop(0);\n }, 500);\n }\n\n bodyScrollLock();\n });\n\n\n // Handle issue contents menu trigger on desktop\n $('.main-nav__contents').click(function(e){\n e.preventDefault();\n $(this).blur().toggleClass('active');\n menu.toggleClass('mb_active').removeClass('active');\n toggle.removeClass('active').attr('aria-expanded', 'false');\n\n if($(this).hasClass('active')){\n $(this).attr('aria-expanded', 'true');\n $('.main-nav__mb_menu .btn__close').attr('aria-expanded', 'true');\n if($('#issues_archive').hasClass('active')){\n Modal.open($('.main-nav__mb_menu'));\n }\n } else {\n $(this).attr('aria-expanded', 'false');\n $('.main-nav__mb_menu .btn__close').attr('aria-expanded', 'false');\n Modal.close(menu);\n }\n\n bodyScrollLock();\n });\n\n // Close issues content on desktop\n $('.main-nav__mb_menu .btn__close').click(function(e){\n e.preventDefault();\n $(this).blur();\n menu.removeClass('mb_active');\n $('.main-nav__contents').attr('aria-expanded', 'false');\n $(this).attr('aria-expanded', 'false');\n Modal.close(menu);\n bodyScrollLock();\n })\n\n // Hide the nav when scrolling down, show when scrolling up\n function masthead_scroll(){\n const windowScroll = $(window).scrollTop();\n\n // first, make sure the header is shown when near the top of the page\n if(windowScroll < 300){\n $('body').removeClass('header_hidden');\n }\n // otherwise, check if we're scrolling up or down\n else {\n const scrollUp = windowScroll - 10;\n const scrollDown = windowScroll + 10;\n setTimeout(function(){\n let newScroll = $(window).scrollTop();\n if(newScroll < scrollUp){\n $('body').removeClass('header_hidden');\n } else if(newScroll > scrollDown){\n $('body').addClass('header_hidden');\n }\n }, 200);\n }\n }\n\n // Handle language switch for mobile\n $('body').on('click', '.current-lang a', function(e){\n e.preventDefault();\n });\n\n $( window ).resize(debouncer(function ( e ) {\n bodyScrollLock();\n }, 20 ) );\n\n $( window ).scroll(debouncer(function ( e ) {\n masthead_scroll();\n }, 10 ) );\n\n\n // Guitar Guide Nav\n $('.gg_nav__l1 > a').click(function(e){\n e.preventDefault();\n $(this).blur();\n\n if($(this).closest('.gg_nav').hasClass('has_multiple')){\n if($(this).hasClass('active')){\n // $(this).removeClass('active').next('ul').slideUp().attr('aria-hidden', 'true');\n return;\n }\n\n const active = $('.gg_nav__l1 > a.active');\n active.removeClass('active').next('ul').slideUp().attr('aria-hidden', 'true');\n $(this).addClass('active').next('ul').slideDown().attr('aria-hidden', 'false');\n }\n });\n\n $('.gg_nav li a').click(function(e){\n // On mobile, close the nav when secondary list items are clicked\n if($(this).closest('.gg_nav').find('.gg_nav__close').is(':visible') && $(this).parent().hasClass('gg_nav__l2')){\n $('.gg_nav').removeClass('active').attr('aria-hidden', 'true');\n }\n });\n\n $('.gg_nav__open').click(function(e){\n e.preventDefault();\n $(this).blur();\n\n const target = $('.gg_nav');\n\n target.toggleClass('active');\n\n if(target.attr('aria-hidden') == 'false'){\n target.attr('aria-hidden', 'true');\n }\n else {\n target.attr('aria-hidden', 'false');\n }\n });\n\n $('.gg_nav__close a').click(function(e){\n e.preventDefault();\n $('.gg_nav').removeClass('active').attr('aria-hidden', 'true');\n });\n\n function gg_nav_mobile_scroll_reveal(){\n if($('.hero').length){\n const windowTop = $(window).scrollTop();\n const trigger = $('.hero').outerHeight() / 1.5;\n\n if(windowTop > trigger){\n $('body').addClass('page_scrolled').removeClass('page_top');\n }\n else {\n $('body').removeClass('page_scrolled').addClass('page_top');\n }\n }\n }\n gg_nav_mobile_scroll_reveal();\n\n function gg_nav_responsive(){\n if($('.gg_nav__open').is(':hidden')){\n $('.gg_nav').attr('aria-hidden', 'false');\n }\n else if(!$('.gg_nav').attr('aria-hidden')\n || ($('.gg_nav').attr('aria-hidden') == 'false' && $('.gg_nav').is(':hidden'))){\n $('.gg_nav').attr('aria-hidden', 'true');\n }\n }\n gg_nav_responsive();\n\n $(window).resize(debouncer(function(){\n gg_nav_responsive();\n }, 30));\n\n $(window).scroll(debouncer(function(){\n gg_nav_mobile_scroll_reveal();\n }, 20));\n});\n", "jQuery(document).ready(function($){\n\n // Oversized Heading Block : Font Sizing function\n function oversized_heading(){\n $('.oversized_heading.default-size').each(function(){\n const container = $(this);\n const heading = container.find('h2');\n let window_width = $(window).innerWidth();\n let new_font_size;\n let image_margin_top;\n\n if($('.wp-admin').length){\n window_width = $('.block-editor-editor-skeleton__content').innerWidth();\n }\n\n const sizing = setInterval(function(){\n let heading_width = heading.outerWidth();\n let heading_size = parseFloat(heading.attr('data-size'));\n heading_size = Math.round((heading_size + Number.EPSILON) * 100) / 100;\n\n // Get the character count, as this will affect the rate at which we try increasing the font, as well as it's width threshold\n let charCount = heading.html().length;\n\n // Deterimine how much to increase the font size each iteration (measured in vw)\n let increase = 1 - (charCount * 0.05);\n if(increase < 0.1){\n increase = 0.1;\n }\n\n // Set the default thresholds. For Longer character count we need to increase the difference between the threshold, since the font size increase has more of a dramatic effect\n let threshold_max = window_width + (window_width / (charCount * .7));\n let threshold_min = window_width + ((window_width / charCount) / 1.3);\n\n // console.log('threshold min: ' + threshold_min + '; threshold max: ' + threshold_max + '; heading_width: ' + heading_width);\n\n // first, check if sizing is needed at all. We want the heading width to land between the threshold declared above; If it is, we quit\n if((heading_width > threshold_min && heading_width < threshold_max) || heading_size > 50){\n heading.removeClass('sizing');\n clearInterval(sizing);\n return;\n } else {\n heading.addClass('sizing');\n }\n\n // If it's too small, we'll increase the font size\n if(heading_width < threshold_min){\n new_font_size = heading_size + increase;\n }\n // Else, if it's too large, we'll decrease the font size\n else if(heading_width > threshold_max){\n new_font_size = heading_size - increase;\n }\n\n image_margin_top = (new_font_size * .28) * -1;\n\n heading.css('font-size', new_font_size + 'vw').attr('data-size', new_font_size);\n\n if(container.hasClass('overlap_image')){\n container.find('figure').css({\n 'top' : image_margin_top + 'vw',\n 'margin-bottom' : image_margin_top + 'vw'\n });\n }\n\n // now check if we need to continue looping\n if(heading.outerWidth() > threshold_min && heading.outerWidth() < threshold_max){\n heading.removeClass('sizing');\n clearInterval(sizing);\n }\n }, 1);\n });\n }\n oversized_heading();\n\n // for wp-admin pages, check if blocks are loaded\n if($('.wp-admin').length){\n setInterval(function(){\n oversized_heading();\n },1500);\n }\n});\n", "jQuery(document).ready(function($){\n $('.audio_controls__wrap').each(function(){\n const container = $(this);\n const player = $(this).next('audio');\n const target = player[0];\n const play_button = $(this).find('.audio_controls__play');\n const external_button = $(this).find('.audio_controls__external');\n\n // Toggle play/pause button\n play_button.click(function(e){\n e.preventDefault();\n $(this).blur();\n\n if (target.paused) {\n target.play();\n }\n else {\n target.pause();\n }\n play_button.toggleClass('pause');\n });\n\n external_button.click(function(e){\n $(this).blur();\n target.pause();\n play_button.removeClass('pause');\n });\n\n player.bind('timeupdate', function(){\n let duration = target.duration;\n let currentTime = Math.round(target.currentTime);\n let progress = (currentTime / duration) * 100;\n\n // update the progress bar width\n container.find('.audio_controls__progress .bar').css('width', progress + '%');\n\n // set the current time display\n let minutes = Math.floor(currentTime / 60);\n let seconds;\n if(minutes > 0){\n seconds = currentTime - (minutes * 60);\n } else {\n seconds = currentTime;\n }\n let digits = seconds.toString().length;\n if(digits < 2){\n seconds = '0' + seconds;\n }\n\n container.find('.audio_controls__time').html(minutes + ':' + seconds);\n });\n\n // when track is complete\n player.bind('ended', function(){\n // add class to progress bar to prevent css transition while the bar resets, then remove it to resume transitions\n const progress_bar = container.find('.audio_controls__progress .bar');\n progress_bar.addClass('no_transition').css('width', '0');\n setTimeout(function(){\n progress_bar.removeClass('no_transition');\n }, 100);\n\n\n // Check if we're not on a slider, or if we're on the last slide.\n let controls_slider = false;\n let last_slide = false;\n\n if(container.hasClass('controls_playlist')){\n controls_slider = true;\n\n const playlist = container.closest('.playlist__wrap').find('.playlist__slider');\n const active_track = playlist.find('.track.active').closest('.slick-slide');\n if(active_track.is(':last-child')) {\n last_slide = true;\n }\n }\n\n if(!controls_slider || last_slide) {\n play_button.removeClass('pause');\n }\n });\n\n // if we're in an .audio_cta block, control the player with the image above\n if(container.parent().hasClass('audio_cta__player')){\n const cta_trigger = container.parent().prev().find('a');\n cta_trigger.click(function(e){\n e.preventDefault();\n cta_trigger.blur().toggleClass('playing');\n\n if(cta_trigger.hasClass('playing')){\n cta_trigger.find('span').html('Click to Pause');\n } else {\n const original_text = cta_trigger.find('span').attr('data-original');\n cta_trigger.find('span').html(original_text);\n }\n\n play_button.trigger('click');\n });\n }\n });\n});\n", "jQuery(document).ready(function ($) {\n // Home Hero Animation\n function home_hero_animation() {\n const tl = gsap.timeline();\n const hero_left = $(\".issue_hero__left, .hero .section__label, .issue_hero__guide\");\n const hero_right = $(\".issue_hero__right\");\n const hero_overlay = $(\".hero .overlay\");\n const overlay_opacity = hero_overlay.attr(\"data-opacity\");\n let delay = 0.4;\n if ($(\"body\").hasClass(\"animate-intro\")) {\n delay = 0;\n }\n\n tl.add(\"hero_in\", delay).from(hero_left, 1.5, { x: \"-50%\", ease: Power4.easeOut }, \"hero_in\");\n if (hero_right.length) {\n tl.from(hero_right, 1.5, { x: \"50%\", ease: Power4.easeOut }, \"hero_in\").fromTo(\n [hero_left, hero_right],\n { autoAlpha: 0, ease: Power4.easeOut },\n { autoAlpha: 1 },\n \"hero_in\"\n );\n } else {\n tl.fromTo(hero_left, { autoAlpha: 0, ease: Power4.easeOut }, { autoAlpha: 1 }, \"hero_in\");\n }\n tl.fromTo(hero_overlay, { autoAlpha: 0, ease: Power4.easeOut }, { autoAlpha: overlay_opacity }, \"hero_in\").add(function () {\n // take off the inline css now that the hero animations are done to allow stylesheets to act responsively\n hero_left.css({ transform: \"\" });\n });\n\n tl.pause();\n tl.resume();\n }\n\n if ($(\"body\").hasClass(\"home\") && !$(\"body\").hasClass(\"animate-intro\")) {\n $(\"body\").on(\"tdAnimate\", home_hero_animation());\n }\n\n // Home Logo animation\n function home_animation() {\n const tl = gsap.timeline();\n const logo = $(\".site-branding\");\n const amp_red = logo.find(\"#amp-path\");\n const amp_black = logo.find(\"#amp-path-black\");\n const wood = logo.find(\"#w, #o-1, #o-2, #d\");\n const steel = logo.find(\"#s, #t, #e-1, #e-2, #l\");\n const content = $(\"#content\");\n const above_logo = $(\".taylor-logo\");\n const below_logo = $(\".site-description\");\n const header = $(\"#masthead\");\n const nav = $(\".main-nav\");\n const hero_elems = $(\".issue_hero__left, .hero .section__label, .issue_hero__right, .hero .overlay\");\n const window_width = $(window).innerWidth();\n const window_height = $(window).innerHeight();\n let intro_height;\n let tagline_pos;\n\n // determine the height of the intro based on aspect ratio / screen height\n if (window_width < window_height) {\n intro_height = window_height * 0.65;\n } else if (window_height < 700) {\n intro_height = window_height - 50;\n tagline_pos = intro_height - 25;\n } else {\n intro_height = window_height * 0.75;\n }\n\n // determine placement of the site tagline\n if (!tagline_pos) {\n if (window_width < 500) {\n tagline_pos = intro_height - 25;\n } else if (window_width < 769) {\n tagline_pos = intro_height - 50;\n } else {\n tagline_pos = intro_height - 75;\n }\n }\n\n $(\"body\").addClass(\"scroll-lock\");\n\n tl.add(\"animStart\", 0.5)\n .set(below_logo, { top: tagline_pos })\n .set(hero_elems, { autoAlpha: 0 }, 0.5)\n // .staggerFrom(wood, 1, {yPercent:-50, autoAlpha:0, ease: Power4.easeInOut}, .1, \"animStart\")\n // .staggerFrom(steel, 1, {yPercent:50, autoAlpha:0, ease: Power4.easeInOut}, .1, \"animStart\")\n // .from(amp_black, 1.5, {drawSVG: 0, ease: Expo.easeInOut}, \"animStart\")\n // .from(amp_red, 1.5, {drawSVG: 0, ease: Expo.easeInOut}, \"animStart+=.2\")\n .add(\"logoEnd\", \"+=1\")\n .from(logo, 1.75, { width: 1160, height: intro_height, x: \"-50%\", y: \"-50%\", left: \"50%\", top: intro_height / 2, ease: \"power4.inOut\" }, \"logoEnd\")\n .from(header, 1.5, { height: intro_height, ease: Power4.easeIn }, \"logoEnd\")\n .from(content, 1.5, { marginTop: intro_height, ease: Power4.easeIn }, \"logoEnd\")\n .to(above_logo, 0.5, { y: 20, autoAlpha: 0, ease: Power4.easeInOut }, \"logoEnd\")\n .to(below_logo, 0.5, { y: 20, autoAlpha: 0, ease: Power4.easeInOut }, \"logoEnd\")\n .from(nav, 0.5, { y: \"-105%\", autoAlpha: 0, ease: Power4.easeOut }, \"logoEnd+=1.25\")\n .add(function () {\n // take off the inline css now that the header animations are done to allow stylesheets to act responsively\n logo.css({ top: \"\", left: \"\", height: \"\", transform: \"\", width: \"\" });\n header.css({ height: \"\" });\n content.css({ \"margin-top\": \"\" });\n nav.css({ transform: \"\", opacity: \"\" });\n $(\"body\").removeClass(\"scroll-lock animate-intro\");\n })\n .add(function () {\n home_hero_animation();\n }, \"-=.5\");\n\n tl.pause();\n tl.resume();\n }\n // Check if we're on the front page, on the first load\n if ($(\"body\").hasClass(\"animate-intro\")) {\n $(\"body\").on(\"tdAnimate\", home_animation());\n }\n\n // Interactive Section SVG animations\n $(\".interactive-anim-circle\").each(function () {\n const tl = gsap.timeline({ repeat: -1 });\n const elem = $(this);\n\n tl.fromTo(elem, { rotation: 0, transformOrigin: \"50% 50%\" }, { rotation: 360, duration: 16, ease: \"none\" });\n tl.pause();\n tl.resume();\n });\n\n // Single Story Hero animation\n function single_hero_animation() {\n const tl = gsap.timeline();\n const breadcrumbs = $(\".hero__breadcrumb\");\n const scroll_button = $(\".hero__scroll\");\n const content = $(\".single_hero__content\");\n\n tl.from(content, { xPercent: -50, ease: Power4.easeOut, duration: 1, delay: 0.75, autoAlpha: 0 })\n .add(\"secondary\", \"-=1\")\n .from(breadcrumbs, { autoAlpha: 0, ease: Power4.easeOut }, \"secondary\")\n .from(scroll_button, { y: \"-100px\", autoAlpha: 0, ease: Power4.easeOut }, \"secondary\")\n .add(function () {\n scroll_button.css({ transform: \"\" });\n breadcrumbs.css({ transform: \"\" });\n });\n }\n\n $(\"body\").on(\"tdAnimate\", single_hero_animation());\n});\n", "import {debouncer} from './utils';\n\n$(document).ready(() => {\n if($('.timeline').length){\n const tl_breakpoint = 767;\n\n // Main Slider\n $('.timeline__slider').each(function(){\n const slider = $(this);\n\n const sliderArgs = {\n 'arrows' : false,\n 'infinite' : false,\n 'autoplay' : false,\n 'dots' : false,\n 'adaptiveHeight' : true,\n\n responsive: [\n {\n breakpoint: tl_breakpoint,\n settings: \"unslick\"\n }\n ]\n }\n\n slider.slick(sliderArgs);\n\n // On slide change, change the active nav and reposition the nav if needed\n slider.on('beforeChange', function(event, slick, currentSlide, nextSlide){\n const nav = slider.closest('.timeline').find('.timeline__nav');\n const newActiveNavItem = nav.find('li').eq(nextSlide).find('a');\n change_tl_slide(newActiveNavItem, false);\n position_tl_nav(newActiveNavItem, nav);\n stop_timeline_videos(slider, currentSlide);\n });\n\n // Reslick the slider if resizing from less than breakpoint to larger.\n $(window).resize(debouncer(function(){\n const windowWidth = window.innerWidth;\n if(windowWidth > tl_breakpoint && !slider.hasClass('slick-initialized')){\n slider.slick(sliderArgs);\n\n // Reset Slider Nav\n const sliderNav = slider.closest('.timeline').find('.timeline__nav');\n const active = sliderNav.find('li:first-child a');\n change_tl_slide(active, false);\n timeline_nav_underline_pos(active, sliderNav);\n }\n }, 15));\n });\n\n\n // Stop timeline videos from playing on slide change\n function stop_timeline_videos(timeline, currentSlideIndex){\n const slide = timeline.find('.slick-slide').eq(currentSlideIndex);\n\n if(slide.find('.video_poster').length && !slide.find('.video_poster').is(':visible')) {\n console.log('running');\n\n // Reset video play button\n slide.find('.video_poster').fadeIn();\n\n // Pause / Reset Video\n if(slide.find('iframe').length){\n const src = slide.find('iframe').attr('src');\n const newSrc = src.replace(\"&autoplay=true\", \"\");\n slide.find('iframe').attr('src', newSrc);\n } else if(slide.find('video').length) {\n slide.find('video')[0].pause();\n }\n }\n else {\n console.log('not running');\n }\n }\n\n\n // Change slide when clicking on an inactive slide (desktop)\n $('body').on('click', '.timeline .slick-slide', function(e){\n if($(this).hasClass('slick-current')){\n return;\n }\n\n const index = $(this).index();\n $(this).closest('.timeline__slider').slick('slickGoTo', index);\n });\n\n\n // Nav Arrow Button Click\n $('body').on('click', '.timeline__arrow', function(e){\n const nav = $(this).closest('.timeline__nav');\n const active = nav.find('a.active');\n const activeParent = active.parent('li');\n const direction = $(this).hasClass('left') ? 'left' : 'right';\n let newActive = false;\n\n if(direction == 'left' && activeParent.not(':first-child')){\n newActive = activeParent.prev().find('a');\n }\n else if(direction == 'right' && activeParent.not(':last-of-type')){\n newActive = activeParent.next().find('a');\n }\n\n if(newActive){\n change_tl_slide(newActive);\n }\n });\n\n\n // Nav Label Links click\n $('body').on('click', '.timeline__nav_link', function(e){\n const el = $(this);\n change_tl_slide(el);\n\n // For mobile\n const windowWidth = window.innerWidth;\n if(windowWidth <= tl_breakpoint){\n const timeline = el.closest('.timeline');\n timeline.addClass('scrolling');\n setTimeout(function(){\n timeline.removeClass('scrolling');\n }, 1000);\n const index = el.parent().index();\n const slide = timeline.find('.timeline__slide').eq(index);\n set_mobile_active_class(slide, timeline);\n }\n });\n\n\n function change_tl_slide(newActiveEl, changeSlider = true){\n const nav = newActiveEl.closest('.timeline__nav');\n const active = nav.find('a.active');\n const windowWidth = window.innerWidth;\n\n // Change nav label class if not already active\n if(active !== newActiveEl){\n active.removeClass('active');\n newActiveEl.addClass('active');\n }\n\n // Move underline\n timeline_nav_underline_pos(newActiveEl, nav);\n\n // Change the main slider active slide\n if(changeSlider){\n // Reposition the nav if needed\n position_tl_nav(newActiveEl, nav);\n\n if(windowWidth > tl_breakpoint){\n const slider = nav.closest('.timeline').find('.timeline__slider');\n const index = newActiveEl.parent().index();\n slider.slick('slickGoTo', index);\n }\n }\n }\n\n\n function timeline_nav_underline_pos(activeEl, nav){\n const windowWidth = window.innerWidth;\n\n if(windowWidth >= tl_breakpoint){\n const listPaddingLeft = Math.round(parseInt(nav.find('ul').css('padding-left')));\n const activeLI = activeEl.parent('li');\n const activeLeft = Math.round(activeLI.position().left);\n const activeWidth = Math.round(activeLI.outerWidth());\n const underline = nav.find('.timeline__nav_underline');\n\n underline.css({'width' : activeWidth, 'left' : activeLeft});\n }\n }\n // Run on load.\n function timeline_nav_underline_init(){\n $('.timeline__nav').each(function(){\n const active = $(this).find('a.active').length ? $(this).find('a.active') : $(this).find('li:first-child a');\n timeline_nav_underline_pos(active, $(this));\n });\n }\n timeline_nav_underline_init();\n\n\n\n function position_tl_nav(activeEl, nav){\n const windowWidth = window.innerWidth;\n const navList = nav.find('ul');\n\n // Set up variables that may be different for desktop vs mobile due to orientation change.\n let navLeftPos,\n navRightPos,\n screenCenter,\n activeCenter,\n centerDif,\n navWidth,\n scrollToPos;\n\n // Desktop Nav\n if(windowWidth > tl_breakpoint){\n navWidth = navList.outerWidth()\n navLeftPos = navList.offset().left;\n navRightPos = navLeftPos + navWidth;\n screenCenter = windowWidth / 2;\n activeCenter = activeEl.offset().left + (activeEl.outerWidth() / 2);\n\n // 1. If the nav is not as wide as the window, set left position to 0\n if(navWidth < windowWidth){\n scrollToPos = 0;\n }\n // 2. Else if the active nav item is left of screen center\n else if(activeCenter < screenCenter){\n centerDif = Math.round(screenCenter - activeCenter);\n\n // Check if scrolling centerDif would overscroll the left edge.\n if(navLeftPos < 0 && (navLeftPos * -1) > centerDif){\n scrollToPos = navLeftPos + centerDif;\n }\n // Else, set the nav to the edge of the window\n else {\n scrollToPos = 0;\n }\n }\n // 3. Else if the active nav item is right of screen center\n else if(activeCenter > screenCenter){\n centerDif = Math.round(activeCenter - screenCenter);\n\n // Check if scrolling centerDif would overscroll the right edge.\n if(navRightPos > windowWidth && (navRightPos - windowWidth) > centerDif){\n scrollToPos = navLeftPos - centerDif;\n }\n // Else, set the nav to the edge of the window\n else {\n scrollToPos = (navWidth * -1) + windowWidth;\n }\n }\n\n // Set Nav Left Position\n navList.css('left', scrollToPos);\n }\n }\n\n\n // used to size list items to allow for vertical scrolling while items are rotated\n function size_nav_items_for_mobile(){\n const windowWidth = window.innerWidth;\n\n $('.timeline__nav').each(function(){\n // mobile nav\n if(windowWidth <= tl_breakpoint && !$(this).hasClass('mobile-sized')){\n $(this).addClass('mobile-sized');\n $(this).find('li').each(function(){\n const link = $(this).find('a');\n const width = link.outerWidth();\n const height = link.outerHeight();\n\n $(this).css({'width': height, 'height' : width});\n });\n }\n // else, remove sizing\n else if(windowWidth > tl_breakpoint && $(this).hasClass('mobile-sized')){\n $(this).removeClass('mobile-sized').find('li').css({'width': '', 'height': ''});\n }\n });\n }\n size_nav_items_for_mobile();\n\n\n // Handle fixed nav positioning, and setting mobile active class based on scroll position.\n function tl_scroll(){\n const windowWidth = window.innerWidth;\n const windowTop = Math.round($(document).scrollTop());\n const windowBottom = Math.round(windowTop + window.innerHeight);\n const windowCenter = Math.round(windowTop + (window.innerHeight / 2));\n\n $('.timeline').each(function(){\n const timeline = $(this);\n const timelineTop = timeline.offset().top;\n const timelineBottom = timelineTop + timeline.outerHeight();\n const timelineCenter = timelineTop + (timeline.outerHeight() / 2);\n\n\n // Mobile Specific Scroll Functions\n if(windowWidth <= tl_breakpoint){\n // Scroll to then fixed functionality. (Mobile)\n if(timelineTop > windowTop){\n if(!timeline.hasClass('nav-absolute-top')){\n timeline.addClass('nav-absolute-top');\n timeline.removeClass('nav-fixed');\n }\n }\n else if(timelineBottom < windowBottom){\n if(!timeline.hasClass('nav-absolute-bottom')){\n timeline.addClass('nav-absolute-bottom');\n timeline.removeClass('nav-fixed');\n }\n }\n else if(!timeline.hasClass('nav-fixed')){\n timeline.addClass('nav-fixed');\n timeline.removeClass('nav-absolute-bottom');\n timeline.removeClass('nav-absolute-top');\n }\n\n // Handle active class\n if(!timeline.hasClass('scrolling')){\n timeline.find('.timeline__slide').each(function(){\n const slide = $(this);\n const margin_bottom = parseInt(slide.css('margin-bottom'));\n const elTop = slide.offset().top;\n const elBottom = elTop + slide.outerHeight() + margin_bottom;\n\n if(elTop <= windowCenter && elBottom > windowCenter){\n set_mobile_active_class(slide, timeline);\n }\n else if(slide.is(':first-child') && elTop > windowCenter){\n set_mobile_active_class(slide, timeline);\n }\n else if(slide.is(':last-child') && elBottom < windowCenter){\n set_mobile_active_class(slide, timeline);\n }\n });\n }\n\n // Remove classes that may be present from desktop\n $('.timeline.nav-fade-out').removeClass('nav-fade-out');\n }\n else { // (Desktop)\n // Hide nav near top of timeline component\n if(windowBottom - timelineTop <= 100 ){\n if(!timeline.hasClass('nav-fade-out')){\n timeline.addClass('nav-fade-out');\n }\n } else if(timeline.hasClass('nav-fade-out')){\n timeline.removeClass('nav-fade-out');\n }\n\n // Scroll to then fixed functionality.\n if(timelineBottom < windowBottom){\n if(timeline.hasClass('nav-fixed')){\n timeline.removeClass('nav-fixed');\n }\n }\n else if(!timeline.hasClass('nav-fixed')){\n timeline.addClass('nav-fixed');\n timeline.removeClass('nav-fade-out');\n }\n\n // Remove classes that may be present from mobile sizes.\n $('.timeline').find('.mobile-active').removeClass('mobile-active');\n }\n });\n }\n tl_scroll();\n\n function set_mobile_active_class(slide, timeline){\n if(!slide.hasClass('mobile-active')){\n slide.addClass('mobile-active');\n timeline.find('.mobile-active').not(slide).removeClass('mobile-active');\n\n const index = slide.index();\n const navLabel = timeline.find('.timeline__nav li').eq(index).find('a');\n timeline.find('.timeline__nav .active').not(navLabel).removeClass('active');\n navLabel.addClass('active');\n\n // scroll to active nav label\n const activeTop = navLabel.position().top;\n const listPaddingTop = parseInt(timeline.find('.timeline__nav ul').css('padding-top'));\n const scrollTop = Math.round(activeTop - listPaddingTop - 60);\n\n timeline.find('.timeline__nav').stop().animate({scrollTop: scrollTop}, 200);\n }\n }\n\n $(window).resize(debouncer(function(){\n $('.timeline__nav').each(function(){\n const nav = $(this);\n const active = nav.find('a.active');\n position_tl_nav(active, nav);\n });\n\n size_nav_items_for_mobile();\n tl_scroll();\n timeline_nav_underline_init();\n }, 20));\n\n $(window).scroll(debouncer(function(){\n tl_scroll();\n }, 10));\n }\n});\n", "import {debouncer} from './utils';\nimport Modal from './accessibility';\n\n$(document).ready(() => {\n const sidebars = $('.fixed_sidebar');\n const sidebarCount = sidebars.length;\n\n if(sidebarCount){\n $('.entry-content').css('position', 'relative');\n\n sidebars.each(function(index){\n const sidebar = $(this);\n const sidebarIndex = index + 1;\n let entryContent = getEntryContentDetails();\n\n init_sidebar(sidebar, sidebarIndex, sidebarCount);\n\n $(window).resize(function(){\n entryContent = getEntryContentDetails();\n\n init_sidebar(sidebar, sidebarIndex, sidebarCount, entryContent);\n });\n\n $(window).scroll(debouncer(function(){\n setTopPos(sidebar, sidebarIndex, sidebarCount, entryContent);\n }, 5));\n\n // Open Modal\n sidebar.find('.trigger').on('click', function(e){\n e.preventDefault();\n $(this).blur();\n const target = sidebar.next('.fixed_sidebar__modal');\n\n target.addClass('active').attr('aria-hidden', 'false');\n\n // Handles trapping focus in modal\n Modal.open(target);\n\n $('body').addClass('hidePageProgress');\n });\n });\n\n $('.fixed_sidebar__close').on('click', function(e){\n e.preventDefault();\n $(this).blur();\n const target = $(this).closest('.fixed_sidebar__modal');\n\n target.removeClass('active').attr('aria-hidden', 'true');\n\n // Handles trapping focus in modal\n Modal.close(target);\n\n $('body').removeClass('hidePageProgress');\n\n // Set the inner content back to the top\n setTimeout(function(){\n target.find('.fixed_sidebar__modal_inner').scrollTop(0);\n }, 400);\n });\n }\n\n // Run on page load and window resize\n function init_sidebar(sidebar, index, sidebarCount, entryContent){\n windowWidth = window.innerWidth;\n\n if(!sidebar.hasClass('visible')){\n sidebar.addClass('visible');\n }\n\n setRightPos(sidebar, windowWidth);\n setTopPos(sidebar, index, sidebarCount, entryContent);\n }\n\n function setRightPos(sidebar, windowWidth){\n const parent = sidebar.parent().parent();\n let right = 0;\n\n if(parent.hasClass('container')){\n const parentWidth = parent.outerWidth();\n const parentRight = parent.offset().left + parentWidth;\n right = parentRight - $(window).innerWidth();\n }\n\n sidebar.attr('data-right', right);\n }\n\n function setTopPos(sidebar, index, sidebarCount, entryContent){\n if(entryContent){\n const windowScroll = $(window).scrollTop();\n const elHeight = sidebar.outerHeight();\n const paddingTop = 150;\n const windowTriggerTop = windowScroll + paddingTop;\n const windowTriggerBottom = windowTriggerTop + elHeight;\n const activeHeight = Math.round(entryContent.height / sidebarCount);\n const activeTriggerTop = (activeHeight * (index -1)) + entryContent.top;\n const activeTriggerBottom = activeTriggerTop + activeHeight;\n const parent = sidebar.parent().parent();\n let position = 'absolute';\n let right = parseInt(sidebar.attr('data-right'));\n let top = '';\n let bottom = '';\n let check = '';\n\n // Fixed Position\n if(windowTriggerTop >= activeTriggerTop && windowTriggerBottom < activeTriggerBottom){\n position = 'fixed';\n top = paddingTop;\n check = 'first';\n right = 0;\n }\n // Position Absolute\n else {\n // scrolled below active position\n if(windowTriggerTop >= activeTriggerTop && windowTriggerBottom >= activeTriggerBottom){\n if(parent.hasClass('container')){\n sidebar.css({'top':'auto', 'bottom':'0'});\n bottom = (parent.offset().top + parent.outerHeight()) - activeTriggerBottom;\n check = 'second';\n }\n else {\n top = (activeHeight * index) - elHeight;\n check = 'third';\n }\n }\n // scrolled above active position\n else {\n check = 'fourth';\n if(parent.hasClass('container')){\n const parentTop = parent.offset().top;\n top = entryContent.top - parentTop;\n }\n else {\n top = activeHeight * (index - 1);\n }\n }\n }\n\n // Set CSS\n sidebar.css({'position': position, 'top': top, 'bottom': bottom, 'right': right});\n }\n }\n\n function getEntryContentDetails(){\n const entryContent = $('.entry-content');\n const height = entryContent.innerHeight();\n const top = entryContent.offset().top;\n const bottom = top + height;\n\n const details = {\n height : height,\n top : top,\n bottom : bottom\n };\n\n return details;\n }\n\n // handle fading in the modal heading\n $('.fixed_sidebar__modal_inner').on('scroll', function(){\n const scrollPos = $(this).scrollTop();\n const heading = $(this).prev().find('h2');\n\n if(scrollPos > 200){\n heading.addClass('active');\n }\n else {\n heading.removeClass('active');\n }\n });\n});\n", "import \"../css/sass/styles.scss\";\n\nimport {debouncer, waitForFinalEvents, setCookie, getCookie, checkCookie} from './components/utils';\nimport slider from './components/slider';\nimport './components/tooltip-image';\nimport './components/qa-accordion.js';\nimport './components/body-guide.js';\nimport './components/guitar-guide-filter.js';\nimport modal from './components/modal';\nimport './components/nav';\nimport './components/oversized-headings';\nimport './components/audio-controls';\nimport './components/svg-animations';\nimport './components/timeline';\nimport './components/fixed-sidebar';\n\nfunction id(v){ return document.getElementById(v); }\n\n/*\n YOUTUBE VIDEO\n */\nfunction onYouTubeIframeAPIReady() {\n // 1. This function creates an