(function () {
	function r(e, n, t) {
		function o(i, f) {
			if (!n[i]) {
				if (!e[i]) {
					var c = "function" == typeof require && require;if (!f && c) return c(i, !0);if (u) return u(i, !0);var a = new Error("Cannot find module '" + i + "'");throw a.code = "MODULE_NOT_FOUND", a;
				}var p = n[i] = { exports: {} };e[i][0].call(p.exports, function (r) {
					var n = e[i][1][r];return o(n || r);
				}, p, p.exports, r, e, n, t);
			}return n[i].exports;
		}for (var u = "function" == typeof require && require, i = 0; i < t.length; i++) o(t[i]);return o;
	}return r;
})()({ 1: [function (require, module, exports) {
		// shim for using process in browser
		var process = module.exports = {};

		// cached from whatever global is present so that test runners that stub it
		// don't break things.  But we need to wrap it in a try catch in case it is
		// wrapped in strict mode code which doesn't define any globals.  It's inside a
		// function because try/catches deoptimize in certain engines.

		var cachedSetTimeout;
		var cachedClearTimeout;

		function defaultSetTimout() {
			throw new Error('setTimeout has not been defined');
		}
		function defaultClearTimeout() {
			throw new Error('clearTimeout has not been defined');
		}
		(function () {
			try {
				if (typeof setTimeout === 'function') {
					cachedSetTimeout = setTimeout;
				} else {
					cachedSetTimeout = defaultSetTimout;
				}
			} catch (e) {
				cachedSetTimeout = defaultSetTimout;
			}
			try {
				if (typeof clearTimeout === 'function') {
					cachedClearTimeout = clearTimeout;
				} else {
					cachedClearTimeout = defaultClearTimeout;
				}
			} catch (e) {
				cachedClearTimeout = defaultClearTimeout;
			}
		})();
		function runTimeout(fun) {
			if (cachedSetTimeout === setTimeout) {
				//normal enviroments in sane situations
				return setTimeout(fun, 0);
			}
			// if setTimeout wasn't available but was latter defined
			if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
				cachedSetTimeout = setTimeout;
				return setTimeout(fun, 0);
			}
			try {
				// when when somebody has screwed with setTimeout but no I.E. maddness
				return cachedSetTimeout(fun, 0);
			} catch (e) {
				try {
					// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
					return cachedSetTimeout.call(null, fun, 0);
				} catch (e) {
					// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
					return cachedSetTimeout.call(this, fun, 0);
				}
			}
		}
		function runClearTimeout(marker) {
			if (cachedClearTimeout === clearTimeout) {
				//normal enviroments in sane situations
				return clearTimeout(marker);
			}
			// if clearTimeout wasn't available but was latter defined
			if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
				cachedClearTimeout = clearTimeout;
				return clearTimeout(marker);
			}
			try {
				// when when somebody has screwed with setTimeout but no I.E. maddness
				return cachedClearTimeout(marker);
			} catch (e) {
				try {
					// When we are in I.E. but the script has been evaled so I.E. doesn't  trust the global object when called normally
					return cachedClearTimeout.call(null, marker);
				} catch (e) {
					// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
					// Some versions of I.E. have different rules for clearTimeout vs setTimeout
					return cachedClearTimeout.call(this, marker);
				}
			}
		}
		var queue = [];
		var draining = false;
		var currentQueue;
		var queueIndex = -1;

		function cleanUpNextTick() {
			if (!draining || !currentQueue) {
				return;
			}
			draining = false;
			if (currentQueue.length) {
				queue = currentQueue.concat(queue);
			} else {
				queueIndex = -1;
			}
			if (queue.length) {
				drainQueue();
			}
		}

		function drainQueue() {
			if (draining) {
				return;
			}
			var timeout = runTimeout(cleanUpNextTick);
			draining = true;

			var len = queue.length;
			while (len) {
				currentQueue = queue;
				queue = [];
				while (++queueIndex < len) {
					if (currentQueue) {
						currentQueue[queueIndex].run();
					}
				}
				queueIndex = -1;
				len = queue.length;
			}
			currentQueue = null;
			draining = false;
			runClearTimeout(timeout);
		}

		process.nextTick = function (fun) {
			var args = new Array(arguments.length - 1);
			if (arguments.length > 1) {
				for (var i = 1; i < arguments.length; i++) {
					args[i - 1] = arguments[i];
				}
			}
			queue.push(new Item(fun, args));
			if (queue.length === 1 && !draining) {
				runTimeout(drainQueue);
			}
		};

		// v8 likes predictible objects
		function Item(fun, array) {
			this.fun = fun;
			this.array = array;
		}
		Item.prototype.run = function () {
			this.fun.apply(null, this.array);
		};
		process.title = 'browser';
		process.browser = true;
		process.env = {};
		process.argv = [];
		process.version = ''; // empty string to avoid regexp issues
		process.versions = {};

		function noop() {}

		process.on = noop;
		process.addListener = noop;
		process.once = noop;
		process.off = noop;
		process.removeListener = noop;
		process.removeAllListeners = noop;
		process.emit = noop;
		process.prependListener = noop;
		process.prependOnceListener = noop;

		process.listeners = function (name) {
			return [];
		};

		process.binding = function (name) {
			throw new Error('process.binding is not supported');
		};

		process.cwd = function () {
			return '/';
		};
		process.chdir = function (dir) {
			throw new Error('process.chdir is not supported');
		};
		process.umask = function () {
			return 0;
		};
	}, {}], 2: [function (require, module, exports) {
		(function (setImmediate, clearImmediate) {
			var nextTick = require('process/browser.js').nextTick;
			var apply = Function.prototype.apply;
			var slice = Array.prototype.slice;
			var immediateIds = {};
			var nextImmediateId = 0;

			// DOM APIs, for completeness

			exports.setTimeout = function () {
				return new Timeout(apply.call(setTimeout, window, arguments), clearTimeout);
			};
			exports.setInterval = function () {
				return new Timeout(apply.call(setInterval, window, arguments), clearInterval);
			};
			exports.clearTimeout = exports.clearInterval = function (timeout) {
				timeout.close();
			};

			function Timeout(id, clearFn) {
				this._id = id;
				this._clearFn = clearFn;
			}
			Timeout.prototype.unref = Timeout.prototype.ref = function () {};
			Timeout.prototype.close = function () {
				this._clearFn.call(window, this._id);
			};

			// Does not start the time, just sets up the members needed.
			exports.enroll = function (item, msecs) {
				clearTimeout(item._idleTimeoutId);
				item._idleTimeout = msecs;
			};

			exports.unenroll = function (item) {
				clearTimeout(item._idleTimeoutId);
				item._idleTimeout = -1;
			};

			exports._unrefActive = exports.active = function (item) {
				clearTimeout(item._idleTimeoutId);

				var msecs = item._idleTimeout;
				if (msecs >= 0) {
					item._idleTimeoutId = setTimeout(function onTimeout() {
						if (item._onTimeout) item._onTimeout();
					}, msecs);
				}
			};

			// That's not how node.js implements it but the exposed api is the same.
			exports.setImmediate = typeof setImmediate === "function" ? setImmediate : function (fn) {
				var id = nextImmediateId++;
				var args = arguments.length < 2 ? false : slice.call(arguments, 1);

				immediateIds[id] = true;

				nextTick(function onNextTick() {
					if (immediateIds[id]) {
						// fn.call() is faster so we optimize for the common use-case
						// @see http://jsperf.com/call-apply-segu
						if (args) {
							fn.apply(null, args);
						} else {
							fn.call(null);
						}
						// Prevent ids from leaking
						exports.clearImmediate(id);
					}
				});

				return id;
			};

			exports.clearImmediate = typeof clearImmediate === "function" ? clearImmediate : function (id) {
				delete immediateIds[id];
			};
		}).call(this, require("timers").setImmediate, require("timers").clearImmediate);
	}, { "process/browser.js": 1, "timers": 2 }], 3: [function (require, module, exports) {
		let proto = typeof HTMLDialogElement !== "undefined" ? HTMLDialogElement : function Objs() {};
		proto = proto.prototype;
		let protoShowModal = proto.showModal;
		let protoShow = proto.show;
		let win = window;

		proto.showModal = function () {
			let event = win.document.createEvent("HTMLEvents");
			event.initEvent("showModal", true, true);

			event.eventName = "showModal";
			protoShowModal.apply(this);
			this.dispatchEvent(event);
		};

		proto.show = function () {
			let event = win.document.createEvent("HTMLEvents");
			event.initEvent("show", true, true);

			event.eventName = "show";
			protoShow.apply(this);
			this.dispatchEvent(event);
		};
	}, {}], 4: [function (require, module, exports) {
		if (Element && !Element.prototype.matches) {
			var proto = Element.prototype;
			proto.matches = proto.matchesSelector || proto.mozMatchesSelector || proto.msMatchesSelector || proto.oMatchesSelector || proto.webkitMatchesSelector;
		}
	}, {}], 5: [function (require, module, exports) {
		(function (global, setImmediate) {
			(function (global, factory) {
				typeof exports === 'object' && typeof module !== 'undefined' ? factory() : typeof define === 'function' && define.amd ? define(factory) : factory();
			})(this, function () {
				'use strict';

				var promiseFinally = function (callback) {
					var constructor = this.constructor;
					return this.then(function (value) {
						return constructor.resolve(callback()).then(function () {
							return value;
						});
					}, function (reason) {
						return constructor.resolve(callback()).then(function () {
							return constructor.reject(reason);
						});
					});
				};

				// Store setTimeout reference so promise-polyfill will be unaffected by
				// other code modifying setTimeout (like sinon.useFakeTimers())
				var setTimeoutFunc = setTimeout;

				function noop() {}

				// Polyfill for Function.prototype.bind
				function bind(fn, thisArg) {
					return function () {
						fn.apply(thisArg, arguments);
					};
				}

				function Promise(fn) {
					if (!(this instanceof Promise)) throw new TypeError('Promises must be constructed via new');
					if (typeof fn !== 'function') throw new TypeError('not a function');
					this._state = 0;
					this._handled = false;
					this._value = undefined;
					this._deferreds = [];

					doResolve(fn, this);
				}

				function handle(self, deferred) {
					while (self._state === 3) {
						self = self._value;
					}
					if (self._state === 0) {
						self._deferreds.push(deferred);
						return;
					}
					self._handled = true;
					Promise._immediateFn(function () {
						var cb = self._state === 1 ? deferred.onFulfilled : deferred.onRejected;
						if (cb === null) {
							(self._state === 1 ? resolve : reject)(deferred.promise, self._value);
							return;
						}
						var ret;
						try {
							ret = cb(self._value);
						} catch (e) {
							reject(deferred.promise, e);
							return;
						}
						resolve(deferred.promise, ret);
					});
				}

				function resolve(self, newValue) {
					try {
						// Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure
						if (newValue === self) throw new TypeError('A promise cannot be resolved with itself.');
						if (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) {
							var then = newValue.then;
							if (newValue instanceof Promise) {
								self._state = 3;
								self._value = newValue;
								finale(self);
								return;
							} else if (typeof then === 'function') {
								doResolve(bind(then, newValue), self);
								return;
							}
						}
						self._state = 1;
						self._value = newValue;
						finale(self);
					} catch (e) {
						reject(self, e);
					}
				}

				function reject(self, newValue) {
					self._state = 2;
					self._value = newValue;
					finale(self);
				}

				function finale(self) {
					if (self._state === 2 && self._deferreds.length === 0) {
						Promise._immediateFn(function () {
							if (!self._handled) {
								Promise._unhandledRejectionFn(self._value);
							}
						});
					}

					for (var i = 0, len = self._deferreds.length; i < len; i++) {
						handle(self, self._deferreds[i]);
					}
					self._deferreds = null;
				}

				function Handler(onFulfilled, onRejected, promise) {
					this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null;
					this.onRejected = typeof onRejected === 'function' ? onRejected : null;
					this.promise = promise;
				}

				/**
     * Take a potentially misbehaving resolver function and make sure
     * onFulfilled and onRejected are only called once.
     *
     * Makes no guarantees about asynchrony.
     */
				function doResolve(fn, self) {
					var done = false;
					try {
						fn(function (value) {
							if (done) return;
							done = true;
							resolve(self, value);
						}, function (reason) {
							if (done) return;
							done = true;
							reject(self, reason);
						});
					} catch (ex) {
						if (done) return;
						done = true;
						reject(self, ex);
					}
				}

				Promise.prototype['catch'] = function (onRejected) {
					return this.then(null, onRejected);
				};

				Promise.prototype.then = function (onFulfilled, onRejected) {
					var prom = new this.constructor(noop);

					handle(this, new Handler(onFulfilled, onRejected, prom));
					return prom;
				};

				Promise.prototype['finally'] = promiseFinally;

				Promise.all = function (arr) {
					return new Promise(function (resolve, reject) {
						if (!arr || typeof arr.length === 'undefined') throw new TypeError('Promise.all accepts an array');
						var args = Array.prototype.slice.call(arr);
						if (args.length === 0) return resolve([]);
						var remaining = args.length;

						function res(i, val) {
							try {
								if (val && (typeof val === 'object' || typeof val === 'function')) {
									var then = val.then;
									if (typeof then === 'function') {
										then.call(val, function (val) {
											res(i, val);
										}, reject);
										return;
									}
								}
								args[i] = val;
								if (--remaining === 0) {
									resolve(args);
								}
							} catch (ex) {
								reject(ex);
							}
						}

						for (var i = 0; i < args.length; i++) {
							res(i, args[i]);
						}
					});
				};

				Promise.resolve = function (value) {
					if (value && typeof value === 'object' && value.constructor === Promise) {
						return value;
					}

					return new Promise(function (resolve) {
						resolve(value);
					});
				};

				Promise.reject = function (value) {
					return new Promise(function (resolve, reject) {
						reject(value);
					});
				};

				Promise.race = function (values) {
					return new Promise(function (resolve, reject) {
						for (var i = 0, len = values.length; i < len; i++) {
							values[i].then(resolve, reject);
						}
					});
				};

				// Use polyfill for setImmediate for performance gains
				Promise._immediateFn = typeof setImmediate === 'function' && function (fn) {
					setImmediate(fn);
				} || function (fn) {
					setTimeoutFunc(fn, 0);
				};

				Promise._unhandledRejectionFn = function _unhandledRejectionFn(err) {
					if (typeof console !== 'undefined' && console) {
						console.warn('Possible Unhandled Promise Rejection:', err); // eslint-disable-line no-console
					}
				};

				var globalNS = function () {
					// the only reliable means to get the global object is
					// `Function('return this')()`
					// However, this causes CSP violations in Chrome apps.
					if (typeof self !== 'undefined') {
						return self;
					}
					if (typeof window !== 'undefined') {
						return window;
					}
					if (typeof global !== 'undefined') {
						return global;
					}
					throw new Error('unable to locate global object');
				}();

				if (!globalNS.Promise) {
					globalNS.Promise = Promise;
				} else if (!globalNS.Promise.prototype['finally']) {
					globalNS.Promise.prototype['finally'] = promiseFinally;
				}
			});
		}).call(this, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}, require("timers").setImmediate);
	}, { "timers": 2 }], 6: [function (require, module, exports) {
		let eventHandler = function (bwai) {
			let win = window;

			let getBeaconEventObject = require("./getBeaconEventObject");
			let serializeForm = require("./serializeForm");

			win.bwai.getBeaconEventObject = getBeaconEventObject;

			return new Promise(function (resolve) {
				let customElements = [];
				let pageExtensions = ["html", "htm", "php", "php5", "php4", "php7", "asp", "aspx", "cf", "cgi", "pl"];

				win.bwai.addCustomEvent = function (elm, fn) {
					win.document.querySelectorAll(elm).forEach(function (elmObj) {
						customElements[elmObj] = fn;
					});
				};

				win.bwai.addCustomPageExtension = function (ext) {
					pageExtensions.push(ext);
				};

				win.bwai.recordedEvents = [];

				win.bwai.checkoutTriggered = function (evt, totalCost, items, shipping) {
					getBeaconEventObject(evt.target, "ecom_payment_gateway", { x: evt.pageX, y: evt.pageY }).then(function (e) {
						if (win.bwai.debug) {
							console.log("add to basket item triggered", evt);
						}
						e.setData({
							items: items,
							cost: totalCost,
							shipping: shipping
						});
						win.bwai.recordedEvents.push(e);try {
							e.send();
						} catch (ex) {};
					});
				};

				win.bwai.addToBasket = function (evt, itm, cost, quantity) {
					getBeaconEventObject(evt.target, "ecom_basket_add", { x: evt.pageX, y: evt.pageY }).then(function (e) {
						if (win.bwai.debug) {
							console.log("add to basket item triggered", evt);
						}
						e.setData({
							item: itm,
							cost: cost,
							quantity: quantity
						});
						win.bwai.recordedEvents.push(e);try {
							e.send();
						} catch (ex) {};
					});
					return false;
				};

				win.bwai.rmFromBasked = function (evt, itm, cost, quantity) {
					getBeaconEventObject(evt.target, "ecom_basket_rm", { x: evt.pageX, y: evt.pageY }).then(function (e) {
						if (win.bwai.debug) {
							console.log("remove from basket item triggered", evt);
						}
						e.setData({
							item: itm,
							cost: cost,
							quantity: quantity
						});
						win.bwai.recordedEvents.push(e);try {
							e.send();
						} catch (ex) {};
					});
					return false;
				};

				win.bwai.checkoutSuccess = function () {
					getBeaconEventObject(null, "ecom_purchase_success").then(function (e) {
						if (win.bwai.debug) {
							console.log("purchase success triggered", evt);
						}
						win.bwai.recordedEvents.push(e);try {
							e.send();
						} catch (ex) {};
					});
				};

				win.bwai.checkoutFailed = function () {
					getBeaconEventObject(null, "ecom_purchase_fail").then(function (e) {
						if (win.bwai.debug) {
							console.log("purchase success triggered", evt);
						}
						win.bwai.recordedEvents.push(e);try {
							e.send();
						} catch (ex) {};
					});
				};

				function getParentAnchor(elm) {
					if (elm.matches("a")) {
						return elm;
					}

					if (elm.parentElement !== null) {
						if (elm.parentElement.matches("a")) {
							return elm.parentElement;
						} else {
							return getParentAnchor(elm.parentElement);
						}
					} else {
						return false;
					}
				}

				function parse_url(str, component) {
					let query;

					let mode = 'php';

					let key = ['source', 'scheme', 'authority', 'userInfo', 'user', 'pass', 'host', 'port', 'relative', 'path', 'directory', 'file', 'query', 'fragment'];

					// For loose we added one optional slash to post-scheme to catch file:/// (should restrict this)
					let parser = {
						php: new RegExp(['(?:([^:\\/?#]+):)?', '(?:\\/\\/()(?:(?:()(?:([^:@\\/]*):?([^:@\\/]*))?@)?([^:\\/?#]*)(?::(\\d*))?))?', '()', '(?:(()(?:(?:[^?#\\/]*\\/)*)()(?:[^?#]*))(?:\\?([^#]*))?(?:#(.*))?)'].join('')),
						strict: new RegExp(['(?:([^:\\/?#]+):)?', '(?:\\/\\/((?:(([^:@\\/]*):?([^:@\\/]*))?@)?([^:\\/?#]*)(?::(\\d*))?))?', '((((?:[^?#\\/]*\\/)*)([^?#]*))(?:\\?([^#]*))?(?:#(.*))?)'].join('')),
						loose: new RegExp(['(?:(?![^:@]+:[^:@\\/]*@)([^:\\/?#.]+):)?', '(?:\\/\\/\\/?)?', '((?:(([^:@\\/]*):?([^:@\\/]*))?@)?([^:\\/?#]*)(?::(\\d*))?)', '(((\\/(?:[^?#](?![^?#\\/]*\\.[^?#\\/.]+(?:[?#]|$)))*\\/?)?([^?#\\/]*))', '(?:\\?([^#]*))?(?:#(.*))?)'].join(''))
					};

					let m = parser[mode].exec(str);
					let uri = {};
					let i = 14;

					while (i--) {
						if (m[i]) {
							uri[key[i]] = m[i];
						}
					}

					if (component) {
						return uri[component.replace('PHP_URL_', '').toLowerCase()];
					}

					if (mode !== 'php') {
						let name = 'queryKey';
						parser = /(?:^|&)([^&=]*)=?([^&]*)/g;
						uri[name] = {};
						query = uri[key[12]] || '';
						query.replace(parser, function ($0, $1, $2) {
							if ($1) {
								uri[name][$1] = $2;
							}
						});
					}

					delete uri.source;
					return uri;
				}

				// setup the click event handler
				win.document.body.addEventListener('click', function (evt) {
					let triggered = false;
					// do we have a custom event defined for this element			
					if (customElements[evt.target] !== undefined) {
						triggered = true;
						let customEvent = customElements[evt.target].call(evt.target, evt);
						customEvent.then(function (e) {
							if (win.bwai.debug) {
								console.log("custom event triggered", e);
							}
							win.bwai.recordedEvents.push(e);try {
								e.send();
							} catch (ex) {};
						});
						return;
					}

					let parentAnchor = getParentAnchor(evt.target);

					// is this an anchor
					if (evt.target.matches("a") || parentAnchor) {
						let anch = evt.target;

						if (!evt.target.matches("a")) {
							anch = parentAnchor;
						}

						if (anch.hasAttribute("href")) {
							if (anch.hasAttribute("download")) {
								triggered = true;
								getBeaconEventObject(evt.target, "download", { x: evt.pageX, y: evt.pageY }).then(function (e) {
									if (win.bwai.debug) {
										console.log("download event triggered", evt);
									}
									e.setData(anch.getAttribute("href"));
									win.bwai.recordedEvents.push(e);try {
										e.send();
									} catch (ex) {};
								});
							} else {
								let href = anch.getAttribute("href");
								let path = anch.getAttribute("href").split("?", 1)[0];
								let dirs = path.split("/");
								let extParts = dirs[dirs.length - 1].split(".");
								let ext = "";
								if (extParts.length > 1 && dirs.length > 3) {
									ext = extParts.slice(-1)[0];
								}
								let method = href.split(":")[0];

								if (href.charAt(0) === "#") {
									triggered = true;
									getBeaconEventObject(evt.target, "anchor", { x: evt.pageX, y: evt.pageY }).then(function (e) {
										if (win.bwai.debug) {
											console.log("anchor event triggered", e);
										}
										win.bwai.recordedEvents.push(e);try {
											e.send();
										} catch (ex) {};
										if (win.bwai.debug) {
											console.log("Sent to beacon tracker", e);
										}
									});
								} else if (method === "mailto") {
									triggered = true;
									getBeaconEventObject(evt.target, "mailto", { x: evt.pageX, y: evt.pageY }).then(function (e) {
										if (win.bwai.debug) {
											console.log("mailto event triggered", e);
										}
										win.bwai.recordedEvents.push(e);try {
											e.send();
										} catch (ex) {};
										if (win.bwai.debug) {
											console.log("Sent to beacon tracker", e);
										}
									});
								} else if (method === "tel") {
									triggered = true;
									getBeaconEventObject(evt.target, "tel", { x: evt.pageX, y: evt.pageY }).then(function (e) {
										if (win.bwai.debug) {
											console.log("tel event triggered", e);
										}
										win.bwai.recordedEvents.push(e);try {
											e.send();
										} catch (ex) {};
										if (win.bwai.debug) {
											console.log("Sent to beacon tracker", e);
										}
									});
								} else {
									if (ext !== "" && ext !== "/" && pageExtensions.indexOf(ext) == -1) {
										triggered = true;
										getBeaconEventObject(evt.target, "download", { x: evt.pageX, y: evt.pageY }).then(function (e) {
											if (win.bwai.debug) {
												console.log("download event triggered", e);
											}
											e.setData(anch.getAttribute("href"));
											win.bwai.recordedEvents.push(e);try {
												e.send();
											} catch (ex) {};
											if (win.bwai.debug) {
												console.log("Sent to beacon tracker", e);
											}
										});
									} else {
										let parsed_url = parse_url(href);
										let internal = parsed_url.scheme == undefined || parsed_url.scheme + ":" == win.document.location.protocol && parsed_url.host == win.document.location.host;
										if (internal) {
											triggered = true;
											getBeaconEventObject(evt.target, "internal_link", { x: evt.pageX, y: evt.pageY }).then(function (e) {
												if (win.bwai.debug) {
													console.log("internal link event triggered", evt);
												}
												e.setData(anch.getAttribute("href"));
												win.bwai.recordedEvents.push(e);try {
													e.send();
												} catch (ex) {};
												if (win.bwai.debug) {
													console.log("Sent to beacon tracker", e);
												}
											});
										} else {
											triggered = true;
											getBeaconEventObject(evt.target, "external_link", { x: evt.pageX, y: evt.pageY }).then(function (e) {
												if (win.bwai.debug) {
													console.log("external link event triggered", e);
												}
												e.setData(anch.getAttribute("href"));
												win.bwai.recordedEvents.push(e);try {
													e.send();
												} catch (ex) {};
												if (win.bwai.debug) {
													console.log("Sent to beacon tracker", e);
												}
											});
										}
									}
								}
							}
						}
					}

					// is this a canvas tag
					if (evt.target.matches("canvas")) {
						triggered = true;
						getBeaconEventObject(evt.target, "canvas_interaction", { x: evt.pageX, y: evt.pageY }).then(function (e) {
							if (win.bwai.debug) {
								console.log("canvas click interaction event triggered", e);
							}
							win.bwai.recordedEvents.push(e);try {
								e.send();
							} catch (ex) {};
							if (win.bwai.debug) {
								console.log("Sent to beacon tracker", e);
							}
						});
					} else {
						if (!triggered) {
							getBeaconEventObject(evt.target, "click", { x: evt.pageX, y: evt.pageY }).then(function (e) {
								if (win.bwai.debug) {
									console.log("click interaction event triggered", e);
								}
								win.bwai.recordedEvents.push(e);try {
									e.send();
								} catch (ex) {};
								if (win.bwai.debug) {
									console.log("Sent to beacon tracker", e);
								}
							});
						}
					}
				});

				// bind to all forms
				win.document.querySelectorAll("form").forEach(function (itm) {
					itm.addEventListener("submit", function (evt) {
						getBeaconEventObject(itm, "form_submit", { x: evt.pageX, y: evt.pageY }).then(function (e) {
							serializeForm(itm).then(function (data) {
								if (win.bwai.debug) {
									console.log("form submited interaction event triggered", e, data);
								}
								e.setData(data);
								win.bwai.recordedEvents.push(e);try {
									e.send();
								} catch (ex) {};
								if (win.bwai.debug) {
									console.log("Sent to beacon tracker", e);
								}
							});
						});
					});
				});

				// bind to form items
				win.document.querySelectorAll("input, select, textarea, datalist").forEach(function (itm) {
					itm.addEventListener("change", function (evt) {
						getBeaconEventObject(itm, "input_specified", { x: evt.pageX, y: evt.pageY }).then(function (e) {
							if (win.bwai.debug) {
								console.log("input data set interaction event triggered", e);
							}
							win.bwai.recordedEvents.push(e);try {
								e.send();
							} catch (ex) {};
							if (win.bwai.debug) {
								console.log("Sent to beacon tracker", e);
							}
						});
					});
				});

				// bind to scroll to check for scroll up or down or scroll top / bottom
				let timeout;
				let startScroll = 0;
				win.document.addEventListener("scroll", function (evt) {
					if (timeout) {
						clearTimeout(timeout);
					}
					timeout = setTimeout(function () {
						let currentScroll = win.scrollY;
						let docHeight = win.document.height !== undefined ? win.document.height : win.document.body.offsetHeight;
						if (currentScroll <= 0) {
							//scroll top
							getBeaconEventObject(win.document.body, "hit_top", { x: evt.pageX, y: evt.pageY }).then(function (e) {
								if (win.bwai.debug) {
									console.log("hit top interaction event triggered", e);
								}
								e.setData({ "from": startScroll, "top": currentScroll });
								win.bwai.recordedEvents.push(e);try {
									e.send();
								} catch (ex) {};
								if (win.bwai.debug) {
									console.log("Sent to beacon tracker", e);
								}
							});
						} else if (currentScroll + win.innerHeight >= docHeight) {
							// scroll bottom
							getBeaconEventObject(win.document.body, "hit_bottom", { x: evt.pageX, y: evt.pageY }).then(function (e) {
								if (win.bwai.debug) {
									console.log("hit bottom interaction event triggered", e);
								}
								e.setData({ "from": startScroll, "top": currentScroll });
								win.bwai.recordedEvents.push(e);try {
									e.send();
								} catch (ex) {};
								if (win.bwai.debug) {
									console.log("Sent to beacon tracker", e);
								}
							});
						} else if (currentScroll > startScroll) {
							// scrolled down
							getBeaconEventObject(win.document.body, "scroll_down", { x: evt.pageX, y: evt.pageY }).then(function (e) {
								if (win.bwai.debug) {
									console.log("scroll down interaction event triggered", e);
								}
								e.setData({ "from": startScroll, "top": currentScroll });
								win.bwai.recordedEvents.push(e);try {
									e.send();
								} catch (ex) {};
								if (win.bwai.debug) {
									console.log("Sent to beacon tracker", e);
								}
							});
						} else if (currentScroll < startScroll) {
							// scrolled up
							getBeaconEventObject(win.document.body, "scroll_up", { x: evt.pageX, y: evt.pageY }).then(function (e) {
								if (win.bwai.debug) {
									console.log("scroll up interaction event triggered", e);
								}
								e.setData({ "from": startScroll, "top": currentScroll });
								win.bwai.recordedEvents.push(e);try {
									e.send();
								} catch (ex) {};
								if (win.bwai.debug) {
									console.log("Sent to beacon tracker", e);
								}
							});
						}
						startScroll = currentScroll;
					}, 200);
				});

				// hook into dialog show pollyfilled into the browsers
				win.document.querySelectorAll("dialog").forEach(function (itm) {
					itm.addEventListener("show", function (evt) {
						getBeaconEventObject(itm, "dialog_opened", { x: evt.pageX, y: evt.pageY }).then(function (e) {
							if (win.bwai.debug) {
								console.log("dialog opened interaction event triggered", e);
							}
							win.bwai.recordedEvents.push(e);try {
								e.send();
							} catch (ex) {};
							if (win.bwai.debug) {
								console.log("Sent to beacon tracker", e);
							}
						});
					});

					itm.addEventListener("showModal", function (evt) {
						getBeaconEventObject(itm, "modal_opened", { x: evt.pageX, y: evt.pageY }).then(function (e) {
							if (win.bwai.debug) {
								console.log("modal dialog opened interaction event triggered", e);
							}
							win.bwai.recordedEvents.push(e);try {
								e.send();
							} catch (ex) {};
							if (win.bwai.debug) {
								console.log("Sent to beacon tracker", e);
							}
						});
					});

					itm.addEventListener("close", function (evt) {
						getBeaconEventObject(itm, "dialog_close", { x: evt.pageX, y: evt.pageY }).then(function (evt) {
							if (win.bwai.debug) {
								console.log("dialog closed interaction event triggered", evt);
							}
							win.bwai.recordedEvents.push(evt);
						});
					});
				});

				// hook into the audio tags
				win.document.querySelectorAll("audio").forEach(function (itm) {
					let mediaSelf = itm;
					itm.addEventListener("play", function (evt) {
						if (mediaSelf.getAttribute("autoplay") === null) {
							getBeaconEventObject(itm, "audio_play", { x: evt.pageX, y: evt.pageY }).then(function (e) {
								e.setData({
									"progress": mediaSelf.currentTime,
									"volume": mediaSelf.volume,
									"controls": mediaSelf.controls ? "default" : "custom",
									"source": mediaSelf.currentSrc,
									"finished": mediaSelf.ended
								});
								win.bwai.recordedEvents.push(e);try {
									e.send();
								} catch (ex) {};
								if (win.bwai.debug) {
									console.log("Sent to beacon tracker", e);
								}
							});
						} else {
							getBeaconEventObject(itm, "audio_auto_play", { x: evt.pageX, y: evt.pageY }).then(function (e) {
								e.setData({
									"progress": mediaSelf.currentTime,
									"volume": mediaSelf.volume,
									"controls": mediaSelf.controls ? "default" : "custom",
									"source": mediaSelf.currentSrc,
									"finished": mediaSelf.ended
								});
								win.bwai.recordedEvents.push(e);try {
									e.send();
								} catch (ex) {};
								if (win.bwai.debug) {
									console.log("Sent to beacon tracker", e);
								}
							});
						}
					});

					itm.addEventListener("pause", function (evt) {
						getBeaconEventObject(itm, "audio_pause", { x: evt.pageX, y: evt.pageY }).then(function (e) {
							if (win.bwai.debug) {
								console.log("audio paused interaction event triggered", e);
							}
							e.setData({
								"progress": mediaSelf.currentTime,
								"volume": mediaSelf.volume,
								"controls": mediaSelf.controls ? "default" : "custom",
								"source": mediaSelf.currentSrc,
								"finished": mediaSelf.ended
							});
							win.bwai.recordedEvents.push(e);try {
								e.send();
							} catch (ex) {};
							if (win.bwai.debug) {
								console.log("Sent to beacon tracker", e);
							}
						});
					});

					itm.addEventListener("ended", function (evt) {
						getBeaconEventObject(itm, "audio_finished", { x: evt.pageX, y: evt.pageY }).then(function (e) {
							if (win.bwai.debug) {
								console.log(" audio finish event triggered", e);
							}
							e.setData({
								"progress": mediaSelf.currentTime,
								"volume": mediaSelf.volume,
								"controls": mediaSelf.controls ? "default" : "custom",
								"source": mediaSelf.currentSrc,
								"finished": mediaSelf.ended
							});
							win.bwai.recordedEvents.push(e);try {
								e.send();
							} catch (ex) {};
							if (win.bwai.debug) {
								console.log("Sent to beacon tracker", e);
							}
						});
					});

					itm.addEventListener("seeked", function (evt) {
						getBeaconEventObject(itm, "audio_seeked", { x: evt.pageX, y: evt.pageY }).then(function (e) {
							if (win.bwai.debug) {
								console.log("audio seeked interaction event triggered", e);
							}
							e.setData({
								"progress": mediaSelf.currentTime,
								"volume": mediaSelf.volume,
								"controls": mediaSelf.controls ? "default" : "custom",
								"source": mediaSelf.currentSrc,
								"finished": mediaSelf.ended
							});
							win.bwai.recordedEvents.push(e);try {
								e.send();
							} catch (ex) {};
							if (win.bwai.debug) {
								console.log("Sent to beacon tracker", e);
							}
						});
					});

					itm.addEventListener("volumechange", function (evt) {
						getBeaconEventObject(itm, "audio_volume_change", { x: evt.pageX, y: evt.pageY }).then(function (e) {
							if (win.bwai.debug) {
								console.log("audio volume changed interaction event triggered", e);
							}
							e.setData({
								"progress": mediaSelf.currentTime,
								"volume": mediaSelf.volume,
								"controls": mediaSelf.controls ? "default" : "custom",
								"source": mediaSelf.currentSrc,
								"finished": mediaSelf.ended
							});
							win.bwai.recordedEvents.push(e);try {
								e.send();
							} catch (ex) {};
							if (win.bwai.debug) {
								console.log("Sent to beacon tracker", e);
							}
						});
					});

					itm.addEventListener("waiting", function (evt) {
						getBeaconEventObject(itm, "audio_buffering", { x: evt.pageX, y: evt.pageY }).then(function (e) {
							if (win.bwai.debug) {
								console.log("video buffering interaction event triggered", e);
							}
							e.setData({
								"progress": mediaSelf.currentTime,
								"volume": mediaSelf.volume,
								"controls": mediaSelf.controls ? "default" : "custom",
								"source": mediaSelf.currentSrc,
								"finished": mediaSelf.ended
							});
							win.bwai.recordedEvents.push(e);try {
								e.send();
							} catch (ex) {};
							if (win.bwai.debug) {
								console.log("Sent to beacon tracker", e);
							}
						});
					});
				});

				// hook into the video tags
				win.document.querySelectorAll("video").forEach(function (itm) {
					let mediaSelf = itm;
					itm.addEventListener("play", function (evt) {
						if (mediaSelf.getAttribute("autoplay") === null) {
							getBeaconEventObject(itm, "video_play", { x: evt.pageX, y: evt.pageY }).then(function (e) {
								if (win.bwai.debug) {
									console.log("video play interaction event triggered", e);
								}
								e.setData({
									"progress": mediaSelf.currentTime,
									"volume": mediaSelf.volume,
									"controls": mediaSelf.controls ? "default" : "custom",
									"source": mediaSelf.currentSrc,
									"finished": mediaSelf.ended
								});
								win.bwai.recordedEvents.push(e);try {
									e.send();
								} catch (ex) {};
								if (win.bwai.debug) {
									console.log("Sent to beacon tracker", e);
								}
							});
						} else {
							if (win.bwai.debug) {
								console.log("video auto play interaction event triggered", e);
							}
							getBeaconEventObject(itm, "video_auto_play", { x: evt.pageX, y: evt.pageY }).then(function (e) {
								e.setData({
									"progress": mediaSelf.currentTime,
									"volume": mediaSelf.volume,
									"controls": mediaSelf.controls ? "default" : "custom",
									"source": mediaSelf.currentSrc,
									"finished": mediaSelf.ended
								});
								win.bwai.recordedEvents.push(e);try {
									e.send();
								} catch (ex) {};
								if (win.bwai.debug) {
									console.log("Sent to beacon tracker", e);
								}
							});
						}
					});
					itm.addEventListener("pause", function (evt) {
						getBeaconEventObject(itm, "video_pause", { x: evt.pageX, y: evt.pageY }).then(function (e) {
							if (win.bwai.debug) {
								console.log("video paused interaction event triggered", e);
							}
							e.setData({
								"progress": mediaSelf.currentTime,
								"volume": mediaSelf.volume,
								"controls": mediaSelf.controls ? "default" : "custom",
								"source": mediaSelf.currentSrc,
								"finished": mediaSelf.ended
							});
							win.bwai.recordedEvents.push(e);try {
								e.send();
							} catch (ex) {};
							if (win.bwai.debug) {
								console.log("Sent to beacon tracker", e);
							}
						});
					});
					itm.addEventListener("ended", function (evt) {
						getBeaconEventObject(itm, "video_finished", { x: evt.pageX, y: evt.pageY }).then(function (e) {
							if (win.bwai.debug) {
								console.log("video finished interaction event triggered", e);
							}
							e.setData({
								"progress": mediaSelf.currentTime,
								"volume": mediaSelf.volume,
								"controls": mediaSelf.controls ? "default" : "custom",
								"source": mediaSelf.currentSrc,
								"finished": mediaSelf.ended
							});
							win.bwai.recordedEvents.push(e);try {
								e.send();
							} catch (ex) {};
							if (win.bwai.debug) {
								console.log("Sent to beacon tracker", e);
							}
						});
					});
					itm.addEventListener("seeked", function (evt) {
						getBeaconEventObject(itm, "video_seeked", { x: evt.pageX, y: evt.pageY }).then(function (e) {
							if (win.bwai.debug) {
								console.log("video seeked interaction event triggered", e);
							}
							e.setData({
								"progress": mediaSelf.currentTime,
								"volume": mediaSelf.volume,
								"controls": mediaSelf.controls ? "default" : "custom",
								"source": mediaSelf.currentSrc,
								"finished": mediaSelf.ended
							});
							win.bwai.recordedEvents.push(e);try {
								e.send();
							} catch (ex) {};
							if (win.bwai.debug) {
								console.log("Sent to beacon tracker", e);
							}
						});
					});
					itm.addEventListener("volumechange", function (evt) {
						getBeaconEventObject(itm, "video_volume_change", { x: evt.pageX, y: evt.pageY }).then(function (e) {
							if (win.bwai.debug) {
								console.log("video volume changed interaction event triggered", e);
							}
							e.setData({
								"progress": mediaSelf.currentTime,
								"volume": mediaSelf.volume,
								"controls": mediaSelf.controls ? "default" : "custom",
								"source": mediaSelf.currentSrc,
								"finished": mediaSelf.ended
							});
							win.bwai.recordedEvents.push(e);try {
								e.send();
							} catch (ex) {};
							if (win.bwai.debug) {
								console.log("Sent to beacon tracker", e);
							}
						});
					});
					itm.addEventListener("waiting", function (evt) {
						getBeaconEventObject(itm, "video_buffering", { x: evt.pageX, y: evt.pageY }).then(function (e) {
							if (win.bwai.debug) {
								console.log("video buffering interaction event triggered", evt);
							}
							e.setData({
								"progress": mediaSelf.currentTime,
								"volume": mediaSelf.volume,
								"controls": mediaSelf.controls ? "default" : "custom",
								"source": mediaSelf.currentSrc,
								"finished": mediaSelf.ended
							});
							win.bwai.recordedEvents.push(e);try {
								e.send();
							} catch (ex) {};
							if (win.bwai.debug) {
								console.log("Sent to beacon tracker", e);
							}
						});
					});
				});

				resolve(win.bwai);
			});
		};

		module.exports = eventHandler;
	}, { "./getBeaconEventObject": 7, "./serializeForm": 15 }], 7: [function (require, module, exports) {
		let getBeaconEventObject = function (elm, eventType, mouse) {
			let getPathInfo = require("./getPathInfo");
			let BeaconEventObject = require("../Structures/BeaconEventObject");
			let win = window;

			return new Promise(function (resolve, reject) {
				if (elm === win) {
					console.log("something gone wrong");
					reject();
				}

				let evtObj = new BeaconEventObject(mouse === false ? false : true, elm === false ? false : true);
				evtObj.action = eventType;

				if (mouse) {
					evtObj.mouse.x = mouse.x;
					evtObj.mouse.y = mouse.y;
				}

				if (elm) {
					evtObj.element.type = elm.tagName;
					evtObj.element.class = elm.getAttribute("class");
					evtObj.element.id = elm.getAttribute("id");

					getPathInfo(elm).then(function (path) {
						evtObj.element.path = path;
						resolve(evtObj);
					}).catch(function () {
						reject(evtObj);
					});
				}

				resolve(evtObj);
			});
		};

		module.exports = getBeaconEventObject;
	}, { "../Structures/BeaconEventObject": 18, "./getPathInfo": 12 }], 8: [function (require, module, exports) {
		let win = window;
		let getBrowserInformation = function () {
			return new Promise(function (resolve) {
				var nAgt = navigator.userAgent;
				var browserName = navigator.appName;
				var fullVersion = '' + parseFloat(navigator.appVersion);
				var majorVersion = parseInt(navigator.appVersion, 10);
				var nameOffset, verOffset, ix;

				// In Opera, the true version is after "Opera" or after "Version"
				if ((verOffset = nAgt.indexOf("Opera")) !== -1) {
					browserName = "Opera";
					fullVersion = nAgt.substring(verOffset + 6);
					if ((verOffset = nAgt.indexOf("Version")) !== -1) {
						fullVersion = nAgt.substring(verOffset + 8);
					}
				}
				// In MSIE, the true version is after "MSIE" in userAgent
				else if ((verOffset = nAgt.indexOf("MSIE")) !== -1) {
						browserName = "Microsoft Internet Explorer";
						fullVersion = nAgt.substring(verOffset + 5);
					}
					// In Chrome, the true version is after "Chrome" 
					else if ((verOffset = nAgt.indexOf("Chrome")) !== -1) {
							browserName = "Chrome";
							fullVersion = nAgt.substring(verOffset + 7);
						}
						// In Safari, the true version is after "Safari" or after "Version" 
						else if ((verOffset = nAgt.indexOf("Safari")) !== -1) {
								browserName = "Safari";
								fullVersion = nAgt.substring(verOffset + 7);
								if ((verOffset = nAgt.indexOf("Version")) !== -1) {
									fullVersion = nAgt.substring(verOffset + 8);
								}
							}
							// In Firefox, the true version is after "Firefox" 
							else if ((verOffset = nAgt.indexOf("Firefox")) !== -1) {
									browserName = "Firefox";
									fullVersion = nAgt.substring(verOffset + 8);
								}
								// In most other browsers, "name/version" is at the end of userAgent 
								else if ((nameOffset = nAgt.lastIndexOf(' ') + 1) < (verOffset = nAgt.lastIndexOf('/'))) {
										browserName = nAgt.substring(nameOffset, verOffset);
										fullVersion = nAgt.substring(verOffset + 1);
										if (browserName.toLowerCase() === browserName.toUpperCase()) {
											browserName = navigator.appName;
										}
									}
				// trim the fullVersion string at semicolon/space if present
				if ((ix = fullVersion.indexOf(";")) !== -1) {
					fullVersion = fullVersion.substring(0, ix);
				}
				if ((ix = fullVersion.indexOf(" ")) !== -1) {
					fullVersion = fullVersion.substring(0, ix);
				}

				majorVersion = parseInt('' + fullVersion, 10);
				if (isNaN(majorVersion)) {
					fullVersion = '' + parseFloat(navigator.appVersion);
					majorVersion = parseInt(navigator.appVersion, 10);
				}

				resolve({
					"name": browserName,
					"full_version": fullVersion,
					"major_version": majorVersion,
					"user_agent": navigator.userAgent
				});
			});
		};

		module.exports = getBrowserInformation;
	}, {}], 9: [function (require, module, exports) {
		let win = window;
		let getFacebookLogin = function () {
			return new Promise(function (resolve, faile) {
				if (typeof w.FB !== "undefined") {
					w.FB.getLoginStatus(function (e) {
						if (e.status === "connected", typeof e.authResponse !== "undefined") {
							Facebook = {};
							FB.api('/me', function (response) {
								Facebook.name = response.name;
								Facebook.id = response.id;
							}, function (error) {
								fail();
							});
						}
					}, function () {
						fail();
					});
				}
			});
		};

		module.exports = getFacebookLogin;
	}, {}], 10: [function (require, module, exports) {
		let win = window;
		let getIPAddress = function () {
			return new Promise(function (resolve, fail) {
				var ajax = new XMLHttpRequest();
				ajax.addEventListener("load", function () {
					resolve(ajax.responseText);
				});
				ajax.addEventListener("error", function () {
					fail();
				});
				ajax.withCredentials = false;
				ajax.open("GET", "https://tracker.thisisbeacon.com/tracker/ip/?domain=" + encodeURIComponent(win.location.protocol + "|" + win.location.host), true);
				ajax.send();
			});
		};

		module.exports = getIPAddress;
	}, {}], 11: [function (require, module, exports) {
		let getOperatingSystem = function () {
			let win = window;

			return new Promise(function (resolve) {
				let mobile;
				let os;
				let osversion;
				let bit;
				let ua = win.navigator.userAgent;
				let platform = win.navigator.platform;

				function getMobile() {
					let check = false;
					(function (a) {
						if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4))) check = true;
					})(navigator.userAgent || navigator.vendor || window.opera);
					return check;
				};
				mobile = getMobile();

				function get_bits_system_architecture() {
					let _to_check = [];
					if (win.navigator.cpuClass) _to_check.push((win.navigator.cpuClass + "").toLowerCase());
					if (win.navigator.platform) _to_check.push((win.navigator.platform + "").toLowerCase());
					if (navigator.userAgent) _to_check.push((navigator.userAgent + "").toLowerCase());

					let _64bits_signatures = ["x86_64", "x86-64", "Win64", "x64;", "amd64", "AMD64", "WOW64", "x64_64", "ia64", "sparc64", "ppc64", "IRIX64"];
					let _bits = 32,
					    _i,
					    _c;
					outer_loop: for (let _c = 0; _c < _to_check.length; _c++) {
						for (_i = 0; _i < _64bits_signatures.length; _i++) {
							if (_to_check[_c].indexOf(_64bits_signatures[_i].toLowerCase()) != -1) {
								_bits = 64;
								break outer_loop;
							}
						}
					}
					return _bits;
				}

				bits = get_bits_system_architecture();

				if (platform === 'MacIntel' || platform === 'MacPPC') {
					os = 'Mac OS X';
					osversion = /10[\.\_\d]+/.exec(ua)[0];
					if (/[\_]/.test(osversion)) {
						osversion = osversion.split('_').join('.');
					}
				} else if (platform === 'CrOS') {
					os = 'ChromeOS';
				} else if (platform === 'Win32' || platform === 'Win64') {
					os = 'Windows';
				} else if (!os && /Android/.test(ua)) {
					os = 'Android';
				} else if (!os && /Linux/.test(platform)) {
					os = 'Linux';
				} else if (!os && /Windows/.test(ua)) {
					os = 'Windows';
				}

				resolve({
					mobile: mobile,
					os: os,
					version: osversion,
					bit: bit
				});
			});
		};

		module.exports = getOperatingSystem;
	}, {}], 12: [function (require, module, exports) {
		let win = window;
		let getPathInfo = function (elm) {
			return new Promise(function (resolve) {

				function getPathInfoLoop(elm, currPath) {
					if (typeof currPath === "undefined") {
						currPath = "";
					}
					try {
						currPath += getPathInfoLoop(elm.parentElement, currPath);
					} catch (e) {
						return currPath;
					}
					if (currPath !== "") {
						currPath += " > ";
					}
					var elmId = "#" + elm.getAttribute("id");
					var elmClass = ".";
					if (elm.getAttribute("class") !== null) {
						elmClass += elm.getAttribute("class").replace(/\s+/g, ".");
					}
					if (elmClass.length > 10) {
						elmClass = elmClass.substring(0, 10);
					}
					currPath += elm.tagName.toLowerCase();
					if (elmId !== "#null" && elmId !== "#") {
						currPath += elmId;
					}
					if (elmClass !== ".null" && elmClass !== ".") {
						currPath += elmClass;
					}
					return currPath;
				}
				let path = getPathInfoLoop(elm);
				resolve(path);
			});
		};

		module.exports = getPathInfo;
	}, {}], 13: [function (require, module, exports) {
		let getRequestInformation = function () {
			let win = window;
			return new Promise(function (resolve) {
				resolve(Object.assign({
					"protocol": win.location.protocol,
					"host": typeof win.bwai.emulateSite !== "undefined" ? win.bwai.emulateSite : win.location.host,
					"path": typeof win.bwai.emulatePath !== "undefined" ? win.bwai.emulatePath : win.location.pathname,
					"query_string": win.location.search.substring(1)
				}, typeof win.bwai.emulateSite === "undefined" && typeof win.bwai.emulatePath === "undefined" ? {} : {
					"isEmulated": true,
					"real": {
						"host": win.location.host,
						"path": win.location.pathname
					}
				}));
			});
		};

		module.exports = getRequestInformation;
	}, {}], 14: [function (require, module, exports) {
		let BindMouseMove = function () {
			let win = window;
			let getBeaconEventObject = require("./getBeaconEventObject");

			let timer = 2000;
			let mouseMoves = [];

			window.addEventListener("mousemove", function (evt) {
				getBeaconEventObject(false, "mousemove", { x: evt.pageX, y: evt.pageY }).then(function (e) {
					mouseMoves.push(e);
				});
			});

			setInterval(function () {
				let send = mouseMoves;
				mouseMoves = [];

				if (send.length > 0) {
					getBeaconEventObject(false, "mouse_updates", false).then(function (e) {
						e.setData(send);
						if (win.bwai.debug) {
							console.log(`syncing mouse move data`, e);
						}
						win.bwai.recordedEvents.push(e);try {
							e.send();
						} catch (ex) {};
					});
				}
			}, timer);
		};

		module.exports = BindMouseMove;
	}, { "./getBeaconEventObject": 7 }], 15: [function (require, module, exports) {
		let serializeForm = function (form) {
			return new Promise(function (resolve) {
				var i,
				    j,
				    len,
				    jLen,
				    formElement,
				    q = [];
				function urlencode(str) {
					// http://kevin.vanzonneveld.net
					// Tilde should be allowed unescaped in future versions of PHP (as reflected below), but if you want to reflect current
					// PHP behavior, you would need to add ".replace(/~/g, '%7E');" to the following.
					return encodeURIComponent(str).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').replace(/\)/g, '%29').replace(/\*/g, '%2A').replace(/%20/g, '+');
				}
				function addNameValue(name, value) {
					q.push(urlencode(name) + '=' + urlencode(value));
				}
				if (!form || !form.nodeName || form.nodeName.toLowerCase() !== 'form') {
					throw 'You must supply a form element';
				}
				for (i = 0, len = form.elements.length; i < len; i++) {
					formElement = form.elements[i];
					if (formElement.name === '' || formElement.disabled) {
						continue;
					}
					switch (formElement.nodeName.toLowerCase()) {
						case 'input':
							switch (formElement.type) {
								case 'text':
								case 'hidden':
								case 'password':
								case 'button': // Not submitted when submitting form manually, though jQuery does serialize this and it can be an HTML4 successful control
								case 'submit':
									addNameValue(formElement.name, formElement.value);
									break;
								case 'checkbox':
								case 'radio':
									if (formElement.checked) {
										addNameValue(formElement.name, formElement.value);
									}
									break;
								case 'file':
									addNameValue(formElement.name, formElement.value); // Will work and part of HTML4 "successful controls", but not used in jQuery
									break;
								case 'reset':
									break;
								default:
									addNameValue(formElement.name, formElement.value);
									break;
							}
							break;
						case 'textarea':
							addNameValue(formElement.name, formElement.value);
							break;
						case 'select':
							switch (formElement.type) {
								case 'select-one':
									addNameValue(formElement.name, formElement.value);
									break;
								case 'select-multiple':
									for (j = 0, jLen = formElement.options.length; j < jLen; j++) {
										if (formElement.options[j].selected) {
											addNameValue(formElement.name, formElement.options[j].value);
										}
									}
									break;
							}
							break;
						case 'button':
							// jQuery does not submit these, though it is an HTML4 successful control
							switch (formElement.type) {
								case 'reset':
								case 'submit':
								case 'button':
									addNameValue(formElement.name, formElement.value);
									break;
							}
							break;
					}
				}
				resolve(q.join('&'));
			});
		};

		module.exports = serializeForm;
	}, {}], 16: [function (require, module, exports) {
		let VimeoHandler = function (bwai) {
			let win = window;
			let getBeaconEventObject = require("./getBeaconEventObject");

			return new Promise(function (resolve) {
				let VimVideos = win.document.querySelectorAll("iframe.bwai-vimeo");

				let processVimeoVids = function (vids) {
					vids.forEach(function (itm) {
						let Player = new win.Vimeo.Player(itm);

						Player.on('play', function (data) {
							getBeaconEventObject(itm, "video_play", {}).then(function (e) {
								if (win.bwai.debug) {
									console.log("video play interaction event triggered", e);
								}
								Player.getCurrentTime().then(function (seconds) {
									Player.getVolume().then(function (vol) {
										Player.getEnded().then(function (ended) {
											e.setData({
												"progress": seconds,
												"volume": vol,
												"controls": "vimeo",
												"source": itm.getAttribute("src"),
												"finished": ended
											});
											win.bwai.recordedEvents.push(e);try {
												e.send();
											} catch (ex) {};
											if (win.bwai.debug) {
												console.log("Sent to beacon tracker", e);
											}
										});
									});
								});
							});
						});

						Player.on('pause', function (data) {
							getBeaconEventObject(itm, "video_pause", {}).then(function (e) {
								if (win.bwai.debug) {
									console.log("video pause interaction event triggered", e);
								}
								Player.getCurrentTime().then(function (seconds) {
									Player.getVolume().then(function (vol) {
										Player.getEnded().then(function (ended) {
											e.setData({
												"progress": seconds,
												"volume": vol,
												"controls": "vimeo",
												"source": itm.getAttribute("src"),
												"finished": ended
											});
											win.bwai.recordedEvents.push(e);try {
												e.send();
											} catch (ex) {};
											if (win.bwai.debug) {
												console.log("Sent to beacon tracker", e);
											}
										});
									});
								});
							});
						});

						Player.on('ended', function (data) {
							getBeaconEventObject(itm, "video_finished", {}).then(function (e) {
								if (win.bwai.debug) {
									console.log("video finished interaction event triggered", e);
								}
								Player.getCurrentTime().then(function (seconds) {
									Player.getVolume().then(function (vol) {
										Player.getEnded().then(function (ended) {
											e.setData({
												"progress": seconds,
												"volume": vol,
												"controls": "vimeo",
												"source": itm.getAttribute("src"),
												"finished": ended
											});
											win.bwai.recordedEvents.push(e);try {
												e.send();
											} catch (ex) {};
											if (win.bwai.debug) {
												console.log("Sent to beacon tracker", e);
											}
										});
									});
								});
							});
						});

						Player.on('bufferstart', function (data) {
							getBeaconEventObject(itm, "video_buffering", {}).then(function (e) {
								if (win.bwai.debug) {
									console.log("video buffering interaction event triggered", e);
								}
								Player.getCurrentTime().then(function (seconds) {
									Player.getVolume().then(function (vol) {
										Player.getEnded().then(function (ended) {
											e.setData({
												"progress": seconds,
												"volume": vol,
												"controls": "vimeo",
												"source": itm.getAttribute("src"),
												"finished": ended
											});
											win.bwai.recordedEvents.push(e);try {
												e.send();
											} catch (ex) {};
											if (win.bwai.debug) {
												console.log("Sent to beacon tracker", e);
											}
										});
									});
								});
							});
						});

						Player.on('seeked', function (data) {
							getBeaconEventObject(itm, "video_seeked", {}).then(function (e) {
								if (win.bwai.debug) {
									console.log("video seeked interaction event triggered", e);
								}
								Player.getCurrentTime().then(function (seconds) {
									Player.getVolume().then(function (vol) {
										Player.getEnded().then(function (ended) {
											e.setData({
												"progress": seconds,
												"volume": vol,
												"controls": "vimeo",
												"source": itm.getAttribute("src"),
												"finished": ended
											});
											win.bwai.recordedEvents.push(e);try {
												e.send();
											} catch (ex) {};
											if (win.bwai.debug) {
												console.log("Sent to beacon tracker", e);
											}
										});
									});
								});
							});
						});

						Player.on('volumechange', function (data) {
							getBeaconEventObject(itm, "video_volume_change", {}).then(function (e) {
								if (win.bwai.debug) {
									console.log("video volume change interaction event triggered", e);
								}
								Player.getCurrentTime().then(function (seconds) {
									Player.getVolume().then(function (vol) {
										Player.getEnded().then(function (ended) {
											e.setData({
												"progress": seconds,
												"volume": vol,
												"controls": "vimeo",
												"source": itm.getAttribute("src"),
												"finished": ended
											});
											win.bwai.recordedEvents.push(e);try {
												e.send();
											} catch (ex) {};
											if (win.bwai.debug) {
												console.log("Sent to beacon tracker", e);
											}
										});
									});
								});
							});
						});
					});
				};

				// do we have any YouTube videos
				if (VimVideos.length > 0) {
					// check if the YT SDK is loaded
					if (typeof win.Vimeo === "undefined") {
						let VimLoaded = false;
						win.bwai.asyncLoadScript("//player.vimeo.com/api/player.js", function () {
							VimLoaded = true;
						});
						// wait for the youtube iframe sdk to be read.
						win.bwai.idleWait(function () {
							return VimLoaded;
						}, function () {
							processVimeoVids(VimVideos);
							resolve(win.bwai);
						});
					} else {
						processVimeoVids(VimVideos);
						resolve(win.bwai);
					}
				} else {
					resolve(win.bwai);
				}
			});
		};

		module.exports = VimeoHandler;
	}, { "./getBeaconEventObject": 7 }], 17: [function (require, module, exports) {
		let YoutubeHandler = function (bwai) {
			let win = window;
			let getBeaconEventObject = require("./getBeaconEventObject");

			return new Promise(function (resolve) {
				let YTVideos = win.document.querySelectorAll("iframe.bwai-youtube");

				// create callback function to go though videos and setup monitor
				let processYoutubeVids = function (vids) {
					vids.forEach(function (itm) {
						let id = itm.getAttribute("id");
						if (id === "" || id === null) {
							id = "yt_" + win.bwai.makeid();
						}
						itm.setAttribute("id", id);
						let src = itm.getAttribute("src");
						if (src.indexOf("?") === -1) {
							src += "?";
						}
						itm.setAttribute("src", src + "&enablejsapi=1&origin=" + win.document.location.origin);
						playerReady = function (ytLoadEvtD) {
							let Player = ytLoadEvtD.target;
							Player.addEventListener('onStateChange', function (evt) {
								console.log(evt);
								switch (evt.data) {
									case YT.PlayerState.PLAYING:
										getBeaconEventObject(itm, "video_play", { x: evt.pageX, y: evt.pageY }).then(function (e) {
											if (win.bwai.debug) {
												console.log("video play interaction event triggered", e);
											}
											e.setData({
												"progress": Player.getCurrentTime(),
												"volume": Player.getVolume(),
												"controls": "youtube",
												"source": itm.getAttribute("src"),
												"finished": Player.getDuration() - Player.getCurrentTime() <= 2
											});
											win.bwai.recordedEvents.push(e);try {
												e.send();
											} catch (ex) {};
											if (win.bwai.debug) {
												console.log("Sent to beacon tracker", e);
											}
										});
										break;

									case YT.PlayerState.PAUSED:
										getBeaconEventObject(itm, "video_pause", { x: evt.pageX, y: evt.pageY }).then(function (e) {
											if (win.bwai.debug) {
												console.log("video paused interaction event triggered", e);
											}
											e.setData({
												"progress": Player.getCurrentTime(),
												"volume": Player.getVolume(),
												"controls": "youtube",
												"source": itm.getAttribute("src"),
												"finished": Player.getDuration() - Player.getCurrentTime() <= 2
											});
											win.bwai.recordedEvents.push(e);try {
												e.send();
											} catch (ex) {};
											if (win.bwai.debug) {
												console.log("Sent to beacon tracker", e);
											}
										});
										break;

									case YT.PlayerState.ENDED:
										getBeaconEventObject(itm, "video_finished", { x: evt.pageX, y: evt.pageY }).then(function (e) {
											if (win.bwai.debug) {
												console.log("video finished interaction event triggered", e);
											}
											e.setData({
												"progress": Player.getCurrentTime(),
												"volume": Player.getVolume(),
												"controls": "youtube",
												"source": itm.getAttribute("src"),
												"finished": Player.getDuration() - Player.getCurrentTime() <= 2
											});
											win.bwai.recordedEvents.push(e);try {
												e.send();
											} catch (ex) {};
											if (win.bwai.debug) {
												console.log("Sent to beacon tracker", e);
											}
										});
										break;

									case YT.PlayerState.BUFFERING:
										getBeaconEventObject(itm, "video_buffering", { x: evt.pageX, y: evt.pageY }).then(function (e) {
											if (win.bwai.debug) {
												console.log("video buffering interaction event triggered", evt);
											}
											e.setData({
												"progress": Player.getCurrentTime(),
												"volume": Player.getVolume(),
												"controls": "youtube",
												"source": itm.getAttribute("src"),
												"finished": Player.getDuration() - Player.getCurrentTime() <= 2
											});
											win.bwai.recordedEvents.push(e);try {
												e.send();
											} catch (ex) {};
											if (win.bwai.debug) {
												console.log("Sent to beacon tracker", e);
											}
										});
										break;
								}
							});
						};

						new win.YT.Player(id, {
							events: {
								"onReady": playerReady
							}
						});
					});
				};

				// do we have any YouTube videos
				if (YTVideos.length > 0) {
					// check if the YT SDK is loaded
					if (typeof win.YT === "undefined") {
						let YTloaded = false;
						win.bwai.asyncLoadScript("//www.youtube.com/iframe_api", function () {
							YTloaded = true;
						});
						// wait for the youtube iframe sdk to be read.
						win.bwai.idleWait(function () {
							if (YTloaded) {
								if (typeof win.YT !== "undefined") {
									return typeof win.YT.Player === "function";
								} else {
									return false;
								}
							} else {
								return false;
							}
						}, function () {
							processYoutubeVids(YTVideos);
							resolve(win.bwai);
						});
					} else {
						processYoutubeVids(YTVideos);
						resolve(win.bwai);
					}
				} else {
					resolve(win.bwai);
				}
			});
		};

		module.exports = YoutubeHandler;
	}, { "./getBeaconEventObject": 7 }], 18: [function (require, module, exports) {
		module.exports = function BeaconEventData(withMouse, withElement) {
			var _this = this;

			let win = window;

			this.type = "action";
			this.cookie = win.bwai.cookie;
			this.action;
			this.data;

			if (withMouse !== false) {
				this.mouse = {
					"x": 0,
					"y": 0
				};
			}
			if (withElement !== false) {
				this.element = {
					"type": "",
					"class": "",
					"id": "",
					"path": ""
				};
			}

			this.page_load_id;
			if (win.bwai.getPageLoadId != undefined) {
				this.page_load_id = win.bwai.getPageLoadId();
			}

			this.timestamp = Math.floor(Date.now() / 1000);

			let Sent = false;
			let Send = function () {
				if (!Sent) {
					if (_this.page_load_id != undefined) {
						var ajax = new XMLHttpRequest();
						let loadedData = win.bwai.loadedData;
						ajax.withCredentials = false;
						let url = 'https://tracker.thisisbeacon.com/tracker/action';
						ajax.open("POST", url + "?domain=" + encodeURIComponent(loadedData.request_info.protocol + "|" + loadedData.request_info.host), true);
						ajax.send(JSON.stringify(_this));
						Sent = true;
					}
				}
			};

			let SetData = function (data) {
				_this.data = data;
				if (win.bwai.debug) {
					console.log("setting data", data, _this);
				}
			};

			this.setData = function (e) {
				return SetData(e);
			};

			this.send = function () {
				_this.page_load_id = win.bwai.getPageLoadId();
				_this.cookie = win.bwai.cookie;
				Send.apply(_this);
			};
		};
	}, {}], 19: [function (require, module, exports) {
		module.exports = {
			"IP": false,
			"facebook": false,
			"http": false,
			"browser": false,
			"os": false
		};
	}, {}], 20: [function (require, module, exports) {
		let win = window;

		function getQueryVariable(variable) {
			var query = window.location.search.substring(1);
			var vars = query.split("&");
			for (var i = 0; i < vars.length; i++) {
				var pair = vars[i].split("=");
				if (pair[0] == variable) {
					return pair[1];
				}
			}
			return false;
		}

		function getPageLoadId() {
			let plid = null;
			let queryplid = getQueryVariable("plid");
			if (queryplid === false) {
				plid = localStorage.getItem("last_plid");
			} else {
				plid = queryplid;
			}
			return plid;
		}

		module.exports = {
			"cookie": win.bwai.cookie,
			"request_info": {
				"protocol": "",
				"host": "",
				"path": "",
				"query_string": "",
				"last_plid": getPageLoadId()
			},
			"facebook": "",
			"IP": "unknown",
			"timestamp": Math.floor(Date.now() / 1000),
			"browser": {},
			"os": ""
		};
	}, {}], 21: [function (require, module, exports) {
		// load everything we need hooking into
		let readyEvts = [];
		let isReady = false;
		let win = window;

		function makeid(length) {
			var result = '';
			var characters = 'ABC0DEFGHIJK4LMNO0PQRST8UVW1X3YZabcd7efghijklm2nopqrstu98vwxyz';
			var charactersLength = characters.length;
			for (var i = 0; i < length; i++) {
				result += characters.charAt(Math.floor(Math.random() * charactersLength));
			}
			return result;
		}

		function isIframe() {
			try {
				return !(window.self == window.top);
			} catch (e) {
				return true;
			}
		}

		win.bwai = Object.assign({
			"debug": false,
			"version": "5.3.0",
			"cookie": "",
			"ready": function (fn) {
				if (!isReady) {
					readyEvts.push(fn);
				} else {
					fn();
				}
			},
			"childFrames": [],
			"frameIdent": makeid(64)
		}, typeof window.bwai !== "undefined" ? window.bwai : {});

		if (win.bwai.cookie == "") {
			win.bwai.cookie = makeid(32);
		}

		if (localStorage.getItem("bwai") !== null) {
			win.bwai.cookie = localStorage.getItem("bwai");
		} else {
			localStorage.setItem("bwai", win.bwai.cookie);
		}

		// create default iframe message handler so we can save them to inform once we're ready
		function DefaultMessageHandler(e) {
			try {
				if (e.data.substr(0, 10) === "bcn-ready:") {
					let ident = e.data.substr(10);
					win.bwai.childFrames[ident] = e.source.window.postMessage;
				}
			} catch (e) {}
		}

		async function Init() {

			// load Pollyfills
			require("./Pollyfill/ElementMatches.js");
			require("./Pollyfill/Promise.js");
			require("./Pollyfill/DialogEvents.js");

			// load storage objects
			win.bwai.loadedData = require("./Structures/LoadedData");
			let BlockingProcesses = require("./Structures/BlockingProcesses");

			// load methods
			let getOperatingSystem = require("./Promises/getOperatingSystem");
			let getRequestInformation = require("./Promises/getRequestInformation");
			let getBrowserInformation = require("./Promises/getBrowserInformation");
			let getFacebookLogin = require("./Promises/getFacebookLogin");
			let getIPAddress = require("./Promises/getIPAddress");

			win.bwai.asyncLoadScript = function (src, cb) {
				var script = document.createElement('script');
				script.onload = function () {
					cb();
				};
				script.src = src;
				document.head.appendChild(script);
				//or something of the likes
			};

			win.bwai.idleWait = function (rdyCheck, cb) {
				let state = false;
				let interval = setInterval(function () {
					state = rdyCheck();
					if (state) {
						clearInterval(interval);
						return cb();
					}
				}, 300);
			};

			// support video playback
			let vimeo = require("./Promises/vimeo");
			let youtube = require("./Promises/youtube");
			let mouseMove = require("./Promises/mouseMove");

			return new Promise(function (resolve) {
				getOperatingSystem().then(function (os) {
					win.bwai.loadedData.os = os;
					BlockingProcesses.os = true;
				});

				getRequestInformation().then(function (request_info) {
					win.bwai.loadedData.request_info = request_info;
					BlockingProcesses.http = true;
				});

				getBrowserInformation().then(function (browser) {
					win.bwai.loadedData.browser = browser;
					BlockingProcesses.browser = true;
				});

				getIPAddress().then(function (IP) {
					win.bwai.loadedData.IP = IP;
					BlockingProcesses.IP = true;
				}).catch(function () {
					win.bwai.loadedData.IP = "unknown";
					BlockingProcesses.IP = true;
				});

				getFacebookLogin().then(function (facebook) {
					win.bwai.loadedData.facebook = facebook;
					BlockingProcesses.facebook = true;
				}).catch(function () {
					win.bwai.loadedData.facebook = false;
					BlockingProcesses.facebook = true;
				});

				youtube();
				vimeo();
				mouseMove();

				let timeout;
				let resolveCheck = function () {
					clearTimeout(timeout);

					for (let key in BlockingProcesses) {
						if (!BlockingProcesses[key]) {
							timeout = setInterval(resolveCheck, 200);
							return;
						}
					}

					// triger page_load
					var ajax = new XMLHttpRequest();
					let url = '//tracker.thisisbeacon.com/tracker/';
					ajax.withCredentials = false;
					ajax.open("POST", url + "?domain=" + encodeURIComponent(win.bwai.loadedData.request_info.protocol + "|" + win.bwai.loadedData.request_info.host), true);
					ajax.onreadystatechange = function () {
						if (this.readyState === 4) {
							if (this.status == 200) {
								var data = JSON.parse(this.responseText);
								if (!isIframe()) {
									win.bwai.getPageLoadId = function () {
										return data.page_load_id;
									};
									// create actual handler because we have data to be ready for it now
									window.addEventListener("message", function (e) {
										try {
											if (e.data.substr(0, 10) === "bcn-ready:") {
												let ident = e.data.substr(10);
												e.source.window.postMessage({ "ident": ident, "plid": win.bwai.getPageLoadId(), "cookie": win.bwai.cookie }, "*");
											}
										} catch (e) {}
									});
									// remove the default we have a new one
									window.removeEventListener("message", DefaultMessageHandler);
									// go though the iframes registered before we were ready and notify them
									win.bwai.childFrames.forEach(function (val, key) {
										val({ "ident": key, "plid": win.bwai.getPageLoadId(), "cookie": win.bwai.cookie }, "*");
									});
									win.bwai.recordedEvents.forEach(function (itm) {
										itm.send(win.bwai.getPageLoadId());
									});
									isReady = true;
									readyEvts.forEach(function (val) {
										val();
									});
									win.document.querySelectorAll("form").forEach(function (itm) {
										let pglidInp = document.createElement("input");
										pglidInp.setAttribute("type", "hidden");
										pglidInp.setAttribute("name", "bwai_page_load_id");
										pglidInp.setAttribute("value", win.bwai.getPageLoadId());
										itm.appendChild(pglidInp);
									});
								}
							}
						}
					};

					ajax.send(JSON.stringify(win.bwai.loadedData));

					resolve(win.bwai);
				};
				timeout = setInterval(resolveCheck, 200);
			});
		}

		if (!isIframe()) {
			// register default handler
			window.addEventListener("message", DefaultMessageHandler());
			Init().then(function (bwai) {
				let eventHandler = require("./Promises/eventHandler");
				let p = eventHandler(bwai).then(function () {});
			});
		} else {
			//{"ident":ident, "plid":win.bwai.getPageLoadId(), "cookie":win.bwai.cookie}
			// if we are an iframe need to handle reciving the data
			window.addEventListener("message", function (e) {
				try {
					if (typeof e.data.ident !== "undefined" && e.data.ident === win.bwai.frameIdent) {
						console.log(e);
						win.bwai.getPageLoadId = function () {
							return e.data.plid;
						};
						win.bwai.cookie = e.data.cookie;
						Init().then(function (bwai) {
							let eventHandler = require("./Promises/eventHandler");
							let p = eventHandler(bwai).then(function () {});
						});
					}
				} catch (e) {}
			}, false);
			// notify parent we're ready
			window.top.postMessage(`bcn-ready:${win.bwai.frameIdent}`, "*");
		}
	}, { "./Pollyfill/DialogEvents.js": 3, "./Pollyfill/ElementMatches.js": 4, "./Pollyfill/Promise.js": 5, "./Promises/eventHandler": 6, "./Promises/getBrowserInformation": 8, "./Promises/getFacebookLogin": 9, "./Promises/getIPAddress": 10, "./Promises/getOperatingSystem": 11, "./Promises/getRequestInformation": 13, "./Promises/mouseMove": 14, "./Promises/vimeo": 16, "./Promises/youtube": 17, "./Structures/BlockingProcesses": 19, "./Structures/LoadedData": 20 }] }, {}, [21]);

