{"version":3,"file":"app.bundle.js","sources":["../frontend/legacy-frontend/vendor/toc/bootstrap-toc.js","../frontend/legacy-frontend/js/flatpickr/flatpickr-config.js","../frontend/legacy-frontend/js/components/site-menu.js","../frontend/legacy-frontend/js/components/site-menu-responsive.js","../frontend/legacy-frontend/js/components/find-on-page-responsive.js","../frontend/legacy-frontend/js/components/context-menu.js","../frontend/legacy-frontend/js/components/youtube-block.js","../frontend/legacy-frontend/js/components/occurance-switcher.js","../frontend/legacy-frontend/js/components/add-to-cart.js","../frontend/legacy-frontend/js/components/listitem-to-cart.js","../frontend/legacy-frontend/js/components/editable-table.js","../frontend/legacy-frontend/js/components/select-content.js","../frontend/legacy-frontend/js/components/checkout-page.js","../frontend/legacy-frontend/js/components/inquiry.js","../frontend/legacy-frontend/js/components/faq.js","../frontend/legacy-frontend/js/components/related-areas-block.js","../frontend/node_modules/bootstrap-autocomplete/dist/latest/bootstrap-autocomplete.js","../frontend/legacy-frontend/js/components/search.js","../frontend/legacy-frontend/js/components/forms.js","../frontend/legacy-frontend/js/components/registrationform.js","../frontend/legacy-frontend/js/components/LiveSurvey/Common.js","../frontend/node_modules/qrcode/lib/can-promise.js","../frontend/node_modules/qrcode/lib/core/utils.js","../frontend/node_modules/qrcode/lib/core/error-correction-level.js","../frontend/node_modules/qrcode/lib/core/bit-buffer.js","../frontend/node_modules/qrcode/lib/core/bit-matrix.js","../frontend/node_modules/qrcode/lib/core/alignment-pattern.js","../frontend/node_modules/qrcode/lib/core/finder-pattern.js","../frontend/node_modules/qrcode/lib/core/mask-pattern.js","../frontend/node_modules/qrcode/lib/core/error-correction-code.js","../frontend/node_modules/qrcode/lib/core/galois-field.js","../frontend/node_modules/qrcode/lib/core/polynomial.js","../frontend/node_modules/qrcode/lib/core/reed-solomon-encoder.js","../frontend/node_modules/qrcode/lib/core/version-check.js","../frontend/node_modules/qrcode/lib/core/regex.js","../frontend/node_modules/qrcode/lib/core/mode.js","../frontend/node_modules/qrcode/lib/core/version.js","../frontend/node_modules/qrcode/lib/core/format-info.js","../frontend/node_modules/qrcode/lib/core/numeric-data.js","../frontend/node_modules/qrcode/lib/core/alphanumeric-data.js","../frontend/node_modules/encode-utf8/index.js","../frontend/node_modules/qrcode/lib/core/byte-data.js","../frontend/node_modules/qrcode/lib/core/kanji-data.js","../frontend/node_modules/dijkstrajs/dijkstra.js","../frontend/node_modules/qrcode/lib/core/segments.js","../frontend/node_modules/qrcode/lib/core/qrcode.js","../frontend/node_modules/qrcode/lib/renderer/utils.js","../frontend/node_modules/qrcode/lib/renderer/canvas.js","../frontend/node_modules/qrcode/lib/renderer/svg-tag.js","../frontend/node_modules/qrcode/lib/browser.js","../frontend/legacy-frontend/js/components/LiveSurvey/Dashboard.js","../frontend/legacy-frontend/js/components/LiveSurvey/User.js","../frontend/node_modules/tiny-slider/src/helpers/raf.js","../frontend/node_modules/tiny-slider/src/helpers/caf.js","../frontend/node_modules/tiny-slider/src/helpers/extend.js","../frontend/node_modules/tiny-slider/src/helpers/checkStorageValue.js","../frontend/node_modules/tiny-slider/src/helpers/setLocalStorage.js","../frontend/node_modules/tiny-slider/src/helpers/getSlideId.js","../frontend/node_modules/tiny-slider/src/helpers/getBody.js","../frontend/node_modules/tiny-slider/src/helpers/docElement.js","../frontend/node_modules/tiny-slider/src/helpers/setFakeBody.js","../frontend/node_modules/tiny-slider/src/helpers/resetFakeBody.js","../frontend/node_modules/tiny-slider/src/helpers/calc.js","../frontend/node_modules/tiny-slider/src/helpers/percentageLayout.js","../frontend/node_modules/tiny-slider/src/helpers/mediaquerySupport.js","../frontend/node_modules/tiny-slider/src/helpers/createStyleSheet.js","../frontend/node_modules/tiny-slider/src/helpers/addCSSRule.js","../frontend/node_modules/tiny-slider/src/helpers/removeCSSRule.js","../frontend/node_modules/tiny-slider/src/helpers/getCssRulesLength.js","../frontend/node_modules/tiny-slider/src/helpers/toDegree.js","../frontend/node_modules/tiny-slider/src/helpers/getTouchDirection.js","../frontend/node_modules/tiny-slider/src/helpers/forEach.js","../frontend/node_modules/tiny-slider/src/helpers/classListSupport.js","../frontend/node_modules/tiny-slider/src/helpers/hasClass.js","../frontend/node_modules/tiny-slider/src/helpers/addClass.js","../frontend/node_modules/tiny-slider/src/helpers/removeClass.js","../frontend/node_modules/tiny-slider/src/helpers/hasAttr.js","../frontend/node_modules/tiny-slider/src/helpers/getAttr.js","../frontend/node_modules/tiny-slider/src/helpers/isNodeList.js","../frontend/node_modules/tiny-slider/src/helpers/setAttrs.js","../frontend/node_modules/tiny-slider/src/helpers/removeAttrs.js","../frontend/node_modules/tiny-slider/src/helpers/arrayFromNodeList.js","../frontend/node_modules/tiny-slider/src/helpers/hideElement.js","../frontend/node_modules/tiny-slider/src/helpers/showElement.js","../frontend/node_modules/tiny-slider/src/helpers/isVisible.js","../frontend/node_modules/tiny-slider/src/helpers/whichProperty.js","../frontend/node_modules/tiny-slider/src/helpers/has3DTransforms.js","../frontend/node_modules/tiny-slider/src/helpers/getEndProperty.js","../frontend/node_modules/tiny-slider/src/helpers/passiveOption.js","../frontend/node_modules/tiny-slider/src/helpers/addEvents.js","../frontend/node_modules/tiny-slider/src/helpers/removeEvents.js","../frontend/node_modules/tiny-slider/src/helpers/events.js","../frontend/node_modules/tiny-slider/src/helpers/jsTransform.js","../frontend/node_modules/tiny-slider/src/tiny-slider.js","../frontend/legacy-frontend/js/components/sliders.js","../frontend/legacy-frontend/js/components/checklist-search.js","../frontend/legacy-frontend/js/components/Inquiry/inquiry-result.js","../frontend/legacy-frontend/js/components/dilemma-container-block.js","../frontend/legacy-frontend/js/components/dilemma-block.js","../frontend/legacy-frontend/js/main.js"],"sourcesContent":["/*!\r\n * Bootstrap Table of Contents v1.0.1 (http://afeld.github.io/bootstrap-toc/)\r\n * Copyright 2015 Aidan Feldman\r\n * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */\r\n(function ($) {\r\n 'use strict';\r\n\r\n window.Toc = {\r\n helpers: {\r\n // return all matching elements in the set, or their descendants\r\n findOrFilter: function ($el, selector) {\r\n // http://danielnouri.org/notes/2011/03/14/a-jquery-find-that-also-finds-the-root-element/\r\n // http://stackoverflow.com/a/12731439/358804\r\n var $descendants = $el.find(selector);\r\n return $el.filter(selector).add($descendants).filter(':not([data-toc-skip])');\r\n },\r\n\r\n generateUniqueIdBase: function (el) {\r\n var text = $(el).text();\r\n\r\n // adapted from\r\n // https://github.com/bryanbraun/anchorjs/blob/65fede08d0e4a705f72f1e7e6284f643d5ad3cf3/anchor.js#L237-L257\r\n\r\n // Regex for finding the non-safe URL characters (many need escaping): & +$,:;=?@\"#{}|^~[`%!'<>]./()*\\ (newlines, tabs, backspace, & vertical tabs)\r\n var nonsafeChars = /[& +$,:;=?@\"#{}|^~[`%!'<>\\]\\.\\/\\(\\)\\*\\\\\\n\\t\\b\\v]/g,\r\n urlText;\r\n\r\n // Note: we trim hyphens after truncating because truncating can cause dangling hyphens.\r\n // Example string: // \" ⚡⚡ Don't forget: URL fragments should be i18n-friendly, hyphenated, short, and clean.\"\r\n urlText = text\r\n .trim() // \"⚡⚡ Don't forget: URL fragments should be i18n-friendly, hyphenated, short, and clean.\"\r\n .replace(/\\'/gi, '') // \"⚡⚡ Dont forget: URL fragments should be i18n-friendly, hyphenated, short, and clean.\"\r\n .replace(nonsafeChars, '-') // \"⚡⚡-Dont-forget--URL-fragments-should-be-i18n-friendly--hyphenated--short--and-clean-\"\r\n .replace(/-{2,}/g, '-') // \"⚡⚡-Dont-forget-URL-fragments-should-be-i18n-friendly-hyphenated-short-and-clean-\"\r\n .substring(0, 64) // \"⚡⚡-Dont-forget-URL-fragments-should-be-i18n-friendly-hyphenated-\"\r\n .replace(/^-+|-+$/gm, '') // \"⚡⚡-Dont-forget-URL-fragments-should-be-i18n-friendly-hyphenated\"\r\n .toLowerCase(); // \"⚡⚡-dont-forget-url-fragments-should-be-i18n-friendly-hyphenated\"\r\n\r\n return urlText || el.tagName.toLowerCase();\r\n },\r\n\r\n generateUniqueId: function (el) {\r\n var anchorBase = this.generateUniqueIdBase(el);\r\n for (var i = 0; ; i++) {\r\n var anchor = anchorBase;\r\n if (i > 0) {\r\n // add suffix\r\n anchor += '-' + i;\r\n }\r\n // check if ID already exists\r\n if (!document.getElementById(anchor)) {\r\n return anchor;\r\n }\r\n }\r\n },\r\n\r\n generateAnchor: function (el) {\r\n if (el.id) {\r\n return el.id;\r\n } else {\r\n var anchor = this.generateUniqueId(el);\r\n el.id = anchor;\r\n return anchor;\r\n }\r\n },\r\n\r\n createNavList: function () {\r\n return $('');\r\n },\r\n\r\n createChildNavList: function ($parent) {\r\n var $childList = this.createNavList();\r\n $parent.append($childList);\r\n return $childList;\r\n },\r\n\r\n generateNavEl: function (anchor, text) {\r\n var $a = $('');\r\n $a.attr('href', '#' + anchor);\r\n $a.text(text);\r\n var $li = $('
  • ');\r\n $li.append($a);\r\n return $li;\r\n },\r\n\r\n generateNavItem: function (headingEl) {\r\n var anchor = this.generateAnchor(headingEl);\r\n var $heading = $(headingEl);\r\n var text = $heading.data('toc-text') || $heading.text();\r\n return this.generateNavEl(anchor, text);\r\n },\r\n\r\n // Find the first heading level (`

    `, then `

    `, etc.) that has more than one element. Defaults to 1 (for `

    `).\r\n getTopLevel: function ($scope) {\r\n for (var i = 1; i <= 6; i++) {\r\n var $headings = this.findOrFilter($scope, 'h' + i);\r\n if ($headings.length > 1) {\r\n return i;\r\n }\r\n }\r\n\r\n return 1;\r\n },\r\n\r\n // returns the elements for the top level, and the next below it\r\n getHeadings: function ($scope, topLevel) {\r\n var topSelector = 'h' + topLevel;\r\n\r\n var secondaryLevel = topLevel + 1;\r\n var secondarySelector = 'h' + secondaryLevel;\r\n\r\n return this.findOrFilter($scope, topSelector + ',' + secondarySelector);\r\n },\r\n\r\n getNavLevel: function (el) {\r\n return parseInt(el.tagName.charAt(1), 10);\r\n },\r\n\r\n populateNav: function ($topContext, topLevel, $headings) {\r\n var $context = $topContext;\r\n var $prevNav;\r\n\r\n var helpers = this;\r\n $headings.each(function (i, el) {\r\n var $newNav = helpers.generateNavItem(el);\r\n var navLevel = helpers.getNavLevel(el);\r\n\r\n // determine the proper $context\r\n if (navLevel === topLevel) {\r\n // use top level\r\n $context = $topContext;\r\n } else if ($prevNav && $context === $topContext) {\r\n // create a new level of the tree and switch to it\r\n $context = helpers.createChildNavList($prevNav);\r\n } // else use the current $context\r\n\r\n $context.append($newNav);\r\n\r\n $prevNav = $newNav;\r\n });\r\n },\r\n\r\n parseOps: function (arg) {\r\n var opts;\r\n if (arg.jquery) {\r\n opts = {\r\n $nav: arg\r\n };\r\n } else {\r\n opts = arg;\r\n }\r\n opts.$scope = opts.$scope || $(document.body);\r\n return opts;\r\n }\r\n },\r\n\r\n // accepts a jQuery object, or an options object\r\n init: function (opts) {\r\n opts = this.helpers.parseOps(opts);\r\n\r\n // ensure that the data attribute is in place for styling\r\n opts.$nav.attr('data-toggle', 'toc');\r\n\r\n var $topContext = this.helpers.createChildNavList(opts.$nav);\r\n var topLevel = this.helpers.getTopLevel(opts.$scope);\r\n var $headings = this.helpers.getHeadings(opts.$scope, topLevel);\r\n this.helpers.populateNav($topContext, topLevel, $headings);\r\n }\r\n };\r\n\r\n //$(function () {\r\n // $('nav[data-toggle=\"toc\"]').each(function (i, el) {\r\n // var $nav = $(el);\r\n // Toc.init($nav);\r\n // });\r\n //});\r\n})(jQuery);\r\n","(function () {\r\n var flatPickerIncluded = document.querySelector('body').classList.contains('flatpicker');\r\n if (!flatPickerIncluded) {\r\n return;\r\n }\r\n\r\n flatpickr('.datepicker', {\r\n allowInput: true,\r\n enableTime: false,\r\n dateFormat: 'Y-m-d',\r\n locale: {\r\n firstDayOfWeek: 1,\r\n weekAbbreviation: 'v',\r\n weekdays: {\r\n shorthand: ['sön', 'mån', 'tis', 'ons', 'tor', 'fre', 'lör'],\r\n longhand: ['söndag', 'måndag', 'tisdag', 'onsdag', 'torsdag', 'fredag', 'lördag']\r\n },\r\n months: {\r\n shorthand: [\r\n 'jan',\r\n 'feb',\r\n 'mar',\r\n 'apr',\r\n 'maj',\r\n 'jun',\r\n 'jul',\r\n 'aug',\r\n 'sep',\r\n 'okt',\r\n 'nov',\r\n 'dec'\r\n ],\r\n longhand: [\r\n 'januari',\r\n 'februari',\r\n 'mars',\r\n 'april',\r\n 'maj',\r\n 'juni',\r\n 'juli',\r\n 'augusti',\r\n 'september',\r\n 'oktober',\r\n 'november',\r\n 'december'\r\n ]\r\n },\r\n rangeSeparator: ' till ',\r\n time_24hr: true,\r\n ordinal: () => {\r\n return '.';\r\n }\r\n }\r\n });\r\n //flatpickr(\".timepicker\", {\r\n // allowInput: true,\r\n // enableTime: true,\r\n // noCalendar: true,\r\n // dateFormat: \"H:i\",\r\n // time_24hr: true,\r\n\r\n //});\r\n})();\r\n","import { prefixRelativeUrl } from '../util.js';\r\n\r\n$(function () {\r\n const currentContentId = $('#site-menu-lg > ul').data('current-contentid');\r\n\r\n const generateRightHtml = function (item) {\r\n return `
    ${item.Title}
    `;\r\n };\r\n\r\n // Handling of the \"Mega menu\", which is a Bootstrap dropdown\r\n $('#site-menu-lg .nav-item.dropdown').on('show.bs.dropdown', (event) => {\r\n const contentId = $(event.relatedTarget).data('contentid');\r\n const $menu = $(event.target).find('.dropdown-menu');\r\n\r\n $('body').addClass('backdrop');\r\n $('header').css('position', 'relative');\r\n $('header').css('z-index', '1120');\r\n\r\n $menu.find('.right-panel').addClass('d-none');\r\n\r\n $menu.find('.dropdown-item.active').removeClass('active');\r\n\r\n $.getJSON(\r\n prefixRelativeUrl(`/__navigation/menuitems/${contentId}/${currentContentId}`)\r\n ).done((data) => {\r\n var children = null;\r\n\r\n const markup = data\r\n .map((item) => {\r\n if (item.Children !== null) {\r\n children = item.Children;\r\n }\r\n return `
    ${item.Title}\r\n ${\r\n item.HasChildren\r\n ? `
    `;\r\n })\r\n .join('');\r\n\r\n $menu.find('.left-panel .dropdown-items-mount').html(markup);\r\n\r\n if (children !== null && children !== undefined) {\r\n var itemMarkup = children.map((childItem) => generateRightHtml(childItem)).join('');\r\n\r\n $menu.find('.right-panel').removeClass('d-none');\r\n\r\n $menu.find('.right-panel .dropdown-items-mount').html(itemMarkup);\r\n\r\n $menu.find('.right-panel .dropdown-item').first().focus();\r\n }\r\n });\r\n });\r\n\r\n $('#site-menu-lg .nav-item.dropdown').on('hide.bs.dropdown', (event) => {\r\n $('body').removeClass('backdrop');\r\n $('header').css('position', '');\r\n $('header').css('z-index', '');\r\n });\r\n\r\n const populateRight = function ($target, $parent) {\r\n $('.left-panel .active').removeClass('active');\r\n $parent.addClass('active');\r\n\r\n const contentId = $target.data('contentid');\r\n const href = $parent.find('a').first().attr('href');\r\n const title = $parent.find('a').first().text();\r\n const $menu = $target.closest('.dropdown-menu');\r\n\r\n $.getJSON(prefixRelativeUrl(`/__navigation/menuitems/${contentId}`))\r\n .done((data) => {\r\n //const headingMarkup =\r\n // `
    ${title}
    `;\r\n const itemMarkup = data.map((item) => generateRightHtml(item)).join('');\r\n\r\n $menu.find('.right-panel').removeClass('d-none');\r\n\r\n $menu.find('.right-panel .dropdown-items-mount').html(itemMarkup);\r\n })\r\n .done((_) => {\r\n $menu.find('.right-panel .dropdown-item').first().focus();\r\n });\r\n };\r\n\r\n $('#site-menu-lg').on('click', '.left-panel .dropdown-item.populate-right', (event) => {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n\r\n var currentTarget = $(event.currentTarget);\r\n populateRight(currentTarget, currentTarget.parent());\r\n });\r\n\r\n $('#site-menu-lg').on('keyup', '.left-panel .dropdown-item.populate-right', (event) => {\r\n if (event.key === 'ArrowRight') {\r\n var currentTarget = $(event.currentTarget);\r\n populateRight(currentTarget, currentTarget.parent());\r\n }\r\n });\r\n\r\n $('#site-menu-lg').on('keyup', '.right-panel .dropdown-item', (event) => {\r\n if (event.key === 'ArrowLeft') {\r\n $(event.target).closest('.dropdown-menu').find('.left-panel .active a').focus();\r\n }\r\n });\r\n});\r\n","import { prefixRelativeUrl, isFeatureActive } from '../util.js';\r\n\r\n$(function () {\r\n const level = ($link) => $link.parents('[role=\"group\"]').length;\r\n const bg = (lvl) => ['bg-primary-light', 'bg-tertiary-light', 'bg-light'][lvl % 3];\r\n\r\n const linkMenuItem = (item, lvl) =>\r\n `
  • \r\n ${item.Title}\r\n
  • `;\r\n\r\n const toggleMenuItem = (item, lvl) =>\r\n `
  • \r\n
    \r\n ${\r\n item.Title\r\n }\r\n \r\n
    \r\n
    \r\n
  • `;\r\n\r\n const fetchMenuItems = (contentId) =>\r\n $.getJSON(prefixRelativeUrl(`/__navigation/menuitems/${contentId}`));\r\n\r\n const toggleAriaExpanded = ($element) =>\r\n $element.attr(\r\n 'aria-expanded',\r\n $element.attr('aria-expanded') === 'false' ? 'true' : 'false'\r\n );\r\n\r\n $('#toggle-main-menu').on('click', (event) => {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n $('#main-menu-container').toggleClass('d-none');\r\n toggleAriaExpanded($(event.currentTarget));\r\n\r\n trapFocus();\r\n toggleBackDrop();\r\n toggleDisableHeaderItems();\r\n\r\n // Scroll menu to active menuitem, if it exists\r\n const foundActiveItem = $('li[role=\"treeitem\"] a.active').first();\r\n\r\n if (foundActiveItem.length === 1) {\r\n const menuContainer = $('.main-menu-container');\r\n menuContainer.scrollTop(\r\n menuContainer.scrollTop() -\r\n menuContainer.offset().top +\r\n foundActiveItem.offset().top\r\n );\r\n }\r\n });\r\n //disable search and shoppingcarticon when responsive menu open\r\n const toggleDisableHeaderItems = () => {\r\n document.querySelectorAll('#site-menu > *').forEach(function (element) {\r\n if (element.id == 'toggle-search-field' || element.id == 'shopping-cart-top-link') {\r\n if (document.body.classList.contains('menu-open')) {\r\n element.classList.add('isdisabled');\r\n } else {\r\n element.classList.remove('isdisabled');\r\n }\r\n }\r\n });\r\n };\r\n //add backgrop when responsive menu open\r\n const toggleBackDrop = () => {\r\n const body = document.body;\r\n if (!body.classList.contains('menu-open')) {\r\n body.classList.add('backdrop', 'menu-open');\r\n } else {\r\n body.classList.remove('backdrop', 'menu-open');\r\n }\r\n };\r\n //keep tab withing menu responsive menu open\r\n const trapFocus = () => {\r\n var element = document.getElementById('site-menu');\r\n var focusableEls = element.querySelectorAll(\r\n 'a[href]:not([disabled]), button:not([disabled]), textarea:not([disabled]), input[type=\"text\"]:not([disabled]), input[type=\"radio\"]:not([disabled]), input[type=\"checkbox\"]:not([disabled]), select:not([disabled])'\r\n );\r\n var firstFocusableEl = document.getElementById('toggle-main-menu');\r\n var lastFocusableEl = focusableEls[focusableEls.length - 1];\r\n var KEYCODE_TAB = 9;\r\n\r\n element.addEventListener('keydown', function (e) {\r\n var isTabPressed = e.key === 'Tab' || e.keyCode === KEYCODE_TAB;\r\n\r\n if (!isTabPressed) {\r\n return;\r\n }\r\n\r\n if (e.shiftKey) {\r\n /* shift + tab */ if (document.activeElement === firstFocusableEl) {\r\n lastFocusableEl.focus();\r\n e.preventDefault();\r\n }\r\n } /* tab */ else {\r\n if (document.activeElement === lastFocusableEl) {\r\n firstFocusableEl.focus();\r\n e.preventDefault();\r\n }\r\n }\r\n });\r\n };\r\n\r\n const toggleGroup = ($treeitem) => {\r\n $treeitem.children('[role=\"group\"]').toggleClass('d-none');\r\n toggleAriaExpanded($treeitem);\r\n return;\r\n };\r\n\r\n const populateGroup = ($mount, lvl) => {\r\n const contentId = $mount.data('item-contentid');\r\n //const first = linkMenuItem({\r\n // Url: $mount.data('item-href'),\r\n // Title: `Gå till ${$mount.data('item-title')}`,\r\n // ContentId: 'u' + $mount.data('item-contentid')\r\n //}, lvl);\r\n\r\n fetchMenuItems(contentId).done((data) => {\r\n const itemsHtml = [\r\n ...data.map((item) =>\r\n item.HasChildren ? toggleMenuItem(item, lvl) : linkMenuItem(item, lvl)\r\n )\r\n ].join('');\r\n $mount.parent('.toggle-sub-menu').attr('aria-expanded', 'true');\r\n $mount.replaceWith(\r\n ``\r\n );\r\n });\r\n };\r\n\r\n const focusItem = (activeItem) => {\r\n $('#main-menu-container [tabindex=\"0\"]').attr('tabindex', '-1');\r\n $(activeItem).attr('tabindex', '0').focus();\r\n };\r\n\r\n const handleGroupToggle = ($treeitem) => {\r\n if ($treeitem.has('[role=\"group\"]').length) {\r\n toggleGroup($treeitem);\r\n return;\r\n }\r\n\r\n const $mount = $treeitem.children('.sub-menu-mount');\r\n if ($mount.length) {\r\n var lvl = level($treeitem);\r\n populateGroup($mount, lvl);\r\n }\r\n };\r\n\r\n const visibleFocusables = () =>\r\n $('#main-menu-container').find('[role=\"treeitem\"][tabindex]:visible');\r\n\r\n const moveFocus = ($current, direction) => {\r\n const currentId = $current.data('item-contentid');\r\n const $visible = visibleFocusables();\r\n const currentIndex = $visible\r\n .get()\r\n .findIndex((element) => $(element).data('item-contentid') === currentId);\r\n const nextIndex = currentIndex + (direction === 'down' ? 1 : -1);\r\n\r\n if (0 <= nextIndex && nextIndex < $visible.length) {\r\n focusItem($visible[nextIndex]);\r\n }\r\n };\r\n\r\n $('#main-menu-container').on('click keydown', '.sub-menu-toggle-button', (event) => {\r\n // Check if the event is a keypress and if the key is Enter (13) or Space (32)\r\n if (event.type === 'keydown' && event.which !== 13 && event.which !== 32) {\r\n return; // if it's a keypress but not Enter or Space, do nothing\r\n }\r\n\r\n // Prevent the default action for Space key to stop it from scrolling the page\r\n if (event.which === 32) {\r\n event.preventDefault();\r\n }\r\n handleGroupToggle($(`#${$(event.currentTarget).data('treeitem')}`));\r\n });\r\n\r\n // keyboard interface, mainly inspired by:\r\n // https://www.w3.org/TR/wai-aria-practices-1.1/examples/treeview/treeview-2/treeview-2a.html\r\n $('#main-menu-container').on('keydown', '[role=\"treeitem\"]', (event) => {\r\n if (event.key === 'Tab') return;\r\n\r\n event.preventDefault();\r\n event.stopPropagation();\r\n\r\n const $target = $(event.target);\r\n switch (event.key) {\r\n case 'Enter':\r\n case ' ' /*Space*/:\r\n if ($target.is('a')) window.location.href = $target.attr('href');\r\n if ($target.is('li')) handleGroupToggle($target);\r\n break;\r\n\r\n case 'ArrowDown':\r\n moveFocus($target, 'down');\r\n break;\r\n\r\n case 'ArrowUp':\r\n moveFocus($target, 'up');\r\n break;\r\n\r\n case 'ArrowRight':\r\n if ($target.is('[aria-expanded=\"true\"]')) {\r\n focusItem($target.find('[tabindex]').first());\r\n }\r\n if ($target.is('[aria-expanded=\"false\"]')) {\r\n handleGroupToggle($target);\r\n }\r\n break;\r\n\r\n case 'ArrowLeft':\r\n if ($target.is('[aria-expanded=\"true\"]')) {\r\n handleGroupToggle($target);\r\n } else {\r\n focusItem($target.parents('[tabindex]').first());\r\n }\r\n break;\r\n\r\n case 'Home':\r\n focusItem(visibleFocusables().first());\r\n break;\r\n\r\n case 'End':\r\n focusItem(visibleFocusables().last());\r\n break;\r\n\r\n case '*':\r\n // expands all closed groups on same level as target\r\n $target\r\n .closest('[role=\"group\"], [role=\"tree\"]')\r\n .children('[aria-expanded=\"false\"]')\r\n .each((_, item) => handleGroupToggle($(item)));\r\n break;\r\n\r\n case 'Escape':\r\n $('#main-menu-container').toggleClass('d-none');\r\n $('#toggle-main-menu').focus();\r\n break;\r\n\r\n default:\r\n const letter = event.key.match(/^[a-zåäö]$/i);\r\n if (letter) {\r\n const $candidates = visibleFocusables().map((i, element) => {\r\n const $element = $(element);\r\n return {\r\n index: i,\r\n id: $element.data('item-contentid'),\r\n element: $element\r\n };\r\n });\r\n\r\n const $matches = $candidates.filter((_, item) => {\r\n return item.element.get(0).innerText.startsWith(letter[0].toUpperCase());\r\n });\r\n\r\n if (!$matches.length) break;\r\n\r\n const currentId = $target.data('item-contentid');\r\n const currentIndex = $candidates\r\n .filter((i, x) => x.element.data('item-contentid') == currentId)\r\n .first()\r\n .get(0).index;\r\n\r\n const next = $matches.get().filter((item) => item.index > currentIndex);\r\n\r\n if (next.length) {\r\n focusItem(next[0].element);\r\n } else {\r\n focusItem($matches[0].element);\r\n }\r\n }\r\n break;\r\n }\r\n });\r\n\r\n // Sticky menu on scroll up, hide on scroll down\r\n const $body = $('body');\r\n let lastScroll = 0;\r\n const scrollDown = 'scrollDown';\r\n const scrollUp = 'scrollUp';\r\n $(window).on('scroll', () => {\r\n const currentScroll = window.pageYOffset;\r\n const isMenuExpanded = $('#toggle-main-menu').attr('aria-expanded') === 'true';\r\n\r\n if (\r\n currentScroll > 0 &&\r\n currentScroll > lastScroll &&\r\n !$body.hasClass(scrollDown) &&\r\n !isMenuExpanded\r\n ) {\r\n $body.addClass(scrollDown);\r\n $body.removeClass(scrollUp);\r\n } else if (currentScroll < lastScroll && $body.hasClass(scrollDown)) {\r\n $body.addClass(scrollUp);\r\n $body.removeClass(scrollDown);\r\n } else if (currentScroll === 0) {\r\n $body.removeClass(scrollUp);\r\n $body.removeClass(scrollDown);\r\n }\r\n\r\n lastScroll = currentScroll;\r\n });\r\n});\r\n\r\n$(function () {\r\n $('#toggle-search-field').click((event) => {\r\n if ($(event.currentTarget).is('[aria-expanded=\"false\"]')) {\r\n $('.search-wrapper').show();\r\n $('.search-wrapper #search-input').focus();\r\n $(event.currentTarget).attr('aria-expanded', 'true');\r\n } else {\r\n $('.search-wrapper').hide();\r\n $(event.currentTarget).attr('aria-expanded', 'false');\r\n }\r\n });\r\n});\r\n","import { isFeatureActive } from '../util.js';\r\n\r\n$(function () {\r\n // Dependent on that vendor/toc/bootstrap-toc.js has set ids of headings\r\n const $headings = $('h2[id], h3[id]');\r\n if ($headings.length) {\r\n $('#find-on-page-responsive').removeClass('d-none').addClass('d-flex');\r\n }\r\n const $dropup = $('#find-on-page-responsive .menu-dropup');\r\n const linksMarkup = $headings\r\n .get()\r\n .map((h) => `${h.innerText}`)\r\n .join('');\r\n\r\n $dropup.html(linksMarkup);\r\n\r\n const expandBadge = ($badge) =>\r\n $badge\r\n .attr('aria-expanded', 'true')\r\n .removeClass('badge-primary-light')\r\n .addClass('badge-primary');\r\n\r\n const collapseBadge = ($badge) =>\r\n $badge\r\n .attr('aria-expanded', 'false')\r\n .removeClass('badge-primary')\r\n .addClass('badge-primary-light');\r\n\r\n $('#find-on-page-responsive a.badge').on('click', (event) => {\r\n $dropup.toggle();\r\n\r\n const $badge = $(event.currentTarget);\r\n if ($dropup.is(':visible')) {\r\n expandBadge($badge);\r\n } else {\r\n collapseBadge($badge);\r\n }\r\n });\r\n\r\n $('#find-on-page-responsive .menu-dropup').on('click', 'a', () => {\r\n $dropup.hide();\r\n collapseBadge($('#find-on-page-responsive a.badge'));\r\n });\r\n});\r\n","import { prefixRelativeUrl, isFeatureActive } from '../util.js';\r\n\r\n$(function () {\r\n const $button = $('#context-dropdown-toggle');\r\n const $menu = $button.next('.context-dropdown');\r\n\r\n $('.context-menu-nav .nav-item.dropdown').on('show.bs.dropdown', (event) => {\r\n $('body').addClass('backdrop');\r\n $('.context-menu-nav .nav-item.dropdown').css('position', 'relative');\r\n $('.context-menu-nav .nav-item.dropdown').css('z-index', '1120');\r\n\r\n $menu.find('.right-panel').addClass('d-none');\r\n\r\n $menu.find('.context-dropdown-item.active').removeClass('active');\r\n });\r\n\r\n $('.context-menu-nav .nav-item.dropdown').on('hide.bs.dropdown', (event) => {\r\n $('body').removeClass('backdrop');\r\n $('.context-menu-nav .nav-item.dropdown').css('position', '');\r\n $('.context-menu-nav .nav-item.dropdown').css('z-index', '');\r\n });\r\n\r\n const populateRight = function ($target, $parent) {\r\n $('.left-panel .active').removeClass('active');\r\n $parent.addClass('active');\r\n\r\n const contentId = $target.data('contentid');\r\n const href = $parent.find('a').first().attr('href');\r\n const title = $parent.find('a').first().text();\r\n const $menu = $target.closest('.context-dropdown');\r\n\r\n $.getJSON(prefixRelativeUrl(`/__navigation/menuitems/${contentId}`))\r\n .done((data) => {\r\n //const headingMarkup =\r\n // `
  • ${title}
  • `;\r\n const itemMarkup = data\r\n .map(\r\n (item) =>\r\n `
  • ${item.Title}
  • `\r\n )\r\n .join('');\r\n\r\n $menu.find('.right-panel').removeClass('d-none');\r\n\r\n $menu\r\n .find('.right-panel')\r\n .html(\r\n ''\r\n );\r\n })\r\n .done((_) => {\r\n $menu.find('.right-panel .context-dropdown-item a').first().focus();\r\n });\r\n };\r\n\r\n $menu.find('.populate-right').click((event) => {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n\r\n var currentTarget = $(event.currentTarget);\r\n\r\n populateRight(currentTarget, currentTarget.parent());\r\n });\r\n\r\n $('.context-menu-nav').on('keyup', '.left-panel .dropdown-item.populate-right', (event) => {\r\n if (event.key === 'ArrowRight') {\r\n var currentTarget = $(event.currentTarget);\r\n\r\n populateRight(currentTarget, currentTarget.parent());\r\n }\r\n });\r\n\r\n $('.context-menu-nav').on('keyup', '.right-panel .dropdown-item', (event) => {\r\n if (event.key === 'ArrowLeft') {\r\n $(event.target).closest('.dropdown-menu').find('.left-panel .active a').focus();\r\n }\r\n });\r\n});\r\n\r\n$(function () {\r\n $('#context-menu .search-btn').click((event) => {\r\n // Timeout to compensate for when having context-menu opened and then clicking the search button\r\n setTimeout(() => {\r\n $('#context-menu .search-wrapper-lg').show();\r\n $(event.currentTarget).attr('aria-expanded', 'true');\r\n\r\n $('#context-menu .search-wrapper-lg input[type=\"search\"]').focus();\r\n\r\n $('body').not('.search-page').addClass('backdrop');\r\n }, 10);\r\n });\r\n\r\n $('#context-menu .search-wrapper-lg button').click((event) => {\r\n $('#context-menu .search-wrapper-lg').hide();\r\n $('#context-menu .search-btn').attr('aria-expanded', 'false');\r\n $('body').removeClass('backdrop');\r\n });\r\n});\r\n","$(function () {\r\n $('.youtube-playlist .stretched-link').click(function (e) {\r\n e.preventDefault();\r\n var $link = $(e.currentTarget);\r\n var $player = $(`#${$link.data('player-ref')}`);\r\n\r\n $player.find('iframe').attr('src', $link.data('video-embed-url'));\r\n $player.find('.h3').html($link.data('video-title'));\r\n $player.find('.lead').html($link.data('video-description'));\r\n $player.get(0).scrollIntoView({ behavior: 'smooth' });\r\n });\r\n});\r\n","$(function () {\r\n $('select[name=\"occations\"]').change(function (e) {\r\n window.location.href = $(e.target).val();\r\n });\r\n});\r\n","$(() => {\r\n const $form = $(`#add-to-cart-form`);\r\n\r\n if (!$form.length) return;\r\n\r\n const formAccessor = (form) => (name) => form.find(`input[name=\"${name}\"]`).val();\r\n const formValue = formAccessor($form);\r\n const type = $form.data('product-type');\r\n const variationCode = formValue('code');\r\n const participantId = (fn, ln, email) => window.btoa(`${fn}${ln}${email}`);\r\n const getCurrentParticipants = () =>\r\n $('.added-participant')\r\n .map((_, li) => {\r\n return {\r\n id: li.dataset.id,\r\n firstname: li.dataset.fn,\r\n lastname: li.dataset.ln,\r\n email: li.dataset.email\r\n };\r\n })\r\n .get();\r\n\r\n $('#cart-updated-toast').toast({ delay: 2622 });\r\n\r\n $form.on(`submit`, (event) => {\r\n //console.log('submit', event);\r\n\r\n event.stopPropagation();\r\n event.preventDefault();\r\n\r\n if (window.productFields && window.dataLayer) {\r\n const productField = window.productFields.find(\r\n (x) => x.id === variationCode.toUpperCase()\r\n );\r\n\r\n if (productField) {\r\n window.dataLayer.push({ ecommerce: null });\r\n window.dataLayer.push({\r\n event: 'addToCart',\r\n ecommerce: {\r\n currencyCode: `${productField.currencyCode}`,\r\n add: {\r\n products: [\r\n {\r\n name: `${productField.name}`,\r\n id: `${productField.id}`,\r\n price: productField.price,\r\n category: `${productField.category}`,\r\n variant: `${productField.variant}`,\r\n quantity: formValue('quantity')\r\n ? formValue('quantity')\r\n : productField.quantity\r\n }\r\n ]\r\n }\r\n }\r\n });\r\n }\r\n }\r\n\r\n if (event.currentTarget.checkValidity()) {\r\n const updateModel = getUpdateModel(type);\r\n\r\n if (type === 'book') {\r\n const bookAddMessage = addBookMessage(formValue('quantity'));\r\n postToCart(updateModel, bookAddMessage);\r\n } else if (type === 'SingeAtendeeEduction') {\r\n postToCart(updateModel, addSingleParticipantMessage());\r\n } else {\r\n const newParticipant = readParticipantFromForm();\r\n postToCart(updateModel, addParticipantMessage(newParticipant));\r\n }\r\n } else {\r\n $form.addClass('was-validated').find(':invalid').first().focus();\r\n }\r\n });\r\n\r\n $('body').on('click', 'button[name=\"remove-participant\"]', (event) => {\r\n event.stopPropagation();\r\n event.preventDefault();\r\n const participantId = $(event.currentTarget).val();\r\n const removedParticipant = readParticipantFromDOM(participantId);\r\n const updateModel = getRemoveParticipantModel(participantId);\r\n postToCart(updateModel, removedParticipantMessage(removedParticipant));\r\n });\r\n\r\n const postToCart = (updateModel, successMessage) => {\r\n $.post({\r\n url: `/api/commerce/cart`,\r\n data: updateModel,\r\n dataType: `json`,\r\n contentType: `application/json`\r\n }).done((data) => {\r\n if (data.success) {\r\n toastMessage(successMessage);\r\n } else {\r\n toastMessage(`Ett fel inträffade: \\n${data.errorMsg}`, false);\r\n return;\r\n }\r\n\r\n resetForm();\r\n\r\n updateCartIcon(data.payload.totalCount);\r\n if (type == 'book' || type == 'SingeAtendeeEduction') return;\r\n const participants = data.payload.items[variationCode]\r\n ? data.payload.items[variationCode].members || []\r\n : [];\r\n\r\n //console.log(participants);\r\n\r\n if (participants.length) {\r\n $('#added-participants').removeClass('d-none');\r\n const last = participants[participants.length - 1];\r\n } else {\r\n $('#added-participants').addClass('d-none');\r\n }\r\n\r\n updateAddedParticipants(\r\n document.getElementById('added-participant-list'),\r\n document.getElementById('participant-template'),\r\n participants\r\n );\r\n });\r\n };\r\n\r\n const getRemoveParticipantModel = (participantId) => {\r\n const filteredModel = getCurrentParticipants().filter(\r\n (participant) => participant.id !== participantId\r\n );\r\n\r\n return JSON.stringify({\r\n isCheckout: false,\r\n items: {\r\n [variationCode]: {\r\n members: filteredModel.length ? filteredModel : null\r\n }\r\n }\r\n });\r\n };\r\n\r\n const resetForm = () => {\r\n $('#given-name, #family-name, #email-address').val('');\r\n $form.removeClass('was-validated');\r\n $('#given-name').focus();\r\n };\r\n\r\n const toastMessage = (htmlMessage, success = true) => {\r\n $('#toast-message').html(htmlMessage);\r\n\r\n const cartUpdatedToast = $('#cart-updated-toast');\r\n\r\n cartUpdatedToast.find('.toast-header')?.toggleClass('bg-primary', success);\r\n cartUpdatedToast.find('.toast-header')?.toggleClass('bg-danger', !success);\r\n\r\n let toastTitleEl = cartUpdatedToast.find('.toast-header > strong');\r\n\r\n if (toastTitleEl) {\r\n toastTitleEl.text(\r\n success ? toastTitleEl.data('success-msg') : toastTitleEl.data('error-msg')\r\n );\r\n }\r\n\r\n cartUpdatedToast.toast('show');\r\n };\r\n\r\n const addParticipantMessage = (participant) =>\r\n `${participant.firstname} ${participant.lastname} tillagd som deltagare.`;\r\n\r\n const removedParticipantMessage = (participant) =>\r\n `${participant.firstname} ${participant.lastname} borttagen som deltagare.`;\r\n\r\n const addBookMessage = (quantity) =>\r\n `${quantity} exemplar ${\r\n parseInt(quantity) > 1 ? 'tillagda' : 'tillagt'\r\n } i varukorgen.`;\r\n\r\n const addSingleParticipantMessage = () => `Varan är tillagd i varukorgen.`;\r\n\r\n const updateCartIcon = (totalCount) => {\r\n $('.shopping-cart-top-link .shopping-cart-icon__count').text(totalCount);\r\n if (totalCount == 0) {\r\n $('.shopping-cart-top-link .shopping-cart-icon').addClass('shopping-cart-icon--empty');\r\n } else {\r\n $('.shopping-cart-top-link .shopping-cart-icon').removeClass(\r\n 'shopping-cart-icon--empty'\r\n );\r\n }\r\n };\r\n\r\n const getUpdateModel = (type) => {\r\n const model = {\r\n isCheckout: false,\r\n items: {\r\n [variationCode]: {}\r\n }\r\n };\r\n\r\n switch (type) {\r\n case 'book':\r\n model.items[variationCode]['quantity'] = parseInt(formValue('quantity'));\r\n break;\r\n case 'SingeAtendeeEduction':\r\n model.items[variationCode]['quantity'] = 1;\r\n model.items[variationCode]['role'] = false;\r\n break;\r\n default:\r\n model.items[variationCode]['members'] = [\r\n ...getCurrentParticipants(),\r\n readParticipantFromForm()\r\n ];\r\n break;\r\n }\r\n\r\n return JSON.stringify(model);\r\n };\r\n\r\n const readParticipantFromForm = () => {\r\n const participant = {\r\n firstname: formValue('given-name'),\r\n lastname: formValue('family-name'),\r\n email: formValue('email-address')\r\n };\r\n\r\n participant.id = participantId(\r\n participant.firstname,\r\n participant.lastname,\r\n participant.email\r\n );\r\n\r\n return participant;\r\n };\r\n\r\n const readParticipantFromDOM = (participantId) => {\r\n const $participant = $('.added-participant')\r\n .filter((_, element) => $(element).data('id') === participantId)\r\n .first();\r\n\r\n return {\r\n firstname: $participant.data('fn'),\r\n lastname: $participant.data('ln'),\r\n email: $participant.data('email'),\r\n id: $participant.data('id')\r\n };\r\n };\r\n\r\n const updateAddedParticipants = (ul, template, particpantData) => {\r\n const participantNodes = particpantData.map((participant) =>\r\n createParticipantNode(template, participant)\r\n );\r\n\r\n while (ul.firstChild) {\r\n ul.removeChild(ul.firstChild);\r\n }\r\n for (let i in participantNodes) {\r\n ul.appendChild(participantNodes[i]);\r\n }\r\n };\r\n\r\n const createParticipantNode = (template, participant) => {\r\n const fragment = template.content.cloneNode(true);\r\n const li = fragment.firstElementChild;\r\n\r\n li.setAttribute('data-fn', participant.firstName);\r\n fragment.querySelector('.fn').textContent = participant.firstName;\r\n\r\n li.setAttribute('data-ln', participant.lastName);\r\n fragment.querySelector('.ln').textContent = participant.lastName;\r\n\r\n li.setAttribute('data-email', participant.email);\r\n fragment.querySelector('.email').textContent = participant.email;\r\n\r\n li.setAttribute('data-id', participant.id);\r\n fragment.querySelector('button[name=\"remove-participant\"]').value = participant.id;\r\n\r\n return li;\r\n };\r\n});\r\n","$(() => {\r\n const postToCart = (updateModel, successMessage) => {\r\n $.post({\r\n url: `/api/commerce/cart`,\r\n data: updateModel,\r\n dataType: `json`,\r\n contentType: `application/json`\r\n }).done((data) => {\r\n toastMessage(successMessage);\r\n updateCartIcon(data.payload.totalCount);\r\n });\r\n };\r\n const toastMessage = (htmlMessage) => {\r\n $('#toast-message').html(htmlMessage);\r\n $('#cart-updated-toast').toast('show');\r\n };\r\n const addBookMessage = (quantity) =>\r\n `${quantity} exemplar ${\r\n parseInt(quantity) > 1 ? 'tillagda' : 'tillagt'\r\n } i varukorgen.`;\r\n const updateCartIcon = (totalCount) => {\r\n $('.shopping-cart-top-link .shopping-cart-icon__count').text(totalCount);\r\n if (totalCount == 0) {\r\n $('.shopping-cart-top-link .shopping-cart-icon').addClass('shopping-cart-icon--empty');\r\n } else {\r\n $('.shopping-cart-top-link .shopping-cart-icon').removeClass(\r\n 'shopping-cart-icon--empty'\r\n );\r\n }\r\n };\r\n const getUpdateModel = (type, variationCode, quantity) => {\r\n const model = {\r\n isCheckout: false,\r\n items: {\r\n [variationCode]: {}\r\n }\r\n };\r\n switch (type) {\r\n case 'book':\r\n model.items[variationCode]['quantity'] = quantity;\r\n break;\r\n default:\r\n model.items[variationCode]['quantity'] = 1;\r\n break;\r\n }\r\n return JSON.stringify(model);\r\n };\r\n\r\n const $forms = $(`.add-to-cart-form`);\r\n if (!$forms.length) return;\r\n\r\n for (var i = 0; i < $forms.length; i++) {\r\n const formAccessor = (name) => $($forms[i]).find(`input[name=\"${name}\"]`).val();\r\n const type = $forms[i].dataset.productType;\r\n const variationCode = formAccessor('code');\r\n const quantity = parseInt(formAccessor('quantity'));\r\n\r\n const cartUpdatedToast = $('#cart-updated-toast');\r\n cartUpdatedToast.toast({ delay: 2622 });\r\n\r\n $($forms[i]).on(`submit`, (event) => {\r\n event.stopPropagation();\r\n event.preventDefault();\r\n\r\n if (window.productFields && window.dataLayer) {\r\n const productField = window.productFields.find(\r\n (x) => x.id === variationCode.toUpperCase()\r\n );\r\n\r\n if (productField) {\r\n window.dataLayer.push({ ecommerce: null });\r\n window.dataLayer.push({\r\n event: 'addToCart',\r\n ecommerce: {\r\n currencyCode: `${productField.currencyCode}`,\r\n add: {\r\n products: [\r\n {\r\n name: `${productField.name}`,\r\n id: `${productField.id}`,\r\n price: `${productField.price}`,\r\n category: `${productField.category}`,\r\n variant: `${productField.variant}`,\r\n quantity: productField.quantity\r\n }\r\n ]\r\n }\r\n }\r\n });\r\n }\r\n }\r\n\r\n const updateModel = getUpdateModel(type, variationCode, quantity);\r\n if (type === 'book') {\r\n const bookAddMessage = addBookMessage(quantity);\r\n postToCart(updateModel, bookAddMessage);\r\n }\r\n });\r\n }\r\n});\r\n","$(() => {\r\n //set id editable-table in form around table\r\n //set class table-edit-btn on the table row btn that should trigger edit\r\n //set class contenteditable on edit input area in td\r\n //set data-contenteditableformcancel in button that should cancel and hide contenteditable\r\n //all input name attributes are posted to controller as json\r\n\r\n //selectors\r\n const tableeditbtns = document.querySelectorAll('.table-edit-btn');\r\n const contentEditableFormCancels = document.querySelectorAll(\r\n \"button[data-contenteditableformcancel='true']\"\r\n );\r\n const contentEditableForm = document.querySelector('#editable-table');\r\n\r\n //functions\r\n tableeditbtns.forEach((btn) => {\r\n btn.addEventListener('click', (e) => {\r\n e.preventDefault();\r\n const editableAreas = e.target\r\n .closest('.mypages--plugin-grid')\r\n .querySelectorAll('.contenteditable');\r\n\r\n editableAreas.forEach((area) => {\r\n area.classList.toggle('d-none');\r\n });\r\n });\r\n });\r\n const submit = ($form, json, tableRow) => {\r\n const currentUrl = $form.getAttribute('action');\r\n\r\n fetch(currentUrl, {\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'X-Requested-With': 'XMLHttpRequest'\r\n },\r\n method: 'POST',\r\n cache: 'no-store',\r\n body: JSON.stringify(json)\r\n })\r\n .then((response) => response.json())\r\n .then((result) => {\r\n if (result.Payload != null) {\r\n for (const key in result.Payload) {\r\n if (result.Payload[key] != null) {\r\n const input = tableRow.querySelector('.contenteditabletext-' + key);\r\n if (input != null) {\r\n input.textContent = result.Payload[key];\r\n input.classList.add('text-success', 'font-weight-bold');\r\n setTimeout(() => {\r\n input.classList.remove('text-success', 'font-weight-bold');\r\n }, 3000);\r\n }\r\n }\r\n }\r\n tableRow\r\n .querySelectorAll('.contenteditable')\r\n .forEach((el) => el.classList.toggle('d-none'));\r\n }\r\n })\r\n .catch((error) => {\r\n alert('Error:', error);\r\n });\r\n };\r\n const inputToJson = (tableRow) => {\r\n const inputs = tableRow.querySelectorAll('.contenteditable input');\r\n const data = {};\r\n inputs.forEach((input) => {\r\n const name = input.getAttribute('name');\r\n const value = input.value;\r\n data[name] = value;\r\n });\r\n return data;\r\n };\r\n if (contentEditableForm != null) {\r\n contentEditableForm.addEventListener('submit', (e) => {\r\n e.preventDefault();\r\n const btnClicked = e.submitter;\r\n const tableRow = btnClicked.closest('.mypages--plugin-grid');\r\n const json = inputToJson(tableRow);\r\n submit(e.target, json, tableRow);\r\n });\r\n }\r\n\r\n if (contentEditableFormCancels != null) {\r\n contentEditableFormCancels.forEach((btn) => {\r\n btn.addEventListener('click', (e) => {\r\n e.preventDefault();\r\n e.target\r\n .closest('.mypages--plugin-grid')\r\n .querySelectorAll('.contenteditable')\r\n .forEach((el) => el.classList.toggle('d-none'));\r\n });\r\n });\r\n }\r\n});\r\n","$(() => {\r\n $('[data-select-content]').click(function (ev) {\r\n const selectedContentEl = $(this);\r\n const variationCode = selectedContentEl.attr('data-select-content').toUpperCase();\r\n\r\n if (variationCode && window.productFields && window.dataLayer) {\r\n const productField = window.productFields.find((x) => x.id === variationCode);\r\n var cmpData = window.__cmp('getCMPData');\r\n\r\n if (productField && cmpData && cmpData.vendorConsents['s905'] === true) {\r\n ev.preventDefault();\r\n window.dataLayer.push({ ecommerce: null });\r\n window.dataLayer.push({\r\n event: 'productClick',\r\n ecommerce: {\r\n click: {\r\n products: [\r\n {\r\n name: productField.name,\r\n id: productField.id,\r\n price: productField.price,\r\n category: productField.category,\r\n variant: productField.variant\r\n }\r\n ]\r\n }\r\n },\r\n eventCallback: function () {\r\n window.location.href = selectedContentEl.attr('href');\r\n }\r\n });\r\n }\r\n }\r\n });\r\n});\r\n","$(function () {\r\n const CART_UPDATED = 'cart:updated';\r\n\r\n $('input.item-quantity').on('input', function (e) {\r\n const quantity = parseInt(e.target.value);\r\n const code = $(e.target).data('code');\r\n\r\n postToCart(\r\n JSON.stringify({\r\n isCheckout: true,\r\n items: {\r\n [code]: { quantity }\r\n }\r\n })\r\n );\r\n });\r\n\r\n $('.remove-cart-item').click(function (e) {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n\r\n const code = $(e.target).data('item-code');\r\n\r\n postToCart(\r\n JSON.stringify({\r\n isCheckout: true,\r\n items: {\r\n [code]: { quantity: 0 }\r\n }\r\n })\r\n );\r\n });\r\n\r\n $('#add-cart-coupon-code').click(function (event) {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n\r\n const code = $('#cart-coupon-code').val();\r\n\r\n $('#cart-coupon-code-error').hide();\r\n\r\n $.post({\r\n url: `/api/commerce/cart/coupon`,\r\n data: { couponCode: code }\r\n }).done((data) => {\r\n console.log('add-code', data);\r\n if (data.success) {\r\n $(document).trigger(CART_UPDATED, data.payload);\r\n } else {\r\n $('#cart-coupon-code-error').show();\r\n }\r\n });\r\n });\r\n\r\n $(document).on('click', '.remove-discount-code', function (event) {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n\r\n const code = event.currentTarget.value;\r\n\r\n $.ajax({\r\n method: 'delete',\r\n url: `/api/commerce/cart/coupon`,\r\n data: { couponCode: code }\r\n }).done((data) => {\r\n console.log('remove-code', data);\r\n $(document).trigger(CART_UPDATED, data.payload);\r\n });\r\n });\r\n\r\n // post cart updates\r\n const postToCart = (updateModel) => {\r\n $.post({\r\n url: `/api/commerce/cart`,\r\n data: updateModel,\r\n dataType: `json`,\r\n contentType: `application/json`\r\n }).done((data) => {\r\n $(document).trigger(CART_UPDATED, data.payload);\r\n });\r\n };\r\n\r\n $(document).on(CART_UPDATED, function (event, payload) {\r\n // Toggle discount data rows\r\n $('.cart-discount-row').toggleClass(\r\n 'd-none',\r\n payload.subTotal === payload.subTotalInclDiscount\r\n );\r\n });\r\n\r\n $(document).on(CART_UPDATED, function (event, payload) {\r\n // Remove removed item items\r\n $('li.cart-item')\r\n .filter((_, li) => {\r\n const code = $(li).data('code');\r\n return !payload.items[code];\r\n })\r\n .remove();\r\n\r\n if ($('li.cart-item').length === 0) {\r\n location.reload(true);\r\n }\r\n });\r\n\r\n $(document).on(CART_UPDATED, function (event, payload) {\r\n // Update item subtotals on quantity change\r\n $('.item-subtotal').each((_, subtotal) => {\r\n const $subtotal = $(subtotal);\r\n const code = $subtotal.data('code');\r\n payload.items[code] && $subtotal.text(payload.items[code].totalPrice);\r\n });\r\n });\r\n\r\n $(document).on(CART_UPDATED, function (event, payload) {\r\n // Update order summary on quantity change\r\n $('.cart-total-without-tax').text(payload.subTotal);\r\n $('.cart-tax').text(payload.taxes);\r\n $('.cart-discount').text(payload.discount);\r\n $('.cart-total-with-discount').text(payload.subTotalInclDiscount);\r\n $('.cart-total-with-tax').text(payload.total);\r\n });\r\n\r\n $(document).on(CART_UPDATED, function (event, payload) {\r\n // Update top right cart icon count\r\n $('.shopping-cart-icon__count').text(payload.totalCount);\r\n });\r\n\r\n $(document).on(CART_UPDATED, function (event, payload) {\r\n // Update discount codes\r\n const itemTemplate = (code) =>\r\n `
  • \r\n ${code}\r\n \r\n
  • `;\r\n const codes = payload.discountCodes.map(itemTemplate).join('');\r\n\r\n $('.discount-code-list ul').html(codes);\r\n $('.discount-code-list').toggleClass('d-none', payload.discountCodes.length === 0);\r\n });\r\n\r\n var isProcessingPurchase = false;\r\n\r\n function togglePurchaseButtonLoad(forceShow = true) {\r\n $('form#complete-purchase-form #purchase-btn-spinner').toggleClass('d-none', !forceShow);\r\n isProcessingPurchase = forceShow;\r\n }\r\n\r\n // submit form validation\r\n $('form#complete-purchase-form.needs-validation').submit((event) => {\r\n if (isProcessingPurchase) {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n return;\r\n }\r\n\r\n togglePurchaseButtonLoad(true);\r\n validateTermsConsent();\r\n validateForm(event);\r\n });\r\n\r\n $('form#complete-purchase-form .form-check-input').on('change', (event) => {\r\n if ($('form#complete-purchase-form').hasClass('was-validated')) {\r\n validateTermsConsent();\r\n event.target.checkValidity();\r\n }\r\n });\r\n\r\n var shippingAddressCheckBox = $(':checkbox[data-target=\"#shipping-address-panel\"]');\r\n\r\n if (shippingAddressCheckBox.is(':checked')) {\r\n $('#shipping-address-panel').addClass('show');\r\n }\r\n\r\n shippingAddressCheckBox.on('change', (event) => {\r\n $('#shipping-address-panel [data-required]').attr('required', event.currentTarget.checked);\r\n });\r\n\r\n var alternateBillingAddressCheckBox = $(':checkbox[data-target=\"#billing-address-panel\"]');\r\n\r\n if (alternateBillingAddressCheckBox.is(':checked')) {\r\n $('#billing-address-panel').addClass('show');\r\n }\r\n\r\n alternateBillingAddressCheckBox.on('change', (event) => {\r\n $('#billing-address-panel [data-required]').attr('required', event.currentTarget.checked);\r\n });\r\n\r\n var termsConsentCheckBox = $(':checkbox[data-terms-consent]');\r\n\r\n if (termsConsentCheckBox.is(':checked')) {\r\n $('#complete-purchase-btn').prop('disabled', false);\r\n }\r\n\r\n termsConsentCheckBox.on('change', (event) => {\r\n $('#complete-purchase-btn').prop('disabled', !event.target.checked);\r\n });\r\n\r\n const validateForm = (event) => {\r\n const $form = $(event.target);\r\n if ($form.get(0).checkValidity() === false) {\r\n togglePurchaseButtonLoad(false);\r\n event.preventDefault();\r\n event.stopPropagation();\r\n }\r\n $form.addClass('was-validated');\r\n };\r\n\r\n // term consent is checked\r\n const validateTermsConsent = () => {\r\n const $consentCheckbox = $('#consents-to-terms-check :checkbox');\r\n const consents = $consentCheckbox.is(':checked');\r\n $consentCheckbox\r\n .get(0)\r\n .setCustomValidity(\r\n !consents\r\n ? 'Du måste godkänna Prevents villkor för att slutföra beställningen.'\r\n : ''\r\n );\r\n if (!consents) {\r\n togglePurchaseButtonLoad(false);\r\n }\r\n };\r\n\r\n // when shipping address active: address, city, postcode are required\r\n //\r\n});\r\n","$(() => {\r\n const singleInquiryForm = document.querySelector('form#inquirycreate');\r\n const groupInquiryForm = document.querySelector('form#groupinquirycreate');\r\n\r\n const setFormSubmitDisabled = (form) => {\r\n const submitButton = form.querySelector('button[type=submit]');\r\n submitButton.setAttribute('disabled', 'disabled');\r\n };\r\n\r\n const checkFormValidityAndActivateSubmit = (e) => {\r\n const form = e.target.closest('form');\r\n const submitButton = form.querySelector('button[type=submit]');\r\n if (form.checkValidity() && submitButton.getAttribute('disabled')) {\r\n submitButton.removeAttribute('disabled');\r\n return;\r\n }\r\n\r\n if (!form.checkValidity() && !submitButton.getAttribute('disabled')) {\r\n submitButton.setAttribute('disabled', 'disabled');\r\n }\r\n };\r\n\r\n if (singleInquiryForm) {\r\n setFormSubmitDisabled(singleInquiryForm);\r\n singleInquiryForm.addEventListener('keyup', checkFormValidityAndActivateSubmit);\r\n }\r\n\r\n if (groupInquiryForm) {\r\n setFormSubmitDisabled(groupInquiryForm);\r\n groupInquiryForm.addEventListener('keyup', checkFormValidityAndActivateSubmit);\r\n }\r\n\r\n $('form#inquirycreate,form#groupinquirycreate').submit((event) => {\r\n validateForm(event);\r\n });\r\n\r\n $('#inquiryCreatedModal button').click((event) => {\r\n event.preventDefault();\r\n const modal = document.getElementById('inquiryCreatedModal');\r\n closeModal(modal);\r\n });\r\n const validateForm = (event) => {\r\n const $form = $(event.target);\r\n if ($form.get(0).checkValidity() === true) {\r\n event.preventDefault();\r\n submit($form);\r\n }\r\n };\r\n const clearinquiryCreate = ($form) => {\r\n $form[0].classList.remove('was-validated');\r\n $form[0].reset();\r\n\r\n setFormSubmitDisabled($form[0]);\r\n };\r\n\r\n const submit = ($form) => {\r\n const currentUrl = $form.get(0).getAttribute('action');\r\n const isGroupInquiry = $form.get(0).querySelector('input[name=GroupInquiry]') != null;\r\n const json = {\r\n InquiryName: $form.get(0).querySelector('input[name=InquiryName]').value,\r\n LastReply:\r\n $form.get(0).querySelector('input[name=LastReply]') != null\r\n ? $form.get(0).querySelector('input[name=LastReply]').value\r\n : null,\r\n GroupInquiry:\r\n $form.get(0).querySelector('input[name=GroupInquiry]') != null\r\n ? $form.get(0).querySelector('input[name=GroupInquiry]').checked\r\n : false\r\n };\r\n\r\n fetch(currentUrl, {\r\n headers: {\r\n 'X-Requested-With': 'XMLHttpRequest',\r\n 'Content-Type': 'application/json'\r\n },\r\n method: 'POST',\r\n cache: 'no-store',\r\n body: JSON.stringify({ model: json })\r\n })\r\n .then((response) => response.json())\r\n .then((result) => {\r\n const modal = document.getElementById('inquiryCreatedModal');\r\n const modalBody = modal.querySelector('#modal-body');\r\n modalBody.innerHTML = '';\r\n\r\n if (result.success) {\r\n modalBody.insertAdjacentHTML(\r\n 'afterbegin',\r\n `${result.modalLinkText}\r\n \r\n \r\n `\r\n );\r\n const feedBackTemplate = isGroupInquiry\r\n ? document.querySelector('#feedbacktextgroupinquiry')\r\n : document.querySelector('#feedbacktext');\r\n modalBody.insertAdjacentHTML('afterbegin', feedBackTemplate.innerHTML);\r\n //addcopylinkevent();\r\n clearinquiryCreate($form);\r\n } else {\r\n modalBody.insertAdjacentHTML(\r\n 'afterbegin',\r\n '
    Något gick fel när enkäten skulle skapas. Försök igen eller kontakta kundservice.
    '\r\n );\r\n }\r\n showModal(modal);\r\n })\r\n .catch((error) => {\r\n console.error('Error:', error);\r\n });\r\n };\r\n\r\n const closeModal = (modal) => {\r\n modal.classList.remove('show');\r\n modal.style.display = 'none';\r\n modal.setAttribute('aria-hidden', 'true');\r\n document.body.classList.remove('modal-open');\r\n document.querySelector('.modal-backdrop').remove();\r\n };\r\n\r\n const showModal = (modal) => {\r\n modal.classList.add('show');\r\n modal.style.display = 'block';\r\n modal.setAttribute('aria-hidden', 'false');\r\n document.body.classList.add('modal-open');\r\n document.body.insertAdjacentHTML(\r\n 'afterbegin',\r\n '
    '\r\n );\r\n };\r\n});\r\n","$(function () {\r\n const showQuestions = (faqList) => {\r\n const accordionItems = faqList.querySelectorAll('.accordion-item.d-none');\r\n accordionItems.forEach((faqItem) => {\r\n faqItem.classList.remove('d-none');\r\n });\r\n };\r\n\r\n const CreateShowMoreLink = () => {\r\n var wrapper = document.createElement('div');\r\n wrapper.className = 'text-center m-auto';\r\n var a = document.createElement('a');\r\n a.href = '#';\r\n a.className = 'btn btn-primary';\r\n var link = document.createTextNode('Visa alla');\r\n a.appendChild(link);\r\n wrapper.appendChild(a);\r\n a.addEventListener('click', function (e) {\r\n e.preventDefault();\r\n showQuestions(e.currentTarget.parentNode.parentNode);\r\n e.target.remove();\r\n });\r\n return wrapper;\r\n };\r\n\r\n const hideQuestions = () => {\r\n var accordions = document.querySelectorAll('.accordion.faq-accordion');\r\n if (accordions != null) {\r\n accordions.forEach((faq) => {\r\n const accordionItems = faq.querySelectorAll('.accordion-item');\r\n\r\n if (accordionItems.length > 5) {\r\n for (let i = 5; i < accordionItems.length; i++) {\r\n accordionItems[i].classList.add('d-none');\r\n }\r\n\r\n const link = CreateShowMoreLink();\r\n faq.insertAdjacentElement('afterEnd', link);\r\n }\r\n });\r\n }\r\n };\r\n\r\n hideQuestions();\r\n});\r\n","$(function () {\r\n $('.related-areas-block').each(\r\n (i, element) => i % 2 === 0 && element.classList.add('bg-light')\r\n );\r\n});\r\n","!function(t){var e={};function s(i){if(e[i])return e[i].exports;var o=e[i]={i:i,l:!1,exports:{}};return t[i].call(o.exports,o,o.exports,s),o.l=!0,o.exports}s.m=t,s.c=e,s.d=function(t,e,i){s.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:i})},s.r=function(t){\"undefined\"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:\"Module\"}),Object.defineProperty(t,\"__esModule\",{value:!0})},s.t=function(t,e){if(1&e&&(t=s(t)),8&e)return t;if(4&e&&\"object\"==typeof t&&t&&t.__esModule)return t;var i=Object.create(null);if(s.r(i),Object.defineProperty(i,\"default\",{enumerable:!0,value:t}),2&e&&\"string\"!=typeof t)for(var o in t)s.d(i,o,function(e){return t[e]}.bind(null,o));return i},s.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return s.d(e,\"a\",e),e},s.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},s.p=\"\",s(s.s=0)}([function(t,e,s){\"use strict\";s.r(e),s.d(e,\"AutoComplete\",(function(){return a}));var i,o=(i=function(t,e){return(i=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var s in e)e.hasOwnProperty(s)&&(t[s]=e[s])})(t,e)},function(t,e){function s(){this.constructor=t}i(t,e),t.prototype=null===e?Object.create(e):(s.prototype=e.prototype,new s)}),n=function(t){function e(e){return t.call(this,e)||this}return o(e,t),e.prototype.getDefaults=function(){return{url:\"\",method:\"get\",queryKey:\"q\",extraData:{},timeout:void 0,requestThrottling:500}},e.prototype.search=function(t,e){var s=this;null!=this.jqXHR&&this.jqXHR.abort();var i={};i[this._settings.queryKey]=t,$.extend(i,this._settings.extraData),this.requestTID&&window.clearTimeout(this.requestTID),this.requestTID=window.setTimeout((function(){s.jqXHR=$.ajax(s._settings.url,{method:s._settings.method,data:i,timeout:s._settings.timeout}),s.jqXHR.done((function(t){e(t)})),s.jqXHR.fail((function(t){var e;null===(e=s._settings)||void 0===e||e.fail(t)})),s.jqXHR.always((function(){s.jqXHR=null}))}),this._settings.requestThrottling)},e}(function(){function t(t){this._settings=$.extend(!0,{},this.getDefaults(),t)}return t.prototype.getDefaults=function(){return{}},t.prototype.getResults=function(t,e,s){return this.results},t.prototype.search=function(t,e){e(this.getResults())},t}()),r=function(){function t(t,e,s,i){this.initialized=!1,this.shown=!1,this.items=[],this.ddMouseover=!1,this._$el=t,this.formatItem=e,this.autoSelect=s,this.noResultsText=i}return t.prototype.init=function(){var t=this,e=$.extend({},this._$el.position(),{height:this._$el[0].offsetHeight});this._dd=$(\"