pace_rails 0.0.5 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 49fd8e68963d4aee0ca2518ba448116a98f3d7f2
4
- data.tar.gz: b834deaa6ea713b5dee895221c183fd6eefff996
3
+ metadata.gz: 0301d0a18968cf240c42a23cceb004c1e3a090a4
4
+ data.tar.gz: 159f46b0d4d956d91e9008343355e0ffde783d3d
5
5
  SHA512:
6
- metadata.gz: 7485a86194487bbabcf7aea0802ee99f0696976c6b11715eb81b8bf6dfcbd140d9347b6124f1d6fec16c5fdbec8609509fbdfc8cae4542896101fe40098695eb
7
- data.tar.gz: 3f90c87d49d56760cc6f738c6dc3d13db69b753e09dff4bd55bdfc9e3c895d9a860e0042e7bfe050f77279a06fd8e56966b176eeaac56309336298f6cadcd753
6
+ metadata.gz: df20b3cbf0ad5c149708bb156fc348e4a149b61c5ad06b889e8bd45f7e6143a28293b605e649eb2137495b5f9b1066ff9d06cfad1ed3e353a22194074228d49e
7
+ data.tar.gz: 4d884cc937fac35e106b8cd199707d60839bf26ae12ba70fa9a8f0763827622d74e32261fded1106e30cb3bf08748dcfba776e72a78bd9d535ef1cd681f50855
data/README.md CHANGED
@@ -25,7 +25,7 @@ You basically have to add the required.
25
25
 
26
26
  In your `application.js.coffee` (or just `application.js`) which is located at `app/assets/javascripts/application.js`:
27
27
 
28
- //= require pace
28
+ //= require pace/pace
29
29
 
30
30
  Also, place the following in your `application.css.scss` file which is located at `app/assets/stylesheets/application.css`:
31
31
 
@@ -1,8 +1,9 @@
1
1
  (function() {
2
- var AjaxMonitor, Bar, DocumentMonitor, ElementMonitor, ElementTracker, EventLagMonitor, Events, RequestIntercept, RequestTracker, SOURCE_KEYS, Scaler, animation, bar, cancelAnimation, cancelAnimationFrame, defaultOptions, extend, getFromDOM, handlePushState, init, intercept, now, options, requestAnimationFrame, result, runAnimation, scalers, sources, uniScaler, _XDomainRequest, _XMLHttpRequest, _pushState, _replaceState,
2
+ var AjaxMonitor, Bar, DocumentMonitor, ElementMonitor, ElementTracker, EventLagMonitor, Events, RequestIntercept, SOURCE_KEYS, Scaler, SocketRequestTracker, XHRRequestTracker, animation, bar, cancelAnimation, cancelAnimationFrame, defaultOptions, extend, extendNative, firstLoad, getFromDOM, handlePushState, init, intercept, now, options, requestAnimationFrame, result, runAnimation, scalers, sources, uniScaler, _WebSocket, _XDomainRequest, _XMLHttpRequest, _pushState, _replaceState,
3
3
  __slice = [].slice,
4
4
  __hasProp = {}.hasOwnProperty,
5
- __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; };
5
+ __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; },
6
+ __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; };
6
7
 
7
8
  defaultOptions = {
8
9
  catchupTime: 500,
@@ -11,10 +12,20 @@
11
12
  ghostTime: 250,
12
13
  maxProgressPerFrame: 10,
13
14
  easeFactor: 1.25,
15
+ startOnPageLoad: true,
14
16
  restartOnPushState: true,
17
+ restartOnBackboneRoute: true,
18
+ target: 'body',
15
19
  elements: {
16
20
  checkInterval: 100,
17
21
  selectors: ['body']
22
+ },
23
+ eventLag: {
24
+ minSamples: 10
25
+ },
26
+ ajax: {
27
+ trackMethods: ['GET'],
28
+ trackWebSockets: true
18
29
  }
19
30
  };
20
31
 
@@ -116,14 +127,16 @@
116
127
  }
117
128
 
118
129
  Bar.prototype.getElement = function() {
130
+ var targetElement;
119
131
  if (this.el == null) {
120
132
  this.el = document.createElement('div');
121
133
  this.el.className = "pace pace-active";
122
134
  this.el.innerHTML = '<div class="pace-progress">\n <div class="pace-progress-inner"></div>\n</div>\n<div class="pace-activity"></div>';
123
- if (document.body.firstChild != null) {
124
- document.body.insertBefore(this.el, document.body.firstChild);
135
+ targetElement = document.querySelector(options.target);
136
+ if (targetElement.firstChild != null) {
137
+ targetElement.insertBefore(this.el, targetElement.firstChild);
125
138
  } else {
126
- document.body.appendChild(this.el);
139
+ targetElement.appendChild(this.el);
127
140
  }
128
141
  }
129
142
  return this.el;
@@ -148,7 +161,7 @@
148
161
 
149
162
  Bar.prototype.render = function() {
150
163
  var el, progressStr;
151
- if (document.body == null) {
164
+ if (document.querySelector(options.target) == null) {
152
165
  return false;
153
166
  }
154
167
  el = this.getElement();
@@ -208,38 +221,77 @@
208
221
 
209
222
  _XDomainRequest = window.XDomainRequest;
210
223
 
224
+ _WebSocket = window.WebSocket;
225
+
226
+ extendNative = function(to, from) {
227
+ var e, key, val, _results;
228
+ _results = [];
229
+ for (key in from.prototype) {
230
+ try {
231
+ val = from.prototype[key];
232
+ if ((to[key] == null) && typeof val !== 'function') {
233
+ _results.push(to[key] = val);
234
+ } else {
235
+ _results.push(void 0);
236
+ }
237
+ } catch (_error) {
238
+ e = _error;
239
+ }
240
+ }
241
+ return _results;
242
+ };
243
+
211
244
  RequestIntercept = (function(_super) {
212
245
  __extends(RequestIntercept, _super);
213
246
 
214
247
  function RequestIntercept() {
215
- var monitor,
248
+ var monitorXHR,
216
249
  _this = this;
217
250
  RequestIntercept.__super__.constructor.apply(this, arguments);
218
- monitor = function(req) {
251
+ monitorXHR = function(req) {
219
252
  var _open;
220
253
  _open = req.open;
221
254
  return req.open = function(type, url, async) {
222
- _this.trigger('request', {
223
- type: type,
224
- url: url,
225
- request: req
226
- });
255
+ var _ref;
256
+ if (_ref = (type != null ? type : 'GET').toUpperCase(), __indexOf.call(options.ajax.trackMethods, _ref) >= 0) {
257
+ _this.trigger('request', {
258
+ type: type,
259
+ url: url,
260
+ request: req
261
+ });
262
+ }
227
263
  return _open.apply(req, arguments);
228
264
  };
229
265
  };
230
- window.XMLHttpRequest = function() {
266
+ window.XMLHttpRequest = function(flags) {
231
267
  var req;
232
- req = new _XMLHttpRequest;
233
- monitor(req);
268
+ req = new _XMLHttpRequest(flags);
269
+ monitorXHR(req);
234
270
  return req;
235
271
  };
272
+ extendNative(window.XMLHttpRequest, _XMLHttpRequest);
236
273
  if (_XDomainRequest != null) {
237
274
  window.XDomainRequest = function() {
238
275
  var req;
239
276
  req = new _XDomainRequest;
240
- monitor(req);
277
+ monitorXHR(req);
278
+ return req;
279
+ };
280
+ extendNative(window.XDomainRequest, _XDomainRequest);
281
+ }
282
+ if ((_WebSocket != null) && options.ajax.trackWebSockets) {
283
+ window.WebSocket = function(url, protocols) {
284
+ var req;
285
+ req = new _WebSocket(url, protocols);
286
+ _this.trigger('request', {
287
+ type: 'socket',
288
+ url: url,
289
+ protocols: protocols,
290
+ request: req
291
+ });
241
292
  return req;
242
293
  };
294
+ extendNative(window.WebSocket, _WebSocket);
243
295
  }
244
296
  }
245
297
 
@@ -253,16 +305,19 @@
253
305
  function AjaxMonitor() {
254
306
  var _this = this;
255
307
  this.elements = [];
256
- intercept.on('request', function(_arg) {
257
- var request;
258
- request = _arg.request;
259
- return _this.watch(request);
308
+ intercept.on('request', function() {
309
+ return _this.watch.apply(_this, arguments);
260
310
  });
261
311
  }
262
312
 
263
- AjaxMonitor.prototype.watch = function(request) {
264
- var tracker;
265
- tracker = new RequestTracker(request);
313
+ AjaxMonitor.prototype.watch = function(_arg) {
314
+ var request, tracker, type;
315
+ type = _arg.type, request = _arg.request;
316
+ if (type === 'socket') {
317
+ tracker = new SocketRequestTracker(request);
318
+ } else {
319
+ tracker = new XHRRequestTracker(request);
320
+ }
266
321
  return this.elements.push(tracker);
267
322
  };
268
323
 
@@ -270,53 +325,26 @@
270
325
 
271
326
  })();
272
327
 
273
- RequestTracker = (function() {
274
- function RequestTracker(request) {
275
- var handler, size, _fn, _i, _len, _onprogress, _onreadystatechange, _ref,
328
+ XHRRequestTracker = (function() {
329
+ function XHRRequestTracker(request) {
330
+ var event, size, _i, _len, _onreadystatechange, _ref,
276
331
  _this = this;
277
332
  this.progress = 0;
278
- if (request.onprogress !== void 0) {
333
+ if (window.ProgressEvent != null) {
279
334
  size = null;
280
- _onprogress = request.onprogress;
281
- request.onprogress = function() {
282
- var e, headers, name, val;
283
- try {
284
- headers = request.getAllResponseHeaders();
285
- for (name in headers) {
286
- val = headers[name];
287
- if (name.toLowerCase() === 'content-length') {
288
- size = +val;
289
- break;
290
- }
291
- }
292
- } catch (_error) {
293
- e = _error;
294
- }
295
- if (size != null) {
296
- try {
297
- return _this.progress = request.responseText.length / size;
298
- } catch (_error) {
299
- e = _error;
300
- }
335
+ request.addEventListener('progress', function(evt) {
336
+ if (evt.lengthComputable) {
337
+ return _this.progress = 100 * evt.loaded / evt.total;
301
338
  } else {
302
339
  return _this.progress = _this.progress + (100 - _this.progress) / 2;
303
340
  }
304
- };
305
- if (typeof _onprogress === "function") {
306
- _onprogress.apply(null, arguments);
307
- }
308
- _ref = ['onload', 'onabort', 'ontimeout', 'onerror'];
309
- _fn = function() {
310
- var fn;
311
- fn = request[handler];
312
- return request[handler] = function() {
313
- _this.progress = 100;
314
- return typeof fn === "function" ? fn.apply(null, arguments) : void 0;
315
- };
316
- };
341
+ });
342
+ _ref = ['load', 'abort', 'timeout', 'error'];
317
343
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
318
- handler = _ref[_i];
319
- _fn();
344
+ event = _ref[_i];
345
+ request.addEventListener(event, function() {
346
+ return _this.progress = 100;
347
+ });
320
348
  }
321
349
  } else {
322
350
  _onreadystatechange = request.onreadystatechange;
@@ -332,7 +360,25 @@
332
360
  }
333
361
  }
334
362
 
335
- return RequestTracker;
363
+ return XHRRequestTracker;
364
+
365
+ })();
366
+
367
+ SocketRequestTracker = (function() {
368
+ function SocketRequestTracker(request) {
369
+ var event, _i, _len, _ref,
370
+ _this = this;
371
+ this.progress = 0;
372
+ _ref = ['error', 'open'];
373
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
374
+ event = _ref[_i];
375
+ request.addEventListener(event, function() {
376
+ return _this.progress = 100;
377
+ });
378
+ }
379
+ }
380
+
381
+ return SocketRequestTracker;
336
382
 
337
383
  })();
338
384
 
@@ -391,9 +437,9 @@
391
437
  };
392
438
 
393
439
  function DocumentMonitor() {
394
- var _onreadystatechange,
440
+ var _onreadystatechange, _ref,
395
441
  _this = this;
396
- this.progress = 0;
442
+ this.progress = (_ref = this.states[document.readyState]) != null ? _ref : 100;
397
443
  _onreadystatechange = document.onreadystatechange;
398
444
  document.onreadystatechange = function() {
399
445
  if (_this.states[document.readyState] != null) {
@@ -420,7 +466,7 @@
420
466
  diff = now() - last - 50;
421
467
  last = now();
422
468
  avg = avg + (diff - avg) / 15;
423
- if (points++ > 20 && Math.abs(avg) < 3) {
469
+ if (points++ > options.eventLag.minSamples && Math.abs(avg) < 3) {
424
470
  avg = 0;
425
471
  }
426
472
  return _this.progress = 100 * (3 / (avg + 3));
@@ -511,6 +557,40 @@
511
557
  };
512
558
  }
513
559
 
560
+ firstLoad = true;
561
+
562
+ if (options.restartOnBackboneRoute) {
563
+ setTimeout(function() {
564
+ if (window.Backbone == null) {
565
+ return;
566
+ }
567
+ return Backbone.history.on('route', function(router, name) {
568
+ var routeName, rule, _i, _len, _results;
569
+ if (!(rule = options.restartOnBackboneRoute)) {
570
+ return;
571
+ }
572
+ if (firstLoad) {
573
+ firstLoad = false;
574
+ return;
575
+ }
576
+ if (typeof rule === 'object') {
577
+ _results = [];
578
+ for (_i = 0, _len = rule.length; _i < _len; _i++) {
579
+ routeName = rule[_i];
580
+ if (!(routeName === name)) {
581
+ continue;
582
+ }
583
+ Pace.restart();
584
+ break;
585
+ }
586
+ return _results;
587
+ } else {
588
+ return Pace.restart();
589
+ }
590
+ });
591
+ }, 0);
592
+ }
593
+
514
594
  SOURCE_KEYS = {
515
595
  ajax: AjaxMonitor,
516
596
  elements: ElementMonitor,
@@ -520,7 +600,7 @@
520
600
 
521
601
  (init = function() {
522
602
  var source, type, _i, _j, _len, _len1, _ref, _ref1, _ref2;
523
- sources = [];
603
+ Pace.sources = sources = [];
524
604
  _ref = ['ajax', 'elements', 'document', 'eventLag'];
525
605
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
526
606
  type = _ref[_i];
@@ -533,7 +613,7 @@
533
613
  source = _ref2[_j];
534
614
  sources.push(new source(options));
535
615
  }
536
- bar = new Bar;
616
+ Pace.bar = bar = new Bar;
537
617
  scalers = [];
538
618
  return uniScaler = new Scaler;
539
619
  })();
@@ -609,7 +689,9 @@
609
689
  } else if (typeof exports === 'object') {
610
690
  module.exports = Pace;
611
691
  } else {
612
- Pace.start();
692
+ if (options.startOnPageLoad) {
693
+ Pace.start();
694
+ }
613
695
  }
614
696
 
615
697
  }).call(this);
@@ -1,3 +1,4 @@
1
+ /* This is a compiled file, you should be editing the file in the templates directory */
1
2
  .pace {
2
3
  -webkit-pointer-events: none;
3
4
  pointer-events: none;
@@ -18,6 +19,11 @@
18
19
  left: 0;
19
20
  height: 12px;
20
21
  overflow: hidden;
22
+
23
+ -webkit-transition: width 1s;
24
+ -moz-transition: width 1s;
25
+ -o-transition: width 1s;
26
+ transition: width 1s;
21
27
  }
22
28
 
23
29
  .pace .pace-progress-inner {
@@ -63,4 +69,4 @@
63
69
  @keyframes pace-stripe-animation {
64
70
  0% { transform: none; transform: none; }
65
71
  100% { transform: translate(-32px, 0); transform: translate(-32px, 0); }
66
- }
72
+ }
@@ -1,3 +1,4 @@
1
+ /* This is a compiled file, you should be editing the file in the templates directory */
1
2
  .pace {
2
3
  -webkit-pointer-events: none;
3
4
  pointer-events: none;
@@ -27,4 +28,4 @@
27
28
  line-height: 1;
28
29
  text-align: right;
29
30
  color: rgba(0, 0, 0, 0.19999999999999996);
30
- }
31
+ }
@@ -1,3 +1,4 @@
1
+ /* This is a compiled file, you should be editing the file in the templates directory */
1
2
  .pace {
2
3
  width: 140px;
3
4
  height: 300px;
@@ -1,3 +1,4 @@
1
+ /* This is a compiled file, you should be editing the file in the templates directory */
1
2
  .pace {
2
3
  -webkit-pointer-events: none;
3
4
  pointer-events: none;
@@ -66,4 +67,4 @@
66
67
  @keyframes pace-rotation {
67
68
  0% { transform: rotate(0deg); }
68
69
  100% { transform: rotate(359deg); }
69
- }
70
+ }
@@ -1,3 +1,4 @@
1
+ /* This is a compiled file, you should be editing the file in the templates directory */
1
2
  .pace {
2
3
  -webkit-pointer-events: none;
3
4
  pointer-events: none;
@@ -13,4 +14,9 @@
13
14
  top: 0;
14
15
  left: 0;
15
16
  bottom: 0;
16
- }
17
+
18
+ -webkit-transition: width 1s;
19
+ -moz-transition: width 1s;
20
+ -o-transition: width 1s;
21
+ transition: width 1s;
22
+ }
@@ -1,3 +1,4 @@
1
+ /* This is a compiled file, you should be editing the file in the templates directory */
1
2
  .pace {
2
3
  -webkit-pointer-events: none;
3
4
  pointer-events: none;
@@ -17,6 +18,11 @@
17
18
  top: 0;
18
19
  left: 0;
19
20
  height: 2px;
21
+
22
+ -webkit-transition: width 1s;
23
+ -moz-transition: width 1s;
24
+ -o-transition: width 1s;
25
+ transition: width 1s;
20
26
  }
21
27
 
22
28
  .pace .pace-progress-inner {
@@ -72,4 +78,4 @@
72
78
  @keyframes pace-spinner {
73
79
  0% { transform: rotate(0deg); transform: rotate(0deg); }
74
80
  100% { transform: rotate(360deg); transform: rotate(360deg); }
75
- }
81
+ }
@@ -1,3 +1,4 @@
1
+ /* This is a compiled file, you should be editing the file in the templates directory */
1
2
  .pace {
2
3
  -webkit-pointer-events: none;
3
4
  pointer-events: none;
@@ -14,10 +15,15 @@
14
15
  left: 0;
15
16
  height: 12px;
16
17
  background: #29d;
17
- -webkit-transition: -webkit-transform 0.3s;
18
- transition: transform 0.3s;
18
+
19
+ -webkit-transition: -webkit-transform .3s, width 1s;
20
+ -moz-transition: width 1s;
21
+ -o-transform: width 1s;
22
+ transition: transform .3s, width 1s;
23
+
19
24
  -webkit-transform: translateY(-50px);
20
25
  transform: translateY(-50px);
26
+
21
27
  pointer-events: none;
22
28
  }
23
29
 
@@ -1,3 +1,4 @@
1
+ /* This is a compiled file, you should be editing the file in the templates directory */
1
2
  .pace {
2
3
  -webkit-pointer-events: none;
3
4
  pointer-events: none;
@@ -20,14 +21,21 @@
20
21
  left: 0;
21
22
  height: 12px;
22
23
  overflow: hidden;
24
+
23
25
  -webkit-border-radius: 0 0 4px 0;
24
26
  -moz-border-radius: 0 0 4px 0;
25
27
  -o-border-radius: 0 0 4px 0;
26
28
  border-radius: 0 0 4px 0;
29
+
27
30
  -webkit-box-shadow: inset -1px 0 rgba(0, 0, 0, 0.3), inset 0 -1px rgba(0, 0, 0, 0.3), inset 0 2px rgba(255, 255, 255, 0.5), inset 0 6px rgba(255, 255, 255, 0.3);
28
31
  -moz-box-shadow: inset -1px 0 rgba(0, 0, 0, 0.3), inset 0 -1px rgba(0, 0, 0, 0.3), inset 0 2px rgba(255, 255, 255, 0.5), inset 0 6px rgba(255, 255, 255, 0.3);
29
32
  -o-box-shadow: inset -1px 0 rgba(0, 0, 0, 0.3), inset 0 -1px rgba(0, 0, 0, 0.3), inset 0 2px rgba(255, 255, 255, 0.5), inset 0 6px rgba(255, 255, 255, 0.3);
30
33
  box-shadow: inset -1px 0 rgba(0, 0, 0, 0.3), inset 0 -1px rgba(0, 0, 0, 0.3), inset 0 2px rgba(255, 255, 255, 0.5), inset 0 6px rgba(255, 255, 255, 0.3);
34
+
35
+ -webkit-transition: width 1s;
36
+ -moz-transition: width 1s;
37
+ -o-transition: width 1s;
38
+ transition: width 1s;
31
39
  }
32
40
 
33
41
  .pace .pace-progress-inner {
@@ -73,4 +81,4 @@
73
81
  @keyframes pace-stripe-animation {
74
82
  0% { transform: none; transform: none; }
75
83
  100% { transform: translate(-28px, 0); transform: translate(-28px, 0); }
76
- }
84
+ }
@@ -1,3 +1,4 @@
1
+ /* This is a compiled file, you should be editing the file in the templates directory */
1
2
  .pace .pace-progress {
2
3
  background: #29d;
3
4
  position: fixed;
@@ -5,8 +6,13 @@
5
6
  top: 0;
6
7
  left: 0;
7
8
  height: 2px;
9
+
10
+ -webkit-transition: width 1s;
11
+ -moz-transition: width 1s;
12
+ -o-transition: width 1s;
13
+ transition: width 1s;
8
14
  }
9
15
 
10
16
  .pace-inactive {
11
17
  display: none;
12
- }
18
+ }
@@ -1,3 +1,3 @@
1
1
  module PaceRails
2
- VERSION = "0.0.5"
2
+ VERSION = "0.0.6"
3
3
  end
data/pace_rails.gemspec CHANGED
@@ -8,7 +8,7 @@ Gem::Specification.new do |spec|
8
8
  spec.version = PaceRails::VERSION
9
9
  spec.authors = ["arvind-naidu"]
10
10
  spec.email = ["techmaxed.net@gmail.com"]
11
- spec.description = %q{This is a gem for Pace. It's based on version 0.4.3.}
11
+ spec.description = %q{This is a gem for Pace. It's based on version 0.4.10.}
12
12
  spec.summary = %q{Automatic page load progress bar}
13
13
  spec.homepage = "https://github.com/arvind-naidu/pace_rails"
14
14
  spec.license = "MIT"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pace_rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - arvind-naidu
@@ -66,7 +66,7 @@ dependencies:
66
66
  - - '>='
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
- description: This is a gem for Pace. It's based on version 0.4.3.
69
+ description: This is a gem for Pace. It's based on version 0.4.10.
70
70
  email:
71
71
  - techmaxed.net@gmail.com
72
72
  executables: []
@@ -78,7 +78,7 @@ files:
78
78
  - LICENSE.txt
79
79
  - README.md
80
80
  - Rakefile
81
- - app/assets/javascripts/pace.js
81
+ - app/assets/javascripts/pace/pace.js
82
82
  - app/assets/stylesheets/pace/barber-shop.css
83
83
  - app/assets/stylesheets/pace/big-counter.css
84
84
  - app/assets/stylesheets/pace/bounce.css