Merge lp:~openerp-dev/openerp-web/trunk-graphview-ged into lp:openerp-web

Proposed by Géry Debongnie
Status: Work in progress
Proposed branch: lp:~openerp-dev/openerp-web/trunk-graphview-ged
Merge into: lp:openerp-web
Diff against target: 54324 lines (+27858/-26037)
67 files modified
addons/web/static/src/js/data.js (+1/-1)
addons/web_graph/__openerp__.py (+5/-32)
addons/web_graph/static/lib/bootstrap/bootstrap.js (+1992/-0)
addons/web_graph/static/lib/dropdown.js (+0/-92)
addons/web_graph/static/lib/flotr2/LICENSE (+0/-19)
addons/web_graph/static/lib/flotr2/Makefile (+0/-40)
addons/web_graph/static/lib/flotr2/README.md (+0/-89)
addons/web_graph/static/lib/flotr2/dev/notes.txt (+0/-86)
addons/web_graph/static/lib/flotr2/flotr2.examples.min.js (+0/-2)
addons/web_graph/static/lib/flotr2/flotr2.examples.types.js (+0/-1425)
addons/web_graph/static/lib/flotr2/flotr2.ie.min.js (+0/-33)
addons/web_graph/static/lib/flotr2/flotr2.js (+0/-6865)
addons/web_graph/static/lib/flotr2/flotr2.min.js (+0/-27)
addons/web_graph/static/lib/flotr2/js/Axis.js (+0/-303)
addons/web_graph/static/lib/flotr2/js/Color.js (+0/-163)
addons/web_graph/static/lib/flotr2/js/DOM.js (+0/-88)
addons/web_graph/static/lib/flotr2/js/Date.js (+0/-207)
addons/web_graph/static/lib/flotr2/js/DefaultOptions.js (+0/-98)
addons/web_graph/static/lib/flotr2/js/EventAdapter.js (+0/-52)
addons/web_graph/static/lib/flotr2/js/Flotr.js (+0/-250)
addons/web_graph/static/lib/flotr2/js/Graph.js (+0/-745)
addons/web_graph/static/lib/flotr2/js/Series.js (+0/-74)
addons/web_graph/static/lib/flotr2/js/Text.js (+0/-88)
addons/web_graph/static/lib/flotr2/js/plugins/crosshair.js (+0/-84)
addons/web_graph/static/lib/flotr2/js/plugins/download.js (+0/-51)
addons/web_graph/static/lib/flotr2/js/plugins/grid.js (+0/-208)
addons/web_graph/static/lib/flotr2/js/plugins/handles.js (+0/-199)
addons/web_graph/static/lib/flotr2/js/plugins/hit.js (+0/-337)
addons/web_graph/static/lib/flotr2/js/plugins/labels.js (+0/-227)
addons/web_graph/static/lib/flotr2/js/plugins/legend.js (+0/-179)
addons/web_graph/static/lib/flotr2/js/plugins/selection.js (+0/-278)
addons/web_graph/static/lib/flotr2/js/plugins/spreadsheet.js (+0/-296)
addons/web_graph/static/lib/flotr2/js/plugins/titles.js (+0/-177)
addons/web_graph/static/lib/flotr2/js/types/bars.js (+0/-274)
addons/web_graph/static/lib/flotr2/js/types/bubbles.js (+0/-119)
addons/web_graph/static/lib/flotr2/js/types/candles.js (+0/-127)
addons/web_graph/static/lib/flotr2/js/types/gantt.js (+0/-229)
addons/web_graph/static/lib/flotr2/js/types/lines.js (+0/-275)
addons/web_graph/static/lib/flotr2/js/types/markers.js (+0/-140)
addons/web_graph/static/lib/flotr2/js/types/pie.js (+0/-210)
addons/web_graph/static/lib/flotr2/js/types/points.js (+0/-66)
addons/web_graph/static/lib/flotr2/js/types/radar.js (+0/-60)
addons/web_graph/static/lib/flotr2/js/types/timeline.js (+0/-90)
addons/web_graph/static/lib/flotr2/lib/base64.js (+0/-113)
addons/web_graph/static/lib/flotr2/lib/bean-min.js (+0/-10)
addons/web_graph/static/lib/flotr2/lib/bean.js (+0/-501)
addons/web_graph/static/lib/flotr2/lib/canvas2image.js (+0/-198)
addons/web_graph/static/lib/flotr2/lib/canvastext.js (+0/-429)
addons/web_graph/static/lib/flotr2/lib/excanvas.js (+0/-1425)
addons/web_graph/static/lib/flotr2/lib/imagediff.js (+0/-343)
addons/web_graph/static/lib/flotr2/lib/jasmine/MIT.LICENSE (+0/-20)
addons/web_graph/static/lib/flotr2/lib/jasmine/jasmine-html.js (+0/-190)
addons/web_graph/static/lib/flotr2/lib/jasmine/jasmine.css (+0/-166)
addons/web_graph/static/lib/flotr2/lib/jasmine/jasmine.js (+0/-2476)
addons/web_graph/static/lib/flotr2/lib/prototype.js (+0/-4320)
addons/web_graph/static/lib/flotr2/lib/underscore-min.js (+0/-27)
addons/web_graph/static/lib/flotr2/lib/underscore.js (+0/-839)
addons/web_graph/static/lib/flotr2/lib/yepnope.js (+0/-1)
addons/web_graph/static/lib/nvd3/d3.v3.js (+8436/-0)
addons/web_graph/static/lib/nvd3/nv.d3.js (+14303/-0)
addons/web_graph/static/src/css/bootstrap.css (+1560/-0)
addons/web_graph/static/src/css/flotr2.css (+0/-69)
addons/web_graph/static/src/css/graph.css (+57/-76)
addons/web_graph/static/src/css/nv.d3.css (+769/-0)
addons/web_graph/static/src/fonts/glyphicons-halflings-regular.svg (+229/-0)
addons/web_graph/static/src/js/graph.js (+460/-393)
addons/web_graph/static/src/xml/web_graph.xml (+46/-36)
To merge this branch: bzr merge lp:~openerp-dev/openerp-web/trunk-graphview-ged
Reviewer Review Type Date Requested Status
OpenERP R&D Web Team Pending
Review via email: mp+193414@code.launchpad.net
To post a comment you must log in.
3906. By Géry Debongnie

[REF] very small code improvements in addon web_graph

3907. By Géry Debongnie

[FIX] fixes a bug in method subgroup, in data.js (web client). it was getting the wrong context

3908. By Géry Debongnie

[IMP] first pass at supporting multiples groupings, in x coordinates (addon web_graph)

3909. By Géry Debongnie

[ADD] add bootstrap library to web_graph addon. (customized minimalist version)

3910. By Géry Debongnie

[FIX] better handling of default groupings in web_graph addon

3911. By Géry Debongnie

[IMP] improves bar chart display in web_graph addon

3912. By Géry Debongnie

[IMP] slightly improve look when displaying charts in addon web_graph

3913. By Géry Debongnie

[FIX] add bootstrap.js file to module import (web_graph)

3914. By Géry Debongnie

[IMP] add button dropdown to chart view interface (module web_graph)

3915. By Géry Debongnie

[IMP] add button dropdown to select measure (module web_graph)

3916. By Géry Debongnie

[IMP] add row and columns buttons in graph view (addon web_graph)

3917. By Géry Debongnie

[IMP] add important fields to row and columns buttons in graph view (addon web_graph)

3918. By Géry Debongnie

[IMP] add clear columns and clear rows field to row and columns buttons in graph view (addon web_graph)

3919. By Géry Debongnie

[IMP] correct code to detect fields to display in row and col buttons in graph view (addon web_graph)

3920. By Géry Debongnie

[IMP] properly handles the case when there are no groupbys defined (graph view, addon web_graph)

3921. By Géry Debongnie

[IMP] work in progress. implementing multidimensional table view in graph view (module web_graph)

3922. By Géry Debongnie

[IMP] work in progress. implementing multidimensional table view in graph view (module web_graph)

3923. By Géry Debongnie

[IMP] implement the headers rendering in table view (in graph_view) (addon web_graph)

Unmerged revisions

3923. By Géry Debongnie

[IMP] implement the headers rendering in table view (in graph_view) (addon web_graph)

3922. By Géry Debongnie

[IMP] work in progress. implementing multidimensional table view in graph view (module web_graph)

3921. By Géry Debongnie

[IMP] work in progress. implementing multidimensional table view in graph view (module web_graph)

3920. By Géry Debongnie

[IMP] properly handles the case when there are no groupbys defined (graph view, addon web_graph)

3919. By Géry Debongnie

[IMP] correct code to detect fields to display in row and col buttons in graph view (addon web_graph)

3918. By Géry Debongnie

[IMP] add clear columns and clear rows field to row and columns buttons in graph view (addon web_graph)

3917. By Géry Debongnie

[IMP] add important fields to row and columns buttons in graph view (addon web_graph)

3916. By Géry Debongnie

[IMP] add row and columns buttons in graph view (addon web_graph)

3915. By Géry Debongnie

[IMP] add button dropdown to select measure (module web_graph)

3914. By Géry Debongnie

[IMP] add button dropdown to chart view interface (module web_graph)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'addons/web/static/src/js/data.js'
--- addons/web/static/src/js/data.js 2013-09-10 12:52:23 +0000
+++ addons/web/static/src/js/data.js 2013-11-07 14:49:39 +0000
@@ -249,7 +249,7 @@
249 return this.attributes[key];249 return this.attributes[key];
250 },250 },
251 subgroups: function () {251 subgroups: function () {
252 return this.model.query().group_by(this.model.context().group_by);252 return this.model.query().group_by(this.model._context.group_by);
253 },253 },
254 query: function () {254 query: function () {
255 return this.model.query.apply(this.model, arguments);255 return this.model.query.apply(this.model, arguments);
256256
=== modified file 'addons/web_graph/__openerp__.py'
--- addons/web_graph/__openerp__.py 2012-08-22 13:03:36 +0000
+++ addons/web_graph/__openerp__.py 2013-11-07 14:49:39 +0000
@@ -15,38 +15,10 @@
15 'version': '3.0',15 'version': '3.0',
16 'depends': ['web'],16 'depends': ['web'],
17 'js': [17 'js': [
18 'static/lib/dropdown.js',18 'static/lib/nvd3/d3.v3.js',
19 'static/lib/flotr2/lib/bean.js',19 'static/lib/nvd3/nv.d3.js',
20 'static/lib/flotr2/js/Flotr.js',20 'static/src/js/graph.js',
21 'static/lib/flotr2/js/DefaultOptions.js',21 'static/lib/bootstrap/bootstrap.js',
22 'static/lib/flotr2/js/Color.js',
23 'static/lib/flotr2/js/Date.js',
24 'static/lib/flotr2/js/DOM.js',
25 'static/lib/flotr2/js/EventAdapter.js',
26 'static/lib/flotr2/js/Text.js',
27 'static/lib/flotr2/js/Graph.js',
28 'static/lib/flotr2/js/Axis.js',
29 'static/lib/flotr2/js/Series.js',
30 'static/lib/flotr2/js/types/lines.js',
31 'static/lib/flotr2/js/types/bars.js',
32 'static/lib/flotr2/js/types/bubbles.js',
33 'static/lib/flotr2/js/types/candles.js',
34 'static/lib/flotr2/js/types/gantt.js',
35 'static/lib/flotr2/js/types/markers.js',
36 'static/lib/flotr2/js/types/pie.js',
37 'static/lib/flotr2/js/types/points.js',
38 'static/lib/flotr2/js/types/radar.js',
39 'static/lib/flotr2/js/types/timeline.js',
40 'static/lib/flotr2/js/plugins/crosshair.js',
41 'static/lib/flotr2/js/plugins/download.js',
42 'static/lib/flotr2/js/plugins/grid.js',
43 'static/lib/flotr2/js/plugins/hit.js',
44 'static/lib/flotr2/js/plugins/selection.js',
45 'static/lib/flotr2/js/plugins/labels.js',
46 'static/lib/flotr2/js/plugins/legend.js',
47 'static/lib/flotr2/js/plugins/spreadsheet.js',
48 'static/lib/flotr2/js/plugins/titles.js',
49 'static/src/js/graph.js'
50 ],22 ],
51 'css': [23 'css': [
52 'static/src/css/*.css',24 'static/src/css/*.css',
@@ -56,3 +28,4 @@
56 ],28 ],
57 'auto_install': True29 'auto_install': True
58}30}
31
5932
=== added directory 'addons/web_graph/static/lib/bootstrap'
=== added file 'addons/web_graph/static/lib/bootstrap/bootstrap.js'
--- addons/web_graph/static/lib/bootstrap/bootstrap.js 1970-01-01 00:00:00 +0000
+++ addons/web_graph/static/lib/bootstrap/bootstrap.js 2013-11-07 14:49:39 +0000
@@ -0,0 +1,1992 @@
1/* ========================================================================
2 * Bootstrap: alert.js v3.0.0
3 * http://getbootstrap.com/javascript/#alerts
4 * ========================================================================
5 * Copyright 2013 Twitter, Inc.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ======================================================================== */
19
20
21+function ($) { "use strict";
22
23 // ALERT CLASS DEFINITION
24 // ======================
25
26 var dismiss = '[data-dismiss="alert"]'
27 var Alert = function (el) {
28 $(el).on('click', dismiss, this.close)
29 }
30
31 Alert.prototype.close = function (e) {
32 var $this = $(this)
33 var selector = $this.attr('data-target')
34
35 if (!selector) {
36 selector = $this.attr('href')
37 selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
38 }
39
40 var $parent = $(selector)
41
42 if (e) e.preventDefault()
43
44 if (!$parent.length) {
45 $parent = $this.hasClass('alert') ? $this : $this.parent()
46 }
47
48 $parent.trigger(e = $.Event('close.bs.alert'))
49
50 if (e.isDefaultPrevented()) return
51
52 $parent.removeClass('in')
53
54 function removeElement() {
55 $parent.trigger('closed.bs.alert').remove()
56 }
57
58 $.support.transition && $parent.hasClass('fade') ?
59 $parent
60 .one($.support.transition.end, removeElement)
61 .emulateTransitionEnd(150) :
62 removeElement()
63 }
64
65
66 // ALERT PLUGIN DEFINITION
67 // =======================
68
69 var old = $.fn.alert
70
71 $.fn.alert = function (option) {
72 return this.each(function () {
73 var $this = $(this)
74 var data = $this.data('bs.alert')
75
76 if (!data) $this.data('bs.alert', (data = new Alert(this)))
77 if (typeof option == 'string') data[option].call($this)
78 })
79 }
80
81 $.fn.alert.Constructor = Alert
82
83
84 // ALERT NO CONFLICT
85 // =================
86
87 $.fn.alert.noConflict = function () {
88 $.fn.alert = old
89 return this
90 }
91
92
93 // ALERT DATA-API
94 // ==============
95
96 $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)
97
98}(window.jQuery);
99
100/* ========================================================================
101 * Bootstrap: button.js v3.0.0
102 * http://getbootstrap.com/javascript/#buttons
103 * ========================================================================
104 * Copyright 2013 Twitter, Inc.
105 *
106 * Licensed under the Apache License, Version 2.0 (the "License");
107 * you may not use this file except in compliance with the License.
108 * You may obtain a copy of the License at
109 *
110 * http://www.apache.org/licenses/LICENSE-2.0
111 *
112 * Unless required by applicable law or agreed to in writing, software
113 * distributed under the License is distributed on an "AS IS" BASIS,
114 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
115 * See the License for the specific language governing permissions and
116 * limitations under the License.
117 * ======================================================================== */
118
119
120+function ($) { "use strict";
121
122 // BUTTON PUBLIC CLASS DEFINITION
123 // ==============================
124
125 var Button = function (element, options) {
126 this.$element = $(element)
127 this.options = $.extend({}, Button.DEFAULTS, options)
128 }
129
130 Button.DEFAULTS = {
131 loadingText: 'loading...'
132 }
133
134 Button.prototype.setState = function (state) {
135 var d = 'disabled'
136 var $el = this.$element
137 var val = $el.is('input') ? 'val' : 'html'
138 var data = $el.data()
139
140 state = state + 'Text'
141
142 if (!data.resetText) $el.data('resetText', $el[val]())
143
144 $el[val](data[state] || this.options[state])
145
146 // push to event loop to allow forms to submit
147 setTimeout(function () {
148 state == 'loadingText' ?
149 $el.addClass(d).attr(d, d) :
150 $el.removeClass(d).removeAttr(d);
151 }, 0)
152 }
153
154 Button.prototype.toggle = function () {
155 var $parent = this.$element.closest('[data-toggle="buttons"]')
156
157 if ($parent.length) {
158 var $input = this.$element.find('input')
159 .prop('checked', !this.$element.hasClass('active'))
160 .trigger('change')
161 if ($input.prop('type') === 'radio') $parent.find('.active').removeClass('active')
162 }
163
164 this.$element.toggleClass('active')
165 }
166
167
168 // BUTTON PLUGIN DEFINITION
169 // ========================
170
171 var old = $.fn.button
172
173 $.fn.button = function (option) {
174 return this.each(function () {
175 var $this = $(this)
176 var data = $this.data('bs.button')
177 var options = typeof option == 'object' && option
178
179 if (!data) $this.data('bs.button', (data = new Button(this, options)))
180
181 if (option == 'toggle') data.toggle()
182 else if (option) data.setState(option)
183 })
184 }
185
186 $.fn.button.Constructor = Button
187
188
189 // BUTTON NO CONFLICT
190 // ==================
191
192 $.fn.button.noConflict = function () {
193 $.fn.button = old
194 return this
195 }
196
197
198 // BUTTON DATA-API
199 // ===============
200
201 $(document).on('click.bs.button.data-api', '[data-toggle^=button]', function (e) {
202 var $btn = $(e.target)
203 if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
204 $btn.button('toggle')
205 e.preventDefault()
206 })
207
208}(window.jQuery);
209
210/* ========================================================================
211 * Bootstrap: carousel.js v3.0.0
212 * http://getbootstrap.com/javascript/#carousel
213 * ========================================================================
214 * Copyright 2013 Twitter, Inc.
215 *
216 * Licensed under the Apache License, Version 2.0 (the "License");
217 * you may not use this file except in compliance with the License.
218 * You may obtain a copy of the License at
219 *
220 * http://www.apache.org/licenses/LICENSE-2.0
221 *
222 * Unless required by applicable law or agreed to in writing, software
223 * distributed under the License is distributed on an "AS IS" BASIS,
224 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
225 * See the License for the specific language governing permissions and
226 * limitations under the License.
227 * ======================================================================== */
228
229
230+function ($) { "use strict";
231
232 // CAROUSEL CLASS DEFINITION
233 // =========================
234
235 var Carousel = function (element, options) {
236 this.$element = $(element)
237 this.$indicators = this.$element.find('.carousel-indicators')
238 this.options = options
239 this.paused =
240 this.sliding =
241 this.interval =
242 this.$active =
243 this.$items = null
244
245 this.options.pause == 'hover' && this.$element
246 .on('mouseenter', $.proxy(this.pause, this))
247 .on('mouseleave', $.proxy(this.cycle, this))
248 }
249
250 Carousel.DEFAULTS = {
251 interval: 5000
252 , pause: 'hover'
253 , wrap: true
254 }
255
256 Carousel.prototype.cycle = function (e) {
257 e || (this.paused = false)
258
259 this.interval && clearInterval(this.interval)
260
261 this.options.interval
262 && !this.paused
263 && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
264
265 return this
266 }
267
268 Carousel.prototype.getActiveIndex = function () {
269 this.$active = this.$element.find('.item.active')
270 this.$items = this.$active.parent().children()
271
272 return this.$items.index(this.$active)
273 }
274
275 Carousel.prototype.to = function (pos) {
276 var that = this
277 var activeIndex = this.getActiveIndex()
278
279 if (pos > (this.$items.length - 1) || pos < 0) return
280
281 if (this.sliding) return this.$element.one('slid', function () { that.to(pos) })
282 if (activeIndex == pos) return this.pause().cycle()
283
284 return this.slide(pos > activeIndex ? 'next' : 'prev', $(this.$items[pos]))
285 }
286
287 Carousel.prototype.pause = function (e) {
288 e || (this.paused = true)
289
290 if (this.$element.find('.next, .prev').length && $.support.transition.end) {
291 this.$element.trigger($.support.transition.end)
292 this.cycle(true)
293 }
294
295 this.interval = clearInterval(this.interval)
296
297 return this
298 }
299
300 Carousel.prototype.next = function () {
301 if (this.sliding) return
302 return this.slide('next')
303 }
304
305 Carousel.prototype.prev = function () {
306 if (this.sliding) return
307 return this.slide('prev')
308 }
309
310 Carousel.prototype.slide = function (type, next) {
311 var $active = this.$element.find('.item.active')
312 var $next = next || $active[type]()
313 var isCycling = this.interval
314 var direction = type == 'next' ? 'left' : 'right'
315 var fallback = type == 'next' ? 'first' : 'last'
316 var that = this
317
318 if (!$next.length) {
319 if (!this.options.wrap) return
320 $next = this.$element.find('.item')[fallback]()
321 }
322
323 this.sliding = true
324
325 isCycling && this.pause()
326
327 var e = $.Event('slide.bs.carousel', { relatedTarget: $next[0], direction: direction })
328
329 if ($next.hasClass('active')) return
330
331 if (this.$indicators.length) {
332 this.$indicators.find('.active').removeClass('active')
333 this.$element.one('slid', function () {
334 var $nextIndicator = $(that.$indicators.children()[that.getActiveIndex()])
335 $nextIndicator && $nextIndicator.addClass('active')
336 })
337 }
338
339 if ($.support.transition && this.$element.hasClass('slide')) {
340 this.$element.trigger(e)
341 if (e.isDefaultPrevented()) return
342 $next.addClass(type)
343 $next[0].offsetWidth // force reflow
344 $active.addClass(direction)
345 $next.addClass(direction)
346 $active
347 .one($.support.transition.end, function () {
348 $next.removeClass([type, direction].join(' ')).addClass('active')
349 $active.removeClass(['active', direction].join(' '))
350 that.sliding = false
351 setTimeout(function () { that.$element.trigger('slid') }, 0)
352 })
353 .emulateTransitionEnd(600)
354 } else {
355 this.$element.trigger(e)
356 if (e.isDefaultPrevented()) return
357 $active.removeClass('active')
358 $next.addClass('active')
359 this.sliding = false
360 this.$element.trigger('slid')
361 }
362
363 isCycling && this.cycle()
364
365 return this
366 }
367
368
369 // CAROUSEL PLUGIN DEFINITION
370 // ==========================
371
372 var old = $.fn.carousel
373
374 $.fn.carousel = function (option) {
375 return this.each(function () {
376 var $this = $(this)
377 var data = $this.data('bs.carousel')
378 var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)
379 var action = typeof option == 'string' ? option : options.slide
380
381 if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))
382 if (typeof option == 'number') data.to(option)
383 else if (action) data[action]()
384 else if (options.interval) data.pause().cycle()
385 })
386 }
387
388 $.fn.carousel.Constructor = Carousel
389
390
391 // CAROUSEL NO CONFLICT
392 // ====================
393
394 $.fn.carousel.noConflict = function () {
395 $.fn.carousel = old
396 return this
397 }
398
399
400 // CAROUSEL DATA-API
401 // =================
402
403 $(document).on('click.bs.carousel.data-api', '[data-slide], [data-slide-to]', function (e) {
404 var $this = $(this), href
405 var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
406 var options = $.extend({}, $target.data(), $this.data())
407 var slideIndex = $this.attr('data-slide-to')
408 if (slideIndex) options.interval = false
409
410 $target.carousel(options)
411
412 if (slideIndex = $this.attr('data-slide-to')) {
413 $target.data('bs.carousel').to(slideIndex)
414 }
415
416 e.preventDefault()
417 })
418
419 $(window).on('load', function () {
420 $('[data-ride="carousel"]').each(function () {
421 var $carousel = $(this)
422 $carousel.carousel($carousel.data())
423 })
424 })
425
426}(window.jQuery);
427
428/* ========================================================================
429 * Bootstrap: dropdown.js v3.0.0
430 * http://getbootstrap.com/javascript/#dropdowns
431 * ========================================================================
432 * Copyright 2013 Twitter, Inc.
433 *
434 * Licensed under the Apache License, Version 2.0 (the "License");
435 * you may not use this file except in compliance with the License.
436 * You may obtain a copy of the License at
437 *
438 * http://www.apache.org/licenses/LICENSE-2.0
439 *
440 * Unless required by applicable law or agreed to in writing, software
441 * distributed under the License is distributed on an "AS IS" BASIS,
442 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
443 * See the License for the specific language governing permissions and
444 * limitations under the License.
445 * ======================================================================== */
446
447
448+function ($) { "use strict";
449
450 // DROPDOWN CLASS DEFINITION
451 // =========================
452
453 var backdrop = '.dropdown-backdrop'
454 var toggle = '[data-toggle=dropdown]'
455 var Dropdown = function (element) {
456 var $el = $(element).on('click.bs.dropdown', this.toggle)
457 }
458
459 Dropdown.prototype.toggle = function (e) {
460 var $this = $(this)
461
462 if ($this.is('.disabled, :disabled')) return
463
464 var $parent = getParent($this)
465 var isActive = $parent.hasClass('open')
466
467 clearMenus()
468
469 if (!isActive) {
470 if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
471 // if mobile we we use a backdrop because click events don't delegate
472 $('<div class="dropdown-backdrop"/>').insertAfter($(this)).on('click', clearMenus)
473 }
474
475 $parent.trigger(e = $.Event('show.bs.dropdown'))
476
477 if (e.isDefaultPrevented()) return
478
479 $parent
480 .toggleClass('open')
481 .trigger('shown.bs.dropdown')
482
483 $this.focus()
484 }
485
486 return false
487 }
488
489 Dropdown.prototype.keydown = function (e) {
490 if (!/(38|40|27)/.test(e.keyCode)) return
491
492 var $this = $(this)
493
494 e.preventDefault()
495 e.stopPropagation()
496
497 if ($this.is('.disabled, :disabled')) return
498
499 var $parent = getParent($this)
500 var isActive = $parent.hasClass('open')
501
502 if (!isActive || (isActive && e.keyCode == 27)) {
503 if (e.which == 27) $parent.find(toggle).focus()
504 return $this.click()
505 }
506
507 var $items = $('[role=menu] li:not(.divider):visible a', $parent)
508
509 if (!$items.length) return
510
511 var index = $items.index($items.filter(':focus'))
512
513 if (e.keyCode == 38 && index > 0) index-- // up
514 if (e.keyCode == 40 && index < $items.length - 1) index++ // down
515 if (!~index) index=0
516
517 $items.eq(index).focus()
518 }
519
520 function clearMenus() {
521 $(backdrop).remove()
522 $(toggle).each(function (e) {
523 var $parent = getParent($(this))
524 if (!$parent.hasClass('open')) return
525 $parent.trigger(e = $.Event('hide.bs.dropdown'))
526 if (e.isDefaultPrevented()) return
527 $parent.removeClass('open').trigger('hidden.bs.dropdown')
528 })
529 }
530
531 function getParent($this) {
532 var selector = $this.attr('data-target')
533
534 if (!selector) {
535 selector = $this.attr('href')
536 selector = selector && /#/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
537 }
538
539 var $parent = selector && $(selector)
540
541 return $parent && $parent.length ? $parent : $this.parent()
542 }
543
544
545 // DROPDOWN PLUGIN DEFINITION
546 // ==========================
547
548 var old = $.fn.dropdown
549
550 $.fn.dropdown = function (option) {
551 return this.each(function () {
552 var $this = $(this)
553 var data = $this.data('dropdown')
554
555 if (!data) $this.data('dropdown', (data = new Dropdown(this)))
556 if (typeof option == 'string') data[option].call($this)
557 })
558 }
559
560 $.fn.dropdown.Constructor = Dropdown
561
562
563 // DROPDOWN NO CONFLICT
564 // ====================
565
566 $.fn.dropdown.noConflict = function () {
567 $.fn.dropdown = old
568 return this
569 }
570
571
572 // APPLY TO STANDARD DROPDOWN ELEMENTS
573 // ===================================
574
575 $(document)
576 .on('click.bs.dropdown.data-api', clearMenus)
577 .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
578 .on('click.bs.dropdown.data-api' , toggle, Dropdown.prototype.toggle)
579 .on('keydown.bs.dropdown.data-api', toggle + ', [role=menu]' , Dropdown.prototype.keydown)
580
581}(window.jQuery);
582
583/* ========================================================================
584 * Bootstrap: modal.js v3.0.0
585 * http://getbootstrap.com/javascript/#modals
586 * ========================================================================
587 * Copyright 2013 Twitter, Inc.
588 *
589 * Licensed under the Apache License, Version 2.0 (the "License");
590 * you may not use this file except in compliance with the License.
591 * You may obtain a copy of the License at
592 *
593 * http://www.apache.org/licenses/LICENSE-2.0
594 *
595 * Unless required by applicable law or agreed to in writing, software
596 * distributed under the License is distributed on an "AS IS" BASIS,
597 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
598 * See the License for the specific language governing permissions and
599 * limitations under the License.
600 * ======================================================================== */
601
602
603+function ($) { "use strict";
604
605 // MODAL CLASS DEFINITION
606 // ======================
607
608 var Modal = function (element, options) {
609 this.options = options
610 this.$element = $(element)
611 this.$backdrop =
612 this.isShown = null
613
614 if (this.options.remote) this.$element.load(this.options.remote)
615 }
616
617 Modal.DEFAULTS = {
618 backdrop: true
619 , keyboard: true
620 , show: true
621 }
622
623 Modal.prototype.toggle = function (_relatedTarget) {
624 return this[!this.isShown ? 'show' : 'hide'](_relatedTarget)
625 }
626
627 Modal.prototype.show = function (_relatedTarget) {
628 var that = this
629 var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })
630
631 this.$element.trigger(e)
632
633 if (this.isShown || e.isDefaultPrevented()) return
634
635 this.isShown = true
636
637 this.escape()
638
639 this.$element.on('click.dismiss.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))
640
641 this.backdrop(function () {
642 var transition = $.support.transition && that.$element.hasClass('fade')
643
644 if (!that.$element.parent().length) {
645 that.$element.appendTo(document.body) // don't move modals dom position
646 }
647
648 that.$element.show()
649
650 if (transition) {
651 that.$element[0].offsetWidth // force reflow
652 }
653
654 that.$element
655 .addClass('in')
656 .attr('aria-hidden', false)
657
658 that.enforceFocus()
659
660 var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })
661
662 transition ?
663 that.$element.find('.modal-dialog') // wait for modal to slide in
664 .one($.support.transition.end, function () {
665 that.$element.focus().trigger(e)
666 })
667 .emulateTransitionEnd(300) :
668 that.$element.focus().trigger(e)
669 })
670 }
671
672 Modal.prototype.hide = function (e) {
673 if (e) e.preventDefault()
674
675 e = $.Event('hide.bs.modal')
676
677 this.$element.trigger(e)
678
679 if (!this.isShown || e.isDefaultPrevented()) return
680
681 this.isShown = false
682
683 this.escape()
684
685 $(document).off('focusin.bs.modal')
686
687 this.$element
688 .removeClass('in')
689 .attr('aria-hidden', true)
690 .off('click.dismiss.modal')
691
692 $.support.transition && this.$element.hasClass('fade') ?
693 this.$element
694 .one($.support.transition.end, $.proxy(this.hideModal, this))
695 .emulateTransitionEnd(300) :
696 this.hideModal()
697 }
698
699 Modal.prototype.enforceFocus = function () {
700 $(document)
701 .off('focusin.bs.modal') // guard against infinite focus loop
702 .on('focusin.bs.modal', $.proxy(function (e) {
703 if (this.$element[0] !== e.target && !this.$element.has(e.target).length) {
704 this.$element.focus()
705 }
706 }, this))
707 }
708
709 Modal.prototype.escape = function () {
710 if (this.isShown && this.options.keyboard) {
711 this.$element.on('keyup.dismiss.bs.modal', $.proxy(function (e) {
712 e.which == 27 && this.hide()
713 }, this))
714 } else if (!this.isShown) {
715 this.$element.off('keyup.dismiss.bs.modal')
716 }
717 }
718
719 Modal.prototype.hideModal = function () {
720 var that = this
721 this.$element.hide()
722 this.backdrop(function () {
723 that.removeBackdrop()
724 that.$element.trigger('hidden.bs.modal')
725 })
726 }
727
728 Modal.prototype.removeBackdrop = function () {
729 this.$backdrop && this.$backdrop.remove()
730 this.$backdrop = null
731 }
732
733 Modal.prototype.backdrop = function (callback) {
734 var that = this
735 var animate = this.$element.hasClass('fade') ? 'fade' : ''
736
737 if (this.isShown && this.options.backdrop) {
738 var doAnimate = $.support.transition && animate
739
740 this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
741 .appendTo(document.body)
742
743 this.$element.on('click.dismiss.modal', $.proxy(function (e) {
744 if (e.target !== e.currentTarget) return
745 this.options.backdrop == 'static'
746 ? this.$element[0].focus.call(this.$element[0])
747 : this.hide.call(this)
748 }, this))
749
750 if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
751
752 this.$backdrop.addClass('in')
753
754 if (!callback) return
755
756 doAnimate ?
757 this.$backdrop
758 .one($.support.transition.end, callback)
759 .emulateTransitionEnd(150) :
760 callback()
761
762 } else if (!this.isShown && this.$backdrop) {
763 this.$backdrop.removeClass('in')
764
765 $.support.transition && this.$element.hasClass('fade')?
766 this.$backdrop
767 .one($.support.transition.end, callback)
768 .emulateTransitionEnd(150) :
769 callback()
770
771 } else if (callback) {
772 callback()
773 }
774 }
775
776
777 // MODAL PLUGIN DEFINITION
778 // =======================
779
780 var old = $.fn.modal
781
782 $.fn.modal = function (option, _relatedTarget) {
783 return this.each(function () {
784 var $this = $(this)
785 var data = $this.data('bs.modal')
786 var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)
787
788 if (!data) $this.data('bs.modal', (data = new Modal(this, options)))
789 if (typeof option == 'string') data[option](_relatedTarget)
790 else if (options.show) data.show(_relatedTarget)
791 })
792 }
793
794 $.fn.modal.Constructor = Modal
795
796
797 // MODAL NO CONFLICT
798 // =================
799
800 $.fn.modal.noConflict = function () {
801 $.fn.modal = old
802 return this
803 }
804
805
806 // MODAL DATA-API
807 // ==============
808
809 $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) {
810 var $this = $(this)
811 var href = $this.attr('href')
812 var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) //strip for ie7
813 var option = $target.data('modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())
814
815 e.preventDefault()
816
817 $target
818 .modal(option, this)
819 .one('hide', function () {
820 $this.is(':visible') && $this.focus()
821 })
822 })
823
824 $(document)
825 .on('show.bs.modal', '.modal', function () { $(document.body).addClass('modal-open') })
826 .on('hidden.bs.modal', '.modal', function () { $(document.body).removeClass('modal-open') })
827
828}(window.jQuery);
829
830/* ========================================================================
831 * Bootstrap: tooltip.js v3.0.0
832 * http://getbootstrap.com/javascript/#tooltip
833 * Inspired by the original jQuery.tipsy by Jason Frame
834 * ========================================================================
835 * Copyright 2013 Twitter, Inc.
836 *
837 * Licensed under the Apache License, Version 2.0 (the "License");
838 * you may not use this file except in compliance with the License.
839 * You may obtain a copy of the License at
840 *
841 * http://www.apache.org/licenses/LICENSE-2.0
842 *
843 * Unless required by applicable law or agreed to in writing, software
844 * distributed under the License is distributed on an "AS IS" BASIS,
845 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
846 * See the License for the specific language governing permissions and
847 * limitations under the License.
848 * ======================================================================== */
849
850
851+function ($) { "use strict";
852
853 // TOOLTIP PUBLIC CLASS DEFINITION
854 // ===============================
855
856 var Tooltip = function (element, options) {
857 this.type =
858 this.options =
859 this.enabled =
860 this.timeout =
861 this.hoverState =
862 this.$element = null
863
864 this.init('tooltip', element, options)
865 }
866
867 Tooltip.DEFAULTS = {
868 animation: true
869 , placement: 'top'
870 , selector: false
871 , template: '<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>'
872 , trigger: 'hover focus'
873 , title: ''
874 , delay: 0
875 , html: false
876 , container: false
877 }
878
879 Tooltip.prototype.init = function (type, element, options) {
880 this.enabled = true
881 this.type = type
882 this.$element = $(element)
883 this.options = this.getOptions(options)
884
885 var triggers = this.options.trigger.split(' ')
886
887 for (var i = triggers.length; i--;) {
888 var trigger = triggers[i]
889
890 if (trigger == 'click') {
891 this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
892 } else if (trigger != 'manual') {
893 var eventIn = trigger == 'hover' ? 'mouseenter' : 'focus'
894 var eventOut = trigger == 'hover' ? 'mouseleave' : 'blur'
895
896 this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
897 this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
898 }
899 }
900
901 this.options.selector ?
902 (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
903 this.fixTitle()
904 }
905
906 Tooltip.prototype.getDefaults = function () {
907 return Tooltip.DEFAULTS
908 }
909
910 Tooltip.prototype.getOptions = function (options) {
911 options = $.extend({}, this.getDefaults(), this.$element.data(), options)
912
913 if (options.delay && typeof options.delay == 'number') {
914 options.delay = {
915 show: options.delay
916 , hide: options.delay
917 }
918 }
919
920 return options
921 }
922
923 Tooltip.prototype.getDelegateOptions = function () {
924 var options = {}
925 var defaults = this.getDefaults()
926
927 this._options && $.each(this._options, function (key, value) {
928 if (defaults[key] != value) options[key] = value
929 })
930
931 return options
932 }
933
934 Tooltip.prototype.enter = function (obj) {
935 var self = obj instanceof this.constructor ?
936 obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type)
937
938 clearTimeout(self.timeout)
939
940 self.hoverState = 'in'
941
942 if (!self.options.delay || !self.options.delay.show) return self.show()
943
944 self.timeout = setTimeout(function () {
945 if (self.hoverState == 'in') self.show()
946 }, self.options.delay.show)
947 }
948
949 Tooltip.prototype.leave = function (obj) {
950 var self = obj instanceof this.constructor ?
951 obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type)
952
953 clearTimeout(self.timeout)
954
955 self.hoverState = 'out'
956
957 if (!self.options.delay || !self.options.delay.hide) return self.hide()
958
959 self.timeout = setTimeout(function () {
960 if (self.hoverState == 'out') self.hide()
961 }, self.options.delay.hide)
962 }
963
964 Tooltip.prototype.show = function () {
965 var e = $.Event('show.bs.'+ this.type)
966
967 if (this.hasContent() && this.enabled) {
968 this.$element.trigger(e)
969
970 if (e.isDefaultPrevented()) return
971
972 var $tip = this.tip()
973
974 this.setContent()
975
976 if (this.options.animation) $tip.addClass('fade')
977
978 var placement = typeof this.options.placement == 'function' ?
979 this.options.placement.call(this, $tip[0], this.$element[0]) :
980 this.options.placement
981
982 var autoToken = /\s?auto?\s?/i
983 var autoPlace = autoToken.test(placement)
984 if (autoPlace) placement = placement.replace(autoToken, '') || 'top'
985
986 $tip
987 .detach()
988 .css({ top: 0, left: 0, display: 'block' })
989 .addClass(placement)
990
991 this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
992
993 var pos = this.getPosition()
994 var actualWidth = $tip[0].offsetWidth
995 var actualHeight = $tip[0].offsetHeight
996
997 if (autoPlace) {
998 var $parent = this.$element.parent()
999
1000 var orgPlacement = placement
1001 var docScroll = document.documentElement.scrollTop || document.body.scrollTop
1002 var parentWidth = this.options.container == 'body' ? window.innerWidth : $parent.outerWidth()
1003 var parentHeight = this.options.container == 'body' ? window.innerHeight : $parent.outerHeight()
1004 var parentLeft = this.options.container == 'body' ? 0 : $parent.offset().left
1005
1006 placement = placement == 'bottom' && pos.top + pos.height + actualHeight - docScroll > parentHeight ? 'top' :
1007 placement == 'top' && pos.top - docScroll - actualHeight < 0 ? 'bottom' :
1008 placement == 'right' && pos.right + actualWidth > parentWidth ? 'left' :
1009 placement == 'left' && pos.left - actualWidth < parentLeft ? 'right' :
1010 placement
1011
1012 $tip
1013 .removeClass(orgPlacement)
1014 .addClass(placement)
1015 }
1016
1017 var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)
1018
1019 this.applyPlacement(calculatedOffset, placement)
1020 this.$element.trigger('shown.bs.' + this.type)
1021 }
1022 }
1023
1024 Tooltip.prototype.applyPlacement = function(offset, placement) {
1025 var replace
1026 var $tip = this.tip()
1027 var width = $tip[0].offsetWidth
1028 var height = $tip[0].offsetHeight
1029
1030 // manually read margins because getBoundingClientRect includes difference
1031 var marginTop = parseInt($tip.css('margin-top'), 10)
1032 var marginLeft = parseInt($tip.css('margin-left'), 10)
1033
1034 // we must check for NaN for ie 8/9
1035 if (isNaN(marginTop)) marginTop = 0
1036 if (isNaN(marginLeft)) marginLeft = 0
1037
1038 offset.top = offset.top + marginTop
1039 offset.left = offset.left + marginLeft
1040
1041 $tip
1042 .offset(offset)
1043 .addClass('in')
1044
1045 // check to see if placing tip in new offset caused the tip to resize itself
1046 var actualWidth = $tip[0].offsetWidth
1047 var actualHeight = $tip[0].offsetHeight
1048
1049 if (placement == 'top' && actualHeight != height) {
1050 replace = true
1051 offset.top = offset.top + height - actualHeight
1052 }
1053
1054 if (/bottom|top/.test(placement)) {
1055 var delta = 0
1056
1057 if (offset.left < 0) {
1058 delta = offset.left * -2
1059 offset.left = 0
1060
1061 $tip.offset(offset)
1062
1063 actualWidth = $tip[0].offsetWidth
1064 actualHeight = $tip[0].offsetHeight
1065 }
1066
1067 this.replaceArrow(delta - width + actualWidth, actualWidth, 'left')
1068 } else {
1069 this.replaceArrow(actualHeight - height, actualHeight, 'top')
1070 }
1071
1072 if (replace) $tip.offset(offset)
1073 }
1074
1075 Tooltip.prototype.replaceArrow = function(delta, dimension, position) {
1076 this.arrow().css(position, delta ? (50 * (1 - delta / dimension) + "%") : '')
1077 }
1078
1079 Tooltip.prototype.setContent = function () {
1080 var $tip = this.tip()
1081 var title = this.getTitle()
1082
1083 $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
1084 $tip.removeClass('fade in top bottom left right')
1085 }
1086
1087 Tooltip.prototype.hide = function () {
1088 var that = this
1089 var $tip = this.tip()
1090 var e = $.Event('hide.bs.' + this.type)
1091
1092 function complete() {
1093 if (that.hoverState != 'in') $tip.detach()
1094 }
1095
1096 this.$element.trigger(e)
1097
1098 if (e.isDefaultPrevented()) return
1099
1100 $tip.removeClass('in')
1101
1102 $.support.transition && this.$tip.hasClass('fade') ?
1103 $tip
1104 .one($.support.transition.end, complete)
1105 .emulateTransitionEnd(150) :
1106 complete()
1107
1108 this.$element.trigger('hidden.bs.' + this.type)
1109
1110 return this
1111 }
1112
1113 Tooltip.prototype.fixTitle = function () {
1114 var $e = this.$element
1115 if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') {
1116 $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
1117 }
1118 }
1119
1120 Tooltip.prototype.hasContent = function () {
1121 return this.getTitle()
1122 }
1123
1124 Tooltip.prototype.getPosition = function () {
1125 var el = this.$element[0]
1126 return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : {
1127 width: el.offsetWidth
1128 , height: el.offsetHeight
1129 }, this.$element.offset())
1130 }
1131
1132 Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
1133 return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } :
1134 placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :
1135 placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
1136 /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }
1137 }
1138
1139 Tooltip.prototype.getTitle = function () {
1140 var title
1141 var $e = this.$element
1142 var o = this.options
1143
1144 title = $e.attr('data-original-title')
1145 || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
1146
1147 return title
1148 }
1149
1150 Tooltip.prototype.tip = function () {
1151 return this.$tip = this.$tip || $(this.options.template)
1152 }
1153
1154 Tooltip.prototype.arrow = function () {
1155 return this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow')
1156 }
1157
1158 Tooltip.prototype.validate = function () {
1159 if (!this.$element[0].parentNode) {
1160 this.hide()
1161 this.$element = null
1162 this.options = null
1163 }
1164 }
1165
1166 Tooltip.prototype.enable = function () {
1167 this.enabled = true
1168 }
1169
1170 Tooltip.prototype.disable = function () {
1171 this.enabled = false
1172 }
1173
1174 Tooltip.prototype.toggleEnabled = function () {
1175 this.enabled = !this.enabled
1176 }
1177
1178 Tooltip.prototype.toggle = function (e) {
1179 var self = e ? $(e.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type) : this
1180 self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
1181 }
1182
1183 Tooltip.prototype.destroy = function () {
1184 this.hide().$element.off('.' + this.type).removeData('bs.' + this.type)
1185 }
1186
1187
1188 // TOOLTIP PLUGIN DEFINITION
1189 // =========================
1190
1191 var old = $.fn.tooltip
1192
1193 $.fn.tooltip = function (option) {
1194 return this.each(function () {
1195 var $this = $(this)
1196 var data = $this.data('bs.tooltip')
1197 var options = typeof option == 'object' && option
1198
1199 if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
1200 if (typeof option == 'string') data[option]()
1201 })
1202 }
1203
1204 $.fn.tooltip.Constructor = Tooltip
1205
1206
1207 // TOOLTIP NO CONFLICT
1208 // ===================
1209
1210 $.fn.tooltip.noConflict = function () {
1211 $.fn.tooltip = old
1212 return this
1213 }
1214
1215}(window.jQuery);
1216
1217/* ========================================================================
1218 * Bootstrap: popover.js v3.0.0
1219 * http://getbootstrap.com/javascript/#popovers
1220 * ========================================================================
1221 * Copyright 2013 Twitter, Inc.
1222 *
1223 * Licensed under the Apache License, Version 2.0 (the "License");
1224 * you may not use this file except in compliance with the License.
1225 * You may obtain a copy of the License at
1226 *
1227 * http://www.apache.org/licenses/LICENSE-2.0
1228 *
1229 * Unless required by applicable law or agreed to in writing, software
1230 * distributed under the License is distributed on an "AS IS" BASIS,
1231 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1232 * See the License for the specific language governing permissions and
1233 * limitations under the License.
1234 * ======================================================================== */
1235
1236
1237+function ($) { "use strict";
1238
1239 // POPOVER PUBLIC CLASS DEFINITION
1240 // ===============================
1241
1242 var Popover = function (element, options) {
1243 this.init('popover', element, options)
1244 }
1245
1246 if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')
1247
1248 Popover.DEFAULTS = $.extend({} , $.fn.tooltip.Constructor.DEFAULTS, {
1249 placement: 'right'
1250 , trigger: 'click'
1251 , content: ''
1252 , template: '<div class="popover"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
1253 })
1254
1255
1256 // NOTE: POPOVER EXTENDS tooltip.js
1257 // ================================
1258
1259 Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)
1260
1261 Popover.prototype.constructor = Popover
1262
1263 Popover.prototype.getDefaults = function () {
1264 return Popover.DEFAULTS
1265 }
1266
1267 Popover.prototype.setContent = function () {
1268 var $tip = this.tip()
1269 var title = this.getTitle()
1270 var content = this.getContent()
1271
1272 $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
1273 $tip.find('.popover-content')[this.options.html ? 'html' : 'text'](content)
1274
1275 $tip.removeClass('fade top bottom left right in')
1276
1277 // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do
1278 // this manually by checking the contents.
1279 if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()
1280 }
1281
1282 Popover.prototype.hasContent = function () {
1283 return this.getTitle() || this.getContent()
1284 }
1285
1286 Popover.prototype.getContent = function () {
1287 var $e = this.$element
1288 var o = this.options
1289
1290 return $e.attr('data-content')
1291 || (typeof o.content == 'function' ?
1292 o.content.call($e[0]) :
1293 o.content)
1294 }
1295
1296 Popover.prototype.arrow = function () {
1297 return this.$arrow = this.$arrow || this.tip().find('.arrow')
1298 }
1299
1300 Popover.prototype.tip = function () {
1301 if (!this.$tip) this.$tip = $(this.options.template)
1302 return this.$tip
1303 }
1304
1305
1306 // POPOVER PLUGIN DEFINITION
1307 // =========================
1308
1309 var old = $.fn.popover
1310
1311 $.fn.popover = function (option) {
1312 return this.each(function () {
1313 var $this = $(this)
1314 var data = $this.data('bs.popover')
1315 var options = typeof option == 'object' && option
1316
1317 if (!data) $this.data('bs.popover', (data = new Popover(this, options)))
1318 if (typeof option == 'string') data[option]()
1319 })
1320 }
1321
1322 $.fn.popover.Constructor = Popover
1323
1324
1325 // POPOVER NO CONFLICT
1326 // ===================
1327
1328 $.fn.popover.noConflict = function () {
1329 $.fn.popover = old
1330 return this
1331 }
1332
1333}(window.jQuery);
1334
1335/* ========================================================================
1336 * Bootstrap: tab.js v3.0.0
1337 * http://getbootstrap.com/javascript/#tabs
1338 * ========================================================================
1339 * Copyright 2013 Twitter, Inc.
1340 *
1341 * Licensed under the Apache License, Version 2.0 (the "License");
1342 * you may not use this file except in compliance with the License.
1343 * You may obtain a copy of the License at
1344 *
1345 * http://www.apache.org/licenses/LICENSE-2.0
1346 *
1347 * Unless required by applicable law or agreed to in writing, software
1348 * distributed under the License is distributed on an "AS IS" BASIS,
1349 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1350 * See the License for the specific language governing permissions and
1351 * limitations under the License.
1352 * ======================================================================== */
1353
1354
1355+function ($) { "use strict";
1356
1357 // TAB CLASS DEFINITION
1358 // ====================
1359
1360 var Tab = function (element) {
1361 this.element = $(element)
1362 }
1363
1364 Tab.prototype.show = function () {
1365 var $this = this.element
1366 var $ul = $this.closest('ul:not(.dropdown-menu)')
1367 var selector = $this.data('target')
1368
1369 if (!selector) {
1370 selector = $this.attr('href')
1371 selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
1372 }
1373
1374 if ($this.parent('li').hasClass('active')) return
1375
1376 var previous = $ul.find('.active:last a')[0]
1377 var e = $.Event('show.bs.tab', {
1378 relatedTarget: previous
1379 })
1380
1381 $this.trigger(e)
1382
1383 if (e.isDefaultPrevented()) return
1384
1385 var $target = $(selector)
1386
1387 this.activate($this.parent('li'), $ul)
1388 this.activate($target, $target.parent(), function () {
1389 $this.trigger({
1390 type: 'shown.bs.tab'
1391 , relatedTarget: previous
1392 })
1393 })
1394 }
1395
1396 Tab.prototype.activate = function (element, container, callback) {
1397 var $active = container.find('> .active')
1398 var transition = callback
1399 && $.support.transition
1400 && $active.hasClass('fade')
1401
1402 function next() {
1403 $active
1404 .removeClass('active')
1405 .find('> .dropdown-menu > .active')
1406 .removeClass('active')
1407
1408 element.addClass('active')
1409
1410 if (transition) {
1411 element[0].offsetWidth // reflow for transition
1412 element.addClass('in')
1413 } else {
1414 element.removeClass('fade')
1415 }
1416
1417 if (element.parent('.dropdown-menu')) {
1418 element.closest('li.dropdown').addClass('active')
1419 }
1420
1421 callback && callback()
1422 }
1423
1424 transition ?
1425 $active
1426 .one($.support.transition.end, next)
1427 .emulateTransitionEnd(150) :
1428 next()
1429
1430 $active.removeClass('in')
1431 }
1432
1433
1434 // TAB PLUGIN DEFINITION
1435 // =====================
1436
1437 var old = $.fn.tab
1438
1439 $.fn.tab = function ( option ) {
1440 return this.each(function () {
1441 var $this = $(this)
1442 var data = $this.data('bs.tab')
1443
1444 if (!data) $this.data('bs.tab', (data = new Tab(this)))
1445 if (typeof option == 'string') data[option]()
1446 })
1447 }
1448
1449 $.fn.tab.Constructor = Tab
1450
1451
1452 // TAB NO CONFLICT
1453 // ===============
1454
1455 $.fn.tab.noConflict = function () {
1456 $.fn.tab = old
1457 return this
1458 }
1459
1460
1461 // TAB DATA-API
1462 // ============
1463
1464 $(document).on('click.bs.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) {
1465 e.preventDefault()
1466 $(this).tab('show')
1467 })
1468
1469}(window.jQuery);
1470
1471/* ========================================================================
1472 * Bootstrap: affix.js v3.0.0
1473 * http://getbootstrap.com/javascript/#affix
1474 * ========================================================================
1475 * Copyright 2013 Twitter, Inc.
1476 *
1477 * Licensed under the Apache License, Version 2.0 (the "License");
1478 * you may not use this file except in compliance with the License.
1479 * You may obtain a copy of the License at
1480 *
1481 * http://www.apache.org/licenses/LICENSE-2.0
1482 *
1483 * Unless required by applicable law or agreed to in writing, software
1484 * distributed under the License is distributed on an "AS IS" BASIS,
1485 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1486 * See the License for the specific language governing permissions and
1487 * limitations under the License.
1488 * ======================================================================== */
1489
1490
1491+function ($) { "use strict";
1492
1493 // AFFIX CLASS DEFINITION
1494 // ======================
1495
1496 var Affix = function (element, options) {
1497 this.options = $.extend({}, Affix.DEFAULTS, options)
1498 this.$window = $(window)
1499 .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))
1500 .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this))
1501
1502 this.$element = $(element)
1503 this.affixed =
1504 this.unpin = null
1505
1506 this.checkPosition()
1507 }
1508
1509 Affix.RESET = 'affix affix-top affix-bottom'
1510
1511 Affix.DEFAULTS = {
1512 offset: 0
1513 }
1514
1515 Affix.prototype.checkPositionWithEventLoop = function () {
1516 setTimeout($.proxy(this.checkPosition, this), 1)
1517 }
1518
1519 Affix.prototype.checkPosition = function () {
1520 if (!this.$element.is(':visible')) return
1521
1522 var scrollHeight = $(document).height()
1523 var scrollTop = this.$window.scrollTop()
1524 var position = this.$element.offset()
1525 var offset = this.options.offset
1526 var offsetTop = offset.top
1527 var offsetBottom = offset.bottom
1528
1529 if (typeof offset != 'object') offsetBottom = offsetTop = offset
1530 if (typeof offsetTop == 'function') offsetTop = offset.top()
1531 if (typeof offsetBottom == 'function') offsetBottom = offset.bottom()
1532
1533 var affix = this.unpin != null && (scrollTop + this.unpin <= position.top) ? false :
1534 offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ? 'bottom' :
1535 offsetTop != null && (scrollTop <= offsetTop) ? 'top' : false
1536
1537 if (this.affixed === affix) return
1538 if (this.unpin) this.$element.css('top', '')
1539
1540 this.affixed = affix
1541 this.unpin = affix == 'bottom' ? position.top - scrollTop : null
1542
1543 this.$element.removeClass(Affix.RESET).addClass('affix' + (affix ? '-' + affix : ''))
1544
1545 if (affix == 'bottom') {
1546 this.$element.offset({ top: document.body.offsetHeight - offsetBottom - this.$element.height() })
1547 }
1548 }
1549
1550
1551 // AFFIX PLUGIN DEFINITION
1552 // =======================
1553
1554 var old = $.fn.affix
1555
1556 $.fn.affix = function (option) {
1557 return this.each(function () {
1558 var $this = $(this)
1559 var data = $this.data('bs.affix')
1560 var options = typeof option == 'object' && option
1561
1562 if (!data) $this.data('bs.affix', (data = new Affix(this, options)))
1563 if (typeof option == 'string') data[option]()
1564 })
1565 }
1566
1567 $.fn.affix.Constructor = Affix
1568
1569
1570 // AFFIX NO CONFLICT
1571 // =================
1572
1573 $.fn.affix.noConflict = function () {
1574 $.fn.affix = old
1575 return this
1576 }
1577
1578
1579 // AFFIX DATA-API
1580 // ==============
1581
1582 $(window).on('load', function () {
1583 $('[data-spy="affix"]').each(function () {
1584 var $spy = $(this)
1585 var data = $spy.data()
1586
1587 data.offset = data.offset || {}
1588
1589 if (data.offsetBottom) data.offset.bottom = data.offsetBottom
1590 if (data.offsetTop) data.offset.top = data.offsetTop
1591
1592 $spy.affix(data)
1593 })
1594 })
1595
1596}(window.jQuery);
1597
1598/* ========================================================================
1599 * Bootstrap: collapse.js v3.0.0
1600 * http://getbootstrap.com/javascript/#collapse
1601 * ========================================================================
1602 * Copyright 2013 Twitter, Inc.
1603 *
1604 * Licensed under the Apache License, Version 2.0 (the "License");
1605 * you may not use this file except in compliance with the License.
1606 * You may obtain a copy of the License at
1607 *
1608 * http://www.apache.org/licenses/LICENSE-2.0
1609 *
1610 * Unless required by applicable law or agreed to in writing, software
1611 * distributed under the License is distributed on an "AS IS" BASIS,
1612 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1613 * See the License for the specific language governing permissions and
1614 * limitations under the License.
1615 * ======================================================================== */
1616
1617
1618+function ($) { "use strict";
1619
1620 // COLLAPSE PUBLIC CLASS DEFINITION
1621 // ================================
1622
1623 var Collapse = function (element, options) {
1624 this.$element = $(element)
1625 this.options = $.extend({}, Collapse.DEFAULTS, options)
1626 this.transitioning = null
1627
1628 if (this.options.parent) this.$parent = $(this.options.parent)
1629 if (this.options.toggle) this.toggle()
1630 }
1631
1632 Collapse.DEFAULTS = {
1633 toggle: true
1634 }
1635
1636 Collapse.prototype.dimension = function () {
1637 var hasWidth = this.$element.hasClass('width')
1638 return hasWidth ? 'width' : 'height'
1639 }
1640
1641 Collapse.prototype.show = function () {
1642 if (this.transitioning || this.$element.hasClass('in')) return
1643
1644 var startEvent = $.Event('show.bs.collapse')
1645 this.$element.trigger(startEvent)
1646 if (startEvent.isDefaultPrevented()) return
1647
1648 var actives = this.$parent && this.$parent.find('> .panel > .in')
1649
1650 if (actives && actives.length) {
1651 var hasData = actives.data('bs.collapse')
1652 if (hasData && hasData.transitioning) return
1653 actives.collapse('hide')
1654 hasData || actives.data('bs.collapse', null)
1655 }
1656
1657 var dimension = this.dimension()
1658
1659 this.$element
1660 .removeClass('collapse')
1661 .addClass('collapsing')
1662 [dimension](0)
1663
1664 this.transitioning = 1
1665
1666 var complete = function () {
1667 this.$element
1668 .removeClass('collapsing')
1669 .addClass('in')
1670 [dimension]('auto')
1671 this.transitioning = 0
1672 this.$element.trigger('shown.bs.collapse')
1673 }
1674
1675 if (!$.support.transition) return complete.call(this)
1676
1677 var scrollSize = $.camelCase(['scroll', dimension].join('-'))
1678
1679 this.$element
1680 .one($.support.transition.end, $.proxy(complete, this))
1681 .emulateTransitionEnd(350)
1682 [dimension](this.$element[0][scrollSize])
1683 }
1684
1685 Collapse.prototype.hide = function () {
1686 if (this.transitioning || !this.$element.hasClass('in')) return
1687
1688 var startEvent = $.Event('hide.bs.collapse')
1689 this.$element.trigger(startEvent)
1690 if (startEvent.isDefaultPrevented()) return
1691
1692 var dimension = this.dimension()
1693
1694 this.$element
1695 [dimension](this.$element[dimension]())
1696 [0].offsetHeight
1697
1698 this.$element
1699 .addClass('collapsing')
1700 .removeClass('collapse')
1701 .removeClass('in')
1702
1703 this.transitioning = 1
1704
1705 var complete = function () {
1706 this.transitioning = 0
1707 this.$element
1708 .trigger('hidden.bs.collapse')
1709 .removeClass('collapsing')
1710 .addClass('collapse')
1711 }
1712
1713 if (!$.support.transition) return complete.call(this)
1714
1715 this.$element
1716 [dimension](0)
1717 .one($.support.transition.end, $.proxy(complete, this))
1718 .emulateTransitionEnd(350)
1719 }
1720
1721 Collapse.prototype.toggle = function () {
1722 this[this.$element.hasClass('in') ? 'hide' : 'show']()
1723 }
1724
1725
1726 // COLLAPSE PLUGIN DEFINITION
1727 // ==========================
1728
1729 var old = $.fn.collapse
1730
1731 $.fn.collapse = function (option) {
1732 return this.each(function () {
1733 var $this = $(this)
1734 var data = $this.data('bs.collapse')
1735 var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)
1736
1737 if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
1738 if (typeof option == 'string') data[option]()
1739 })
1740 }
1741
1742 $.fn.collapse.Constructor = Collapse
1743
1744
1745 // COLLAPSE NO CONFLICT
1746 // ====================
1747
1748 $.fn.collapse.noConflict = function () {
1749 $.fn.collapse = old
1750 return this
1751 }
1752
1753
1754 // COLLAPSE DATA-API
1755 // =================
1756
1757 $(document).on('click.bs.collapse.data-api', '[data-toggle=collapse]', function (e) {
1758 var $this = $(this), href
1759 var target = $this.attr('data-target')
1760 || e.preventDefault()
1761 || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7
1762 var $target = $(target)
1763 var data = $target.data('bs.collapse')
1764 var option = data ? 'toggle' : $this.data()
1765 var parent = $this.attr('data-parent')
1766 var $parent = parent && $(parent)
1767
1768 if (!data || !data.transitioning) {
1769 if ($parent) $parent.find('[data-toggle=collapse][data-parent="' + parent + '"]').not($this).addClass('collapsed')
1770 $this[$target.hasClass('in') ? 'addClass' : 'removeClass']('collapsed')
1771 }
1772
1773 $target.collapse(option)
1774 })
1775
1776}(window.jQuery);
1777
1778/* ========================================================================
1779 * Bootstrap: scrollspy.js v3.0.0
1780 * http://getbootstrap.com/javascript/#scrollspy
1781 * ========================================================================
1782 * Copyright 2013 Twitter, Inc.
1783 *
1784 * Licensed under the Apache License, Version 2.0 (the "License");
1785 * you may not use this file except in compliance with the License.
1786 * You may obtain a copy of the License at
1787 *
1788 * http://www.apache.org/licenses/LICENSE-2.0
1789 *
1790 * Unless required by applicable law or agreed to in writing, software
1791 * distributed under the License is distributed on an "AS IS" BASIS,
1792 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1793 * See the License for the specific language governing permissions and
1794 * limitations under the License.
1795 * ======================================================================== */
1796
1797
1798+function ($) { "use strict";
1799
1800 // SCROLLSPY CLASS DEFINITION
1801 // ==========================
1802
1803 function ScrollSpy(element, options) {
1804 var href
1805 var process = $.proxy(this.process, this)
1806
1807 this.$element = $(element).is('body') ? $(window) : $(element)
1808 this.$body = $('body')
1809 this.$scrollElement = this.$element.on('scroll.bs.scroll-spy.data-api', process)
1810 this.options = $.extend({}, ScrollSpy.DEFAULTS, options)
1811 this.selector = (this.options.target
1812 || ((href = $(element).attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
1813 || '') + ' .nav li > a'
1814 this.offsets = $([])
1815 this.targets = $([])
1816 this.activeTarget = null
1817
1818 this.refresh()
1819 this.process()
1820 }
1821
1822 ScrollSpy.DEFAULTS = {
1823 offset: 10
1824 }
1825
1826 ScrollSpy.prototype.refresh = function () {
1827 var offsetMethod = this.$element[0] == window ? 'offset' : 'position'
1828
1829 this.offsets = $([])
1830 this.targets = $([])
1831
1832 var self = this
1833 var $targets = this.$body
1834 .find(this.selector)
1835 .map(function () {
1836 var $el = $(this)
1837 var href = $el.data('target') || $el.attr('href')
1838 var $href = /^#\w/.test(href) && $(href)
1839
1840 return ($href
1841 && $href.length
1842 && [[ $href[offsetMethod]().top + (!$.isWindow(self.$scrollElement.get(0)) && self.$scrollElement.scrollTop()), href ]]) || null
1843 })
1844 .sort(function (a, b) { return a[0] - b[0] })
1845 .each(function () {
1846 self.offsets.push(this[0])
1847 self.targets.push(this[1])
1848 })
1849 }
1850
1851 ScrollSpy.prototype.process = function () {
1852 var scrollTop = this.$scrollElement.scrollTop() + this.options.offset
1853 var scrollHeight = this.$scrollElement[0].scrollHeight || this.$body[0].scrollHeight
1854 var maxScroll = scrollHeight - this.$scrollElement.height()
1855 var offsets = this.offsets
1856 var targets = this.targets
1857 var activeTarget = this.activeTarget
1858 var i
1859
1860 if (scrollTop >= maxScroll) {
1861 return activeTarget != (i = targets.last()[0]) && this.activate(i)
1862 }
1863
1864 for (i = offsets.length; i--;) {
1865 activeTarget != targets[i]
1866 && scrollTop >= offsets[i]
1867 && (!offsets[i + 1] || scrollTop <= offsets[i + 1])
1868 && this.activate( targets[i] )
1869 }
1870 }
1871
1872 ScrollSpy.prototype.activate = function (target) {
1873 this.activeTarget = target
1874
1875 $(this.selector)
1876 .parents('.active')
1877 .removeClass('active')
1878
1879 var selector = this.selector
1880 + '[data-target="' + target + '"],'
1881 + this.selector + '[href="' + target + '"]'
1882
1883 var active = $(selector)
1884 .parents('li')
1885 .addClass('active')
1886
1887 if (active.parent('.dropdown-menu').length) {
1888 active = active
1889 .closest('li.dropdown')
1890 .addClass('active')
1891 }
1892
1893 active.trigger('activate')
1894 }
1895
1896
1897 // SCROLLSPY PLUGIN DEFINITION
1898 // ===========================
1899
1900 var old = $.fn.scrollspy
1901
1902 $.fn.scrollspy = function (option) {
1903 return this.each(function () {
1904 var $this = $(this)
1905 var data = $this.data('bs.scrollspy')
1906 var options = typeof option == 'object' && option
1907
1908 if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))
1909 if (typeof option == 'string') data[option]()
1910 })
1911 }
1912
1913 $.fn.scrollspy.Constructor = ScrollSpy
1914
1915
1916 // SCROLLSPY NO CONFLICT
1917 // =====================
1918
1919 $.fn.scrollspy.noConflict = function () {
1920 $.fn.scrollspy = old
1921 return this
1922 }
1923
1924
1925 // SCROLLSPY DATA-API
1926 // ==================
1927
1928 $(window).on('load', function () {
1929 $('[data-spy="scroll"]').each(function () {
1930 var $spy = $(this)
1931 $spy.scrollspy($spy.data())
1932 })
1933 })
1934
1935}(window.jQuery);
1936
1937/* ========================================================================
1938 * Bootstrap: transition.js v3.0.0
1939 * http://getbootstrap.com/javascript/#transitions
1940 * ========================================================================
1941 * Copyright 2013 Twitter, Inc.
1942 *
1943 * Licensed under the Apache License, Version 2.0 (the "License");
1944 * you may not use this file except in compliance with the License.
1945 * You may obtain a copy of the License at
1946 *
1947 * http://www.apache.org/licenses/LICENSE-2.0
1948 *
1949 * Unless required by applicable law or agreed to in writing, software
1950 * distributed under the License is distributed on an "AS IS" BASIS,
1951 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1952 * See the License for the specific language governing permissions and
1953 * limitations under the License.
1954 * ======================================================================== */
1955
1956
1957+function ($) { "use strict";
1958
1959 // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
1960 // ============================================================
1961
1962 function transitionEnd() {
1963 var el = document.createElement('bootstrap')
1964
1965 var transEndEventNames = {
1966 'WebkitTransition' : 'webkitTransitionEnd'
1967 , 'MozTransition' : 'transitionend'
1968 , 'OTransition' : 'oTransitionEnd otransitionend'
1969 , 'transition' : 'transitionend'
1970 }
1971
1972 for (var name in transEndEventNames) {
1973 if (el.style[name] !== undefined) {
1974 return { end: transEndEventNames[name] }
1975 }
1976 }
1977 }
1978
1979 // http://blog.alexmaccaw.com/css-transitions
1980 $.fn.emulateTransitionEnd = function (duration) {
1981 var called = false, $el = this
1982 $(this).one($.support.transition.end, function () { called = true })
1983 var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
1984 setTimeout(callback, duration)
1985 return this
1986 }
1987
1988 $(function () {
1989 $.support.transition = transitionEnd()
1990 })
1991
1992}(window.jQuery);
01993
=== removed file 'addons/web_graph/static/lib/dropdown.js'
--- addons/web_graph/static/lib/dropdown.js 2012-05-07 13:38:21 +0000
+++ addons/web_graph/static/lib/dropdown.js 1970-01-01 00:00:00 +0000
@@ -1,92 +0,0 @@
1/* ============================================================
2 * bootstrap-dropdown.js v2.0.2
3 * http://twitter.github.com/bootstrap/javascript.html#dropdowns
4 * ============================================================
5 * Copyright 2012 Twitter, Inc.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============================================================ */
19
20
21!function( $ ){
22
23 "use strict"
24
25 /* DROPDOWN CLASS DEFINITION
26 * ========================= */
27
28 var toggle = '[data-toggle="dropdown"]'
29 , Dropdown = function ( element ) {
30 var $el = $(element).on('click.dropdown.data-api', this.toggle)
31 $('html').on('click.dropdown.data-api', function () {
32 $el.parent().removeClass('open')
33 })
34 }
35
36 Dropdown.prototype = {
37
38 constructor: Dropdown
39
40 , toggle: function ( e ) {
41 var $this = $(this)
42 , selector = $this.attr('data-target')
43 , $parent
44 , isActive
45
46 if (!selector) {
47 selector = $this.attr('href')
48 selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
49 }
50
51 $parent = $(selector)
52 $parent.length || ($parent = $this.parent())
53
54 isActive = $parent.hasClass('open')
55
56 clearMenus()
57 !isActive && $parent.toggleClass('open')
58
59 return false
60 }
61
62 }
63
64 function clearMenus() {
65 $(toggle).parent().removeClass('open')
66 }
67
68
69 /* DROPDOWN PLUGIN DEFINITION
70 * ========================== */
71
72 $.fn.dropdown = function ( option ) {
73 return this.each(function () {
74 var $this = $(this)
75 , data = $this.data('dropdown')
76 if (!data) $this.data('dropdown', (data = new Dropdown(this)))
77 if (typeof option == 'string') data[option].call($this)
78 })
79 }
80
81 $.fn.dropdown.Constructor = Dropdown
82
83
84 /* APPLY TO STANDARD DROPDOWN ELEMENTS
85 * =================================== */
86
87 $(function () {
88 $('html').on('click.dropdown.data-api', clearMenus)
89 $('body').on('click.dropdown.data-api', toggle, Dropdown.prototype.toggle)
90 })
91
92}( window.jQuery );
93\ No newline at end of file0\ No newline at end of file
941
=== removed directory 'addons/web_graph/static/lib/flotr2'
=== removed file 'addons/web_graph/static/lib/flotr2/LICENSE'
--- addons/web_graph/static/lib/flotr2/LICENSE 2012-05-07 08:19:08 +0000
+++ addons/web_graph/static/lib/flotr2/LICENSE 1970-01-01 00:00:00 +0000
@@ -1,19 +0,0 @@
1Copyright (c) 2012 Carl Sutherland
2
3Permission is hereby granted, free of charge, to any person obtaining a copy
4of this software and associated documentation files (the "Software"), to deal
5in the Software without restriction, including without limitation the rights
6to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7copies of the Software, and to permit persons to whom the Software is
8furnished to do so, subject to the following conditions:
9
10The above copyright notice and this permission notice shall be included in
11all copies or substantial portions of the Software.
12
13THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19THE SOFTWARE.
200
=== removed file 'addons/web_graph/static/lib/flotr2/Makefile'
--- addons/web_graph/static/lib/flotr2/Makefile 2012-05-07 10:34:07 +0000
+++ addons/web_graph/static/lib/flotr2/Makefile 1970-01-01 00:00:00 +0000
@@ -1,40 +0,0 @@
1all: test flotr2
2
3test:
4 cd spec; jasmine-headless-webkit -j jasmine.yml -c
5
6libraries:
7 smoosh make/lib.json
8 cat ./build/bean.js > build/lib.js
9 cat ./build/underscore.js >> build/lib.js
10 cat ./build/bean.min.js > build/lib.min.js
11 echo ";" >> build/lib.min.js
12 cat ./build/underscore.min.js >> build/lib.min.js
13 echo ";" >> build/lib.min.js
14
15ie:
16 smoosh make/ie.json
17
18flotr2: libraries ie
19 smoosh make/flotr2.json
20 cat build/lib.js build/flotr2.js > flotr2.js
21 cat build/lib.min.js > flotr2.min.js
22 cat build/flotr2.min.js >> flotr2.min.js
23 echo ';' >> flotr2.min.js
24 cp build/ie.min.js flotr2.ie.min.js
25
26flotr2-basic: libraries ie
27 smoosh make/basic.json
28 cat build/lib.min.js > flotr2-basic.min.js
29 cat build/flotr2-basic.min.js >> flotr2-basic.min.js
30
31flotr2-standalone: ie
32 smoosh make/flotr2.json
33 cat build/flotr2.js > flotr2.js
34 cp build/ie.min.js flotr2.ie.min.js
35
36flotr-examples:
37 smoosh make/examples.json
38 cp build/examples.min.js flotr2.examples.min.js
39 cp build/examples-types.js flotr2.examples.types.js
40
410
=== removed file 'addons/web_graph/static/lib/flotr2/README.md'
--- addons/web_graph/static/lib/flotr2/README.md 2012-05-07 08:19:08 +0000
+++ addons/web_graph/static/lib/flotr2/README.md 1970-01-01 00:00:00 +0000
@@ -1,89 +0,0 @@
1Flotr2
2======
3
4The Canvas graphing library.
5
6![Google Groups](http://groups.google.com/intl/en/images/logos/groups_logo_sm.gif)
7
8http://groups.google.com/group/flotr2/
9
10Please fork http://jsfiddle.net/cesutherland/ZFBj5/ with your question or bug reproduction case.
11
12
13API
14---
15
16The API consists of a primary draw method which accepts a configuration object, helper methods, and several microlibs.
17
18### Example
19
20```javascript
21 var
22 // Container div:
23 container = document.getElementById("flotr-example-graph"),
24 // First data series:
25 d1 = [[0, 3], [4, 8], [8, 5], [9, 13]],
26 // Second data series:
27 d2 = [],
28 // A couple flotr configuration options:
29 options = {
30 xaxis: {
31 minorTickFreq: 4
32 },
33 grid: {
34 minorVerticalLines: true
35 }
36 },
37 i, graph;
38
39 // Generated second data set:
40 for (i = 0; i < 14; i += 0.5) {
41 d2.push([i, Math.sin(i)]);
42 }
43
44 // Draw the graph:
45 graph = Flotr.draw(
46 container, // Container element
47 [ d1, d2 ], // Array of data series
48 options // Configuration options
49 );
50```
51
52### Microlibs
53
54* [underscore.js](http://documentcloud.github.com/underscore/)
55* [bean.js](https://github.com/fat/bean)
56
57Extending
58---------
59
60Flotr may be extended by adding new plugins and graph types.
61
62### Graph Types
63
64Graph types define how a particular chart is rendered. Examples include line, bar, pie.
65
66Existing graph types are found in `js/types/`.
67
68### Plugins
69
70Plugins extend the core of flotr with new functionality. They can add interactions, new decorations, etc. Examples
71include titles, labels and selection.
72
73The plugins included are found in `js/plugins/`.
74
75Development
76-----------
77
78This project uses [smoosh](https://github.com/fat/smoosh) to build and [jasmine](http://pivotal.github.com/jasmine/)
79with [js-imagediff](https://github.com/HumbleSoftware/js-imagediff) to test. Tests may be executed by
80[jasmine-headless-webkit](http://johnbintz.github.com/jasmine-headless-webkit/) with
81`cd spec; jasmine-headless-webkit -j jasmine.yml -c` or by a browser by navigating to
82`flotr2/spec/SpecRunner.html`.
83
84Shoutouts
85---------
86
87Thanks to Bas Wenneker, Fabien Ménager and others for all the work on the original Flotr.
88Thanks to Jochen Berger and Jordan Santell for their contributions to Flotr2.
89
900
=== removed directory 'addons/web_graph/static/lib/flotr2/dev'
=== removed file 'addons/web_graph/static/lib/flotr2/dev/notes.txt'
--- addons/web_graph/static/lib/flotr2/dev/notes.txt 2012-05-07 08:19:08 +0000
+++ addons/web_graph/static/lib/flotr2/dev/notes.txt 1970-01-01 00:00:00 +0000
@@ -1,86 +0,0 @@
1Flotr 2 Architecture Notes
2
3
4Global:
5======
6
7Flotr.js -
8 versioning information
9 browser detection
10 extension (plugins, graph types)
11 draw
12 clone / merge
13 tick size
14 tick formatter
15 engineering notation
16 magnitude
17 rad, pixel, floor
18 drawText
19 measureText
20 getBestTextAlign
21 align map
22 compatibility
23
24
25Graph Architecture:
26===================
27
28Axis -
29 all series
30 orientation
31 ticks (major, minor)
32 scale (d2p, p2d, logarithmic)
33 notion of stacks
34
35Series -
36 per 'data'
37 notion of range (x, y, min, max)
38
39Graph -
40 DOM constructon
41 event attachment
42 options initialization
43 data range calculations
44 canvas spacing calculations
45 event normalization
46 draw methods
47 DOM cleanup
48 event cleanup
49
50
51Utilities:
52==========
53
54Color
55 build colors
56 parse textual color data
57 convert colors
58 clone colors
59
60Text
61 calculate text size
62 canvas size
63 html size
64
65Date
66 formatting
67 constants
68
69
70Spacing Calculation
71===================
72
73Flotr
74 calculate data
75 calculate margins
76
77Chart
78 calculate Data Ranges - Explicit or auto data minimum, maximums
79 calculate Data Range Extensions - By chart type, extend data range with needs of chart type (ie. stacked bars, stacked lines)
80 add Chart Padding - By chart type
81
82Text
83 use explicit margins
84 calculate label margins
85 calculate title margins
86
870
=== removed file 'addons/web_graph/static/lib/flotr2/flotr2.examples.min.js'
--- addons/web_graph/static/lib/flotr2/flotr2.examples.min.js 2012-05-07 08:19:08 +0000
+++ addons/web_graph/static/lib/flotr2/flotr2.examples.min.js 1970-01-01 00:00:00 +0000
@@ -1,2 +0,0 @@
1
2(function(){var a=Flotr.EventAdapter,b=Flotr._,c="click",d="example",e="mouseenter",f="mouseleave",g=".",h="flotr-examples",i="flotr-examples-container",j="flotr-examples-reset",k="flotr-examples-thumbs",l="flotr-examples-thumb",m="flotr-examples-collapsed",n="flotr-examples-highlight",o="flotr-examples-large",p="flotr-examples-medium",q="flotr-examples-small",r="flotr-examples-mobile",s='<div class="'+l+'"></div>',t='<div class="'+h+'">'+'<div class="'+j+'">View All</div>'+'<div class="'+k+'"></div>'+'<div class="'+i+'"></div>'+"</div>";Examples=function(a){if(b.isUndefined(Flotr.ExampleList))throw"Flotr.ExampleList not defined.";this.options=a,this.list=Flotr.ExampleList,this.current=null,this.single=!1,this._initNodes(),this._example=new Flotr.Examples.Example({node:this._exampleNode}),this._initExamples()},Examples.prototype={examples:function(){function f(b){var c=$(b.currentTarget),e=c.data("example"),f=b.data.orientation;f^c.hasClass(n)&&(c.toggleClass(n).css(a),d._example.executeCallback(e,c))}var a={cursor:"pointer"},b=this._thumbsNode,c=this.list.get(),d=this,e=["basic","basic-axis","basic-bars","basic-bars-horizontal","basic-bar-stacked","basic-stacked-horizontal","basic-pie","basic-radar","basic-bubble","basic-candle","basic-legend","mouse-tracking","mouse-zoom","mouse-drag","basic-time","negative-values","click-example","download-image","download-data","advanced-titles","color-gradients","basic-timeline","advanced-markers"];(function h(){var a=e.shift(),f=c[a];if(f.type==="profile"||f.type==="test")return;var g=$(s);g.data("example",f),b.append(g),d._example.executeCallback(f,g),g.click(function(){d._loadExample(f)}),e.length&&setTimeout(h,20)})(),b.delegate(g+l,"mouseenter",{orientation:!0},f),b.delegate(g+l,"mouseleave",{orientation:!1},f)},_loadExample:function(a){a&&(window.location.hash="!"+(this.single?"single/":"")+a.key,u||(this._thumbsNode.css({position:"absolute",height:"0px",overflow:"hidden",width:"0px"}),this._resetNode.css({top:"16px"})),this._examplesNode.addClass(m),this._exampleNode.show(),this._example.setExample(a),this._resize(),$(document).scrollTop(0))},_reset:function(){window.location.hash="",u||this._thumbsNode.css({position:"",height:"",overflow:"",width:""}),this._examplesNode.removeClass(m),this._thumbsNode.height(""),this._exampleNode.hide()},_initNodes:function(){var a=$(this.options.node),b=this,c=$(t);b._resetNode=c.find(g+j),b._exampleNode=c.find(g+i),b._thumbsNode=c.find(g+k),b._examplesNode=c,b._resetNode.click(function(){b._reset()}),a.append(c),this._initResizer()},_initResizer:function(){function e(){var b=c.height()-(a.options.thumbPadding||0),e=c.width(),f;e>1760?(f=o,a._thumbsNode.height(b)):e>1140?(f=p,a._thumbsNode.height(b)):(f=q,a._thumbsNode.height("")),d!==f&&(d&&a._examplesNode.removeClass(d),a._examplesNode.addClass(f),d=f)}var a=this,b=a._examplesNode,c=$(window),d;$(window).resize(e),e(),this._resize=e},_initExamples:function(){var a=window.location.hash,b,c;a?(a=a.substring(2),c=a.split("/"),c.length==1?(b=this.list.get(a),this.examples()):c[0]=="single"&&(this.single=!0,b=this.list.get(c[1])),this._loadExample(b)):this.examples()}};var u=function(){var a=!!(navigator.userAgent.match(/Android/i)||navigator.userAgent.match(/webOS/i)||navigator.userAgent.match(/iPhone/i)||navigator.userAgent.match(/iPod/i)),b=!!$.browser.mozilla;return!a||b}();Flotr.Examples=Examples})(),function(){var a=Flotr._,b=".",c="flotr-example",d="flotr-example-label",e="flotr-example-title",f="flotr-example-description",g="flotr-example-editor",h="flotr-example-graph",i='<div class="'+c+'">'+'<div class="'+d+" "+e+'"></div>'+'<div class="'+f+'"></div>'+'<div class="'+g+'"></div>'+"</div>",j=function(a){this.options=a,this.example=null,this._initNodes()};j.prototype={setExample:function(a){var b=this.getSource(a),c=this._editorNode;this.example=a,Math.seedrandom(a.key),this._exampleNode.css({display:"block"}),this._titleNode.html(a.name||""),this._markupNode.html(a.description||""),this._editor?this._editor.setExample(b):this._editor=new Flotr.Examples.Editor(c,{example:b,teardown:function(){Flotr.EventAdapter.stopObserving($(c).find(".render")[0]),$(c).find("canvas").each(function(a,b){Flotr.EventAdapter.stopObserving(b)})}})},getSource:function(a){var b=a.callback.toString();return navigator.userAgent.search(/firefox/i)!==-1&&(b=js_beautify(b)),b},executeCallback:function(b,c){a.isElement(c)||(c=c[0]);var d=b.args?[c].concat(b.args):[c];return Math.seedrandom(b.key),b.callback.apply(this,d)},_initNodes:function(){var a=this.options.node,c=$(i);this._titleNode=c.find(b+e),this._markupNode=c.find(b+f),this._editorNode=c.find(b+g),this._exampleNode=c,a.append(c)}},Flotr.Examples.Example=j}(),function(){function Editor(a,b){function o(){i.hide(),f&&f.call(),m.render({example:d,render:h})}function p(a,b,c){var d=!1,e='<span class="error">Error: </span>',f,g;e+='<span class="message">'+a+"</span>",typeof c!="undefined"&&(e+='<span class="position">',e+='Line <span class="line">'+c+"</span>",console.log(b),b&&(e+=" of ",b==window.location?(e+='<span class="url">script</span>',!d):e+='<span class="url">'+b+"</span>"),e+=".</span>"),i.show(),i.html(e)}var c=b.type||"javascript",d=b.example||"",e=b.noRun||!1,f=b.teardown||!1,g=$(T_CONTROLS),h=$(T_RENDER),i=$(T_ERRORS),j=$(T_SOURCE),k=$(T_EDITOR),l="editor-render-"+COUNT,m,h,n;m=new TYPES[c]({onerror:p});if(!m)throw"Invalid type: API not found for type `"+c+"`.";h.attr("id",l),i.hide(),k.append(h).append(g).append(j).addClass(c).addClass(e?"no-run":""),a=$(a),a.append(k),j.append(i),d=m.example({example:d,render:h}),n=CodeMirror(j[0],{value:d,readOnly:e,lineNumbers:!0,mode:m.codeMirrorType}),e||(g.delegate(".run","click",function(){d=n.getValue(),o()}),o()),window.onerror=function(a,b,c){return p(a,b,c),console.log(a),ONERROR&&$.isFunction(ONERROR)?ONERROR(a,b,c):!1},COUNT++,this.setExample=function(a){d=m.example({example:a,render:h}),n.setValue(d),n.refresh(),o()}}var ONERROR=window.onerror,COUNT=0,TYPES={},T_CONTROLS='<div class="controls"><button class="run btn large primary">Run</button></div>',T_EDITOR='<div class="editor"></div>',T_SOURCE='<div class="source"></div>',T_ERRORS='<div class="errors"></div>',T_RENDER='<div class="render"></div>',T_IFRAME="<iframe></iframe>";TYPES.javascript=function(b){this.onerror=b.onerror},TYPES.javascript.prototype={codeMirrorType:"javascript",example:function(a){var b=a.example,c=a.render,d=$(c).attr("id");return"("+b+')(document.getElementById("'+d+'"));'},render:function(o){eval(o.example)}},TYPES.html=function(b){this.onerror=b.onerror},TYPES.html.prototype={codeMirrorType:"htmlmixed",example:function(a){return $.trim(a.example)},render:function(a){var b=a.example,c=a.render,d=$(T_IFRAME),e=this,f,g;c.html(d),f=d[0].contentWindow,g=f.document,g.open(),f.onerror=d.onerror=function(){e.onerror.apply(null,arguments)},g.write(b),g.close()}},typeof Flotr.Examples=="undefined"&&(Flotr.Examples={}),Flotr.Examples.Editor=Editor}(),function(){var a=Flotr.DOM,b=Flotr.EventAdapter,c=Flotr._,d="click",e="example-profile",f="examples",g=function(a){if(c.isUndefined(Flotr.ExampleList))throw"Flotr.ExampleList not defined.";this.editMode="off",this.list=Flotr.ExampleList,this.current=null,this.single=!1,this.init()};g.prototype=c.extend({},Flotr.Examples.prototype,{examples:function(){var e=document.getElementById(f),g=a.node("<ul></ul>"),h;c.each(this.list.getType("profile"),function(e){h=a.node("<li>"+e.name+"</li>"),a.insert(g,h),b.observe(h,d,c.bind(function(){this.example(e)},this))},this),a.insert(e,g)},example:function(a){this._renderSource(a),this.profileStart(a),setTimeout(c.bind(function(){this._renderGraph(a),this.profileEnd()},this),50)},profileStart:function(a){var b=document.getElementById(e);this._startTime=new Date,b.innerHTML='<div>Profile started for "'+a.name+'"...</div>'},profileEnd:function(a){var b=document.getElementById(e);profileTime=new Date-this._startTime,this._startTime=null,b.innerHTML+="<div>Profile complete: "+profileTime+"ms<div>"}}),Flotr.Profile=g}()
3\ No newline at end of file0\ No newline at end of file
41
=== removed file 'addons/web_graph/static/lib/flotr2/flotr2.examples.types.js'
--- addons/web_graph/static/lib/flotr2/flotr2.examples.types.js 2012-05-07 08:19:08 +0000
+++ addons/web_graph/static/lib/flotr2/flotr2.examples.types.js 1970-01-01 00:00:00 +0000
@@ -1,1425 +0,0 @@
1(function () {
2
3var ExampleList = function () {
4
5 // Map of examples.
6 this.examples = {};
7
8};
9
10ExampleList.prototype = {
11
12 add : function (example) {
13 this.examples[example.key] = example;
14 },
15
16 get : function (key) {
17 return key ? (this.examples[key] || null) : this.examples;
18 },
19
20 getType : function (type) {
21 return Flotr._.select(this.examples, function (example) {
22 return (example.type === type);
23 });
24 }
25}
26
27Flotr.ExampleList = new ExampleList();
28
29})();
30
31(function () {
32
33Flotr.ExampleList.add({
34 key : 'basic',
35 name : 'Basic',
36 callback : basic
37});
38
39function basic (container) {
40
41 var
42 d1 = [[0, 3], [4, 8], [8, 5], [9, 13]], // First data series
43 d2 = [], // Second data series
44 i, graph;
45
46 // Generate first data set
47 for (i = 0; i < 14; i += 0.5) {
48 d2.push([i, Math.sin(i)]);
49 }
50
51 // Draw Graph
52 graph = Flotr.draw(container, [ d1, d2 ], {
53 xaxis: {
54 minorTickFreq: 4
55 },
56 grid: {
57 minorVerticalLines: true
58 }
59 });
60}
61
62})();
63
64(function () {
65
66Flotr.ExampleList.add({
67 key : 'basic-stacked',
68 name : 'Basic Stacked',
69 callback : basic_stacked,
70 type : 'test'
71});
72
73function basic_stacked (container) {
74
75 var
76 d1 = [[0, 3], [4, 8], [8, 2], [9, 3]], // First data series
77 d2 = [[0, 2], [4, 3], [8, 8], [9, 4]], // Second data series
78 i, graph;
79
80 // Draw Graph
81 graph = Flotr.draw(container, [ d1, d2 ], {
82 lines: {
83 show : true,
84 stacked: true
85 },
86 xaxis: {
87 minorTickFreq: 4
88 },
89 grid: {
90 minorVerticalLines: true
91 }
92 });
93}
94
95})();
96
97(function () {
98
99Flotr.ExampleList.add({
100 key : 'basic-stepped',
101 name : 'Basic Stepped',
102 callback : basic_stepped,
103 type : 'test'
104});
105
106function basic_stepped (container) {
107
108 var
109 d1 = [[0, 3], [4, 8], [8, 5], [9, 13]], // First data series
110 d2 = [], // Second data series
111 i, graph;
112
113 // Generate first data set
114 for (i = 0; i < 14; i += 0.5) {
115 d2.push([i, Math.sin(i)]);
116 }
117
118 // Draw Graph
119 graph = Flotr.draw(container, [ d1, d2 ], {
120 lines: {
121 steps : true,
122 show : true
123 },
124 xaxis: {
125 minorTickFreq: 4
126 },
127 yaxis: {
128 autoscale: true
129 },
130 grid: {
131 minorVerticalLines: true
132 },
133 mouse : {
134 track : true,
135 relative : true
136 }
137 });
138}
139
140})();
141
142(function () {
143
144Flotr.ExampleList.add({
145 key : 'basic-axis',
146 name : 'Basic Axis',
147 callback : basic_axis
148});
149
150function basic_axis (container) {
151
152 var
153 d1 = [],
154 d2 = [],
155 d3 = [],
156 d4 = [],
157 d5 = [], // Data
158 ticks = [[ 0, "Lower"], 10, 20, 30, [40, "Upper"]], // Ticks for the Y-Axis
159 graph;
160
161 for(var i = 0; i <= 10; i += 0.1){
162 d1.push([i, 4 + Math.pow(i,1.5)]);
163 d2.push([i, Math.pow(i,3)]);
164 d3.push([i, i*5+3*Math.sin(i*4)]);
165 d4.push([i, i]);
166 if( i.toFixed(1)%1 == 0 ){
167 d5.push([i, 2*i]);
168 }
169 }
170
171 d3[30][1] = null;
172 d3[31][1] = null;
173
174 function ticksFn (n) { return '('+n+')'; }
175
176 graph = Flotr.draw(container, [
177 { data : d1, label : 'y = 4 + x^(1.5)', lines : { fill : true } },
178 { data : d2, label : 'y = x^3'},
179 { data : d3, label : 'y = 5x + 3sin(4x)'},
180 { data : d4, label : 'y = x'},
181 { data : d5, label : 'y = 2x', lines : { show : true }, points : { show : true } }
182 ], {
183 xaxis : {
184 noTicks : 7, // Display 7 ticks.
185 tickFormatter : ticksFn, // Displays tick values between brackets.
186 min : 1, // Part of the series is not displayed.
187 max : 7.5 // Part of the series is not displayed.
188 },
189 yaxis : {
190 ticks : ticks, // Set Y-Axis ticks
191 max : 40 // Maximum value along Y-Axis
192 },
193 grid : {
194 verticalLines : false,
195 backgroundColor : {
196 colors : [[0,'#fff'], [1,'#ccc']],
197 start : 'top',
198 end : 'bottom'
199 }
200 },
201 legend : {
202 position : 'nw'
203 },
204 title : 'Basic Axis example',
205 subtitle : 'This is a subtitle'
206 });
207}
208
209})();
210
211(function () {
212
213Flotr.ExampleList.add({
214 key : 'basic-bars',
215 name : 'Basic Bars',
216 callback : basic_bars
217});
218
219Flotr.ExampleList.add({
220 key : 'basic-bars-horizontal',
221 name : 'Horizontal Bars',
222 args : [true],
223 callback : basic_bars,
224 tolerance : 5
225});
226
227function basic_bars (container, horizontal) {
228
229 var
230 horizontal = (horizontal ? true : false), // Show horizontal bars
231 d1 = [], // First data series
232 d2 = [], // Second data series
233 point, // Data point variable declaration
234 i;
235
236 for (i = 0; i < 4; i++) {
237
238 if (horizontal) {
239 point = [Math.ceil(Math.random()*10), i];
240 } else {
241 point = [i, Math.ceil(Math.random()*10)];
242 }
243
244 d1.push(point);
245
246 if (horizontal) {
247 point = [Math.ceil(Math.random()*10), i+0.5];
248 } else {
249 point = [i+0.5, Math.ceil(Math.random()*10)];
250 }
251
252 d2.push(point);
253 };
254
255 // Draw the graph
256 Flotr.draw(
257 container,
258 [d1, d2],
259 {
260 bars : {
261 show : true,
262 horizontal : horizontal,
263 shadowSize : 0,
264 barWidth : 0.5
265 },
266 mouse : {
267 track : true,
268 relative : true
269 },
270 yaxis : {
271 min : 0,
272 autoscaleMargin : 1
273 }
274 }
275 );
276}
277
278})();
279
280(function () {
281
282Flotr.ExampleList.add({
283 key : 'basic-bar-stacked',
284 name : 'Stacked Bars',
285 callback : bars_stacked
286});
287
288Flotr.ExampleList.add({
289 key : 'basic-stacked-horizontal',
290 name : 'Stacked Horizontal Bars',
291 args : [true],
292 callback : bars_stacked,
293 tolerance : 5
294});
295
296function bars_stacked (container, horizontal) {
297
298 var
299 d1 = [],
300 d2 = [],
301 d3 = [],
302 graph, i;
303
304 for (i = -10; i < 10; i++) {
305 if (horizontal) {
306 d1.push([Math.random(), i]);
307 d2.push([Math.random(), i]);
308 d3.push([Math.random(), i]);
309 } else {
310 d1.push([i, Math.random()]);
311 d2.push([i, Math.random()]);
312 d3.push([i, Math.random()]);
313 }
314 }
315
316 graph = Flotr.draw(container,[
317 { data : d1, label : 'Serie 1' },
318 { data : d2, label : 'Serie 2' },
319 { data : d3, label : 'Serie 3' }
320 ], {
321 legend : {
322 backgroundColor : '#D2E8FF' // Light blue
323 },
324 bars : {
325 show : true,
326 stacked : true,
327 horizontal : horizontal,
328 barWidth : 0.6,
329 lineWidth : 1,
330 shadowSize : 0
331 },
332 grid : {
333 verticalLines : horizontal,
334 horizontalLines : !horizontal
335 }
336 });
337}
338
339})();
340
341(function () {
342
343Flotr.ExampleList.add({
344 key : 'basic-pie',
345 name : 'Basic Pie',
346 callback : basic_pie
347});
348
349function basic_pie (container) {
350
351 var
352 d1 = [[0, 4]],
353 d2 = [[0, 3]],
354 d3 = [[0, 1.03]],
355 d4 = [[0, 3.5]],
356 graph;
357
358 graph = Flotr.draw(container, [
359 { data : d1, label : 'Comedy' },
360 { data : d2, label : 'Action' },
361 { data : d3, label : 'Romance',
362 pie : {
363 explode : 50
364 }
365 },
366 { data : d4, label : 'Drama' }
367 ], {
368 HtmlText : false,
369 grid : {
370 verticalLines : false,
371 horizontalLines : false
372 },
373 xaxis : { showLabels : false },
374 yaxis : { showLabels : false },
375 pie : {
376 show : true,
377 explode : 6
378 },
379 mouse : { track : true },
380 legend : {
381 position : 'se',
382 backgroundColor : '#D2E8FF'
383 }
384 });
385}
386
387})();
388
389(function () {
390
391Flotr.ExampleList.add({
392 key : 'basic-radar',
393 name : 'Basic Radar',
394 callback : basic_radar
395});
396
397function basic_radar (container) {
398
399 // Fill series s1 and s2.
400 var
401 s1 = { label : 'Actual', data : [[0, 3], [1, 8], [2, 5], [3, 5], [4, 3], [5, 9]] },
402 s2 = { label : 'Target', data : [[0, 8], [1, 7], [2, 8], [3, 2], [4, 4], [5, 7]] },
403 graph, ticks;
404
405 // Radar Labels
406 ticks = [
407 [0, "Statutory"],
408 [1, "External"],
409 [2, "Videos"],
410 [3, "Yippy"],
411 [4, "Management"],
412 [5, "oops"]
413 ];
414
415 // Draw the graph.
416 graph = Flotr.draw(container, [ s1, s2 ], {
417 radar : { show : true},
418 grid : { circular : true, minorHorizontalLines : true},
419 yaxis : { min : 0, max : 10, minorTickFreq : 2},
420 xaxis : { ticks : ticks}
421 });
422}
423
424})();
425
426(function () {
427
428Flotr.ExampleList.add({
429 key : 'basic-bubble',
430 name : 'Basic Bubble',
431 callback : basic_bubble
432});
433
434function basic_bubble (container) {
435
436 var
437 d1 = [],
438 d2 = [],
439 point, graph, i;
440
441 for (i = 0; i < 10; i++ ){
442 point = [i, Math.ceil(Math.random()*10), Math.ceil(Math.random()*10)];
443 d1.push(point);
444
445 point = [i, Math.ceil(Math.random()*10), Math.ceil(Math.random()*10)];
446 d2.push(point);
447 }
448
449 // Draw the graph
450 graph = Flotr.draw(container, [d1, d2], {
451 bubbles : { show : true, baseRadius : 5 },
452 xaxis : { min : -4, max : 14 },
453 yaxis : { min : -4, max : 14 }
454 });
455}
456
457})();
458
459(function () {
460
461Flotr.ExampleList.add({
462 key : 'basic-candle',
463 name : 'Basic Candle',
464 callback : basic_candle
465});
466
467function basic_candle (container) {
468
469 var
470 d1 = [],
471 price = 3.206,
472 graph,
473 i, a, b, c;
474
475 for (i = 0; i < 50; i++) {
476 a = Math.random();
477 b = Math.random();
478 c = (Math.random() * (a + b)) - b;
479 d1.push([i, price, price + a, price - b, price + c]);
480 price = price + c;
481 }
482
483 // Graph
484 graph = Flotr.draw(container, [ d1 ], {
485 candles : { show : true, candleWidth : 0.6 },
486 xaxis : { noTicks : 10 }
487 });
488}
489
490})();
491
492
493(function () {
494
495Flotr.ExampleList.add({
496 key : 'basic-legend',
497 name : 'Basic Legend',
498 callback : basic_legend
499});
500
501function basic_legend (container) {
502
503 var
504 d1 = [],
505 d2 = [],
506 d3 = [],
507 data,
508 graph, i;
509
510 // Data Generation
511 for (i = 0; i < 15; i += 0.5) {
512 d1.push([i, i + Math.sin(i+Math.PI)]);
513 d2.push([i, i]);
514 d3.push([i, 15-Math.cos(i)]);
515 }
516
517 data = [
518 { data : d1, label :'x + sin(x+&pi;)' },
519 { data : d2, label :'x' },
520 { data : d3, label :'15 - cos(x)' }
521 ];
522
523
524 // This function prepend each label with 'y = '
525 function labelFn (label) {
526 return 'y = ' + label;
527 }
528
529 // Draw graph
530 graph = Flotr.draw(container, data, {
531 legend : {
532 position : 'se', // Position the legend 'south-east'.
533 labelFormatter : labelFn, // Format the labels.
534 backgroundColor : '#D2E8FF' // A light blue background color.
535 },
536 HtmlText : false
537 });
538}
539
540})();
541
542(function () {
543
544Flotr.ExampleList.add({
545 key : 'mouse-tracking',
546 name : 'Mouse Tracking',
547 callback : mouse_tracking
548});
549
550function mouse_tracking (container) {
551
552 var
553 d1 = [],
554 d2 = [],
555 d3 = [],
556 graph, i;
557
558 for (i = 0; i < 20; i += 0.5) {
559 d1.push([i, 2*i]);
560 d2.push([i, i*1.5+1.5*Math.sin(i)]);
561 d3.push([i, 3*Math.cos(i)+10]);
562 }
563
564 graph = Flotr.draw(
565 container,
566 [
567 {
568 data : d1,
569 mouse : { track : false } // Disable mouse tracking for d1
570 },
571 d2,
572 d3
573 ],
574 {
575 mouse : {
576 track : true, // Enable mouse tracking
577 lineColor : 'purple',
578 relative : true,
579 position : 'ne',
580 sensibility : 1,
581 trackDecimals : 2,
582 trackFormatter : function (o) { return 'x = ' + o.x +', y = ' + o.y; }
583 },
584 crosshair : {
585 mode : 'xy'
586 }
587 }
588 );
589
590};
591
592})();
593
594(function () {
595
596Flotr.ExampleList.add({
597 key : 'mouse-zoom',
598 name : 'Mouse Zoom',
599 callback : mouse_zoom,
600 description : "<p>Select an area of the graph to zoom. Click to reset the chart.</p>"
601});
602
603function mouse_zoom (container) {
604
605 var
606 d1 = [],
607 d2 = [],
608 d3 = [],
609 options,
610 graph,
611 i;
612
613 for (i = 0; i < 40; i += 0.5) {
614 d1.push([i, Math.sin(i)+3*Math.cos(i)]);
615 d2.push([i, Math.pow(1.1, i)]);
616 d3.push([i, 40 - i+Math.random()*10]);
617 }
618
619 options = {
620 selection : { mode : 'x', fps : 30 },
621 title : 'Mouse Zoom'
622 };
623
624 // Draw graph with default options, overwriting with passed options
625 function drawGraph (opts) {
626
627 // Clone the options, so the 'options' variable always keeps intact.
628 var o = Flotr._.extend(Flotr._.clone(options), opts || {});
629
630 // Return a new graph.
631 return Flotr.draw(
632 container,
633 [ d1, d2, d3 ],
634 o
635 );
636 }
637
638 // Actually draw the graph.
639 graph = drawGraph();
640
641 // Hook into the 'flotr:select' event.
642 Flotr.EventAdapter.observe(container, 'flotr:select', function (area) {
643
644 // Draw graph with new area
645 f = drawGraph({
646 xaxis: {min:area.x1, max:area.x2},
647 yaxis: {min:area.y1, max:area.y2}
648 });
649
650 });
651
652 // When graph is clicked, draw the graph with default area.
653 Flotr.EventAdapter.observe(container, 'flotr:click', function () { drawGraph(); });
654};
655
656})();
657
658
659(function () {
660
661Flotr.ExampleList.add({
662 key : 'mouse-drag',
663 name : 'Mouse Drag',
664 callback : mouse_drag
665});
666
667function mouse_drag (container) {
668
669 var
670 d1 = [],
671 d2 = [],
672 d3 = [],
673 options,
674 graph,
675 start,
676 i;
677
678 for (i = -40; i < 40; i += 0.5) {
679 d1.push([i, Math.sin(i)+3*Math.cos(i)]);
680 d2.push([i, Math.pow(1.1, i)]);
681 d3.push([i, 40 - i+Math.random()*10]);
682 }
683
684 options = {
685 xaxis: {min: 0, max: 20},
686 title : 'Mouse Drag'
687 };
688
689 // Draw graph with default options, overwriting with passed options
690 function drawGraph (opts) {
691
692 // Clone the options, so the 'options' variable always keeps intact.
693 var o = Flotr._.extend(Flotr._.clone(options), opts || {});
694
695 // Return a new graph.
696 return Flotr.draw(
697 container,
698 [ d1, d2, d3 ],
699 o
700 );
701 }
702
703 graph = drawGraph();
704
705 function initializeDrag (e) {
706 start = graph.getEventPosition(e);
707 Flotr.EventAdapter.observe(document, 'mousemove', move);
708 Flotr.EventAdapter.observe(document, 'mouseup', stopDrag);
709 }
710
711 function move (e) {
712 var
713 end = graph.getEventPosition(e),
714 xaxis = graph.axes.x,
715 offset = start.x - end.x;
716
717 graph = drawGraph({
718 xaxis : {
719 min : xaxis.min + offset,
720 max : xaxis.max + offset
721 }
722 });
723 // @todo: refector initEvents in order not to remove other observed events
724 Flotr.EventAdapter.observe(graph.overlay, 'mousedown', initializeDrag);
725 }
726
727 function stopDrag () {
728 Flotr.EventAdapter.stopObserving(document, 'mousemove', move);
729 }
730
731 Flotr.EventAdapter.observe(graph.overlay, 'mousedown', initializeDrag);
732
733};
734
735})();
736
737(function () {
738
739Flotr.ExampleList.add({
740 key : 'basic-time',
741 name : 'Basic Time',
742 callback : basic_time,
743 description : "<p>Select an area of the graph to zoom. Click to reset the chart.</p>"
744});
745
746function basic_time (container) {
747
748 var
749 d1 = [],
750 start = new Date("2009/01/01 01:00").getTime(),
751 options,
752 graph,
753 i, x, o;
754
755 for (i = 0; i < 100; i++) {
756 x = start+(i*1000*3600*24*36.5);
757 d1.push([x, i+Math.random()*30+Math.sin(i/20+Math.random()*2)*20+Math.sin(i/10+Math.random())*10]);
758 }
759
760 options = {
761 xaxis : {
762 mode : 'time',
763 labelsAngle : 45
764 },
765 selection : {
766 mode : 'x'
767 },
768 HtmlText : false,
769 title : 'Time'
770 };
771
772 // Draw graph with default options, overwriting with passed options
773 function drawGraph (opts) {
774
775 // Clone the options, so the 'options' variable always keeps intact.
776 o = Flotr._.extend(Flotr._.clone(options), opts || {});
777
778 // Return a new graph.
779 return Flotr.draw(
780 container,
781 [ d1 ],
782 o
783 );
784 }
785
786 graph = drawGraph();
787
788 Flotr.EventAdapter.observe(container, 'flotr:select', function(area){
789 // Draw selected area
790 graph = drawGraph({
791 xaxis : { min : area.x1, max : area.x2, mode : 'time', labelsAngle : 45 },
792 yaxis : { min : area.y1, max : area.y2 }
793 });
794 });
795
796 // When graph is clicked, draw the graph with default area.
797 Flotr.EventAdapter.observe(container, 'flotr:click', function () { graph = drawGraph(); });
798};
799
800})();
801
802(function () {
803
804Flotr.ExampleList.add({
805 key : 'negative-values',
806 name : 'Negative Values',
807 callback : negative_values
808});
809
810function negative_values (container) {
811
812 var
813 d0 = [], // Line through y = 0
814 d1 = [], // Random data presented as a scatter plot.
815 d2 = [], // A regression line for the scatter.
816 sx = 0,
817 sy = 0,
818 sxy = 0,
819 sxsq = 0,
820 xmean,
821 ymean,
822 alpha,
823 beta,
824 n, x, y;
825
826 for (n = 0; n < 20; n++){
827
828 x = n;
829 y = x + Math.random()*8 - 15;
830
831 d0.push([x, 0]);
832 d1.push([x, y]);
833
834 // Computations used for regression line
835 sx += x;
836 sy += y;
837 sxy += x*y;
838 sxsq += Math.pow(x,2);
839 }
840
841 xmean = sx/n;
842 ymean = sy/n;
843 beta = ((n*sxy) - (sx*sy))/((n*sxsq)-(Math.pow(sx,2)));
844 alpha = ymean - (beta * xmean);
845
846 // Compute the regression line.
847 for (n = 0; n < 20; n++){
848 d2.push([n, alpha + beta*n])
849 }
850
851 // Draw the graph
852 graph = Flotr.draw(
853 container, [
854 { data : d0, shadowSize : 0, color : '#545454' }, // Horizontal
855 { data : d1, label : 'y = x + (Math.random() * 8) - 15', points : { show : true } }, // Scatter
856 { data : d2, label : 'y = ' + alpha.toFixed(2) + ' + ' + beta.toFixed(2) + '*x' } // Regression
857 ],
858 {
859 legend : { position : 'se', backgroundColor : '#D2E8FF' },
860 title : 'Negative Values'
861 }
862 );
863};
864
865})();
866
867(function () {
868
869Flotr.ExampleList.add({
870 key : 'click-example',
871 name : 'Click Example',
872 callback : click_example
873});
874
875function click_example (container) {
876
877 var
878 d1 = [[0,0]], // Point at origin
879 options,
880 graph;
881
882 options = {
883 xaxis: {min: 0, max: 15},
884 yaxis: {min: 0, max: 15},
885 lines: {show: true},
886 points: {show: true},
887 mouse: {track:true},
888 title: 'Click Example'
889 };
890
891 graph = Flotr.draw(container, [d1], options);
892
893 // Add a point to the series and redraw the graph
894 Flotr.EventAdapter.observe(container, 'flotr:click', function(position){
895
896 // Add a point to the series at the location of the click
897 d1.push([position.x, position.y]);
898
899 // Sort the series.
900 d1 = d1.sort(function (a, b) { return a[0] - b[0]; });
901
902 // Redraw the graph, with the new series.
903 graph = Flotr.draw(container, [d1], options);
904 });
905};
906
907})();
908
909(function () {
910
911Flotr.ExampleList.add({
912 key : 'download-image',
913 name : 'Download Image',
914 callback : download_image,
915 description : '' +
916 '<form name="image-download" id="image-download" action="" onsubmit="return false">' +
917 '<label><input type="radio" name="format" value="png" checked="checked" /> PNG</label>' +
918 '<label><input type="radio" name="format" value="jpeg" /> JPEG</label>' +
919
920 '<button name="to-image" onclick="CurrentExample(\'to-image\')">To Image</button>' +
921 '<button name="download" onclick="CurrentExample(\'download\')">Download</button>' +
922 '<button name="reset" onclick="CurrentExample(\'reset\')">Reset</button>' +
923 '</form>'
924});
925
926function download_image (container) {
927
928 var
929 d1 = [],
930 d2 = [],
931 d3 = [],
932 d4 = [],
933 d5 = [],
934 graph,
935 i;
936
937 for (i = 0; i <= 10; i += 0.1) {
938 d1.push([i, 4 + Math.pow(i,1.5)]);
939 d2.push([i, Math.pow(i,3)]);
940 d3.push([i, i*5+3*Math.sin(i*4)]);
941 d4.push([i, i]);
942 if( i.toFixed(1)%1 == 0 ){
943 d5.push([i, 2*i]);
944 }
945 }
946
947 // Draw the graph
948 graph = Flotr.draw(
949 container,[
950 {data:d1, label:'y = 4 + x^(1.5)', lines:{fill:true}},
951 {data:d2, label:'y = x^3', yaxis:2},
952 {data:d3, label:'y = 5x + 3sin(4x)'},
953 {data:d4, label:'y = x'},
954 {data:d5, label:'y = 2x', lines: {show: true}, points: {show: true}}
955 ],{
956 title: 'Download Image Example',
957 subtitle: 'You can save me as an image',
958 xaxis:{
959 noTicks: 7, // Display 7 ticks.
960 tickFormatter: function(n){ return '('+n+')'; }, // => displays tick values between brackets.
961 min: 1, // => part of the series is not displayed.
962 max: 7.5, // => part of the series is not displayed.
963 labelsAngle: 45,
964 title: 'x Axis'
965 },
966 yaxis:{
967 ticks: [[0, "Lower"], 10, 20, 30, [40, "Upper"]],
968 max: 40,
969 title: 'y = f(x)'
970 },
971 y2axis:{color:'#FF0000', max: 500, title: 'y = x^3'},
972 grid:{
973 verticalLines: false,
974 backgroundColor: 'white'
975 },
976 HtmlText: false,
977 legend: {
978 position: 'nw'
979 }
980 });
981
982 this.CurrentExample = function (operation) {
983
984 var
985 format = $('#image-download input:radio[name=format]:checked').val();
986 if (Flotr.isIE && Flotr.isIE < 9) {
987 alert(
988 "Your browser doesn't allow you to get a bitmap image from the plot, " +
989 "you can only get a VML image that you can use in Microsoft Office.<br />"
990 );
991 }
992
993 if (operation == 'to-image') {
994 graph.download.saveImage(format, null, null, true)
995 } else if (operation == 'download') {
996 graph.download.saveImage(format);
997 } else if (operation == 'reset') {
998 graph.download.restoreCanvas();
999 }
1000 };
1001
1002 return graph;
1003};
1004
1005})();
1006
1007(function () {
1008
1009Flotr.ExampleList.add({
1010 key : 'download-data',
1011 name : 'Download Data',
1012 callback : download_data
1013});
1014
1015function download_data (container) {
1016
1017 var
1018 d1 = [],
1019 d2 = [],
1020 d3 = [],
1021 d4 = [],
1022 d5 = [],
1023 graph,
1024 i,x;
1025
1026 for (i = 0; i <= 100; i += 1) {
1027 x = i / 10;
1028 d1.push([x, 4 + Math.pow(x,1.5)]);
1029 d2.push([x, Math.pow(x,3)]);
1030 d3.push([x, i*5+3*Math.sin(x*4)]);
1031 d4.push([x, x]);
1032 if(x%1 === 0 ){
1033 d5.push([x, 2*x]);
1034 }
1035 }
1036
1037 // Draw the graph.
1038 graph = Flotr.draw(
1039 container, [
1040 { data : d1, label : 'y = 4 + x^(1.5)', lines : { fill : true } },
1041 { data : d2, label : 'y = x^3' },
1042 { data : d3, label : 'y = 5x + 3sin(4x)' },
1043 { data : d4, label : 'y = x' },
1044 { data : d5, label : 'y = 2x', lines : { show : true }, points : { show : true } }
1045 ],{
1046 xaxis : {
1047 noTicks : 7,
1048 tickFormatter : function (n) { return '('+n+')'; },
1049 min: 1, // Part of the series is not displayed.
1050 max: 7.5
1051 },
1052 yaxis : {
1053 ticks : [[ 0, "Lower"], 10, 20, 30, [40, "Upper"]],
1054 max : 40
1055 },
1056 grid : {
1057 verticalLines : false,
1058 backgroundColor : 'white'
1059 },
1060 legend : {
1061 position : 'nw'
1062 },
1063 spreadsheet : {
1064 show : true,
1065 tickFormatter : function (e) { return e+''; }
1066 }
1067 });
1068};
1069
1070})();
1071
1072(function () {
1073
1074Flotr.ExampleList.add({
1075 key : 'advanced-titles',
1076 name : 'Advanced Titles',
1077 callback : advanced_titles
1078});
1079
1080function advanced_titles (container) {
1081
1082 var
1083 d1 = [],
1084 d2 = [],
1085 d3 = [],
1086 d4 = [],
1087 d5 = [],
1088 graph,
1089 i;
1090
1091 for (i = 0; i <= 10; i += 0.1) {
1092 d1.push([i, 4 + Math.pow(i,1.5)]);
1093 d2.push([i, Math.pow(i,3)]);
1094 d3.push([i, i*5+3*Math.sin(i*4)]);
1095 d4.push([i, i]);
1096 if (i.toFixed(1)%1 == 0) {
1097 d5.push([i, 2*i]);
1098 }
1099 }
1100
1101 // Draw the graph.
1102 graph = Flotr.draw(
1103 container,[
1104 { data : d1, label : 'y = 4 + x^(1.5)', lines : { fill : true } },
1105 { data : d2, label : 'y = x^3', yaxis : 2 },
1106 { data : d3, label : 'y = 5x + 3sin(4x)' },
1107 { data : d4, label : 'y = x' },
1108 { data : d5, label : 'y = 2x', lines : { show : true }, points : { show : true } }
1109 ], {
1110 title : 'Advanced Titles Example',
1111 subtitle : 'You can save me as an image',
1112 xaxis : {
1113 noTicks : 7,
1114 tickFormatter : function (n) { return '('+n+')'; },
1115 min : 1,
1116 max : 7.5,
1117 labelsAngle : 45,
1118 title : 'x Axis'
1119 },
1120 yaxis : {
1121 ticks : [[0, "Lower"], 10, 20, 30, [40, "Upper"]],
1122 max : 40,
1123 title : 'y = f(x)'
1124 },
1125 y2axis : { color : '#FF0000', max : 500, title : 'y = x^3' },
1126 grid : {
1127 verticalLines : false,
1128 backgroundColor : 'white'
1129 },
1130 HtmlText : false,
1131 legend : {
1132 position : 'nw'
1133 }
1134 });
1135};
1136
1137})();
1138
1139(function () {
1140
1141Flotr.ExampleList.add({
1142 key : 'color-gradients',
1143 name : 'Color Gradients',
1144 callback : color_gradients
1145});
1146
1147function color_gradients (container) {
1148
1149 var
1150 bars = {
1151 data: [],
1152 bars: {
1153 show: true,
1154 barWidth: 0.8,
1155 lineWidth: 0,
1156 fillColor: {
1157 colors: ['#CB4B4B', '#fff'],
1158 start: 'top',
1159 end: 'bottom'
1160 },
1161 fillOpacity: 0.8
1162 }
1163 }, markers = {
1164 data: [],
1165 markers: {
1166 show: true,
1167 position: 'ct'
1168 }
1169 }, lines = {
1170 data: [],
1171 lines: {
1172 show: true,
1173 fillColor: ['#00A8F0', '#fff'],
1174 fill: true,
1175 fillOpacity: 1
1176 }
1177 },
1178 point,
1179 graph,
1180 i;
1181
1182 for (i = 0; i < 8; i++) {
1183 point = [i, Math.ceil(Math.random() * 10)];
1184 bars.data.push(point);
1185 markers.data.push(point);
1186 }
1187
1188 for (i = -1; i < 9; i += 0.01){
1189 lines.data.push([i, i*i/8+2]);
1190 }
1191
1192 graph = Flotr.draw(
1193 container,
1194 [lines, bars, markers], {
1195 yaxis: {
1196 min: 0,
1197 max: 11
1198 },
1199 xaxis: {
1200 min: -0.5,
1201 max: 7.5
1202 },
1203 grid: {
1204 verticalLines: false,
1205 backgroundColor: ['#fff', '#ccc']
1206 }
1207 }
1208 );
1209};
1210
1211})();
1212
1213
1214(function () {
1215
1216Flotr.ExampleList.add({
1217 key : 'profile-bars',
1218 name : 'Profile Bars',
1219 type : 'profile',
1220 callback : profile_bars
1221});
1222
1223/*
1224Flotr.ExampleList.add({
1225 key : 'basic-bars-horizontal',
1226 name : 'Horizontal Bars',
1227 args : [true],
1228 callback : basic_bars
1229});
1230*/
1231
1232function profile_bars (container, horizontal) {
1233
1234 var
1235 horizontal = (horizontal ? true : false), // Show horizontal bars
1236 d1 = [], // First data series
1237 d2 = [], // Second data series
1238 point, // Data point variable declaration
1239 i;
1240
1241 for (i = 0; i < 5000; i++) {
1242
1243 if (horizontal) {
1244 point = [Math.ceil(Math.random()*10), i];
1245 } else {
1246 point = [i, Math.ceil(Math.random()*10)];
1247 }
1248
1249 d1.push(point);
1250
1251 if (horizontal) {
1252 point = [Math.ceil(Math.random()*10), i+0.5];
1253 } else {
1254 point = [i+0.5, Math.ceil(Math.random()*10)];
1255 }
1256
1257 d2.push(point);
1258 };
1259
1260 // Draw the graph
1261 Flotr.draw(
1262 container,
1263 [d1, d2],
1264 {
1265 bars : {
1266 show : true,
1267 horizontal : horizontal,
1268 barWidth : 0.5
1269 },
1270 mouse : {
1271 track : true,
1272 relative : true
1273 },
1274 yaxis : {
1275 min : 0,
1276 autoscaleMargin : 1
1277 }
1278 }
1279 );
1280}
1281
1282})();
1283
1284(function () {
1285
1286Flotr.ExampleList.add({
1287 key : 'basic-timeline',
1288 name : 'Basic Timeline',
1289 callback : basic_timeline
1290});
1291
1292function basic_timeline (container) {
1293
1294 var
1295 d1 = [[1, 4, 5]],
1296 d2 = [[3.2, 3, 4]],
1297 d3 = [[1.9, 2, 2], [5, 2, 3.3]],
1298 d4 = [[1.55, 1, 9]],
1299 d5 = [[5, 0, 2.3]],
1300 data = [],
1301 timeline = { show : true, barWidth : .5 },
1302 markers = [],
1303 labels = ['Obama', 'Bush', 'Clinton', 'Palin', 'McCain'],
1304 i, graph, point;
1305
1306 // Timeline
1307 Flotr._.each([d1, d2, d3, d4, d5], function (d) {
1308 data.push({
1309 data : d,
1310 timeline : Flotr._.clone(timeline)
1311 });
1312 });
1313
1314 // Markers
1315 Flotr._.each([d1, d2, d3, d4, d5], function (d) {
1316 point = d[0];
1317 markers.push([point[0], point[1]]);
1318 });
1319 data.push({
1320 data: markers,
1321 markers: {
1322 show: true,
1323 position: 'rm',
1324 fontSize: 11,
1325 labelFormatter : function (o) { return labels[o.index]; }
1326 }
1327 });
1328
1329 // Draw Graph
1330 graph = Flotr.draw(container, data, {
1331 xaxis: {
1332 noTicks: 3,
1333 tickFormatter: function (x) {
1334 var
1335 x = parseInt(x),
1336 months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
1337 return months[(x-1)%12];
1338 }
1339 },
1340 yaxis: {
1341 showLabels : false
1342 },
1343 grid: {
1344 horizontalLines : false
1345 }
1346 });
1347}
1348
1349})();
1350
1351(function () {
1352
1353Flotr.ExampleList.add({
1354 key : 'advanced-markers',
1355 name : 'Advanced Markers',
1356 callback : advanced_markers,
1357 timeout : 150
1358});
1359
1360function advanced_markers (container) {
1361
1362 var
1363 xmark = new Image(),
1364 checkmark = new Image(),
1365 bars = {
1366 data: [],
1367 bars: {
1368 show: true,
1369 barWidth: 0.6,
1370 lineWidth: 0,
1371 fillOpacity: 0.8
1372 }
1373 }, markers = {
1374 data: [],
1375 markers: {
1376 show: true,
1377 position: 'ct',
1378 labelFormatter: function (o) {
1379 return (o.y >= 5) ? checkmark : xmark;
1380 }
1381 }
1382 },
1383 flotr = Flotr,
1384 point,
1385 graph,
1386 i;
1387
1388
1389 for (i = 0; i < 8; i++) {
1390 point = [i, Math.ceil(Math.random() * 10)];
1391 bars.data.push(point);
1392 markers.data.push(point);
1393 }
1394
1395 var runner = function () {
1396 if (!xmark.complete || !checkmark.complete) {
1397 setTimeout(runner, 50);
1398 return;
1399 }
1400
1401 graph = flotr.draw(
1402 container,
1403 [bars, markers], {
1404 yaxis: {
1405 min: 0,
1406 max: 11
1407 },
1408 xaxis: {
1409 min: -0.5,
1410 max: 7.5
1411 },
1412 grid: {
1413 verticalLines: false
1414 }
1415 }
1416 );
1417 }
1418
1419 xmark.onload = runner;
1420 xmark.src = 'images/xmark.png';
1421 checkmark.src = 'images/checkmark.png';
1422};
1423
1424})();
1425
14260
=== removed file 'addons/web_graph/static/lib/flotr2/flotr2.ie.min.js'
--- addons/web_graph/static/lib/flotr2/flotr2.ie.min.js 2012-05-07 08:19:08 +0000
+++ addons/web_graph/static/lib/flotr2/flotr2.ie.min.js 1970-01-01 00:00:00 +0000
@@ -1,33 +0,0 @@
1// Copyright 2006 Google Inc.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14// Known Issues:
15//
16// * Patterns only support repeat.
17// * Radial gradient are not implemented. The VML version of these look very
18// different from the canvas one.
19// * Clipping paths are not implemented.
20// * Coordsize. The width and height attribute have higher priority than the
21// width and height style values which isn't correct.
22// * Painting mode isn't implemented.
23// * Canvas width/height should is using content-box by default. IE in
24// Quirks mode will draw the canvas using border-box. Either change your
25// doctype to HTML5
26// (http://www.whatwg.org/specs/web-apps/current-work/#the-doctype)
27// or use Box Sizing Behavior from WebFX
28// (http://webfx.eae.net/dhtml/boxsizing/boxsizing.html)
29// * Non uniform scaling does not correctly scale strokes.
30// * Optimize. There is always room for speed improvements.
31// Only add this code if we do not already have a canvas implementation
32
33document.createElement("canvas").getContext||function(){function j(){return this.context_||(this.context_=new N(this))}function l(a,b,c){var d=k.call(arguments,2);return function(){return a.apply(b,d.concat(k.call(arguments)))}}function m(a){return String(a).replace(/&/g,"&amp;").replace(/"/g,"&quot;")}function n(a,b,c){a.namespaces[b]||a.namespaces.add(b,c,"#default#VML")}function o(a){n(a,"g_vml_","urn:schemas-microsoft-com:vml"),n(a,"g_o_","urn:schemas-microsoft-com:office:office");if(!a.styleSheets.ex_canvas_){var b=a.createStyleSheet();b.owningElement.id="ex_canvas_",b.cssText="canvas{display:inline-block;overflow:hidden;text-align:left;width:300px;height:150px}"}}function q(a){var b=a.srcElement;switch(a.propertyName){case"width":b.getContext().clearRect(),b.style.width=b.attributes.width.nodeValue+"px",b.firstChild&&(b.firstChild.style.width=b.clientWidth+"px");break;case"height":b.getContext().clearRect(),b.style.height=b.attributes.height.nodeValue+"px",b.firstChild&&(b.firstChild.style.height=b.clientHeight+"px")}}function r(a){var b=a.srcElement;b.firstChild&&(b.firstChild.style.width=b.clientWidth+"px",b.firstChild.style.height=b.clientHeight+"px")}function v(){return[[1,0,0],[0,1,0],[0,0,1]]}function w(a,b){var c=v();for(var d=0;d<3;d++)for(var e=0;e<3;e++){var f=0;for(var g=0;g<3;g++)f+=a[d][g]*b[g][e];c[d][e]=f}return c}function x(a,b){b.fillStyle=a.fillStyle,b.lineCap=a.lineCap,b.lineJoin=a.lineJoin,b.lineWidth=a.lineWidth,b.miterLimit=a.miterLimit,b.shadowBlur=a.shadowBlur,b.shadowColor=a.shadowColor,b.shadowOffsetX=a.shadowOffsetX,b.shadowOffsetY=a.shadowOffsetY,b.strokeStyle=a.strokeStyle,b.globalAlpha=a.globalAlpha,b.font=a.font,b.textAlign=a.textAlign,b.textBaseline=a.textBaseline,b.arcScaleX_=a.arcScaleX_,b.arcScaleY_=a.arcScaleY_,b.lineScale_=a.lineScale_}function z(a){var b=a.indexOf("(",3),c=a.indexOf(")",b+1),d=a.substring(b+1,c).split(",");if(d.length!=4||a.charAt(3)!="a")d[3]=1;return d}function A(a){return parseFloat(a)/100}function B(a,b,c){return Math.min(c,Math.max(b,a))}function C(a){var b,c,d,e,f,g;e=parseFloat(a[0])/360%360,e<0&&e++,f=B(A(a[1]),0,1),g=B(A(a[2]),0,1);if(f==0)b=c=d=g;else{var h=g<.5?g*(1+f):g+f-g*f,i=2*g-h;b=D(i,h,e+1/3),c=D(i,h,e),d=D(i,h,e-1/3)}return"#"+s[Math.floor(b*255)]+s[Math.floor(c*255)]+s[Math.floor(d*255)]}function D(a,b,c){return c<0&&c++,c>1&&c--,6*c<1?a+(b-a)*6*c:2*c<1?b:3*c<2?a+(b-a)*(2/3-c)*6:a}function F(a){if(a in E)return E[a];var b,c=1;a=String(a);if(a.charAt(0)=="#")b=a;else if(/^rgb/.test(a)){var d=z(a),b="#",e;for(var f=0;f<3;f++)d[f].indexOf("%")!=-1?e=Math.floor(A(d[f])*255):e=+d[f],b+=s[B(e,0,255)];c=+d[3]}else if(/^hsl/.test(a)){var d=z(a);b=C(d),c=d[3]}else b=y[a]||a;return E[a]={color:b,alpha:c}}function I(a){if(H[a])return H[a];var b=document.createElement("div"),c=b.style;try{c.font=a}catch(d){}return H[a]={style:c.fontStyle||G.style,variant:c.fontVariant||G.variant,weight:c.fontWeight||G.weight,size:c.fontSize||G.size,family:c.fontFamily||G.family}}function J(a,b){var c={};for(var d in a)c[d]=a[d];var e=parseFloat(b.currentStyle.fontSize),f=parseFloat(a.size);return typeof a.size=="number"?c.size=a.size:a.size.indexOf("px")!=-1?c.size=f:a.size.indexOf("em")!=-1?c.size=e*f:a.size.indexOf("%")!=-1?c.size=e/100*f:a.size.indexOf("pt")!=-1?c.size=f/.75:c.size=e,c}function K(a){return a.style+" "+a.variant+" "+a.weight+" "+a.size+"px "+a.family}function M(a){return L[a]||"square"}function N(a){this.m_=v(),this.mStack_=[],this.aStack_=[],this.currentPath_=[],this.strokeStyle="#000",this.fillStyle="#000",this.lineWidth=1,this.lineJoin="miter",this.lineCap="butt",this.miterLimit=g*1,this.globalAlpha=1,this.font="10px sans-serif",this.textAlign="left",this.textBaseline="alphabetic",this.canvas=a;var b="width:"+a.clientWidth+"px;height:"+a.clientHeight+"px;overflow:hidden;position:absolute",c=a.ownerDocument.createElement("div");c.style.cssText=b,a.appendChild(c);var d=c.cloneNode(!1);d.style.backgroundColor="red",d.style.filter="alpha(opacity=0)",a.appendChild(d),this.element_=c,this.arcScaleX_=1,this.arcScaleY_=1,this.lineScale_=1}function P(a,b,c,d){a.currentPath_.push({type:"bezierCurveTo",cp1x:b.x,cp1y:b.y,cp2x:c.x,cp2y:c.y,x:d.x,y:d.y}),a.currentX_=d.x,a.currentY_=d.y}function Q(a,b){var c=F(a.strokeStyle),d=c.color,e=c.alpha*a.globalAlpha,f=a.lineScale_*a.lineWidth;f<1&&(e*=f),b.push("<g_vml_:stroke",' opacity="',e,'"',' joinstyle="',a.lineJoin,'"',' miterlimit="',a.miterLimit,'"',' endcap="',M(a.lineCap),'"',' weight="',f,'px"',' color="',d,'" />')}function R(b,c,d,e){var f=b.fillStyle,h=b.arcScaleX_,i=b.arcScaleY_,j=e.x-d.x,k=e.y-d.y;if(f instanceof V){var l=0,m={x:0,y:0},n=0,o=1;if(f.type_=="gradient"){var p=f.x0_/h,q=f.y0_/i,r=f.x1_/h,s=f.y1_/i,t=S(b,p,q),u=S(b,r,s),v=u.x-t.x,w=u.y-t.y;l=Math.atan2(v,w)*180/Math.PI,l<0&&(l+=360),l<1e-6&&(l=0)}else{var t=S(b,f.x0_,f.y0_);m={x:(t.x-d.x)/j,y:(t.y-d.y)/k},j/=h*g,k/=i*g;var x=a.max(j,k);n=2*f.r0_/x,o=2*f.r1_/x-n}var y=f.colors_;y.sort(function(a,b){return a.offset-b.offset});var z=y.length,A=y[0].color,B=y[z-1].color,C=y[0].alpha*b.globalAlpha,D=y[z-1].alpha*b.globalAlpha,E=[];for(var G=0;G<z;G++){var H=y[G];E.push(H.offset*o+n+" "+H.color)}c.push('<g_vml_:fill type="',f.type_,'"',' method="none" focus="100%"',' color="',A,'"',' color2="',B,'"',' colors="',E.join(","),'"',' opacity="',D,'"',' g_o_:opacity2="',C,'"',' angle="',l,'"',' focusposition="',m.x,",",m.y,'" />')}else if(f instanceof W){if(j&&k){var I=-d.x,J=-d.y;c.push("<g_vml_:fill",' position="',I/j*h*h,",",J/k*i*i,'"',' type="tile"',' src="',f.src_,'" />')}}else{var K=F(b.fillStyle),L=K.color,M=K.alpha*b.globalAlpha;c.push('<g_vml_:fill color="',L,'" opacity="',M,'" />')}}function S(a,b,c){var d=a.m_;return{x:g*(b*d[0][0]+c*d[1][0]+d[2][0])-h,y:g*(b*d[0][1]+c*d[1][1]+d[2][1])-h}}function T(a){return isFinite(a[0][0])&&isFinite(a[0][1])&&isFinite(a[1][0])&&isFinite(a[1][1])&&isFinite(a[2][0])&&isFinite(a[2][1])}function U(a,b,c){if(!T(b))return;a.m_=b;if(c){var d=b[0][0]*b[1][1]-b[0][1]*b[1][0];a.lineScale_=f(e(d))}}function V(a){this.type_=a,this.x0_=0,this.y0_=0,this.r0_=0,this.x1_=0,this.y1_=0,this.r1_=0,this.colors_=[]}function W(a,b){Y(a);switch(b){case"repeat":case null:case"":this.repetition_="repeat";break;case"repeat-x":case"repeat-y":case"no-repeat":this.repetition_=b;break;default:X("SYNTAX_ERR")}this.src_=a.src,this.width_=a.width,this.height_=a.height}function X(a){throw new Z(a)}function Y(a){(!a||a.nodeType!=1||a.tagName!="IMG")&&X("TYPE_MISMATCH_ERR"),a.readyState!="complete"&&X("INVALID_STATE_ERR")}function Z(a){this.code=this[a],this.message=a+": DOM Exception "+this.code}var a=Math,b=a.round,c=a.sin,d=a.cos,e=a.abs,f=a.sqrt,g=10,h=g/2,i=+navigator.userAgent.match(/MSIE ([\d.]+)?/)[1],k=Array.prototype.slice;o(document);var p={init:function(a){var b=a||document;b.createElement("canvas"),b.attachEvent("onreadystatechange",l(this.init_,this,b))},init_:function(a){var b=a.getElementsByTagName("canvas");for(var c=0;c<b.length;c++)this.initElement(b[c])},initElement:function(a){if(!a.getContext){a.getContext=j,o(a.ownerDocument),a.innerHTML="",a.attachEvent("onpropertychange",q),a.attachEvent("onresize",r);var b=a.attributes;b.width&&b.width.specified?a.style.width=b.width.nodeValue+"px":a.width=a.clientWidth,b.height&&b.height.specified?a.style.height=b.height.nodeValue+"px":a.height=a.clientHeight}return a}};p.init();var s=[];for(var t=0;t<16;t++)for(var u=0;u<16;u++)s[t*16+u]=t.toString(16)+u.toString(16);var y={aliceblue:"#F0F8FF",antiquewhite:"#FAEBD7",aquamarine:"#7FFFD4",azure:"#F0FFFF",beige:"#F5F5DC",bisque:"#FFE4C4",black:"#000000",blanchedalmond:"#FFEBCD",blueviolet:"#8A2BE2",brown:"#A52A2A",burlywood:"#DEB887",cadetblue:"#5F9EA0",chartreuse:"#7FFF00",chocolate:"#D2691E",coral:"#FF7F50",cornflowerblue:"#6495ED",cornsilk:"#FFF8DC",crimson:"#DC143C",cyan:"#00FFFF",darkblue:"#00008B",darkcyan:"#008B8B",darkgoldenrod:"#B8860B",darkgray:"#A9A9A9",darkgreen:"#006400",darkgrey:"#A9A9A9",darkkhaki:"#BDB76B",darkmagenta:"#8B008B",darkolivegreen:"#556B2F",darkorange:"#FF8C00",darkorchid:"#9932CC",darkred:"#8B0000",darksalmon:"#E9967A",darkseagreen:"#8FBC8F",darkslateblue:"#483D8B",darkslategray:"#2F4F4F",darkslategrey:"#2F4F4F",darkturquoise:"#00CED1",darkviolet:"#9400D3",deeppink:"#FF1493",deepskyblue:"#00BFFF",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1E90FF",firebrick:"#B22222",floralwhite:"#FFFAF0",forestgreen:"#228B22",gainsboro:"#DCDCDC",ghostwhite:"#F8F8FF",gold:"#FFD700",goldenrod:"#DAA520",grey:"#808080",greenyellow:"#ADFF2F",honeydew:"#F0FFF0",hotpink:"#FF69B4",indianred:"#CD5C5C",indigo:"#4B0082",ivory:"#FFFFF0",khaki:"#F0E68C",lavender:"#E6E6FA",lavenderblush:"#FFF0F5",lawngreen:"#7CFC00",lemonchiffon:"#FFFACD",lightblue:"#ADD8E6",lightcoral:"#F08080",lightcyan:"#E0FFFF",lightgoldenrodyellow:"#FAFAD2",lightgreen:"#90EE90",lightgrey:"#D3D3D3",lightpink:"#FFB6C1",lightsalmon:"#FFA07A",lightseagreen:"#20B2AA",lightskyblue:"#87CEFA",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#B0C4DE",lightyellow:"#FFFFE0",limegreen:"#32CD32",linen:"#FAF0E6",magenta:"#FF00FF",mediumaquamarine:"#66CDAA",mediumblue:"#0000CD",mediumorchid:"#BA55D3",mediumpurple:"#9370DB",mediumseagreen:"#3CB371",mediumslateblue:"#7B68EE",mediumspringgreen:"#00FA9A",mediumturquoise:"#48D1CC",mediumvioletred:"#C71585",midnightblue:"#191970",mintcream:"#F5FFFA",mistyrose:"#FFE4E1",moccasin:"#FFE4B5",navajowhite:"#FFDEAD",oldlace:"#FDF5E6",olivedrab:"#6B8E23",orange:"#FFA500",orangered:"#FF4500",orchid:"#DA70D6",palegoldenrod:"#EEE8AA",palegreen:"#98FB98",paleturquoise:"#AFEEEE",palevioletred:"#DB7093",papayawhip:"#FFEFD5",peachpuff:"#FFDAB9",peru:"#CD853F",pink:"#FFC0CB",plum:"#DDA0DD",powderblue:"#B0E0E6",rosybrown:"#BC8F8F",royalblue:"#4169E1",saddlebrown:"#8B4513",salmon:"#FA8072",sandybrown:"#F4A460",seagreen:"#2E8B57",seashell:"#FFF5EE",sienna:"#A0522D",skyblue:"#87CEEB",slateblue:"#6A5ACD",slategray:"#708090",slategrey:"#708090",snow:"#FFFAFA",springgreen:"#00FF7F",steelblue:"#4682B4",tan:"#D2B48C",thistle:"#D8BFD8",tomato:"#FF6347",turquoise:"#40E0D0",violet:"#EE82EE",wheat:"#F5DEB3",whitesmoke:"#F5F5F5",yellowgreen:"#9ACD32"},E={},G={style:"normal",variant:"normal",weight:"normal",size:10,family:"sans-serif"},H={},L={butt:"flat",round:"round"},O=N.prototype;O.clearRect=function(){this.textMeasureEl_&&(this.textMeasureEl_.removeNode(!0),this.textMeasureEl_=null),this.element_.innerHTML=""},O.beginPath=function(){this.currentPath_=[]},O.moveTo=function(a,b){var c=S(this,a,b);this.currentPath_.push({type:"moveTo",x:c.x,y:c.y}),this.currentX_=c.x,this.currentY_=c.y},O.lineTo=function(a,b){var c=S(this,a,b);this.currentPath_.push({type:"lineTo",x:c.x,y:c.y}),this.currentX_=c.x,this.currentY_=c.y},O.bezierCurveTo=function(a,b,c,d,e,f){var g=S(this,e,f),h=S(this,a,b),i=S(this,c,d);P(this,h,i,g)},O.quadraticCurveTo=function(a,b,c,d){var e=S(this,a,b),f=S(this,c,d),g={x:this.currentX_+2/3*(e.x-this.currentX_),y:this.currentY_+2/3*(e.y-this.currentY_)},h={x:g.x+(f.x-this.currentX_)/3,y:g.y+(f.y-this.currentY_)/3};P(this,g,h,f)},O.arc=function(a,b,f,i,j,k){f*=g;var l=k?"at":"wa",m=a+d(i)*f-h,n=b+c(i)*f-h,o=a+d(j)*f-h,p=b+c(j)*f-h;e(m-o)<1e-7&&!k&&(m+=.125),e(n-p)<1e-7&&k&&(n-=.125);var q=S(this,a,b),r=S(this,m,n),s=S(this,o,p);this.currentPath_.push({type:l,x:q.x,y:q.y,radius:f,xStart:r.x,yStart:r.y,xEnd:s.x,yEnd:s.y})},O.rect=function(a,b,c,d){this.moveTo(a,b),this.lineTo(a+c,b),this.lineTo(a+c,b+d),this.lineTo(a,b+d),this.closePath()},O.strokeRect=function(a,b,c,d){var e=this.currentPath_;this.beginPath(),this.moveTo(a,b),this.lineTo(a+c,b),this.lineTo(a+c,b+d),this.lineTo(a,b+d),this.closePath(),this.stroke(),this.currentPath_=e},O.fillRect=function(a,b,c,d){var e=this.currentPath_;this.beginPath(),this.moveTo(a,b),this.lineTo(a+c,b),this.lineTo(a+c,b+d),this.lineTo(a,b+d),this.closePath(),this.fill(),this.currentPath_=e},O.createLinearGradient=function(a,b,c,d){var e=new V("gradient");return e.x0_=a,e.y0_=b,e.x1_=c,e.y1_=d,e},O.createRadialGradient=function(a,b,c,d,e,f){var g=new V("gradientradial");return g.x0_=a,g.y0_=b,g.r0_=c,g.x1_=d,g.y1_=e,g.r1_=f,g},O.drawImage=function(c,d){var e,f,h,i,j,k,l,m,n=c.runtimeStyle.width,o=c.runtimeStyle.height;c.runtimeStyle.width="auto",c.runtimeStyle.height="auto";var p=c.width,q=c.height;c.runtimeStyle.width=n,c.runtimeStyle.height=o;if(arguments.length==3)e=arguments[1],f=arguments[2],j=k=0,l=h=p,m=i=q;else if(arguments.length==5)e=arguments[1],f=arguments[2],h=arguments[3],i=arguments[4],j=k=0,l=p,m=q;else if(arguments.length==9)j=arguments[1],k=arguments[2],l=arguments[3],m=arguments[4],e=arguments[5],f=arguments[6],h=arguments[7],i=arguments[8];else throw Error("Invalid number of arguments");var r=S(this,e,f),s=l/2,t=m/2,u=[],v=10,w=10;u.push(" <g_vml_:group",' coordsize="',g*v,",",g*w,'"',' coordorigin="0,0"',' style="width:',v,"px;height:",w,"px;position:absolute;");if(this.m_[0][0]!=1||this.m_[0][1]||this.m_[1][1]!=1||this.m_[1][0]){var x=[];x.push("M11=",this.m_[0][0],",","M12=",this.m_[1][0],",","M21=",this.m_[0][1],",","M22=",this.m_[1][1],",","Dx=",b(r.x/g),",","Dy=",b(r.y/g),"");var y=r,z=S(this,e+h,f),A=S(this,e,f+i),B=S(this,e+h,f+i);y.x=a.max(y.x,z.x,A.x,B.x),y.y=a.max(y.y,z.y,A.y,B.y),u.push("padding:0 ",b(y.x/g),"px ",b(y.y/g),"px 0;filter:progid:DXImageTransform.Microsoft.Matrix(",x.join(""),", sizingmethod='clip');")}else u.push("top:",b(r.y/g),"px;left:",b(r.x/g),"px;");u.push(' ">','<g_vml_:image src="',c.src,'"',' style="width:',g*h,"px;"," height:",g*i,'px"',' cropleft="',j/p,'"',' croptop="',k/q,'"',' cropright="',(p-j-l)/p,'"',' cropbottom="',(q-k-m)/q,'"'," />","</g_vml_:group>"),this.element_.insertAdjacentHTML("BeforeEnd",u.join(""))},O.stroke=function(a){var c=[],d=!1,e=10,f=10;c.push("<g_vml_:shape",' filled="',!!a,'"',' style="position:absolute;width:',e,"px;height:",f,'px;"',' coordorigin="0,0"',' coordsize="',g*e,",",g*f,'"',' stroked="',!a,'"',' path="');var h=!1,i={x:null,y:null},j={x:null,y:null};for(var k=0;k<this.currentPath_.length;k++){var l=this.currentPath_[k],m;switch(l.type){case"moveTo":m=l,c.push(" m ",b(l.x),",",b(l.y));break;case"lineTo":c.push(" l ",b(l.x),",",b(l.y));break;case"close":c.push(" x "),l=null;break;case"bezierCurveTo":c.push(" c ",b(l.cp1x),",",b(l.cp1y),",",b(l.cp2x),",",b(l.cp2y),",",b(l.x),",",b(l.y));break;case"at":case"wa":c.push(" ",l.type," ",b(l.x-this.arcScaleX_*l.radius),",",b(l.y-this.arcScaleY_*l.radius)," ",b(l.x+this.arcScaleX_*l.radius),",",b(l.y+this.arcScaleY_*l.radius)," ",b(l.xStart),",",b(l.yStart)," ",b(l.xEnd),",",b(l.yEnd))}if(l){if(i.x==null||l.x<i.x)i.x=l.x;if(j.x==null||l.x>j.x)j.x=l.x;if(i.y==null||l.y<i.y)i.y=l.y;if(j.y==null||l.y>j.y)j.y=l.y}}c.push(' ">'),a?R(this,c,i,j):Q(this,c),c.push("</g_vml_:shape>"),this.element_.insertAdjacentHTML("beforeEnd",c.join(""))},O.fill=function(){this.stroke(!0)},O.closePath=function(){this.currentPath_.push({type:"close"})},O.save=function(){var a={};x(this,a),this.aStack_.push(a),this.mStack_.push(this.m_),this.m_=w(v(),this.m_)},O.restore=function(){this.aStack_.length&&(x(this.aStack_.pop(),this),this.m_=this.mStack_.pop())},O.translate=function(a,b){var c=[[1,0,0],[0,1,0],[a,b,1]];U(this,w(c,this.m_),!1)},O.rotate=function(a){var b=d(a),e=c(a),f=[[b,e,0],[-e,b,0],[0,0,1]];U(this,w(f,this.m_),!1)},O.scale=function(a,b){this.arcScaleX_*=a,this.arcScaleY_*=b;var c=[[a,0,0],[0,b,0],[0,0,1]];U(this,w(c,this.m_),!0)},O.transform=function(a,b,c,d,e,f){var g=[[a,b,0],[c,d,0],[e,f,1]];U(this,w(g,this.m_),!0)},O.setTransform=function(a,b,c,d,e,f){var g=[[a,b,0],[c,d,0],[e,f,1]];U(this,g,!0)},O.drawText_=function(a,c,d,e,f){var h=this.m_,i=1e3,j=0,k=i,l={x:0,y:0},n=[],o=J(I(this.font),this.element_),p=K(o),q=this.element_.currentStyle,r=this.textAlign.toLowerCase();switch(r){case"left":case"center":case"right":break;case"end":r=q.direction=="ltr"?"right":"left";break;case"start":r=q.direction=="rtl"?"right":"left";break;default:r="left"}switch(this.textBaseline){case"hanging":case"top":l.y=o.size/1.75;break;case"middle":break;default:case null:case"alphabetic":case"ideographic":case"bottom":l.y=-o.size/2.25}switch(r){case"right":j=i,k=.05;break;case"center":j=k=i/2}var s=S(this,c+l.x,d+l.y);n.push('<g_vml_:line from="',-j,' 0" to="',k,' 0.05" ',' coordsize="100 100" coordorigin="0 0"',' filled="',!f,'" stroked="',!!f,'" style="position:absolute;width:1px;height:1px;">'),f?Q(this,n):R(this,n,{x:-j,y:0},{x:k,y:o.size});var t=h[0][0].toFixed(3)+","+h[1][0].toFixed(3)+","+h[0][1].toFixed(3)+","+h[1][1].toFixed(3)+",0,0",u=b(s.x/g)+","+b(s.y/g);n.push('<g_vml_:skew on="t" matrix="',t,'" ',' offset="',u,'" origin="',j,' 0" />','<g_vml_:path textpathok="true" />','<g_vml_:textpath on="true" string="',m(a),'" style="v-text-align:',r,";font:",m(p),'" /></g_vml_:line>'),this.element_.insertAdjacentHTML("beforeEnd",n.join(""))},O.fillText=function(a,b,c,d){this.drawText_(a,b,c,d,!1)},O.strokeText=function(a,b,c,d){this.drawText_(a,b,c,d,!0)},O.measureText=function(a){if(!this.textMeasureEl_){var b='<span style="position:absolute;top:-20000px;left:0;padding:0;margin:0;border:none;white-space:pre;"></span>';this.element_.insertAdjacentHTML("beforeEnd",b),this.textMeasureEl_=this.element_.lastChild}var c=this.element_.ownerDocument;return this.textMeasureEl_.innerHTML="",this.textMeasureEl_.style.font=this.font,this.textMeasureEl_.appendChild(c.createTextNode(a)),{width:this.textMeasureEl_.offsetWidth}},O.clip=function(){},O.arcTo=function(){},O.createPattern=function(a,b){return new W(a,b)},V.prototype.addColorStop=function(a,b){b=F(b),this.colors_.push({offset:a,color:b.color,alpha:b.alpha})};var $=Z.prototype=new Error;$.INDEX_SIZE_ERR=1,$.DOMSTRING_SIZE_ERR=2,$.HIERARCHY_REQUEST_ERR=3,$.WRONG_DOCUMENT_ERR=4,$.INVALID_CHARACTER_ERR=5,$.NO_DATA_ALLOWED_ERR=6,$.NO_MODIFICATION_ALLOWED_ERR=7,$.NOT_FOUND_ERR=8,$.NOT_SUPPORTED_ERR=9,$.INUSE_ATTRIBUTE_ERR=10,$.INVALID_STATE_ERR=11,$.SYNTAX_ERR=12,$.INVALID_MODIFICATION_ERR=13,$.NAMESPACE_ERR=14,$.INVALID_ACCESS_ERR=15,$.VALIDATION_ERR=16,$.TYPE_MISMATCH_ERR=17,G_vmlCanvasManager=p,CanvasRenderingContext2D=N,CanvasGradient=V,CanvasPattern=W,DOMException=Z}(),function(){function c(b){var c,d,e,f,g,h;e=b.length,d=0,c="";while(d<e){f=b.charCodeAt(d++)&255;if(d==e){c+=a.charAt(f>>2),c+=a.charAt((f&3)<<4),c+="==";break}g=b.charCodeAt(d++);if(d==e){c+=a.charAt(f>>2),c+=a.charAt((f&3)<<4|(g&240)>>4),c+=a.charAt((g&15)<<2),c+="=";break}h=b.charCodeAt(d++),c+=a.charAt(f>>2),c+=a.charAt((f&3)<<4|(g&240)>>4),c+=a.charAt((g&15)<<2|(h&192)>>6),c+=a.charAt(h&63)}return c}function d(a){var c,d,e,f,g,h,i;h=a.length,g=0,i="";while(g<h){do c=b[a.charCodeAt(g++)&255];while(g<h&&c==-1);if(c==-1)break;do d=b[a.charCodeAt(g++)&255];while(g<h&&d==-1);if(d==-1)break;i+=String.fromCharCode(c<<2|(d&48)>>4);do{e=a.charCodeAt(g++)&255;if(e==61)return i;e=b[e]}while(g<h&&e==-1);if(e==-1)break;i+=String.fromCharCode((d&15)<<4|(e&60)>>2);do{f=a.charCodeAt(g++)&255;if(f==61)return i;f=b[f]}while(g<h&&f==-1);if(f==-1)break;i+=String.fromCharCode((e&3)<<6|f)}return i}var a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",b=[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1,-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1];window.btoa||(window.btoa=c),window.atob||(window.atob=d)}();var CanvasText={letters:{"\n":{width:-1,points:[]}," ":{width:10,points:[]},"!":{width:10,points:[[5,21],[5,7],null,[5,2],[4,1],[5,0],[6,1],[5,2]]},'"':{width:16,points:[[4,21],[4,14],null,[12,21],[12,14]]},"#":{width:21,points:[[11,25],[4,-7],null,[17,25],[10,-7],null,[4,12],[18,12],null,[3,6],[17,6]]},$:{width:20,points:[[8,25],[8,-4],null,[12,25],[12,-4],null,[17,18],[15,20],[12,21],[8,21],[5,20],[3,18],[3,16],[4,14],[5,13],[7,12],[13,10],[15,9],[16,8],[17,6],[17,3],[15,1],[12,0],[8,0],[5,1],[3,3]]},"%":{width:24,points:[[21,21],[3,0],null,[8,21],[10,19],[10,17],[9,15],[7,14],[5,14],[3,16],[3,18],[4,20],[6,21],[8,21],null,[17,7],[15,6],[14,4],[14,2],[16,0],[18,0],[20,1],[21,3],[21,5],[19,7],[17,7]]},"&":{width:26,points:[[23,12],[23,13],[22,14],[21,14],[20,13],[19,11],[17,6],[15,3],[13,1],[11,0],[7,0],[5,1],[4,2],[3,4],[3,6],[4,8],[5,9],[12,13],[13,14],[14,16],[14,18],[13,20],[11,21],[9,20],[8,18],[8,16],[9,13],[11,10],[16,3],[18,1],[20,0],[22,0],[23,1],[23,2]]},"'":{width:10,points:[[5,19],[4,20],[5,21],[6,20],[6,18],[5,16],[4,15]]},"(":{width:14,points:[[11,25],[9,23],[7,20],[5,16],[4,11],[4,7],[5,2],[7,-2],[9,-5],[11,-7]]},")":{width:14,points:[[3,25],[5,23],[7,20],[9,16],[10,11],[10,7],[9,2],[7,-2],[5,-5],[3,-7]]},"*":{width:16,points:[[8,21],[8,9],null,[3,18],[13,12],null,[13,18],[3,12]]},"+":{width:26,points:[[13,18],[13,0],null,[4,9],[22,9]]},",":{width:10,points:[[6,1],[5,0],[4,1],[5,2],[6,1],[6,-1],[5,-3],[4,-4]]},"-":{width:26,points:[[4,9],[22,9]]},".":{width:10,points:[[5,2],[4,1],[5,0],[6,1],[5,2]]},"/":{width:22,points:[[20,25],[2,-7]]},0:{width:20,points:[[9,21],[6,20],[4,17],[3,12],[3,9],[4,4],[6,1],[9,0],[11,0],[14,1],[16,4],[17,9],[17,12],[16,17],[14,20],[11,21],[9,21]]},1:{width:20,points:[[6,17],[8,18],[11,21],[11,0]]},2:{width:20,points:[[4,16],[4,17],[5,19],[6,20],[8,21],[12,21],[14,20],[15,19],[16,17],[16,15],[15,13],[13,10],[3,0],[17,0]]},3:{width:20,points:[[5,21],[16,21],[10,13],[13,13],[15,12],[16,11],[17,8],[17,6],[16,3],[14,1],[11,0],[8,0],[5,1],[4,2],[3,4]]},4:{width:20,points:[[13,21],[3,7],[18,7],null,[13,21],[13,0]]},5:{width:20,points:[[15,21],[5,21],[4,12],[5,13],[8,14],[11,14],[14,13],[16,11],[17,8],[17,6],[16,3],[14,1],[11,0],[8,0],[5,1],[4,2],[3,4]]},6:{width:20,points:[[16,18],[15,20],[12,21],[10,21],[7,20],[5,17],[4,12],[4,7],[5,3],[7,1],[10,0],[11,0],[14,1],[16,3],[17,6],[17,7],[16,10],[14,12],[11,13],[10,13],[7,12],[5,10],[4,7]]},7:{width:20,points:[[17,21],[7,0],null,[3,21],[17,21]]},8:{width:20,points:[[8,21],[5,20],[4,18],[4,16],[5,14],[7,13],[11,12],[14,11],[16,9],[17,7],[17,4],[16,2],[15,1],[12,0],[8,0],[5,1],[4,2],[3,4],[3,7],[4,9],[6,11],[9,12],[13,13],[15,14],[16,16],[16,18],[15,20],[12,21],[8,21]]},9:{width:20,points:[[16,14],[15,11],[13,9],[10,8],[9,8],[6,9],[4,11],[3,14],[3,15],[4,18],[6,20],[9,21],[10,21],[13,20],[15,18],[16,14],[16,9],[15,4],[13,1],[10,0],[8,0],[5,1],[4,3]]},":":{width:10,points:[[5,14],[4,13],[5,12],[6,13],[5,14],null,[5,2],[4,1],[5,0],[6,1],[5,2]]},";":{width:10,points:[[5,14],[4,13],[5,12],[6,13],[5,14],null,[6,1],[5,0],[4,1],[5,2],[6,1],[6,-1],[5,-3],[4,-4]]},"<":{width:24,points:[[20,18],[4,9],[20,0]]},"=":{width:26,points:[[4,12],[22,12],null,[4,6],[22,6]]},">":{width:24,points:[[4,18],[20,9],[4,0]]},"?":{width:18,points:[[3,16],[3,17],[4,19],[5,20],[7,21],[11,21],[13,20],[14,19],[15,17],[15,15],[14,13],[13,12],[9,10],[9,7],null,[9,2],[8,1],[9,0],[10,1],[9,2]]},"@":{width:27,points:[[18,13],[17,15],[15,16],[12,16],[10,15],[9,14],[8,11],[8,8],[9,6],[11,5],[14,5],[16,6],[17,8],null,[12,16],[10,14],[9,11],[9,8],[10,6],[11,5],null,[18,16],[17,8],[17,6],[19,5],[21,5],[23,7],[24,10],[24,12],[23,15],[22,17],[20,19],[18,20],[15,21],[12,21],[9,20],[7,19],[5,17],[4,15],[3,12],[3,9],[4,6],[5,4],[7,2],[9,1],[12,0],[15,0],[18,1],[20,2],[21,3],null,[19,16],[18,8],[18,6],[19,5]]},A:{width:18,points:[[9,21],[1,0],null,[9,21],[17,0],null,[4,7],[14,7]]},B:{width:21,points:[[4,21],[4,0],null,[4,21],[13,21],[16,20],[17,19],[18,17],[18,15],[17,13],[16,12],[13,11],null,[4,11],[13,11],[16,10],[17,9],[18,7],[18,4],[17,2],[16,1],[13,0],[4,0]]},C:{width:21,points:[[18,16],[17,18],[15,20],[13,21],[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5]]},D:{width:21,points:[[4,21],[4,0],null,[4,21],[11,21],[14,20],[16,18],[17,16],[18,13],[18,8],[17,5],[16,3],[14,1],[11,0],[4,0]]},E:{width:19,points:[[4,21],[4,0],null,[4,21],[17,21],null,[4,11],[12,11],null,[4,0],[17,0]]},F:{width:18,points:[[4,21],[4,0],null,[4,21],[17,21],null,[4,11],[12,11]]},G:{width:21,points:[[18,16],[17,18],[15,20],[13,21],[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[18,8],null,[13,8],[18,8]]},H:{width:22,points:[[4,21],[4,0],null,[18,21],[18,0],null,[4,11],[18,11]]},I:{width:8,points:[[4,21],[4,0]]},J:{width:16,points:[[12,21],[12,5],[11,2],[10,1],[8,0],[6,0],[4,1],[3,2],[2,5],[2,7]]},K:{width:21,points:[[4,21],[4,0],null,[18,21],[4,7],null,[9,12],[18,0]]},L:{width:17,points:[[4,21],[4,0],null,[4,0],[16,0]]},M:{width:24,points:[[4,21],[4,0],null,[4,21],[12,0],null,[20,21],[12,0],null,[20,21],[20,0]]},N:{width:22,points:[[4,21],[4,0],null,[4,21],[18,0],null,[18,21],[18,0]]},O:{width:22,points:[[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[19,8],[19,13],[18,16],[17,18],[15,20],[13,21],[9,21]]},P:{width:21,points:[[4,21],[4,0],null,[4,21],[13,21],[16,20],[17,19],[18,17],[18,14],[17,12],[16,11],[13,10],[4,10]]},Q:{width:22,points:[[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[19,8],[19,13],[18,16],[17,18],[15,20],[13,21],[9,21],null,[12,4],[18,-2]]},R:{width:21,points:[[4,21],[4,0],null,[4,21],[13,21],[16,20],[17,19],[18,17],[18,15],[17,13],[16,12],[13,11],[4,11],null,[11,11],[18,0]]},S:{width:20,points:[[17,18],[15,20],[12,21],[8,21],[5,20],[3,18],[3,16],[4,14],[5,13],[7,12],[13,10],[15,9],[16,8],[17,6],[17,3],[15,1],[12,0],[8,0],[5,1],[3,3]]},T:{width:16,points:[[8,21],[8,0],null,[1,21],[15,21]]},U:{width:22,points:[[4,21],[4,6],[5,3],[7,1],[10,0],[12,0],[15,1],[17,3],[18,6],[18,21]]},V:{width:18,points:[[1,21],[9,0],null,[17,21],[9,0]]},W:{width:24,points:[[2,21],[7,0],null,[12,21],[7,0],null,[12,21],[17,0],null,[22,21],[17,0]]},X:{width:20,points:[[3,21],[17,0],null,[17,21],[3,0]]},Y:{width:18,points:[[1,21],[9,11],[9,0],null,[17,21],[9,11]]},Z:{width:20,points:[[17,21],[3,0],null,[3,21],[17,21],null,[3,0],[17,0]]},"[":{width:14,points:[[4,25],[4,-7],null,[5,25],[5,-7],null,[4,25],[11,25],null,[4,-7],[11,-7]]},"\\":{width:14,points:[[0,21],[14,-3]]},"]":{width:14,points:[[9,25],[9,-7],null,[10,25],[10,-7],null,[3,25],[10,25],null,[3,-7],[10,-7]]},"^":{width:14,points:[[3,10],[8,18],[13,10]]},_:{width:16,points:[[0,-2],[16,-2]]},"`":{width:10,points:[[6,21],[5,20],[4,18],[4,16],[5,15],[6,16],[5,17]]},a:{width:19,points:[[15,14],[15,0],null,[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},b:{width:19,points:[[4,21],[4,0],null,[4,11],[6,13],[8,14],[11,14],[13,13],[15,11],[16,8],[16,6],[15,3],[13,1],[11,0],[8,0],[6,1],[4,3]]},c:{width:18,points:[[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},d:{width:19,points:[[15,21],[15,0],null,[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},e:{width:18,points:[[3,8],[15,8],[15,10],[14,12],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},f:{width:12,points:[[10,21],[8,21],[6,20],[5,17],[5,0],null,[2,14],[9,14]]},g:{width:19,points:[[15,14],[15,-2],[14,-5],[13,-6],[11,-7],[8,-7],[6,-6],null,[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},h:{width:19,points:[[4,21],[4,0],null,[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0]]},i:{width:8,points:[[3,21],[4,20],[5,21],[4,22],[3,21],null,[4,14],[4,0]]},j:{width:10,points:[[5,21],[6,20],[7,21],[6,22],[5,21],null,[6,14],[6,-3],[5,-6],[3,-7],[1,-7]]},k:{width:17,points:[[4,21],[4,0],null,[14,14],[4,4],null,[8,8],[15,0]]},l:{width:8,points:[[4,21],[4,0]]},m:{width:30,points:[[4,14],[4,0],null,[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0],null,[15,10],[18,13],[20,14],[23,14],[25,13],[26,10],[26,0]]},n:{width:19,points:[[4,14],[4,0],null,[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0]]},o:{width:19,points:[[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3],[16,6],[16,8],[15,11],[13,13],[11,14],[8,14]]},p:{width:19,points:[[4,14],[4,-7],null,[4,11],[6,13],[8,14],[11,14],[13,13],[15,11],[16,8],[16,6],[15,3],[13,1],[11,0],[8,0],[6,1],[4,3]]},q:{width:19,points:[[15,14],[15,-7],null,[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},r:{width:13,points:[[4,14],[4,0],null,[4,8],[5,11],[7,13],[9,14],[12,14]]},s:{width:17,points:[[14,11],[13,13],[10,14],[7,14],[4,13],[3,11],[4,9],[6,8],[11,7],[13,6],[14,4],[14,3],[13,1],[10,0],[7,0],[4,1],[3,3]]},t:{width:12,points:[[5,21],[5,4],[6,1],[8,0],[10,0],null,[2,14],[9,14]]},u:{width:19,points:[[4,14],[4,4],[5,1],[7,0],[10,0],[12,1],[15,4],null,[15,14],[15,0]]},v:{width:16,points:[[2,14],[8,0],null,[14,14],[8,0]]},w:{width:22,points:[[3,14],[7,0],null,[11,14],[7,0],null,[11,14],[15,0],null,[19,14],[15,0]]},x:{width:17,points:[[3,14],[14,0],null,[14,14],[3,0]]},y:{width:16,points:[[2,14],[8,0],null,[14,14],[8,0],[6,-4],[4,-6],[2,-7],[1,-7]]},z:{width:17,points:[[14,14],[3,0],null,[3,14],[14,14],null,[3,0],[14,0]]},"{":{width:14,points:[[9,25],[7,24],[6,23],[5,21],[5,19],[6,17],[7,16],[8,14],[8,12],[6,10],null,[7,24],[6,22],[6,20],[7,18],[8,17],[9,15],[9,13],[8,11],[4,9],[8,7],[9,5],[9,3],[8,1],[7,0],[6,-2],[6,-4],[7,-6],null,[6,8],[8,6],[8,4],[7,2],[6,1],[5,-1],[5,-3],[6,-5],[7,-6],[9,-7]]},"|":{width:8,points:[[4,25],[4,-7]]},"}":{width:14,points:[[5,25],[7,24],[8,23],[9,21],[9,19],[8,17],[7,16],[6,14],[6,12],[8,10],null,[7,24],[8,22],[8,20],[7,18],[6,17],[5,15],[5,13],[6,11],[10,9],[6,7],[5,5],[5,3],[6,1],[7,0],[8,-2],[8,-4],[7,-6],null,[8,8],[6,6],[6,4],[7,2],[8,1],[9,-1],[9,-3],[8,-5],[7,-6],[5,-7]]},"~":{width:24,points:[[3,6],[3,8],[4,11],[6,12],[8,12],[10,11],[14,8],[16,7],[18,7],[20,8],[21,10],null,[3,8],[4,10],[6,11],[8,11],[10,10],[14,7],[16,6],[18,6],[20,7],[21,10],[21,12]]},"�":{diacritic:"`",letter:"a"},"�":{diacritic:"�",letter:"a"},"�":{diacritic:"^",letter:"a"},"�":{diacritic:"�",letter:"a"},"�":{diacritic:"~",letter:"a"},"�":{diacritic:"`",letter:"e"},"�":{diacritic:"�",letter:"e"},"�":{diacritic:"^",letter:"e"},"�":{diacritic:"�",letter:"e"},"�":{diacritic:"`",letter:"i"},"�":{diacritic:"�",letter:"i"},"�":{diacritic:"^",letter:"i"},"�":{diacritic:"�",letter:"i"},"�":{diacritic:"`",letter:"o"},"�":{diacritic:"�",letter:"o"},"�":{diacritic:"^",letter:"o"},"�":{diacritic:"�",letter:"o"},"�":{diacritic:"~",letter:"o"},"�":{diacritic:"`",letter:"u"},"�":{diacritic:"�",letter:"u"},"�":{diacritic:"^",letter:"u"},"�":{diacritic:"�",letter:"u"},"�":{diacritic:"�",letter:"y"},"�":{diacritic:"�",letter:"y"},"�":{diacritic:"�",letter:"c"},"�":{diacritic:"~",letter:"n"},"�":{diacritic:"`",letter:"A"},"�":{diacritic:"�",letter:"A"},"�":{diacritic:"^",letter:"A"},"�":{diacritic:"�",letter:"A"},"�":{diacritic:"~",letter:"A"},"�":{diacritic:"`",letter:"E"},"�":{diacritic:"�",letter:"E"},"�":{diacritic:"^",letter:"E"},"�":{diacritic:"�",letter:"E"},"�":{diacritic:"`",letter:"I"},"�":{diacritic:"�",letter:"I"},"�":{diacritic:"^",letter:"I"},"�":{diacritic:"�",letter:"I"},"�":{diacritic:"`",letter:"O"},"�":{diacritic:"�",letter:"O"},"�":{diacritic:"^",letter:"O"},"�":{diacritic:"�",letter:"O"},"�":{diacritic:"~",letter:"O"},"�":{diacritic:"`",letter:"U"},"�":{diacritic:"�",letter:"U"},"�":{diacritic:"^",letter:"U"},"�":{diacritic:"�",letter:"U"},"�":{diacritic:"�",letter:"Y"},"�":{diacritic:"�",letter:"C"},"�":{diacritic:"~",letter:"N"}},specialchars:{pi:{width:19,points:[[6,14],[6,0],null,[14,14],[14,0],null,[2,13],[6,16],[13,13],[17,16]]}},diacritics:{"�":{entity:"cedil",points:[[6,-4],[4,-6],[2,-7],[1,-7]]},"�":{entity:"acute",points:[[8,19],[13,22]]},"`":{entity:"grave",points:[[7,22],[12,19]]},"^":{entity:"circ",points:[[5.5,19],[9.5,23],[12.5,19]]},"�":{entity:"trema",points:[[5,21],[6,20],[7,21],[6,22],[5,21],null,[12,21],[13,20],[14,21],[13,22],[12,21]]},"~":{entity:"tilde",points:[[4,18],[7,22],[10,18],[13,22]]}},style:{size:8,font:null,color:"#000000",weight:1,textAlign:"left",textBaseline:"bottom",adjustAlign:!1,angle:0,tracking:1,boundingBoxColor:"#ff0000",originPointColor:"#000000"},debug:!1,_bufferLexemes:{},extend:function(a,b){for(var c in b){if(c in a)continue;a[c]=b[c]}return a},letter:function(a){return CanvasText.letters[a]},parseLexemes:function(a){if(CanvasText._bufferLexemes[a])return CanvasText._bufferLexemes[a];var b,c,d=a.match(/&[A-Za-z]{2,5};|\s|./g),e=[],f=[];for(b=0;b<d.length;b++){c=d[b];if(c.length==1)f.push(c);else{var g=c.substring(1,c.length-1);CanvasText.specialchars[g]?f.push(g):f=f.concat(c.toArray())}}for(b=0;b<f.length;b++)c=f[b],(c=CanvasText.letters[c]||CanvasText.specialchars[c])&&e.push(c);for(b=0;b<e.length;b++)(e===null||typeof e=="undefined")&&delete e[b];return CanvasText._bufferLexemes[a]=e},ascent:function(a){return a=a||CanvasText.style,a.size||CanvasText.style.size},descent:function(a){return a=a||CanvasText.style,7*(a.size||CanvasText.style.size)/25},measure:function(a,b){if(!a)return;b=b||CanvasText.style;var d,e,f=CanvasText.parseLexemes(a),g=0;for(d=f.length-1;d>-1;--d)c=f[d],e=c.diacritic?CanvasText.letter(c.letter).width:c.width,g+=e*(b.tracking||CanvasText.style.tracking)*(b.size||CanvasText.style.size)/25;return g},getDimensions:function(a,b){b=b||CanvasText.style;var c=CanvasText.measure(a,b),d=b.size||CanvasText.style.size,e=b.angle||CanvasText.style.angle;return b.angle==0?{width:c,height:d}:{width:Math.abs(Math.cos(e)*c)+Math.abs(Math.sin(e)*d),height:Math.abs(Math.sin(e)*c)+Math.abs(Math.cos(e)*d)}},drawPoints:function(a,b,c,d,e,f){var g,h,i=!0,j=0;f=f||{x:0,y:0},a.beginPath();for(g=0;g<b.length;g++){h=b[g];if(!h){i=!0;continue}i?(a.moveTo(c+h[0]*e+f.x,d-h[1]*e+f.y),i=!1):a.lineTo(c+h[0]*e+f.x,d-h[1]*e+f.y)}a.stroke(),a.closePath()},draw:function(a,b,c,d){if(!a)return;CanvasText.extend(d,CanvasText.style);var e,f,g=0,h=d.size/25,i=0,j=0,k=CanvasText.parseLexemes(a),l={x:0,y:0},m=CanvasText.measure(a,d),n;d.adjustAlign&&(n=CanvasText.getBestAlign(d.angle,d),CanvasText.extend(d,n));switch(d.textAlign){case"left":break;case"center":l.x=-m/2;break;case"right":l.x=-m}switch(d.textBaseline){case"bottom":break;case"middle":l.y=d.size/2;break;case"top":l.y=d.size}this.save(),this.translate(b,c),this.rotate(d.angle),this.lineCap="round",this.lineWidth=2*h*(d.weight||CanvasText.style.weight),this.strokeStyle=d.color||CanvasText.style.color;for(e=0;e<k.length;e++){f=k[e];if(f.width==-1){i=0,j=d.size*1.4;continue}var o=f.points,p=f.width;if(f.diacritic){var q=CanvasText.diacritics[f.diacritic],r=CanvasText.letter(f.letter);CanvasText.drawPoints(this,q.points,i,j-(f.letter.toUpperCase()==f.letter?3:0),h,l),o=r.points,p=r.width}CanvasText.drawPoints(this,o,i,j,h,l),CanvasText.debug&&(this.save(),this.lineJoin="miter",this.lineWidth=.5,this.strokeStyle=d.boundingBoxColor||CanvasText.style.boundingBoxColor,this.strokeRect(i+l.x,j+l.y,p*h,-d.size),this.fillStyle=d.originPointColor||CanvasText.style.originPointColor,this.beginPath(),this.arc(0,0,1.5,0,Math.PI*2,!0),this.fill(),this.closePath(),this.restore()),i+=p*h*(d.tracking||CanvasText.style.tracking)}return this.restore(),g}};CanvasText.proto=window.CanvasRenderingContext2D?window.CanvasRenderingContext2D.prototype:document.createElement("canvas").getContext("2d").__proto__,CanvasText.proto&&(CanvasText.proto.drawText=CanvasText.draw,CanvasText.proto.measure=CanvasText.measure,CanvasText.proto.getTextBounds=CanvasText.getDimensions,CanvasText.proto.fontAscent=CanvasText.ascent,CanvasText.proto.fontDescent=CanvasText.descent)
34\ No newline at end of file0\ No newline at end of file
351
=== removed file 'addons/web_graph/static/lib/flotr2/flotr2.js'
--- addons/web_graph/static/lib/flotr2/flotr2.js 2012-05-07 08:19:08 +0000
+++ addons/web_graph/static/lib/flotr2/flotr2.js 1970-01-01 00:00:00 +0000
@@ -1,6865 +0,0 @@
1/*!
2 * bean.js - copyright Jacob Thornton 2011
3 * https://github.com/fat/bean
4 * MIT License
5 * special thanks to:
6 * dean edwards: http://dean.edwards.name/
7 * dperini: https://github.com/dperini/nwevents
8 * the entire mootools team: github.com/mootools/mootools-core
9 */
10/*global module:true, define:true*/
11!function (name, context, definition) {
12 if (typeof module !== 'undefined') module.exports = definition(name, context);
13 else if (typeof define === 'function' && typeof define.amd === 'object') define(definition);
14 else context[name] = definition(name, context);
15}('bean', this, function (name, context) {
16 var win = window
17 , old = context[name]
18 , overOut = /over|out/
19 , namespaceRegex = /[^\.]*(?=\..*)\.|.*/
20 , nameRegex = /\..*/
21 , addEvent = 'addEventListener'
22 , attachEvent = 'attachEvent'
23 , removeEvent = 'removeEventListener'
24 , detachEvent = 'detachEvent'
25 , doc = document || {}
26 , root = doc.documentElement || {}
27 , W3C_MODEL = root[addEvent]
28 , eventSupport = W3C_MODEL ? addEvent : attachEvent
29 , slice = Array.prototype.slice
30 , mouseTypeRegex = /click|mouse|menu|drag|drop/i
31 , touchTypeRegex = /^touch|^gesture/i
32 , ONE = { one: 1 } // singleton for quick matching making add() do one()
33
34 , nativeEvents = (function (hash, events, i) {
35 for (i = 0; i < events.length; i++)
36 hash[events[i]] = 1
37 return hash
38 })({}, (
39 'click dblclick mouseup mousedown contextmenu ' + // mouse buttons
40 'mousewheel DOMMouseScroll ' + // mouse wheel
41 'mouseover mouseout mousemove selectstart selectend ' + // mouse movement
42 'keydown keypress keyup ' + // keyboard
43 'orientationchange ' + // mobile
44 'focus blur change reset select submit ' + // form elements
45 'load unload beforeunload resize move DOMContentLoaded readystatechange ' + // window
46 'error abort scroll ' + // misc
47 (W3C_MODEL ? // element.fireEvent('onXYZ'... is not forgiving if we try to fire an event
48 // that doesn't actually exist, so make sure we only do these on newer browsers
49 'show ' + // mouse buttons
50 'input invalid ' + // form elements
51 'touchstart touchmove touchend touchcancel ' + // touch
52 'gesturestart gesturechange gestureend ' + // gesture
53 'message readystatechange pageshow pagehide popstate ' + // window
54 'hashchange offline online ' + // window
55 'afterprint beforeprint ' + // printing
56 'dragstart dragenter dragover dragleave drag drop dragend ' + // dnd
57 'loadstart progress suspend emptied stalled loadmetadata ' + // media
58 'loadeddata canplay canplaythrough playing waiting seeking ' + // media
59 'seeked ended durationchange timeupdate play pause ratechange ' + // media
60 'volumechange cuechange ' + // media
61 'checking noupdate downloading cached updateready obsolete ' + // appcache
62 '' : '')
63 ).split(' ')
64 )
65
66 , customEvents = (function () {
67 function isDescendant(parent, node) {
68 while ((node = node.parentNode) !== null) {
69 if (node === parent) return true
70 }
71 return false
72 }
73
74 function check(event) {
75 var related = event.relatedTarget
76 if (!related) return related === null
77 return (related !== this && related.prefix !== 'xul' && !/document/.test(this.toString()) && !isDescendant(this, related))
78 }
79
80 return {
81 mouseenter: { base: 'mouseover', condition: check }
82 , mouseleave: { base: 'mouseout', condition: check }
83 , mousewheel: { base: /Firefox/.test(navigator.userAgent) ? 'DOMMouseScroll' : 'mousewheel' }
84 }
85 })()
86
87 , fixEvent = (function () {
88 var commonProps = 'altKey attrChange attrName bubbles cancelable ctrlKey currentTarget detail eventPhase getModifierState isTrusted metaKey relatedNode relatedTarget shiftKey srcElement target timeStamp type view which'.split(' ')
89 , mouseProps = commonProps.concat('button buttons clientX clientY dataTransfer fromElement offsetX offsetY pageX pageY screenX screenY toElement'.split(' '))
90 , keyProps = commonProps.concat('char charCode key keyCode'.split(' '))
91 , touchProps = commonProps.concat('touches targetTouches changedTouches scale rotation'.split(' '))
92 , preventDefault = 'preventDefault'
93 , createPreventDefault = function (event) {
94 return function () {
95 if (event[preventDefault])
96 event[preventDefault]()
97 else
98 event.returnValue = false
99 }
100 }
101 , stopPropagation = 'stopPropagation'
102 , createStopPropagation = function (event) {
103 return function () {
104 if (event[stopPropagation])
105 event[stopPropagation]()
106 else
107 event.cancelBubble = true
108 }
109 }
110 , createStop = function (synEvent) {
111 return function () {
112 synEvent[preventDefault]()
113 synEvent[stopPropagation]()
114 synEvent.stopped = true
115 }
116 }
117 , copyProps = function (event, result, props) {
118 var i, p
119 for (i = props.length; i--;) {
120 p = props[i]
121 if (!(p in result) && p in event) result[p] = event[p]
122 }
123 }
124
125 return function (event, isNative) {
126 var result = { originalEvent: event, isNative: isNative }
127 if (!event)
128 return result
129
130 var props
131 , type = event.type
132 , target = event.target || event.srcElement
133
134 result[preventDefault] = createPreventDefault(event)
135 result[stopPropagation] = createStopPropagation(event)
136 result.stop = createStop(result)
137 result.target = target && target.nodeType === 3 ? target.parentNode : target
138
139 if (isNative) { // we only need basic augmentation on custom events, the rest is too expensive
140 if (type.indexOf('key') !== -1) {
141 props = keyProps
142 result.keyCode = event.which || event.keyCode
143 } else if (mouseTypeRegex.test(type)) {
144 props = mouseProps
145 result.rightClick = event.which === 3 || event.button === 2
146 result.pos = { x: 0, y: 0 }
147 if (event.pageX || event.pageY) {
148 result.clientX = event.pageX
149 result.clientY = event.pageY
150 } else if (event.clientX || event.clientY) {
151 result.clientX = event.clientX + doc.body.scrollLeft + root.scrollLeft
152 result.clientY = event.clientY + doc.body.scrollTop + root.scrollTop
153 }
154 if (overOut.test(type))
155 result.relatedTarget = event.relatedTarget || event[(type === 'mouseover' ? 'from' : 'to') + 'Element']
156 } else if (touchTypeRegex.test(type)) {
157 props = touchProps
158 }
159 copyProps(event, result, props || commonProps)
160 }
161 return result
162 }
163 })()
164
165 // if we're in old IE we can't do onpropertychange on doc or win so we use doc.documentElement for both
166 , targetElement = function (element, isNative) {
167 return !W3C_MODEL && !isNative && (element === doc || element === win) ? root : element
168 }
169
170 // we use one of these per listener, of any type
171 , RegEntry = (function () {
172 function entry(element, type, handler, original, namespaces) {
173 this.element = element
174 this.type = type
175 this.handler = handler
176 this.original = original
177 this.namespaces = namespaces
178 this.custom = customEvents[type]
179 this.isNative = nativeEvents[type] && element[eventSupport]
180 this.eventType = W3C_MODEL || this.isNative ? type : 'propertychange'
181 this.customType = !W3C_MODEL && !this.isNative && type
182 this.target = targetElement(element, this.isNative)
183 this.eventSupport = this.target[eventSupport]
184 }
185
186 entry.prototype = {
187 // given a list of namespaces, is our entry in any of them?
188 inNamespaces: function (checkNamespaces) {
189 var i, j
190 if (!checkNamespaces)
191 return true
192 if (!this.namespaces)
193 return false
194 for (i = checkNamespaces.length; i--;) {
195 for (j = this.namespaces.length; j--;) {
196 if (checkNamespaces[i] === this.namespaces[j])
197 return true
198 }
199 }
200 return false
201 }
202
203 // match by element, original fn (opt), handler fn (opt)
204 , matches: function (checkElement, checkOriginal, checkHandler) {
205 return this.element === checkElement &&
206 (!checkOriginal || this.original === checkOriginal) &&
207 (!checkHandler || this.handler === checkHandler)
208 }
209 }
210
211 return entry
212 })()
213
214 , registry = (function () {
215 // our map stores arrays by event type, just because it's better than storing
216 // everything in a single array. uses '$' as a prefix for the keys for safety
217 var map = {}
218
219 // generic functional search of our registry for matching listeners,
220 // `fn` returns false to break out of the loop
221 , forAll = function (element, type, original, handler, fn) {
222 if (!type || type === '*') {
223 // search the whole registry
224 for (var t in map) {
225 if (t.charAt(0) === '$')
226 forAll(element, t.substr(1), original, handler, fn)
227 }
228 } else {
229 var i = 0, l, list = map['$' + type], all = element === '*'
230 if (!list)
231 return
232 for (l = list.length; i < l; i++) {
233 if (all || list[i].matches(element, original, handler))
234 if (!fn(list[i], list, i, type))
235 return
236 }
237 }
238 }
239
240 , has = function (element, type, original) {
241 // we're not using forAll here simply because it's a bit slower and this
242 // needs to be fast
243 var i, list = map['$' + type]
244 if (list) {
245 for (i = list.length; i--;) {
246 if (list[i].matches(element, original, null))
247 return true
248 }
249 }
250 return false
251 }
252
253 , get = function (element, type, original) {
254 var entries = []
255 forAll(element, type, original, null, function (entry) { return entries.push(entry) })
256 return entries
257 }
258
259 , put = function (entry) {
260 (map['$' + entry.type] || (map['$' + entry.type] = [])).push(entry)
261 return entry
262 }
263
264 , del = function (entry) {
265 forAll(entry.element, entry.type, null, entry.handler, function (entry, list, i) {
266 list.splice(i, 1)
267 if (list.length === 0)
268 delete map['$' + entry.type]
269 return false
270 })
271 }
272
273 // dump all entries, used for onunload
274 , entries = function () {
275 var t, entries = []
276 for (t in map) {
277 if (t.charAt(0) === '$')
278 entries = entries.concat(map[t])
279 }
280 return entries
281 }
282
283 return { has: has, get: get, put: put, del: del, entries: entries }
284 })()
285
286 // add and remove listeners to DOM elements
287 , listener = W3C_MODEL ? function (element, type, fn, add) {
288 element[add ? addEvent : removeEvent](type, fn, false)
289 } : function (element, type, fn, add, custom) {
290 if (custom && add && element['_on' + custom] === null)
291 element['_on' + custom] = 0
292 element[add ? attachEvent : detachEvent]('on' + type, fn)
293 }
294
295 , nativeHandler = function (element, fn, args) {
296 return function (event) {
297 event = fixEvent(event || ((this.ownerDocument || this.document || this).parentWindow || win).event, true)
298 return fn.apply(element, [event].concat(args))
299 }
300 }
301
302 , customHandler = function (element, fn, type, condition, args, isNative) {
303 return function (event) {
304 if (condition ? condition.apply(this, arguments) : W3C_MODEL ? true : event && event.propertyName === '_on' + type || !event) {
305 if (event)
306 event = fixEvent(event || ((this.ownerDocument || this.document || this).parentWindow || win).event, isNative)
307 fn.apply(element, event && (!args || args.length === 0) ? arguments : slice.call(arguments, event ? 0 : 1).concat(args))
308 }
309 }
310 }
311
312 , once = function (rm, element, type, fn, originalFn) {
313 // wrap the handler in a handler that does a remove as well
314 return function () {
315 rm(element, type, originalFn)
316 fn.apply(this, arguments)
317 }
318 }
319
320 , removeListener = function (element, orgType, handler, namespaces) {
321 var i, l, entry
322 , type = (orgType && orgType.replace(nameRegex, ''))
323 , handlers = registry.get(element, type, handler)
324
325 for (i = 0, l = handlers.length; i < l; i++) {
326 if (handlers[i].inNamespaces(namespaces)) {
327 if ((entry = handlers[i]).eventSupport)
328 listener(entry.target, entry.eventType, entry.handler, false, entry.type)
329 // TODO: this is problematic, we have a registry.get() and registry.del() that
330 // both do registry searches so we waste cycles doing this. Needs to be rolled into
331 // a single registry.forAll(fn) that removes while finding, but the catch is that
332 // we'll be splicing the arrays that we're iterating over. Needs extra tests to
333 // make sure we don't screw it up. @rvagg
334 registry.del(entry)
335 }
336 }
337 }
338
339 , addListener = function (element, orgType, fn, originalFn, args) {
340 var entry
341 , type = orgType.replace(nameRegex, '')
342 , namespaces = orgType.replace(namespaceRegex, '').split('.')
343
344 if (registry.has(element, type, fn))
345 return element // no dupe
346 if (type === 'unload')
347 fn = once(removeListener, element, type, fn, originalFn) // self clean-up
348 if (customEvents[type]) {
349 if (customEvents[type].condition)
350 fn = customHandler(element, fn, type, customEvents[type].condition, true)
351 type = customEvents[type].base || type
352 }
353 entry = registry.put(new RegEntry(element, type, fn, originalFn, namespaces[0] && namespaces))
354 entry.handler = entry.isNative ?
355 nativeHandler(element, entry.handler, args) :
356 customHandler(element, entry.handler, type, false, args, false)
357 if (entry.eventSupport)
358 listener(entry.target, entry.eventType, entry.handler, true, entry.customType)
359 }
360
361 , del = function (selector, fn, $) {
362 return function (e) {
363 var target, i, array = typeof selector === 'string' ? $(selector, this) : selector
364 for (target = e.target; target && target !== this; target = target.parentNode) {
365 for (i = array.length; i--;) {
366 if (array[i] === target) {
367 return fn.apply(target, arguments)
368 }
369 }
370 }
371 }
372 }
373
374 , remove = function (element, typeSpec, fn) {
375 var k, m, type, namespaces, i
376 , rm = removeListener
377 , isString = typeSpec && typeof typeSpec === 'string'
378
379 if (isString && typeSpec.indexOf(' ') > 0) {
380 // remove(el, 't1 t2 t3', fn) or remove(el, 't1 t2 t3')
381 typeSpec = typeSpec.split(' ')
382 for (i = typeSpec.length; i--;)
383 remove(element, typeSpec[i], fn)
384 return element
385 }
386 type = isString && typeSpec.replace(nameRegex, '')
387 if (type && customEvents[type])
388 type = customEvents[type].type
389 if (!typeSpec || isString) {
390 // remove(el) or remove(el, t1.ns) or remove(el, .ns) or remove(el, .ns1.ns2.ns3)
391 if (namespaces = isString && typeSpec.replace(namespaceRegex, ''))
392 namespaces = namespaces.split('.')
393 rm(element, type, fn, namespaces)
394 } else if (typeof typeSpec === 'function') {
395 // remove(el, fn)
396 rm(element, null, typeSpec)
397 } else {
398 // remove(el, { t1: fn1, t2, fn2 })
399 for (k in typeSpec) {
400 if (typeSpec.hasOwnProperty(k))
401 remove(element, k, typeSpec[k])
402 }
403 }
404 return element
405 }
406
407 , add = function (element, events, fn, delfn, $) {
408 var type, types, i, args
409 , originalFn = fn
410 , isDel = fn && typeof fn === 'string'
411
412 if (events && !fn && typeof events === 'object') {
413 for (type in events) {
414 if (events.hasOwnProperty(type))
415 add.apply(this, [ element, type, events[type] ])
416 }
417 } else {
418 args = arguments.length > 3 ? slice.call(arguments, 3) : []
419 types = (isDel ? fn : events).split(' ')
420 isDel && (fn = del(events, (originalFn = delfn), $)) && (args = slice.call(args, 1))
421 // special case for one()
422 this === ONE && (fn = once(remove, element, events, fn, originalFn))
423 for (i = types.length; i--;) addListener(element, types[i], fn, originalFn, args)
424 }
425 return element
426 }
427
428 , one = function () {
429 return add.apply(ONE, arguments)
430 }
431
432 , fireListener = W3C_MODEL ? function (isNative, type, element) {
433 var evt = doc.createEvent(isNative ? 'HTMLEvents' : 'UIEvents')
434 evt[isNative ? 'initEvent' : 'initUIEvent'](type, true, true, win, 1)
435 element.dispatchEvent(evt)
436 } : function (isNative, type, element) {
437 element = targetElement(element, isNative)
438 // if not-native then we're using onpropertychange so we just increment a custom property
439 isNative ? element.fireEvent('on' + type, doc.createEventObject()) : element['_on' + type]++
440 }
441
442 , fire = function (element, type, args) {
443 var i, j, l, names, handlers
444 , types = type.split(' ')
445
446 for (i = types.length; i--;) {
447 type = types[i].replace(nameRegex, '')
448 if (names = types[i].replace(namespaceRegex, ''))
449 names = names.split('.')
450 if (!names && !args && element[eventSupport]) {
451 fireListener(nativeEvents[type], type, element)
452 } else {
453 // non-native event, either because of a namespace, arguments or a non DOM element
454 // iterate over all listeners and manually 'fire'
455 handlers = registry.get(element, type)
456 args = [false].concat(args)
457 for (j = 0, l = handlers.length; j < l; j++) {
458 if (handlers[j].inNamespaces(names))
459 handlers[j].handler.apply(element, args)
460 }
461 }
462 }
463 return element
464 }
465
466 , clone = function (element, from, type) {
467 var i = 0
468 , handlers = registry.get(from, type)
469 , l = handlers.length
470
471 for (;i < l; i++)
472 handlers[i].original && add(element, handlers[i].type, handlers[i].original)
473 return element
474 }
475
476 , bean = {
477 add: add
478 , one: one
479 , remove: remove
480 , clone: clone
481 , fire: fire
482 , noConflict: function () {
483 context[name] = old
484 return this
485 }
486 }
487
488 if (win[attachEvent]) {
489 // for IE, clean up on unload to avoid leaks
490 var cleanup = function () {
491 var i, entries = registry.entries()
492 for (i in entries) {
493 if (entries[i].type && entries[i].type !== 'unload')
494 remove(entries[i].element, entries[i].type)
495 }
496 win[detachEvent]('onunload', cleanup)
497 win.CollectGarbage && win.CollectGarbage()
498 }
499 win[attachEvent]('onunload', cleanup)
500 }
501
502 return bean
503});
504// Underscore.js 1.1.7
505// (c) 2011 Jeremy Ashkenas, DocumentCloud Inc.
506// Underscore is freely distributable under the MIT license.
507// Portions of Underscore are inspired or borrowed from Prototype,
508// Oliver Steele's Functional, and John Resig's Micro-Templating.
509// For all details and documentation:
510// http://documentcloud.github.com/underscore
511
512(function() {
513
514 // Baseline setup
515 // --------------
516
517 // Establish the root object, `window` in the browser, or `global` on the server.
518 var root = this;
519
520 // Save the previous value of the `_` variable.
521 var previousUnderscore = root._;
522
523 // Establish the object that gets returned to break out of a loop iteration.
524 var breaker = {};
525
526 // Save bytes in the minified (but not gzipped) version:
527 var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
528
529 // Create quick reference variables for speed access to core prototypes.
530 var slice = ArrayProto.slice,
531 unshift = ArrayProto.unshift,
532 toString = ObjProto.toString,
533 hasOwnProperty = ObjProto.hasOwnProperty;
534
535 // All **ECMAScript 5** native function implementations that we hope to use
536 // are declared here.
537 var
538 nativeForEach = ArrayProto.forEach,
539 nativeMap = ArrayProto.map,
540 nativeReduce = ArrayProto.reduce,
541 nativeReduceRight = ArrayProto.reduceRight,
542 nativeFilter = ArrayProto.filter,
543 nativeEvery = ArrayProto.every,
544 nativeSome = ArrayProto.some,
545 nativeIndexOf = ArrayProto.indexOf,
546 nativeLastIndexOf = ArrayProto.lastIndexOf,
547 nativeIsArray = Array.isArray,
548 nativeKeys = Object.keys,
549 nativeBind = FuncProto.bind;
550
551 // Create a safe reference to the Underscore object for use below.
552 var _ = function(obj) { return new wrapper(obj); };
553
554 // Export the Underscore object for **CommonJS**, with backwards-compatibility
555 // for the old `require()` API. If we're not in CommonJS, add `_` to the
556 // global object.
557 if (typeof module !== 'undefined' && module.exports) {
558 module.exports = _;
559 _._ = _;
560 } else {
561 // Exported as a string, for Closure Compiler "advanced" mode.
562 root['_'] = _;
563 }
564
565 // Current version.
566 _.VERSION = '1.1.7';
567
568 // Collection Functions
569 // --------------------
570
571 // The cornerstone, an `each` implementation, aka `forEach`.
572 // Handles objects with the built-in `forEach`, arrays, and raw objects.
573 // Delegates to **ECMAScript 5**'s native `forEach` if available.
574 var each = _.each = _.forEach = function(obj, iterator, context) {
575 if (obj == null) return;
576 if (nativeForEach && obj.forEach === nativeForEach) {
577 obj.forEach(iterator, context);
578 } else if (obj.length === +obj.length) {
579 for (var i = 0, l = obj.length; i < l; i++) {
580 if (i in obj && iterator.call(context, obj[i], i, obj) === breaker) return;
581 }
582 } else {
583 for (var key in obj) {
584 if (hasOwnProperty.call(obj, key)) {
585 if (iterator.call(context, obj[key], key, obj) === breaker) return;
586 }
587 }
588 }
589 };
590
591 // Return the results of applying the iterator to each element.
592 // Delegates to **ECMAScript 5**'s native `map` if available.
593 _.map = function(obj, iterator, context) {
594 var results = [];
595 if (obj == null) return results;
596 if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
597 each(obj, function(value, index, list) {
598 results[results.length] = iterator.call(context, value, index, list);
599 });
600 return results;
601 };
602
603 // **Reduce** builds up a single result from a list of values, aka `inject`,
604 // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
605 _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
606 var initial = memo !== void 0;
607 if (obj == null) obj = [];
608 if (nativeReduce && obj.reduce === nativeReduce) {
609 if (context) iterator = _.bind(iterator, context);
610 return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
611 }
612 each(obj, function(value, index, list) {
613 if (!initial) {
614 memo = value;
615 initial = true;
616 } else {
617 memo = iterator.call(context, memo, value, index, list);
618 }
619 });
620 if (!initial) throw new TypeError("Reduce of empty array with no initial value");
621 return memo;
622 };
623
624 // The right-associative version of reduce, also known as `foldr`.
625 // Delegates to **ECMAScript 5**'s native `reduceRight` if available.
626 _.reduceRight = _.foldr = function(obj, iterator, memo, context) {
627 if (obj == null) obj = [];
628 if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
629 if (context) iterator = _.bind(iterator, context);
630 return memo !== void 0 ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
631 }
632 var reversed = (_.isArray(obj) ? obj.slice() : _.toArray(obj)).reverse();
633 return _.reduce(reversed, iterator, memo, context);
634 };
635
636 // Return the first value which passes a truth test. Aliased as `detect`.
637 _.find = _.detect = function(obj, iterator, context) {
638 var result;
639 any(obj, function(value, index, list) {
640 if (iterator.call(context, value, index, list)) {
641 result = value;
642 return true;
643 }
644 });
645 return result;
646 };
647
648 // Return all the elements that pass a truth test.
649 // Delegates to **ECMAScript 5**'s native `filter` if available.
650 // Aliased as `select`.
651 _.filter = _.select = function(obj, iterator, context) {
652 var results = [];
653 if (obj == null) return results;
654 if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);
655 each(obj, function(value, index, list) {
656 if (iterator.call(context, value, index, list)) results[results.length] = value;
657 });
658 return results;
659 };
660
661 // Return all the elements for which a truth test fails.
662 _.reject = function(obj, iterator, context) {
663 var results = [];
664 if (obj == null) return results;
665 each(obj, function(value, index, list) {
666 if (!iterator.call(context, value, index, list)) results[results.length] = value;
667 });
668 return results;
669 };
670
671 // Determine whether all of the elements match a truth test.
672 // Delegates to **ECMAScript 5**'s native `every` if available.
673 // Aliased as `all`.
674 _.every = _.all = function(obj, iterator, context) {
675 var result = true;
676 if (obj == null) return result;
677 if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);
678 each(obj, function(value, index, list) {
679 if (!(result = result && iterator.call(context, value, index, list))) return breaker;
680 });
681 return result;
682 };
683
684 // Determine if at least one element in the object matches a truth test.
685 // Delegates to **ECMAScript 5**'s native `some` if available.
686 // Aliased as `any`.
687 var any = _.some = _.any = function(obj, iterator, context) {
688 iterator = iterator || _.identity;
689 var result = false;
690 if (obj == null) return result;
691 if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
692 each(obj, function(value, index, list) {
693 if (result |= iterator.call(context, value, index, list)) return breaker;
694 });
695 return !!result;
696 };
697
698 // Determine if a given value is included in the array or object using `===`.
699 // Aliased as `contains`.
700 _.include = _.contains = function(obj, target) {
701 var found = false;
702 if (obj == null) return found;
703 if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
704 any(obj, function(value) {
705 if (found = value === target) return true;
706 });
707 return found;
708 };
709
710 // Invoke a method (with arguments) on every item in a collection.
711 _.invoke = function(obj, method) {
712 var args = slice.call(arguments, 2);
713 return _.map(obj, function(value) {
714 return (method.call ? method || value : value[method]).apply(value, args);
715 });
716 };
717
718 // Convenience version of a common use case of `map`: fetching a property.
719 _.pluck = function(obj, key) {
720 return _.map(obj, function(value){ return value[key]; });
721 };
722
723 // Return the maximum element or (element-based computation).
724 _.max = function(obj, iterator, context) {
725 if (!iterator && _.isArray(obj)) return Math.max.apply(Math, obj);
726 var result = {computed : -Infinity};
727 each(obj, function(value, index, list) {
728 var computed = iterator ? iterator.call(context, value, index, list) : value;
729 computed >= result.computed && (result = {value : value, computed : computed});
730 });
731 return result.value;
732 };
733
734 // Return the minimum element (or element-based computation).
735 _.min = function(obj, iterator, context) {
736 if (!iterator && _.isArray(obj)) return Math.min.apply(Math, obj);
737 var result = {computed : Infinity};
738 each(obj, function(value, index, list) {
739 var computed = iterator ? iterator.call(context, value, index, list) : value;
740 computed < result.computed && (result = {value : value, computed : computed});
741 });
742 return result.value;
743 };
744
745 // Sort the object's values by a criterion produced by an iterator.
746 _.sortBy = function(obj, iterator, context) {
747 return _.pluck(_.map(obj, function(value, index, list) {
748 return {
749 value : value,
750 criteria : iterator.call(context, value, index, list)
751 };
752 }).sort(function(left, right) {
753 var a = left.criteria, b = right.criteria;
754 return a < b ? -1 : a > b ? 1 : 0;
755 }), 'value');
756 };
757
758 // Groups the object's values by a criterion produced by an iterator
759 _.groupBy = function(obj, iterator) {
760 var result = {};
761 each(obj, function(value, index) {
762 var key = iterator(value, index);
763 (result[key] || (result[key] = [])).push(value);
764 });
765 return result;
766 };
767
768 // Use a comparator function to figure out at what index an object should
769 // be inserted so as to maintain order. Uses binary search.
770 _.sortedIndex = function(array, obj, iterator) {
771 iterator || (iterator = _.identity);
772 var low = 0, high = array.length;
773 while (low < high) {
774 var mid = (low + high) >> 1;
775 iterator(array[mid]) < iterator(obj) ? low = mid + 1 : high = mid;
776 }
777 return low;
778 };
779
780 // Safely convert anything iterable into a real, live array.
781 _.toArray = function(iterable) {
782 if (!iterable) return [];
783 if (iterable.toArray) return iterable.toArray();
784 if (_.isArray(iterable)) return slice.call(iterable);
785 if (_.isArguments(iterable)) return slice.call(iterable);
786 return _.values(iterable);
787 };
788
789 // Return the number of elements in an object.
790 _.size = function(obj) {
791 return _.toArray(obj).length;
792 };
793
794 // Array Functions
795 // ---------------
796
797 // Get the first element of an array. Passing **n** will return the first N
798 // values in the array. Aliased as `head`. The **guard** check allows it to work
799 // with `_.map`.
800 _.first = _.head = function(array, n, guard) {
801 return (n != null) && !guard ? slice.call(array, 0, n) : array[0];
802 };
803
804 // Returns everything but the first entry of the array. Aliased as `tail`.
805 // Especially useful on the arguments object. Passing an **index** will return
806 // the rest of the values in the array from that index onward. The **guard**
807 // check allows it to work with `_.map`.
808 _.rest = _.tail = function(array, index, guard) {
809 return slice.call(array, (index == null) || guard ? 1 : index);
810 };
811
812 // Get the last element of an array.
813 _.last = function(array) {
814 return array[array.length - 1];
815 };
816
817 // Trim out all falsy values from an array.
818 _.compact = function(array) {
819 return _.filter(array, function(value){ return !!value; });
820 };
821
822 // Return a completely flattened version of an array.
823 _.flatten = function(array) {
824 return _.reduce(array, function(memo, value) {
825 if (_.isArray(value)) return memo.concat(_.flatten(value));
826 memo[memo.length] = value;
827 return memo;
828 }, []);
829 };
830
831 // Return a version of the array that does not contain the specified value(s).
832 _.without = function(array) {
833 return _.difference(array, slice.call(arguments, 1));
834 };
835
836 // Produce a duplicate-free version of the array. If the array has already
837 // been sorted, you have the option of using a faster algorithm.
838 // Aliased as `unique`.
839 _.uniq = _.unique = function(array, isSorted) {
840 return _.reduce(array, function(memo, el, i) {
841 if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) memo[memo.length] = el;
842 return memo;
843 }, []);
844 };
845
846 // Produce an array that contains the union: each distinct element from all of
847 // the passed-in arrays.
848 _.union = function() {
849 return _.uniq(_.flatten(arguments));
850 };
851
852 // Produce an array that contains every item shared between all the
853 // passed-in arrays. (Aliased as "intersect" for back-compat.)
854 _.intersection = _.intersect = function(array) {
855 var rest = slice.call(arguments, 1);
856 return _.filter(_.uniq(array), function(item) {
857 return _.every(rest, function(other) {
858 return _.indexOf(other, item) >= 0;
859 });
860 });
861 };
862
863 // Take the difference between one array and another.
864 // Only the elements present in just the first array will remain.
865 _.difference = function(array, other) {
866 return _.filter(array, function(value){ return !_.include(other, value); });
867 };
868
869 // Zip together multiple lists into a single array -- elements that share
870 // an index go together.
871 _.zip = function() {
872 var args = slice.call(arguments);
873 var length = _.max(_.pluck(args, 'length'));
874 var results = new Array(length);
875 for (var i = 0; i < length; i++) results[i] = _.pluck(args, "" + i);
876 return results;
877 };
878
879 // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),
880 // we need this function. Return the position of the first occurrence of an
881 // item in an array, or -1 if the item is not included in the array.
882 // Delegates to **ECMAScript 5**'s native `indexOf` if available.
883 // If the array is large and already in sort order, pass `true`
884 // for **isSorted** to use binary search.
885 _.indexOf = function(array, item, isSorted) {
886 if (array == null) return -1;
887 var i, l;
888 if (isSorted) {
889 i = _.sortedIndex(array, item);
890 return array[i] === item ? i : -1;
891 }
892 if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item);
893 for (i = 0, l = array.length; i < l; i++) if (array[i] === item) return i;
894 return -1;
895 };
896
897
898 // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
899 _.lastIndexOf = function(array, item) {
900 if (array == null) return -1;
901 if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) return array.lastIndexOf(item);
902 var i = array.length;
903 while (i--) if (array[i] === item) return i;
904 return -1;
905 };
906
907 // Generate an integer Array containing an arithmetic progression. A port of
908 // the native Python `range()` function. See
909 // [the Python documentation](http://docs.python.org/library/functions.html#range).
910 _.range = function(start, stop, step) {
911 if (arguments.length <= 1) {
912 stop = start || 0;
913 start = 0;
914 }
915 step = arguments[2] || 1;
916
917 var len = Math.max(Math.ceil((stop - start) / step), 0);
918 var idx = 0;
919 var range = new Array(len);
920
921 while(idx < len) {
922 range[idx++] = start;
923 start += step;
924 }
925
926 return range;
927 };
928
929 // Function (ahem) Functions
930 // ------------------
931
932 // Create a function bound to a given object (assigning `this`, and arguments,
933 // optionally). Binding with arguments is also known as `curry`.
934 // Delegates to **ECMAScript 5**'s native `Function.bind` if available.
935 // We check for `func.bind` first, to fail fast when `func` is undefined.
936 _.bind = function(func, obj) {
937 if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
938 var args = slice.call(arguments, 2);
939 return function() {
940 return func.apply(obj, args.concat(slice.call(arguments)));
941 };
942 };
943
944 // Bind all of an object's methods to that object. Useful for ensuring that
945 // all callbacks defined on an object belong to it.
946 _.bindAll = function(obj) {
947 var funcs = slice.call(arguments, 1);
948 if (funcs.length == 0) funcs = _.functions(obj);
949 each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
950 return obj;
951 };
952
953 // Memoize an expensive function by storing its results.
954 _.memoize = function(func, hasher) {
955 var memo = {};
956 hasher || (hasher = _.identity);
957 return function() {
958 var key = hasher.apply(this, arguments);
959 return hasOwnProperty.call(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));
960 };
961 };
962
963 // Delays a function for the given number of milliseconds, and then calls
964 // it with the arguments supplied.
965 _.delay = function(func, wait) {
966 var args = slice.call(arguments, 2);
967 return setTimeout(function(){ return func.apply(func, args); }, wait);
968 };
969
970 // Defers a function, scheduling it to run after the current call stack has
971 // cleared.
972 _.defer = function(func) {
973 return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
974 };
975
976 // Internal function used to implement `_.throttle` and `_.debounce`.
977 var limit = function(func, wait, debounce) {
978 var timeout;
979 return function() {
980 var context = this, args = arguments;
981 var throttler = function() {
982 timeout = null;
983 func.apply(context, args);
984 };
985 if (debounce) clearTimeout(timeout);
986 if (debounce || !timeout) timeout = setTimeout(throttler, wait);
987 };
988 };
989
990 // Returns a function, that, when invoked, will only be triggered at most once
991 // during a given window of time.
992 _.throttle = function(func, wait) {
993 return limit(func, wait, false);
994 };
995
996 // Returns a function, that, as long as it continues to be invoked, will not
997 // be triggered. The function will be called after it stops being called for
998 // N milliseconds.
999 _.debounce = function(func, wait) {
1000 return limit(func, wait, true);
1001 };
1002
1003 // Returns a function that will be executed at most one time, no matter how
1004 // often you call it. Useful for lazy initialization.
1005 _.once = function(func) {
1006 var ran = false, memo;
1007 return function() {
1008 if (ran) return memo;
1009 ran = true;
1010 return memo = func.apply(this, arguments);
1011 };
1012 };
1013
1014 // Returns the first function passed as an argument to the second,
1015 // allowing you to adjust arguments, run code before and after, and
1016 // conditionally execute the original function.
1017 _.wrap = function(func, wrapper) {
1018 return function() {
1019 var args = [func].concat(slice.call(arguments));
1020 return wrapper.apply(this, args);
1021 };
1022 };
1023
1024 // Returns a function that is the composition of a list of functions, each
1025 // consuming the return value of the function that follows.
1026 _.compose = function() {
1027 var funcs = slice.call(arguments);
1028 return function() {
1029 var args = slice.call(arguments);
1030 for (var i = funcs.length - 1; i >= 0; i--) {
1031 args = [funcs[i].apply(this, args)];
1032 }
1033 return args[0];
1034 };
1035 };
1036
1037 // Returns a function that will only be executed after being called N times.
1038 _.after = function(times, func) {
1039 return function() {
1040 if (--times < 1) { return func.apply(this, arguments); }
1041 };
1042 };
1043
1044
1045 // Object Functions
1046 // ----------------
1047
1048 // Retrieve the names of an object's properties.
1049 // Delegates to **ECMAScript 5**'s native `Object.keys`
1050 _.keys = nativeKeys || function(obj) {
1051 if (obj !== Object(obj)) throw new TypeError('Invalid object');
1052 var keys = [];
1053 for (var key in obj) if (hasOwnProperty.call(obj, key)) keys[keys.length] = key;
1054 return keys;
1055 };
1056
1057 // Retrieve the values of an object's properties.
1058 _.values = function(obj) {
1059 return _.map(obj, _.identity);
1060 };
1061
1062 // Return a sorted list of the function names available on the object.
1063 // Aliased as `methods`
1064 _.functions = _.methods = function(obj) {
1065 var names = [];
1066 for (var key in obj) {
1067 if (_.isFunction(obj[key])) names.push(key);
1068 }
1069 return names.sort();
1070 };
1071
1072 // Extend a given object with all the properties in passed-in object(s).
1073 _.extend = function(obj) {
1074 each(slice.call(arguments, 1), function(source) {
1075 for (var prop in source) {
1076 if (source[prop] !== void 0) obj[prop] = source[prop];
1077 }
1078 });
1079 return obj;
1080 };
1081
1082 // Fill in a given object with default properties.
1083 _.defaults = function(obj) {
1084 each(slice.call(arguments, 1), function(source) {
1085 for (var prop in source) {
1086 if (obj[prop] == null) obj[prop] = source[prop];
1087 }
1088 });
1089 return obj;
1090 };
1091
1092 // Create a (shallow-cloned) duplicate of an object.
1093 _.clone = function(obj) {
1094 return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
1095 };
1096
1097 // Invokes interceptor with the obj, and then returns obj.
1098 // The primary purpose of this method is to "tap into" a method chain, in
1099 // order to perform operations on intermediate results within the chain.
1100 _.tap = function(obj, interceptor) {
1101 interceptor(obj);
1102 return obj;
The diff has been truncated for viewing.