if (typeof document.addEventListener === 'function') {	
	document.addEventListener('DOMContentLoaded', function () {
		disbaleLIDotInNestedList();
		if (typeof renderMathInElement === "function") {
			renderMathInElement(document.body, [{ left: '\(', right: '\)', display: true }, { left: '\[', right: '\]', display: true }]);
		}
		addNonbreakDivs();
		apllyWatermark();
	});
} else {
	document.attachEvent('onreadystatechange', function () {
		disbaleLIDotInNestedList();
		if (typeof renderMathInElement === "function") {
			renderMathInElement(document.body, [{ left: '\(', right: '\)', display: true }, { left: '\[', right: '\]', display: true }]);
		}
		addNonbreakDivs();
		apllyWatermark();
	});
}



function addNonbreakDivsAround(headerElement) {
	var headers = document.getElementsByTagName(headerElement);
	for (i = 0; i < headers.length; i++) {
		var nodeParent = headers[i].parentNode;
		if (nodeParent.classList !== undefined && nodeParent.classList.contains('chapterHeader')) {
			var sibling = nodeParent.nextElementSibling;
			if (sibling !== null) {
				var divWrap = document.createElement("div");
				divWrap.classList.add('nobreak');
				headers[i].parentNode.parentNode.insertBefore(divWrap, nodeParent);
				divWrap.appendChild(nodeParent);
				divWrap.appendChild(sibling);
			}
		}
		else {
			if(nodeParent.nodeName != "TBODY")
			{
				var hsibling = headers[i].nextElementSibling;
				if (hsibling !== null) {
					var hdivWrap = document.createElement("div");
					if (hdivWrap.classList == undefined) {
						hdivWrap.className += " nobreak";
					}
					else {
						hdivWrap.classList.add('nobreak');
					}
					headers[i].parentNode.insertBefore(hdivWrap, headers[i]);
					hdivWrap.appendChild(headers[i]);
					hdivWrap.appendChild(hsibling);
				}
			}
		}
	}
}

function scrollToName(name) {
	Array.from(document.querySelectorAll('.watermarked')).forEach(function (el) {
		el.classList.add('watermarkedDisable');
		el.classList.remove('watermarked');
	});

	document.getElementsByName(name)[0].scrollIntoView();

	Array.from(document.querySelectorAll('.watermarkedDisable')).forEach(function (el) {
		el.classList.add('watermarked');
		el.classList.remove('watermarkedDisable');
	});
}

function scrollToId(id) {
	Array.from(document.querySelectorAll('.watermarked')).forEach(function (el) {
		el.classList.add('watermarkedDisable');
		el.classList.remove('watermarked');
	});

	document.getElementById(id).scrollIntoView();

	Array.from(document.querySelectorAll('.watermarkedDisable')).forEach(function (el) {
		el.classList.add('watermarked');
		el.classList.remove('watermarkedDisable');
	});
}

function apllyWatermark() {
	/**
	*Compatibility IE
	*/
	if (!Array.from) {
		Array.from = (function () {
			var toStr = Object.prototype.toString;
			var isCallable = function (fn) {
				return typeof fn === 'function' || toStr.call(fn) === '[object Function]';
			};
			var toInteger = function (value) {
				var number = Number(value);
				if (isNaN(number)) { return 0; }
				if (number === 0 || !isFinite(number)) { return number; }
				return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number));
			};
			var maxSafeInteger = Math.pow(2, 53) - 1;
			var toLength = function (value) {
				var len = toInteger(value);
				return Math.min(Math.max(len, 0), maxSafeInteger);
			};

			// The length property of the from method is 1.
			return function from(arrayLike/*, mapFn, thisArg */) {
				// 1. Let C be the this value.
				var C = this;

				// 2. Let items be ToObject(arrayLike).
				var items = Object(arrayLike);

				// 3. ReturnIfAbrupt(items).
				if (arrayLike == null) {
					throw new TypeError("Array.from requires an array-like object - not null or undefined");
				}

				// 4. If mapfn is undefined, then let mapping be false.
				var mapFn = arguments.length > 1 ? arguments[1] : void undefined;
				var T;
				if (typeof mapFn !== 'undefined') {
					// 5. else
					// 5. a If IsCallable(mapfn) is false, throw a TypeError exception.
					if (!isCallable(mapFn)) {
						throw new TypeError('Array.from: when provided, the second argument must be a function');
					}

					// 5. b. If thisArg was supplied, let T be thisArg; else let T be undefined.
					if (arguments.length > 2) {
						T = arguments[2];
					}
				}

				// 10. Let lenValue be Get(items, "length").
				// 11. Let len be ToLength(lenValue).
				var len = toLength(items.length);

				// 13. If IsConstructor(C) is true, then
				// 13. a. Let A be the result of calling the [[Construct]] internal method of C with an argument list containing the single item len.
				// 14. a. Else, Let A be ArrayCreate(len).
				var A = isCallable(C) ? Object(new C(len)) : new Array(len);

				// 16. Let k be 0.
				var k = 0;
				// 17. Repeat, while k < len… (also steps a - h)
				var kValue;
				while (k < len) {
					kValue = items[k];
					if (mapFn) {
						A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k);
					} else {
						A[k] = kValue;
					}
					k += 1;
				}
				// 18. Let putStatus be Put(A, "length", len, true).
				A.length = len;
				// 20. Return A.
				return A;
			};
		}());
	}
	if (!String.prototype.repeat) {
		String.prototype.repeat = function (count) {
			'use strict';
			if (this == null) {
				throw new TypeError('can\'t convert ' + this + ' to object');
			}
			var str = '' + this;
			count = +count;
			if (count != count) {
				count = 0;
			}
			if (count < 0) {
				throw new RangeError('repeat count must be non-negative');
			}
			if (count == Infinity) {
				throw new RangeError('repeat count must be less than infinity');
			}
			count = Math.floor(count);
			if (str.length == 0 || count == 0) {
				return '';
			}
			// Ensuring count is a 31-bit integer allows us to heavily optimize the
			// main part. But anyway, most current (August 2014) browsers can't handle
			// strings 1 << 28 chars or longer, so:
			if (str.length * count >= 1 << 28) {
				throw new RangeError('repeat count must not overflow maximum string size');
			}
			var rpt = '';
			for (var i = 0; i < count; i++) {
				rpt += str;
			}
			return rpt;
		}
	}
	/**
	*End Compatibility IE
	*/
	Array.from(document.querySelectorAll('.watermarked')).forEach(function (el) {
		var atribute = el.getAttribute("data-watermark");
		atribute = el.title;
		el.title = "";
		atribute = (atribute + ' ').repeat(40000);

		el.setAttribute("data-watermark", atribute);
		var height = document.body.scrollHeight * 1.2;
		el.pseudoStyle("before", "width", height + "px");
		el.pseudoStyle("before", "height", height + "px");
		el.pseudoStyle("before", "left", (height / -2) + "px");
	});
}
var UID = {
	_current: 0,
	getNew: function () {
		this._current++;
		return this._current;
	}
};

HTMLElement.prototype.pseudoStyle = function (element, prop, value) {
	var _this = this;
	var _sheetId = "pseudoStyles";
	var _head = document.head || document.getElementsByTagName('head')[0];
	var _sheet = document.getElementById(_sheetId) || document.createElement('style');
	_sheet.id = _sheetId;
	var className = "pseudoStyle" + UID.getNew();

	_this.className += " " + className;

	_sheet.innerHTML += " ." + className + ":" + element + "{" + prop + ":" + value + "}";
	_head.appendChild(_sheet);
	return this;
};

function removeElementsByClass(className) {
	var elements = document.getElementsByClassName(className);
	while (elements.length > 0) {
		elements[0].parentNode.removeChild(elements[0]);
	}
}
function disbaleLIDotInNestedList() {
	var lis = document.getElementsByTagName("LI");
	for (i = 0; i < lis.length; i++) {
		for (j = 0; j < lis[i].children.length; j++) {
			if (lis[i].children[j].tagName === "UL") {
				lis[i].classList.remove("nodot");
				lis[i].classList.add("nodot");
				break;
			}
		}
	}
}

function formulaToImg(check) {
	//default parameter - IE fix
	if (check === undefined) {
		check = false;
	}
	//original source because conver to img
	removeElementsByClass('katex-mathml');

	var divinlines = document.getElementsByClassName("div-inline");
	while (divinlines.length) {
		for (i = 0; divinlines.length > i; i++) {
			divinlines[i].classList.remove("div-inline");
		}
		divinlines = document.getElementsByClassName("div-inline");
	}

	//all node with class formula-text transform/replace by image
	var formulaRows = document.getElementsByClassName('formula-text');
	var promis = [];
	for (i = 0; i < formulaRows.length; i++) {
		var formulaNode1 = formulaRows[i];
		var curriedDoWork = function (formulaNode) {
			return function (dataUrl) {
				var img = new Image();
				img.src = dataUrl;
				var numChild = formulaNode.childElementCount;
				while (formulaNode.firstChild) {
					formulaNode.removeChild(formulaNode.firstChild);
				}
				if ("TR".localeCompare(formulaNode.tagName) === 0) {
					var newTd = document.createElement('td');
					newTd.setAttribute('colspan', numChild);
					newTd.appendChild(img);
					formulaNode.appendChild(newTd);
				}
				else {
					formulaNode.appendChild(img);
					formulaNode.classList.remove("formula-text");
				}
			}
		};
		promis.push(
			domtoimage.toPng(formulaNode1)
				.then(curriedDoWork(formulaNode1))
				.catch(function (error) {
					console.error('oops, something went wrong!' + error.message, error);
				}));
	}
	Promise.all(promis).then(function (responses) {
		//sometime left some formulas
		if (check) {
			removeElementsByClass('katex');
			callbackObj.generateHtml();
		}
		else {
			formulaToImg(true);
		}

	});
}