(function(){ const zoovuId = 'CyzaA6QChFlGdVynxrCCAtAOVozmZWRF1lR0+5Bz4WM='; const domainId = '31444e33-847e-4855-aef2-68a6d7de0729'; const variables = [{"id":"1eec2be6-dc91-4c4e-a443-da2f051baf5b","name":"Add to cart","type":"CONSTANT","valueType":"TEXT","value":"Add to cart"},{"id":"26e045ae-0482-453b-bad1-f0265d34da9d","name":"addToCart_price","type":"FUNCTION","valueType":"DECIMAL","function":function(event){const clickedElement = event.target.closest('button.atc'); if (!clickedElement) return null; const isSearchPage = window.location.search.includes('zQuery'); const isHomePage = window.location.pathname === '/' let ancestor, rawPrice; if (isSearchPage) { ancestor = clickedElement?.closest('.result-card__actions, .zv-modal__content') || null; rawPrice = ancestor ?.querySelector('.price-wrapper .sell-value') ?.textContent?.trim() } else if (isHomePage) { ancestor = clickedElement.closest('.product-card'); rawPrice = ancestor ?.querySelector('.price-wrapper input') ?.value; } else { ancestor = clickedElement.parentElement.parentElement; rawPrice = ancestor ?.querySelector('.price-wrapper .price > .price:last-of-type') ?.textContent?.trim(); } const cleanPrice = parseFloat(rawPrice?.replace(/[^\d.,-]/g, "")); return isNaN(cleanPrice) ? 0 : cleanPrice; }},{"id":"70fb9e0a-634b-4937-9147-2cec6b573c98","name":"addToCart_quantity","type":"FUNCTION","valueType":"INTEGER","function":function(event){const clickedElement = event.target.closest('button.atc'); const isSearchPage = window.location.search.includes('zQuery'); let quantity = 1; if (clickedElement) { const ancestor = isSearchPage ? clickedElement.parentElement : clickedElement.parentElement.parentElement; const quantityInput = ancestor?.querySelector('input[type="number"]'); if (quantityInput) { quantity = +quantityInput.value || 1; } } return quantity;}},{"id":"81ab552d-d8db-456d-9618-fcaf74d934e0","name":"addToCart_sku","type":"FUNCTION","valueType":"TEXT","function":function(event){const clickedElement = event.target.closest('button.atc'); let sku = ''; if (clickedElement) { const elementId = clickedElement.id; sku = elementId?.split('#')[1] || ''; } return sku;}},{"id":"3be07ee8-8a02-4588-ac5c-c775f9486959","name":"autoSuggestionClickout","type":"FUNCTION","valueType":"BOOLEAN","function":function(event){const clickedElement = event.target.closest('[data-product-identifier]'); if (clickedElement && clickedElement.closest('.unibox')) { return true; } return false;}},{"id":"40aaafa6-0969-4236-ad9e-be68fb3319d3","name":"cartUpdated_price","type":"FUNCTION","valueType":"DECIMAL","function":function(event){const updateCartBtn = event.target.closest('.quantity-wrapper button:not([formaction*="/cart/remove"])'); if(!updateCartBtn) return; const quantityWrapper = updateCartBtn?.parentElement; const ancestor = quantityWrapper?.parentElement?.parentElement; const price = ancestor.querySelector('.price'); const priceInputValue = price?.querySelector('input')?.value; return getNumericPriceFromString(priceInputValue) || null;}},{"id":"22cc39a7-af86-4b04-b501-f6f110b649bf","name":"cartUpdated_quantity","type":"FUNCTION","valueType":"INTEGER","function":function(event){const updateCartBtn = event.target.closest('.quantity-wrapper button:not([formaction*="/cart/remove"])'); if(!updateCartBtn) return; const quantityWrapper = updateCartBtn.parentElement; const input = quantityWrapper?.querySelector('input') return parseFloat(input?.value) || 1 }},{"id":"6f23f86a-92fe-46f8-8091-5e6a4593a8c7","name":"cartUpdated_sku","type":"FUNCTION","valueType":"TEXT","function":function(event){const updateCartBtn = event.target.closest('.quantity-wrapper button:not([formaction*="/cart/remove"])'); if(!updateCartBtn) return; const ancestor = updateCartBtn.parentElement.parentElement; const input = ancestor?.querySelector(':scope > input') const sku = input?.id.replace('_Quantity', '') ?? null; return sku ? sku.trim() : null; }},{"id":"b73b1d5c-2232-410e-be49-48ec6609f4d7","name":"Clickout, add product from search result","type":"CONSTANT","valueType":"TEXT","value":"Clickout, add product from search result"},{"id":"e836ec60-0a63-47c8-b89f-80b62b01b6af","name":"currency","type":"FUNCTION","valueType":"TEXT","function":function(event){const hostname = window.location.hostname; const currencyMap = { "jp.nobleknight.com": "JPY", "test.jp.nobleknight.com": "JPY", "au.nobleknight.com": "AUD", "test.au.nobleknight.com": "AUD", "eu.nobleknight.com": "EUR", "test.eu.nobleknight.com": "EUR", "ca.nobleknight.com": "CAD", "test.ca.nobleknight.com": "CAD", "uk.nobleknight.com": "GBP", "test.uk.nobleknight.com": "GBP", }; const currency = currencyMap[hostname] || "USD"; return currency;}},{"id":"ad6080ea-719b-4732-952f-ef4f1ce45e02","name":"Event target","type":"FUNCTION","valueType":"EVENT","function":function(event){return event.target}},{"id":"6df04a75-ec03-4c54-8ec9-094004ab9fbd","name":"getPurchaseData","type":"FUNCTION","valueType":"LIST","function":function(event){const rawData = localStorage.getItem('zvCartData') ?? '[]'; try { const data = JSON.parse(rawData); console.log(data) return Array.isArray(data) ? data : []; } catch { return []; }}},{"id":"2e141436-b43c-40d6-bbed-64cfdca7f222","name":"Go to PDP - search clickout","type":"CONSTANT","valueType":"TEXT","value":"Go to PDP - search clickout"},{"id":"6c77635c-e95a-4eca-8086-f6be1b1193e8","name":"Named referral: Search","type":"CONSTANT","valueType":"TEXT","value":"Search"},{"id":"75cf8fd1-fafe-44be-9806-23ff3017c9c1","name":"Page URL","type":"FUNCTION","valueType":"TEXT","function":function(event){return window.location.href;}},{"id":"5f51c142-4aee-4aac-a398-e6fb649c5969","name":"pdp_sku","type":"FUNCTION","valueType":"TEXT","function":function(event){const currentUrl = window.location.href; const match = currentUrl.match(/(?<=\/P\/)[^/]+/); const sku = match ? match[0] : ''; return sku; }},{"id":"b12f3744-de4e-487e-b45c-494d0ecd4b3b","name":"Product details page visit","type":"CONSTANT","valueType":"TEXT","value":"Product details page visit"},{"id":"907985d3-9828-4823-ab71-0b6b472bd6a4","name":"productImageClicked","type":"FUNCTION","valueType":"BOOLEAN","function":function(event){return !!event.target.closest('.result-card__image-wrapper'); }},{"id":"3f31b345-4f62-42ce-9cd4-888f458cb6e9","name":"productTitleClicked","type":"FUNCTION","valueType":"BOOLEAN","function":function(event){return !!event.target.closest('.result-card__link');}},{"id":"279b8532-1de4-4eca-bbfa-75f167a01a3c","name":"removedFromCart_price","type":"FUNCTION","valueType":"DECIMAL","function":function(event){const removeFromCartBtn = event.target.closest('button[formaction*="/cart/remove"]'); if(!removeFromCartBtn) return; const quantityWrapper = removeFromCartBtn?.parentElement; const ancestor = quantityWrapper?.parentElement?.parentElement; const price = ancestor.querySelector('.price'); const priceInputValue = price?.querySelector('input')?.value; return getNumericPriceFromString(priceInputValue) || null;}},{"id":"cc121fc5-1528-4995-8a6f-a24d8e2370ea","name":"removedFromCart_quantity","type":"FUNCTION","valueType":"INTEGER","function":function(event){const removeFromCartBtn = event.target.closest('button[formaction*="/cart/remove"]'); if(!removeFromCartBtn) return; const quantityWrapper = removeFromCartBtn?.parentElement; const quantityInput = quantityWrapper?.querySelector('.quantity-input'); return quantityInput ? parseFloat(quantityInput.value) : 1 }},{"id":"4e56850d-0176-4de4-88ed-9eb668a7752a","name":"removedFromCart_sku","type":"FUNCTION","valueType":"TEXT","function":function(event){const removeFromCartBtn = event.target.closest('button[formaction*="/cart/remove"]'); if(!removeFromCartBtn) return; const formActionAttribute = removeFromCartBtn.getAttribute('formaction'); return formActionAttribute ? formActionAttribute.replace(/[^\d].+\//, '') : null}},{"id":"42c22679-b3f7-4003-8975-c3e179e21d90","name":"Remove from cart","type":"CONSTANT","valueType":"TEXT","value":"Remove from cart"},{"id":"e5e4af14-ca7b-478f-8863-3b67c53bf1e4","name":"searchInput","type":"FUNCTION","valueType":"BOOLEAN","function":function(event){if (event.target && event.target.id === "site-search") { return true; } return false;}},{"id":"ca544c79-ff6e-412a-a0b5-2bf963c493fd","name":"Search phrase typed","type":"CONSTANT","valueType":"TEXT","value":"Search phrase typed"},{"id":"67ad9faf-3f5a-42a3-879a-964988bd9137","name":"searchProductUrl","type":"FUNCTION","valueType":"TEXT","function":function(event){const element = event.target.closest( 'a.result-card__link, a.result-card__image-wrapper, .unibox__selectable' ); if (!element) return ''; const dataLink = element.getAttribute('data-link'); if (dataLink !== null && dataLink !== undefined) { return dataLink.trim(); } const href = element.getAttribute('href'); return href ? href.trim() : '';}},{"id":"c0fe42da-f640-40d9-8e2e-9e39ea0c8dfe","name":"Search results","type":"CONSTANT","valueType":"TEXT","value":"Search results"},{"id":"295a8dec-ac3b-4ab5-93a7-178409836a98","name":"searchResults_noResults","type":"FUNCTION","valueType":"BOOLEAN","function":function(event){const searchSuggestions = document.querySelectorAll('.z-search-suggests'); return searchSuggestions.length === 0;}},{"id":"79ea7cc4-d2c1-4825-ae29-2a67c53b9593","name":"searchResults_skus","type":"FUNCTION","valueType":"LIST","function":function(event){ const skuLinks = document.querySelectorAll('.result-card__link'); const skus = Array.from(skuLinks).map((link) => { const match = link.href.match(/(?<=\/P\/)[^/]+/i); return match ? match[0] : null; }).filter(Boolean); return skus; }},{"id":"26cd3938-f2f8-4e2d-ba51-27a3116c948a","name":"searchTerm","type":"FUNCTION","valueType":"TEXT","function":function(event){const urlParams = new URLSearchParams(window.location.search); const searchTerm = urlParams.get('zQuery'); return searchTerm ?? ''}},{"id":"9ec04551-6b11-4101-b769-b08ee5148b1d","name":"Update cart","type":"CONSTANT","valueType":"TEXT","value":"Update cart"},{"id":"ebfd679f-3e55-46a7-b5cc-e450d90d294d","name":"updateCartButtonClicked","type":"FUNCTION","valueType":"BOOLEAN","function":function(event){return !!event.target.closest('.quantity-wrapper button:not([formaction*="/cart/remove"])'); }},{"id":"2908e0da-045c-4940-84bb-aa1e36f43551","name":"zoovuConsent","type":"FUNCTION","valueType":"BOOLEAN","function":function(event){return !!(window?.ketchConsent?.analytics ?? true);}},{"id":"d1f18334-3294-4223-b55f-5c3328fbe65b","name":"zvLocale","type":"FUNCTION","valueType":"TEXT","function":function(event){const hostname = window.location.hostname; const localeMap = { "jp.nobleknight.com": "en-JP", "test.jp.nobleknight.com": "en-JP", "au.nobleknight.com": "en-AU", "test.au.nobleknight.com": "en-AU", "eu.nobleknight.com": "en-DE", "test.eu.nobleknight.com": "en-DE", "ca.nobleknight.com": "en-CA", "test.ca.nobleknight.com": "en-CA", "uk.nobleknight.com": "en-GB", "test.uk.nobleknight.com": "en-GB", }; const locale = localeMap[hostname] || "en-US"; return locale;}}]; const script = {"id":"2fad5e03-9342-4a18-a81e-24bcb7e4a367","rows":[{"id":"fa6a7bed-19e1-44ef-a0e4-ed56c5115727","rowType":"EVENT","trigger":{"id":"eb67aea3-d60d-4791-8f05-eaf44119887a","name":"Add to Cart - Search Clickout","type":"CLICK","groups":[{"id":"66eebb7d-5cba-49aa-a4a3-a0256ac41728","rows":[{"valueType":"EVENT","id":"939831bf-411b-48ec-8555-d52525cedd66","variableId":"ad6080ea-719b-4732-952f-ef4f1ce45e02","value":"atc","operator":"CONTAINS_CLASS"},{"valueType":"TEXT","id":"d9a072e7-fbbf-4406-b503-911b75cbc0f5","variableId":"75cf8fd1-fafe-44be-9806-23ff3017c9c1","value":"?zQuery","operator":"CONTAINS"}]}]},"action":{"type":"CLICKOUT"},"fields":[{"id":"c597fce2-b9ac-4cac-88f1-6e8fe05c8ae5","variableId":"75cf8fd1-fafe-44be-9806-23ff3017c9c1","fieldName":"targetUrl"},{"id":"8ceaf297-1505-4ef1-a044-25c632a42921","variableId":"d1f18334-3294-4223-b55f-5c3328fbe65b","fieldName":"locale"},{"id":"6b7299ab-58e6-45e8-b18a-c370ef4237f8","variableId":"6c77635c-e95a-4eca-8086-f6be1b1193e8","fieldName":"namedReferral"},{"id":"fb1c94e5-c739-4438-b871-4f2fb558634e","variableId":"b73b1d5c-2232-410e-be49-48ec6609f4d7","fieldName":"eventLabel"}]},{"id":"6abaf40a-9c4c-4b85-b09f-7bf0021e4209","rowType":"EVENT","trigger":{"id":"4a560114-ae6a-4d17-9f57-849b081a7e6d","name":"Page Load","type":"PAGE_LOAD","groups":[{"id":"2007244e-c679-4fce-86a3-d3fec9f97c18","rows":[{"valueType":"TEXT","id":"7b55efa4-79f9-4a26-821c-25265bf8787d","variableId":"75cf8fd1-fafe-44be-9806-23ff3017c9c1","value":"/P/","operator":"DOES_NOT_CONTAIN"}]}]},"action":{"type":"PAGE_VISITED"},"fields":[{"id":"ce31e883-bb05-46ce-bd03-54fdd2b5bf34","variableId":"d1f18334-3294-4223-b55f-5c3328fbe65b","fieldName":"locale"}]},{"id":"d9749d4b-36b8-4e4f-8f1a-fe077a54f0c5","rowType":"EVENT","trigger":{"id":"b869581e-9d4a-4f7b-bce7-c20df25519e0","name":"PDP Visit","type":"PAGE_LOAD","groups":[{"id":"c3836e89-33b2-4962-805b-f293d87ea48b","rows":[{"valueType":"TEXT","id":"d9e86de5-7dff-4660-9d7e-fd8307096e52","variableId":"75cf8fd1-fafe-44be-9806-23ff3017c9c1","value":"/P/","operator":"CONTAINS"}]}]},"action":{"type":"PDP_VISITED"},"fields":[{"id":"1537147d-cd29-4050-a3fc-56720e2db731","variableId":"d1f18334-3294-4223-b55f-5c3328fbe65b","fieldName":"locale"},{"id":"08c5259d-0ddd-49ab-875b-03a482497614","variableId":"5f51c142-4aee-4aac-a398-e6fb649c5969","fieldName":"sku"},{"id":"21d13f36-f76a-4460-a0e6-4c7b7d59c743","variableId":"b12f3744-de4e-487e-b45c-494d0ecd4b3b","fieldName":"eventLabel"}]},{"id":"24c18c3f-b39a-4e01-ba84-276012d6d63a","rowType":"EVENT","trigger":{"id":"2d1c94a3-cfc6-40b4-a1a2-5aa7c4c8d997","name":"Add to Cart Trigger","type":"CLICK","groups":[{"id":"325a2ab8-33fd-45db-b889-896ae265cd8b","rows":[{"valueType":"EVENT","id":"24b9848f-ac22-41fd-83a7-c0778f9ecb49","variableId":"ad6080ea-719b-4732-952f-ef4f1ce45e02","value":"atc","operator":"CONTAINS_CLASS"}]}]},"action":{"type":"ADD_TO_CART"},"fields":[{"id":"c9ca4994-f20e-41c1-a7d1-806901b54a78","variableId":"d1f18334-3294-4223-b55f-5c3328fbe65b","fieldName":"locale"},{"id":"6a8e7ddb-f432-404f-a2ab-4b8349072ce6","variableId":"81ab552d-d8db-456d-9618-fcaf74d934e0","fieldName":"sku"},{"id":"671e5a8f-0ffe-49a5-b070-cb69892fbaa4","variableId":"e836ec60-0a63-47c8-b89f-80b62b01b6af","fieldName":"currencyCode"},{"id":"c8a73915-5aea-4ece-befa-02d69bf87079","variableId":"26e045ae-0482-453b-bad1-f0265d34da9d","fieldName":"price"},{"id":"6d936e76-8c84-4644-8605-7f810d2c56fc","variableId":"70fb9e0a-634b-4937-9147-2cec6b573c98","fieldName":"quantity"},{"id":"1862970f-abc7-4332-a748-6e496e616ec0","variableId":"1eec2be6-dc91-4c4e-a443-da2f051baf5b","fieldName":"eventLabel"}]},{"id":"24e9bda4-4306-4077-a0b0-0ce51d17fae8","rowType":"EVENT","trigger":{"id":"4f68e3d9-ead6-4684-bf15-55b527b33ded","name":"Search Input Trigger","type":"INPUT","groups":[{"id":"cee528f6-72d9-4ed1-a69b-1a75a0fd0238","rows":[{"valueType":"BOOLEAN","id":"b45ef6e3-09fd-43a0-9961-b8d54695dc0a","variableId":"e5e4af14-ca7b-478f-8863-3b67c53bf1e4","value":"true","operator":"EQUALS"}]}]},"action":{"type":"SEARCH"},"fields":[{"id":"2dbefd00-2bcb-473d-b334-fb957ce45e17","variableId":"d1f18334-3294-4223-b55f-5c3328fbe65b","fieldName":"locale"},{"id":"b1ab2939-bfa2-4c24-b60a-e4a6b04a7809","variableId":"ca544c79-ff6e-412a-a0b5-2bf963c493fd","fieldName":"eventLabel"}]},{"id":"fb73f4e5-9903-414f-ba90-0284abafb07e","rowType":"EVENT","trigger":{"id":"1ebf3c7e-fe51-43a8-af0f-3aea99425f12","name":"isSearchPage Trigger","type":"PAGE_LOAD","groups":[{"id":"8bbdf8c6-271f-4559-a2d5-1a4a1fb040f1","rows":[{"valueType":"TEXT","id":"c33b0913-13ea-4b4a-b210-870fc9f4de6f","variableId":"75cf8fd1-fafe-44be-9806-23ff3017c9c1","value":"zQuery=","operator":"CONTAINS"}]}]},"action":{"type":"SEARCH_RESULT"},"fields":[{"id":"68efcb0a-d274-426f-9196-253c7c515d42","variableId":"d1f18334-3294-4223-b55f-5c3328fbe65b","fieldName":"locale"},{"id":"727b6a63-39c6-413c-85db-75390a1c1be8","variableId":"295a8dec-ac3b-4ab5-93a7-178409836a98","fieldName":"isEmpty"},{"id":"b83bd754-585a-4c5b-b467-e4328eb177ff","variableId":"79ea7cc4-d2c1-4825-ae29-2a67c53b9593","fieldName":"skus"},{"id":"e704cabd-a02d-4ee3-827f-cd9448d9f340","variableId":"c0fe42da-f640-40d9-8e2e-9e39ea0c8dfe","fieldName":"eventLabel"},{"id":"678a505a-c776-4d06-b5f8-1f7ff2e1ea57","variableId":"26cd3938-f2f8-4e2d-ba51-27a3116c948a","fieldName":"category"}]},{"id":"a53af0c6-762c-4b16-9394-48f93c4bc8a1","rowType":"EVENT","trigger":{"id":"8a80c42a-a5c9-4a36-acf2-3f9ae7c28057","name":"removeFromCart Trigger","type":"CLICK","groups":[{"id":"71e70fde-4690-485a-a4e1-d6821b55d284","rows":[{"valueType":"EVENT","id":"43436c63-efa9-4d21-993c-858fd33d72e5","variableId":"ad6080ea-719b-4732-952f-ef4f1ce45e02","value":"[formaction*=\"/cart/remove\"]","operator":"MATCHES_CSS_SELECTOR"}]}]},"action":{"type":"REMOVE_FROM_CART"},"fields":[{"id":"0e57de4b-83d1-43ab-b792-4c42311fdad7","variableId":"d1f18334-3294-4223-b55f-5c3328fbe65b","fieldName":"locale"},{"id":"274f0975-22d6-41f6-9d85-f1af3d8db680","variableId":"4e56850d-0176-4de4-88ed-9eb668a7752a","fieldName":"sku"},{"id":"abddfaf2-7995-4227-8d77-5363325ec8a9","variableId":"279b8532-1de4-4eca-bbfa-75f167a01a3c","fieldName":"price"},{"id":"4a9bd60b-7d22-4dbd-8efb-193fbdc026e7","variableId":"e836ec60-0a63-47c8-b89f-80b62b01b6af","fieldName":"currencyCode"},{"id":"4ea8e079-61fa-4b8d-ad3a-fd9a9653e005","variableId":"cc121fc5-1528-4995-8a6f-a24d8e2370ea","fieldName":"quantity"},{"id":"6e854854-78fa-4c65-9b07-3c92e07d9468","variableId":"42c22679-b3f7-4003-8975-c3e179e21d90","fieldName":"eventLabel"}]},{"id":"8e830fd1-04ab-4e01-90c4-48e4b64c3dd7","rowType":"EVENT","trigger":{"id":"a14a7b17-8a49-45bb-b7cf-701a72408118","name":"updateCart Trigger","type":"CLICK","groups":[{"id":"0db85688-128f-4bbc-8a49-31d8b472abc2","rows":[{"valueType":"TEXT","id":"214d3411-6766-4795-b4b7-f829f4572d86","variableId":"75cf8fd1-fafe-44be-9806-23ff3017c9c1","value":"/Cart","operator":"CONTAINS"},{"valueType":"BOOLEAN","id":"1fbd5ae1-f8f2-4557-946b-d2349226852a","variableId":"ebfd679f-3e55-46a7-b5cc-e450d90d294d","value":"true","operator":"EQUALS"}]}]},"action":{"type":"UPDATE_CART"},"fields":[{"id":"5bccd725-d575-4e18-a0ef-ced6464eaf2f","variableId":"d1f18334-3294-4223-b55f-5c3328fbe65b","fieldName":"locale"},{"id":"9afd94e7-cf57-4df4-b127-87dd67815fae","variableId":"6f23f86a-92fe-46f8-8091-5e6a4593a8c7","fieldName":"sku"},{"id":"9069097d-2aab-4d2d-8cfa-b6cb04663255","variableId":"40aaafa6-0969-4236-ad9e-be68fb3319d3","fieldName":"price"},{"id":"04f83f35-19c5-4013-9d68-d920b283c5bf","variableId":"e836ec60-0a63-47c8-b89f-80b62b01b6af","fieldName":"currencyCode"},{"id":"c4b9ce34-ca6f-4efc-abfd-88f0f686c529","variableId":"22cc39a7-af86-4b04-b501-f6f110b649bf","fieldName":"quantity"},{"id":"332e1017-6e28-4d0a-bb66-7455a2cdb1be","variableId":"9ec04551-6b11-4101-b769-b08ee5148b1d","fieldName":"eventLabel"}]},{"id":"6fb84735-87ac-40f4-b7c1-32e004204fc2","rowType":"EVENT","trigger":{"id":"801377f5-96d9-4bfe-b7a8-84036626165d","name":"Analytics Consent Declined","type":"PAGE_LOAD","groups":[{"id":"3c784802-d740-471f-b9d9-376ce424d857","rows":[{"valueType":"BOOLEAN","id":"c905c54e-f47f-4dda-a4e2-5bd141819b11","variableId":"2908e0da-045c-4940-84bb-aa1e36f43551","value":"false","operator":"EQUALS"}]}]},"action":{"type":"DECLINE_TRACKING"},"fields":[{"id":"477ba136-adf9-4345-b393-190c35cf3689","variableId":"d1f18334-3294-4223-b55f-5c3328fbe65b","fieldName":"locale"}]},{"id":"c491c154-c3aa-4ef9-ade1-414ee1b65458","rowType":"EVENT","trigger":{"id":"4eec6c64-b4ec-449c-8811-b044fae7b1b1","name":"Products In Search Clicked","type":"CLICK","groups":[{"id":"9f0eac52-818f-4e86-a3fb-3c2c5463844e","rows":[{"valueType":"BOOLEAN","id":"21cb33b7-4622-4b5d-8fb8-027583023f97","variableId":"3f31b345-4f62-42ce-9cd4-888f458cb6e9","value":"true","operator":"EQUALS"}]},{"id":"9291a200-7812-48fd-96d6-0cac7bca8222","rows":[{"valueType":"BOOLEAN","id":"f4668e9c-ac70-406e-98db-aa772ae4eaa1","variableId":"907985d3-9828-4823-ab71-0b6b472bd6a4","value":"true","operator":"EQUALS"}]},{"id":"720a164d-7de2-41b9-9f94-1e0db32671ec","rows":[{"valueType":"BOOLEAN","id":"19515653-f68e-4265-9a55-f112542193bd","variableId":"3be07ee8-8a02-4588-ac5c-c775f9486959","value":"true","operator":"EQUALS"}]}]},"action":{"type":"CLICKOUT"},"fields":[{"id":"02af08c0-eef1-4069-87e9-84d972a7c448","variableId":"6c77635c-e95a-4eca-8086-f6be1b1193e8","fieldName":"namedReferral"},{"id":"6a146d62-abdb-4f7c-b28e-4a5fa326bf11","variableId":"67ad9faf-3f5a-42a3-879a-964988bd9137","fieldName":"targetUrl"},{"id":"38877f8f-0669-4c85-94fb-ca5b5a23ac80","variableId":"d1f18334-3294-4223-b55f-5c3328fbe65b","fieldName":"locale"},{"id":"b55b5eda-bc2d-444b-b495-fa0f220f9f52","variableId":"2e141436-b43c-40d6-bbed-64cfdca7f222","fieldName":"eventLabel"}]},{"id":"152faa78-8ef8-43f2-b11b-0e329148ce58","rowType":"CUSTOM_ACTION","trigger":{"id":"34082dff-b14f-4130-8d2c-446eb4a4a637","name":"checkoutTrigger","type":"CLICK","groups":[{"id":"aaa549d0-603f-4054-aaea-424b8f7d32b4","rows":[{"valueType":"TEXT","id":"e3dfb0f1-c741-470f-b2c7-09dc0c82aee5","variableId":"75cf8fd1-fafe-44be-9806-23ff3017c9c1","value":"/Cart","operator":"CONTAINS"},{"valueType":"EVENT","id":"3b361b55-b200-4dd7-b46b-ca4f980fc4fa","variableId":"ad6080ea-719b-4732-952f-ef4f1ce45e02","value":"[href=\"/Information\"]","operator":"MATCHES_CSS_SELECTOR"}]}]},"action":{"id":"3724f4e3-cae3-49d9-b7e4-f165d8d8e616","type":"CUSTOM","code":function(event){const cartItems = document.querySelectorAll('.container[name="cart"] form[action*="/cart/update"]'); const mappedItems = Array.from(cartItems).map((item) => { const actionAttribute = item.getAttribute('action') || ''; const skuMatch = actionAttribute?.match(/(\d+)\/?$/); const sku = skuMatch ? skuMatch[1] : null; const name = item.querySelector('.product-details h3')?.textContent.trim() || ''; const quantity = Number.parseInt(item.querySelector('.quantity > input')?.value ?? '', 10) || 0; const pricePerUnit = Number.parseFloat(item.querySelector('.price input')?.value ?? '') || 0; return {name, sku, quantity, pricePerUnit} }) localStorage.setItem('zvCartData', JSON.stringify(mappedItems))}},"fields":[]},{"id":"bb146bbd-0e81-42ce-858a-4a51c73e1d44","rowType":"EVENT","trigger":{"id":"7ca7b0dd-6e06-4ac2-95b2-dc173cc1eed5","name":"isThankYouPage","type":"PAGE_LOAD","groups":[{"id":"05eac16d-2bce-4381-bdd2-cb58df67402e","rows":[{"valueType":"TEXT","id":"99e60c89-6923-45f1-b37f-2858867efd82","variableId":"75cf8fd1-fafe-44be-9806-23ff3017c9c1","value":"NKGThankYou","operator":"CONTAINS"}]}]},"action":{"type":"PURCHASED"},"fields":[{"id":"bbf78640-d740-4d4a-8d22-5ba7eb46346c","variableId":"e836ec60-0a63-47c8-b89f-80b62b01b6af","fieldName":"currencyCode"},{"id":"cd82ed14-d1ed-47bf-9820-e64e42047f2a","variableId":"6df04a75-ec03-4c54-8ec9-094004ab9fbd","fieldName":"products"}]}]}; const advancedCode = function(){let scr = document.createElement('script'); scr.id = 'bl-script'; scr.src='https://services.zoovu.com/events/behavioral-launchers-script/d0681dac-ebe1-4083-8996-7ce42d6047e1/js-loader?locale=en-US'; document.body.appendChild(scr); }; const url = 'https://queue-propagator.zoovu.com'; const currentEnvironment = 'barracuda'; const currentAccountId = 1782; // ------------------------- API ------------------------- let trackingEnabled = true; function disableTracking() { trackingEnabled = false; } function enableTracking() { trackingEnabled = true; } function getNumericPriceFromString(stringPrice) { const parsedPrice = stringPrice .replace(/\.$/, '') .replace(/([^.',\s\d])*/g, '') .replace(/([.',\s](?=\d{3}))/g, '') .replace(/([.',](?=\d{2}))/g, '.'); return Number(parsedPrice); } class TrackingExecutionError extends Error { constructor(message, trackingEntityType, variableId, triggerId, scriptId, trackingErrorType) { super(message); this.trackingEntityType = trackingEntityType; this.variableId = variableId; this.triggerId = triggerId; this.scriptId = scriptId; this.trackingErrorType = trackingErrorType; } } // ------------------------- helpers ------------------------- const eventTypes = Object.freeze({ PAGE_VISITED: "PAGE_VISITED", ADD_TO_CART: "ADD_TO_CART", REMOVE_FROM_CART: "REMOVE_FROM_CART", PDP_VISITED: "PDP_VISITED", PURCHASED: "PURCHASED", UPDATE_CART: "UPDATE_CART", DECLINE_TRACKING: "DECLINE_TRACKING", SEARCH: "SEARCH", SEARCH_RESULT: "SEARCH_RESULT", CLICKOUT: "CLICKOUT" }); const trackingEventTypes = Object.freeze({ TRACKING_SUCCESSFUL_EXECUTION: 'TRACKING_SUCCESSFUL_EXECUTION', TRACKING_EXECUTION_FAILURE: 'TRACKING_EXECUTION_FAILURE' }) const actionTypes = Object.freeze({ ...eventTypes, CUSTOM: 'CUSTOM' }) const triggerTypes = Object.freeze({ CLICK: 'CLICK', INPUT: 'INPUT', PAGE_LOAD: 'PAGE_LOAD' }); const variableTypes = Object.freeze({ FUNCTION: 'FUNCTION', CONSTANT: 'CONSTANT' }); const trackingEntityTypes = Object.freeze({ VARIABLE: 'VARIABLE', TRIGGER: 'TRIGGER', CUSTOM_ACTION: 'CUSTOM_ACTION' }); const trackingErrorTypes = Object.freeze({ MISSING_VALUE: 'MISSING_VALUE', TYPE_MISMATCH: 'TYPE_MISMATCH', UNSUPPORTED_VARIABLE: 'UNSUPPORTED_VARIABLE', MISSING_VARIABLE: 'MISSING_VARIABLE', OTHER: 'OTHER' }); const matchers = Object.freeze({ EQUALS: (a, b) => a === b, DOES_NOT_EQUAL: (a, b) => a !== b, CONTAINS: (a, b) => a.indexOf(b) >= 0, DOES_NOT_CONTAIN: (a, b) => a.indexOf(b) === -1, GREATER_THAN: (a, b) => a > b, LESS_THAN: (a, b) => a < b, GREATER_THAN_OR_EQUAL: (a, b) => a >= b, LESS_THAN_OR_EQUAL: (a, b) => a <= b, MATCHES_CSS_SELECTOR: (target, test) => target.matches(test), MATCHES_ID: (target, test) => target.id === test, CONTAINS_ID: (target, test) => target.id.includes(test), DOES_NOT_CONTAIN_ID: (target, test) => !target.id.includes(test), MATCHES_CLASS: (target, test) => target.className === test, CONTAINS_CLASS: (target, test) => target.className.includes(test), DOES_NOT_CONTAIN_CLASS: (target, test) => !target.className.includes(test), }); const trackingFieldName = `${domainId}_${zoovuId}_trackingExecutions` const MAX_RECORDS = 100 const DEBOUNCE_TIME = 1500 if (!JSON.parse(localStorage.getItem(trackingFieldName))) { localStorage.setItem(trackingFieldName, JSON.stringify([])) } function checkValue(type, value) { switch (type) { case 'BOOLEAN': return value === true || value === 'true'; case 'TEXT': return value; case 'DECIMAL': return typeof value === 'string' ? parseFloat(value) : value; case 'INTEGER': return typeof value === 'string' ? parseInt(value) : value; default: return value; } } function cast(type, value) { switch (type) { case 'BOOLEAN': return value === true || value === 'true'; case 'TEXT': return value; case 'DECIMAL': return typeof value === 'string' ? parseFloat(value) : value; case 'INTEGER': return typeof value === 'string' ? parseInt(value) : value; default: return value; } } function debounce(fn, delay) { let timer = null; return function () { const context = this, args = arguments; clearTimeout(timer); timer = setTimeout(function () { fn.apply(context, args); }, delay); }; } function getOrganization() { return zoovuId; } function getDomainId() { return domainId; } function getTimezone() { return Intl.DateTimeFormat().resolvedOptions().timeZone; } function getReferrer() { const referrer = document.referrer; if (/^(https?|android-app):\/\//i.test(referrer)) { return referrer; } else { return undefined; } } function getPath() { return window.location.href.replace(window.location.origin, ''); } function getCookieValue(cookieName) { const cookies = document.cookie.split('; '); for (let i = 0; i < cookies.length; i++) { const cookie = cookies[i].split('='); if (cookie[0] === cookieName) { return cookie[1]; } } return null; } function generateUuid() { return self.crypto.randomUUID(); } function addZoovuCidToCookies() { const uuid = generateUuid(); const zoovuCid = `zoovu-cid=${uuid}; path=/`; document.cookie = zoovuCid; return uuid; } function getCID() { return getCookieValue(`zoovu-cid`) !== null ? getCookieValue(`zoovu-cid`) : addZoovuCidToCookies(); } function getEnvironment() { return currentEnvironment; } function getAccountId() { return currentAccountId; } function getPropertyTypeError(propertyName, expectedType, currentType) { return `TYPE MISMATCH: ${propertyName}: should be ${expectedType} but is ${currentType}` } function typeCheckValue(value, variableType, propertyName, variableId, triggerId) { let errorMessage = ''; if (value === undefined || value === null) { throw new TrackingExecutionError(`${propertyName}: value is not defined.`, trackingEntityTypes.VARIABLE, variableId, triggerId, script.id, trackingErrorTypes.MISSING_VALUE) } switch (variableType) { case "TEXT": if (typeof value !== 'string') errorMessage = getPropertyTypeError(propertyName, 'string', typeof value); break; case "INTEGER": case "DECIMAL": if (typeof value !== 'number') errorMessage = getPropertyTypeError(propertyName, 'number', typeof value); break; case "BOOLEAN": if (typeof value !== 'boolean') errorMessage = getPropertyTypeError(propertyName, 'boolean', typeof value); break; case 'LIST': if (!Array.isArray(value)) errorMessage = getPropertyTypeError(propertyName, 'list', typeof value); break; case 'EVENT': break; default: throw new TrackingExecutionError(`Not supported variable type: ${variableType}`, trackingEntityTypes.VARIABLE, variableId, triggerId, script.id, trackingErrorTypes.UNSUPPORTED_VARIABLE) } if (errorMessage) { throw new TrackingExecutionError(errorMessage, trackingEntityTypes.VARIABLE, variableId, triggerId, script.id, trackingErrorTypes.TYPE_MISMATCH) } } function ensureRequiredFieldsPresent(fields, eventType) { return Object.entries(fields).every(([key, value]) => { if (!value) { throw new TrackingExecutionError( `Required property ${key} missing value for ${eventType}.`, trackingEntityTypes.VARIABLE, variableId, null, script.id, trackingErrorTypes.MISSING_VALUE ) } return true; }); } function getBaseEventBody(eventType) { return { origin: 'CLIENT', queryParams: {}, organization: getOrganization(), domainId: getDomainId(), path: getPath(), referrer: getReferrer(), cid: getCID(), timezone: getTimezone(), // dynamic eventType: eventType ?? '', eventLabel: '', }; } function getEventExecutable(actionType) { switch (actionType) { case actionTypes.PAGE_VISITED: return sendPageVisitedEvent; case actionTypes.ADD_TO_CART: return sendAddToCartEvent; case actionTypes.CLICKOUT: return sendClickoutEvent; case actionTypes.REMOVE_FROM_CART: return sendRemoveFromCartEvent; case actionTypes.PDP_VISITED: return sendPdpVisitedEvent; case actionTypes.PURCHASED: return sendPurchaseEvent; case actionTypes.DECLINE_TRACKING: return sendDeclineTrackingEvent; case actionTypes.UPDATE_CART: return sendUpdateCartEvent; case actionTypes.SEARCH: return sendSearchEvent; case actionTypes.SEARCH_RESULT: return sendSearchResultEvent; } } function getVariableValueById(variableId, event, fieldName, triggerId) { const foundVariable = variables.find(v => v.id === variableId); let variableValue = null; if (foundVariable) { if (foundVariable.type === variableTypes.CONSTANT) { variableValue = cast(foundVariable.valueType, foundVariable.value); } else if (foundVariable.type === variableTypes.FUNCTION && typeof foundVariable.function === 'function') { try { variableValue = foundVariable.function(event); } catch (e) { throw new TrackingExecutionError( e.message, trackingEntityTypes.VARIABLE, variableId, triggerId, script.id, trackingErrorTypes.OTHER ) } } else { throw new TrackingExecutionError( `${foundVariable.type} is not supported.`, trackingEntityTypes.VARIABLE, variableId, triggerId, script.id, trackingErrorTypes.UNSUPPORTED_VARIABLE ) } typeCheckValue(variableValue, foundVariable.valueType, fieldName ? fieldName : foundVariable.name, variableId, triggerId); return variableValue; } else { throw new TrackingExecutionError( `No variable with ID ${variableId}`, trackingEntityTypes.VARIABLE, variableId, triggerId, script.id, trackingErrorTypes.MISSING_VARIABLE ) } } function evaluateSingleTriggerRow(row, event, triggerId) { const target = getVariableValueById(row.variableId, event, undefined, triggerId); const matcher = matchers[row.operator]; checkValue(row.valueType, row.value); const value = cast(row.valueType, row.value); if (matcher && typeof matcher === 'function') { return matcher(target, value); } return false; } function preparePayloadFromFields(fields, event) { const payload = {}; fields.forEach(f => { payload[f.fieldName] = getVariableValueById(f.variableId, event, f.fieldName) }) return payload; } function evaluateTriggerConditions(trigger, event) { // OR between groups return trigger.groups.some(group => // AND between rows group.rows.every(row => evaluateSingleTriggerRow(row, event, trigger.id))) } function runAction(action, fields, event, trigger) { const trackingExecutions = jsonParser(trackingFieldName) if (action.type === actionTypes.CUSTOM && typeof action.code === 'function') { // add script custom action trackingExecutions.push(createTrackingSuccessfulExecutionRecord(trackingEntityTypes.CUSTOM_ACTION, action.id)) try { action.code(event); } catch (e) { throw new TrackingExecutionError( e.message, trackingEntityTypes.CUSTOM_ACTION, action.id, null, script.id, trackingErrorTypes.OTHER ) } localStorage.setItem(trackingFieldName, JSON.stringify(trackingExecutions)); } else { const sendEventFunction = getEventExecutable(action.type); if (sendEventFunction && typeof sendEventFunction === 'function') { const payload = preparePayloadFromFields(fields, event) sendEventFunction(payload); addSuccessfulExecutions(trigger, fields) } } } function evaluateSingleRule(rule, event) { if (evaluateTriggerConditions(rule.trigger, event)) { runAction(rule.action, rule.fields, event, rule.trigger); } } function evaluateRules(rules, event) { try { rules.forEach(rule => { evaluateSingleRule(rule, event) }); } catch (error) { const trackingExecutions = jsonParser(trackingFieldName); const { message, trackingEntityType, variableId, triggerId, scriptId, trackingErrorType } = error; const failedExecution = createTrackingFailedExecutionRecord( trackingEntityType, variableId, triggerId, scriptId, trackingErrorType, message ) trackingExecutions.push(failedExecution) localStorage.setItem(trackingFieldName, JSON.stringify(trackingExecutions)); console.debug(error) } } function observeAndReactOnPageChange(callback) { let oldHref; if (oldHref === undefined) { callback(); oldHref = document.location.href; } const body = document.querySelector('body'); const observer = new MutationObserver(() => { if (oldHref !== document.location.href) { oldHref = document.location.href; callback(); } }); observer.observe(body, {childList: true, subtree: true}); } function executeAdvancedCode() { if (typeof advancedCode === 'function') { advancedCode(); } } function jsonParser(key) { const foundValue = JSON.parse(localStorage.getItem(key)) if (!Array.isArray(foundValue)) { throw Error('Invalid value in localStorage for key ' + key) } return foundValue } function createTrackingSuccessfulExecutionRecord(entityType, entityId) { const executionTime = Date.now(); return { organization: getOrganization(), domainId: getDomainId(), eventType: trackingEventTypes.TRACKING_SUCCESSFUL_EXECUTION, trackingEntityType: entityType, trackingEntityId: entityId, executionTime } } function createTrackingFailedExecutionRecord(entityType, entityId, triggerId, scriptId, errorType, message) { const executionTime = Date.now(); return { organization: getOrganization(), domainId: getDomainId(), eventType: trackingEventTypes.TRACKING_EXECUTION_FAILURE, trackingEntityType: entityType, trackingEntityId: entityId, executionTime, triggerId: triggerId || null, scriptId: scriptId || null, error: { type: errorType, message } } } function addSuccessfulExecutions(trigger, fields) { const successfulExecutions = jsonParser(trackingFieldName) // add script trigger successfulExecutions.push(createTrackingSuccessfulExecutionRecord(trackingEntityTypes.TRIGGER, trigger.id)) // add script function variables fields.forEach(field => { const foundVariableInField = variables.find(variable => variable.id === field.variableId) if (foundVariableInField.type === variableTypes.FUNCTION) { successfulExecutions.push(createTrackingSuccessfulExecutionRecord(trackingEntityTypes.VARIABLE, foundVariableInField.id)) } }) // add trigger function variables trigger.groups.forEach(groups => { groups.rows.forEach(row => { const foundVariable = variables.find(variable => variable.id === row.variableId) if (foundVariable.type === variableTypes.FUNCTION) { successfulExecutions.push(createTrackingSuccessfulExecutionRecord(trackingEntityTypes.VARIABLE, foundVariable.id)) } }) }) localStorage.setItem(trackingFieldName, JSON.stringify(successfulExecutions)); } // ------------------------- events ------------------------- async function sendEvent(body) { if (trackingEnabled) { await fetch(`${url}/fact`, { method: 'POST', mode: 'cors', cache: 'no-cache', credentials: 'same-origin', headers: { 'Content-Type': 'application/json', }, redirect: 'follow', referrerPolicy: 'no-referrer', body: JSON.stringify(body), }); } else { console.debug("Tracking disabled - no permission to track"); } } async function sendSSTRPurchaseEvent(body) { if (trackingEnabled) { const purchaseUrl = 'https://ev-co.zoovu.com/v1/CollectSalesEvent'; await fetch(purchaseUrl, { method: 'POST', mode: 'cors', cache: 'no-cache', headers: { 'Content-Type': 'application/json', }, redirect: 'follow', referrerPolicy: 'no-referrer', body: JSON.stringify(body), }); } else { console.debug("Tracking disabled - no permission to track"); } } async function sendTrackingSuccessfulExecution(body) { if (trackingEnabled) { await fetch(`${url}/tracking/executions`, { method: 'POST', mode: 'cors', cache: 'no-cache', headers: { 'Content-Type': 'application/json', }, redirect: 'follow', referrerPolicy: 'no-referrer', body: JSON.stringify(body), }); } else { console.debug("Tracking disabled - no permission to track"); } } function sendFactEventBase(eventType, eventSpecificBody) { const body = { ...getBaseEventBody(eventType), // event label + custom per-event fields ...eventSpecificBody, }; sendEvent(body); }; function sendPageVisitedEvent({locale, category, eventLabel = 'Page visit'}) { const body = { locale, eventLabel, // optional category, }; if (ensureRequiredFieldsPresent({locale}, eventTypes.PAGE_VISITED)) { sendFactEventBase(eventTypes.PAGE_VISITED, body); } }; function sendPdpVisitedEvent({ locale, sku, quantity = 1, currencyCode, eventLabel = "Product details page visit", price, category }) { const body = { locale, sku, eventLabel, // optional category, price, currencyCode, quantity, }; if (ensureRequiredFieldsPresent({locale, sku}, eventTypes.PDP_VISITED)) { sendFactEventBase(eventTypes.PDP_VISITED, body); } }; function sendAddToCartEvent({ locale, sku, quantity = 1, currencyCode, eventLabel = "Add to cart", price, category }) { const body = { locale, sku, eventLabel, // optional category, price, currencyCode, quantity, }; if (ensureRequiredFieldsPresent({locale, sku}, eventTypes.ADD_TO_CART)) { sendFactEventBase(eventTypes.ADD_TO_CART, body); } }; function sendRemoveFromCartEvent({ locale, sku, quantity = 1, currencyCode, eventLabel = "Remove from cart", price, category }) { const body = { locale, sku, eventLabel, // optional category, price, currencyCode, quantity, }; if (ensureRequiredFieldsPresent({locale, sku}, eventTypes.REMOVE_FROM_CART)) { sendFactEventBase(eventTypes.REMOVE_FROM_CART, body); } }; function sendUpdateCartEvent({ locale, sku, quantity = 1, currencyCode, eventLabel = "Update cart", price, category }) { const body = { locale, sku, eventLabel, // optional category, price, currencyCode, quantity, }; if (ensureRequiredFieldsPresent({locale, sku}, eventTypes.UPDATE_CART)) { sendFactEventBase(eventTypes.UPDATE_CART, body); } }; function sendDeclineTrackingEvent({ locale, eventLabel = "No permission to track", category }) { const body = { locale, eventLabel, // optional category }; if (ensureRequiredFieldsPresent({locale}, eventTypes.DECLINE_TRACKING)) { sendFactEventBase(eventTypes.DECLINE_TRACKING, body); disableTracking(); } }; function sendSearchEvent({ locale, eventLabel = "Search phrase typed", category }) { const body = { locale, eventLabel, // optional category, }; if (ensureRequiredFieldsPresent({locale}, eventTypes.SEARCH)) { sendFactEventBase(eventTypes.SEARCH, body); } }; function sendSearchResultEvent({ locale, isEmpty = false, eventLabel = "Search results", skus, category }) { const body = { locale, isEmpty, skus, eventLabel, // optional category }; if (ensureRequiredFieldsPresent({locale, skus}, eventTypes.SEARCH_RESULT)) { sendFactEventBase(eventTypes.SEARCH_RESULT, body); } }; function sendClickoutEvent({ locale, targetUrl, namedReferral, eventLabel = "Clickout", category }) { const body = { locale, targetUrl, namedReferral, eventLabel, // optional category }; if (ensureRequiredFieldsPresent({locale, targetUrl, namedReferral}, eventTypes.CLICKOUT)) { sendFactEventBase(eventTypes.CLICKOUT, body); } }; function sendPurchaseEvent({ currencyCode, transactionId, products }) { const sstrBody = { transactionId, products, currency: currencyCode, browserTimestamp: Date.now(), env: getEnvironment(), accountId: getAccountId(), clientId: getCID(), }; if (ensureRequiredFieldsPresent({products, currencyCode,}, eventTypes.PURCHASED)) { sendSSTRPurchaseEvent(sstrBody); } }; function sendSuccessfulExecutionEvent(forceSend) { const successfulExecutions = jsonParser(trackingFieldName) if (successfulExecutions.length === MAX_RECORDS || (forceSend && successfulExecutions.length > 0)) { sendTrackingSuccessfulExecution(successfulExecutions) localStorage.setItem(trackingFieldName, JSON.stringify([])) } } // ------------------------- core ------------------------- function reactOnLoad() { const pageLoadRules = script.rows.filter(row => row.trigger.type === triggerTypes.PAGE_LOAD); window.addEventListener("load", (event) => { observeAndReactOnPageChange(() => evaluateRules(pageLoadRules, event) && sendSuccessfulExecutionEvent()) }, {capture: true}); } function reactOnClick() { const clickRules = script.rows.filter(row => row.trigger.type === triggerTypes.CLICK); // click via mouse document.querySelector('body').addEventListener('mousedown', (event) => { evaluateRules(clickRules, event); sendSuccessfulExecutionEvent() }, {capture: true}); // click via enter button document.querySelector('body').addEventListener('keydown', (event) => { if (event.code === "Enter" || event.code === "NumpadEnter") { evaluateRules(clickRules, event); sendSuccessfulExecutionEvent() } }, {capture: true}); } function reactOnInput() { const inputRules = script.rows.filter(row => row.trigger.type === triggerTypes.INPUT); document.querySelector('body').addEventListener('input', debounce(function (event) { evaluateRules(inputRules, event); sendSuccessfulExecutionEvent() }, DEBOUNCE_TIME), {capture: true}); } function reactOnMouseLeave() { document.addEventListener("mouseleave", function (event) { if (event.clientY <= 0 || event.clientX <= 0 || (event.clientX >= window.innerWidth || event.clientY >= window.innerHeight)) { sendSuccessfulExecutionEvent(true) } }); } function track() { try { executeAdvancedCode(); reactOnLoad(); reactOnClick(); reactOnInput(); reactOnMouseLeave(); } catch (error) { console.debug("Tracking disabled", error); } } // RUN SCRIPT AFTER PAGE LOAD if (document.readyState === "loading" || document.readyState === "interactive") { // Loading hasn't finished yet document.addEventListener("readystatechange", (event) => { if (event.target.readyState === "complete") { track(); } }); } else { track(); } })();