(function() { var ajaxmonitor, bar, documentmonitor, elementmonitor, elementtracker, eventlagmonitor, evented, events, notargeterror, requestintercept, source_keys, scaler, socketrequesttracker, xhrrequesttracker, animation, avgamplitude, bar, cancelanimation, cancelanimationframe, defaultoptions, extend, extendnative, getfromdom, getintercept, handlepushstate, ignorestack, init, now, options, requestanimationframe, result, runanimation, scalers, shouldignoreurl, shouldtrack, source, sources, uniscaler, _websocket, _xdomainrequest, _xmlhttprequest, _i, _intercept, _len, _pushstate, _ref, _ref1, _replacestate, __slice = [].slice, __hasprop = {}.hasownproperty, __extends = function(child, parent) { for (var key in parent) { if (__hasprop.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, __indexof = [].indexof || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; defaultoptions = { catchuptime: 500, initialrate: .03, mintime: 500, ghosttime: 500, maxprogressperframe: 10, easefactor: 1.25, startonpageload: true, restartonpushstate: true, restartonrequestafter: 500, target: 'body', elements: { checkinterval: 100, selectors: ['body'] }, eventlag: { minsamples: 10, samplecount: 3, lagthreshold: 3 }, ajax: { trackmethods: ['get'], trackwebsockets: true, ignoreurls: [] } }; now = function() { var _ref; return (_ref = typeof performance !== "undefined" && performance !== null ? typeof performance.now === "function" ? performance.now() : void 0 : void 0) != null ? _ref : +(new date); }; requestanimationframe = window.requestanimationframe || window.mozrequestanimationframe || window.webkitrequestanimationframe || window.msrequestanimationframe; cancelanimationframe = window.cancelanimationframe || window.mozcancelanimationframe; if (requestanimationframe == null) { requestanimationframe = function(fn) { return settimeout(fn, 50); }; cancelanimationframe = function(id) { return cleartimeout(id); }; } runanimation = function(fn) { var last, tick; last = now(); tick = function() { var diff; diff = now() - last; if (diff >= 33) { last = now(); return fn(diff, function() { return requestanimationframe(tick); }); } else { return settimeout(tick, 33 - diff); } }; return tick(); }; result = function() { var args, key, obj; obj = arguments[0], key = arguments[1], args = 3 <= arguments.length ? __slice.call(arguments, 2) : []; if (typeof obj[key] === 'function') { return obj[key].apply(obj, args); } else { return obj[key]; } }; extend = function() { var key, out, source, sources, val, _i, _len; out = arguments[0], sources = 2 <= arguments.length ? __slice.call(arguments, 1) : []; for (_i = 0, _len = sources.length; _i < _len; _i++) { source = sources[_i]; if (source) { for (key in source) { if (!__hasprop.call(source, key)) continue; val = source[key]; if ((out[key] != null) && typeof out[key] === 'object' && (val != null) && typeof val === 'object') { extend(out[key], val); } else { out[key] = val; } } } } return out; }; avgamplitude = function(arr) { var count, sum, v, _i, _len; sum = count = 0; for (_i = 0, _len = arr.length; _i < _len; _i++) { v = arr[_i]; sum += math.abs(v); count++; } return sum / count; }; getfromdom = function(key, json) { var data, e, el; if (key == null) { key = 'options'; } if (json == null) { json = true; } el = document.queryselector("[data-pace-" + key + "]"); if (!el) { return; } data = el.getattribute("data-pace-" + key); if (!json) { return data; } try { return json.parse(data); } catch (_error) { e = _error; return typeof console !== "undefined" && console !== null ? console.error("error parsing inline pace options", e) : void 0; } }; evented = (function() { function evented() {} evented.prototype.on = function(event, handler, ctx, once) { var _base; if (once == null) { once = false; } if (this.bindings == null) { this.bindings = {}; } if ((_base = this.bindings)[event] == null) { _base[event] = []; } return this.bindings[event].push({ handler: handler, ctx: ctx, once: once }); }; evented.prototype.once = function(event, handler, ctx) { return this.on(event, handler, ctx, true); }; evented.prototype.off = function(event, handler) { var i, _ref, _results; if (((_ref = this.bindings) != null ? _ref[event] : void 0) == null) { return; } if (handler == null) { return delete this.bindings[event]; } else { i = 0; _results = []; while (i < this.bindings[event].length) { if (this.bindings[event][i].handler === handler) { _results.push(this.bindings[event].splice(i, 1)); } else { _results.push(i++); } } return _results; } }; evented.prototype.trigger = function() { var args, ctx, event, handler, i, once, _ref, _ref1, _results; event = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; if ((_ref = this.bindings) != null ? _ref[event] : void 0) { i = 0; _results = []; while (i < this.bindings[event].length) { _ref1 = this.bindings[event][i], handler = _ref1.handler, ctx = _ref1.ctx, once = _ref1.once; handler.apply(ctx != null ? ctx : this, args); if (once) { _results.push(this.bindings[event].splice(i, 1)); } else { _results.push(i++); } } return _results; } }; return evented; })(); if (window.pace == null) { window.pace = {}; } extend(pace, evented.prototype); options = pace.options = extend({}, defaultoptions, window.paceoptions, getfromdom()); _ref = ['ajax', 'document', 'eventlag', 'elements']; for (_i = 0, _len = _ref.length; _i < _len; _i++) { source = _ref[_i]; if (options[source] === true) { options[source] = defaultoptions[source]; } } notargeterror = (function(_super) { __extends(notargeterror, _super); function notargeterror() { _ref1 = notargeterror.__super__.constructor.apply(this, arguments); return _ref1; } return notargeterror; })(error); bar = (function() { function bar() { this.progress = 0; } bar.prototype.getelement = function() { var targetelement; if (this.el == null) { targetelement = document.queryselector(options.target); if (!targetelement) { throw new notargeterror; } this.el = document.createelement('div'); this.el.classname = "pace pace-active"; document.body.classname = document.body.classname.replace(/pace-done/g, ''); document.body.classname += ' pace-running'; this.el.innerhtml = '
\n
\n
\n
'; if (targetelement.firstchild != null) { targetelement.insertbefore(this.el, targetelement.firstchild); } else { targetelement.appendchild(this.el); } } return this.el; }; bar.prototype.finish = function() { var el; el = this.getelement(); el.classname = el.classname.replace('pace-active', ''); el.classname += ' pace-inactive'; document.body.classname = document.body.classname.replace('pace-running', ''); return document.body.classname += ' pace-done'; }; bar.prototype.update = function(prog) { this.progress = prog; return this.render(); }; bar.prototype.destroy = function() { try { this.getelement().parentnode.removechild(this.getelement()); } catch (_error) { notargeterror = _error; } return this.el = void 0; }; bar.prototype.render = function() { var el, progressstr; if (document.queryselector(options.target) == null) { return false; } el = this.getelement(); el.children[0].style.width = "" + this.progress + "%"; if (!this.lastrenderedprogress || this.lastrenderedprogress | 0 !== this.progress | 0) { el.children[0].setattribute('data-progress-text', "" + (this.progress | 0) + "%"); if (this.progress >= 100) { progressstr = '99'; } else { progressstr = this.progress < 10 ? "0" : ""; progressstr += this.progress | 0; } el.children[0].setattribute('data-progress', "" + progressstr); } return this.lastrenderedprogress = this.progress; }; bar.prototype.done = function() { return this.progress >= 100; }; return bar; })(); events = (function() { function events() { this.bindings = {}; } events.prototype.trigger = function(name, val) { var binding, _j, _len1, _ref2, _results; if (this.bindings[name] != null) { _ref2 = this.bindings[name]; _results = []; for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) { binding = _ref2[_j]; _results.push(binding.call(this, val)); } return _results; } }; events.prototype.on = function(name, fn) { var _base; if ((_base = this.bindings)[name] == null) { _base[name] = []; } return this.bindings[name].push(fn); }; return events; })(); _xmlhttprequest = window.xmlhttprequest; _xdomainrequest = window.xdomainrequest; _websocket = window.websocket; extendnative = function(to, from) { var e, key, val, _results; _results = []; for (key in from.prototype) { try { val = from.prototype[key]; if ((to[key] == null) && typeof val !== 'function') { _results.push(to[key] = val); } else { _results.push(void 0); } } catch (_error) { e = _error; } } return _results; }; ignorestack = []; pace.ignore = function() { var args, fn, ret; fn = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; ignorestack.unshift('ignore'); ret = fn.apply(null, args); ignorestack.shift(); return ret; }; pace.track = function() { var args, fn, ret; fn = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; ignorestack.unshift('track'); ret = fn.apply(null, args); ignorestack.shift(); return ret; }; shouldtrack = function(method) { var _ref2; if (method == null) { method = 'get'; } if (ignorestack[0] === 'track') { return 'force'; } if (!ignorestack.length && options.ajax) { if (method === 'socket' && options.ajax.trackwebsockets) { return true; } else if (_ref2 = method.touppercase(), __indexof.call(options.ajax.trackmethods, _ref2) >= 0) { return true; } } return false; }; requestintercept = (function(_super) { __extends(requestintercept, _super); function requestintercept() { var monitorxhr, _this = this; requestintercept.__super__.constructor.apply(this, arguments); monitorxhr = function(req) { var _open; _open = req.open; return req.open = function(type, url, async) { if (shouldtrack(type)) { _this.trigger('request', { type: type, url: url, request: req }); } return _open.apply(req, arguments); }; }; window.xmlhttprequest = function(flags) { var req; req = new _xmlhttprequest(flags); monitorxhr(req); return req; }; try { extendnative(window.xmlhttprequest, _xmlhttprequest); } catch (_error) {} if (_xdomainrequest != null) { window.xdomainrequest = function() { var req; req = new _xdomainrequest; monitorxhr(req); return req; }; try { extendnative(window.xdomainrequest, _xdomainrequest); } catch (_error) {} } if ((_websocket != null) && options.ajax.trackwebsockets) { window.websocket = function(url, protocols) { var req; if (protocols != null) { req = new _websocket(url, protocols); } else { req = new _websocket(url); } if (shouldtrack('socket')) { _this.trigger('request', { type: 'socket', url: url, protocols: protocols, request: req }); } return req; }; try { extendnative(window.websocket, _websocket); } catch (_error) {} } } return requestintercept; })(events); _intercept = null; getintercept = function() { if (_intercept == null) { _intercept = new requestintercept; } return _intercept; }; shouldignoreurl = function(url) { var pattern, _j, _len1, _ref2; _ref2 = options.ajax.ignoreurls; for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) { pattern = _ref2[_j]; if (typeof pattern === 'string') { if (url.indexof(pattern) !== -1) { return true; } } else { if (pattern.test(url)) { return true; } } } return false; }; getintercept().on('request', function(_arg) { var after, args, request, type, url; type = _arg.type, request = _arg.request, url = _arg.url; if (shouldignoreurl(url)) { return; } if (!pace.running && (options.restartonrequestafter !== false || shouldtrack(type) === 'force')) { args = arguments; after = options.restartonrequestafter || 0; if (typeof after === 'boolean') { after = 0; } return settimeout(function() { var stillactive, _j, _len1, _ref2, _ref3, _results; if (type === 'socket') { stillactive = request.readystate < 2; } else { stillactive = (0 < (_ref2 = request.readystate) && _ref2 < 4); } if (stillactive) { pace.restart(); _ref3 = pace.sources; _results = []; for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) { source = _ref3[_j]; if (source instanceof ajaxmonitor) { source.watch.apply(source, args); break; } else { _results.push(void 0); } } return _results; } }, after); } }); ajaxmonitor = (function() { function ajaxmonitor() { var _this = this; this.elements = []; getintercept().on('request', function() { return _this.watch.apply(_this, arguments); }); } ajaxmonitor.prototype.watch = function(_arg) { var request, tracker, type, url; type = _arg.type, request = _arg.request, url = _arg.url; if (shouldignoreurl(url)) { return; } if (type === 'socket') { tracker = new socketrequesttracker(request); } else { tracker = new xhrrequesttracker(request); } return this.elements.push(tracker); }; return ajaxmonitor; })(); xhrrequesttracker = (function() { function xhrrequesttracker(request) { var event, size, _j, _len1, _onreadystatechange, _ref2, _this = this; this.progress = 0; if (window.progressevent != null) { size = null; request.addeventlistener('progress', function(evt) { if (evt.lengthcomputable) { return _this.progress = 100 * evt.loaded / evt.total; } else { return _this.progress = _this.progress + (100 - _this.progress) / 2; } }); _ref2 = ['load', 'abort', 'timeout', 'error']; for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) { event = _ref2[_j]; request.addeventlistener(event, function() { return _this.progress = 100; }); } } else { _onreadystatechange = request.onreadystatechange; request.onreadystatechange = function() { var _ref3; if ((_ref3 = request.readystate) === 0 || _ref3 === 4) { _this.progress = 100; } else if (request.readystate === 3) { _this.progress = 50; } return typeof _onreadystatechange === "function" ? _onreadystatechange.apply(null, arguments) : void 0; }; } } return xhrrequesttracker; })(); socketrequesttracker = (function() { function socketrequesttracker(request) { var event, _j, _len1, _ref2, _this = this; this.progress = 0; _ref2 = ['error', 'open']; for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) { event = _ref2[_j]; request.addeventlistener(event, function() { return _this.progress = 100; }); } } return socketrequesttracker; })(); elementmonitor = (function() { function elementmonitor(options) { var selector, _j, _len1, _ref2; if (options == null) { options = {}; } this.elements = []; if (options.selectors == null) { options.selectors = []; } _ref2 = options.selectors; for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) { selector = _ref2[_j]; this.elements.push(new elementtracker(selector)); } } return elementmonitor; })(); elementtracker = (function() { function elementtracker(selector) { this.selector = selector; this.progress = 0; this.check(); } elementtracker.prototype.check = function() { var _this = this; if (document.queryselector(this.selector)) { return this.done(); } else { return settimeout((function() { return _this.check(); }), options.elements.checkinterval); } }; elementtracker.prototype.done = function() { return this.progress = 100; }; return elementtracker; })(); documentmonitor = (function() { documentmonitor.prototype.states = { loading: 0, interactive: 50, complete: 100 }; function documentmonitor() { var _onreadystatechange, _ref2, _this = this; this.progress = (_ref2 = this.states[document.readystate]) != null ? _ref2 : 100; _onreadystatechange = document.onreadystatechange; document.onreadystatechange = function() { if (_this.states[document.readystate] != null) { _this.progress = _this.states[document.readystate]; } return typeof _onreadystatechange === "function" ? _onreadystatechange.apply(null, arguments) : void 0; }; } return documentmonitor; })(); eventlagmonitor = (function() { function eventlagmonitor() { var avg, interval, last, points, samples, _this = this; this.progress = 0; avg = 0; samples = []; points = 0; last = now(); interval = setinterval(function() { var diff; diff = now() - last - 50; last = now(); samples.push(diff); if (samples.length > options.eventlag.samplecount) { samples.shift(); } avg = avgamplitude(samples); if (++points >= options.eventlag.minsamples && avg < options.eventlag.lagthreshold) { _this.progress = 100; return clearinterval(interval); } else { return _this.progress = 100 * (3 / (avg + 3)); } }, 50); } return eventlagmonitor; })(); scaler = (function() { function scaler(source) { this.source = source; this.last = this.sincelastupdate = 0; this.rate = options.initialrate; this.catchup = 0; this.progress = this.lastprogress = 0; if (this.source != null) { this.progress = result(this.source, 'progress'); } } scaler.prototype.tick = function(frametime, val) { var scaling; if (val == null) { val = result(this.source, 'progress'); } if (val >= 100) { this.done = true; } if (val === this.last) { this.sincelastupdate += frametime; } else { if (this.sincelastupdate) { this.rate = (val - this.last) / this.sincelastupdate; } this.catchup = (val - this.progress) / options.catchuptime; this.sincelastupdate = 0; this.last = val; } if (val > this.progress) { this.progress += this.catchup * frametime; } scaling = 1 - math.pow(this.progress / 100, options.easefactor); this.progress += scaling * this.rate * frametime; this.progress = math.min(this.lastprogress + options.maxprogressperframe, this.progress); this.progress = math.max(0, this.progress); this.progress = math.min(100, this.progress); this.lastprogress = this.progress; return this.progress; }; return scaler; })(); sources = null; scalers = null; bar = null; uniscaler = null; animation = null; cancelanimation = null; pace.running = false; handlepushstate = function() { if (options.restartonpushstate) { return pace.restart(); } }; if (window.history.pushstate != null) { _pushstate = window.history.pushstate; window.history.pushstate = function() { handlepushstate(); return _pushstate.apply(window.history, arguments); }; } if (window.history.replacestate != null) { _replacestate = window.history.replacestate; window.history.replacestate = function() { handlepushstate(); return _replacestate.apply(window.history, arguments); }; } source_keys = { ajax: ajaxmonitor, elements: elementmonitor, document: documentmonitor, eventlag: eventlagmonitor }; (init = function() { var type, _j, _k, _len1, _len2, _ref2, _ref3, _ref4; pace.sources = sources = []; _ref2 = ['ajax', 'elements', 'document', 'eventlag']; for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) { type = _ref2[_j]; if (options[type] !== false) { sources.push(new source_keys[type](options[type])); } } _ref4 = (_ref3 = options.extrasources) != null ? _ref3 : []; for (_k = 0, _len2 = _ref4.length; _k < _len2; _k++) { source = _ref4[_k]; sources.push(new source(options)); } pace.bar = bar = new bar; scalers = []; return uniscaler = new scaler; })(); pace.stop = function() { pace.trigger('stop'); pace.running = false; bar.destroy(); cancelanimation = true; if (animation != null) { if (typeof cancelanimationframe === "function") { cancelanimationframe(animation); } animation = null; } return init(); }; pace.restart = function() { pace.trigger('restart'); pace.stop(); return pace.start(); }; pace.go = function() { var start; pace.running = true; bar.render(); start = now(); cancelanimation = false; return animation = runanimation(function(frametime, enqueuenextframe) { var avg, count, done, element, elements, i, j, remaining, scaler, scalerlist, sum, _j, _k, _len1, _len2, _ref2; remaining = 100 - bar.progress; count = sum = 0; done = true; for (i = _j = 0, _len1 = sources.length; _j < _len1; i = ++_j) { source = sources[i]; scalerlist = scalers[i] != null ? scalers[i] : scalers[i] = []; elements = (_ref2 = source.elements) != null ? _ref2 : [source]; for (j = _k = 0, _len2 = elements.length; _k < _len2; j = ++_k) { element = elements[j]; scaler = scalerlist[j] != null ? scalerlist[j] : scalerlist[j] = new scaler(element); done &= scaler.done; if (scaler.done) { continue; } count++; sum += scaler.tick(frametime); } } avg = sum / count; bar.update(uniscaler.tick(frametime, avg)); if (bar.done() || done || cancelanimation) { bar.update(100); pace.trigger('done'); return settimeout(function() { bar.finish(); pace.running = false; return pace.trigger('hide'); }, math.max(options.ghosttime, math.max(options.mintime - (now() - start), 0))); } else { return enqueuenextframe(); } }); }; pace.start = function(_options) { extend(options, _options); pace.running = true; try { bar.render(); } catch (_error) { notargeterror = _error; } if (!document.queryselector('.pace')) { return settimeout(pace.start, 50); } else { pace.trigger('start'); return pace.go(); } }; if (typeof define === 'function' && define.amd) { define(function() { return pace; }); } else if (typeof exports === 'object') { module.exports = pace; } else { if (options.startonpageload) { pace.start(); } } }).call(this);