<!-- OneTrust Cookies Consent Notice start for lightyear.cloud --> <script src="https://cdn-ukwest.onetrust.com/scripttemplates/otSDKStub.js" type="text/javascript" charset="UTF-8" data-domain-script="0197a69a-8630-7f3b-bd4c-caeb8c6dff1c" ></script> <script type="text/javascript"> (function () { // --- your allowlist of gated vendors + required OneTrust groups --- var RULES = [ // VWO { test: /\/\/dev\.visualwebsiteoptimizer\.com\//i, groups: ["C0003"] }, // YouTube - C0003 { test: /\/\/www\.youtube\.com\//i, groups: ["C0003"] }, { test: /\/\/youtube\.com\//i, groups: ["C0003"] }, { test: /\/\/www\.youtube-nocookie\.com\//i, groups: ["C0003"] }, { test: /\/\/youtubei\.googleapis\.com\//i, groups: ["C0003"] }, { test: /\/\/i\.ytimg\.com\//i, groups: ["C0003"] }, { test: /\/\/s\.ytimg\.com\//i, groups: ["C0003"] }, { test: /\/\/yt3\.ggpht\.com\//i, groups: ["C0003"] }, // Vimeo - C0003 { test: /\/\/player\.vimeo\.com\//i, groups: ["C0003"] }, { test: /\/\/vimeo\.com\//i, groups: ["C0003"] }, { test: /\/\/f\.vimeocdn\.com\//i, groups: ["C0003"] }, { test: /\/\/i\.vimeocdn\.com\//i, groups: ["C0003"] }, // Calendly - C0003 { test: /\/\/calendly\.com\//i, groups: ["C0003"] }, { test: /\/\/assets\.calendly\.com\//i, groups: ["C0003"] }, { test: /\/\/cdn\.calendly\.com\//i, groups: ["C0003"] }, // Existing C0004 domains { test: /\/\/munchkin\.marketo\.net\//i, groups: ["C0004"] }, { test: /\/\/cdn\.bizible\.com\//i, groups: ["C0004"] }, { test: /\/\/bizible\.com\//i, groups: ["C0004"] }, { test: /\/\/cdn\.bizibly\.com\//i, groups: ["C0004"] }, { test: /\/\/adobedc\.net\//i, groups: ["C0004"] }, { test: /\/\/a\.omappapi\.com\//i, groups: ["C0004"] }, { test: /\/\/tracker\.gaconnector\.com\//i, groups: ["C0004"] }, { test: /\/\/static\.hotjar\.com\//i, groups: ["C0004"] }, { test: /\/\/js\.hs\-scripts\.com\//i, groups: ["C0004"] }, { test: /\/scripts\/custom\-gclid\.js\//i, groups: ["C0004"] }, // HubSpot - C0004 { test: /\/\/js\.hubspot\.com\//i, groups: ["C0004"] }, { test: /\/\/js\.hsforms\.net\//i, groups: ["C0004"] }, { test: /\/\/js\.hscta\.net\//i, groups: ["C0004"] }, { test: /\/\/js\.hsadspixel\.net\//i, groups: ["C0004"] }, { test: /\/\/js\.hs\-analytics\.net\//i, groups: ["C0004"] }, { test: /\/\/js\.hs\-banner\.com\//i, groups: ["C0004"] }, // Bing - C0004 { test: /\/\/bat\.bing\.com\//i, groups: ["C0004"] }, { test: /\/\/clarity\.ms\//i, groups: ["C0004"] }, { test: /\/\/c\.bing\.com\//i, groups: ["C0004"] }, { test: /\/\/www\.bing\.com\/api\//i, groups: ["C0004"] }, // MSN - C0004 { test: /\/\/c\.msn\.com\//i, groups: ["C0004"] }, { test: /\/\/www\.msn\.com\/api\//i, groups: ["C0004"] }, // LinkedIn - C0005 { test: /\/\/snap\.licdn\.com\//i, groups: ["C0005"] }, { test: /\/\/px\.ads\.linkedin\.com\//i, groups: ["C0005"] }, { test: /\/\/www\.linkedin\.com\/px\//i, groups: ["C0005"] }, { test: /\/\/platform\.linkedin\.com\//i, groups: ["C0005"] }, ]; function matchRule(src) { for (var i = 0; i < RULES.length; i++) if (RULES[i].test.test(src)) return RULES[i]; return null; } function hasConsent(req) { var g = (window.OnetrustActiveGroups || "").split(","); return req.every(function (id) { return g.indexOf(id) !== -1; }); } function isMunchkinNode(node) { var src = node.getAttribute("data-gated-src") || node.getAttribute("src") || ""; return /\/\/munchkin\.marketo\.net\//i.test(src); } // --- Restore a blocked script element (preserve attrs + handlers) --- function restoreScript(node) { var replayQ = null; // --- Munchkin-specific handoff: remove stub so real lib can install itself if (isMunchkinNode(node) && window.Munchkin && window.Munchkin.__otStub) { replayQ = window.Munchkin.__q ? window.Munchkin.__q.slice() : null; try { delete window.Munchkin; } catch (e) { window.Munchkin = undefined; } } var s = document.createElement("script"); // copy common attrs [ "src", "async", "defer", "noModule", "crossorigin", "referrerpolicy", "integrity", "nonce", ].forEach(function (a) { var v = node.getAttribute(a); if (v !== null) s.setAttribute(a, v); }); // restore type (module vs classic). If plain, default to classic JS. var t = node.getAttribute("type"); s.type = t && t !== "text/plain" ? t : "text/javascript"; // copy handlers if any were set as properties if (node.onload) s.onload = node.onload; if (node.onerror) s.onerror = node.onerror; if (node.onreadystatechange) s.onreadystatechange = node.onreadystatechange; // inline support (rare for your RULES) if (node.text && !s.src) s.text = node.text; // when real script finishes loading, replay any queued calls if (isMunchkinNode(node) && replayQ) { s.addEventListener("load", function () { if (window.Munchkin && typeof window.Munchkin.init === "function") { replayQ.forEach(function (item) { var method = item[0], args = item[1] || []; if (typeof window.Munchkin[method] === "function") { window.Munchkin[method].apply(window.Munchkin, args); } }); } }); } node.replaceWith(s); } function restoreAllEligible() { // Only restore nodes whose vendor is allowed now var nodes = document.querySelectorAll( 'script.optanon-blocked[type="text/plain"][data-gated-src]' ); for (var i = 0; i < nodes.length; i++) { var n = nodes[i]; var src = n.getAttribute("data-gated-src") || n.getAttribute("src") || ""; var rule = matchRule(src); if (rule && hasConsent(rule.groups)) restoreScript(n); } } // --- Iframe and Video blocking for video platforms --- var IFRAME_RULES = [ { test: /youtube\.com|youtube-nocookie\.com|youtu\.be/i, groups: ["C0003"] }, { test: /vimeo\.com|player\.vimeo\.com/i, groups: ["C0003"] }, { test: /calendly\.com/i, groups: ["C0003"] } ]; var VIDEO_RULES = [ { test: /youtube\.com|youtube-nocookie\.com|youtu\.be/i, groups: ["C0003"] }, { test: /vimeo\.com|player\.vimeo\.com|vimeocdn\.com/i, groups: ["C0003"] }, { test: /wistia\.com|fast\.wistia/i, groups: ["C0003"] }, { test: /brightcove\.com|players\.brightcove/i, groups: ["C0003"] }, { test: /vidyard\.com/i, groups: ["C0003"] }, { test: /jwplayer\.com|jwpcdn\.com/i, groups: ["C0003"] }, { test: /cloudinary\.com/i, groups: ["C0003"] }, { test: /streamable\.com/i, groups: ["C0003"] } ]; function matchIframeRule(src) { for (var i = 0; i < IFRAME_RULES.length; i++) if (IFRAME_RULES[i].test.test(src)) return IFRAME_RULES[i]; return null; } function matchVideoRule(src) { for (var i = 0; i < VIDEO_RULES.length; i++) if (VIDEO_RULES[i].test.test(src)) return VIDEO_RULES[i]; return null; } // Function to create placeholder element function createPlaceholder(type) { var placeholder = document.createElement("div"); placeholder.className = "optanon-video-placeholder"; placeholder.style.cssText = "position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);text-align:center;padding:20px;background:rgba(0,0,0,0.8);color:white;border-radius:5px;z-index:10;"; placeholder.innerHTML = "<p>Book a call</p><p>Please accept cookies to book a call.</p><button onclick='window.OneTrust.ToggleInfoDisplay()' style='margin-top: 15px; padding:12px 24px;background:#E4173F;color:white;border:none;border-radius:24px;cursor:pointer;font-size:16px;cursor:pointer;'>Manage Preferences</button>"; return placeholder; } // Function to block HTML5 video element function blockVideo(video) { var src = video.getAttribute("src") || video.getAttribute("data-src") || ""; // Check all source elements within the video tag var sources = video.querySelectorAll("source"); var needsBlocking = false; var rule = null; // Check main video src if (src) { rule = matchVideoRule(src); if (rule) needsBlocking = true; } // Check source elements for (var i = 0; i < sources.length; i++) { var sourceSrc = sources[i].getAttribute("src") || ""; var sourceRule = matchVideoRule(sourceSrc); if (sourceRule) { needsBlocking = true; rule = sourceRule; break; } } // Also check for third-party video platforms even without explicit rules // This catches self-hosted videos that might still drop cookies if (!needsBlocking && video.hasAttribute("data-require-consent")) { needsBlocking = true; rule = { groups: ["C0003"] }; } if (!needsBlocking) return; if (rule && hasConsent(rule.groups)) return; // Store original sources and block the video video.setAttribute("data-consent-required", rule.groups.join(",")); video.className += (video.className ? " " : "") + "optanon-blocked-video"; // Store and remove sources if (video.src) { video.setAttribute("data-blocked-src", video.src); video.removeAttribute("src"); } // Store source elements data and remove them var sourcesData = []; for (var j = 0; j < sources.length; j++) { sourcesData.push({ src: sources[j].src, type: sources[j].type, media: sources[j].media }); } if (sourcesData.length > 0) { video.setAttribute("data-blocked-sources", JSON.stringify(sourcesData)); // Remove source elements while (video.firstChild) { video.removeChild(video.firstChild); } } // Add placeholder styling video.style.position = "relative"; video.style.backgroundColor = "#f0f0f0"; video.style.minHeight = video.style.height || "315px"; video.style.minWidth = video.style.width || "560px"; // Disable video controls and autoplay video.removeAttribute("autoplay"); video.removeAttribute("controls"); video.setAttribute("data-blocked", "true"); // Create placeholder var placeholder = createPlaceholder("video"); // Position parent if needed if (video.parentElement) { if (video.parentElement.style.position !== "absolute" && video.parentElement.style.position !== "relative") { video.parentElement.style.position = "relative"; } video.parentElement.appendChild(placeholder); video.setAttribute("data-placeholder-id", "optanon-video-placeholder"); } } // Function to restore blocked videos function restoreBlockedVideos() { var videos = document.querySelectorAll("video.optanon-blocked-video"); for (var i = 0; i < videos.length; i++) { var video = videos[i]; var requiredGroups = (video.getAttribute("data-consent-required") || "").split(","); if (hasConsent(requiredGroups)) { // Remove placeholder var placeholder = video.parentElement ? video.parentElement.querySelector(".optanon-video-placeholder") : null; if (placeholder) placeholder.remove(); // Restore main src var blockedSrc = video.getAttribute("data-blocked-src"); if (blockedSrc) { video.src = blockedSrc; video.removeAttribute("data-blocked-src"); } // Restore source elements var sourcesData = video.getAttribute("data-blocked-sources"); if (sourcesData) { var sources = JSON.parse(sourcesData); for (var j = 0; j < sources.length; j++) { var source = document.createElement("source"); source.src = sources[j].src; if (sources[j].type) source.type = sources[j].type; if (sources[j].media) source.media = sources[j].media; video.appendChild(source); } video.removeAttribute("data-blocked-sources"); } // Restore video attributes video.setAttribute("controls", "true"); video.removeAttribute("data-blocked"); video.removeAttribute("data-consent-required"); video.className = video.className.replace("optanon-blocked-video", "").trim(); video.style.backgroundColor = ""; video.style.minHeight = ""; video.style.minWidth = ""; // Reload video video.load(); } } } // Function to block iframe function blockIframe(iframe) { var src = iframe.getAttribute("src") || iframe.getAttribute("data-src") || ""; var rule = matchIframeRule(src); if (!rule) return; // not a targeted iframe if (hasConsent(rule.groups)) return; // consent already granted // Store original src and block the iframe if (iframe.src) { iframe.setAttribute("data-blocked-src", iframe.src); iframe.removeAttribute("src"); } iframe.setAttribute("data-consent-required", rule.groups.join(",")); iframe.className += (iframe.className ? " " : "") + "optanon-blocked-iframe"; // Add placeholder styling iframe.style.backgroundColor = "#f0f0f0"; iframe.style.minHeight = iframe.style.minHeight || "315px"; // Create placeholder message var placeholder = createPlaceholder("video"); // If iframe has parent, add placeholder if (iframe.parentElement && iframe.parentElement.style.position !== "absolute" && iframe.parentElement.style.position !== "relative") { iframe.parentElement.style.position = "relative"; } if (iframe.parentElement) { iframe.parentElement.appendChild(placeholder); iframe.setAttribute("data-placeholder-id", placeholder.className); } } // Function to restore blocked iframes function restoreBlockedIframes() { var iframes = document.querySelectorAll("iframe.optanon-blocked-iframe"); for (var i = 0; i < iframes.length; i++) { var iframe = iframes[i]; var blockedSrc = iframe.getAttribute("data-blocked-src"); var requiredGroups = (iframe.getAttribute("data-consent-required") || "").split(","); if (blockedSrc && hasConsent(requiredGroups)) { // Remove placeholder var placeholder = iframe.parentElement ? iframe.parentElement.querySelector(".optanon-video-placeholder") : null; if (placeholder) placeholder.remove(); // Restore iframe iframe.src = blockedSrc; iframe.removeAttribute("data-blocked-src"); iframe.removeAttribute("data-consent-required"); iframe.className = iframe.className.replace("optanon-blocked-iframe", "").trim(); iframe.style.backgroundColor = ""; iframe.style.minHeight = ""; } } } // Override createElement to catch dynamically created iframes var originalCreateElement = document.createElement; document.createElement = function(tagName) { var element = originalCreateElement.call(document, tagName); if (tagName.toLowerCase() === "iframe") { // Use setter to intercept src assignment var srcDescriptor = Object.getOwnPropertyDescriptor(element, "src") || Object.getOwnPropertyDescriptor(HTMLIFrameElement.prototype, "src"); Object.defineProperty(element, "src", { get: function() { return this.getAttribute("src"); }, set: function(value) { var rule = matchIframeRule(value); if (rule && !hasConsent(rule.groups)) { this.setAttribute("data-blocked-src", value); this.className += (this.className ? " " : "") + "optanon-blocked-iframe"; this.setAttribute("data-consent-required", rule.groups.join(",")); } else { srcDescriptor.set.call(this, value); } }, configurable: true }); } return element; }; // Hook DOM insertions for iframes and videos ["appendChild", "insertBefore", "replaceChild"].forEach(function (m) { var orig = Node.prototype[m]; Node.prototype[m] = function (child) { if (child) { if (child.tagName === "IFRAME") { try { blockIframe(child); } catch (e) {} } else if (child.tagName === "VIDEO") { try { blockVideo(child); } catch (e) {} } } var result = orig.apply(this, arguments); // Also check after insertion in case src is set after adding to DOM if (child) { if (child.tagName === "IFRAME") { setTimeout(function() { blockIframe(child); }, 0); } else if (child.tagName === "VIDEO") { setTimeout(function() { blockVideo(child); }, 0); } } return result; }; }); // Monitor existing iframes and videos on page load function blockExistingMedia() { var iframes = document.querySelectorAll("iframe"); for (var i = 0; i < iframes.length; i++) { blockIframe(iframes[i]); } var videos = document.querySelectorAll("video"); for (var j = 0; j < videos.length; j++) { blockVideo(videos[j]); } } // MutationObserver for iframes and videos added via innerHTML or other methods var mediaObserver = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { mutation.addedNodes.forEach(function(node) { if (node.tagName === "IFRAME") { blockIframe(node); } else if (node.tagName === "VIDEO") { blockVideo(node); } // Check for iframes and videos in added subtree if (node.querySelectorAll) { var iframes = node.querySelectorAll("iframe"); for (var i = 0; i < iframes.length; i++) { blockIframe(iframes[i]); } var videos = node.querySelectorAll("video"); for (var j = 0; j < videos.length; j++) { blockVideo(videos[j]); } } }); }); }); // Start observing when DOM is ready if (document.body) { mediaObserver.observe(document.body, { childList: true, subtree: true }); blockExistingMedia(); } else { document.addEventListener("DOMContentLoaded", function() { mediaObserver.observe(document.body, { childList: true, subtree: true }); blockExistingMedia(); }); } // --- Block Bizible/Marketo pixel tracking images --- function blockTrackingPixels() { // Block img elements that are tracking pixels var images = document.querySelectorAll('img'); images.forEach(function(img) { var src = img.src || img.getAttribute('src') || ''; if (src.includes('bizible.com') || src.includes('bizibly.com') || src.includes('adobedc.net')) { if (!hasConsent(['C0004'])) { img.setAttribute('data-blocked-src', src); img.removeAttribute('src'); img.style.display = 'none'; } } }); } // Monitor for tracking pixels var pixelObserver = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { mutation.addedNodes.forEach(function(node) { if (node.tagName === 'IMG') { var src = node.src || node.getAttribute('src') || ''; if (src.includes('bizible.com') || src.includes('bizibly.com') || src.includes('adobedc.net')) { if (!hasConsent(['C0004'])) { node.setAttribute('data-blocked-src', src); node.removeAttribute('src'); node.style.display = 'none'; } } } }); }); }); if (document.body) { pixelObserver.observe(document.body, { childList: true, subtree: true }); blockTrackingPixels(); } // --- Handle custom video implementations with click-to-load --- function interceptVideoButtons() { // Find all elements that look like they'll load a video on click var videoContainers = document.querySelectorAll('.js-video[data-video-url], .video[data-video-url]'); videoContainers.forEach(function(container) { var videoUrl = container.getAttribute('data-video-url'); if (!videoUrl) return; // Check if this is a YouTube or Vimeo URL that needs consent var needsConsent = false; var requiredGroups = []; if (/youtube\.com|youtu\.be/.test(videoUrl)) { needsConsent = true; requiredGroups = ["C0003"]; } else if (/vimeo\.com/.test(videoUrl)) { needsConsent = true; requiredGroups = ["C0003"]; } if (!needsConsent || hasConsent(requiredGroups)) return; // Find the play button within this container var playButton = container.querySelector('.js-videoPlay, button[type="button"]'); if (!playButton) return; // Store original click handler if it exists var originalOnclick = playButton.onclick; playButton.setAttribute('data-consent-required', requiredGroups.join(',')); playButton.setAttribute('data-original-video-url', videoUrl); // Replace click handler with consent check playButton.onclick = function(e) { e.preventDefault(); e.stopPropagation(); if (hasConsent(requiredGroups)) { // Restore original behavior if consent granted if (originalOnclick) { originalOnclick.call(this, e); } else { // Try to trigger the video load manually if no onclick was stored this.click(); } } else { // Show consent modal showVideoConsentModal(container, requiredGroups); } return false; }; // Also intercept addEventListener for this button var originalAddEventListener = playButton.addEventListener; playButton.addEventListener = function(type, listener, options) { if (type === 'click') { // Wrap the click listener var wrappedListener = function(e) { if (!hasConsent(requiredGroups)) { e.preventDefault(); e.stopPropagation(); showVideoConsentModal(container, requiredGroups); return false; } return listener.call(this, e); }; originalAddEventListener.call(this, type, wrappedListener, options); } else { originalAddEventListener.call(this, type, listener, options); } }; }); } // Function to show consent modal for custom video implementations function showVideoConsentModal(container, requiredGroups) { // Check if modal already exists var existingModal = container.querySelector('.optanon-video-consent-modal'); if (existingModal) { existingModal.style.display = 'block'; return; } // Create consent modal overlay var modal = document.createElement('div'); modal.className = 'optanon-video-consent-modal'; modal.style.cssText = 'position:absolute;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.7);display:flex;align-items:center;justify-content:center;z-index:1000;'; var modalContent = document.createElement('div'); modalContent.style.cssText = 'background:white;padding:30px;border-radius:8px;text-align:center;max-width:400px; margin: 10% auto;'; modalContent.innerHTML = '<h3 style="margin:0 0 15px 0;color:#11111;">Cookie consent required</h3>' + '<p style="margin:0 0 20px 0;color:#11111;">This video requires your consent to load content from third-party providers.</p>' + '<button onclick="window.OneTrust.ToggleInfoDisplay()" style="padding:12px 24px;background:#E4173F;color:white;border:none;border-radius:24px;cursor:pointer;font-size:16px;margin-right:10px;">Manage preferences</button>' + '<button onclick="this.closest(\'.optanon-video-consent-modal\').style.display=\'none\'" style="padding:12px 24px;background:#F7F7F7;color:#11111;border:none;border-radius:24px;cursor:pointer;font-size:16px;">Cancel</button>'; modal.appendChild(modalContent); container.style.position = 'relative'; container.appendChild(modal); } // Re-check video buttons after consent changes function recheckVideoButtons() { var buttons = document.querySelectorAll('[data-consent-required]'); buttons.forEach(function(button) { var requiredGroups = (button.getAttribute('data-consent-required') || '').split(','); if (hasConsent(requiredGroups)) { // Remove consent modal if it exists var container = button.closest('.js-video, .video'); if (container) { var modal = container.querySelector('.optanon-video-consent-modal'); if (modal) modal.remove(); } } }); } // Initialize video button interception if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', function() { setTimeout(interceptVideoButtons, 100); // Small delay to ensure other scripts have initialized }); } else { setTimeout(interceptVideoButtons, 100); } // Re-run interception periodically to catch dynamically added videos setInterval(interceptVideoButtons, 2000); // --- Hook DOM insertions for dynamically-added scripts (your original bit) --- function handleScript(node) { var src = node.getAttribute("src") || ""; var rule = matchRule(src); if (!rule) return; // not targeted if (hasConsent(rule.groups)) return; // consent already granted node.setAttribute("data-gated-src", src); node.type = "text/plain"; node.className += (node.className ? " " : "") + "optanon-blocked"; } ["appendChild", "insertBefore"].forEach(function (m) { var orig = Node.prototype[m]; Node.prototype[m] = function (child) { if (child && child.tagName === "SCRIPT") { try { handleScript(child); } catch (e) {} } return orig.apply(this, arguments); }; }); // --- NEW: Patch document.write / writeln (covers your example) --- function gateHtml(html) { // normalize (strip surrounding whitespace) var s = String(html); // Find <script ... src="..."> and if URL matches a RULE without consent, // rewrite to type="text/plain" and mark for later restore. // This regex is intentionally simple; it handles typical cases. return s.replace( /<script\b([^>]*?)\bsrc\s*=\s*(['"])([^'"]+)\2([^>]*)>(?:<\/script>)?/gi, function (_m, pre, q, src, post) { var rule = matchRule(src || ""); if (!rule || hasConsent(rule.groups)) return _m; // leave as-is // ensure we keep original attrs, add our markers, and suppress execution var attrs = (pre || "") + " src=" + q + src + q + (post || ""); // remove existing type if present; we'll set text/plain attrs = attrs.replace(/\btype\s*=\s*(['"])[^'"]*\1/gi, ""); attrs += ' type="text/plain" class="optanon-blocked" data-gated-src="' + src.replace(/"/g, "&quot;") + '"'; return "\<script " + attrs + "\>\<\/script\>"; } ); } ["write", "writeln"].forEach(function (m) { var orig = document[m]; document[m] = function () { // Join arguments (browsers allow multiple) var html = Array.prototype.join.call(arguments, ""); var gated = gateHtml(html); return orig.call(document, gated); }; }); // Cookie blocking - Enhanced to catch iframe cookies const originalCookieDescriptor = Object.getOwnPropertyDescriptor(Document.prototype, 'cookie'); // Block postMessage from YouTube iframes before consent const originalPostMessage = window.postMessage; window.postMessage = function(message, targetOrigin) { if (targetOrigin && targetOrigin.includes('youtube.com') && !hasConsent(['C0003'])) { return; } return originalPostMessage.apply(this, arguments); }; const cookiePatterns = { C0003: [ // VWO cookies /_vwo/, // YouTube cookies - more comprehensive patterns /^YSC/, /^VISITOR_INFO/, /^VISITOR_PRIVACY/, /^PREF/, /^GPS/, /^CONSENT/, /_Secure-ROLLOUT/, /^LOGIN_INFO/, /^SIDCC/, /^SSID/, /^APISID/, /^SAPISID/, /^HSID/, /^SID/, /^DEVICE_INFO/, /^CONSISTENCY/, /^use_hitbox/, /^remote_sid/, // Vimeo cookies /^vuid/, /^player/, /^_abexps/, /^_gcl/, /^continuous_play/, /^has_logged_in/, // Calendly cookies (removed GA cookies as they're handled in GTM) /_calendly/, /^calendly/ ], C0004: [ // Existing patterns /gaconnector/, /_biz/, /_vis/, // Marketo/Bizible cookies - more comprehensive (includes _BUID) /_BUID/, /^_BUID$/, /^_biz_uid/, /^_biz_nA/, /^_biz_pendingA/, /^_biz_sid/, /^_biz_flagsA/, /^mkto_/, /^_mkto_trk/, /^_mkt_disp/, /^_mkt_trk/, // HubSpot cookies /__hs/, /hubspot/, /__hst/, /__hsc/, /__hssc/, /__hssrc/, // Bing cookies /_uet/, /MUID/, /_clck/, /_clsk/, // MSN cookies (often shared with Bing) /MSN/ ], C0005: [ // LinkedIn cookies /^li_/, /^lidc/, /^bcookie/, /^bscookie/, /^lang/, /^UserMatchHistory/, /^AnalyticsSyncHistory/ ] }; Object.defineProperty(Document.prototype, 'cookie', { get: function() { return originalCookieDescriptor.get.call(this); }, set: function(value) { const cookieName = value.split('=')[0].trim(); // Allow OneTrust cookies if (cookieName.startsWith('OptAnon')) { return originalCookieDescriptor.set.call(this, value); } // Allow all Cloudflare security cookies regardless of domain if (cookieName === '__cf_bm' || cookieName === '_cf_bm') { return originalCookieDescriptor.set.call(this, value); } // Check against patterns for (const category in cookiePatterns) { if (!hasConsent([category])) { for (const pattern of cookiePatterns[category]) { if (pattern.test(cookieName)) { return; } } } } return originalCookieDescriptor.set.call(this, value); }, configurable: true }); // --- Consent change: restore anything now allowed --- window.addEventListener("OneTrustGroupsUpdated", function() { restoreAllEligible(); restoreBlockedIframes(); restoreBlockedVideos(); recheckVideoButtons(); }); // Optional: if your snippet might run after some writes already happened // scan current DOM once: document.querySelectorAll("script[src]").forEach(function (n) { try { handleScript(n); } catch (e) {} }); restoreAllEligible(); // --- OPTIONAL SAFETY: stub Munchkin to avoid ReferenceError before load --- // This lets inline `Munchkin.init('302-WOS-863')` run without crashing. // The real library will overwrite this when allowed; you can replay if needed. (function () { if (!window.Munchkin) { var MK = function () {}; // placeholder MK.__otStub = true; // mark as our stub MK.__q = []; // queue MK.init = function () { MK.__q.push(["init", Array.prototype.slice.call(arguments)]); }; window.Munchkin = MK; } })(); })(); function OptanonWrapper() { } </script> <!-- OneTrust Cookies Consent Notice end for lightyear.cloud --> Inspire Learning Trust Cuts Reconciliation Time From Hours to Minutes
Free trial

Inspire Learning Trust Cuts Reconciliation Time From Hours to Minutes

Inspire Learning Trust is a multi-academy trust based in Rotherham, supporting students across all key stages of education. The Trust brings together a sixth form college, two secondary schools, and a junior primary school, creating a seamless learning journey for students from their early years through to further education. With a focus on community, collaboration, and high standards, Inspire Learning Trust is committed to providing every student with the support, skills, and opportunities they need to thrive both in the classroom and beyond. 

With multiple sites, managing the volume of invoices and supplier data across the Trust became increasingly time-consuming. Time-consuming invoice processing and duplicates slipping in prompted the team to look for an AP automation solution that could streamline their processes and integrate seamlessly with their existing accounting system, Sage 200.

Marked Down for Duplication

David Hodgson, the Trust's Strategic Lead, explained that before implementing Lightyear, when invoices were received via email, the team had to manually download and attach each one before entering the details into Sage.

"When invoices came into our inbox, at that stage, the team had to download and prepare the invoices manually, which could take hours, or even days."

Another major challenge for the finance team was managing duplicate invoices. This added further unnecessary administrative burden.

"One of the biggest issues we faced was the risk of duplicate invoices coming in without us spotting them. We had to monitor the folder to make sure everything was captured constantly. Also, when statements were coming in, somebody had to manually check all those statements to make sure that there wasn't anything missing."

The team adopted Lightyear as their AP automation solution to eliminate these challenges and process invoices faster.

My team used to spend 3 hours a month managing statements. Now, that's been reduced to about 10 minutes.

Top of the Class Technology

We explored three or four other providers before deciding on Lightyear. For me, the two key reasons were the pricing and the features. Lightyear gave us the flexibility and value we were looking for."

David explained why the Lightyear AP automation solution perfectly fits the Trust.

"Once you’ve taught the system, which is like teaching a five-year-old to read and do maths. It just gets it. Now I can look at it and think, ‘There’s nothing I need to do here.’ It’s taken the headache out of chasing invoice numbers and dates."

David further elaborated that implementing Lightyear helped them avoid double payments as the system automatically flags duplicate invoices.

"We had a statement from Amazon come through with invoices we’d accidentally paid twice, and it took quite a while to sort it out, especially with how frequently we use Amazon across all four sites. Now, thanks to Lightyear, invoices are flagged automatically if there’s a duplicate, so it’s really easy to spot and avoid double payments."

The statement section has become almost minimal for us compared to what it used to be.

Reconciling Statements Went From 3 Hours to 10 Minutes

"My team was spending around 3 hours a month managing supplier statements, and we were getting about 84 each month. Now, that’s been brought down to about 10 minutes each month. We are also able to see straight away what's missing and what's not. The statement section has become almost minimal for us compared to what it used to be."

Alongside time savings, David explained how the Lightyear platform has made it easier for the team to support each other during staff absences.

"The system helped us cover for Nicci while she was on leave, without overwhelming the team. It’s user-friendly, much cleaner, and now that she’s back, smiling, it’s clear how much time it’s saving her to focus on more important things."

When asked what advice David would give someone looking at Lightyear for AP automation, he said:

"I'd definitely say go for it, but be prepared to put the work in upfront. The more you invest at the start, the better the results. Clean up your suppliers, nominals, and systems first because it makes the transition to automation much smoother.”

See what our other customers say about Lightyear

Get started with Lightyear today and see how AP automation can help you save time and costs.

Recognised As An Industry Leader