(
	function () {
	"use strict";
	let savedErrors = [], timeout;

	function sendReport(message) {
		let request = new XMLHttpRequest();
		request.open('POST', '/error/reporterror');
		request.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
		request.setRequestHeader('Content-Type', 'application/json');
		request.send(JSON.stringify(message));
	}

	/**
	 * @param {ErrorEvent} event
	 */
	function handleEvent(event) {
		if (event.lineno === 0 && event.filename === '' && event.colno === 0 && (event.message === '' || event.message === 'Script error.')) {
			return;
		}
		savedErrors.push(event);
		if (event.cancelable) {
			event.preventDefault();
			event.stopImmediatePropagation();
		}
		window.clearTimeout(timeout);
		timeout = window.setTimeout(sendReports, 500);
	}

	/**
	 * @param {ErrorEvent} event
	 */
	function sendEvent(event) {
		let message = {
			message: event.message,
			file: event.filename,
			line: event.lineno,
			column: event.colno,
			url: document.location.href,
			error: event.error || null
		};

		sendReport(message);
	}

	function sendReports() {
		let pending = savedErrors.length;

		if (pending > 10) {
			let aggregate = {};

			savedErrors.forEach(function (error) {
				let m = error.message + '::' + error.filename + '::' + error.lineno + '::' + error.colno;
				aggregate[m] = (aggregate[m] ?? 0) + 1;
			});

			console.info('Sending aggregate report for ' + pending + ' reports');
			sendReport({error: 'Aggregated errors', count: pending, details: aggregate});
			savedErrors = [];
		}
		else if (pending > 0) {
			console.info('Sending ' + pending + ' reports');
			while (savedErrors.length > 0) {
				sendEvent(savedErrors.shift());
			}
		}
	}

	if (document.location.host.indexOf('local') === -1) {
		window.addEventListener('error', handleEvent);
	}

	window.BundleSites = window.BundleSites || {};
	window.BundleSites.reportError = function (msg) {
		handleEvent(new ErrorEvent('error', new Error(msg)));
	};
})();


(function () {
	"use strict";

	function showElement() {
		// noinspection ES6ConvertVarToLetConst
		var warning = document.getElementById('old-browser');

		if (warning) {
			warning.removeAttribute('hidden');
		}
		else if (document.readyState !== 'complete') {
			window.setTimeout(showElement, 100);
		}
	}

	if (!(
		window.visualViewport || // FF91; Chrome 61; Safari 13;
		(window.InstallTrigger && Animation.prototype.updatePlaybackRate && Animation.prototype.updatePlaybackRate.toString().indexOf('[native code]') !== -1) || // FF >= v60
		(window.chrome && 'fontDisplay' in document.documentElement.style) || // Chrome >= v60 or Opera Equivalent
		(window.ApplePayError && window.RTCPeerConnectionIceEvent) // Safari >= v12
	)) {
		if (document.addEventListener) {
			document.addEventListener('readystatechange', showElement);
		}
		else {
			window.setTimeout(showElement, 100);
		}
	}
})();

