function i(a) { var b = "'" + a.replace(/'/g, "\\'").replace(/(\$[.\w]+\[\$[.\w]+\]|(\$[.\w]+))/g, "'+$1+'").replace(/\$\.(\w)/g, "this.$1").replace(/<\/\./g, " -1; for ($_ in $arg) this[$_] = $arg[$_]; $arg.words || (this.words = new Array("foo", "bar", "baz", "xyzzy")), $arg.interval || (this.interval = 500), this.current = 0, this.iscorrect = new Array, this.starttime = 0, this.chars = 0, this.goodchars = 0, this.keypresses = 0, this.lastword = !1, this.wrongwords = new Array, this.interval_id, this.rawcpm, this.cpm, this.wpm, this.enterused = !1, this.do_hook = function(a, b, c, d, e) { this[a] && this[a].apply(this, new Array(b, c, d, e)) }, this.render = function() { this.do_hook("before_render"); var $newhtml = ""; if (this.current) for (var $i = 0; $i < this.current; $i++) { var $class = this.iscorrect[$i] ? "correct" : "incorrect"; $newhtml += eval(i("$.words[$i]")) } $newhtml += eval(i("$.words[$.current]")), $newhtml += "" + this.words.slice(this.current + 1, this.words.length).join("") + ""; var $words_el = el("words"); $words_el.innerHTML = $newhtml, this.opera && ($words_el.crollTop = 0); var $scrollbase_el = el("currentword"), $scroll = $scrollbase_el.offsetTop - el("currentword").offsetHeight; $scroll -= $words_el.offsetTop, 0 > $scroll && ($scroll = 0), $($words_el).stop(!0, !0).animate({ scrollTop: $scroll }, 500), this.do_hook("after_render") }, this.calcspeed = function() { var a = time() - this.starttime; a && this.current && (this.do_hook("before_calcspeed", a), this.rawcpm = Math.floor(this.chars / a * 60), this.cpm = Math.floor(this.goodchars / a * 60), this.wpm = Math.round(this.cpm / 5), this.do_hook("after_calcspeed", a)) }, this.advance = function() { this.do_hook("before_advance"), this.current++, this.current >= this.words.length && (this.lastword = !0), this.calcspeed(), this.lastword ? (clearInterval(this.interval_id), el("input").disabled = 1, el("wordsbox").innerHTML = this.report ? this.report() : "Done!") : this.render(), this.do_hook("after_advance") }, this.beforgiving = function() {}, this.keypress = function(a, b) { for (var c = a.value, d = c.length, e = this.words[this.current], f = "", g = 0; g < e.length; g++) f += g >= c.length ? e[g] : e[g] == c[g] ? "" + e[g] + "" : "" + e[g] + ""; if ($("#currentword").html(f), this.do_hook("before_keypress", c), d) { this.keypresses++; var h = b.which ? b.which : b.keyCode; if (13 == h && (this.enterused || alert("Use space bar instead of enter. It's faster. Use the 'Restart' link to start over."), this.enterused = !0, a.value = c += " "), !c.match(/[^ ]/)) return a.value = c.replace(/^ +/, ""), void 0; if (!this.starttime) { this.starttime = time(); var i = this; this.interval_id = setInterval(this.ticktock ? function() { i.ticktock() } : function() {}, this.interval) } var j = c.match(/^.+? /); if (!j) return this.do_hook("after_keypress", c), void 0; $wordsandspace = new String(j), a.value = c.replace(/^.+? +/, ""), this.chars += $wordsandspace.length; var k = $wordsandspace.match(/^[^ ]+/), l = this.words[this.current]; if (k == l) this.do_hook("on_correct_word", k), this.goodchars += $wordsandspace.length, this.iscorrect[this.current] = !0, this.advance(); else if (this.allowwrong) { if (this.do_hook("on_wrong_word", k, l), !this.strictwrong) for (var m = -2; 3 >= m; m++) if (0 != m && k == this.words[this.current + m]) { if (m > 0) for (var n = 0; m > n; n++) this.do_hook("on_skipped_word", this.words[this.current]), this.iscorrect[this.current] = !1, this.current++; else { if (this.iscorrect[this.current + m]) break; for (var o = new Array; 0 > m; m++) this.current--, o.unshift(this.wrongwords[this.current]); this.do_hook("on_extra_words", o) } this.goodchars += $wordsandspace.length, this.iscorrect[this.current] = !0 } this.advance() } else $("#currentword").html(this.words[this.current]); this.do_hook("after_keypress", c) } }, this.init = function() { this.do_hook("before_init"), this.render(), this.do_hook("after_init") } } function restart() { window.location.reload() }! function(a, b) { "object" == typeof module && "object" == typeof module.exports ? module.exports = a.document ? b(a, !0) : function(a) { if (!a.document) throw new Error("jQuery requires a window with a document"); return b(a) } : b(a) }("undefined" != typeof window ? window : this, function(a, b) { function s(a) { var b = a.length, c = n.type(a); return "function" === c || n.isWindow(a) ? !1 : 1 === a.nodeType && b ? !0 : "array" === c || 0 === b || "number" == typeof b && b > 0 && b - 1 in a } function x(a, b, c) { if (n.isFunction(b)) return n.grep(a, function(a, d) { return !!b.call(a, d, a) !== c }); if (b.nodeType) return n.grep(a, function(a) { return a === b !== c }); if ("string" == typeof b) { if (w.test(b)) return n.filter(b, a, c); b = n.filter(b, a) } return n.grep(a, function(a) { return n.inArray(a, b) >= 0 !== c }) } function E(a, b) { do a = a[b]; while (a && 1 !== a.nodeType); return a } function H(a) { var b = G[a] = {}; return n.each(a.match(F) || [], function(a, c) { b[c] = !0 }), b } function J() { z.addEventListener ? (z.removeEventListener("DOMContentLoaded", K, !1), a.removeEventListener("load", K, !1)) : (z.detachEvent("onreadystatechange", K), a.detachEvent("onload", K)) } function K() { (z.addEventListener || "load" === event.type || "complete" === z.readyState) && (J(), n.ready()) } function P(a, b, c) { if (void 0 === c && 1 === a.nodeType) { var d = "data-" + b.replace(O, "-$1").toLowerCase(); if (c = a.getAttribute(d), "string" == typeof c) { try { c = "true" === c ? !0 : "false" === c ? !1 : "null" === c ? null : +c + "" === c ? +c : N.test(c) ? n.parseJSON(c) : c } catch (e) {} n.data(a, b, c) } else c = void 0 } return c } function Q(a) { var b; for (b in a) if (("data" !== b || !n.isEmptyObject(a[b])) && "toJSON" !== b) return !1; return !0 } function R(a, b, d, e) { if (n.acceptData(a)) { var f, g, h = n.expando, i = a.nodeType, j = i ? n.cache : a, k = i ? a[h] : a[h] && h; if (k && j[k] && (e || j[k].data) || void 0 !== d || "string" != typeof b) return k || (k = i ? a[h] = c.pop() || n.guid++ : h), j[k] || (j[k] = i ? {} : { toJSON: n.noop }), ("object" == typeof b || "function" == typeof b) && (e ? j[k] = n.extend(j[k], b) : j[k].data = n.extend(j[k].data, b)), g = j[k], e || (g.data || (g.data = {}), g = g.data), void 0 !== d && (g[n.camelCase(b)] = d), "string" == typeof b ? (f = g[b], null == f && (f = g[n.camelCase(b)])) : f = g, f } } function S(a, b, c) { if (n.acceptData(a)) { var d, e, f = a.nodeType, g = f ? n.cache : a, h = f ? a[n.expando] : n.expando; if (g[h]) { if (b && (d = c ? g[h] : g[h].data)) { n.isArray(b) ? b = b.concat(n.map(b, n.camelCase)) : b in d ? b = [b] : (b = n.camelCase(b), b = b in d ? [b] : b.split(" ")), e = b.length; for (; e--;) delete d[b[e]]; if (c ? !Q(d) : !n.isEmptyObject(d)) return }(c || (delete g[h].data, Q(g[h]))) && (f ? n.cleanData([a], !0) : l.deleteExpando || g != g.window ? delete g[h] : g[h] = null) } } } function bb() { return !0 } function cb() { return !1 } function db() { try { return z.activeElement } catch (a) {} } function eb(a) { var b = fb.split("|"), c = a.createDocumentFragment(); if (c.createElement) for (; b.length;) c.createElement(b.pop()); return c } function vb(a, b) { var c, d, e = 0, f = typeof a.getElementsByTagName !== L ? a.getElementsByTagName(b || "*") : typeof a.querySelectorAll !== L ? a.querySelectorAll(b || "*") : void 0; if (!f) for (f = [], c = a.childNodes || a; null != (d = c[e]); e++) !b || n.nodeName(d, b) ? f.push(d) : n.merge(f, vb(d, b)); return void 0 === b || b && n.nodeName(a, b) ? n.merge([a], f) : f } function wb(a) { X.test(a.type) && (a.defaultChecked = a.checked) } function xb(a, b) { return n.nodeName(a, "table") && n.nodeName(11 !== b.nodeType ? b : b.firstChild, "tr") ? a.getElementsByTagName("tbody")[0] || a.appendChild(a.ownerDocument.createElement("tbody")) : a } function yb(a) { return a.type = (null !== n.find.attr(a, "type")) + "/" + a.type, a } function zb(a) { var b = qb.exec(a.type); return b ? a.type = b[1] : a.removeAttribute("type"), a } function Ab(a, b) { for (var c, d = 0; null != (c = a[d]); d++) n._data(c, "globalEval", !b || n._data(b[d], "globalEval")) } function Bb(a, b) { if (1 === b.nodeType && n.hasData(a)) { var c, d, e, f = n._data(a), g = n._data(b, f), h = f.events; if (h) { delete g.handle, g.events = {}; for (c in h) for (d = 0, e = h[c].length; e > d; d++) n.event.add(b, c, h[c][d]) } g.data && (g.data = n.extend({}, g.data)) } } function Cb(a, b) { var c, d, e; if (1 === b.nodeType) { if (c = b.nodeName.toLowerCase(), !l.noCloneEvent && b[n.expando]) { e = n._data(b); for (d in e.events) n.removeEvent(b, d, e.handle); b.removeAttribute(n.expando) } "script" === c && b.text !== a.text ? (yb(b).text = a.text, zb(b)) : "object" === c ? (b.parentNode && (b.outerHTML = a.outerHTML), l.html5Clone && a.innerHTML && !n.trim(b.innerHTML) && (b.innerHTML = a.innerHTML)) : "input" === c && X.test(a.type) ? (b.defaultChecked = b.checked = a.checked, b.value !== a.value && (b.value = a.value)) : "option" === c ? b.defaultSelected = b.selected = a.defaultSelected : ("input" === c || "textarea" === c) && (b.defaultValue = a.defaultValue) } } function Fb(b, c) { var d = n(c.createElement(b)).appendTo(c.body), e = a.getDefaultComputedStyle ? a.getDefaultComputedStyle(d[0]).display : n.css(d[0], "display"); return d.detach(), e } function Gb(a) { var b = z, c = Eb[a]; return c || (c = Fb(a, b), "none" !== c && c || (Db = (Db || n("