{"version":3,"file":"analytics-p_Or6fYl.js","sources":["../../../node_modules/lodash-es/differenceWith.js","../../../node_modules/lodash-es/uniqWith.js","../../../app/javascript/modules/analytics.js"],"sourcesContent":["import baseDifference from './_baseDifference.js';\nimport baseFlatten from './_baseFlatten.js';\nimport baseRest from './_baseRest.js';\nimport isArrayLikeObject from './isArrayLikeObject.js';\nimport last from './last.js';\n\n/**\n * This method is like `_.difference` except that it accepts `comparator`\n * which is invoked to compare elements of `array` to `values`. The order and\n * references of result values are determined by the first array. The comparator\n * is invoked with two arguments: (arrVal, othVal).\n *\n * **Note:** Unlike `_.pullAllWith`, this method returns a new array.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {...Array} [values] The values to exclude.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns the new array of filtered values.\n * @example\n *\n * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];\n *\n * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);\n * // => [{ 'x': 2, 'y': 1 }]\n */\nvar differenceWith = baseRest(function(array, values) {\n var comparator = last(values);\n if (isArrayLikeObject(comparator)) {\n comparator = undefined;\n }\n return isArrayLikeObject(array)\n ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), undefined, comparator)\n : [];\n});\n\nexport default differenceWith;\n","import baseUniq from './_baseUniq.js';\n\n/**\n * This method is like `_.uniq` except that it accepts `comparator` which\n * is invoked to compare elements of `array`. The order of result values is\n * determined by the order they occur in the array.The comparator is invoked\n * with two arguments: (arrVal, othVal).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns the new duplicate free array.\n * @example\n *\n * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];\n *\n * _.uniqWith(objects, _.isEqual);\n * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]\n */\nfunction uniqWith(array, comparator) {\n comparator = typeof comparator == 'function' ? comparator : undefined;\n return (array && array.length) ? baseUniq(array, undefined, comparator) : [];\n}\n\nexport default uniqWith;\n","import { uniqWith, isEqual, differenceWith, groupBy } from \"lodash-es\";\nimport { on, ready } from \"../utils/listeners\";\n\non(\"click\", \".js-mega-nav-item\", el => {\n analytics.track(\"Clicked Mega Nav\", {\n name: el.dataset.name,\n number: el.dataset.number,\n situation: el.dataset.situation\n });\n});\n\non(\"click\", \".js-open-menu\", () => {\n analytics.track(\"Opened Menu\");\n});\n\non(\"click\", \".js-nav-group-item\", el => {\n analytics.track(\"Clicked Nav Group Item\", {\n megaNavItemName: el.dataset.megaNavItemName,\n navGroupName: el.dataset.navGroupName,\n navGroupPosition: el.dataset.navGroupPosition,\n navGroupItemName: el.dataset.navGroupItemName,\n navGroupItemPosition: el.dataset.navGroupItemPosition\n });\n});\n\non(\"click\", \".js-book-builder-link\", async el => {\n await analytics.track(\"Book Builder CTA Clicked on PLP\", {\n category: el.dataset.categoryName\n });\n window.location = el.dataset.bookBuilderPath;\n});\n\non(\"click\", \".js-collection-drawer-link\", () => {\n analytics.track(\"Clicked View the Full Collection on PLP\");\n});\n\non(\"click\", \".js-collection-modal-listing .product\", el => {\n analytics.track(\"Clicked Product in PLP Collection Modal\", {\n analytics_id: el.dataset.id\n });\n});\n\non(\"click\", \".js-collection-drawer-favourites-cta\", () => {\n analytics.track(\"Add All to Favourites (Collection Modal)\");\n});\n\non(\"click\", \".js-collection-drawer-close-button\", () => {\n analytics.track(\"Closed PLP Collection Modal\");\n});\n\non(\"click\", \".js-comparison-link\", el => {\n analytics.track(\"Clicked Size Guide\", {\n productId: el.dataset.productId\n });\n});\n\non(\"click\", \"[data-event]\", el => {\n const { event, ...props } = el.dataset;\n\n // Take all data attributes, filter out ones that don't start with 'event',\n // remove the event prefix and lowercase the first letter.\n // IN: data-event-country=\"UK\" data-event-category-name=\"Notebooks\"\n // OUT: { country: \"UK\", categoryName: \"Notebooks\" }\n const filteredProps = Object.keys(props).reduce((acc, key) => {\n if (key.startsWith(\"event\")) {\n const newKey =\n key.replace(\"event\", \"\").charAt(0).toLowerCase() + key.slice(6);\n acc[newKey] = props[key];\n }\n return acc;\n }, {});\n analytics.track(event, filteredProps);\n});\n\non(\"click\", \".product\", (p, e) => {\n if (![\"IMG\", \"A\"].includes(e.target.tagName)) {\n return;\n }\n\n const impressionList = p.closest(\".js-impression-list\");\n\n const click = {\n productId: p.dataset.id,\n analyticsId: p.dataset.id\n };\n\n if (impressionList) {\n Object.assign(click, impressionList.dataset);\n\n const position = [...impressionList.querySelectorAll(\".product\")].indexOf(\n p\n );\n\n if (position > -1) click.position = position + 1;\n }\n\n Object.keys(click).forEach(k => {\n if (k.startsWith(\"v\")) delete click[k];\n });\n\n if (!click.analyticsId) {\n analytics.track(\"Clicked Product - Undefined Analytics ID\", {\n classList: e.target.classList,\n tagName: e.target.tagName,\n dataSet: p.dataset\n });\n } else {\n analytics.track(\"Clicked Product\", click);\n }\n});\n\n// Set up an intersection observer which reports product listing impressions to\n// our analytics services. This needs to be rerun each time additional product cards\n// have been added to the page, because of the way IntersectionObservers work\n\nconst viewedProducts = [];\nlet previouslyTrackedProducts = [];\n\nconst options = {\n root: null,\n rootMargin: \"0px\",\n threshold: [0.0, 0.75]\n};\n\nconst callback = entries => {\n entries.forEach(entry => {\n const product = entry.target;\n\n if (entry.isIntersecting) {\n if (entry.intersectionRatio > 0.75) {\n product.dataset.lastViewStarted = entry.time;\n product.dataset.lastViewEnded = undefined;\n } else if (product.dataset.lastViewStarted) {\n product.dataset.lastViewEnded = entry.time;\n }\n }\n });\n};\n\nconst alreadyTracked = product =>\n viewedProducts.some(p => p.id === product.dataset.id);\n\nconst observer = new IntersectionObserver(callback, options);\n\nconst handleRefreshInterval = () => {\n const currentTime = performance.now();\n\n document.querySelectorAll(\".product\").forEach(p => {\n const { lastViewStarted, lastViewEnded } = p.dataset;\n if (!lastViewStarted) return;\n if (alreadyTracked(p)) return;\n\n if (currentTime - parseFloat(lastViewStarted) > 150) {\n const ended = parseFloat(lastViewEnded) || currentTime;\n if (ended - parseFloat(lastViewStarted) > 150) {\n const impressionList = p.closest(\".js-impression-list\");\n\n const impression = { id: p.dataset.id };\n\n if (impressionList) {\n Object.assign(impression, impressionList.dataset);\n\n const position = [\n ...impressionList.querySelectorAll(\".product\")\n ].indexOf(p);\n\n if (position > -1) impression.position = position + 1;\n }\n\n viewedProducts.push(impression);\n }\n }\n });\n};\n\nconst handleTracking = () => {\n const difference = uniqWith(\n differenceWith(viewedProducts, previouslyTrackedProducts, (p1, p2) => {\n return p1.id === p2.id;\n }),\n isEqual\n );\n\n previouslyTrackedProducts = [...viewedProducts];\n\n if (difference.length) {\n const groups = groupBy(difference, i => [i.situation, i.term]);\n\n Object.keys(groups).forEach(key => {\n const impressions = groups[key];\n const products = impressions.map(i => [i.id, i.position]);\n\n const { id, position, ...other } = impressions[0];\n\n const track = {\n products,\n ...other\n };\n\n // Vue adds data-v-xxx to tags, which isn't something we want to track (these get converted to columns\n // in the warehouse). Just remove anything beginning with v-\n Object.keys(track).forEach(k => {\n if (k.startsWith(\"v\")) delete track[k];\n });\n\n analytics.track(\"Product Impression\", track);\n });\n }\n};\n\nconst setupImpressionTracker = () => {\n const products = document.querySelectorAll(\".product\");\n products.forEach(p => observer.observe(p));\n};\n\nwindow.setInterval(handleRefreshInterval, 100);\nwindow.setInterval(handleTracking, 1000);\n\nready(() => {\n setupImpressionTracker();\n});\n\nwindow.addEventListener(\"htmlChanged\", () => {\n setupImpressionTracker();\n});\n"],"names":["differenceWith","baseRest","array","values","comparator","last","isArrayLikeObject","baseDifference","baseFlatten","uniqWith","baseUniq","on","el","event","props","filteredProps","acc","key","newKey","p","impressionList","click","position","k","viewedProducts","previouslyTrackedProducts","options","callback","entries","entry","product","alreadyTracked","observer","handleRefreshInterval","currentTime","lastViewStarted","lastViewEnded","impression","handleTracking","difference","p1","p2","isEqual","groups","groupBy","i","impressions","products","id","other","track","setupImpressionTracker","ready"],"mappings":"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","x_google_ignoreList":[0,1]}