(function () {
	var CFG = {
		id: "34796",
		html: "<div style=\"background:;\"><div style=\"font-family: tahoma, sans-serif; font-size: 13px;\" class=\"he_stage\" data-theme=\"0\" width=\"100%\" align=\"center\">\n  <table style=\"width: 1087px; margin-bottom: 0px;\" class=\"full_width\" width=\"1087\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n    <tbody>\n      <tr>\n        <td data-zone=\"vertical container\" class=\"he_nodrop\" style=\"width: 1087px;\" valign=\"top\" align=\"left\">\n          <table style=\"margin-bottom:0;\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n            <tbody>\n              <tr>\n                <td data-zone=\"vertical container\" style=\"width: 1087px; height: auto;\" class=\"\" width=\"*\" valign=\"top\">\n                  <table style=\"margin-bottom:0;\" width=\"100%\" cellspacing=\"0\" cellpadding=\"0\">\n                    <tbody>\n                      <tr>\n                        <td data-zone=\"vertical container\" style=\"width: 1087px; height: auto;\" class=\"\" width=\"*\" valign=\"top\">\n                          <table style=\"margin-bottom:0;\" width=\"100%\" cellspacing=\"0\" cellpadding=\"0\">\n                            <tbody>\n                              <tr>\n                                <td data-zone=\"vertical container\" style=\"width: 1087px; height: auto;\" class=\"\" width=\"*\" valign=\"top\">\n                                  <table style=\"margin-bottom:0;\" width=\"100%\" cellspacing=\"0\" cellpadding=\"0\">\n                                    <tbody>\n                                      <tr>\n                                        <td data-zone=\"vertical container\" style=\"width: 1087px; height: auto;\" class=\"\" width=\"*\" valign=\"top\">\n                                          <table style=\"margin-bottom:0;\" width=\"100%\" cellspacing=\"0\" cellpadding=\"0\">\n                                            <tbody>\n                                              <tr>\n                                                <td class=\"ColumnRight\" style=\"width: 1047px; padding: 5px 20px; height: auto;\" data-zone=\"vertical container\" width=\"*\" valign=\"middle\" align=\"center\">\n                                                  <table style=\"margin-bottom:0;\" width=\"100%\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n                                                    <tbody>\n                                                      <tr>\n                                                        <td data-zone=\"form\" class=\"rm-form-wrapper\" style=\"left: 0px; top: 0px; width: 1047px; outline: none; border-width: 0px; border-style: none; border-color: rgb(0, 0, 0); padding: 0px; height: auto;\" data-progressive-total-fields=\"0\" valign=\"top\">\n                                                          <form>\n                                                            <table style=\"width:100%;margin-bottom:0;\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n                                                              <tbody>\n                                                                <tr>\n                                                                  <td data-zone=\"vertical container\" style=\"width: 1047px; height: auto;\" class=\"\" width=\"*\" valign=\"top\">\n                                                                    <table style=\"margin-bottom:0;\" width=\"100%\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n                                                                      <tbody>\n                                                                        <tr>\n                                                                          <td data-zone=\"text\" style=\"padding: 0px; left: 0px; top: 0px; font-family: tahoma, sans-serif; font-size: 13px; width: 1047px; height: auto;\" class=\"\" valign=\"top\">\n                                                                            <div><strong><span style=\"font-size:26px;\"><span style=\"font-family:Arial,sans-serif;\">Subscribe to EUREKA!<\/span><\/span><\/strong><\/div>\n                                                                          <\/td>\n                                                                        <\/tr>\n                                                                      <\/tbody>\n                                                                    <\/table>\n                                                                  <\/td>\n                                                                <\/tr>\n                                                                <tr>\n                                                                  <td data-zone=\"form field\" style=\"padding: 0px; width: 1047px; font: 13px arial, helvetica, sans-serif; height: auto;\" class=\"contenttext\" valign=\"top\">\n                                                                    <label><span class=\"rm-form-label\">* Email Address<\/span>\n                                                                      <input type=\"text\" class=\"rm-form-input rm-field-width-xxxlarge\" name=\"RM_FIELD_3\" data-required=\"true\"> <\/label>\n                                                                  <\/td>\n                                                                <\/tr>\n                                                                <tr>\n                                                                  <td data-zone=\"form submit\" style=\"padding: 10px 0px 0px; width: 1047px; text-align: left; font: 13px arial, helvetica, sans-serif; height: auto;\" class=\"\" valign=\"top\">\n                                                                    <input type=\"submit\" value=\"Submit\" class=\"rm-form-submit\">\n                                                                    <style type=\"text\/css\" data-css=\"submit\">\n                                                                      .rm-form-wrapper .rm-form-submit {\n                                                                        background-color: #00557a;\n                                                                        border-color: #ecefdf;\n                                                                        color: #ffffff;\n                                                                        border-width: 0px;\n                                                                        border-style: solid;\n                                                                        padding: 5px 15px;\n                                                                        font-size: 18px;\n                                                                        cursor: pointer;\n                                                                      }\n                                                                    <\/style>\n                                                                  <\/td>\n                                                                <\/tr>\n                                                              <\/tbody>\n                                                            <\/table>\n                                                          <\/form>\n                                                          <style type=\"text\/css\" data-css=\"form\">\n                                                            .rm-form-wrapper .rm-form-subinput {\n                                                              margin-right: 5px;\n                                                              display: inline-block;\n                                                            }\n\n                                                            .rm-form-wrapper div label {\n                                                              float: left;\n                                                              clear: both;\n                                                            }\n\n                                                            .rm-form-wrapper .rm-form-input {\n                                                              margin-top: 5px;\n                                                              padding: 5px;\n                                                              display: block;\n                                                            }\n\n                                                            .rm-form-wrapper .rm-form-help,\n                                                            .rm-form-wrapper .rm-form-input,\n                                                            .rm-form-wrapper .rm-form-label,\n                                                            .rm-form-wrapper .rm-form-sublabel {\n                                                              font-family: Arial, sans-serif;\n                                                            }\n\n                                                            .rm-form-wrapper .rm-form-help {\n                                                              color: #777;\n                                                              font-size: 14px;\n                                                              font-style: italic;\n                                                              line-height: 1.2em;\n                                                              margin: 2px 0;\n                                                            }\n\n                                                            .rm-form-wrapper .rm-form-label,\n                                                            .rm-form-wrapper .rm-form-sublabel {\n                                                              color: #444444;\n                                                              font-size: 14px;\n                                                            }\n\n                                                            .rm-form-wrapper .rm-form-label {\n                                                              font-weight: thin;\n                                                              margin: 0 0 5px;\n                                                            }\n\n                                                            .rm-form-wrapper .rm-field-width-small {\n                                                              width: 100px;\n                                                            }\n\n                                                            .rm-form-wrapper .rm-field-width-medium {\n                                                              width: 150px;\n                                                            }\n\n                                                            .rm-form-wrapper .rm-field-width-large {\n                                                              width: 200px;\n                                                            }\n\n                                                            .rm-form-wrapper .rm-field-width-xlarge {\n                                                              width: 250px;\n                                                            }\n\n                                                            .rm-form-wrapper .rm-field-width-xxlarge {\n                                                              width: 300px;\n                                                            }\n\n                                                            .rm-form-wrapper .rm-field-width-xxxlarge {\n                                                              width: 350px;\n                                                            }\n\n                                                            .rm-form-wrapper .rm-field-width-full {\n                                                              width: 100%;\n                                                            }\n                                                          <\/style>\n                                                          <div data-hidden-content=\"thank\" style=\"display: none;\">\n                                                            <div style=\"text-align: center;\"><span style=\"font-size:14px;\"><span style=\"color:#00567a;\"><span style=\"font-family:Arial,sans-serif;\">Thank you for signing up to the EUREKA! digital newsletter. Remember, you can unsubscribe from future communications at any time by clicking on the <strong>unsubscribe<\/strong> link in&nbsp;the footer of every email.<\/span><\/span>\n                                                              <\/span>\n                                                            <\/div>\n                                                          <\/div>\n                                                        <\/td>\n                                                      <\/tr>\n                                                    <\/tbody>\n                                                  <\/table>\n                                                <\/td>\n                                              <\/tr>\n                                            <\/tbody>\n                                          <\/table>\n                                        <\/td>\n                                      <\/tr>\n                                    <\/tbody>\n                                  <\/table>\n                                <\/td>\n                              <\/tr>\n                            <\/tbody>\n                          <\/table>\n                        <\/td>\n                      <\/tr>\n                    <\/tbody>\n                  <\/table>\n                <\/td>\n              <\/tr>\n            <\/tbody>\n          <\/table>\n        <\/td>\n      <\/tr>\n    <\/tbody>\n  <\/table>\n<\/div><\/div>",
		uri: "eureka-signup",
		url: "https:\/\/urological.realmagnet.land",
		submit_url: "\/\/urological.realmagnet.land\/submit\/34796,3?",
		query_string: "",
		image_url: "\/\/urological.realmagnet.land\/image\/34796,12758?",
		rm_host: false,
		form_action: "redirect", // 'self' or 'redirect'
		form_redirect_url: "https:\/\/urological.realmagnet.land\/eureka-confirmation-page",
		lead_api: "eqqd8eGlhUmqWQqXWQRyVQ",
		lead_script: "https://tracking.magnetmail.net/MagnetLeads.js",
		lead_onsubmit_url: "https://tracking.magnetmail.net/rd/",
		prepopulate_fields: "{}",
        show_progressive: "{}",
        personalization: "{}"
	};

	var skipJsValidation = false;
var debugMode = false;
var maxUrlLength = 2000 - CFG.submit_url.length; // for form submits via jsonp
//var maxUrlLength = 150 - CFG.submit_url.length; // for form submits via jsonp

CFG.recaptcha = {
	url: 'https://www.google.com/recaptcha/api.js?render=explicit&onload=RMCBRecaptchaCallback',
	key: '6LfHs_gSAAAAAMH8XuLRsg118e_qvET0wQgrPDlc'
};

var errorMessages = {
	nestedForms: 'Landing Page cannot be embedded inside another form. <br/>Switch to "iFrame" option or move target DIV out of the existing form.',
	field_required: 'is required.',
	field_invalid: 'invalid format.',
	field_numeric: 'invalid number.',
	field_email: 'invalid email format.',
	field_date: 'invalid date format. Please enter date in mm/dd/yyyy format.',
	field_urlLength: 'value is too long for submission',
	submission_error: 'An error occurred while processing your submission. Please contact our support team.',
	server_error: 'Server responded with error. Please contact our support team.',
	database_error: 'An error occurred while saving this form. Please contact our support team.'
};
var captchaCodes = {
	'missing-input-secret': 'The secret parameter is missing.',
	'invalid-input-secret': 'The secret parameter is invalid or malformed.',
	'missing-input-response': 'The response parameter is missing.',
	'invalid-input-response': 'The response parameter is invalid or malformed.',
	'timeout-or-duplicate': 'Timeout or duplicate.'
};

// utils
var _ = {};
	_.consolelog = function(){
		if (!debugMode) return;
		var args = Array.prototype.slice.call(arguments);
		args.unshift('[ID='+CFG.id+']');
		console.log.apply(null, args);
	};
	_.ieVersion = (function(){
		// Returns the version of Internet Explorer or a -1
		// (indicating the use of another browser).
		var ua = window.navigator.userAgent;
		var msie = ua.indexOf('MSIE ');
		if (msie > 0) {
			// IE 10 or older => return version number
			return parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10);
		}
		var trident = ua.indexOf('Trident/');
		if (trident > 0) {
			// IE 11 => return version number
			var rv = ua.indexOf('rv:');
			return parseInt(ua.substring(rv + 3, ua.indexOf('.', rv)), 10);
		}
		var edge = ua.indexOf('Edge/');
		if (edge > 0) {
			// Edge (IE 12+) => return version number
			return parseInt(ua.substring(edge + 5, ua.indexOf('.', edge)), 10);
		}
		return -1;
	})();
	_.getComputedStyle = function(el){
		if (window.getComputedStyle !== undefined) {
			return window.getComputedStyle(el, null); // for modern browsers
		} else {
			return el.currentStyle; // for IE < 9
		}		
	};
	_.isInIframe = (function(){
		try {
			return window.self !== window.top;
		} catch (e) {
			return true;
		}
	})();
	_.isRMHost = (function(){
		if (_.isInIframe) return false;
		var hostname = window.location.hostname.toLowerCase();
		var loadedFrom = CFG.url.toLowerCase().replace(/\/$/, "").replace(/^(http|https):\/\//,'');
		return hostname == loadedFrom;
	})();
	_.domReady = function(callback){
		if (document.readyState === 'complete' || (document.readyState !== 'loading' && !document.documentElement.doScroll)) {
			callback();
		} else {
			if (window.addEventListener) {
				window.addEventListener('DOMContentLoaded', callback);
			} else {
				document.attachEvent('onreadystatechange', function(){
					if (document.readyState === "complete"){
						callback(window.event)
					}
				})
			}
		}
	};
	_.findTarget = function(tagId) {
		var targetIdNew = 'RM-target-lp-' + tagId;
		var targetIdOld = 'landing_container';
		var target = document.getElementById(targetIdNew);
		if (!target) target = document.getElementById(targetIdOld);
		if (!target) {
			console.error('RealMagnet: Cannot find a target container for the LandingPage. Add <div id="' + targetIdNew + '"></div> to your page.');
			return;
		}
		return target;
	};
	_.parseURI = function(uri) {
		if (uri === undefined) uri = '';
		uri = uri.replace(/^\?/ ,'');
		uri = uri.replace(/\&$/ ,'');
		var params = uri.split("&"),
			hash = {};
		for (var i = 0; i < params.length; i++) {
			var val = params[i].split("=");
			if (val[0]) {
				hash[unescape(val[0])] = val[1] === undefined ? true: unescape(val[1]);
			}
		}
		return hash;
	};
	_.docSize = function(){
		var el = document.querySelectorAll('html')[0];
		var computed = _.getComputedStyle(el);
		return {
			width: el.offsetWidth,
			height: el.offsetHeight + parseInt(computed['margin-top'], 10) + parseInt(computed['margin-bottom'], 10)
		};
	};
	_.on = function(el, evType, callback) {
		var els = el instanceof Array ? el : [el];
		for (var i = 0; i < els.length; i++) {
			if (els[i].addEventListener) {
				els[i].addEventListener(evType, callback, false); // for modern browsers
			} else {
				els[i].attachEvent('on' + evType, function() {
					callback(window.event);  // for IE < 9
				});
			}
		}
	};
	_.forEach = function(arr, callback, context) {
		if (arr && arr.length) {
			for (var i = 0; i < arr.length; i++) {
				callback.call(context, arr[i], i);
			}
		}
	};
	_.toggle = function(el, flag){
		el.style.display = flag ? 'block' : 'none';
	};
	_.toggleClass = function(el, className, flag){
		var hasClassRegex = new RegExp("\\b"+className+"\\b", "gi");
		var hasClass = hasClassRegex.exec(el.className) !== null;
		if (flag && !hasClass) {
			el.className += (el.className ? ' ' : '') + className;
		}
		if (!flag && hasClass) {
			el.className = el.className.replace(hasClassRegex, '');
		}
	};
	_.injectCSS = function(target, cssText) {
		var styleElement = document.createElement('style');
		styleElement.type = 'text/css';
		if (styleElement.styleSheet) {
			styleElement.styleSheet.cssText = cssText;
		} else {
			styleElement.appendChild(document.createTextNode(cssText));
		}
		target.appendChild(styleElement);
	};
	_.removeChildElements = function(el){
		while (el.hasChildNodes()) {
			el.removeChild(el.lastChild);
		}
	};
	_.isInForm = function(el){
		while(el.parentElement.tagName != 'BODY') {
			if (el.parentElement.tagName == 'FORM') {
				return true;
			}
			el = el.parentElement;
		}
		return false;
	};
	_.createToken = function(){
		var d = new Date();
		return '' + d.getTime();
	};
	_.trackUtmSource = function(target) {
		// track UTM source (by getting 1px picture)
		var imgEl = document.createElement('img');
		imgEl.src = CFG.image_url + 'utm_source=' + (_.docUri['utm_source'] || '');
		imgEl.setAttribute("style", "width: 0px !important; height: 0px !important;");
		target.appendChild(imgEl);
	};
	_.docUri = (function(){
		var res = _.parseURI(window.location.search.substring(1));
		_.consolelog('docUri: ', res);
		return res;
	})();
	/**
	 * Send JSONP request
	 * @param  {object} cfg Params
	                    .url
	                    .onSuccess
	                    .onError
	 * @return {void}
	 */
	_.JSONPRequest = function(cfg) {
		// working with jsonp request we need to check for:
		// 1) script was not loaded (e.g. connection might be lost);
		// 2) http error (e.g. something happend on server and it returned 500)
		// 3) script was loaded but it's incorrect inside (e.g. there was an error on server and it returned some text instead of script data)

		var ok = false; // callback was revoked
		var cbName = 'f' + String(Math.random()).slice(2); // generate jsonp function name
		
		cfg.url += ~cfg.url.indexOf('?') ? '&' : '?';
		cfg.url += '_c=RMCBRegistry.' + cbName;

		if (!window.RMCBRegistry) window.RMCBRegistry = {};

		window.RMCBRegistry[cbName] = function(data){
			ok = true;
			delete window.RMCBRegistry[cbName];
			cfg.onSuccess(data);
		};

		// this will be envoked anyway, but in successful case - only after jsonp function
		function checkCallback() {
			if (ok) return;
			delete window.RMCBRegistry[cbName];
			cfg.onError(cfg.url);
		}

		var script = document.createElement('script');

		// IE<9 supports only readystatechange event, not onload/onerror
		script.onreadystatechange = function() {
			if (this.readyState == 'complete' || this.readyState == 'loaded') {
				this.onreadystatechange = null;
				checkCallback();
			}
		};

		// script.onload/onerror fires after jsonp function
		script.onload = script.onerror = checkCallback;
		script.src = cfg.url;
		document.getElementsByTagName('head')[0].appendChild(script);
	};
	/**
	 * Load Script
	 * @param  {object} cfg Params 
	                    .url
	                    .onLoad
	 * @return {void}
	 */
	_.loadScript = function(cfg){
		if (typeof cfg.onLoad !== 'function') cfg.onLoad = function(){};
		var script = document.createElement('script');
		// IE<9 supports only readystatechange event, not onload/onerror
		if (script.onload !== undefined) {
			script.onload = cfg.onLoad;
		} else {
			script.onreadystatechange = function() {
				if (this.readyState == 'complete' || this.readyState == 'loaded') {
					this.onreadystatechange = null;
					cfg.onLoad();
				}
			};
		}
		script.src = cfg.url;
		document.getElementsByTagName('head')[0].appendChild(script);
	};

if (!Array.prototype.indexOf) {
	Array.prototype.indexOf = function(searchElement, fromIndex) {
	var k;
	if (this == null) {
		throw new TypeError('"this" is null or not defined');
	}
	var o = Object(this);
	var len = o.length >>> 0;
	if (len === 0) {
		return -1;
    }
    var n = fromIndex | 0;
    if (n >= len) {
		return -1;
    }
    k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
    while (k < len) {
		if (k in o && o[k] === searchElement) {
			return k;
		}
		k++;
	}
	return -1;
  };
}


// validation module
var FormValidation = (function(){

	var formCSS = '';
	formCSS += ".rm-form-error-summary {background-color: #f2dede; color: #871f1f; padding: 5px; font-family: Arial; display: none; border-left: 5px solid #d9534f}\n";
	formCSS += "ul.rm-form-error-summary {list-style-type: none;}\n";
	formCSS += ".rm-form-invalid-field {border: 1px solid red;}\n";
	formCSS += ".rm-form-invalid-field:focus {outline: red auto 5px;}\n";
	formCSS += "input.rm-form-invalid-field[type=radio], input.rm-form-invalid-field[type=checkbox] {border: none; outline: red solid 1px;}\n";
	formCSS += "input.rm-form-invalid-field[type=radio]:focus, input.rm-form-invalid-field[type=checkbox]:focus {border: none; outline: red solid 2px;}\n";

	// calculate max pair length based on constant data we append to URL for every JSONP request
	var urlReservedLength = ('_t=99&_n=' + _.createToken() + '&_c=RMCBRegistry.f03946496673638267' + '&').length;
	var maxPairLength = maxUrlLength - urlReservedLength;

	function checkRule(ruleName, formZone) {
		if (skipJsValidation) return true;

		var val = formZone.val();
		if (ruleName == 'required') {
			if (val.length > 1) return true;
			if (val.length == 1 && val[0] !== undefined && val[0] !== '') return true;
			return false;
		}

		// for all rules except "required" element needs to have some value
		if (!val.length || !val[0]) return true;

		// most likely rules "numeric" and "email" will be applied only to single fields (like text, textarea)
		// for elements like checkboxes, radios, select-boxes we will have only "required" rule
		if (ruleName == 'urlLength') {
			var str = formZone.elName + '=' + encodeURIComponent(val);
			if (str.length > maxPairLength) {
				_.consolelog('** ', str, str.length+' VS '+maxPairLength);
			}
			return str.length <= maxPairLength;
		}
		if (ruleName == 'numeric') {
			var re = /^\d+$/g;
			return  re.test(val[0]);
		}
		if (ruleName == 'email') {
			var re = /.+\@.+\..+/g;
			return  re.test(val[0]);
		}
		if (ruleName == 'date') {
			// 1. check dd/dd/dddd format
			var re = /^([\d]{1,2})\/([\d]{1,2})\/([\d]{4})$/;
			var res = re.exec(val[0]);
			if (!res) return false;

			// 2. check if date is valid
			val[0] = ('00' + res[1]).slice(-2) + '/' + ('00' + res[2]).slice(-2)  + '/' + res[3];

			var date = new Date(val[0]);
			if (date == 'Invalid Date') return false;

			var m = date.getMonth() + 1,
				d = date.getDate(),
				y = date.getFullYear();

			var str = ('00' + m).slice(-2) + '/' + ('00' + d).slice(-2) + '/' + y;
			return str == val[0];
		}
		return true;
	}

	function FormZone(group, parent) {
		this.elType = group[0].type;
		this.elName = group[0].name;
		this.elements = group;
		this.elLabel = this.getLabelText();
		this.rules = ['urlLength'];
		this.errors = [];
		this.prepareRules();
	}
	FormZone.prototype.getLabelText = function() {
		var formFieldZone = null;
		var el = this.elements[0], el2;
		while (formFieldZone === null) {
			if (el.parentElement.attributes['data-zone'] && el.parentElement.attributes['data-zone'].value == 'form field') {
				formFieldZone = el.parentElement;
			} else {
				el = el.parentElement;
			}
		}
		if (this.elType === 'checkbox' || this.elType === 'radio') {
			el2 = formFieldZone.querySelectorAll('h5');
			if (el2.length)
				return el2[0].innerHTML;
		}
		el2 = this.elements[0].parentElement.querySelectorAll('span');
		if (el2.length)
			return el2[0].innerHTML;

		return this.elName;
	}
	FormZone.prototype.val = function(newValue) {
		if (newValue === undefined) {
			var val = [];
			for (var i = 0; i < this.elements.length; i++) {
				if (this.elType == 'checkbox' || this.elType == 'radio') {
					if (this.elements[i].checked) val.push(this.elements[i].value);
				} else if (this.elType == 'select-multiple' || this.elType == 'select-one') {
					for (var j = 0; j < this.elements[i].options.length; j++) {
						if (this.elements[i].options[j].selected) val.push(this.elements[i].options[j].value);
					}
				} else {
					val.push(this.elements[i].value);
				}			
			}
			return val;
		}
		if (this.elType === 'text' || this.elType === 'textarea') {
			this.elements[0].value = newValue;
		}
		if (this.elType === 'checkbox' || this.elType == 'radio') {
			newValue = newValue.split(',');
			for (var i = 0; i < this.elements.length; i++) {
				this.elements[i].removeAttribute('checked');
				for (var j = 0; j < newValue.length; j++) {
					if (this.elements[i].value == newValue[j]) {
						this.elements[i].setAttribute('checked', 'checked');
						break;
					}
				}
			}
		}
		if (this.elType === 'select-one') {
			for (var i = 0; i < this.elements[0].options.length; i++) {
				if (this.elements[0].options[i].value == newValue) {
					this.elements[0].selectedIndex = i;
					break;
				}
			}
		}
	}
	FormZone.prototype.prepareRules = function(){
		var el = this.elements[0];
		for (var i = 0; i < this.elements[0].attributes.length; i++) {
			var attr = this.elements[0].attributes[i];
			if (attr.name == 'data-required' && attr.value == 'true') {
				this.rules.push('required');
			}
			if (attr.name == 'data-numeric' && attr.value == 'true') {
				this.rules.push('numeric');
			}
			if (attr.name == 'data-email-field' && attr.value == 'true') {
				this.rules.push('email');
			}
			if (attr.name == 'data-date-field' && attr.value == 'true') {
				this.rules.push('date');
			}
		}
		if (this.rules.indexOf('required') == -1 && this.elName == 'RM_FIELD_3') {
			this.rules.push('required');
		}
	}
	FormZone.prototype.isValid = function(){
		var res;
		var valid = true;
		this.errors = [];
		_.forEach(this.rules, function(rule, i){
			res = checkRule(rule, this);
			valid = res && valid;
			if (!res) this.addError(errorMessages['field_' + rule]);
		}, this);
		return valid;
	}
	FormZone.prototype.addError = function(message){
		this.errors.push('<strong>' + this.elLabel + '</strong>: ' + message);
	}
	FormZone.prototype.highlight = function(flag) {
		_.forEach(this.elements, function(el, i){
			_.toggleClass(el, 'rm-form-invalid-field', flag);
		}, this);
	}
	FormZone.prototype.putFocus = function() {
		this.elements[0].focus(); 
	}

	function UtmSourceZone() {
		this.elName = 'utm_source';
		this.elLabel = 'UTM source';
		this.errors = [];
	}
	UtmSourceZone.prototype = {
		val: function() {
			return _.docUri['utm_source'] || '';
		},
		isValid: function() {
			this.errors = [];
			var res = checkRule('urlLength', this);
			if (!res) this.errors.push('<strong>' + this.elLabel + '</strong>:' + errorMessages['field_urlLength']);
			return res;
		},
		putFocus: function(){},
		highlight: function(){}
	}

	function CaptchaZone() {
		this.elName = 'rc_response';
		this.elLabel = 'Captcha';
		this.obj = window.grecaptcha;
	}
	CaptchaZone.prototype = {
		val: function() {
			return [this.obj.getResponse()];
		},
		isValid: function(){
			this.errors = [];
			if (this.obj.getResponse()) return true;
			this.addError('please solve a challenge.');
			return false;
		},
		addError: function(message){
			this.errors.push('<strong>' + this.elLabel + '</strong>: ' + message);
		},
		putFocus: function(){},
		highlight: function(){}
	};
	function FormValidation(formZone, onValid){
		var self = this;
		this.form = formZone.querySelectorAll('form')[0];
		this.submitBtn = formZone.querySelectorAll('button[type=submit], input[type=submit], input[type=image]')[0];
		this.totalProgressive = formZone.attributes['data-progressive-total-fields'] ? parseInt(formZone.attributes['data-progressive-total-fields'].value, 10) : 0;

		_.injectCSS(this.form, formCSS);
		this.errorContainer = document.createElement('ul');
		_.toggleClass(this.errorContainer, 'rm-form-error-summary', true);
		this.form.insertBefore(this.errorContainer, this.form.firstChild);

		this.zones = {};
		this.findZones();
		this.prepopulate();
		_.on(this.form, 'submit', function(e){
			e.preventDefault();
			if (self.submitBtn.attributes['disabled']) return;
			self.submitBtn.setAttribute('disabled', true);
			if (self.isValid()) {
				onValid(self);
			} else {
				self.submitBtn.removeAttribute('disabled');
			}
		});
	}
	FormValidation.prototype.prepopulate = function(){
		for (var name in this.zones) {
			if (this.zones[name] instanceof FormZone) {
				if (CFG.prepopulate_fields[name] || _.docUri[name]) {
					this.zones[name].val(_.docUri[name] ? _.docUri[name] :  CFG.prepopulate_fields[name]);
				}
			}
		}
	}
	FormValidation.prototype.findZones = function() {
		var fieldZones = this.form.querySelectorAll('[data-zone="form field"]');

		// filter progressive zones
		if (this.totalProgressive) {
			_.consolelog('SHOW PROGRESSIVE ('+this.totalProgressive+'): ', CFG.show_progressive);
			_.forEach(fieldZones, function(item){
				var els = item.querySelectorAll('input, select, textarea');
				if (els.length) {
					if (els[0].attributes && els[0].attributes['data-progressive'] && els[0].attributes['data-progressive'].value) {
						if (!CFG.show_progressive[els[0].name]) {
							item.parentElement.removeChild(item);
						}
					}
				}
			})
		}
		var els = this.form.querySelectorAll('input, select, textarea');
		var self = this;
		var fieldGroups = {};
		_.forEach(els, function(el){
			if (el.type === 'submit' || el.type === 'image') return;
			if (!fieldGroups[el.name]) fieldGroups[el.name] = [];
			fieldGroups[el.name].push(el);
		});
		for (var i in fieldGroups) {
			this.zones[i] = new FormZone(fieldGroups[i], this);
		}
		this.zones['utm_source'] = new UtmSourceZone();

		var captchaTarget = this.form.querySelectorAll('[class="rm-captcha-target"]'); 
		if (!captchaTarget.length) return;

		window.RMCBRecaptchaCallback = function() {
			window.grecaptcha.render(captchaTarget[0], {
				'sitekey' : CFG.recaptcha.key
			});
			self.zones['rc_response'] = new CaptchaZone();
		}
		_.loadScript({url: CFG.recaptcha.url});
	}
	FormValidation.prototype.isValid = function(){
		var res;
		var valid = true;
		this.errors = [];
		for (var name in this.zones) {
			res = this.zones[name].isValid();
			valid = res && valid;
		}
		_.consolelog('FormValidation - FORM isValid? ', valid);
		this.renderErrors();
		return valid;
	}
	FormValidation.prototype.renderErrors = function(){
		_.consolelog('FormValidation - render errors');
		var firstError;
		var firstZone;
		for (var name in this.zones) {
			if (this.zones[name].errors.length) {
				if (!firstError) firstError = name;
				this.errors = this.errors.concat(this.zones[name].errors);
			}
			if (!firstZone) firstZone = name;
			this.zones[name].highlight(this.zones[name].errors.length > 0);
		}
		if (this.errors.length) this.zones[firstError || firstZone].putFocus();
		_.removeChildElements(this.errorContainer);
		_.forEach(this.errors, function(err){
			var li = document.createElement("li");
			li.innerHTML = err;
			this.errorContainer.appendChild(li);
		}, this);
		_.toggle(this.errorContainer, this.errors.length > 0);
	}
	FormValidation.prototype.getValues = function(){
		_.consolelog('FormValidation - get values');
		var res = [];
		for (var name in this.zones){
			var tmp = {};
			tmp[name] = this.zones[name].val();
			res.push(tmp);
		}
		return res;
	}

	return FormValidation;
})();

// insert into iframe
var IframeController = (function(){

	function IframeController(target){
		_.consolelog('IFRAME');
		var self = this;
		this.iFrame = document.createElement('iframe');
		this.iFrame.frameBorder = '0';
		this.iFrame.scrolling = 'no';
		this.iFrame.style = 'border:none;border-width:0px;';

		var str = '';
		for (var i in _.docUri) {
			str += (str ? '&' : '') + i + '=' + _.docUri[i];
		}
		CFG.uri += str ? ('?' + str) : '';

		var url = CFG.url.replace(/^(http:)|(https:)/, '');
		this.iFrame.src = url + '/' + CFG.uri + '#' + encodeURIComponent(window.location.origin);
		
		window.addEventListener('message', function(e){
			self.receiveMessage(e);
		}, false);
		target.appendChild(this.iFrame);
	}
	IframeController.prototype.cmds = {};
	IframeController.prototype.cmds.resize = function(params) {
		this.iFrame.style.height = params.height + 'px';
		this.iFrame.style.width = '100%';//params.width;
	};
	IframeController.prototype.cmds.redirect = function(params) {
		window.location.href = CFG.form_redirect_url;
	};
	IframeController.prototype.cmds.trackSubmission = function(params) {
		_.loadScript({
			url: CFG.lead_onsubmit_url + params.token
		});
	};
	IframeController.prototype.receiveMessage = function(e){
		_.consolelog('window got message:', e.data );
		if (this.cmds[e.data.msg] && e.data.tagId === CFG.id) {
			this.cmds[e.data.msg].call(this, e.data.params);
		}
	}
	return IframeController;
})();

// insert into div
var DivController = (function(){
	
	function IframeHost(tagId) {
		var self = this;
		this.tagId = tagId;
		this.parent = window.parent;
		this.parentOrigin = decodeURIComponent(window.location.hash.substring(1));
		this.size = {width: 0, height: 0};
		window.onload = function(){
			self.onload();
		}
	}
	IframeHost.prototype = {
		onload: function(){
			var self = this;
			document.documentElement.style.overflowY = 'hidden';
			this.checkSize();
			setInterval(function(){
				self.checkSize();
			}, 200);
		},
		checkSize: function(){
			var currentSize = _.docSize();
			if (currentSize.width !== this.size.width || currentSize.height !== this.size.height) {
				this.size.width = currentSize.width;
				this.size.height = currentSize.height;
				this.notify('resize');
			}
		},
		notify: function(msg, params){
			var data = {msg: msg, tagId: this.tagId};
			switch (msg) {
				case 'resize':
					data.params = {width: this.size.width, height: this.size.height};
					break;
				case 'redirect':
					_.consolelog('iframe asks to redirect');
					break;
				case 'submitted':
					data.params = params;
					break;
			}
			this.parent.postMessage(data, this.parentOrigin);		
		}
	}

	function buildChunks(formValues, token){
		var chunks = [];
		var tokenChunk = '_n=' + token;
		var chunk = '' + tokenChunk;
		var pair;
		_.forEach(formValues, function(item){
			for (var k in item) {
				pair = '&' + k + '=' + encodeURIComponent(item[k]);
				if ((chunk.length + pair.length) > maxUrlLength) {
					chunks.push(chunk);
					chunk = '' + tokenChunk;
				}
				chunk += pair;
			}
		});
		chunks.push(chunk);
		return chunks;
	}

	function DivController(target){
		if (_.isInForm(target)) {
			target.innerHTML = errorMessages.nestedForms;
			return;
		}

		this.target = target;
		
		if (_.ieVersion !== -1) {
			CFG.html = CFG.html.replace(/(@media[^{]+)(max-width)([^{]+{)/gm, '$1max-device-width$3');			
		}

		this.setPersonalizedData();
		this.target.innerHTML = CFG.html;

		this.initForm();
		this.updateBG();
		this.setIE8CommonStyles();
	}
	DivController.prototype.updateBG = function() {
		// set BODY's background properties the same as defined for ".he_stage" when within iframe or hosted at RM
		if (!_.isInIframe && !_.isRMHost) return;
		var tmp = this.target.querySelectorAll('.he_stage');
		if (!tmp.length) return;
		var applyToBody = ['backgroundColor', 'backgroundImage', 'backgroundRepeat', 'backgroundSize'];
		var styles = _.getComputedStyle(tmp[0]);
		_.forEach(applyToBody, function(item){
			if (styles[item]) {
				document.body.style[item] = styles[item];
			}
		});
	};
	DivController.prototype.setIE8CommonStyles = function(){
		// IE 8 apply styles only when they're in the <head> tag
		if (!_.isInIframe && !_.isRMHost) return;
		if (_.ieVersion != 8) return;
		var re = /<style(?:[\s+]type="text\/css")?>([\s\S]*?)<\/style>/gim;
		var commonStyles = re.exec(CFG.html);

		if (!commonStyles || commonStyles.length < 2) return;
		_.injectCSS(document.getElementsByTagName('head')[0], commonStyles[1]);
	};
	DivController.prototype.initForm = function(){
		var formZone = this.target.querySelectorAll('[data-zone="form"]')
		var form = this.target.querySelectorAll('form');
		var self = this;

		if (_.isInIframe) {
			this.iframeHost = new IframeHost(CFG.id);
		}

		_.trackUtmSource(this.target);
		if (_.isRMHost && !_.isInIframe) {
			this.trackLeadVisit();
		}

		if (form.length && formZone.length) {
			CFG.prepopulate_fields = CFG.prepopulate_fields ? JSON.parse(CFG.prepopulate_fields) : {};
			CFG.show_progressive = CFG.show_progressive ? JSON.parse(CFG.show_progressive) : {};
			this.validator = new FormValidation(formZone[0], function() {
				self.submitData();
			});
		}
	};
	DivController.prototype.submitData = function(){
		var self = this;
		var data = this.validator.getValues();

		_.consolelog('submitData!', data);

		var token = _.createToken();
		var chunks = buildChunks(data, token);
		var totalResponses = 0;
		var totalErrors = 0;
		var serverErrors = 0;
		var url;
		var errors = [];
		_.forEach(chunks, function(chunk){
			url = CFG.submit_url + '_t=' + chunks.length + '&' + chunk;
			_.consolelog('JSONP: ', url);
			_.JSONPRequest({
				url: url,
				onSuccess: function(data){
					_.consolelog('JSONP success: ', data);
					if (data.nonce != token || (data.status && data.status != 'success')) {
						totalErrors++;

						if (data.nonce != token) {
							self.validator.errors.push(errorMessages['submission_error']);
						} else if (data.status == 'missing') {
							if (self.validator.zones[data.message]) {
								self.validator.zones[data.message].addError(errorMessages['field_required']);
							} else {
								self.validator.errors.push(data.status + ': ' + data.message);
							}
						} else if (data.status == 'invalid') {
							if (self.validator.zones[data.message]) {
								self.validator.zones[data.message].addError(errorMessages['field_invalid']);
							} else {
								self.validator.errors.push(data.status + ': ' + data.message);
							}
						} else if (data.status == 'captcha') {
							if (self.validator.zones['rc_response']) {
								self.validator.zones['rc_response'].addError(captchaCodes[data.message] ? captchaCodes[data.message] : data.message);
							}
						} else if (data.status == 'database') {
							self.validator.errors.push(errorMessages['database_error']);
						} else {
							self.validator.errors.push(data.status + ': ' + data.message);
						}
					}
					if (data.token) {
						self.trackLeadSubmit(data.token);
					}
					checkLastResponse();
				},
				onError: function() {
					totalErrors++;
					serverErrors++;
					
					_.consolelog('JSONP server error: ', arguments);
					self.validator.submitBtn.removeAttribute('disabled');
					checkLastResponse();
				}
			});
		});

		function checkLastResponse() {
			totalResponses++;
			if (totalResponses != chunks.length) return;

			if (totalErrors) {
				self.validator.submitBtn.removeAttribute('disabled');
				_.consolelog('JSONP submission failed');
				if (serverErrors) {
					self.validator.errors.push(errorMessages['server_error']);
				}
				self.validator.renderErrors();
				if (window.grecaptcha) window.grecaptcha.reset();
				return;
			}
			_.consolelog('JSONP submission successfull');
			self.onSubmitDone();
		}
	};
	DivController.prototype.setPersonalizedData = function() {
		if (CFG.personalization) {
			CFG.personalization = JSON.parse(CFG.personalization);
			for (var keyword in CFG.personalization) {
				CFG.html = CFG.html.replace(keyword, CFG.personalization[keyword]);
			}
		}
	};
	DivController.prototype.onSubmitDone = function(){
		_.consolelog('submit done');
		// google analytics
		if (window.ga) {
			window.ga('send', 'event', 'landing page', 'submitted');
		}
		if (CFG.form_action == 'self') {
			this.validator.form.style.display = 'none';

			var thanksBlock = this.target.querySelectorAll('[data-hidden-content="thank"]');
			if (thanksBlock.length) {
				thanksBlock[0].style.display = 'block';
			}
		}
		if (CFG.form_action == 'redirect') {
			if (this.iframeHost) {
				this.iframeHost.notify('redirect');
			} else {
				window.location.href = CFG.form_redirect_url;
			}
		}
	};

	DivController.prototype.trackLeadVisit = function(){
		_.consolelog('* trackLeadVisit');
		if (CFG.lead_api) {
			_.loadScript({
				url: CFG.lead_script,
				onLoad: function(){
					if (window.com.realmagnet.MagnetLeads.init) {
						window.com.realmagnet.MagnetLeads.init(CFG.lead_api);
						window.com.realmagnet.MagnetLeads.visitPage();
					} else {
						console.log('com.realmagnet.MagnetLeads.init was not found');
					}
				}
			});
		}		
	}
	DivController.prototype.trackLeadSubmit = function(token) {
		_.consolelog('* trackLeadSubmit');
		if (CFG.lead_api) {
			_.loadScript({url: CFG.lead_onsubmit_url + token});
		}
	}


	return DivController;
})();

// start embedding
_.domReady(function(){
	var target = _.findTarget(CFG.id);

	if (_.ieVersion == 7) {
		target.innerHTML = "This page does not work properly in Internet Explorer 7. Please open this page with a modern browser.";
		return;
	}
	var scriptParams = _.parseURI(CFG.query_string);

	if (scriptParams._i) {
		var obj = new IframeController(target);
	} else {
		var obj = new DivController(target);
	}
});;

})();
