• Link to LinkedIn
☎   +32 2 7171064     âœ‰   info@datalumen.eu
Datalumen
  • Services
      • Advisory Services
      • Implementation Services
      • Managed Services
      • Training
  • Solutions
      • Business Glossaries & Data Catalogs
      • Data Quality & Data Observability
      • Data Virtualization
      • Master Data Management
      • Data Privacy Solutions
  • Careers
  • Insights
  • About
  • Contact
  • Click to open the search input field Click to open the search input field Search
  • Menu Menu

OPENLINEAGE: UNVEILING DATA LINEAGE FOR MODERN DATA ECOSYSTEMS

29/08/2024/by Datalumen

Understanding the journey of data from its source to its final destination is crucial for businesses and organizations. This journey, known as data lineage, has become increasingly complex with the proliferation of data sources, transformation processes, and analytical tools. Enter OpenLineage, an open-source standard that aims to simplify and standardize data lineage tracking across diverse data ecosystems.

What is data lineage?

Data lineage is the process of tracing the journey of data from its origin to its destination, tracking every transformation, processing step, and the tools or systems it interacts with along the way. With data flowing through increasingly complex architectures, the ability to accurately map and understand these movements is vital for ensuring data quality, compliance, and operational efficiency.

However, tracking data lineage is no small feat, especially with the explosion of data sources, analytics platforms, and transformation tools that make up modern data stacks.


What is OpenLineage?

OpenLineage is an open standard for data lineage collection and analysis. Initiated by Datakin and now part of the Linux Foundation, OpenLineage provides a set of standardized definitions and APIs that allow different tools and platforms in the data ecosystem to share lineage metadata in a consistent format.

The primary goal of OpenLineage is to create a unified approach to collecting and utilizing data lineage information. By establishing a common language for data lineage, OpenLineage enables better interoperability between various data tools, platforms, and processes.


Key Components of OpenLineage

  1. OpenLineage Specification: This defines the core concepts and data model for representing lineage metadata. It includes definitions for jobs, datasets, runs, and the relationships between them.
  2. Integration Libraries: OpenLineage provides libraries and SDKs for popular data processing frameworks like Apache Spark, Apache Airflow, and dbt. These integrations allow developers to easily instrument their data pipelines to emit lineage events.
  3. API: The OpenLineage API defines how lineage events should be structured and transmitted. This standardization ensures that all tools speaking the OpenLineage language can understand and process lineage data consistently.
  4. Facets: These are extensible metadata attributes that can be attached to core OpenLineage entities, allowing for custom metadata to be included in lineage information.



Why should I care about this?

Standardization and InteroperabilityOne of the most significant advantages of OpenLineage is its ability to standardize lineage data across different tools and platforms. This standardization enables seamless integration between various components of a data stack, from data ingestion tools to transformation engines and analytics platforms. As a result, organizations can build a comprehensive view of their data lineage without being locked into a single vendor or tool.
Enhanced Data Governance and ComplianceWith the increasing importance of data privacy regulations like GDPR and the AI Act, understanding data lineage is crucial for compliance. OpenLineage makes it easier to track the flow of sensitive data across systems, helping organizations ensure that data is handled in accordance with regulatory requirements. This comprehensive lineage information also aids in auditing processes and demonstrating compliance to regulatory bodies.
Improved TrustBy providing visibility into the entire data pipeline, OpenLineage helps data teams identify and resolve data quality issues more efficiently. When inconsistencies or errors are discovered, teams can quickly trace the problem back to its source, understanding all the transformations and processes the data has undergone. This transparency builds trust in the data and the insights derived from it.
Efficient Troubleshooting and DebuggingWhen issues arise in data pipelines or analytics, OpenLineage’s detailed lineage information becomes invaluable. Data engineers and analysts can trace the path of data through various systems, identifying where problems may have occurred. This capability significantly reduces the time and effort required for troubleshooting, leading to faster resolution of data-related issues.
Support for Data Cataloging and Metadata ManagementOpenLineage integrates seamlessly with data catalogs and metadata management tools. By providing rich lineage information, it enhances the capabilities of these tools, allowing for more comprehensive documentation of data assets. This integration supports better data discovery, understanding, and utilization across the organization.

Conclusion

OpenLineage represents a significant step forward in the field of data lineage and metadata management. By providing a standardized, open-source approach to tracking data lineage, it addresses many of the challenges faced by modern data-driven organizations. From improving data governance and quality to enhancing troubleshooting capabilities and fostering collaboration, OpenLineage offers a wide range of benefits.

As data ecosystems continue to grow in complexity, tools like OpenLineage will become increasingly crucial. Organizations that adopt OpenLineage can expect to gain a competitive edge through better data management, increased efficiency, and improved data-driven decision-making capabilities.

The open nature of the project ensures that it will continue to evolve and improve, driven by the needs of the data community. As more tools and platforms adopt the OpenLineage standard, we can expect to see even greater interoperability and capabilities in the future of data lineage tracking.

 

 

 

CONTACT US

Need expert support with your data agenda? Discover how Datalumen can help you. 

Contact us and start our data conversation




Tags: Data Compliancy, Data Governance, Data Lineage, Data Pipeline Monitoring, Metadata Management, OpenLineage
Share this entry
  • Share on Facebook
  • Share on X
  • Share on WhatsApp
  • Share on LinkedIn
  • Share by Mail
https://www.datalumen.eu/wp-content/uploads/2024/09/Datalumen_Openlineage_What_Why_Benefits-scaled.jpg 1472 2560 Datalumen https://www.datalumen.eu/wp-content/uploads/2019/06/datalumen_color_V1.1-340-156B.png Datalumen2024-08-29 11:01:292024-09-11 11:01:49OPENLINEAGE: UNVEILING DATA LINEAGE FOR MODERN DATA ECOSYSTEMS
You might also like
AGILE DATA GOVERNANCE – THE SMART WAY TO UPGRADE YOUR DATA DYNAMICS?
THE GDPR BUSINESS VALUE ROADMAP
ESTABLISHING ROBUST DATA LITERACY – FROM AWARENESS TO ACTION
NIS2 & DATA GOVERNANCE: THE DYNAMIC DUO TO PUT SOME MUSIC IN YOUR CYBERSECURITY
Change & Data Governance Picture by Akil Mazumder via Pexels CHANGE & DATA GOVERNANCE – TAKE A LEAP FORWARD
THE HIDDEN COST OF CUTTING CORNERS: UNDERSTANDING TECHNICAL DEBT IN DATA MANAGEMENT
AUGMENTED DATA QUALITY: AN AI-FUELED APPROACH FOR YOUR DATA ZEN MOMENT
DECODING YOUR DATA LANDSCAPE: UNDERSTANDING BUSINESS AND TECHNICAL DATA ARCHITECTURE FOR EFFECTIVE DATA GOVERNANCE

Recent Posts

  • UNLOCKING AI’S POTENTIAL: KEY TAKEAWAYS FROM THE GARTNER DATA & ANALYTICS SUMMIT 2025
  • DECODING YOUR DATA LANDSCAPE: UNDERSTANDING BUSINESS AND TECHNICAL DATA ARCHITECTURE FOR EFFECTIVE DATA GOVERNANCE
  • THE HIDDEN COST OF CUTTING CORNERS: UNDERSTANDING TECHNICAL DEBT IN DATA MANAGEMENT
  • WHAT YOU SHOULD KNOW BEFORE IMPLEMENTING A DATA CATALOG
  • NIS2 & DATA GOVERNANCE: THE DYNAMIC DUO TO PUT SOME MUSIC IN YOUR CYBERSECURITY

Topics

Search Search

+32 2 7171064

info@datalumen.eu

Spark your data with our newsletter!

Services

Advisory
Implementation Services
Managed Services
Training

Solutions

Master Data Management
Business Glossaries & Data Catalogs
Data Quality & Observability
Data Virtualization
Data Protection

About Us

Insights
Careers
Customers
Partners


Company details
Privacy Policy
Cookie Policy

Manage your cookies

© Datalumen NV
Link to: ESTABLISHING ROBUST DATA LITERACY – FROM AWARENESS TO ACTION Link to: ESTABLISHING ROBUST DATA LITERACY – FROM AWARENESS TO ACTION ESTABLISHING ROBUST DATA LITERACY – FROM AWARENESS TO ACTION Link to: UNLOCK REAL-TIME DATA TRUST – LAUNDERING DATA FOR QUALITY AND OBSERVABILITY WITH COLLIBRA & SAP Link to: UNLOCK REAL-TIME DATA TRUST – LAUNDERING DATA FOR QUALITY AND OBSERVABILITY WITH COLLIBRA & SAP UNLOCK REAL-TIME DATA TRUST – LAUNDERING DATA FOR QUALITY AND OBSERVABILITY...
Scroll to top Scroll to top Scroll to top
The choice is yours

Your privacy is important & we are committed to being transparent. By continuing to browse the site, you are agreeing to our use of cookies. To provide the best experiences, we use technologies like cookies to store and/or access device information. 

Functional Always active
The technical storage or access is strictly necessary for the legitimate purpose of enabling the use of a specific service explicitly requested by the subscriber or user, or for the sole purpose of carrying out the transmission of a communication over an electronic communications network.
Preferences
The technical storage or access is necessary for the legitimate purpose of storing preferences that are not requested by the subscriber or user.
Statistics
The technical storage or access that is used exclusively for statistical purposes. The technical storage or access that is used exclusively for anonymous statistical purposes. Without a subpoena, voluntary compliance on the part of your Internet Service Provider, or additional records from a third party, information stored or retrieved for this purpose alone cannot usually be used to identify you.
Marketing
The technical storage or access is required to create user profiles to send advertising, or to track the user on a website or across several websites for similar marketing purposes.
  • Manage options
  • Manage services
  • Manage {vendor_count} vendors
  • Read more about these purposes
Customize preferences
  • {title}
  • {title}
  • {title}
×
@import url(https://fonts.bunny.net/css?family=ibm-plex-sans:400,600); #_form_15_{font-size:14px;line-height:1.6;font-family:arial, helvetica, sans-serif;margin:0}#_form_15_ *{outline:0}._form_hide{display:none;visibility:hidden}._form_show{display:block;visibility:visible}#_form_15_._form-top{top:0}#_form_15_._form-bottom{bottom:0}#_form_15_._form-left{left:0}#_form_15_._form-right{right:0}#_form_15_ input[type="text"],#_form_15_ input[type="tel"],#_form_15_ input[type="date"],#_form_15_ textarea{padding:6px;height:auto;border:#979797 1px solid;border-radius:4px;color:#000000 !important;font-size:14px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}#_form_15_ textarea{resize:none}#_form_15_ ._submit{-webkit-appearance:none;cursor:pointer;font-family:arial, sans-serif;font-size:14px;text-align:center;background:#030303 !important;border:0 !important;-moz-border-radius:4px !important;-webkit-border-radius:4px !important;border-radius:4px !important;color:#FFFFFF !important;padding:10px !important}#_form_15_ ._submit:disabled{cursor:not-allowed;opacity:0.4}#_form_15_ ._submit.processing{position:relative}#_form_15_ ._submit.processing::before{content:"";width:1em;height:1em;position:absolute;z-index:1;top:50%;left:50%;border:double 3px transparent;border-radius:50%;background-image:linear-gradient(#030303, #030303), conic-gradient(#030303, #FFFFFF);background-origin:border-box;background-clip:content-box, border-box;animation:1200ms ease 0s infinite normal none running _spin}#_form_15_ ._submit.processing::after{content:"";position:absolute;top:0;bottom:0;left:0;right:0;background:#030303 !important;border:0 !important;-moz-border-radius:4px !important;-webkit-border-radius:4px !important;border-radius:4px !important;color:#FFFFFF !important;padding:10px !important}@keyframes _spin{0%{transform:translate(-50%, -50%) rotate(90deg)}100%{transform:translate(-50%, -50%) rotate(450deg)}}#_form_15_ ._close-icon{cursor:pointer;background-image:url("https://d226aj4ao1t61q.cloudfront.net/esfkyjh1u_forms-close-dark.png");background-repeat:no-repeat;background-size:14.2px 14.2px;position:absolute;display:block;top:11px;right:9px;overflow:hidden;width:16.2px;height:16.2px}#_form_15_ ._close-icon:before{position:relative}#_form_15_ ._form-body{margin-bottom:30px}#_form_15_ ._form-image-left{width:150px;float:left}#_form_15_ ._form-content-right{margin-left:164px}#_form_15_ ._form-branding{color:#fff;font-size:10px;clear:both;text-align:left;margin-top:30px;font-weight:100}#_form_15_ ._form-branding ._logo{display:block;width:130px;height:14px;margin-top:6px;background-image:url("https://d226aj4ao1t61q.cloudfront.net/hh9ujqgv5_aclogo_li.png");background-size:130px auto;background-repeat:no-repeat}#_form_15_ .form-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}#_form_15_ ._form-label,#_form_15_ ._form_element ._form-label{font-weight:bold;margin-bottom:5px;display:block}#_form_15_._dark ._form-branding{color:#333}#_form_15_._dark ._form-branding ._logo{background-image:url("https://d226aj4ao1t61q.cloudfront.net/jftq2c8s_aclogo_dk.png")}#_form_15_ ._form_element{position:relative;margin-bottom:10px;font-size:0;max-width:100%}#_form_15_ ._form_element *{font-size:14px}#_form_15_ ._form_element._clear{clear:both;width:100%;float:none}#_form_15_ ._form_element._clear:after{clear:left}#_form_15_ ._form_element input[type="text"],#_form_15_ ._form_element input[type="date"],#_form_15_ ._form_element select,#_form_15_ ._form_element textarea:not(.g-recaptcha-response){display:block;width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;font-family:inherit}#_form_15_ ._field-wrapper{position:relative}#_form_15_ ._inline-style{float:left}#_form_15_ ._inline-style input[type="text"]{width:150px}#_form_15_ ._inline-style:not(._clear)+._inline-style:not(._clear){margin-left:20px}#_form_15_ ._form_element img._form-image{max-width:100%}#_form_15_ ._form_element ._form-fieldset{border:0;padding:0.01em 0 0 0;margin:0;min-width:0}#_form_15_ ._clear-element{clear:left}#_form_15_ ._full_width{width:100%}#_form_15_ ._form_full_field{display:block;width:100%;margin-bottom:10px}#_form_15_ input[type="text"]._has_error,#_form_15_ textarea._has_error{border:#F37C7B 1px solid}#_form_15_ input[type="checkbox"]._has_error{outline:#F37C7B 1px solid}#_form_15_ ._error{display:block;position:absolute;font-size:14px;z-index:10000001}#_form_15_ ._error._above{padding-bottom:4px;bottom:39px;right:0}#_form_15_ ._error._below{padding-top:8px;top:100%;right:0}#_form_15_ ._error._above ._error-arrow{bottom:-4px;right:15px;border-left:8px solid transparent;border-right:8px solid transparent;border-top:8px solid #FFDDDD}#_form_15_ ._error._below ._error-arrow{top:0;right:15px;border-left:8px solid transparent;border-right:8px solid transparent;border-bottom:8px solid #FFDDDD}#_form_15_ ._error-inner{padding:12px 12px 12px 36px;background-color:#FFDDDD;background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M16 8C16 12.4183 12.4183 16 8 16C3.58172 16 0 12.4183 0 8C0 3.58172 3.58172 0 8 0C12.4183 0 16 3.58172 16 8ZM9 3V9H7V3H9ZM9 13V11H7V13H9Z' fill='%23CA0000'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:12px center;font-size:14px;font-family:arial, sans-serif;font-weight:600;line-height:16px;color:#000;text-align:center;text-decoration:none;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;box-shadow:0px 1px 4px rgba(31, 33, 41, 0.298295)}#_form_15_ ._error-inner._form_error{margin-bottom:5px;text-align:left}#_form_15_ ._button-wrapper ._error-inner._form_error{position:static}#_form_15_ ._error-inner._no_arrow{margin-bottom:10px}#_form_15_ ._error-arrow{position:absolute;width:0;height:0}#_form_15_ ._error-html{margin-bottom:10px}.pika-single{z-index:10000001 !important}#_form_15_ input[type="text"].datetime_date{width:69%;display:inline}#_form_15_ select.datetime_time{width:29%;display:inline;height:32px}#_form_15_ input[type="date"].datetime_date{width:69%;display:inline-flex}#_form_15_ input[type="time"].datetime_time{width:29%;display:inline-flex}@media (min-width:320px) and (max-width:667px){::-webkit-scrollbar{display:none}#_form_15_{margin:0;width:100%;min-width:100%;max-width:100%;box-sizing:border-box}#_form_15_ *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;font-size:1em}#_form_15_ ._form-content{margin:0;width:100%}#_form_15_ ._form-inner{display:block;min-width:100%}#_form_15_ ._form-title,#_form_15_ ._inline-style{margin-top:0;margin-right:0;margin-left:0}#_form_15_ ._form-title{font-size:1.2em}#_form_15_ ._form_element{margin:0 0 20px;padding:0;width:100%}#_form_15_ ._form-element,#_form_15_ ._inline-style,#_form_15_ input[type="text"],#_form_15_ label,#_form_15_ p,#_form_15_ textarea:not(.g-recaptcha-response){float:none;display:block;width:100%}#_form_15_ ._row._checkbox-radio label{display:inline}#_form_15_ ._row,#_form_15_ p,#_form_15_ label{margin-bottom:0.7em;width:100%}#_form_15_ ._row input[type="checkbox"],#_form_15_ ._row input[type="radio"]{margin:0 !important;vertical-align:middle !important}#_form_15_ ._row input[type="checkbox"]+span label{display:inline}#_form_15_ ._row span label{margin:0 !important;width:initial !important;vertical-align:middle !important}#_form_15_ ._form-image{max-width:100%;height:auto !important}#_form_15_ input[type="text"]{padding-left:10px;padding-right:10px;font-size:16px;line-height:1.3em;-webkit-appearance:none}#_form_15_ input[type="radio"],#_form_15_ input[type="checkbox"]{display:inline-block;width:1.3em;height:1.3em;font-size:1em;margin:0 0.3em 0 0;vertical-align:baseline}#_form_15_ button[type="submit"]{padding:20px;font-size:1.5em}#_form_15_ ._inline-style{margin:20px 0 0 !important}}#_form_15_{position:relative;text-align:left;margin:25px auto 0;padding-top:20px;padding-right:20px;padding-bottom:20px;padding-left:20px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;background:#FFFFFF !important;border:0px solid #B0B0B0 !important;max-width:500px;-moz-border-radius:0px !important;-webkit-border-radius:0px !important;border-radius:0px !important;color:#000000}#_form_15_._inline-form,#_form_15_._inline-form ._form-content{font-family:"IBM Plex Sans", Helvetica, sans-serif}#_form_15_._inline-form ._row span,#_form_15_._inline-form ._row label{font-family:"IBM Plex Sans", Helvetica, sans-serif;font-size:14px;font-weight:400;line-height:1.6em}#_form_15__inlineform input[type="text"],#_form_15__inlineform input[type="date"],#_form_15__inlineform input[type="tel"],#_form_15__inlineform select,#_form_15__inlineform textarea:not(.g-recaptcha-response){font-family:"IBM Plex Sans", Helvetica, sans-serif;font-size:14px;font-weight:400;font-color:#000000;line-height:1.6em}#_form_15_._inline-form ._html-code *:not(h1, h2, h3, h4, h5, h6),#_form_15_._inline-form ._form-thank-you{font-family:"IBM Plex Sans", Helvetica, sans-serif}#_form_15_._inline-form ._form-label,#_form_15_._inline-form ._form-emailidentifier,#_form_15_._inline-form ._form-checkbox-option-label{font-family:"IBM Plex Sans", Helvetica, sans-serif;font-size:14px;font-weight:700;line-height:1.6em}#_form_15_._inline-form ._submit{margin-top:12px;font-family:"IBM Plex Sans", Helvetica, sans-serif}#_form_15_._inline-form ._html-code h1,#_form_15_._inline-form ._html-code h2,#_form_15_._inline-form ._html-code h3,#_form_15_._inline-form ._html-code h4,#_form_15_._inline-form ._html-code h5,#_form_15_._inline-form ._html-code h6,#_form_15_._inline-form ._form-title{font-size:22px;line-height:normal;font-weight:600;margin-bottom:0}#_form_15_._inline-form ._form-branding{font-family:"IBM Plex Sans", Helvetica, sans-serif;font-size:13px;font-weight:100;font-style:normal;text-decoration:none}#_form_15_:before,#_form_15_:after{content:" ";display:table}#_form_15_:after{clear:both}#_form_15_._inline-style{width:auto;display:inline-block}#_form_15_._inline-style input[type="text"],#_form_15_._inline-style input[type="date"]{padding:10px 12px}#_form_15_._inline-style button._inline-style{position:relative;top:27px}#_form_15_._inline-style p{margin:0}#_form_15_._inline-style ._button-wrapper{position:relative;margin:27px 12.5px 0 20px}#_form_15_ ._form-thank-you{position:relative;left:0;right:0;text-align:center;font-size:18px}#_form_15_ ._form-pc-confirmation ._submit{margin-top:16px}@media (min-width:320px) and (max-width:667px){#_form_15_._inline-form._inline-style ._inline-style._button-wrapper{margin-top:20px !important;margin-left:0 !important}}#_form_15_ .iti.iti--allow-dropdown.iti--separate-dial-code{width:100%}#_form_15_ .iti input{width:100%;height:32px;border:#979797 1px solid;border-radius:4px}#_form_15_ .iti--separate-dial-code .iti__selected-flag{background-color:#FFFFFF;border-radius:4px}#_form_15_ .iti--separate-dial-code .iti__selected-flag:hover{background-color:rgba(0, 0, 0, 0.05)}#_form_15_ .iti__country-list{border-radius:4px;margin-top:4px;min-width:460px}#_form_15_ .iti__country-list--dropup{margin-bottom:4px}#_form_15_ .phone-error-hidden{display:none}#_form_15_ .phone-error{color:#E40E49}#_form_15_ .phone-input-error{border:1px solid #E40E49 !important}#_form_15_._inline-form ._form-content ._form-list-subscriptions-field fieldset{margin:0;margin-bottom:1.1428571429em;border:none;padding:0}#_form_15_._inline-form ._form-content ._form-list-subscriptions-field fieldset:last-child{margin-bottom:0}#_form_15_._inline-form ._form-content ._form-list-subscriptions-field legend{margin-bottom:1.1428571429em}#_form_15_._inline-form ._form-content ._form-list-subscriptions-field label{display:flex;align-items:flex-start;justify-content:flex-start;margin-bottom:0.8571428571em}#_form_15_._inline-form ._form-content ._form-list-subscriptions-field label:last-child{margin-bottom:0}#_form_15_._inline-form ._form-content ._form-list-subscriptions-field input{margin:0;margin-right:8px}#_form_15_._inline-form ._form-content ._form-list-subscriptions-field ._form-checkbox-option-label{display:block;font-weight:400;margin-top:-4px}#_form_15_._inline-form ._form-content ._form-list-subscriptions-field ._form-checkbox-option-label-with-description{display:block;font-weight:700;margin-top:-4px}#_form_15_._inline-form ._form-content ._form-list-subscriptions-field ._form-checkbox-option-description{margin:0;font-size:0.8571428571em}#_form_15_._inline-form ._form-content ._form-list-subscriptions-field ._form-subscriptions-unsubscribe-all-description{line-height:normal;margin-top:-2px}






GDPR Consent*




Datalumen communication contains research, analysis or marketing information. You can always unsubribe and correction of your contact details may be made by using the Contact us link. Our Privacy Policy is available online.

window.cfields = {"1":"mobile_phone","5":"gdpr_consent"}; window._show_thank_you = function(id, message, trackcmp_url, email) { var form = document.getElementById('_form_' + id + '_'), thank_you = form.querySelector('._form-thank-you'); form.querySelector('._form-content').style.display = 'none'; thank_you.innerHTML = message; thank_you.style.display = 'block'; const vgoAlias = typeof visitorGlobalObjectAlias === 'undefined' ? 'vgo' : visitorGlobalObjectAlias; var visitorObject = window[vgoAlias]; if (email && typeof visitorObject !== 'undefined') { visitorObject('setEmail', email); visitorObject('update'); } else if (typeof(trackcmp_url) != 'undefined' && trackcmp_url) { // Site tracking URL to use after inline form submission. _load_script(trackcmp_url); } if (typeof window._form_callback !== 'undefined') window._form_callback(id); }; window._show_unsubscribe = function(id, message, trackcmp_url, email) { var form = document.getElementById('_form_' + id + '_'), unsub = form.querySelector('._form-thank-you'); var branding = form.querySelector('._form-branding'); if (branding) { branding.style.display = 'none'; } form.querySelector('._form-content').style.display = 'none'; unsub.style.display = 'block'; form.insertAdjacentHTML('afterend', message) const vgoAlias = typeof visitorGlobalObjectAlias === 'undefined' ? 'vgo' : visitorGlobalObjectAlias; var visitorObject = window[vgoAlias]; if (email && typeof visitorObject !== 'undefined') { visitorObject('setEmail', email); visitorObject('update'); } else if (typeof(trackcmp_url) != 'undefined' && trackcmp_url) { // Site tracking URL to use after inline form submission. _load_script(trackcmp_url); } if (typeof window._form_callback !== 'undefined') window._form_callback(id); }; window._show_error = function(id, message, html) { var form = document.getElementById('_form_' + id + '_'), err = document.createElement('div'), button = form.querySelector('button'), old_error = form.querySelector('._form_error'); if (old_error) old_error.parentNode.removeChild(old_error); err.innerHTML = message; err.className = '_error-inner _form_error _no_arrow'; var wrapper = document.createElement('div'); wrapper.className = '_form-inner'; wrapper.appendChild(err); button.parentNode.insertBefore(wrapper, button); var submitButton = form.querySelector('[id^="_form"][id$="_submit"]'); submitButton.disabled = false; submitButton.classList.remove('processing'); if (html) { var div = document.createElement('div'); div.className = '_error-html'; div.innerHTML = html; err.appendChild(div); } }; window._show_pc_confirmation = function(id, header, detail, show, email) { var form = document.getElementById('_form_' + id + '_'), pc_confirmation = form.querySelector('._form-pc-confirmation'); if (pc_confirmation.style.display === 'none') { form.querySelector('._form-content').style.display = 'none'; pc_confirmation.innerHTML = "

" + header + "

" + "

" + detail + "

" + ""; pc_confirmation.style.display = 'block'; var mp = document.querySelector('input[name="mp"]'); mp.value = '0'; } else { form.querySelector('._form-content').style.display = 'inline'; pc_confirmation.style.display = 'none'; }

var hideButton = document.getElementById('hideButton'); // Add event listener to the button hideButton.addEventListener('click', function() { var submitButton = document.querySelector('#_form_15_submit'); submitButton.disabled = false; submitButton.classList.remove('processing'); var mp = document.querySelector('input[name="mp"]'); mp.value = '1'; window.location.href = window.location.href; });

const vgoAlias = typeof visitorGlobalObjectAlias === 'undefined' ? 'vgo' : visitorGlobalObjectAlias; var visitorObject = window[vgoAlias]; if (email && typeof visitorObject !== 'undefined') { visitorObject('setEmail', email); visitorObject('update'); } else if (typeof(trackcmp_url) != 'undefined' && trackcmp_url) { // Site tracking URL to use after inline form submission. _load_script(trackcmp_url); } if (typeof window._form_callback !== 'undefined') window._form_callback(id); }; window._load_script = function(url, callback, isSubmit) { var head = document.querySelector('head'), script = document.createElement('script'), r = false; var submitButton = document.querySelector('#_form_15_submit'); script.charset = 'utf-8'; script.src = url; if (callback) { script.onload = script.onreadystatechange = function() { if (!r && (!this.readyState || this.readyState == 'complete')) { r = true; callback(); } }; } script.onerror = function() { if (isSubmit) { if (script.src.length > 10000) { _show_error("15", "Sorry, your submission failed. Please shorten your responses and try again."); } else { _show_error("15", "Sorry, your submission failed. Please try again."); } submitButton.disabled = false; submitButton.classList.remove('processing'); } }

head.appendChild(script); }; (function() { if (window.location.search.search("excludeform") !== -1) return false; var getCookie = function(name) { var match = document.cookie.match(new RegExp('(^|; )' + name + '=([^;]+)')); return match ? match[2] : null; } var setCookie = function(name, value) { var now = new Date(); var time = now.getTime(); var expireTime = time + 1000 * 60 * 60 * 24 * 365; now.setTime(expireTime); document.cookie = name + '=' + value + '; expires=' + now + ';path=/; Secure; SameSite=Lax;'; } var addEvent = function(element, event, func) { if (element.addEventListener) { element.addEventListener(event, func); } else { var oldFunc = element['on' + event]; element['on' + event] = function() { oldFunc.apply(this, arguments); func.apply(this, arguments); }; } } var _removed = false; var form_to_submit = document.getElementById('_form_15_'); var allInputs = form_to_submit.querySelectorAll('input, select, textarea'), tooltips = [], submitted = false;

var getUrlParam = function(name) { if (name.toLowerCase() !== 'email') { var params = new URLSearchParams(window.location.search); return params.get(name) || false; } // email is a special case because a plus is valid in the email address var qString = window.location.search; if (!qString) { return false; } var parameters = qString.substr(1).split('&'); for (var i = 0; i < parameters.length; i++) { var parameter = parameters[i].split('='); if (parameter[0].toLowerCase() === 'email') { return parameter[1] === undefined ? true : decodeURIComponent(parameter[1]); } } return false; }; var acctDateFormat = "%d/%m/%Y"; var getNormalizedDate = function(date, acctFormat) { var decodedDate = decodeURIComponent(date); if (acctFormat && acctFormat.match(/(%d|%e).*%m/gi) !== null) { return decodedDate.replace(/(d{2}).*(d{2}).*(d{4})/g, '$3-$2-$1'); } else if (Date.parse(decodedDate)) { var dateObj = new Date(decodedDate); var year = dateObj.getFullYear(); var month = dateObj.getMonth() + 1; var day = dateObj.getDate(); return `${year}-${month < 10 ? `0${month}` : month}-${day < 10 ? `0${day}` : day}`; } return false; }; var getNormalizedTime = function(time) { var hour, minutes; var decodedTime = decodeURIComponent(time); var timeParts = Array.from(decodedTime.matchAll(/(d{1,2}):(d{1,2})W*([AaPp][Mm])?/gm))[0]; if (timeParts[3]) { // 12 hour format var isPM = timeParts[3].toLowerCase() === 'pm'; if (isPM) { hour = parseInt(timeParts[1]) === 12 ? '12' : `${parseInt(timeParts[1]) + 12}`; } else { hour = parseInt(timeParts[1]) === 12 ? '0' : timeParts[1]; } } else { // 24 hour format hour = timeParts[1]; } var normalizedHour = parseInt(hour) < 10 ? `0${parseInt(hour)}` : hour; var minutes = timeParts[2]; return `${normalizedHour}:${minutes}`; }; for (var i = 0; i < allInputs.length; i++) { var regexStr = "field[(d+)]"; var results = new RegExp(regexStr).exec(allInputs[i].name); if (results != undefined) { allInputs[i].dataset.name = allInputs[i].name.match(/[time]$/) ? `${window.cfields[results[1]]}_time` : window.cfields[results[1]]; } else { allInputs[i].dataset.name = allInputs[i].name; } var fieldVal = getUrlParam(allInputs[i].dataset.name); if (fieldVal) { if (allInputs[i].dataset.autofill === "false") { continue; } if (allInputs[i].type == "radio" || allInputs[i].type == "checkbox") { if (allInputs[i].value == fieldVal) { allInputs[i].checked = true; } } else if (allInputs[i].type == "date") { allInputs[i].value = getNormalizedDate(fieldVal, acctDateFormat); } else if (allInputs[i].type == "time") { allInputs[i].value = getNormalizedTime(fieldVal); } else { allInputs[i].value = fieldVal; } } } var remove_tooltips = function() { for (var i = 0; i < tooltips.length; i++) { tooltips[i].tip.parentNode.removeChild(tooltips[i].tip); } tooltips = []; }; var remove_tooltip = function(elem) { for (var i = 0; i < tooltips.length; i++) { if (tooltips[i].elem === elem) { tooltips[i].tip.parentNode.removeChild(tooltips[i].tip); tooltips.splice(i, 1); return; } } }; var create_tooltip = function(elem, text) { var tooltip = document.createElement('div'), arrow = document.createElement('div'), inner = document.createElement('div'), new_tooltip = {}; if (elem.type != 'radio' && elem.type != 'checkbox') { tooltip.className = '_error'; arrow.className = '_error-arrow'; inner.className = '_error-inner'; inner.innerHTML = text; tooltip.appendChild(arrow); tooltip.appendChild(inner); elem.parentNode.appendChild(tooltip); } else { tooltip.className = '_error-inner _no_arrow'; tooltip.innerHTML = text; elem.parentNode.insertBefore(tooltip, elem); new_tooltip.no_arrow = true; } new_tooltip.tip = tooltip; new_tooltip.elem = elem; tooltips.push(new_tooltip); return new_tooltip; }; var resize_tooltip = function(tooltip) { var rect = tooltip.elem.getBoundingClientRect(); var doc = document.documentElement, scrollPosition = rect.top - ((window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0)); if (scrollPosition < 40) { tooltip.tip.className = tooltip.tip.className.replace(/ ?(_above|_below) ?/g, '') + ' _below'; } else { tooltip.tip.className = tooltip.tip.className.replace(/ ?(_above|_below) ?/g, '') + ' _above'; } }; var resize_tooltips = function() { if (_removed) return; for (var i = 0; i < tooltips.length; i++) { if (!tooltips[i].no_arrow) resize_tooltip(tooltips[i]); } }; var validate_field = function(elem, remove) { var tooltip = null, value = elem.value, no_error = true; remove ? remove_tooltip(elem) : false; if (elem.type != 'checkbox') elem.className = elem.className.replace(/ ?_has_error ?/g, ''); if (elem.getAttribute('required') !== null) { if (elem.type == 'radio' || (elem.type == 'checkbox' && /any/.test(elem.className))) { var elems = form_to_submit.elements[elem.name]; if (!(elems instanceof NodeList || elems instanceof HTMLCollection) || elems.length <= 1) { no_error = elem.checked; } else { no_error = false; for (var i = 0; i < elems.length; i++) { if (elems[i].checked) no_error = true; } } if (!no_error) { tooltip = create_tooltip(elem, "Please select an option."); } } else if (elem.type =='checkbox') { var elems = form_to_submit.elements[elem.name], found = false, err = []; no_error = true; for (var i = 0; i < elems.length; i++) { if (elems[i].getAttribute('required') === null) continue; if (!found && elems[i] !== elem) return true; found = true; elems[i].className = elems[i].className.replace(/ ?_has_error ?/g, ''); if (!elems[i].checked) { no_error = false; elems[i].className = elems[i].className + ' _has_error'; err.push("Checking %s is required".replace("%s", elems[i].value)); } } if (!no_error) { tooltip = create_tooltip(elem, err.join('
')); } } else if (elem.tagName == 'SELECT') { var selected = true; if (elem.multiple) { selected = false; for (var i = 0; i < elem.options.length; i++) { if (elem.options[i].selected) { selected = true; break; } } } else { for (var i = 0; i < elem.options.length; i++) { if (elem.options[i].selected && (!elem.options[i].value || (elem.options[i].value.match(/n/g))) ) { selected = false; } } } if (!selected) { elem.className = elem.className + ' _has_error'; no_error = false; tooltip = create_tooltip(elem, "Please select an option."); } } else if (value === undefined || value === null || value === '') { elem.className = elem.className + ' _has_error'; no_error = false; tooltip = create_tooltip(elem, "This field is required."); } } if (no_error && (elem.id == 'field[]' || elem.id == 'ca[11][v]')) { if (elem.className.includes('phone-input-error')) { elem.className = elem.className + ' _has_error'; no_error = false; } } if (no_error && elem.name == 'email') { if (!value.match(/^[+_a-z0-9-'&=]+(.[+_a-z0-9-']+)*@[a-z0-9-]+(.[a-z0-9-]+)*(.[a-z]{2,})$/i)) { elem.className = elem.className + ' _has_error'; no_error = false; tooltip = create_tooltip(elem, "Enter a valid email address."); } else { // New code to reject hotmail.com, yahoo.com, gmail.com addresses and addresses containing the firstname field as the domain var domain = value.split('@')[1].toLowerCase(); var firstname = document.getElementById('firstname').value.toLowerCase(); var lastname = document.getElementById('lastname').value.toLowerCase(); if (domain === 'hotmail' || domain === 'aol' || domain === 'gmail' || domain === 'yahoo' || domain === 'live' || domain === 'outlook' || domain === 'msn.com' || domain.includes(firstname) || domain.includes(lastname)) { elem.className = elem.className + ' _has_error'; no_error = false; tooltip = create_tooltip(elem, "We do not accept private email addresses. Please submit your valid business email."); } } } if (no_error && /date_field/.test(elem.className)) { if (!value.match(/^dddd-dd-dd$/)) { elem.className = elem.className + ' _has_error'; no_error = false; tooltip = create_tooltip(elem, "Enter a valid date."); } } tooltip ? resize_tooltip(tooltip) : false; return no_error; }; var needs_validate = function(el) { if(el.getAttribute('required') !== null){ return true } if(el.name === 'email' && el.value !== ""){ return true } if((el.id == 'field[]' || el.id == 'ca[11][v]') && el.className.includes('phone-input-error')){ return true } return false }; var validate_form = function(e) { var err = form_to_submit.querySelector('._form_error'), no_error = true; if (!submitted) { submitted = true; for (var i = 0, len = allInputs.length; i < len; i++) { var input = allInputs[i]; if (needs_validate(input)) { if (input.type == 'tel') { addEvent(input, 'blur', function() { this.value = this.value.trim(); validate_field(this, true); }); } if (input.type == 'text' || input.type == 'number' || input.type == 'time') { addEvent(input, 'blur', function() { this.value = this.value.trim(); validate_field(this, true); }); addEvent(input, 'input', function() { validate_field(this, true); }); } else if (input.type == 'radio' || input.type == 'checkbox') { (function(el) { var radios = form_to_submit.elements[el.name]; for (var i = 0; i < radios.length; i++) { addEvent(radios[i], 'click', function() { validate_field(el, true); }); } })(input); } else if (input.tagName == 'SELECT') { addEvent(input, 'change', function() { validate_field(this, true); }); } else if (input.type == 'textarea'){ addEvent(input, 'input', function() { validate_field(this, true); }); } } } } remove_tooltips(); for (var i = 0, len = allInputs.length; i 31 && (charCode 57) && charCode !== 8) { e.preventDefault(); } }); };

var showPhoneInputError = function(inputId) { var errorMessage = document.getElementById("error-msg-" + inputId); var input = document.getElementById(inputId); errorMessage.classList.add("phone-error"); errorMessage.classList.remove("phone-error-hidden"); input.classList.add("phone-input-error"); };

window['recaptcha_callback'] = function() { // Get all recaptchas in the DOM (there may be more than one form on the page). var recaptchas = document.getElementsByClassName("g-recaptcha"); for (var i in recaptchas) { // Set the recaptcha element ID, so the recaptcha can be applied to each element. var recaptcha_id = "recaptcha_" + i; recaptchas[i].id = recaptcha_id; var el = document.getElementById(recaptcha_id); if (el != null) { var sitekey = el.getAttribute("data-sitekey"); var stoken = el.getAttribute("data-stoken"); grecaptcha.render(recaptcha_id, {"sitekey":sitekey,"stoken":stoken}); } } }; _load_script( "https://www.google.com/recaptcha/api.js?onload=recaptcha_callback&render=explicit" ); var _form_serialize = function(form){if(!form||form.nodeName!=="FORM"){return }var i,j,q=[];for(i=0;i<form.elements.length;i++){if(form.elements[i].name===""){continue}switch(form.elements[i].nodeName){case"INPUT":switch(form.elements[i].type){case"tel":q.push(form.elements[i].name+"="+encodeURIComponent(form.elements[i].previousSibling.querySelector('div.iti__selected-dial-code').innerText)+encodeURIComponent(" ")+encodeURIComponent(form.elements[i].value));break;case"text":case"number":case"date":case"time":case"hidden":case"password":case"button":case"reset":case"submit":q.push(form.elements[i].name+"="+encodeURIComponent(form.elements[i].value));break;case"checkbox":case"radio":if(form.elements[i].checked){q.push(form.elements[i].name+"="+encodeURIComponent(form.elements[i].value))}break;case"file":break}break;case"TEXTAREA":q.push(form.elements[i].name+"="+encodeURIComponent(form.elements[i].value));break;case"SELECT":switch(form.elements[i].type){case"select-one":q.push(form.elements[i].name+"="+encodeURIComponent(form.elements[i].value));break;case"select-multiple":for(j=0;j { if (key !== 'hideButton') { formData.append(key, value); } //formData.append(key, value); }); let request = { headers: { "Accept": "application/json" }, body: formData, method: "POST" };

let pageUrlParams = new URLSearchParams(window.location.search); if (pageUrlParams.has('t')) { request.headers.Authorization = 'Bearer ' + pageUrlParams.get('t'); } const response = await fetch('https://datalumen.activehosted.com/proc.php?jsonp=true', request); return response.json(); } if (formSupportsPost) { submitForm().then((data) => { eval(data.js); }); } else { _load_script('https://datalumen.activehosted.com/proc.php?' + serialized + '&jsonp=true', null, true); } } return false; }; addEvent(form_to_submit, 'submit', form_submit); })();

×