baseboard 1.0.1

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.
Files changed (74) hide show
  1. checksums.yaml +15 -0
  2. data/README.md +4 -0
  3. data/bin/baseboard +9 -0
  4. data/javascripts/batman.jquery.js +163 -0
  5. data/javascripts/batman.js +13680 -0
  6. data/javascripts/dashing.coffee +125 -0
  7. data/javascripts/es5-shim.js +1021 -0
  8. data/javascripts/jquery.js +4 -0
  9. data/lib/baseboard/app.rb +178 -0
  10. data/lib/baseboard/cli.rb +109 -0
  11. data/lib/baseboard/downloader.rb +18 -0
  12. data/lib/baseboard.rb +6 -0
  13. data/templates/dashboard/%name%.erb.tt +7 -0
  14. data/templates/job/%name%.rb +4 -0
  15. data/templates/project/.gitignore +2 -0
  16. data/templates/project/Gemfile +6 -0
  17. data/templates/project/README.md +1 -0
  18. data/templates/project/assets/fonts/fontawesome-webfont.eot +0 -0
  19. data/templates/project/assets/fonts/fontawesome-webfont.svg +399 -0
  20. data/templates/project/assets/fonts/fontawesome-webfont.ttf +0 -0
  21. data/templates/project/assets/fonts/fontawesome-webfont.woff +0 -0
  22. data/templates/project/assets/images/logo.png +0 -0
  23. data/templates/project/assets/javascripts/application.coffee +25 -0
  24. data/templates/project/assets/javascripts/d3-3.2.8.js +5 -0
  25. data/templates/project/assets/javascripts/dashing.gridster.coffee +37 -0
  26. data/templates/project/assets/javascripts/gridster/jquery.gridster.js +3263 -0
  27. data/templates/project/assets/javascripts/gridster/jquery.leanModal.min.js +5 -0
  28. data/templates/project/assets/javascripts/jquery.knob.js +646 -0
  29. data/templates/project/assets/javascripts/rickshaw-1.4.3.min.js +2 -0
  30. data/templates/project/assets/stylesheets/application.scss +258 -0
  31. data/templates/project/assets/stylesheets/font-awesome.css +1479 -0
  32. data/templates/project/assets/stylesheets/jquery.gridster.css +57 -0
  33. data/templates/project/config.ru +18 -0
  34. data/templates/project/dashboards/layout.erb +32 -0
  35. data/templates/project/dashboards/sample.erb +25 -0
  36. data/templates/project/dashboards/sampletv.erb +56 -0
  37. data/templates/project/jobs/buzzwords.rb +9 -0
  38. data/templates/project/jobs/convergence.rb +14 -0
  39. data/templates/project/jobs/sample.rb +13 -0
  40. data/templates/project/jobs/twitter.rb +28 -0
  41. data/templates/project/lib/.empty_directory +1 -0
  42. data/templates/project/public/404.html +26 -0
  43. data/templates/project/public/favicon.ico +0 -0
  44. data/templates/project/widgets/clock/clock.coffee +18 -0
  45. data/templates/project/widgets/clock/clock.html +2 -0
  46. data/templates/project/widgets/clock/clock.scss +13 -0
  47. data/templates/project/widgets/comments/comments.coffee +24 -0
  48. data/templates/project/widgets/comments/comments.html +7 -0
  49. data/templates/project/widgets/comments/comments.scss +33 -0
  50. data/templates/project/widgets/graph/graph.coffee +37 -0
  51. data/templates/project/widgets/graph/graph.html +5 -0
  52. data/templates/project/widgets/graph/graph.scss +65 -0
  53. data/templates/project/widgets/iframe/iframe.coffee +9 -0
  54. data/templates/project/widgets/iframe/iframe.html +1 -0
  55. data/templates/project/widgets/iframe/iframe.scss +8 -0
  56. data/templates/project/widgets/image/image.coffee +9 -0
  57. data/templates/project/widgets/image/image.html +1 -0
  58. data/templates/project/widgets/image/image.scss +13 -0
  59. data/templates/project/widgets/list/list.coffee +6 -0
  60. data/templates/project/widgets/list/list.html +18 -0
  61. data/templates/project/widgets/list/list.scss +60 -0
  62. data/templates/project/widgets/meter/meter.coffee +14 -0
  63. data/templates/project/widgets/meter/meter.html +7 -0
  64. data/templates/project/widgets/meter/meter.scss +35 -0
  65. data/templates/project/widgets/number/number.coffee +24 -0
  66. data/templates/project/widgets/number/number.html +11 -0
  67. data/templates/project/widgets/number/number.scss +39 -0
  68. data/templates/project/widgets/text/text.coffee +1 -0
  69. data/templates/project/widgets/text/text.html +7 -0
  70. data/templates/project/widgets/text/text.scss +32 -0
  71. data/templates/widget/%name%/%name%.coffee.tt +9 -0
  72. data/templates/widget/%name%/%name%.html +1 -0
  73. data/templates/widget/%name%/%name%.scss.tt +3 -0
  74. metadata +339 -0
@@ -0,0 +1,5 @@
1
+ // leanModal v1.1 by Ray Stone - http://finelysliced.com.au
2
+ // Dual licensed under the MIT and GPL
3
+
4
+ (function($){$.fn.extend({leanModal:function(options){var defaults={top:100,overlay:0.5,closeButton:null};var overlay=$("<div id='lean_overlay'></div>");$("body").append(overlay);options=$.extend(defaults,options);return this.each(function(){var o=options;$(this).click(function(e){var modal_id=$(this).attr("href");$("#lean_overlay").click(function(){close_modal(modal_id)});$(o.closeButton).click(function(){close_modal(modal_id)});var modal_height=$(modal_id).outerHeight();var modal_width=$(modal_id).outerWidth();
5
+ $("#lean_overlay").css({"display":"block",opacity:0});$("#lean_overlay").fadeTo(200,o.overlay);$(modal_id).css({"display":"block","position":"fixed","opacity":0,"z-index":11000,"left":50+"%","margin-left":-(modal_width/2)+"px","top":o.top+"px"});$(modal_id).fadeTo(200,1);e.preventDefault()})});function close_modal(modal_id){$("#lean_overlay").fadeOut(200);$(modal_id).css({"display":"none"})}}})})(jQuery);
@@ -0,0 +1,646 @@
1
+ /*!jQuery Knob*/
2
+ /**
3
+ * Downward compatible, touchable dial
4
+ *
5
+ * Version: 1.2.0 (15/07/2012)
6
+ * Requires: jQuery v1.7+
7
+ *
8
+ * Copyright (c) 2012 Anthony Terrien
9
+ * Under MIT and GPL licenses:
10
+ * http://www.opensource.org/licenses/mit-license.php
11
+ * http://www.gnu.org/licenses/gpl.html
12
+ *
13
+ * Thanks to vor, eskimoblood, spiffistan, FabrizioC
14
+ */
15
+ $(function () {
16
+
17
+ /**
18
+ * Kontrol library
19
+ */
20
+ "use strict";
21
+
22
+ /**
23
+ * Definition of globals and core
24
+ */
25
+ var k = {}, // kontrol
26
+ max = Math.max,
27
+ min = Math.min;
28
+
29
+ k.c = {};
30
+ k.c.d = $(document);
31
+ k.c.t = function (e) {
32
+ return e.originalEvent.touches.length - 1;
33
+ };
34
+
35
+ /**
36
+ * Kontrol Object
37
+ *
38
+ * Definition of an abstract UI control
39
+ *
40
+ * Each concrete component must call this one.
41
+ * <code>
42
+ * k.o.call(this);
43
+ * </code>
44
+ */
45
+ k.o = function () {
46
+ var s = this;
47
+
48
+ this.o = null; // array of options
49
+ this.$ = null; // jQuery wrapped element
50
+ this.i = null; // mixed HTMLInputElement or array of HTMLInputElement
51
+ this.g = null; // 2D graphics context for 'pre-rendering'
52
+ this.v = null; // value ; mixed array or integer
53
+ this.cv = null; // change value ; not commited value
54
+ this.x = 0; // canvas x position
55
+ this.y = 0; // canvas y position
56
+ this.$c = null; // jQuery canvas element
57
+ this.c = null; // rendered canvas context
58
+ this.t = 0; // touches index
59
+ this.isInit = false;
60
+ this.fgColor = null; // main color
61
+ this.pColor = null; // previous color
62
+ this.dH = null; // draw hook
63
+ this.cH = null; // change hook
64
+ this.eH = null; // cancel hook
65
+ this.rH = null; // release hook
66
+
67
+ this.run = function () {
68
+ var cf = function (e, conf) {
69
+ var k;
70
+ for (k in conf) {
71
+ s.o[k] = conf[k];
72
+ }
73
+ s.init();
74
+ s._configure()
75
+ ._draw();
76
+ };
77
+
78
+ if(this.$.data('kontroled')) return;
79
+ this.$.data('kontroled', true);
80
+
81
+ this.extend();
82
+ this.o = $.extend(
83
+ {
84
+ // Config
85
+ min : this.$.data('min') || 0,
86
+ max : this.$.data('max') || 100,
87
+ stopper : true,
88
+ readOnly : this.$.data('readonly'),
89
+
90
+ // UI
91
+ cursor : (this.$.data('cursor') === true && 30)
92
+ || this.$.data('cursor')
93
+ || 0,
94
+ thickness : this.$.data('thickness') || 0.35,
95
+ width : this.$.data('width') || 200,
96
+ height : this.$.data('height') || 200,
97
+ displayInput : this.$.data('displayinput') == null || this.$.data('displayinput'),
98
+ displayPrevious : this.$.data('displayprevious'),
99
+ fgColor : this.$.data('fgcolor') || '#87CEEB',
100
+ inline : false,
101
+
102
+ // Hooks
103
+ draw : null, // function () {}
104
+ change : null, // function (value) {}
105
+ cancel : null, // function () {}
106
+ release : null // function (value) {}
107
+ }, this.o
108
+ );
109
+
110
+ // routing value
111
+ if(this.$.is('fieldset')) {
112
+
113
+ // fieldset = array of integer
114
+ this.v = {};
115
+ this.i = this.$.find('input')
116
+ this.i.each(function(k) {
117
+ var $this = $(this);
118
+ s.i[k] = $this;
119
+ s.v[k] = $this.val();
120
+
121
+ $this.bind(
122
+ 'change'
123
+ , function () {
124
+ var val = {};
125
+ val[k] = $this.val();
126
+ s.val(val);
127
+ }
128
+ );
129
+ });
130
+ this.$.find('legend').remove();
131
+
132
+ } else {
133
+ // input = integer
134
+ this.i = this.$;
135
+ this.v = this.$.val();
136
+ (this.v == '') && (this.v = this.o.min);
137
+
138
+ this.$.bind(
139
+ 'change'
140
+ , function () {
141
+ s.val(s.$.val());
142
+ }
143
+ );
144
+ }
145
+
146
+ (!this.o.displayInput) && this.$.hide();
147
+
148
+ this.$c = $('<canvas width="' +
149
+ this.o.width + 'px" height="' +
150
+ this.o.height + 'px"></canvas>');
151
+ this.c = this.$c[0].getContext("2d");
152
+
153
+ this.$
154
+ .wrap($('<div style="' + (this.o.inline ? 'display:inline;' : '') +
155
+ 'width:' + this.o.width + 'px;height:' +
156
+ this.o.height + 'px;"></div>'))
157
+ .before(this.$c);
158
+
159
+ if (this.v instanceof Object) {
160
+ this.cv = {};
161
+ this.copy(this.v, this.cv);
162
+ } else {
163
+ this.cv = this.v;
164
+ }
165
+
166
+ this.$
167
+ .bind("configure", cf)
168
+ .parent()
169
+ .bind("configure", cf);
170
+
171
+ this._listen()
172
+ ._configure()
173
+ ._xy()
174
+ .init();
175
+
176
+ this.isInit = true;
177
+
178
+ this._draw();
179
+
180
+ return this;
181
+ };
182
+
183
+ this._draw = function () {
184
+
185
+ // canvas pre-rendering
186
+ var d = true,
187
+ c = document.createElement('canvas');
188
+
189
+ c.width = s.o.width;
190
+ c.height = s.o.height;
191
+ s.g = c.getContext('2d');
192
+
193
+ s.clear();
194
+
195
+ s.dH
196
+ && (d = s.dH());
197
+
198
+ (d !== false) && s.draw();
199
+
200
+ s.c.drawImage(c, 0, 0);
201
+ c = null;
202
+ };
203
+
204
+ this._touch = function (e) {
205
+
206
+ var touchMove = function (e) {
207
+
208
+ var v = s.xy2val(
209
+ e.originalEvent.touches[s.t].pageX,
210
+ e.originalEvent.touches[s.t].pageY
211
+ );
212
+
213
+ if (v == s.cv) return;
214
+
215
+ if (
216
+ s.cH
217
+ && (s.cH(v) === false)
218
+ ) return;
219
+
220
+
221
+ s.change(v);
222
+ s._draw();
223
+ };
224
+
225
+ // get touches index
226
+ this.t = k.c.t(e);
227
+
228
+ // First touch
229
+ touchMove(e);
230
+
231
+ // Touch events listeners
232
+ k.c.d
233
+ .bind("touchmove.k", touchMove)
234
+ .bind(
235
+ "touchend.k"
236
+ , function () {
237
+ k.c.d.unbind('touchmove.k touchend.k');
238
+
239
+ if (
240
+ s.rH
241
+ && (s.rH(s.cv) === false)
242
+ ) return;
243
+
244
+ s.val(s.cv);
245
+ }
246
+ );
247
+
248
+ return this;
249
+ };
250
+
251
+ this._mouse = function (e) {
252
+
253
+ var mouseMove = function (e) {
254
+ var v = s.xy2val(e.pageX, e.pageY);
255
+ if (v == s.cv) return;
256
+
257
+ if (
258
+ s.cH
259
+ && (s.cH(v) === false)
260
+ ) return;
261
+
262
+ s.change(v);
263
+ s._draw();
264
+ };
265
+
266
+ // First click
267
+ mouseMove(e);
268
+
269
+ // Mouse events listeners
270
+ k.c.d
271
+ .bind("mousemove.k", mouseMove)
272
+ .bind(
273
+ // Escape key cancel current change
274
+ "keyup.k"
275
+ , function (e) {
276
+ if (e.keyCode === 27) {
277
+ k.c.d.unbind("mouseup.k mousemove.k keyup.k");
278
+
279
+ if (
280
+ s.eH
281
+ && (s.eH() === false)
282
+ ) return;
283
+
284
+ s.cancel();
285
+ }
286
+ }
287
+ )
288
+ .bind(
289
+ "mouseup.k"
290
+ , function (e) {
291
+ k.c.d.unbind('mousemove.k mouseup.k keyup.k');
292
+
293
+ if (
294
+ s.rH
295
+ && (s.rH(s.cv) === false)
296
+ ) return;
297
+
298
+ s.val(s.cv);
299
+ }
300
+ );
301
+
302
+ return this;
303
+ };
304
+
305
+ this._xy = function () {
306
+ var o = this.$c.offset();
307
+ this.x = o.left;
308
+ this.y = o.top;
309
+ return this;
310
+ };
311
+
312
+ this._listen = function () {
313
+
314
+ if (!this.o.readOnly) {
315
+ this.$c
316
+ .bind(
317
+ "mousedown"
318
+ , function (e) {
319
+ e.preventDefault();
320
+ s._xy()._mouse(e);
321
+ }
322
+ )
323
+ .bind(
324
+ "touchstart"
325
+ , function (e) {
326
+ e.preventDefault();
327
+ s._xy()._touch(e);
328
+ }
329
+ );
330
+ this.listen();
331
+ } else {
332
+ this.$.attr('readonly', 'readonly');
333
+ }
334
+
335
+ return this;
336
+ };
337
+
338
+ this._configure = function () {
339
+
340
+ // Hooks
341
+ if (this.o.draw) this.dH = this.o.draw;
342
+ if (this.o.change) this.cH = this.o.change;
343
+ if (this.o.cancel) this.eH = this.o.cancel;
344
+ if (this.o.release) this.rH = this.o.release;
345
+
346
+ if (this.o.displayPrevious) {
347
+ this.pColor = this.h2rgba(this.o.fgColor, "0.4");
348
+ this.fgColor = this.h2rgba(this.o.fgColor, "0.6");
349
+ } else {
350
+ this.fgColor = this.o.fgColor;
351
+ }
352
+
353
+ return this;
354
+ };
355
+
356
+ this._clear = function () {
357
+ this.$c[0].width = this.$c[0].width;
358
+ };
359
+
360
+ // Abstract methods
361
+ this.listen = function () {}; // on start, one time
362
+ this.extend = function () {}; // each time configure triggered
363
+ this.init = function () {}; // each time configure triggered
364
+ this.change = function (v) {}; // on change
365
+ this.val = function (v) {}; // on release
366
+ this.xy2val = function (x, y) {}; //
367
+ this.draw = function () {}; // on change / on release
368
+ this.clear = function () { this._clear(); };
369
+
370
+ // Utils
371
+ this.h2rgba = function (h, a) {
372
+ var rgb;
373
+ h = h.substring(1,7)
374
+ rgb = [parseInt(h.substring(0,2),16)
375
+ ,parseInt(h.substring(2,4),16)
376
+ ,parseInt(h.substring(4,6),16)];
377
+ return "rgba(" + rgb[0] + "," + rgb[1] + "," + rgb[2] + "," + a + ")";
378
+ };
379
+
380
+ this.copy = function (f, t) {
381
+ for (var i in f) { t[i] = f[i]; }
382
+ };
383
+ };
384
+
385
+
386
+ /**
387
+ * k.Dial
388
+ */
389
+ k.Dial = function () {
390
+ k.o.call(this);
391
+
392
+ this.startAngle = null;
393
+ this.xy = null;
394
+ this.radius = null;
395
+ this.lineWidth = null;
396
+ this.cursorExt = null;
397
+ this.w2 = null;
398
+ this.PI2 = 2*Math.PI;
399
+
400
+ this.extend = function () {
401
+ this.o = $.extend(
402
+ {
403
+ bgColor : this.$.data('bgcolor') || '#EEEEEE',
404
+ angleOffset : this.$.data('angleoffset') || 0,
405
+ angleArc : this.$.data('anglearc') || 360,
406
+ inline : true
407
+ }, this.o
408
+ );
409
+ };
410
+
411
+ this.val = function (v) {
412
+ if (null != v) {
413
+ this.cv = this.o.stopper ? max(min(v, this.o.max), this.o.min) : v;
414
+ this.v = this.cv;
415
+ this.$.val(this.v);
416
+ this._draw();
417
+ } else {
418
+ return this.v;
419
+ }
420
+ };
421
+
422
+ this.xy2val = function (x, y) {
423
+ var a, ret;
424
+
425
+ a = Math.atan2(
426
+ x - (this.x + this.w2)
427
+ , - (y - this.y - this.w2)
428
+ ) - this.angleOffset;
429
+
430
+ if(this.angleArc != this.PI2 && (a < 0) && (a > -0.5)) {
431
+ // if isset angleArc option, set to min if .5 under min
432
+ a = 0;
433
+ } else if (a < 0) {
434
+ a += this.PI2;
435
+ }
436
+
437
+ ret = ~~ (0.5 + (a * (this.o.max - this.o.min) / this.angleArc))
438
+ + this.o.min;
439
+
440
+ this.o.stopper
441
+ && (ret = max(min(ret, this.o.max), this.o.min));
442
+
443
+ return ret;
444
+ };
445
+
446
+ this.listen = function () {
447
+ // bind MouseWheel
448
+ var s = this,
449
+ mw = function (e) {
450
+ e.preventDefault();
451
+
452
+ var ori = e.originalEvent
453
+ ,deltaX = ori.detail || ori.wheelDeltaX
454
+ ,deltaY = ori.detail || ori.wheelDeltaY
455
+ ,v = parseInt(s.$.val()) + (deltaX>0 || deltaY>0 ? 1 : deltaX<0 || deltaY<0 ? -1 : 0);
456
+
457
+ if (
458
+ s.cH
459
+ && (s.cH(v) === false)
460
+ ) return;
461
+
462
+ s.val(v);
463
+ }
464
+ , kval, to, m = 1, kv = {37:-1, 38:1, 39:1, 40:-1};
465
+
466
+ this.$
467
+ .bind(
468
+ "keydown"
469
+ ,function (e) {
470
+ var kc = e.keyCode;
471
+ kval = parseInt(String.fromCharCode(kc));
472
+
473
+ if (isNaN(kval)) {
474
+
475
+ (kc !== 13) // enter
476
+ && (kc !== 8) // bs
477
+ && (kc !== 9) // tab
478
+ && (kc !== 189) // -
479
+ && e.preventDefault();
480
+
481
+ // arrows
482
+ if ($.inArray(kc,[37,38,39,40]) > -1) {
483
+ e.preventDefault();
484
+
485
+ var v = parseInt(s.$.val()) + kv[kc] * m;
486
+
487
+ s.o.stopper
488
+ && (v = max(min(v, s.o.max), s.o.min));
489
+
490
+ s.change(v);
491
+ s._draw();
492
+
493
+ // long time keydown speed-up
494
+ to = window.setTimeout(
495
+ function () { m*=2; }
496
+ ,30
497
+ );
498
+ }
499
+ }
500
+ }
501
+ )
502
+ .bind(
503
+ "keyup"
504
+ ,function (e) {
505
+ if (isNaN(kval)) {
506
+ if (to) {
507
+ window.clearTimeout(to);
508
+ to = null;
509
+ m = 1;
510
+ s.val(s.$.val());
511
+ }
512
+ } else {
513
+ // kval postcond
514
+ (s.$.val() > s.o.max && s.$.val(s.o.max))
515
+ || (s.$.val() < s.o.min && s.$.val(s.o.min));
516
+ }
517
+
518
+ }
519
+ );
520
+
521
+ this.$c.bind("mousewheel DOMMouseScroll", mw);
522
+ this.$.bind("mousewheel DOMMouseScroll", mw)
523
+ };
524
+
525
+ this.init = function () {
526
+
527
+ if (
528
+ this.v < this.o.min
529
+ || this.v > this.o.max
530
+ ) this.v = this.o.min;
531
+
532
+ this.$.val(this.v);
533
+ this.w2 = this.o.width / 2;
534
+ this.cursorExt = this.o.cursor / 100;
535
+ this.xy = this.w2;
536
+ this.lineWidth = this.xy * this.o.thickness;
537
+ this.radius = this.xy - this.lineWidth / 2;
538
+
539
+ this.o.angleOffset
540
+ && (this.o.angleOffset = isNaN(this.o.angleOffset) ? 0 : this.o.angleOffset);
541
+
542
+ this.o.angleArc
543
+ && (this.o.angleArc = isNaN(this.o.angleArc) ? this.PI2 : this.o.angleArc);
544
+
545
+ // deg to rad
546
+ this.angleOffset = this.o.angleOffset * Math.PI / 180;
547
+ this.angleArc = this.o.angleArc * Math.PI / 180;
548
+
549
+ // compute start and end angles
550
+ this.startAngle = 1.5 * Math.PI + this.angleOffset;
551
+ this.endAngle = 1.5 * Math.PI + this.angleOffset + this.angleArc;
552
+
553
+ var s = max(
554
+ String(Math.abs(this.o.max)).length
555
+ , String(Math.abs(this.o.min)).length
556
+ , 2
557
+ ) + 2;
558
+
559
+ this.o.displayInput
560
+ && this.i.css({
561
+ 'width' : ((this.o.width / 2 + 4) >> 0) + 'px'
562
+ ,'height' : ((this.o.width / 3) >> 0) + 'px'
563
+ ,'position' : 'absolute'
564
+ ,'vertical-align' : 'middle'
565
+ ,'margin-top' : ((this.o.width / 3) >> 0) + 'px'
566
+ ,'margin-left' : '-' + ((this.o.width * 3 / 4 + 2) >> 0) + 'px'
567
+ ,'border' : 0
568
+ ,'background' : 'none'
569
+ ,'font' : 'bold ' + ((this.o.width / s) >> 0) + 'px Arial'
570
+ ,'text-align' : 'center'
571
+ ,'color' : this.o.fgColor
572
+ ,'padding' : '0px'
573
+ ,'-webkit-appearance': 'none'
574
+ })
575
+ || this.i.css({
576
+ 'width' : '0px'
577
+ ,'visibility' : 'hidden'
578
+ });
579
+ };
580
+
581
+ this.change = function (v) {
582
+ this.cv = v;
583
+ this.$.val(v);
584
+ };
585
+
586
+ this.angle = function (v) {
587
+ return (v - this.o.min) * this.angleArc / (this.o.max - this.o.min);
588
+ };
589
+
590
+ this.draw = function () {
591
+
592
+ var c = this.g, // context
593
+ a = this.angle(this.cv) // Angle
594
+ , sat = this.startAngle // Start angle
595
+ , eat = sat + a // End angle
596
+ , sa, ea // Previous angles
597
+ , r = 1;
598
+
599
+ c.lineWidth = this.lineWidth;
600
+
601
+ this.o.cursor
602
+ && (sat = eat - this.cursorExt)
603
+ && (eat = eat + this.cursorExt);
604
+
605
+ c.beginPath();
606
+ c.strokeStyle = this.o.bgColor;
607
+ c.arc(this.xy, this.xy, this.radius, this.endAngle, this.startAngle, true);
608
+ c.stroke();
609
+
610
+ if (this.o.displayPrevious) {
611
+ ea = this.startAngle + this.angle(this.v);
612
+ sa = this.startAngle;
613
+ this.o.cursor
614
+ && (sa = ea - this.cursorExt)
615
+ && (ea = ea + this.cursorExt);
616
+
617
+ c.beginPath();
618
+ c.strokeStyle = this.pColor;
619
+ c.arc(this.xy, this.xy, this.radius, sa, ea, false);
620
+ c.stroke();
621
+ r = (this.cv == this.v);
622
+ }
623
+
624
+ c.beginPath();
625
+ c.strokeStyle = r ? this.o.fgColor : this.fgColor ;
626
+ c.arc(this.xy, this.xy, this.radius, sat, eat, false);
627
+ c.stroke();
628
+ };
629
+
630
+ this.cancel = function () {
631
+ this.val(this.v);
632
+ };
633
+ };
634
+
635
+ $.fn.dial = $.fn.knob = function (o) {
636
+ return this.each(
637
+ function () {
638
+ var d = new k.Dial();
639
+ d.o = o;
640
+ d.$ = $(this);
641
+ d.run();
642
+ }
643
+ ).parent();
644
+ };
645
+
646
+ });