() {\r\n const currentPage = useKexRouterCurrentPage();\r\n return currentPage as PageType;\r\n}\r\n\r\nexport default useCurrentPage;\r\n","// /*\r\n// * Updates item in array.\r\n// */\r\n// export const updateItemInArray = (\r\n// array,\r\n// itemIdProp,\r\n// itemId,\r\n// updateItemCallback\r\n// ) => {\r\n// const updatedItems = array.map(item => {\r\n// if (item[itemIdProp] !== itemId) {\r\n// // Since we only want to update one item, preserve all others as they are now\r\n// return item;\r\n// }\r\n\r\n// // Use the provided callback to create an updated item\r\n// const updatedItem = updateItemCallback(item);\r\n// return updatedItem;\r\n// });\r\n\r\n// return updatedItems;\r\n// };\r\n\r\n// /*\r\n// * Helper for generating class names.\r\n// * e.g classnames('foo', { bar: true, duck: false }, 'baz', { quux: true }, true && classname); => 'foo bar baz quux'\r\n// */\r\n// export const classnames = (...args) =>\r\n// args\r\n// .reduce(\r\n// (classString, arg) =>\r\n// typeof arg === 'string'\r\n// ? (classString += ` ${arg}`)\r\n// : arg\r\n// ? Object.keys(arg)\r\n// .reduce(\r\n// (acc, key) => (acc += !!arg[key] ? ` ${key}` : ''),\r\n// classString\r\n// )\r\n// .trim()\r\n// : classString,\r\n// ''\r\n// )\r\n// .trim();\r\n\r\n// /*\r\n// * Generates an element id for use with block sub navigation\r\n// */\r\n// export const generateId = (type, heading, index) =>\r\n// type && heading && index !== undefined\r\n// ? `${type}-${heading.replace(/\\s|\"/g, '-')}-${index}`\r\n// : '';\r\n\r\ntype HasFileExtension = {\r\n url: string;\r\n};\r\nexport const hasFileExtension = ({ url }: HasFileExtension) =>\r\n url.indexOf('.') > -1;\r\n\r\n// // Maybe this should be handled in EPI instead on the settings page - simple string list providing the allowed file extension types.\r\n// const allowedFileTypes = [\r\n// 'pdf',\r\n// 'xls',\r\n// 'xlsx',\r\n// 'csv',\r\n// 'doc',\r\n// 'docx',\r\n// 'jpeg',\r\n// 'png',\r\n// 'gif',\r\n// 'mp4',\r\n// 'ppt',\r\n// 'pptx',\r\n// ];\r\n\r\n// let path = url.split(/#|\\?/)[0];\r\n// let splitPath = path.split('.');\r\n// let extension = splitPath[splitPath.length - 1];\r\n// return allowedFileTypes.includes(extension); // Do we have an extensions?\r\n// };\r\n\r\ntype IsInternalLinkType = {\r\n url: string;\r\n};\r\n/*\r\n * Checks if url is within the domain\r\n */\r\nexport const isInternalLink = ({ url }: IsInternalLinkType) => {\r\n if (\r\n (url.charAt(0) === '/' && url.charAt(1) !== '/') ||\r\n url.charAt(0) === '?' ||\r\n url.charAt(0) === '#'\r\n )\r\n return true;\r\n\r\n const urlPartsQuery = url.split('?');\r\n if (urlPartsQuery.length > 1) {\r\n if (urlPartsQuery[0].indexOf(window.location.host) === -1) {\r\n return false;\r\n }\r\n return true;\r\n }\r\n\r\n const urlPartsHash = urlPartsQuery[0].split('#');\r\n if (urlPartsHash.length > 1) {\r\n if (urlPartsHash[0].indexOf(window.location.host) === -1) {\r\n return false;\r\n }\r\n return true;\r\n }\r\n\r\n if (url.indexOf(window.location.host) !== -1) {\r\n return true;\r\n }\r\n return false;\r\n};\r\n\r\ntype IsEmailLinkType = {\r\n url: string;\r\n};\r\n/*\r\n * Checks if an URL is a mailto link\r\n */\r\nexport const isEmailLink = ({ url }: IsEmailLinkType) => {\r\n return url.indexOf('mailto:') === 0;\r\n};\r\n\r\ntype ParseUrlType = {};\r\n/*\r\n * Parses url sting into parts\r\n */\r\nexport const parseUrl = (url: string) => {\r\n const matches = url.match(\r\n /^(([^:/?#]+:)?(?:\\/\\/((?:([^/?#:]*):([^/?#:]*)@)?([^/?#:]*)(?::([^/?#:]*))?)))?([^?#]*)(\\?[^#]*)?(#.*)?$/\r\n );\r\n const m = matches === null ? [] : matches;\r\n //http://username:password@localhost:257/deploy/?asd=asd#asd\r\n const r = {\r\n hash: m[10] || '', // #asd\r\n host: m[3] || '', // localhost:257\r\n hostname: m[6] || '', // localhost\r\n href: m[0] || '', // http://username:password@localhost:257/deploy/?asd=asd#asd\r\n origin: m[1] || '', // http://username:password@localhost:257\r\n pathname: m[8] || (m[1] ? '/' : ''), // /deploy/\r\n port: m[7] || '', // 257\r\n protocol: m[2] || '', // http:\r\n search: m[9] || '', // ?asd=asd\r\n username: m[4] || '', // username\r\n password: m[5] || '', // password\r\n };\r\n if (r.protocol.length === 2) {\r\n r.protocol = 'file:///' + r.protocol.toUpperCase();\r\n r.origin = r.protocol + '//' + r.host;\r\n }\r\n r.href = r.origin + r.pathname + r.search + r.hash;\r\n return m && r;\r\n};\r\n\r\n/*\r\n * get value for url parameter\r\n */\r\nexport const getUrlParameter = (name: string, queryString?: string) => {\r\n name = name.replace(/[[]/, '\\\\[').replace(/[\\]]/, '\\\\]');\r\n var regex = new RegExp('[\\\\?&]' + name + '=([^]*)');\r\n var results = regex.exec(\r\n queryString ? queryString : canUseDOM() ? window.location.search : ''\r\n );\r\n return results === null\r\n ? ''\r\n : decodeURIComponent(results[1].replace(/\\+/g, ' '));\r\n};\r\n\r\nexport const getUrlParameters = (name: string, queryString?: string) => {\r\n name = name.replace(/[[]/, '\\\\[').replace(/[\\]]/, '\\\\]');\r\n var regex = new RegExp('[\\\\?&]' + name + '=([^]*)', 'g');\r\n let m;\r\n let results: string[] = [];\r\n\r\n while (\r\n (m = regex.exec(queryString ? queryString : window.location.search)) !==\r\n null\r\n ) {\r\n // This is necessary to avoid infinite loops with zero-width matches\r\n if (m.index === regex.lastIndex) {\r\n regex.lastIndex++;\r\n }\r\n\r\n // The result can be accessed through the `match`-variable.\r\n m.forEach((match, groupIndex) => {\r\n if (groupIndex % 2)\r\n results.push(decodeURIComponent(match.replace(/\\+/g, ' ')));\r\n });\r\n }\r\n return results;\r\n};\r\n\r\n/* Used on CategoryPage.tsx to memorize scroll position */\r\n\r\nfunction replaceQueryParam(param: string, newval: string, search: string) {\r\n var regex = new RegExp('([?;&])' + param + '[^&;]*[;&]?');\r\n var query = search.replace(regex, '$1').replace(/&$/, '');\r\n\r\n return (\r\n (query.length > 2 ? query + '&' : '?') +\r\n (newval ? param + '=' + newval : '')\r\n );\r\n}\r\n\r\nexport const setUrlParameter = (name: string, value: string) => {\r\n var str = window.location.search;\r\n str = replaceQueryParam(name, value, str);\r\n // window.history.pushState('', '', str);\r\n};\r\n\r\n/*\r\n * Used to check if we are in server context or not.\r\n */\r\nexport const canUseDOM = () => {\r\n return !!(\r\n typeof window !== 'undefined' &&\r\n window.document &&\r\n window.document.createElement\r\n );\r\n};\r\n\r\nexport const updateUrl = (pageTitle: string, url: string) => {\r\n const state = { id: new Date().valueOf() };\r\n window.history.pushState(state, pageTitle, url);\r\n};\r\n\r\n/*\r\n * used for epi edit mode.\r\n */\r\nexport const applyEditModeAttr = (name: string | false) => {\r\n return name\r\n ? {\r\n 'data-epi-property-name': name,\r\n }\r\n : {};\r\n};\r\n\r\n// /*\r\n// * Trigger a browser resize event\r\n// */\r\n// export const triggerResizeEvent = () => {\r\n// setTimeout(() => {\r\n// if (canUseDOM()) {\r\n// if (\r\n// navigator.userAgent.indexOf('MSIE') !== -1 ||\r\n// navigator.appVersion.indexOf('Trident/') > 0\r\n// ) {\r\n// var evt = document.createEvent('UIEvents');\r\n// evt.initUIEvent('resize', true, false, window, 0);\r\n// window.dispatchEvent(evt);\r\n// } else {\r\n// window.dispatchEvent(new Event('resize'));\r\n// }\r\n// }\r\n// }, 0);\r\n// };\r\n\r\n// /**\r\n// * native scroll in to view function\r\n// * @param {*} elm\r\n// */\r\n// export const ScrollIntoView = elm => {\r\n// !Object.isEmpty(elm) &&\r\n// elm.scrollIntoView({\r\n// behavior: 'smooth',\r\n// });\r\n// };\r\n\r\n/**\r\n * Scroll to function\r\n * @param {*} elm - element to scroll to - Could be a saved ref.current\r\n */\r\nlet scrollTimeouts: NodeJS.Timeout[] = [];\r\nexport const ScrollToEle = (ele: HTMLElement) => {\r\n if (scrollTimeouts.length) {\r\n scrollTimeouts.forEach((timeOut: NodeJS.Timeout) => {\r\n clearTimeout(timeOut);\r\n });\r\n scrollTimeouts = [];\r\n }\r\n\r\n function currentYPosition() {\r\n // Firefox, Chrome, Opera, Safari\r\n if (window.pageYOffset) return window.pageYOffset;\r\n // Internet Explorer 6 - standards mode\r\n if (document.documentElement && document.documentElement.scrollTop)\r\n return document.documentElement.scrollTop;\r\n // Internet Explorer 6, 7 and 8\r\n if (document.body.scrollTop) return document.body.scrollTop;\r\n return 0;\r\n }\r\n\r\n function elmYPosition(elm: HTMLElement) {\r\n let y = elm.offsetTop;\r\n return y - 30;\r\n }\r\n\r\n const doScroll = (leapY: number, timer: number, speed: number) =>\r\n new Promise(resolve => {\r\n scrollTimeouts.push(\r\n global.setTimeout(() => {\r\n window.scrollTo(0, leapY);\r\n resolve();\r\n }, timer * speed)\r\n );\r\n });\r\n\r\n return new Promise(resolve => {\r\n let startY = currentYPosition();\r\n let stopY = elmYPosition(ele);\r\n let distance = stopY > startY ? stopY - startY : startY - stopY;\r\n if (distance < 100) {\r\n window.scrollTo(0, stopY);\r\n resolve();\r\n }\r\n let speed = Math.round(distance / 100);\r\n if (speed >= 20) speed = 20;\r\n let step = Math.round(distance / 25);\r\n let leapY = stopY > startY ? startY + step : startY - step;\r\n let timer = 0;\r\n const promises = [];\r\n if (stopY > startY) {\r\n for (let i = startY; i < stopY; i += step) {\r\n promises.push(doScroll(leapY, timer, speed));\r\n leapY += step;\r\n if (leapY > stopY) leapY = stopY;\r\n timer++;\r\n }\r\n Promise.all(promises).then(() => {\r\n scrollTimeouts = [];\r\n resolve();\r\n });\r\n return;\r\n }\r\n for (let i = startY; i > stopY; i -= step) {\r\n promises.push(doScroll(leapY, timer, speed));\r\n leapY -= step;\r\n if (leapY < stopY) leapY = stopY;\r\n timer++;\r\n }\r\n Promise.all(promises).then(() => {\r\n scrollTimeouts = [];\r\n resolve();\r\n });\r\n });\r\n};\r\n\r\n// /*\r\n// * Inorder to not get a hacky scroll when we already have loaded the compononents.\r\n// * especially for contentarea\r\n// */\r\n// export const loadedComponents = [];\r\n\r\n/*\r\n * A web storage helper, for both sessionStorage and localStorage\r\n */\r\ntype WebStorageHelperType = {\r\n type: 'sessionStorage' | 'localStorage';\r\n storageKey: string;\r\n defaultValue: string | object | boolean;\r\n};\r\nexport const webStorageHelper = ({\r\n type,\r\n storageKey,\r\n defaultValue,\r\n}: WebStorageHelperType) => {\r\n const get = (key?: string) => {\r\n const item = window[type].getItem(storageKey);\r\n let data = item ? JSON.parse(item) : null;\r\n data = data === null ? defaultValue : data;\r\n return key ? data[key] : data;\r\n };\r\n const set = (val: string | object | boolean): void =>\r\n window[type].setItem(storageKey, JSON.stringify(val));\r\n\r\n if (!window[type].getItem(storageKey)) {\r\n set(defaultValue);\r\n }\r\n return {\r\n get,\r\n set,\r\n };\r\n};\r\n\r\n// /*\r\n// * Coverts object to url params\r\n// */\r\n// export const objectToUrlParams = object => {\r\n// return (\r\n// '?' +\r\n// Object.keys(object)\r\n// .filter(key => !!object[key])\r\n// .map(key => `${key}=${encodeURIComponent(object[key])}`)\r\n// .join('&')\r\n// );\r\n// };\r\n\r\n// /*\r\n// * Gets absolute height of element (margin and borders)\r\n// */\r\n// export const getAbsoluteHeight = el => {\r\n// // Get the DOM Node if you pass in a string\r\n// el = typeof el === 'string' ? document.querySelector(el) : el;\r\n\r\n// var styles = window.getComputedStyle(el);\r\n// var margin =\r\n// parseFloat(styles['marginTop']) + parseFloat(styles['marginBottom']);\r\n\r\n// return Math.ceil(el.offsetHeight + margin);\r\n// };\r\n\r\n// /*\r\n// * Checks if element fits in viewport.\r\n// * Possible to pass in margins in the calculation, e.g include the header's height\r\n// */\r\n// export const isElementInViewport = (\r\n// el,\r\n// { topMargin = 0, rightMargin = 0, bottomMargin = 0, leftMargin = 0 } = {}\r\n// ) => {\r\n// var rect = el.getBoundingClientRect();\r\n// return (\r\n// rect.top >= topMargin &&\r\n// rect.left >= leftMargin &&\r\n// rect.bottom <=\r\n// (window.innerHeight || document.documentElement.clientHeight) -\r\n// bottomMargin &&\r\n// rect.right <=\r\n// (window.innerWidth || document.documentElement.clientWidth) - rightMargin\r\n// );\r\n// };\r\n\r\n// /**\r\n// * Trigger animation on element\r\n// *\r\n// * @param {*} elm\r\n// * @param {*} className\r\n// */\r\n// export const triggerAnimation = (elm, className) => {\r\n// elm.classList.remove(className);\r\n// void elm.offsetWidth;\r\n// elm.classList.add(className);\r\n// };\r\n\r\n// /**\r\n// * Take form element and returns it's form elements\r\n// * values serialized in string format\r\n// *\r\n// * @param {*} form\r\n// */\r\n// export const getFormSerializedString = form => {\r\n// return Array.from(new FormData(form), e =>\r\n// e.map(value => value).join('=')\r\n// ).join('&');\r\n// };\r\n\r\n// /**\r\n// * takes a query string and transforms it to an object\r\n// * if no query string is provided it's using window location search\r\n// * @param {*} query\r\n// */\r\n// export const getQueryStringParams = queryString => {\r\n// let query = queryString || window.location.search;\r\n// return query\r\n// ? (/^[?#]/.test(query) ? query.slice(1) : query)\r\n// .split('&')\r\n// .reduce((params, param) => {\r\n// let [key, value] = param.split('=');\r\n// if (!params[key]) params[key] = [];\r\n// value &&\r\n// params[key].push(decodeURIComponent(value.replace(/\\+/g, ' ')));\r\n// return params;\r\n// }, {})\r\n// : {};\r\n// };\r\n\r\n// /**\r\n// * function for mimic optional chaining,\r\n// *\r\n// * @param {*} obj - object to check prop for\r\n// * @param {*} properties - string which represent the propeties, 'a.b.c'\r\n// * @param {*} defaultValue\r\n// */\r\n// export const getObjectProperty = (obj, properties, defaultValue) => {\r\n// if (!obj) return defaultValue;\r\n// const props = properties.split('.');\r\n// let objProp = obj;\r\n// for (let index = 0; index < props.length; index++) {\r\n// if (objProp[props[index]] !== undefined) {\r\n// objProp = objProp[props[index]];\r\n// } else {\r\n// objProp = defaultValue;\r\n// break;\r\n// }\r\n// }\r\n// return objProp;\r\n// };\r\n\r\n// /**\r\n// * Does what the function names says\r\n// */\r\n// export const getScrollbarWidth = () => {\r\n// var inner = document.createElement('p');\r\n// inner.style.width = '100%';\r\n// inner.style.height = '200px';\r\n\r\n// var outer = document.createElement('div');\r\n// outer.style.position = 'absolute';\r\n// outer.style.top = '-200px';\r\n// outer.style.left = '-300px';\r\n// outer.style.visibility = 'hidden';\r\n// outer.style.width = '200px';\r\n// outer.style.height = '150px';\r\n// outer.style.overflow = 'hidden';\r\n// outer.appendChild(inner);\r\n\r\n// document.body.appendChild(outer);\r\n// var w1 = inner.offsetWidth;\r\n// outer.style.overflow = 'scroll';\r\n// var w2 = inner.offsetWidth;\r\n// if (w1 === w2) w2 = outer.clientWidth;\r\n\r\n// document.body.removeChild(outer);\r\n\r\n// return w1 - w2;\r\n// };\r\n\r\n// /**\r\n// * Usefull when you need to wrapp content based on a condition\r\n// * @param {*} condition - condition if wrap or not\r\n// * @param {*} wrapper - wrapper function/Component\r\n// * @param {*} children - as in children\r\n// */\r\n// export const ConditionalWrapper = ({ condition, wrapper, children }) =>\r\n// condition ? wrapper(children) : children;\r\n","import { EventDispatcher, ON_KEX_ERROR } from './EventDispatcher';\r\n\r\nexport default function(\r\n url: string,\r\n signal: AbortSignal,\r\n onComplete: (\r\n data: T,\r\n resolve: (value?: P | PromiseLike
) => void,\r\n reject: (reason?: any) => void,\r\n response: Response\r\n ) => void,\r\n litiumRequest: string = '',\r\n requestToken: string = ''\r\n) {\r\n return new Promise
((resolve, reject) => {\r\n let response: Response;\r\n fetch(url, {\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n credentials: 'same-origin',\r\n 'litium-request-context': litiumRequest,\r\n RequestVerificationToken: requestToken,\r\n },\r\n signal,\r\n })\r\n .then(res => {\r\n response = res;\r\n if (res.ok || res.status === 404) {\r\n return res.json();\r\n } else {\r\n throw new Error(`API: ${res.statusText}`);\r\n }\r\n })\r\n .then(data => onComplete(data, resolve, reject, response))\r\n .catch(err => {\r\n if (\r\n err.name === 'AbortError' ||\r\n err === 'DOMException: The user aborted a request.'\r\n ) {\r\n resolve(undefined);\r\n } else {\r\n EventDispatcher.dispatch(ON_KEX_ERROR, err);\r\n }\r\n });\r\n });\r\n}\r\n","import React, { useReducer } from 'react';\r\nimport { styled, theme } from '../../../Theme/';\r\n\r\ntype PropType = {\r\n children: React.ReactNode;\r\n};\r\n\r\nconst KexLoadingDispatchContext = React.createContext({});\r\n\r\ntype ActionType = 'add' | 'remove';\r\n\r\nconst reducer = (state: { count: number }, action: ActionType) => {\r\n switch (action) {\r\n case 'add': {\r\n return { count: state.count + 1 };\r\n }\r\n case 'remove': {\r\n const count = state.count - 1;\r\n return { count: count < 0 ? 0 : count };\r\n }\r\n default: {\r\n return state;\r\n }\r\n }\r\n};\r\n\r\nconst animateSvgOnLoading = {\r\n animationName: {\r\n '100%': {\r\n transform: 'rotate(360deg)',\r\n },\r\n },\r\n animationDuration: theme.timings.one,\r\n animationTimingFunction: 'linear',\r\n animationIterationCount: 'infinite',\r\n};\r\n\r\nconst animateCircleOnLoading = {\r\n animationName: {\r\n '0%': {\r\n strokeDasharray: '1, 150',\r\n strokeDashoffset: '0',\r\n stroke: theme.lighterDarkGray,\r\n },\r\n '50%': {\r\n strokeDasharray: '90, 150',\r\n strokeDashoffset: '-35',\r\n stroke: theme.primaryBlue,\r\n },\r\n '100%': {\r\n strokeDasharray: '90, 150',\r\n strokeDashoffset: '-124',\r\n stroke: theme.primaryBackground,\r\n },\r\n },\r\n animationDuration: theme.timings.oneAndAHalf,\r\n animationTimingFunction: 'ease-in-out',\r\n animationIterationCount: 'infinite',\r\n};\r\nconst divStyleOnLoading = {\r\n opacity: '1',\r\n};\r\n\r\nfunction KexLoadingCircle({ children }: PropType) {\r\n const [{ count }, dispatch] = useReducer(reducer, { count: 0 });\r\n const isLoading = count !== 0;\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n \r\n {children}\r\n \r\n );\r\n}\r\n\r\nconst useKexLoadingCircle: () => React.Dispatch = () => {\r\n return React.useContext(KexLoadingDispatchContext) as React.Dispatch<\r\n ActionType\r\n >;\r\n};\r\n\r\nexport { KexLoadingCircle, useKexLoadingCircle };\r\n\r\nconst OuterDiv = styled.div({\r\n position: 'fixed',\r\n width: '100vw',\r\n height: '100vh',\r\n zIndex: theme.zIndex.pageLoader,\r\n overflow: 'hidden',\r\n top: 0,\r\n right: 0,\r\n opacity: '0',\r\n transition: {\r\n duration: theme.timings.threeTenths,\r\n property: 'opacity',\r\n timingFunction: theme.animation.timingFn,\r\n },\r\n pointerEvents: 'none',\r\n});\r\n\r\nconst InnerDiv = styled.div({\r\n position: 'absolute',\r\n top: 'calc(40%)',\r\n right: '50%',\r\n transform: 'translate(50%, -50%)',\r\n backgroundColor: '#fff',\r\n borderRadius: '50%',\r\n width: '80px',\r\n height: '80px',\r\n boxShadow: '0px 10px 10px -10px black',\r\n transition: {\r\n duration: theme.timings.threeTenths,\r\n delay: theme.timings.oneHalf,\r\n property: 'opacity',\r\n timingFunction: theme.animation.timingFn,\r\n },\r\n opacity: '0',\r\n});\r\n\r\nconst Svg = styled.svg({\r\n position: 'absolute',\r\n top: 'calc(50% - 25px)',\r\n right: 'calc(50% - 25px)',\r\n width: '50px',\r\n height: '50px',\r\n});\r\n\r\nconst Circle = styled.circle({\r\n stroke: theme.primary,\r\n strokeLinecap: 'round',\r\n});\r\n","import { useEffect } from 'react';\r\nimport { IS_SERVER_CONTEXT } from '../Configs/EnvConfig';\r\nimport { webStorageHelper } from '../Common/Helpers';\r\nimport { KexNavigateType, KexNavigateEventStateType } from './KexRouter';\r\n\r\nexport const addScrollHistory = () => {\r\n /*\r\n * if current history does not contain any id, add it.\r\n */\r\n if (window.history.state === null) {\r\n window.history.replaceState(\r\n { id: new Date().valueOf() },\r\n document.title,\r\n window.location.href\r\n );\r\n }\r\n\r\n const scrolls = scrollHistory.get();\r\n scrolls[window.history.state.id] =\r\n window.pageYOffset || document.documentElement.scrollTop;\r\n scrollHistory.set(scrolls);\r\n};\r\n\r\nconst scrollHistory: any = IS_SERVER_CONTEXT\r\n ? {}\r\n : webStorageHelper({\r\n type: 'sessionStorage',\r\n storageKey: 'scrollHistory',\r\n defaultValue: {},\r\n });\r\n\r\nconst pushState = (responseUrl: string, pageTitle: string) => {\r\n addScrollHistory();\r\n const state = { id: new Date().valueOf() };\r\n\r\n window.history.pushState(state, pageTitle, responseUrl);\r\n};\r\n\r\nconst replaceState = (responseUrl: string, pageTitle: string) => {\r\n if (window.location.href !== responseUrl) {\r\n window.history.replaceState(window.history.state, pageTitle, responseUrl);\r\n }\r\n};\r\n\r\nexport const updateScrollPosition = (\r\n eventState: KexNavigateEventStateType,\r\n responseUrl: string,\r\n pageTitle: string,\r\n pageType: string\r\n) => {\r\n //if user navigated through links in page, push link to browser history\r\n if (eventState.clicked) {\r\n pushState(responseUrl, pageTitle);\r\n } else {\r\n replaceState(responseUrl, pageTitle);\r\n }\r\n\r\n if (eventState.clicked) {\r\n //if user navigated through links in page, scroll to top\r\n window.scrollTo(0, 0);\r\n } else {\r\n /*\r\n * User has used browser's back or forward function\r\n *\r\n * if - use saved scroll pos in session storage\r\n * else - fallback to top\r\n */\r\n if (eventState && eventState.id !== undefined) {\r\n const scrolls = scrollHistory.get();\r\n if (scrolls[eventState.id] !== undefined) {\r\n const id = scrolls[eventState.id];\r\n setTimeout(() => window.scrollTo(0, id), 0);\r\n setTimeout(() => {\r\n const scrollPos =\r\n window.pageYOffset || document.documentElement.scrollTop;\r\n scrollPos !== id && window.scrollTo(0, id);\r\n }, 500);\r\n }\r\n } else {\r\n window.scrollTo(0, 0);\r\n }\r\n }\r\n window.focus();\r\n};\r\n\r\nexport const useSaveScrollPosition = (kexNavigate: KexNavigateType) => {\r\n useEffect(() => {\r\n let timeOutFn: number;\r\n let touchMoved = false;\r\n const isTouchDevice = 'ontouchstart' in window;\r\n\r\n /*\r\n * workaround for touchdevices (mainly phones) that do not have 'scrollRestoration' in window.history\r\n */\r\n if (isTouchDevice && !('scrollRestoration' in window.history)) {\r\n document.body.addEventListener(\r\n 'touchstart',\r\n () => {\r\n touchMoved = true;\r\n },\r\n { passive: true }\r\n );\r\n\r\n window.addEventListener(\r\n 'scroll',\r\n () => {\r\n if (touchMoved) {\r\n addScrollHistory();\r\n clearTimeout(timeOutFn);\r\n timeOutFn = window.setTimeout(() => {\r\n touchMoved = false;\r\n }, 50);\r\n }\r\n },\r\n { passive: true }\r\n );\r\n }\r\n\r\n if ('scrollRestoration' in window.history) {\r\n window.history.scrollRestoration = 'manual';\r\n window.addEventListener('scroll', addScrollHistory, { passive: true });\r\n } else {\r\n /*\r\n * workaround for browsers that do not have 'scrollRestoration' in window.history\r\n */\r\n ['blur', 'mouseout', 'beforeunload'].forEach(e =>\r\n window.addEventListener(e, addScrollHistory)\r\n );\r\n }\r\n\r\n window.addEventListener('popstate', e => {\r\n kexNavigate(window.location.href, e);\r\n });\r\n }, [kexNavigate]);\r\n};\r\n","import { parseUrl } from '../Common/Helpers';\r\nimport PageModelBase from '../Models/PageModelBase.interface';\r\nimport Fetcher from '../Common/Fetcher';\r\nimport AbortControllerRefType from '../Common/AbortControllerRefType';\r\n\r\nexport interface ReturnPageModel extends PageModelBase {\r\n responseUrl?: string;\r\n}\r\n\r\nfunction FetchPage(\r\n url: string,\r\n abortControllerRef: React.MutableRefObject\r\n) {\r\n abortControllerRef.current?.abortController?.abort();\r\n abortControllerRef.current = {\r\n url,\r\n abortController: new AbortController(),\r\n };\r\n const signal = abortControllerRef.current.abortController.signal;\r\n\r\n if (url === 'epiedit') {\r\n url = window.location.pathname + window.location.search;\r\n }\r\n\r\n /*\r\n * fix so we are only fetching the current page and not the whole appinitdata\r\n */\r\n return Fetcher(\r\n url,\r\n signal,\r\n (data, resolve, reject, requestResult) => {\r\n // if requested url is the same as response page, add, if present, hash to response url if\r\n // requested url had hash.\r\n const responseUrl = requestResult.url;\r\n const parsedUrl = parseUrl(url);\r\n const parsedResUrl = parseUrl(responseUrl);\r\n data.currentPage.responseUrl =\r\n parsedUrl.pathname + parsedUrl.search ===\r\n parsedResUrl.pathname + parsedResUrl.search\r\n ? parsedUrl.hash\r\n ? `${responseUrl}${parsedUrl.hash}`\r\n : responseUrl\r\n : responseUrl;\r\n resolve(data.currentPage);\r\n }\r\n );\r\n}\r\n\r\nexport default FetchPage;\r\n","import { useRef, useEffect } from 'react';\r\n\r\nfunction usePrevious(value) {\r\n // The ref object is a generic container whose current property is mutable ...\r\n // ... and can hold any value, similar to an instance property on a class\r\n const ref = useRef();\r\n\r\n // Store current value in ref\r\n useEffect(() => {\r\n ref.current = value;\r\n }, [value]); // Only re-run if value changes\r\n\r\n // Return previous value (happens before update in useEffect above)\r\n return ref.current;\r\n}\r\n\r\nexport default usePrevious;\r\n","import { useState, useEffect, useRef } from 'react';\r\nimport useSWR from 'swr';\r\nimport FetchPage, { ReturnPageModel } from './FetchPage';\r\nimport { useKexLoadingCircle } from '../Loading/KexLoadingCircle/KexLoadingCircle';\r\nimport { IS_PRODUCTION_ENV } from '../Configs/EnvConfig';\r\nimport AppInitModel from '../Models/AppInitModel.interface';\r\nimport usePrevious from '../Hooks/usePrevious';\r\nimport AbortControllerRefType from '../Common/AbortControllerRefType';\r\n\r\nlet hasMounted = false;\r\n\r\nexport default function(\r\n url: string,\r\n initialData: AppInitModel\r\n): [ReturnPageModel, string, string] {\r\n const [currentPage, setCurrentPage] = useState(\r\n initialData.currentPage\r\n );\r\n\r\n const dispatchLoading = useKexLoadingCircle();\r\n const abortControllerRef = useRef();\r\n\r\n if (abortControllerRef.current && abortControllerRef.current.url !== url) {\r\n abortControllerRef.current.abortController.abort();\r\n }\r\n const { data: fetchedPage } = useSWR(\r\n url ? [url, abortControllerRef] : null,\r\n FetchPage,\r\n {\r\n initialData: hasMounted ? undefined : initialData.currentPage,\r\n revalidateOnFocus: IS_PRODUCTION_ENV,\r\n dedupingInterval: initialData.appSettings.pageCacheTime,\r\n }\r\n );\r\n const prevFetchedPage = usePrevious(fetchedPage);\r\n\r\n useEffect(() => {\r\n if (!hasMounted) {\r\n hasMounted = true;\r\n } else {\r\n if (\r\n (!prevFetchedPage && fetchedPage) ||\r\n (prevFetchedPage && !fetchedPage)\r\n ) {\r\n dispatchLoading(!fetchedPage ? 'add' : 'remove');\r\n }\r\n\r\n if (fetchedPage) {\r\n setCurrentPage(fetchedPage);\r\n }\r\n }\r\n }, [dispatchLoading, fetchedPage, prevFetchedPage]);\r\n\r\n return [currentPage, currentPage.pageId, currentPage.pageTitle];\r\n}\r\n","import React, {\r\n useEffect,\r\n useCallback,\r\n useReducer,\r\n useRef,\r\n useMemo,\r\n} from 'react';\r\n\r\nimport { useSaveScrollPosition, updateScrollPosition } from './ScrollHandling';\r\nimport useQueryPage from './useQueryPage';\r\nimport AppInitModel from '../Models/AppInitModel.interface';\r\nimport PageModelBase from '../Models/PageModelBase.interface';\r\n\r\ntype PropType = {\r\n appInitData: AppInitModel;\r\n initUrl: string;\r\n children: React.ReactNode;\r\n};\r\n\r\nexport type KexNavigateEventStateType = PopStateEvent & {\r\n clicked?: true;\r\n id?: number;\r\n};\r\n\r\nexport type KexNavigateType = (\r\n url: string,\r\n event?: PopStateEvent | undefined\r\n) => Promise;\r\n\r\ntype kexNavigateCallbackRefType = {\r\n resolve: (data: any) => any;\r\n reject: (data: any) => any;\r\n eventState: KexNavigateEventStateType;\r\n};\r\n\r\nconst KexRouterDispatchContext = React.createContext({});\r\nconst KexRouterCurrentPage = React.createContext({});\r\n\r\nconst reducer = (state: any, action: any) => {\r\n switch (action.type) {\r\n case 'updateUrl': {\r\n return { ...state, url: action.url };\r\n }\r\n default: {\r\n return state;\r\n }\r\n }\r\n};\r\nlet hasMounted = false;\r\n\r\nfunction KexRouter({ appInitData, initUrl, children }: PropType) {\r\n const [routerState, dispatchState] = useReducer(reducer, {\r\n url: initUrl,\r\n });\r\n const kexNavigateCallbackRef = useRef();\r\n const [currentPageData, pageId, pageTitle] = useQueryPage(\r\n routerState.url,\r\n appInitData\r\n );\r\n\r\n const kexNavigate = useCallback((url: string, event?: PopStateEvent): Promise<\r\n PageModelBase\r\n > => {\r\n const { state } = event ? event : { state: { clicked: true } };\r\n return new Promise((resolve, reject) => {\r\n kexNavigateCallbackRef.current = {\r\n resolve,\r\n reject,\r\n eventState: state,\r\n };\r\n dispatchState({\r\n type: 'updateUrl',\r\n url: url,\r\n });\r\n });\r\n }, []);\r\n\r\n useSaveScrollPosition(kexNavigate);\r\n\r\n useEffect(() => {\r\n document.title = `${pageTitle}`;\r\n }, [pageTitle]);\r\n\r\n /**\r\n * using useMemo instead of useEffect because we need to updateScrollPosition (change url)\r\n * before we render the new current page.\r\n */\r\n useMemo(() => {\r\n if (hasMounted) {\r\n if (kexNavigateCallbackRef.current) {\r\n if (currentPageData.responseUrl) {\r\n updateScrollPosition(\r\n kexNavigateCallbackRef.current.eventState,\r\n currentPageData.responseUrl,\r\n pageTitle,\r\n currentPageData.pageType\r\n );\r\n kexNavigateCallbackRef.current = undefined;\r\n }\r\n }\r\n } else {\r\n hasMounted = true;\r\n }\r\n /* we only want to trigger updateScrollPosition the first time we get data from\r\n * useQueryPage and it's safe to only use pageId as dependency.\r\n */\r\n // eslint-disable-next-line\r\n }, [pageId, currentPageData.responseUrl]);\r\n\r\n return (\r\n \r\n \r\n {children}\r\n \r\n \r\n );\r\n}\r\n\r\nconst useKexNavigate = () => {\r\n return React.useContext(KexRouterDispatchContext) as KexNavigateType;\r\n};\r\n\r\nfunction useKexRouterCurrentPage() {\r\n return React.useContext(KexRouterCurrentPage) as unknown;\r\n}\r\n\r\nexport { KexRouter, useKexNavigate, useKexRouterCurrentPage };\r\n","import React from 'react';\r\nimport { useKexNavigate } from '../KexRouter/KexRouter';\r\nimport {\r\n isInternalLink,\r\n isEmailLink,\r\n hasFileExtension,\r\n} from '../Common/Helpers';\r\nimport { styled, StyledProps } from '@glitz/react';\r\n\r\ntype RedirectType = {\r\n kexNavigate: any;\r\n target: string;\r\n url: string;\r\n onNavigated?: () => void;\r\n};\r\n\r\ntype PropType = StyledProps & {\r\n onClick?: (x?: () => void) => void;\r\n callbackOnClick?: boolean;\r\n onNavigated?: () => void;\r\n children?: React.ReactNode;\r\n pageType?: any;\r\n href?: string;\r\n isMedia?: boolean;\r\n title?: string;\r\n};\r\n\r\nconst redirect = ({\r\n kexNavigate,\r\n target,\r\n url = '',\r\n onNavigated,\r\n}: RedirectType) => {\r\n if (url === '' || url === undefined) return;\r\n if (\r\n target !== '_blank' &&\r\n isInternalLink({ url }) &&\r\n !hasFileExtension({ url })\r\n ) {\r\n onNavigated ? kexNavigate(url).then(onNavigated()) : kexNavigate(url);\r\n } else if (isEmailLink({ url })) {\r\n window.location.href = url;\r\n } else {\r\n window.open(url, '_blank');\r\n }\r\n};\r\n\r\nconst KexLink = ({\r\n onClick,\r\n callbackOnClick,\r\n onNavigated,\r\n children,\r\n href,\r\n isMedia,\r\n compose,\r\n ...rest\r\n}: PropType) => {\r\n const kexNavigate = useKexNavigate();\r\n return typeof href === 'string' && href.substr(0, 4) === 'http' ? (\r\n \r\n {children}\r\n \r\n ) : (\r\n {\r\n e.persist();\r\n e.preventDefault();\r\n const target = e.currentTarget.target;\r\n if (callbackOnClick) {\r\n onClick &&\r\n onClick(() =>\r\n redirect({ kexNavigate, target, url: href ?? '', onNavigated })\r\n );\r\n } else {\r\n onClick && onClick();\r\n redirect({ kexNavigate, target, url: href ?? '', onNavigated });\r\n }\r\n }}\r\n href={href}\r\n >\r\n {children}\r\n \r\n );\r\n};\r\n\r\nexport default styled(KexLink);\r\n","/** \r\n Colors\r\n*/\r\nexport const primary = '#484848';\r\nexport const secondary = '#F7EDDA';\r\nexport const secondaryText = '#F5F5F5';\r\nexport const white = '#FFFFFF';\r\nexport const breadText = '#404040';\r\nexport const heading = '#5C5C5C';\r\nexport const modal = '#A3A3A3';\r\nexport const hover = '#EDEDED';\r\nexport const primaryBackground = '#F8F8F8';\r\n\r\nexport const placeholder = '#AEAEAE';\r\nexport const sale = '#9C2929';\r\nexport const black = '#000000';\r\nexport const red = '#FF0000';\r\nexport const darkGray = '#292929';\r\nexport const lighterDarkGray = '#2E3035';\r\nexport const gray = '#3E3E3E';\r\nexport const lightGray = '#FAFAFA';\r\nexport const primaryBlue = '#0F4C81';\r\nexport const primaryDarkBlue = '#043662';\r\nexport const headerIconGray = '#C9CAC8';\r\nexport const veryLightGray = '#ECECEC';\r\nexport const linkColor = '#0664AA';\r\nexport const iconLightBlue = '#94B2CC';\r\nexport const grayLine = '#DCDCDC';\r\nexport const lightBlue = '#D9E4ED';\r\nexport const lightBlueHover = '#B7CBDC';\r\nexport const middleGray = '#767676';\r\nexport const inStockGreen = '#489C70';\r\nexport const notInStockRed = '#F44545';\r\nexport const purple = '#852A81';\r\n\r\n/** Validation */\r\n\r\nexport const errorPrimary = '#feb2b2';\r\nexport const errorText = '#9a2626';\r\n\r\nexport const buttonPrimary = '#2E2E2E';\r\n\r\nexport const transparent = 'transparent';\r\n","import React from 'react';\r\nimport loadable from '@loadable/component';\r\n\r\nimport KexPage from './Shared/KexPage/KexPage';\r\nimport { KexRouter } from './Shared/KexRouter/KexRouter';\r\nimport { Header } from './Shared/Models/Headers/Header';\r\nimport Footer from './Shared/Models/Footers/Footer/Footer';\r\nimport USPArea from './Shared/Models/USPArea/USPArea';\r\nimport { KexLoadingCircle } from './Shared/Loading/KexLoadingCircle/KexLoadingCircle';\r\nimport KexReporterOverlay from './Shared/KexReporterOverlay/KexReporterOverlay';\r\nimport KexNotificationOverlay from './Shared/Notifications/BasicNotification';\r\nimport ErrorBoundary from './Shared/ErrorBoundary/ErrorBoundary';\r\nimport useCurrentPage from '../Features/Shared/Hooks/useCurrentPage';\r\nimport AppInitModel from './Shared/Models/AppInitModel.interface';\r\nimport PageModelBase from './Shared/Models/PageModelBase.interface';\r\nimport { AppSettingsProvider } from './Shared/AppSettingsProvider/AppSettingsProvider';\r\nimport { UserContextProvider } from './Shared/UserContextProvider/UserContextProvider';\r\nimport Cookies from './Cookies/Cookies.js';\r\nimport { SignOut } from './LoginPage/Account';\r\nimport LoginPage from './LoginPage/LoginPage';\r\n\r\ntype PropType = {\r\n appInitData: AppInitModel;\r\n};\r\n\r\nconst NotFoundPage = loadable(() =>\r\n import(/* webpackPrefetch: true */ './NotFoundPage/NotFoundPage')\r\n);\r\n\r\nconst Content = ({ appInitData }: PropType) => {\r\n const { pageType } = useCurrentPage();\r\n\r\n return pageType === 'BlockPreviewPage' ? (\r\n \r\n ) : (\r\n <>\r\n \r\n \r\n {/* {appInitData.uspArea && } */}\r\n \r\n\r\n \r\n \r\n >\r\n );\r\n};\r\n\r\nfunction App({ appInitData }: PropType) {\r\n // setInterval(() => {\r\n // SignOut = (languageRoute: string, requestToken: string) => {\r\n // window.location.href = `${LoginPage}`;\r\n // };\r\n // }, 1000 * 60);\r\n return (\r\n \r\n \r\n \r\n }>\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n );\r\n}\r\n\r\nexport default App;\r\n\r\n// setInterval(() => {\r\n// SignOut(redirectUrl);\r\n// window.location.href = `${redirectUrl ? redirectUrl : data.redirectUrl}`;\r\n// }, 1000 * 60);\r\n","import React from 'react';\r\nimport loadable from '@loadable/component';\r\nimport LoadingPageType from '../Loading/LoadingPageType/LoadingPageType';\r\nimport useCurrentPage from '../Hooks/useCurrentPage';\r\nimport PageModelBase from '../Models/PageModelBase.interface';\r\n\r\n/* not possible to use full dynamic imports, in server context it wont be able to locate chunks */\r\nconst loadablePages = {\r\n StartPage: loadable(() =>\r\n import(/* webpackPrefetch: true */ '../../StartPage/StartPage')\r\n ),\r\n StandardPage: loadable(() =>\r\n import(/* webpackPrefetch: true */ '../../StandardPage/StandardPage')\r\n ),\r\n RecruitingPage: loadable(() =>\r\n import(/* webpackPrefetch: true */ '../../RecruitingPage/RecruitingPage')\r\n ),\r\n SegmentPage: loadable(() =>\r\n import(/* webpackPrefetch: true */ '../../SegmentPage/SegmentPage')\r\n ),\r\n ProductPage: loadable(() =>\r\n import(/* webpackPrefetch: true */ '../../ProductPage/ProductPage')\r\n ),\r\n BlockPreviewPage: loadable(() =>\r\n import('../../BlockPreview/BlockPreviewPage')\r\n ),\r\n CategoryPage: loadable(() =>\r\n import(/* webpackPrefetch: true */ '../../CategoryPage/CategoryPage')\r\n ),\r\n CheckoutPage: loadable(() =>\r\n import(/* webpackPrefetch: true */ '../../CheckoutPage/CheckoutPage')\r\n ),\r\n CartPage: loadable(() =>\r\n import(/* webpackPrefetch: true */ '../../Cart/CartPage')\r\n ),\r\n OrderConfirmationPage: loadable(() =>\r\n import(\r\n /* webpackPrefetch: true */ '../../OrderConfirmation/OrderConfirmationPage'\r\n )\r\n ),\r\n SearchPage: loadable(() =>\r\n import(/* webpackPrefetch: true */ '../../SearchPage/SearchPage')\r\n ),\r\n LoginPage: loadable(() =>\r\n import(/* webpackPrefetch: true */ '../../LoginPage/LoginPage')\r\n ),\r\n NotFoundPage: loadable(() => import('../../NotFoundPage/NotFoundPage')),\r\n NewsArchivePage: loadable(() =>\r\n import(/* webpackPrefetch: true */ '../../NewsArchivePage/NewsArchivePage')\r\n ),\r\n NewsPage: loadable(() =>\r\n import(/* webpackPrefetch: true */ '../../NewsPage/NewsPage')\r\n ),\r\n PlanogramPage: loadable(() =>\r\n import(/* webpackPrefetch: true */ '../../PlanogramPage/PlanogramPage')\r\n ),\r\n MyPagesPage: loadable(() =>\r\n import(/* webpackPrefetch: true */ '../../MyPagesPage/MyPagesPage')\r\n ),\r\n MyPlanogramsPage: loadable(() =>\r\n import(\r\n /* webpackPrefetch: true */ '../../MyPlanogramsPage/MyPlanogramsPage'\r\n )\r\n ),\r\n MyPlanogramsSeasonalPage: loadable(() =>\r\n import(\r\n /* webpackPrefetch: true */ '../../MyPlanogramsSeasonalPage/MyPlanogramsSeasonalPage'\r\n )\r\n ),\r\n};\r\n\r\nconst KexPage = () => {\r\n const { pageType } = useCurrentPage();\r\n\r\n const LoadablePage = (loadablePages as any)[pageType];\r\n return LoadablePage === undefined ? (\r\n <>>\r\n ) : (\r\n } />\r\n );\r\n};\r\n\r\nexport default KexPage;\r\n","import { useState, useEffect } from 'react';\r\n\r\nimport { IS_SERVER_CONTEXT } from '../Configs/EnvConfig';\r\n\r\nfunction useMedia(query, initialServerValue = false) {\r\n const [state, setState] = useState(() =>\r\n IS_SERVER_CONTEXT ? initialServerValue : window.matchMedia(query).matches\r\n );\r\n\r\n useEffect(() => {\r\n const mql = window.matchMedia(query);\r\n const onChange = () => {\r\n setState(!!mql.matches);\r\n };\r\n\r\n mql.addListener(onChange);\r\n setState(mql.matches);\r\n return () => {\r\n mql.removeListener(onChange);\r\n };\r\n }, [query]);\r\n\r\n return state;\r\n}\r\n\r\nexport default useMedia;\r\n","import React from 'react';\r\nimport UserState from '../Models/UserState.interface';\r\nimport useQueryUserState from './useQueryUserState';\r\n\r\ntype PropType = {\r\n children: React.ReactNode;\r\n data: UserState;\r\n};\r\n\r\nconst UserContext = React.createContext({});\r\n\r\nexport const UserContextProvider = ({ children, data }: PropType) => {\r\n const [userStateData] = useQueryUserState(data);\r\n return (\r\n \r\n {children}\r\n \r\n );\r\n};\r\n\r\nexport const useUserStateData = () => {\r\n return React.useContext(UserContext) as UserState;\r\n};\r\n","import React from 'react';\r\nimport { styled, StyledProps } from '@glitz/react';\r\n\r\nfunction CloseIcon({ compose }: StyledProps) {\r\n return (\r\n \r\n \r\n \r\n );\r\n}\r\n\r\nexport default styled(CloseIcon);\r\n","import React from 'react';\r\nimport { styled, theme } from '../../Theme';\r\nimport { media } from '@glitz/core';\r\nimport { StyledProps } from '@glitz/react';\r\n\r\ntype Divider = StyledProps;\r\n\r\nconst ContentDivider = ({ compose }: Divider) => {\r\n return ;\r\n};\r\n\r\nconst Base = styled.div({\r\n height: theme.tiny,\r\n width: theme.massive,\r\n margin: { y: theme.huge },\r\n backgroundColor: theme.primary,\r\n ...media(theme.mediaQuery.mediaMaxSmall, {\r\n margin: { top: theme.huge, bottom: theme.large },\r\n }),\r\n});\r\n\r\nexport default styled(ContentDivider);\r\n","import React from 'react';\r\nimport loadable from '@loadable/component';\r\nimport IHeader from './Header.interface';\r\nimport useQueryHeader from './useQueryHeader';\r\nimport useMedia from '../../Hooks/useMedia';\r\nimport { theme } from '../../../Theme';\r\nimport useCurrentPage from '../../Hooks/useCurrentPage';\r\nimport PageModelBase from '../PageModelBase.interface';\r\n\r\nconst MobileHeader = loadable(() => import('./MobileHeader/MobileHeader'));\r\nconst DesktopHeader = loadable(() => import('./DesktopHeader/DesktopHeader'));\r\nconst MobileMenu = loadable(() => import('../../MobileMenu/MobileMenu'));\r\n\r\ntype PropType = {\r\n initData: IHeader;\r\n};\r\n\r\nconst HeaderContext = React.createContext({});\r\n\r\nfunction Header({ initData }: PropType) {\r\n const [headerData] = useQueryHeader(initData);\r\n const { inEditMode } = useCurrentPage();\r\n const isDesktop = useMedia(theme.mediaQuery.mediaMinLarge);\r\n\r\n return (\r\n \r\n {/* episerver does not like loading both headers while in on-page-edit. When we do, it messes up some other CSS. */}\r\n {isDesktop || inEditMode ? : }\r\n {!isDesktop && }\r\n \r\n );\r\n}\r\n\r\nconst useHeaderData = () => {\r\n return React.useContext(HeaderContext) as IHeader;\r\n};\r\n\r\nexport { Header, useHeaderData };\r\n","import GetLoggedInSateModel from '../../App/Models/GetLoggedInSate.interface';\r\nimport Fetcher from '../Common/Fetcher';\r\nimport UserState from '../Models/UserState.interface';\r\n\r\nlet abortController: AbortController = new AbortController();\r\n\r\nfunction FetchUserState(url: string) {\r\n abortController.abort();\r\n abortController = new AbortController();\r\n const signal = abortController.signal;\r\n\r\n return Fetcher(\r\n url,\r\n signal,\r\n (res, resolve, reject) => {\r\n if (res.success) {\r\n resolve(res?.userState);\r\n }\r\n\r\n resolve({} as UserState);\r\n }\r\n );\r\n}\r\n\r\nexport default FetchUserState;\r\n","import { useState, useEffect } from 'react';\r\nimport useSWR, { mutate } from 'swr';\r\nimport { IS_PRODUCTION_ENV } from '../Configs/EnvConfig';\r\nimport FetchUserState from './FetchUserState';\r\nimport UserState from '../Models/UserState.interface';\r\nimport { useAppSettingsData } from '../AppSettingsProvider/AppSettingsProvider';\r\n\r\nlet hasMounted = false;\r\nlet url = '';\r\n\r\nexport default function(initialData: UserState): [UserState] {\r\n const [data, setData] = useState(initialData);\r\n\r\n const { languageRoute } = useAppSettingsData();\r\n\r\n url = `/api/${languageRoute}/App/GetUserState`;\r\n\r\n const queryData = useSWR(\r\n '/App/GetUserState',\r\n () => FetchUserState(url),\r\n {\r\n initialData: hasMounted ? undefined : initialData,\r\n revalidateOnFocus: IS_PRODUCTION_ENV,\r\n }\r\n );\r\n\r\n useEffect(() => {\r\n if (!hasMounted) {\r\n hasMounted = true;\r\n } else {\r\n if (queryData.data) {\r\n setData(queryData.data);\r\n }\r\n }\r\n }, [queryData.data]);\r\n\r\n return [data];\r\n}\r\n\r\nexport async function updateUserState() {\r\n const res = await FetchUserState(url);\r\n if (res) {\r\n mutate('/App/GetUserState', res, false);\r\n }\r\n}\r\n","import GetStandardHeaderModel from '../../../App/Models/GetStandardHeaderModel.interface';\r\nimport IHeader from './Header.interface';\r\nimport Fetcher from '../../Common/Fetcher';\r\n\r\nlet abortController: AbortController = new AbortController();\r\n\r\nfunction FetchHeader(url: string, litiumContext: string) {\r\n abortController.abort();\r\n abortController = new AbortController();\r\n const signal = abortController.signal;\r\n\r\n return Fetcher(\r\n url,\r\n signal,\r\n (res, resolve, reject) => {\r\n if (res.success) {\r\n resolve(res.data);\r\n }\r\n },\r\n litiumContext\r\n );\r\n}\r\n\r\nexport default FetchHeader;\r\n","import { useState, useEffect } from 'react';\r\nimport useSWR, { mutate } from 'swr';\r\nimport { useKexLoadingCircle } from '../../Loading/KexLoadingCircle/KexLoadingCircle';\r\nimport { IS_PRODUCTION_ENV } from '../../Configs/EnvConfig';\r\nimport FetchHeader from './FetchHeader';\r\nimport IHeader from './Header.interface';\r\nimport { useAppSettingsData } from '../../AppSettingsProvider/AppSettingsProvider';\r\nimport useCurrentPage from '../../Hooks/useCurrentPage';\r\n\r\nlet hasMounted = false;\r\nlet url = '';\r\nlet litiumContext = '';\r\n\r\nexport default function(initialData: IHeader): [IHeader] {\r\n const [data, setData] = useState(initialData);\r\n const kexLoadingCircleDispatch = useKexLoadingCircle();\r\n const { languageRoute } = useAppSettingsData();\r\n const { pageId, channelId } = useCurrentPage();\r\n\r\n litiumContext = JSON.stringify({\r\n currentPageSystemId: pageId,\r\n productCategorySystemId: pageId,\r\n channelSystemId: channelId,\r\n });\r\n\r\n url = `/api/${languageRoute}/App/GetStandardHeader`;\r\n\r\n const queryData = useSWR(\r\n '/App/GetStandardHeader',\r\n () => FetchHeader(url, litiumContext),\r\n {\r\n initialData: hasMounted ? undefined : initialData,\r\n revalidateOnFocus: IS_PRODUCTION_ENV,\r\n }\r\n );\r\n\r\n useEffect(() => {\r\n kexLoadingCircleDispatch(!queryData.data ? 'add' : 'remove');\r\n }, [kexLoadingCircleDispatch, queryData.data]);\r\n\r\n useEffect(() => {\r\n if (!hasMounted) {\r\n hasMounted = true;\r\n } else {\r\n if (queryData.data) {\r\n setData(queryData.data);\r\n }\r\n }\r\n }, [queryData.data]);\r\n\r\n return [data];\r\n}\r\n\r\nexport async function updateHeaderData(header: IHeader) {\r\n mutate('/App/GetStandardHeader', header, false);\r\n}\r\n\r\nexport async function updateHeader() {\r\n const res = await FetchHeader(url, litiumContext);\r\n\r\n if (res) {\r\n mutate('/App/GetStandardHeader', res, false);\r\n }\r\n}\r\n","import React from 'react';\r\n\r\nfunction LoadingPageType() {\r\n return ;\r\n}\r\n\r\nexport default LoadingPageType;\r\n","import React, { useState, useEffect } from 'react';\r\nimport loadable from '@loadable/component';\r\nimport {\r\n EventDispatcher,\r\n NOTIFY_ACTION,\r\n STOP_NOTIFY_ACTION,\r\n} from '../Common/EventDispatcher';\r\nimport BaseNotification from './Models/BaseNotification.interface';\r\n\r\nconst KexNotification = loadable(() =>\r\n import('./Models/KexNotificationBanner')\r\n);\r\n\r\nfunction KexNotificationOverlay() {\r\n const tempNoteObject: BaseNotification = {} as BaseNotification;\r\n const [notify, setNotify] = useState(tempNoteObject);\r\n\r\n const onNotify = (notification: BaseNotification) => {\r\n setNotify(notification);\r\n Decontruct();\r\n };\r\n\r\n const stopNotify = (notification: BaseNotification) => {\r\n setNotify(notification);\r\n };\r\n\r\n useEffect(() => {\r\n EventDispatcher.subscribe(NOTIFY_ACTION, onNotify);\r\n EventDispatcher.subscribe(STOP_NOTIFY_ACTION, stopNotify);\r\n\r\n return () => {\r\n EventDispatcher.unsubscribe(NOTIFY_ACTION, onNotify);\r\n EventDispatcher.unsubscribe(STOP_NOTIFY_ACTION, stopNotify);\r\n };\r\n });\r\n return GetNotification(notify);\r\n}\r\n\r\nfunction Decontruct() {\r\n setTimeout(() => {\r\n EventDispatcher.dispatch(STOP_NOTIFY_ACTION, {} as BaseNotification);\r\n }, 5000);\r\n}\r\n\r\nfunction GetNotification(notification: any) {\r\n const loadableNotifications = {\r\n BaseNotification: loadable(() => import('./Models/KexNotificationBanner')),\r\n CartNotification: loadable(() =>\r\n import('./Models/KexCartNotificationBanner')\r\n ),\r\n };\r\n\r\n const LoadableNotification = (loadableNotifications as any)[\r\n notification.type\r\n ];\r\n if (LoadableNotification === undefined)\r\n return ;\r\n return ;\r\n}\r\n\r\nexport default KexNotificationOverlay;\r\n","import React, { ErrorInfo } from 'react';\r\n\r\ntype PropType = {\r\n /* TODO define FallbackComponent types */\r\n FallbackComponent: any;\r\n children: React.ReactNode;\r\n onError?: (this: ErrorBoundary, error: Error, info: string) => void;\r\n};\r\n\r\ntype StateType = {\r\n error?: Error;\r\n info: ErrorInfo;\r\n};\r\n\r\nclass ErrorBoundary extends React.Component {\r\n constructor(props: PropType) {\r\n super(props);\r\n this.state = {\r\n error: undefined,\r\n info: {\r\n componentStack: '',\r\n },\r\n };\r\n }\r\n\r\n static getDerivedStateFromError(error: Error) {\r\n // Update state so the next render will show the fallback UI.\r\n return { error: error };\r\n }\r\n\r\n componentDidCatch(error: Error, info: ErrorInfo) {\r\n const { onError } = this.props;\r\n\r\n if (typeof onError === 'function') {\r\n try {\r\n /* istanbul ignore next: Ignoring ternary; can’t reproduce missing info in test environment. */\r\n onError.call(this, error, info ? info.componentStack : '');\r\n } catch (ignoredError) {}\r\n }\r\n\r\n if ((window as any).appInsights) {\r\n (window as any).appInsights.trackException(error);\r\n }\r\n\r\n this.setState({ error, info });\r\n }\r\n\r\n render() {\r\n const { children, FallbackComponent } = this.props;\r\n const { error, info } = this.state;\r\n\r\n if (error !== undefined) {\r\n return (\r\n \r\n );\r\n }\r\n\r\n return children || null;\r\n }\r\n}\r\n\r\nexport default ErrorBoundary;\r\n","import React from 'react';\r\nimport { styled, theme } from '../../../../../Theme';\r\nimport KexLink from '../../../../KexLink/KexLink';\r\nimport ILink from '../../../Link.interface';\r\nimport FooterColumn from '../FooterColumn.interface';\r\nimport { pseudo, media } from '@glitz/core';\r\nimport { mediaQuery } from '../../../../../Theme/mediaQueries';\r\nimport { red } from '../../../../../Theme/colors';\r\n\r\ntype PropTypes = {\r\n footerColumn: FooterColumn;\r\n isFirst?: boolean;\r\n isLast?: boolean;\r\n};\r\n\r\nfunction FooterList({ footerColumn, isFirst, isLast }: PropTypes) {\r\n return footerColumn ? (\r\n \r\n {footerColumn.header && {footerColumn.header}}\r\n \r\n {footerColumn.links &&\r\n footerColumn.links.map((item: ILink, index: number) => (\r\n \r\n {item.text}\r\n \r\n ))}\r\n
\r\n \r\n \r\n ) : (\r\n \r\n );\r\n}\r\n\r\nconst Wrapper = styled.div({\r\n flexBasis: '100%',\r\n maxWidth: '100%',\r\n wordBreak: 'break-word',\r\n paddingRight: '20px',\r\n marginBottom: theme.spacing(11),\r\n ...pseudo([':nth-child(n)[data-isfirst=\"true\"]'], {\r\n marginTop: 0,\r\n }),\r\n ...pseudo([':nth-child(n)[data-isLast=\"true\"]'], {\r\n marginTop: theme.spacing(3),\r\n }),\r\n ...media(mediaQuery.mediaMinSmall, {\r\n flexBasis: '70%',\r\n maxWidth: '70%',\r\n }),\r\n ...media(mediaQuery.mediaMinLarge, {\r\n flexBasis: '18%',\r\n maxWidth: '18%',\r\n marginBottom: 0,\r\n ...pseudo([':nth-child(n)[data-isfirst=\"true\"]'], {\r\n flexBasis: '40%',\r\n maxWidth: '40%',\r\n padding: { x: 0 },\r\n marginRight: 'auto',\r\n }),\r\n ...pseudo([':nth-child(n)[data-isLast=\"true\"]'], {\r\n margin: { x: 'auto' },\r\n }),\r\n }),\r\n});\r\n\r\nconst Title = styled.h4({\r\n fontSize: '22px',\r\n letterSpacing: theme.tiny,\r\n lineHeight: theme.huge,\r\n color: theme.white,\r\n marginBottom: theme.spacing(5),\r\n ...media(mediaQuery.mediaMinLarge, { fontSize: theme.zeta }),\r\n});\r\n\r\nconst List = styled.ul({\r\n listStyle: 'none',\r\n padding: {\r\n xy: 0,\r\n },\r\n});\r\n\r\nconst ListItem = styled.li({\r\n margin: { top: theme.medium },\r\n letterSpacing: theme.letterSpacing.wide,\r\n});\r\n\r\nconst Link = styled(KexLink, {\r\n font: { size: theme.moreLarge },\r\n textDecoration: 'underline',\r\n color: theme.white,\r\n ':hover': {\r\n textDecoration: 'none',\r\n },\r\n});\r\n\r\nconst BodyText = styled.div({\r\n fontSize: theme.gamma,\r\n color: theme.white,\r\n lineHeight: '25.6px',\r\n});\r\n\r\nexport default FooterList;\r\n","import GetStandardFooterModel from '../../../../App/Models/GetStandardFooterModel.interface';\r\nimport IFooter from './Footer.interface';\r\nimport Fetcher from '../../../Common/Fetcher';\r\n\r\nlet abortController: AbortController = new AbortController();\r\n\r\nfunction FetchFooter(url: string, litiumContext: string) {\r\n abortController.abort();\r\n abortController = new AbortController();\r\n const signal = abortController.signal;\r\n\r\n return Fetcher(\r\n url,\r\n signal,\r\n (res, resolve, reject) => {\r\n if (res.success) {\r\n resolve(res.data);\r\n }\r\n },\r\n litiumContext\r\n );\r\n}\r\n\r\nexport default FetchFooter;\r\n","import { useState, useEffect } from 'react';\r\nimport useSWR from 'swr';\r\n\r\nimport { useKexLoadingCircle } from '../../../Loading/KexLoadingCircle/KexLoadingCircle';\r\nimport { IS_PRODUCTION_ENV } from '../../../Configs/EnvConfig';\r\nimport FetchFooter from './FetchFooter';\r\nimport IFooter from './Footer.interface';\r\nimport { useAppSettingsData } from '../../../AppSettingsProvider/AppSettingsProvider';\r\nimport useCurrentPage from '../../../Hooks/useCurrentPage';\r\n\r\nlet hasMounted = false;\r\n\r\nexport default function(initialData: IFooter): [IFooter] {\r\n const [data, setData] = useState(initialData);\r\n const kexLoadingCircleDispatch = useKexLoadingCircle();\r\n\r\n const { languageRoute } = useAppSettingsData();\r\n const { pageId, channelId } = useCurrentPage();\r\n\r\n const litiumContext = JSON.stringify({\r\n currentPageSystemId: pageId,\r\n productCategorySystemId: pageId,\r\n channelSystemId: channelId,\r\n });\r\n\r\n const url = `/api/${languageRoute}/App/GetStandardFooter`;\r\n\r\n const queryData = useSWR(\r\n '/App/GetStandardFooter',\r\n () => FetchFooter(url, litiumContext),\r\n {\r\n initialData: hasMounted ? undefined : initialData,\r\n revalidateOnFocus: IS_PRODUCTION_ENV,\r\n }\r\n );\r\n\r\n useEffect(() => {\r\n kexLoadingCircleDispatch(!queryData.data ? 'add' : 'remove');\r\n }, [kexLoadingCircleDispatch, queryData.data]);\r\n\r\n useEffect(() => {\r\n if (!hasMounted) {\r\n hasMounted = true;\r\n } else {\r\n if (queryData.data) {\r\n setData(queryData.data);\r\n }\r\n }\r\n }, [queryData.data]);\r\n\r\n return [data];\r\n}\r\n","import React from 'react';\r\nimport { styled, theme } from '../../../../Theme';\r\nimport FooterList from './FooterList/FooterList';\r\nimport IFooter from './Footer.interface';\r\nimport useQueryFooter from './useQueryFooter';\r\nimport { media } from '@glitz/core';\r\nimport { mediaQuery } from '../../../../Theme/mediaQueries';\r\nimport { auto } from '@popperjs/core';\r\n\r\ntype PropTypes = {\r\n initData: IFooter;\r\n};\r\n\r\nfunction Footer({ initData }: PropTypes) {\r\n const [\r\n {\r\n footerFarLeftColumn,\r\n footerLeftColumn,\r\n footerRightColumn,\r\n footerFarRightColumn,\r\n footerBottomColumn,\r\n },\r\n ] = useQueryFooter(initData);\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n );\r\n}\r\n\r\nconst FooterElm = styled.footer({ backgroundColor: theme.lighterDarkGray });\r\n\r\nconst FooterContentContainer = styled.div({\r\n maxWidth: theme.contentMaxWidth,\r\n padding: { x: '7.5px' },\r\n margin: { x: 'auto' },\r\n});\r\n\r\nconst FooterListWrapper = styled.div({\r\n display: 'flex',\r\n flexWrap: 'wrap',\r\n padding: {\r\n y: theme.spacing(8),\r\n },\r\n ...media(mediaQuery.mediaMinLarge, {\r\n padding: { top: theme.spacing(10), bottom: theme.spacing(12) },\r\n }),\r\n});\r\n\r\nexport default Footer;\r\n","import React from 'react';\r\nimport { styled, StyledProps } from '@glitz/react';\r\n\r\nfunction CookieIcon({ compose }: StyledProps) {\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n {/* */}\r\n \r\n );\r\n}\r\n\r\nexport default styled(CookieIcon);\r\n","import React, { useEffect, useState, useRef } from 'react';\r\nimport { media, pseudo } from '@glitz/core';\r\nimport { mediaQuery } from '../Theme/mediaQueries';\r\nimport CookieIcon from '../Shared/Icons/CookieIcon';\r\nimport KexLink from '../Shared/KexLink/KexLink';\r\nimport { linkColor, primaryBlue, transparent } from '../Theme/colors';\r\nimport { styled, theme } from '../Theme';\r\nimport Divider from '../Shared/Divider/Divider';\r\n\r\nconst Cookies = ({ initData }) => {\r\n const props = {};\r\n const { appSettings, currentPage } = initData;\r\n const url = '';\r\n\r\n const [translations, setTranslations] = useState({\r\n display: true,\r\n heading: '',\r\n info: '',\r\n acceptButtonText: '',\r\n customSettingsButtonText: '',\r\n customSettingsHeading: '',\r\n customSettingsNecessaryHeading: '',\r\n customSettingsNecessaryInfo: '',\r\n customSettingsStatisticsHeading: '',\r\n customSettingsStatisticsInfo: '',\r\n customSettingsFunctionalHeading: '',\r\n customSettingsFunctionalInfo: '',\r\n customSettingsCloseButtonText: '',\r\n customSettingsSaveButtonText: '',\r\n });\r\n\r\n const [displayCookies, setDisplayCookies] = useState(false);\r\n const [showCustomSettings, setShowCustomSettings] = useState(false);\r\n const [submitCookiesModel, setSubmitCookiesModel] = useState({\r\n allowAllCookies: true,\r\n settings: {\r\n Statistics: false,\r\n Functional: false,\r\n },\r\n });\r\n\r\n useEffect(() => {\r\n const cookieUrl = `/api/${appSettings.languageRoute}/cookies/`;\r\n fetch(`${cookieUrl}GetCookie?webSiteSystemId=${currentPage.systemId}`)\r\n .then(res => res.json())\r\n .then(res => {\r\n if (res.displayCookiesPrompt == false) return;\r\n setTranslations(res);\r\n setDisplayCookies(true);\r\n });\r\n }, []);\r\n\r\n async function setStateAllowAllCookies(value) {\r\n setSubmitCookiesModel(prevState => ({\r\n ...prevState,\r\n allowAllCookies: value,\r\n }));\r\n }\r\n\r\n async function setStateSettings(setting) {\r\n const settings = { ...submitCookiesModel.settings };\r\n settings[setting] = !settings[setting];\r\n console.log(InputRef2);\r\n setSubmitCookiesModel(prevState => ({\r\n ...prevState,\r\n settings,\r\n }));\r\n }\r\n\r\n async function postConsent(allowAllCookies) {\r\n setSubmitCookiesModel(prevState => ({\r\n ...prevState,\r\n allowAllCookies: allowAllCookies,\r\n }));\r\n\r\n const cookieUrlPost = `/api/${appSettings.languageRoute}/cookies/`;\r\n await fetch(cookieUrlPost, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n },\r\n body: JSON.stringify(submitCookiesModel),\r\n })\r\n .then(res => {\r\n // If successful post, refresh\r\n window.location.reload();\r\n })\r\n .catch(e => {\r\n // Could display this in the cookie window if desirable\r\n console.warn(e);\r\n });\r\n\r\n setDisplayCookies(false);\r\n }\r\n\r\n const [hideInfoText, setInfoText] = useState(true);\r\n const SectionCookiesNotice = showCustomSettings\r\n ? SectionCookiesNotice2\r\n : SectionCookiesNotice1;\r\n\r\n const InputRef1 = useRef(null);\r\n const InputRef2 = useRef(null);\r\n\r\n return displayCookies ? (\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n {translations?.heading}\r\n \r\n \r\n
\r\n \r\n {showCustomSettings == false && (\r\n \r\n postConsent(true)}>\r\n {translations?.acceptButtonText}\r\n \r\n {\r\n setStateAllowAllCookies(false);\r\n setShowCustomSettings(true);\r\n setInfoText(false);\r\n }}\r\n >\r\n {translations?.customSettingsButtonText}\r\n \r\n \r\n )}\r\n {showCustomSettings == true && (\r\n <>\r\n \r\n \r\n \r\n \r\n {translations?.customSettingsHeading}\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n {translations?.customSettingsNecessaryHeading}\r\n \r\n {translations?.customSettingsNecessaryInfo}\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n setStateSettings('Statistics')}\r\n id={'Input1'}\r\n />\r\n \r\n \r\n \r\n \r\n \r\n {translations?.customSettingsStatisticsHeading}\r\n \r\n {translations?.customSettingsStatisticsInfo}\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n setStateSettings('Functional')}\r\n id={'Input2'}\r\n />\r\n \r\n \r\n \r\n \r\n \r\n {translations?.customSettingsFunctionalHeading}\r\n \r\n {translations?.customSettingsFunctionalInfo}\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n {\r\n setStateAllowAllCookies(true);\r\n setShowCustomSettings(false);\r\n setInfoText(true);\r\n }}\r\n >\r\n {translations?.customSettingsCloseButtonText}\r\n \r\n postConsent(false)}\r\n >\r\n {translations?.customSettingsSaveButtonText}\r\n \r\n \r\n \r\n >\r\n )}\r\n \r\n \r\n \r\n ) : (\r\n \r\n );\r\n};\r\n\r\nconst SectionCookiesNoticeOuter = styled.div({\r\n width: '100%',\r\n backgroundColor: 'rgba(0,0,0, 0.2)',\r\n position: 'fixed',\r\n inset: 0,\r\n margin: 'auto',\r\n zIndex: '10000',\r\n});\r\n\r\nconst SectionCookiesNotice1 = styled.div({\r\n backgroundColor: theme.white,\r\n position: 'absolute',\r\n left: '50%',\r\n top: '50%',\r\n transform: 'translate(-50%, -50%)',\r\n width: '550px',\r\n maxWidth: '100%',\r\n margin: 'auto',\r\n});\r\n\r\nconst SectionCookiesNotice2 = styled.div({\r\n backgroundColor: theme.white,\r\n position: 'absolute',\r\n left: '50%',\r\n top: '50%',\r\n transform: 'translate(-50%, -50%)',\r\n width: '750px',\r\n maxWidth: '100%',\r\n margin: 'auto',\r\n});\r\n\r\nconst CookiesNoticeContainer = styled.div({\r\n padding: { x: '3rem', y: ' 2rem' },\r\n display: 'flex',\r\n flexDirection: 'column',\r\n justifyContent: 'center',\r\n alignContent: 'center',\r\n ...media(theme.mediaQuery.mediaMaxMedium, {\r\n width: '100%',\r\n marginLeft: 0,\r\n marginBottom: 0,\r\n overflowY: 'scroll',\r\n height: '80vh',\r\n padding: { x: '2rem', y: ' 1rem' },\r\n }),\r\n});\r\n\r\nconst CookiesNoticeContent = styled.div({\r\n display: 'flex',\r\n flexDirection: 'column',\r\n alignContent: 'center',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n});\r\n\r\nconst StyledCookieIcon = styled.div({\r\n justifyContent: 'center',\r\n alignItems: 'center',\r\n marginBottom: '1rem',\r\n backgroundColor: theme.primaryBlue,\r\n borderRadius: '50%',\r\n paddingTop: '11px',\r\n paddingLeft: '11px',\r\n});\r\n\r\nconst CookieHeading = styled.h2({\r\n fontWeight: '600',\r\n fontSize: '1.5rem',\r\n lineHeight: '1.5rem',\r\n marginBottom: '1rem',\r\n});\r\n\r\nconst BodyText = styled.div({\r\n marginBottom: '32px',\r\n lineHeight: '1.5rem',\r\n textAlign: 'center',\r\n fontSize: '1rem',\r\n fontWeight: 500,\r\n ...media(theme.mediaQuery.mediaMinSmall, {\r\n lineHeight: '1.5rem',\r\n }),\r\n});\r\n\r\nconst CookiesNoticeBtnContainer = styled.div({\r\n display: 'flex',\r\n flexDirection: 'column',\r\n justifyContent: 'center',\r\n alignItems: 'center',\r\n marginTop: '2rem',\r\n gap: '1rem',\r\n});\r\n\r\nconst CookieBtn = styled.button({\r\n width: '100%',\r\n backgroundColor: theme.primaryBlue,\r\n color: theme.white,\r\n padding: { x: '3rem', y: '1rem' },\r\n cursor: 'pointer',\r\n fontWeight: '600',\r\n fontSize: '16px',\r\n ...media(theme.mediaQuery.mediaMaxMedium, {\r\n marginTop: '0.5rem',\r\n padding: { x: '2rem', y: '1rem' },\r\n }),\r\n});\r\n\r\nconst CookieBtnSecondary = styled.button({\r\n width: '100%',\r\n backgroundColor: theme.white,\r\n border: { xy: { width: '1px', style: 'solid', color: theme.primaryBlue } },\r\n color: theme.primaryBlue,\r\n padding: { x: '3rem', y: '1rem' },\r\n cursor: 'pointer',\r\n fontWeight: '600',\r\n fontSize: '16px',\r\n ...media(theme.mediaQuery.mediaMaxMedium, {\r\n marginTop: '0.5rem',\r\n padding: { x: '2rem', y: '1rem' },\r\n }),\r\n});\r\n\r\nconst SectionCookiesNoticeSettings = styled.div({\r\n backgroundColor: theme.white,\r\n inset: 0,\r\n width: '750px',\r\n maxWidth: '100%',\r\n overflowY: 'auto',\r\n overflowX: 'hidden',\r\n margin: 'auto',\r\n ...media(theme.mediaQuery.mediaMaxMedium, {\r\n height: '60%',\r\n }),\r\n});\r\n\r\nconst CookiesNoticeSettingsContainer = styled.div({\r\n background: '#F8F4F0',\r\n padding: '2rem',\r\n marginLeft: '-1rem',\r\n width: 'calc(100% + 2rem)',\r\n marginBottom: '2rem',\r\n ...media(theme.mediaQuery.mediaMaxMedium, {\r\n overflow: 'scroll',\r\n }),\r\n});\r\n\r\nconst CookieSettingsHeading = styled.div({\r\n textAlign: 'center',\r\n marginBottom: '2rem',\r\n});\r\n\r\nconst CookieSettingsHeadingH3 = styled.h3({\r\n fontSize: '18px',\r\n lineHeight: '28px',\r\n fontWeight: '600',\r\n margin: '0',\r\n color: '#555555',\r\n});\r\n\r\nconst StyledDivider = styled(Divider, {\r\n width: '100%',\r\n backgroundColor: theme.grayLine,\r\n margin: { y: theme.delta },\r\n ...media(mediaQuery.mediaMaxSmall, {\r\n margin: { y: theme.delta },\r\n }),\r\n});\r\n\r\nconst CookieSettingsContainer = styled.div({\r\n display: 'flex',\r\n margin: { y: '1.5rem', x: '0px' },\r\n});\r\n\r\nconst CookieSettingsContent = styled.div({\r\n display: 'flex',\r\n flexDirection: 'row',\r\n});\r\n\r\nconst CookieSettingToggle = styled.div({\r\n marginRight: '10px',\r\n marginTop: '15px',\r\n});\r\n\r\nconst SwitchLocked = styled.div({\r\n position: 'relative',\r\n display: 'inline-block',\r\n width: '44px',\r\n height: '24px',\r\n backgroundColor: theme.primaryBlue,\r\n opacity: '50%',\r\n borderTopLeftRadius: '12px',\r\n borderTopRightRadius: '12px',\r\n borderBottomLeftRadius: '12px',\r\n borderBottomRightRadius: '12px',\r\n});\r\n\r\nconst SliderRoundLocked = styled.span({\r\n position: 'absolute',\r\n height: '18px',\r\n width: '18px',\r\n left: '22px',\r\n bottom: '3px',\r\n backgroundColor: theme.white,\r\n borderRadius: '50%',\r\n});\r\n\r\nconst CookieSettingText = styled.h4({\r\n width: '100%,',\r\n margin: { y: '0px', x: '1rem' },\r\n fontSize: '16px',\r\n fontWeight: 700,\r\n lineHeight: '22px',\r\n});\r\n\r\nconst CookieSettingTextP = styled.p({\r\n color: '#555555',\r\n fontSize: '16px',\r\n fontWeight: 500,\r\n});\r\n\r\nconst CookiesNoticeSettingsBtnContainer = styled.div({});\r\n\r\nconst SettingsBtns = styled.div({\r\n display: 'flex',\r\n justifyContent: 'center',\r\n gap: '1rem',\r\n ...media(theme.mediaQuery.mediaMaxMedium, {\r\n marginTop: '0.5rem',\r\n }),\r\n});\r\n\r\nconst ToggleWrapper = styled.div({\r\n position: 'relative',\r\n});\r\n\r\nconst CheckBox = styled.input({\r\n opacity: 0,\r\n zIndex: 1,\r\n borderRadius: '15px',\r\n width: '44px',\r\n height: '24px',\r\n});\r\n\r\nconst CheckboxLabel = styled.label({\r\n position: 'absolute',\r\n top: 0,\r\n left: 0,\r\n width: '44px',\r\n height: '24px',\r\n borderRadius: '15px',\r\n background: '#D7D2CB',\r\n cursor: 'pointer',\r\n});\r\n\r\nconst CheckboxSlider = styled.span({\r\n pointerEvents: 'none',\r\n position: 'absolute',\r\n top: 0,\r\n display: 'block',\r\n content: '\"\"',\r\n borderRadius: '50%',\r\n width: '18px',\r\n height: '18px',\r\n margin: '3px',\r\n background: '#ffffff',\r\n transition: '0.2s',\r\n});\r\nexport default Cookies;\r\n","import React from 'react';\r\nimport { styled, theme } from '../../Theme';\r\nimport { useAppSettingsData } from '../../Shared/AppSettingsProvider/AppSettingsProvider';\r\nimport CloseIcon from '../Icons/CloseIcon';\r\n\r\nfunction KexReporterModal() {\r\n const {\r\n translations: {\r\n 'error/errorHeader': errorHeader,\r\n 'error/errorRequestText': errorRequestText,\r\n },\r\n } = useAppSettingsData();\r\n\r\n return (\r\n \r\n \r\n window.location.reload(true)}>\r\n \r\n \r\n {errorRequestText}\r\n \r\n );\r\n}\r\n\r\nexport default KexReporterModal;\r\n\r\nconst Root = styled.div({\r\n width: '100%',\r\n backgroundColor: '#F5F5F5',\r\n padding: { x: '40px', y: '40px' },\r\n height: '100%',\r\n position: 'fixed',\r\n zIndex: theme.zIndex.errorModal,\r\n});\r\n\r\nconst StyledCloseIcon = styled(CloseIcon, {\r\n height: '32px',\r\n width: '32px',\r\n marginRight: '8px',\r\n});\r\n\r\nconst CloseButton = styled.button({\r\n position: 'absolute',\r\n right: '47px',\r\n top: '47px',\r\n});\r\n\r\nconst Header = styled.h2({\r\n fontSize: theme.great,\r\n fontWeight: theme.fontWeight.bold,\r\n marginBottom: '40px',\r\n});\r\n\r\nconst Text = styled.p({\r\n fontSize: theme.gamma,\r\n});\r\n","import React, { useState, useEffect } from 'react';\r\nimport { EventDispatcher, ON_KEX_ERROR } from '../Common/EventDispatcher';\r\nimport KexReporterModal from './KexReporterModal';\r\n\r\nfunction KexReporterOverlay() {\r\n const [errorCount, setErrorCount] = useState(0);\r\n\r\n const onError = () => {\r\n setErrorCount(1);\r\n };\r\n\r\n useEffect(() => {\r\n EventDispatcher.subscribe(ON_KEX_ERROR, onError);\r\n\r\n return () => {\r\n EventDispatcher.unsubscribe(ON_KEX_ERROR, onError);\r\n };\r\n });\r\n\r\n return <>{errorCount !== 0 && }>;\r\n}\r\n\r\nexport default KexReporterOverlay;\r\n","import './imports';\r\nimport React from 'react';\r\nimport { hydrate, render } from 'react-dom';\r\nimport { loadableReady } from '@loadable/component';\r\nimport { GlitzClient } from '@glitz/core';\r\nimport { GlitzProvider } from '@glitz/react';\r\nimport { default as GlitzTransformers } from '@glitz/transformers';\r\nimport { mediaQuerySorter } from './Theme/mediaQueries';\r\n// currently we are not using redux, saving it for later and see if we are using it\r\n// import { Provider } from 'react-redux';\r\n// import { storeConfig } from './Shared/Configs/StoreConfig';\r\n// const store = storeConfig(state);\r\nimport AppInitModel from './Shared/Models/AppInitModel.interface';\r\n\r\nimport App from './App';\r\nimport { mutate } from 'swr';\r\n\r\nconst state = (window as any).__APP_INIT_DATA__ as AppInitModel;\r\n\r\nconst rootEle: any = document.getElementById('root');\r\nconst glitz = new GlitzClient({\r\n transformer: GlitzTransformers(),\r\n mediaOrder: mediaQuerySorter,\r\n});\r\n\r\nif (window.history.state === null) {\r\n window.history.replaceState(\r\n { id: new Date().valueOf() },\r\n document.title,\r\n window.location.href\r\n );\r\n}\r\n\r\nif (rootEle.children[0]) {\r\n loadableReady(() => {\r\n hydrate(\r\n // currently we are not using redux, saving it for later and see if we are using it\r\n // \r\n \r\n \r\n ,\r\n // \r\n rootEle\r\n );\r\n });\r\n} else {\r\n render(\r\n // currently we are not using redux, saving it for later and see if we are using it\r\n // \r\n \r\n \r\n ,\r\n // \r\n rootEle,\r\n () => {\r\n const splash: any = document.getElementById('splash');\r\n splash != null &&\r\n splash.firstElementChild &&\r\n splash.firstElementChild.setAttribute(\r\n 'class',\r\n splash.firstElementChild\r\n .getAttribute('class')\r\n .replace('splash-pulse', '')\r\n );\r\n splash != null && splash.classList.add('splash-remove');\r\n setTimeout(() => {\r\n splash && document.body.removeChild(splash);\r\n }, 700);\r\n }\r\n );\r\n}\r\n\r\n// Listen to the \"beta/epiReady\" event to update the \"context\" property.\r\nwindow.addEventListener('load', () => {\r\n // Expect \"epi\" to be there after the \"load\" event. If it's not then we're\r\n // not in any editing context.\r\n let updateTimer: number;\r\n const epi = (window as any).epi;\r\n if (!epi) {\r\n return;\r\n }\r\n\r\n function setContext() {\r\n epi.publish('beta/domUpdated');\r\n // Subscribe to *all* property updates in on-page edit mode\r\n epi.subscribe('beta/contentSaved', function(propertyDetails: any) {\r\n // Ignore update if it wasn't successful, for example if there were validation errors\r\n if (!propertyDetails.successful) {\r\n return;\r\n }\r\n // fetch new complete data and update whole state.\r\n clearTimeout(updateTimer);\r\n updateTimer = window.setTimeout(() => {\r\n mutate('epiedit');\r\n }, 500);\r\n });\r\n }\r\n\r\n // Check for beta and that ready is an actual true value (not just truthy).\r\n if (epi.beta && epi.beta.ready === true) {\r\n // \"beta/epiReady\" already fired.\r\n setContext();\r\n\r\n // The subscribe method won't be available in View mode.\r\n } else if (epi.subscribe) {\r\n epi.subscribe('beta/epiReady', () => {\r\n setContext();\r\n });\r\n }\r\n});\r\n","Object.isEmpty = function(o) {\r\n for (var i in o) {\r\n return false;\r\n }\r\n return true;\r\n};\r\n\r\n// https://tc39.github.io/ecma262/#sec-array.prototype.find\r\nif (!Array.prototype.find) {\r\n /* eslint-disable-next-line no-extend-native */\r\n Object.defineProperty(Array.prototype, 'find', {\r\n value: function(predicate) {\r\n // 1. Let O be ? ToObject(this value).\r\n if (this == null) {\r\n throw new TypeError('\"this\" is null or not defined');\r\n }\r\n\r\n var o = Object(this);\r\n\r\n // 2. Let len be ? ToLength(? Get(O, \"length\")).\r\n var len = o.length >>> 0;\r\n\r\n // 3. If IsCallable(predicate) is false, throw a TypeError exception.\r\n if (typeof predicate !== 'function') {\r\n throw new TypeError('predicate must be a function');\r\n }\r\n\r\n // 4. If thisArg was supplied, let T be thisArg; else let T be undefined.\r\n var thisArg = arguments[1];\r\n\r\n // 5. Let k be 0.\r\n var k = 0;\r\n\r\n // 6. Repeat, while k < len\r\n while (k < len) {\r\n // a. Let Pk be ! ToString(k).\r\n // b. Let kValue be ? Get(O, Pk).\r\n // c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)).\r\n // d. If testResult is true, return kValue.\r\n var kValue = o[k];\r\n if (predicate.call(thisArg, kValue, k, o)) {\r\n return kValue;\r\n }\r\n // e. Increase k by 1.\r\n k++;\r\n }\r\n\r\n // 7. Return undefined.\r\n return undefined;\r\n },\r\n configurable: true,\r\n writable: true,\r\n });\r\n}\r\n\r\n/* eslint-disable */\r\nif (Number.isFinite === undefined)\r\n Number.isFinite = function(value) {\r\n return typeof value === 'number' && isFinite(value);\r\n };\r\n\r\nNumber.isNaN =\r\n Number.isNaN ||\r\n function isNaN(input) {\r\n return typeof input === 'number' && input !== input;\r\n };\r\n/* eslint-enable */\r\n"],"sourceRoot":""}