~ubuntu-branches/ubuntu/vivid/zoneminder/vivid-proposed

« back to all changes in this revision

Viewing changes to web/tools/mootools/mootools.js

  • Committer: Bazaar Package Importer
  • Author(s): Peter Howard
  • Date: 2009-11-14 15:02:10 UTC
  • mfrom: (4.1.4 sid)
  • Revision ID: james.westby@ubuntu.com-20091114150210-d8721h9wm90cbaog
Tags: 1.24.2-2
* Remove custom perl parth from zmpkg.pl, fix location of manpages.
(closes: #551746, #553092)
* Fix GCC4.4 bug
(closes: #531717)
* Fix potential bug in postinst script

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
Script: Core.js
3
 
        Mootools - My Object Oriented javascript.
4
 
 
5
 
License:
6
 
        MIT-style license.
7
 
 
8
 
MooTools Copyright:
9
 
        copyright (c) 2007 Valerio Proietti, <http://mad4milk.net>
10
 
 
11
 
MooTools Credits:
12
 
        - Class is slightly based on Base.js <http://dean.edwards.name/weblog/2006/03/base/> (c) 2006 Dean Edwards, License <http://creativecommons.org/licenses/LGPL/2.1/>
13
 
        - Some functions are inspired by those found in prototype.js <http://prototype.conio.net/> (c) 2005 Sam Stephenson sam [at] conio [dot] net, MIT-style license
14
 
        - Documentation by Aaron Newton (aaron.newton [at] cnet [dot] com) and Valerio Proietti.
15
 
*/
16
 
 
17
 
var MooTools = {
18
 
        version: '1.11'
19
 
};
20
 
 
21
 
/* Section: Core Functions */
22
 
 
23
 
/*
24
 
Function: $defined
25
 
        Returns true if the passed in value/object is defined, that means is not null or undefined.
26
 
 
27
 
Arguments:
28
 
        obj - object to inspect
29
 
*/
30
 
 
31
 
function $defined(obj){
32
 
        return (obj != undefined);
33
 
};
34
 
 
35
 
/*
36
 
Function: $type
37
 
        Returns the type of object that matches the element passed in.
38
 
 
39
 
Arguments:
40
 
        obj - the object to inspect.
41
 
 
42
 
Example:
43
 
        >var myString = 'hello';
44
 
        >$type(myString); //returns "string"
45
 
 
46
 
Returns:
47
 
        'element' - if obj is a DOM element node
48
 
        'textnode' - if obj is a DOM text node
49
 
        'whitespace' - if obj is a DOM whitespace node
50
 
        'arguments' - if obj is an arguments object
51
 
        'object' - if obj is an object
52
 
        'string' - if obj is a string
53
 
        'number' - if obj is a number
54
 
        'boolean' - if obj is a boolean
55
 
        'function' - if obj is a function
56
 
        'regexp' - if obj is a regular expression
57
 
        'class' - if obj is a Class. (created with new Class, or the extend of another class).
58
 
        'collection' - if obj is a native htmlelements collection, such as childNodes, getElementsByTagName .. etc.
59
 
        false - (boolean) if the object is not defined or none of the above.
60
 
*/
61
 
 
62
 
function $type(obj){
63
 
        if (!$defined(obj)) return false;
64
 
        if (obj.htmlElement) return 'element';
65
 
        var type = typeof obj;
66
 
        if (type == 'object' && obj.nodeName){
67
 
                switch(obj.nodeType){
68
 
                        case 1: return 'element';
69
 
                        case 3: return (/\S/).test(obj.nodeValue) ? 'textnode' : 'whitespace';
70
 
                }
71
 
        }
72
 
        if (type == 'object' || type == 'function'){
73
 
                switch(obj.constructor){
74
 
                        case Array: return 'array';
75
 
                        case RegExp: return 'regexp';
76
 
                        case Class: return 'class';
77
 
                }
78
 
                if (typeof obj.length == 'number'){
79
 
                        if (obj.item) return 'collection';
80
 
                        if (obj.callee) return 'arguments';
81
 
                }
82
 
        }
83
 
        return type;
84
 
};
85
 
 
86
 
/*
87
 
Function: $merge
88
 
        merges a number of objects recursively without referencing them or their sub-objects.
89
 
 
90
 
Arguments:
91
 
        any number of objects.
92
 
 
93
 
Example:
94
 
        >var mergedObj = $merge(obj1, obj2, obj3);
95
 
        >//obj1, obj2, and obj3 are unaltered
96
 
*/
97
 
 
98
 
function $merge(){
99
 
        var mix = {};
100
 
        for (var i = 0; i < arguments.length; i++){
101
 
                for (var property in arguments[i]){
102
 
                        var ap = arguments[i][property];
103
 
                        var mp = mix[property];
104
 
                        if (mp && $type(ap) == 'object' && $type(mp) == 'object') mix[property] = $merge(mp, ap);
105
 
                        else mix[property] = ap;
106
 
                }
107
 
        }
108
 
        return mix;
109
 
};
110
 
 
111
 
/*
112
 
Function: $extend
113
 
        Copies all the properties from the second passed object to the first passed Object.
114
 
        If you do myWhatever.extend = $extend the first parameter will become myWhatever, and your extend function will only need one parameter.
115
 
 
116
 
Example:
117
 
        (start code)
118
 
        var firstOb = {
119
 
                'name': 'John',
120
 
                'lastName': 'Doe'
121
 
        };
122
 
        var secondOb = {
123
 
                'age': '20',
124
 
                'sex': 'male',
125
 
                'lastName': 'Dorian'
126
 
        };
127
 
        $extend(firstOb, secondOb);
128
 
        //firstOb will become:
129
 
        {
130
 
                'name': 'John',
131
 
                'lastName': 'Dorian',
132
 
                'age': '20',
133
 
                'sex': 'male'
134
 
        };
135
 
        (end)
136
 
 
137
 
Returns:
138
 
        The first object, extended.
139
 
*/
140
 
 
141
 
var $extend = function(){
142
 
        var args = arguments;
143
 
        if (!args[1]) args = [this, args[0]];
144
 
        for (var property in args[1]) args[0][property] = args[1][property];
145
 
        return args[0];
146
 
};
147
 
 
148
 
/*
149
 
Function: $native
150
 
        Will add a .extend method to the objects passed as a parameter, but the property passed in will be copied to the object's prototype only if non previously existent.
151
 
        Its handy if you dont want the .extend method of an object to overwrite existing methods.
152
 
        Used automatically in MooTools to implement Array/String/Function/Number methods to browser that dont support them whitout manual checking.
153
 
 
154
 
Arguments:
155
 
        a number of classes/native javascript objects
156
 
 
157
 
*/
158
 
 
159
 
var $native = function(){
160
 
        for (var i = 0, l = arguments.length; i < l; i++){
161
 
                arguments[i].extend = function(props){
162
 
                        for (var prop in props){
163
 
                                if (!this.prototype[prop]) this.prototype[prop] = props[prop];
164
 
                                if (!this[prop]) this[prop] = $native.generic(prop);
165
 
                        }
166
 
                };
167
 
        }
168
 
};
169
 
 
170
 
$native.generic = function(prop){
171
 
        return function(bind){
172
 
                return this.prototype[prop].apply(bind, Array.prototype.slice.call(arguments, 1));
173
 
        };
174
 
};
175
 
 
176
 
$native(Function, Array, String, Number);
177
 
 
178
 
/*
179
 
Function: $chk
180
 
        Returns true if the passed in value/object exists or is 0, otherwise returns false.
181
 
        Useful to accept zeroes.
182
 
 
183
 
Arguments:
184
 
        obj - object to inspect
185
 
*/
186
 
 
187
 
function $chk(obj){
188
 
        return !!(obj || obj === 0);
189
 
};
190
 
 
191
 
/*
192
 
Function: $pick
193
 
        Returns the first object if defined, otherwise returns the second.
194
 
 
195
 
Arguments:
196
 
        obj - object to test
197
 
        picked - the default to return
198
 
 
199
 
Example:
200
 
        (start code)
201
 
                function say(msg){
202
 
                        alert($pick(msg, 'no meessage supplied'));
203
 
                }
204
 
        (end)
205
 
*/
206
 
 
207
 
function $pick(obj, picked){
208
 
        return $defined(obj) ? obj : picked;
209
 
};
210
 
 
211
 
/*
212
 
Function: $random
213
 
        Returns a random integer number between the two passed in values.
214
 
 
215
 
Arguments:
216
 
        min - integer, the minimum value (inclusive).
217
 
        max - integer, the maximum value (inclusive).
218
 
 
219
 
Returns:
220
 
        a random integer between min and max.
221
 
*/
222
 
 
223
 
function $random(min, max){
224
 
        return Math.floor(Math.random() * (max - min + 1) + min);
225
 
};
226
 
 
227
 
/*
228
 
Function: $time
229
 
        Returns the current timestamp
230
 
 
231
 
Returns:
232
 
        a timestamp integer.
233
 
*/
234
 
 
235
 
function $time(){
236
 
        return new Date().getTime();
237
 
};
238
 
 
239
 
/*
240
 
Function: $clear
241
 
        clears a timeout or an Interval.
242
 
 
243
 
Returns:
244
 
        null
245
 
 
246
 
Arguments:
247
 
        timer - the setInterval or setTimeout to clear.
248
 
 
249
 
Example:
250
 
        >var myTimer = myFunction.delay(5000); //wait 5 seconds and execute my function.
251
 
        >myTimer = $clear(myTimer); //nevermind
252
 
 
253
 
See also:
254
 
        <Function.delay>, <Function.periodical>
255
 
*/
256
 
 
257
 
function $clear(timer){
258
 
        clearTimeout(timer);
259
 
        clearInterval(timer);
260
 
        return null;
261
 
};
262
 
 
263
 
/*
264
 
Class: Abstract
265
 
        Abstract class, to be used as singleton. Will add .extend to any object
266
 
 
267
 
Arguments:
268
 
        an object
269
 
 
270
 
Returns:
271
 
        the object with an .extend property, equivalent to <$extend>.
272
 
*/
273
 
 
274
 
var Abstract = function(obj){
275
 
        obj = obj || {};
276
 
        obj.extend = $extend;
277
 
        return obj;
278
 
};
279
 
 
280
 
//window, document
281
 
 
282
 
var Window = new Abstract(window);
283
 
var Document = new Abstract(document);
284
 
document.head = document.getElementsByTagName('head')[0];
285
 
 
286
 
/*
287
 
Class: window
288
 
        Some properties are attached to the window object by the browser detection.
289
 
        
290
 
Note:
291
 
        browser detection is entirely object-based. We dont sniff.
292
 
 
293
 
Properties:
294
 
        window.ie - will be set to true if the current browser is internet explorer (any).
295
 
        window.ie6 - will be set to true if the current browser is internet explorer 6.
296
 
        window.ie7 - will be set to true if the current browser is internet explorer 7.
297
 
        window.gecko - will be set to true if the current browser is Mozilla/Gecko.
298
 
        window.webkit - will be set to true if the current browser is Safari/Konqueror.
299
 
        window.webkit419 - will be set to true if the current browser is Safari2 / webkit till version 419.
300
 
        window.webkit420 - will be set to true if the current browser is Safari3 (Webkit SVN Build) / webkit over version 419.
301
 
        window.opera - is set to true by opera itself.
302
 
*/
303
 
 
304
 
window.xpath = !!(document.evaluate);
305
 
if (window.ActiveXObject) window.ie = window[window.XMLHttpRequest ? 'ie7' : 'ie6'] = true;
306
 
else if (document.childNodes && !document.all && !navigator.taintEnabled) window.webkit = window[window.xpath ? 'webkit420' : 'webkit419'] = true;
307
 
else if (document.getBoxObjectFor != null) window.gecko = true;
308
 
 
309
 
/*compatibility*/
310
 
 
311
 
window.khtml = window.webkit;
312
 
 
313
 
Object.extend = $extend;
314
 
 
315
 
/*end compatibility*/
316
 
 
317
 
//htmlelement
318
 
 
319
 
if (typeof HTMLElement == 'undefined'){
320
 
        var HTMLElement = function(){};
321
 
        if (window.webkit) document.createElement("iframe"); //fixes safari
322
 
        HTMLElement.prototype = (window.webkit) ? window["[[DOMElement.prototype]]"] : {};
323
 
}
324
 
HTMLElement.prototype.htmlElement = function(){};
325
 
 
326
 
//enables background image cache for internet explorer 6
327
 
 
328
 
if (window.ie6) try {document.execCommand("BackgroundImageCache", false, true);} catch(e){};
329
 
 
330
 
/*
331
 
Script: Class.js
332
 
        Contains the Class Function, aims to ease the creation of reusable Classes.
333
 
 
334
 
License:
335
 
        MIT-style license.
336
 
*/
337
 
 
338
 
/*
339
 
Class: Class
340
 
        The base class object of the <http://mootools.net> framework.
341
 
        Creates a new class, its initialize method will fire upon class instantiation.
342
 
        Initialize wont fire on instantiation when you pass *null*.
343
 
 
344
 
Arguments:
345
 
        properties - the collection of properties that apply to the class.
346
 
 
347
 
Example:
348
 
        (start code)
349
 
        var Cat = new Class({
350
 
                initialize: function(name){
351
 
                        this.name = name;
352
 
                }
353
 
        });
354
 
        var myCat = new Cat('Micia');
355
 
        alert(myCat.name); //alerts 'Micia'
356
 
        (end)
357
 
*/
358
 
 
359
 
var Class = function(properties){
360
 
        var klass = function(){
361
 
                return (arguments[0] !== null && this.initialize && $type(this.initialize) == 'function') ? this.initialize.apply(this, arguments) : this;
362
 
        };
363
 
        $extend(klass, this);
364
 
        klass.prototype = properties;
365
 
        klass.constructor = Class;
366
 
        return klass;
367
 
};
368
 
 
369
 
/*
370
 
Property: empty
371
 
        Returns an empty function
372
 
*/
373
 
 
374
 
Class.empty = function(){};
375
 
 
376
 
Class.prototype = {
377
 
 
378
 
        /*
379
 
        Property: extend
380
 
                Returns the copy of the Class extended with the passed in properties.
381
 
 
382
 
        Arguments:
383
 
                properties - the properties to add to the base class in this new Class.
384
 
 
385
 
        Example:
386
 
                (start code)
387
 
                var Animal = new Class({
388
 
                        initialize: function(age){
389
 
                                this.age = age;
390
 
                        }
391
 
                });
392
 
                var Cat = Animal.extend({
393
 
                        initialize: function(name, age){
394
 
                                this.parent(age); //will call the previous initialize;
395
 
                                this.name = name;
396
 
                        }
397
 
                });
398
 
                var myCat = new Cat('Micia', 20);
399
 
                alert(myCat.name); //alerts 'Micia'
400
 
                alert(myCat.age); //alerts 20
401
 
                (end)
402
 
        */
403
 
 
404
 
        extend: function(properties){
405
 
                var proto = new this(null);
406
 
                for (var property in properties){
407
 
                        var pp = proto[property];
408
 
                        proto[property] = Class.Merge(pp, properties[property]);
409
 
                }
410
 
                return new Class(proto);
411
 
        },
412
 
 
413
 
        /*
414
 
        Property: implement
415
 
                Implements the passed in properties to the base Class prototypes, altering the base class, unlike <Class.extend>.
416
 
 
417
 
        Arguments:
418
 
                properties - the properties to add to the base class.
419
 
 
420
 
        Example:
421
 
                (start code)
422
 
                var Animal = new Class({
423
 
                        initialize: function(age){
424
 
                                this.age = age;
425
 
                        }
426
 
                });
427
 
                Animal.implement({
428
 
                        setName: function(name){
429
 
                                this.name = name
430
 
                        }
431
 
                });
432
 
                var myAnimal = new Animal(20);
433
 
                myAnimal.setName('Micia');
434
 
                alert(myAnimal.name); //alerts 'Micia'
435
 
                (end)
436
 
        */
437
 
 
438
 
        implement: function(){
439
 
                for (var i = 0, l = arguments.length; i < l; i++) $extend(this.prototype, arguments[i]);
440
 
        }
441
 
 
442
 
};
443
 
 
444
 
//internal
445
 
 
446
 
Class.Merge = function(previous, current){
447
 
        if (previous && previous != current){
448
 
                var type = $type(current);
449
 
                if (type != $type(previous)) return current;
450
 
                switch(type){
451
 
                        case 'function':
452
 
                                var merged = function(){
453
 
                                        this.parent = arguments.callee.parent;
454
 
                                        return current.apply(this, arguments);
455
 
                                };
456
 
                                merged.parent = previous;
457
 
                                return merged;
458
 
                        case 'object': return $merge(previous, current);
459
 
                }
460
 
        }
461
 
        return current;
462
 
};
463
 
 
464
 
/*
465
 
Script: Class.Extras.js
466
 
        Contains common implementations for custom classes. In Mootools is implemented in <Ajax>, <XHR> and <Fx.Base> and many more.
467
 
 
468
 
License:
469
 
        MIT-style license.
470
 
*/
471
 
 
472
 
/*
473
 
Class: Chain
474
 
        An "Utility" Class. Its methods can be implemented with <Class.implement> into any <Class>.
475
 
        Currently implemented in <Fx.Base>, <XHR> and <Ajax>. In <Fx.Base> for example, is used to execute a list of function, one after another, once the effect is completed.
476
 
        The functions will not be fired all togheter, but one every completion, to create custom complex animations.
477
 
 
478
 
Example:
479
 
        (start code)
480
 
        var myFx = new Fx.Style('element', 'opacity');
481
 
 
482
 
        myFx.start(1,0).chain(function(){
483
 
                myFx.start(0,1);
484
 
        }).chain(function(){
485
 
                myFx.start(1,0);
486
 
        }).chain(function(){
487
 
                myFx.start(0,1);
488
 
        });
489
 
        //the element will appear and disappear three times
490
 
        (end)
491
 
*/
492
 
 
493
 
var Chain = new Class({
494
 
 
495
 
        /*
496
 
        Property: chain
497
 
                adds a function to the Chain instance stack.
498
 
 
499
 
        Arguments:
500
 
                fn - the function to append.
501
 
        */
502
 
 
503
 
        chain: function(fn){
504
 
                this.chains = this.chains || [];
505
 
                this.chains.push(fn);
506
 
                return this;
507
 
        },
508
 
 
509
 
        /*
510
 
        Property: callChain
511
 
                Executes the first function of the Chain instance stack, then removes it. The first function will then become the second.
512
 
        */
513
 
 
514
 
        callChain: function(){
515
 
                if (this.chains && this.chains.length) this.chains.shift().delay(10, this);
516
 
        },
517
 
 
518
 
        /*
519
 
        Property: clearChain
520
 
                Clears the stack of a Chain instance.
521
 
        */
522
 
 
523
 
        clearChain: function(){
524
 
                this.chains = [];
525
 
        }
526
 
 
527
 
});
528
 
 
529
 
/*
530
 
Class: Events
531
 
        An "Utility" Class. Its methods can be implemented with <Class.implement> into any <Class>.
532
 
        In <Fx.Base> Class, for example, is used to give the possibility add any number of functions to the Effects events, like onComplete, onStart, onCancel.
533
 
        Events in a Class that implements <Events> can be either added as an option, or with addEvent. Never with .options.onEventName.
534
 
 
535
 
Example:
536
 
        (start code)
537
 
        var myFx = new Fx.Style('element', 'opacity').addEvent('onComplete', function(){
538
 
                alert('the effect is completed');
539
 
        }).addEvent('onComplete', function(){
540
 
                alert('I told you the effect is completed');
541
 
        });
542
 
 
543
 
        myFx.start(0,1);
544
 
        //upon completion it will display the 2 alerts, in order.
545
 
        (end)
546
 
 
547
 
Implementing:
548
 
        This class can be implemented into other classes to add the functionality to them.
549
 
        Goes well with the <Options> class.
550
 
 
551
 
Example:
552
 
        (start code)
553
 
        var Widget = new Class({
554
 
                initialize: function(){},
555
 
                finish: function(){
556
 
                        this.fireEvent('onComplete');
557
 
                }
558
 
        });
559
 
        Widget.implement(new Events);
560
 
        //later...
561
 
        var myWidget = new Widget();
562
 
        myWidget.addEvent('onComplete', myfunction);
563
 
        (end)
564
 
*/
565
 
 
566
 
var Events = new Class({
567
 
 
568
 
        /*
569
 
        Property: addEvent
570
 
                adds an event to the stack of events of the Class instance.
571
 
 
572
 
        Arguments:
573
 
                type - string; the event name (e.g. 'onComplete')
574
 
                fn - function to execute
575
 
        */
576
 
 
577
 
        addEvent: function(type, fn){
578
 
                if (fn != Class.empty){
579
 
                        this.$events = this.$events || {};
580
 
                        this.$events[type] = this.$events[type] || [];
581
 
                        this.$events[type].include(fn);
582
 
                }
583
 
                return this;
584
 
        },
585
 
 
586
 
        /*
587
 
        Property: fireEvent
588
 
                fires all events of the specified type in the Class instance.
589
 
 
590
 
        Arguments:
591
 
                type - string; the event name (e.g. 'onComplete')
592
 
                args - array or single object; arguments to pass to the function; if more than one argument, must be an array
593
 
                delay - (integer) delay (in ms) to wait to execute the event
594
 
 
595
 
        Example:
596
 
        (start code)
597
 
        var Widget = new Class({
598
 
                initialize: function(arg1, arg2){
599
 
                        ...
600
 
                        this.fireEvent("onInitialize", [arg1, arg2], 50);
601
 
                }
602
 
        });
603
 
        Widget.implement(new Events);
604
 
        (end)
605
 
        */
606
 
 
607
 
        fireEvent: function(type, args, delay){
608
 
                if (this.$events && this.$events[type]){
609
 
                        this.$events[type].each(function(fn){
610
 
                                fn.create({'bind': this, 'delay': delay, 'arguments': args})();
611
 
                        }, this);
612
 
                }
613
 
                return this;
614
 
        },
615
 
 
616
 
        /*
617
 
        Property: removeEvent
618
 
                removes an event from the stack of events of the Class instance.
619
 
 
620
 
        Arguments:
621
 
                type - string; the event name (e.g. 'onComplete')
622
 
                fn - function that was added
623
 
        */
624
 
 
625
 
        removeEvent: function(type, fn){
626
 
                if (this.$events && this.$events[type]) this.$events[type].remove(fn);
627
 
                return this;
628
 
        }
629
 
 
630
 
});
631
 
 
632
 
/*
633
 
Class: Options
634
 
        An "Utility" Class. Its methods can be implemented with <Class.implement> into any <Class>.
635
 
        Used to automate the options settings, also adding Class <Events> when the option begins with on.
636
 
 
637
 
        Example:
638
 
                (start code)
639
 
                var Widget = new Class({
640
 
                        options: {
641
 
                                color: '#fff',
642
 
                                size: {
643
 
                                        width: 100
644
 
                                        height: 100
645
 
                                }
646
 
                        },
647
 
                        initialize: function(options){
648
 
                                this.setOptions(options);
649
 
                        }
650
 
                });
651
 
                Widget.implement(new Options);
652
 
                //later...
653
 
                var myWidget = new Widget({
654
 
                        color: '#f00',
655
 
                        size: {
656
 
                                width: 200
657
 
                        }
658
 
                });
659
 
                //myWidget.options = {color: #f00, size: {width: 200, height: 100}}
660
 
                (end)
661
 
*/
662
 
 
663
 
var Options = new Class({
664
 
 
665
 
        /*
666
 
        Property: setOptions
667
 
                sets this.options
668
 
 
669
 
        Arguments:
670
 
                defaults - object; the default set of options
671
 
                options - object; the user entered options. can be empty too.
672
 
 
673
 
        Note:
674
 
                if your Class has <Events> implemented, every option beginning with on, followed by a capital letter (onComplete) becomes an Class instance event.
675
 
        */
676
 
 
677
 
        setOptions: function(){
678
 
                this.options = $merge.apply(null, [this.options].extend(arguments));
679
 
                if (this.addEvent){
680
 
                        for (var option in this.options){
681
 
                                if ($type(this.options[option] == 'function') && (/^on[A-Z]/).test(option)) this.addEvent(option, this.options[option]);
682
 
                        }
683
 
                }
684
 
                return this;
685
 
        }
686
 
 
687
 
});
688
 
 
689
 
/*
690
 
Script: Array.js
691
 
        Contains Array prototypes, <$A>, <$each>
692
 
 
693
 
License:
694
 
        MIT-style license.
695
 
*/
696
 
 
697
 
/*
698
 
Class: Array
699
 
        A collection of The Array Object prototype methods.
700
 
*/
701
 
 
702
 
//custom methods
703
 
 
704
 
Array.extend({
705
 
 
706
 
        /*
707
 
        Property: forEach
708
 
                Iterates through an array; This method is only available for browsers without native *forEach* support.
709
 
                For more info see <http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:forEach>
710
 
 
711
 
                *forEach* executes the provided function (callback) once for each element present in the array. callback is invoked only for indexes of the array which have assigned values; it is not invoked for indexes which have been deleted or which have never been assigned values.
712
 
 
713
 
        Arguments:
714
 
                fn - function to execute with each item in the array; passed the item and the index of that item in the array
715
 
                bind - the object to bind "this" to (see <Function.bind>)
716
 
 
717
 
        Example:
718
 
                >['apple','banana','lemon'].each(function(item, index){
719
 
                >       alert(index + " = " + item); //alerts "0 = apple" etc.
720
 
                >}, bindObj); //optional second arg for binding, not used here
721
 
        */
722
 
 
723
 
        forEach: function(fn, bind){
724
 
                for (var i = 0, j = this.length; i < j; i++) fn.call(bind, this[i], i, this);
725
 
        },
726
 
 
727
 
        /*
728
 
        Property: filter
729
 
                This method is provided only for browsers without native *filter* support.
730
 
                For more info see <http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:filter>
731
 
 
732
 
                *filter* calls a provided callback function once for each element in an array, and constructs a new array of all the values for which callback returns a true value. callback is invoked only for indexes of the array which have assigned values; it is not invoked for indexes which have been deleted or which have never been assigned values. Array elements which do not pass the callback test are simply skipped, and are not included in the new array.
733
 
 
734
 
        Arguments:
735
 
                fn - function to execute with each item in the array; passed the item and the index of that item in the array
736
 
                bind - the object to bind "this" to (see <Function.bind>)
737
 
 
738
 
        Example:
739
 
                >var biggerThanTwenty = [10,3,25,100].filter(function(item, index){
740
 
                > return item > 20;
741
 
                >});
742
 
                >//biggerThanTwenty = [25,100]
743
 
        */
744
 
 
745
 
        filter: function(fn, bind){
746
 
                var results = [];
747
 
                for (var i = 0, j = this.length; i < j; i++){
748
 
                        if (fn.call(bind, this[i], i, this)) results.push(this[i]);
749
 
                }
750
 
                return results;
751
 
        },
752
 
 
753
 
        /*
754
 
        Property: map
755
 
                This method is provided only for browsers without native *map* support.
756
 
                For more info see <http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:map>
757
 
 
758
 
                *map* calls a provided callback function once for each element in an array, in order, and constructs a new array from the results. callback is invoked only for indexes of the array which have assigned values; it is not invoked for indexes which have been deleted or which have never been assigned values.
759
 
 
760
 
        Arguments:
761
 
                fn - function to execute with each item in the array; passed the item and the index of that item in the array
762
 
                bind - the object to bind "this" to (see <Function.bind>)
763
 
 
764
 
        Example:
765
 
                >var timesTwo = [1,2,3].map(function(item, index){
766
 
                > return item*2;
767
 
                >});
768
 
                >//timesTwo = [2,4,6];
769
 
        */
770
 
 
771
 
        map: function(fn, bind){
772
 
                var results = [];
773
 
                for (var i = 0, j = this.length; i < j; i++) results[i] = fn.call(bind, this[i], i, this);
774
 
                return results;
775
 
        },
776
 
 
777
 
        /*
778
 
        Property: every
779
 
                This method is provided only for browsers without native *every* support.
780
 
                For more info see <http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:every>
781
 
 
782
 
                *every* executes the provided callback function once for each element present in the array until it finds one where callback returns a false value. If such an element is found, the every method immediately returns false. Otherwise, if callback returned a true value for all elements, every will return true. callback is invoked only for indexes of the array which have assigned values; it is not invoked for indexes which have been deleted or which have never been assigned values.
783
 
 
784
 
        Arguments:
785
 
                fn - function to execute with each item in the array; passed the item and the index of that item in the array
786
 
                bind - the object to bind "this" to (see <Function.bind>)
787
 
 
788
 
        Example:
789
 
                >var areAllBigEnough = [10,4,25,100].every(function(item, index){
790
 
                > return item > 20;
791
 
                >});
792
 
                >//areAllBigEnough = false
793
 
        */
794
 
 
795
 
        every: function(fn, bind){
796
 
                for (var i = 0, j = this.length; i < j; i++){
797
 
                        if (!fn.call(bind, this[i], i, this)) return false;
798
 
                }
799
 
                return true;
800
 
        },
801
 
 
802
 
        /*
803
 
        Property: some
804
 
                This method is provided only for browsers without native *some* support.
805
 
                For more info see <http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:some>
806
 
 
807
 
                *some* executes the callback function once for each element present in the array until it finds one where callback returns a true value. If such an element is found, some immediately returns true. Otherwise, some returns false. callback is invoked only for indexes of the array which have assigned values; it is not invoked for indexes which have been deleted or which have never been assigned values.
808
 
 
809
 
        Arguments:
810
 
                fn - function to execute with each item in the array; passed the item and the index of that item in the array
811
 
                bind - the object to bind "this" to (see <Function.bind>)
812
 
 
813
 
        Example:
814
 
                >var isAnyBigEnough = [10,4,25,100].some(function(item, index){
815
 
                > return item > 20;
816
 
                >});
817
 
                >//isAnyBigEnough = true
818
 
        */
819
 
 
820
 
        some: function(fn, bind){
821
 
                for (var i = 0, j = this.length; i < j; i++){
822
 
                        if (fn.call(bind, this[i], i, this)) return true;
823
 
                }
824
 
                return false;
825
 
        },
826
 
 
827
 
        /*
828
 
        Property: indexOf
829
 
                This method is provided only for browsers without native *indexOf* support.
830
 
                For more info see <http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:indexOf>
831
 
 
832
 
                *indexOf* compares a search element to elements of the Array using strict equality (the same method used by the ===, or triple-equals, operator).
833
 
 
834
 
        Arguments:
835
 
                item - any type of object; element to locate in the array
836
 
                from - integer; optional; the index of the array at which to begin the search (defaults to 0)
837
 
 
838
 
        Example:
839
 
                >['apple','lemon','banana'].indexOf('lemon'); //returns 1
840
 
                >['apple','lemon'].indexOf('banana'); //returns -1
841
 
        */
842
 
 
843
 
        indexOf: function(item, from){
844
 
                var len = this.length;
845
 
                for (var i = (from < 0) ? Math.max(0, len + from) : from || 0; i < len; i++){
846
 
                        if (this[i] === item) return i;
847
 
                }
848
 
                return -1;
849
 
        },
850
 
 
851
 
        /*
852
 
        Property: each
853
 
                Same as <Array.forEach>.
854
 
 
855
 
        Arguments:
856
 
                fn - function to execute with each item in the array; passed the item and the index of that item in the array
857
 
                bind - optional, the object that the "this" of the function will refer to.
858
 
 
859
 
        Example:
860
 
                >var Animals = ['Cat', 'Dog', 'Coala'];
861
 
                >Animals.each(function(animal){
862
 
                >       document.write(animal)
863
 
                >});
864
 
        */
865
 
 
866
 
        /*
867
 
        Property: copy
868
 
                returns a copy of the array.
869
 
 
870
 
        Returns:
871
 
                a new array which is a copy of the current one.
872
 
 
873
 
        Arguments:
874
 
                start - integer; optional; the index where to start the copy, default is 0. If negative, it is taken as the offset from the end of the array.
875
 
                length - integer; optional; the number of elements to copy. By default, copies all elements from start to the end of the array.
876
 
 
877
 
        Example:
878
 
                >var letters = ["a","b","c"];
879
 
                >var copy = letters.copy();             // ["a","b","c"] (new instance)
880
 
        */
881
 
 
882
 
        copy: function(start, length){
883
 
                start = start || 0;
884
 
                if (start < 0) start = this.length + start;
885
 
                length = length || (this.length - start);
886
 
                var newArray = [];
887
 
                for (var i = 0; i < length; i++) newArray[i] = this[start++];
888
 
                return newArray;
889
 
        },
890
 
 
891
 
        /*
892
 
        Property: remove
893
 
                Removes all occurrences of an item from the array.
894
 
 
895
 
        Arguments:
896
 
                item - the item to remove
897
 
 
898
 
        Returns:
899
 
                the Array with all occurrences of the item removed.
900
 
 
901
 
        Example:
902
 
                >["1","2","3","2"].remove("2") // ["1","3"];
903
 
        */
904
 
 
905
 
        remove: function(item){
906
 
                var i = 0;
907
 
                var len = this.length;
908
 
                while (i < len){
909
 
                        if (this[i] === item){
910
 
                                this.splice(i, 1);
911
 
                                len--;
912
 
                        } else {
913
 
                                i++;
914
 
                        }
915
 
                }
916
 
                return this;
917
 
        },
918
 
 
919
 
        /*
920
 
        Property: contains
921
 
                Tests an array for the presence of an item.
922
 
 
923
 
        Arguments:
924
 
                item - the item to search for in the array.
925
 
                from - integer; optional; the index at which to begin the search, default is 0. If negative, it is taken as the offset from the end of the array.
926
 
 
927
 
        Returns:
928
 
                true - the item was found
929
 
                false - it wasn't
930
 
 
931
 
        Example:
932
 
                >["a","b","c"].contains("a"); // true
933
 
                >["a","b","c"].contains("d"); // false
934
 
        */
935
 
 
936
 
        contains: function(item, from){
937
 
                return this.indexOf(item, from) != -1;
938
 
        },
939
 
 
940
 
        /*
941
 
        Property: associate
942
 
                Creates an object with key-value pairs based on the array of keywords passed in
943
 
                and the current content of the array.
944
 
 
945
 
        Arguments:
946
 
                keys - the array of keywords.
947
 
 
948
 
        Example:
949
 
                (start code)
950
 
                var Animals = ['Cat', 'Dog', 'Coala', 'Lizard'];
951
 
                var Speech = ['Miao', 'Bau', 'Fruuu', 'Mute'];
952
 
                var Speeches = Animals.associate(Speech);
953
 
                //Speeches['Miao'] is now Cat.
954
 
                //Speeches['Bau'] is now Dog.
955
 
                //...
956
 
                (end)
957
 
        */
958
 
 
959
 
        associate: function(keys){
960
 
                var obj = {}, length = Math.min(this.length, keys.length);
961
 
                for (var i = 0; i < length; i++) obj[keys[i]] = this[i];
962
 
                return obj;
963
 
        },
964
 
 
965
 
        /*
966
 
        Property: extend
967
 
                Extends an array with another one.
968
 
 
969
 
        Arguments:
970
 
                array - the array to extend ours with
971
 
 
972
 
        Example:
973
 
                >var Animals = ['Cat', 'Dog', 'Coala'];
974
 
                >Animals.extend(['Lizard']);
975
 
                >//Animals is now: ['Cat', 'Dog', 'Coala', 'Lizard'];
976
 
        */
977
 
 
978
 
        extend: function(array){
979
 
                for (var i = 0, j = array.length; i < j; i++) this.push(array[i]);
980
 
                return this;
981
 
        },
982
 
 
983
 
        /*
984
 
        Property: merge
985
 
                merges an array in another array, without duplicates. (case- and type-sensitive)
986
 
 
987
 
        Arguments:
988
 
                array - the array to merge from.
989
 
 
990
 
        Example:
991
 
                >['Cat','Dog'].merge(['Dog','Coala']); //returns ['Cat','Dog','Coala']
992
 
        */
993
 
 
994
 
        merge: function(array){
995
 
                for (var i = 0, l = array.length; i < l; i++) this.include(array[i]);
996
 
                return this;
997
 
        },
998
 
 
999
 
        /*
1000
 
        Property: include
1001
 
                includes the passed in element in the array, only if its not already present. (case- and type-sensitive)
1002
 
 
1003
 
        Arguments:
1004
 
                item - item to add to the array (if not present)
1005
 
 
1006
 
        Example:
1007
 
                >['Cat','Dog'].include('Dog'); //returns ['Cat','Dog']
1008
 
                >['Cat','Dog'].include('Coala'); //returns ['Cat','Dog','Coala']
1009
 
        */
1010
 
 
1011
 
        include: function(item){
1012
 
                if (!this.contains(item)) this.push(item);
1013
 
                return this;
1014
 
        },
1015
 
 
1016
 
        /*
1017
 
        Property: getRandom
1018
 
                returns a random item in the Array
1019
 
        */
1020
 
 
1021
 
        getRandom: function(){
1022
 
                return this[$random(0, this.length - 1)] || null;
1023
 
        },
1024
 
 
1025
 
        /*
1026
 
        Property: getLast
1027
 
                returns the last item in the Array
1028
 
        */
1029
 
 
1030
 
        getLast: function(){
1031
 
                return this[this.length - 1] || null;
1032
 
        }
1033
 
 
1034
 
});
1035
 
 
1036
 
//copies
1037
 
 
1038
 
Array.prototype.each = Array.prototype.forEach;
1039
 
Array.each = Array.forEach;
1040
 
 
1041
 
/* Section: Utility Functions */
1042
 
 
1043
 
/*
1044
 
Function: $A()
1045
 
        Same as <Array.copy>, but as function.
1046
 
        Useful to apply Array prototypes to iterable objects, as a collection of DOM elements or the arguments object.
1047
 
 
1048
 
Example:
1049
 
        (start code)
1050
 
        function myFunction(){
1051
 
                $A(arguments).each(argument, function(){
1052
 
                        alert(argument);
1053
 
                });
1054
 
        };
1055
 
        //the above will alert all the arguments passed to the function myFunction.
1056
 
        (end)
1057
 
*/
1058
 
 
1059
 
function $A(array){
1060
 
        return Array.copy(array);
1061
 
};
1062
 
 
1063
 
/*
1064
 
Function: $each
1065
 
        Use to iterate through iterables that are not regular arrays, such as builtin getElementsByTagName calls, arguments of a function, or an object.
1066
 
 
1067
 
Arguments:
1068
 
        iterable - an iterable element or an objct.
1069
 
        function - function to apply to the iterable.
1070
 
        bind - optional, the 'this' of the function will refer to this object.
1071
 
 
1072
 
Function argument:
1073
 
        The function argument will be passed the following arguments.
1074
 
 
1075
 
        item - the current item in the iterator being procesed
1076
 
        index - integer; the index of the item, or key in case of an object.
1077
 
 
1078
 
Examples:
1079
 
        (start code)
1080
 
        $each(['Sun','Mon','Tue'], function(day, index){
1081
 
                alert('name:' + day + ', index: ' + index);
1082
 
        });
1083
 
        //alerts "name: Sun, index: 0", "name: Mon, index: 1", etc.
1084
 
        //over an object
1085
 
        $each({first: "Sunday", second: "Monday", third: "Tuesday"}, function(value, key){
1086
 
                alert("the " + key + " day of the week is " + value);
1087
 
        });
1088
 
        //alerts "the first day of the week is Sunday",
1089
 
        //"the second day of the week is Monday", etc.
1090
 
        (end)
1091
 
*/
1092
 
 
1093
 
function $each(iterable, fn, bind){
1094
 
        if (iterable && typeof iterable.length == 'number' && $type(iterable) != 'object'){
1095
 
                Array.forEach(iterable, fn, bind);
1096
 
        } else {
1097
 
                 for (var name in iterable) fn.call(bind || iterable, iterable[name], name);
1098
 
        }
1099
 
};
1100
 
 
1101
 
/*compatibility*/
1102
 
 
1103
 
Array.prototype.test = Array.prototype.contains;
1104
 
 
1105
 
/*end compatibility*/
1106
 
 
1107
 
/*
1108
 
Script: String.js
1109
 
        Contains String prototypes.
1110
 
 
1111
 
License:
1112
 
        MIT-style license.
1113
 
*/
1114
 
 
1115
 
/*
1116
 
Class: String
1117
 
        A collection of The String Object prototype methods.
1118
 
*/
1119
 
 
1120
 
String.extend({
1121
 
 
1122
 
        /*
1123
 
        Property: test
1124
 
                Tests a string with a regular expression.
1125
 
 
1126
 
        Arguments:
1127
 
                regex - a string or regular expression object, the regular expression you want to match the string with
1128
 
                params - optional, if first parameter is a string, any parameters you want to pass to the regex ('g' has no effect)
1129
 
 
1130
 
        Returns:
1131
 
                true if a match for the regular expression is found in the string, false if not.
1132
 
                See <http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:RegExp:test>
1133
 
 
1134
 
        Example:
1135
 
                >"I like cookies".test("cookie"); // returns true
1136
 
                >"I like cookies".test("COOKIE", "i") // ignore case, returns true
1137
 
                >"I like cookies".test("cake"); // returns false
1138
 
        */
1139
 
 
1140
 
        test: function(regex, params){
1141
 
                return (($type(regex) == 'string') ? new RegExp(regex, params) : regex).test(this);
1142
 
        },
1143
 
 
1144
 
        /*
1145
 
        Property: toInt
1146
 
                parses a string to an integer.
1147
 
 
1148
 
        Returns:
1149
 
                either an int or "NaN" if the string is not a number.
1150
 
 
1151
 
        Example:
1152
 
                >var value = "10px".toInt(); // value is 10
1153
 
        */
1154
 
 
1155
 
        toInt: function(){
1156
 
                return parseInt(this, 10);
1157
 
        },
1158
 
 
1159
 
        /*
1160
 
        Property: toFloat
1161
 
                parses a string to an float.
1162
 
 
1163
 
        Returns:
1164
 
                either a float or "NaN" if the string is not a number.
1165
 
 
1166
 
        Example:
1167
 
                >var value = "10.848".toFloat(); // value is 10.848
1168
 
        */
1169
 
 
1170
 
        toFloat: function(){
1171
 
                return parseFloat(this);
1172
 
        },
1173
 
 
1174
 
        /*
1175
 
        Property: camelCase
1176
 
                Converts a hiphenated string to a camelcase string.
1177
 
 
1178
 
        Example:
1179
 
                >"I-like-cookies".camelCase(); //"ILikeCookies"
1180
 
 
1181
 
        Returns:
1182
 
                the camel cased string
1183
 
        */
1184
 
 
1185
 
        camelCase: function(){
1186
 
                return this.replace(/-\D/g, function(match){
1187
 
                        return match.charAt(1).toUpperCase();
1188
 
                });
1189
 
        },
1190
 
 
1191
 
        /*
1192
 
        Property: hyphenate
1193
 
                Converts a camelCased string to a hyphen-ated string.
1194
 
 
1195
 
        Example:
1196
 
                >"ILikeCookies".hyphenate(); //"I-like-cookies"
1197
 
        */
1198
 
 
1199
 
        hyphenate: function(){
1200
 
                return this.replace(/\w[A-Z]/g, function(match){
1201
 
                        return (match.charAt(0) + '-' + match.charAt(1).toLowerCase());
1202
 
                });
1203
 
        },
1204
 
 
1205
 
        /*
1206
 
        Property: capitalize
1207
 
                Converts the first letter in each word of a string to Uppercase.
1208
 
 
1209
 
        Example:
1210
 
                >"i like cookies".capitalize(); //"I Like Cookies"
1211
 
 
1212
 
        Returns:
1213
 
                the capitalized string
1214
 
        */
1215
 
 
1216
 
        capitalize: function(){
1217
 
                return this.replace(/\b[a-z]/g, function(match){
1218
 
                        return match.toUpperCase();
1219
 
                });
1220
 
        },
1221
 
 
1222
 
        /*
1223
 
        Property: trim
1224
 
                Trims the leading and trailing spaces off a string.
1225
 
 
1226
 
        Example:
1227
 
                >"    i like cookies     ".trim() //"i like cookies"
1228
 
 
1229
 
        Returns:
1230
 
                the trimmed string
1231
 
        */
1232
 
 
1233
 
        trim: function(){
1234
 
                return this.replace(/^\s+|\s+$/g, '');
1235
 
        },
1236
 
 
1237
 
        /*
1238
 
        Property: clean
1239
 
                trims (<String.trim>) a string AND removes all the double spaces in a string.
1240
 
 
1241
 
        Returns:
1242
 
                the cleaned string
1243
 
 
1244
 
        Example:
1245
 
                >" i      like     cookies      \n\n".clean() //"i like cookies"
1246
 
        */
1247
 
 
1248
 
        clean: function(){
1249
 
                return this.replace(/\s{2,}/g, ' ').trim();
1250
 
        },
1251
 
 
1252
 
        /*
1253
 
        Property: rgbToHex
1254
 
                Converts an RGB value to hexidecimal. The string must be in the format of "rgb(255,255,255)" or "rgba(255,255,255,1)";
1255
 
 
1256
 
        Arguments:
1257
 
                array - boolean value, defaults to false. Use true if you want the array ['FF','33','00'] as output instead of "#FF3300"
1258
 
 
1259
 
        Returns:
1260
 
                hex string or array. returns "transparent" if the output is set as string and the fourth value of rgba in input string is 0.
1261
 
 
1262
 
        Example:
1263
 
                >"rgb(17,34,51)".rgbToHex(); //"#112233"
1264
 
                >"rgba(17,34,51,0)".rgbToHex(); //"transparent"
1265
 
                >"rgb(17,34,51)".rgbToHex(true); //['11','22','33']
1266
 
        */
1267
 
 
1268
 
        rgbToHex: function(array){
1269
 
                var rgb = this.match(/\d{1,3}/g);
1270
 
                return (rgb) ? rgb.rgbToHex(array) : false;
1271
 
        },
1272
 
 
1273
 
        /*
1274
 
        Property: hexToRgb
1275
 
                Converts a hexidecimal color value to RGB. Input string must be the hex color value (with or without the hash). Also accepts triplets ('333');
1276
 
 
1277
 
        Arguments:
1278
 
                array - boolean value, defaults to false. Use true if you want the array [255,255,255] as output instead of "rgb(255,255,255)";
1279
 
 
1280
 
        Returns:
1281
 
                rgb string or array.
1282
 
 
1283
 
        Example:
1284
 
                >"#112233".hexToRgb(); //"rgb(17,34,51)"
1285
 
                >"#112233".hexToRgb(true); //[17,34,51]
1286
 
        */
1287
 
 
1288
 
        hexToRgb: function(array){
1289
 
                var hex = this.match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/);
1290
 
                return (hex) ? hex.slice(1).hexToRgb(array) : false;
1291
 
        },
1292
 
 
1293
 
        /*
1294
 
        Property: contains
1295
 
                checks if the passed in string is contained in the String. also accepts an optional second parameter, to check if the string is contained in a list of separated values.
1296
 
 
1297
 
        Example:
1298
 
                >'a b c'.contains('c', ' '); //true
1299
 
                >'a bc'.contains('bc'); //true
1300
 
                >'a bc'.contains('b', ' '); //false
1301
 
        */
1302
 
 
1303
 
        contains: function(string, s){
1304
 
                return (s) ? (s + this + s).indexOf(s + string + s) > -1 : this.indexOf(string) > -1;
1305
 
        },
1306
 
 
1307
 
        /*
1308
 
        Property: escapeRegExp
1309
 
                Returns string with escaped regular expression characters
1310
 
 
1311
 
        Example:
1312
 
                >var search = 'animals.sheeps[1]'.escapeRegExp(); // search is now 'animals\.sheeps\[1\]'
1313
 
 
1314
 
        Returns:
1315
 
                Escaped string
1316
 
        */
1317
 
 
1318
 
        escapeRegExp: function(){
1319
 
                return this.replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1');
1320
 
        }
1321
 
 
1322
 
});
1323
 
 
1324
 
Array.extend({
1325
 
 
1326
 
        /*
1327
 
        Property: rgbToHex
1328
 
                see <String.rgbToHex>, but as an array method.
1329
 
        */
1330
 
 
1331
 
        rgbToHex: function(array){
1332
 
                if (this.length < 3) return false;
1333
 
                if (this.length == 4 && this[3] == 0 && !array) return 'transparent';
1334
 
                var hex = [];
1335
 
                for (var i = 0; i < 3; i++){
1336
 
                        var bit = (this[i] - 0).toString(16);
1337
 
                        hex.push((bit.length == 1) ? '0' + bit : bit);
1338
 
                }
1339
 
                return array ? hex : '#' + hex.join('');
1340
 
        },
1341
 
 
1342
 
        /*
1343
 
        Property: hexToRgb
1344
 
                same as <String.hexToRgb>, but as an array method.
1345
 
        */
1346
 
 
1347
 
        hexToRgb: function(array){
1348
 
                if (this.length != 3) return false;
1349
 
                var rgb = [];
1350
 
                for (var i = 0; i < 3; i++){
1351
 
                        rgb.push(parseInt((this[i].length == 1) ? this[i] + this[i] : this[i], 16));
1352
 
                }
1353
 
                return array ? rgb : 'rgb(' + rgb.join(',') + ')';
1354
 
        }
1355
 
 
1356
 
});
1357
 
 
1358
 
/* 
1359
 
Script: Function.js
1360
 
        Contains Function prototypes and utility functions .
1361
 
 
1362
 
License:
1363
 
        MIT-style license.
1364
 
 
1365
 
Credits:
1366
 
        - Some functions are inspired by those found in prototype.js <http://prototype.conio.net/> (c) 2005 Sam Stephenson sam [at] conio [dot] net, MIT-style license
1367
 
*/
1368
 
 
1369
 
/*
1370
 
Class: Function
1371
 
        A collection of The Function Object prototype methods.
1372
 
*/
1373
 
 
1374
 
Function.extend({
1375
 
 
1376
 
        /*
1377
 
        Property: create
1378
 
                Main function to create closures.
1379
 
 
1380
 
        Returns:
1381
 
                a function.
1382
 
 
1383
 
        Arguments:
1384
 
                options - An Options object.
1385
 
 
1386
 
        Options:
1387
 
                bind - The object that the "this" of the function will refer to. Default is the current function.
1388
 
                event - If set to true, the function will act as an event listener and receive an event as first argument.
1389
 
                                If set to a class name, the function will receive a new instance of this class (with the event passed as argument's constructor) as first argument.
1390
 
                                Default is false.
1391
 
                arguments - A single argument or array of arguments that will be passed to the function when called.
1392
 
                
1393
 
                                        If both the event and arguments options are set, the event is passed as first argument and the arguments array will follow.
1394
 
                                        
1395
 
                                        Default is no custom arguments, the function will receive the standard arguments when called.
1396
 
                                        
1397
 
                delay - Numeric value: if set, the returned function will delay the actual execution by this amount of milliseconds and return a timer handle when called.
1398
 
                                Default is no delay.
1399
 
                periodical - Numeric value: if set, the returned function will periodically perform the actual execution with this specified interval and return a timer handle when called.
1400
 
                                Default is no periodical execution.
1401
 
                attempt - If set to true, the returned function will try to execute and return either the results or false on error. Default is false.
1402
 
        */
1403
 
 
1404
 
        create: function(options){
1405
 
                var fn = this;
1406
 
                options = $merge({
1407
 
                        'bind': fn,
1408
 
                        'event': false,
1409
 
                        'arguments': null,
1410
 
                        'delay': false,
1411
 
                        'periodical': false,
1412
 
                        'attempt': false
1413
 
                }, options);
1414
 
                if ($chk(options.arguments) && $type(options.arguments) != 'array') options.arguments = [options.arguments];
1415
 
                return function(event){
1416
 
                        var args;
1417
 
                        if (options.event){
1418
 
                                event = event || window.event;
1419
 
                                args = [(options.event === true) ? event : new options.event(event)];
1420
 
                                if (options.arguments) args.extend(options.arguments);
1421
 
                        }
1422
 
                        else args = options.arguments || arguments;
1423
 
                        var returns = function(){
1424
 
                                return fn.apply($pick(options.bind, fn), args);
1425
 
                        };
1426
 
                        if (options.delay) return setTimeout(returns, options.delay);
1427
 
                        if (options.periodical) return setInterval(returns, options.periodical);
1428
 
                        if (options.attempt) try {return returns();} catch(err){return false;};
1429
 
                        return returns();
1430
 
                };
1431
 
        },
1432
 
 
1433
 
        /*
1434
 
        Property: pass
1435
 
                Shortcut to create closures with arguments and bind.
1436
 
 
1437
 
        Returns:
1438
 
                a function.
1439
 
 
1440
 
        Arguments:
1441
 
                args - the arguments passed. must be an array if arguments > 1
1442
 
                bind - optional, the object that the "this" of the function will refer to.
1443
 
 
1444
 
        Example:
1445
 
                >myFunction.pass([arg1, arg2], myElement);
1446
 
        */
1447
 
 
1448
 
        pass: function(args, bind){
1449
 
                return this.create({'arguments': args, 'bind': bind});
1450
 
        },
1451
 
 
1452
 
        /*
1453
 
        Property: attempt
1454
 
                Tries to execute the function, returns either the result of the function or false on error.
1455
 
 
1456
 
        Arguments:
1457
 
                args - the arguments passed. must be an array if arguments > 1
1458
 
                bind - optional, the object that the "this" of the function will refer to.
1459
 
 
1460
 
        Example:
1461
 
                >myFunction.attempt([arg1, arg2], myElement);
1462
 
        */
1463
 
 
1464
 
        attempt: function(args, bind){
1465
 
                return this.create({'arguments': args, 'bind': bind, 'attempt': true})();
1466
 
        },
1467
 
 
1468
 
        /*
1469
 
        Property: bind
1470
 
                method to easily create closures with "this" altered.
1471
 
 
1472
 
        Arguments:
1473
 
                bind - optional, the object that the "this" of the function will refer to.
1474
 
                args - optional, the arguments passed. must be an array if arguments > 1
1475
 
 
1476
 
        Returns:
1477
 
                a function.
1478
 
 
1479
 
        Example:
1480
 
                >function myFunction(){
1481
 
                >       this.setStyle('color', 'red');
1482
 
                >       // note that 'this' here refers to myFunction, not an element
1483
 
                >       // we'll need to bind this function to the element we want to alter
1484
 
                >};
1485
 
                >var myBoundFunction = myFunction.bind(myElement);
1486
 
                >myBoundFunction(); // this will make the element myElement red.
1487
 
        */
1488
 
 
1489
 
        bind: function(bind, args){
1490
 
                return this.create({'bind': bind, 'arguments': args});
1491
 
        },
1492
 
 
1493
 
        /*
1494
 
        Property: bindAsEventListener
1495
 
                cross browser method to pass event firer
1496
 
 
1497
 
        Arguments:
1498
 
                bind - optional, the object that the "this" of the function will refer to.
1499
 
                args - optional, the arguments passed. must be an array if arguments > 1
1500
 
 
1501
 
        Returns:
1502
 
                a function with the parameter bind as its "this" and as a pre-passed argument event or window.event, depending on the browser.
1503
 
 
1504
 
        Example:
1505
 
                >function myFunction(event){
1506
 
                >       alert(event.clientx) //returns the coordinates of the mouse..
1507
 
                >};
1508
 
                >myElement.onclick = myFunction.bindAsEventListener(myElement);
1509
 
        */
1510
 
 
1511
 
        bindAsEventListener: function(bind, args){
1512
 
                return this.create({'bind': bind, 'event': true, 'arguments': args});
1513
 
        },
1514
 
 
1515
 
        /*
1516
 
        Property: delay
1517
 
                Delays the execution of a function by a specified duration.
1518
 
 
1519
 
        Arguments:
1520
 
                delay - the duration to wait in milliseconds.
1521
 
                bind - optional, the object that the "this" of the function will refer to.
1522
 
                args - optional, the arguments passed. must be an array if arguments > 1
1523
 
 
1524
 
        Example:
1525
 
                >myFunction.delay(50, myElement) //wait 50 milliseconds, then call myFunction and bind myElement to it
1526
 
                >(function(){alert('one second later...')}).delay(1000); //wait a second and alert
1527
 
        */
1528
 
 
1529
 
        delay: function(delay, bind, args){
1530
 
                return this.create({'delay': delay, 'bind': bind, 'arguments': args})();
1531
 
        },
1532
 
 
1533
 
        /*
1534
 
        Property: periodical
1535
 
                Executes a function in the specified intervals of time
1536
 
 
1537
 
        Arguments:
1538
 
                interval - the duration of the intervals between executions.
1539
 
                bind - optional, the object that the "this" of the function will refer to.
1540
 
                args - optional, the arguments passed. must be an array if arguments > 1
1541
 
        */
1542
 
 
1543
 
        periodical: function(interval, bind, args){
1544
 
                return this.create({'periodical': interval, 'bind': bind, 'arguments': args})();
1545
 
        }
1546
 
 
1547
 
});
1548
 
 
1549
 
/*
1550
 
Script: Number.js
1551
 
        Contains the Number prototypes.
1552
 
 
1553
 
License:
1554
 
        MIT-style license.
1555
 
*/
1556
 
 
1557
 
/*
1558
 
Class: Number
1559
 
        A collection of The Number Object prototype methods.
1560
 
*/
1561
 
 
1562
 
Number.extend({
1563
 
 
1564
 
        /*
1565
 
        Property: toInt
1566
 
                Returns this number; useful because toInt must work on both Strings and Numbers.
1567
 
        */
1568
 
 
1569
 
        toInt: function(){
1570
 
                return parseInt(this);
1571
 
        },
1572
 
 
1573
 
        /*
1574
 
        Property: toFloat
1575
 
                Returns this number as a float; useful because toFloat must work on both Strings and Numbers.
1576
 
        */
1577
 
 
1578
 
        toFloat: function(){
1579
 
                return parseFloat(this);
1580
 
        },
1581
 
 
1582
 
        /*
1583
 
        Property: limit
1584
 
                Limits the number.
1585
 
 
1586
 
        Arguments:
1587
 
                min - number, minimum value
1588
 
                max - number, maximum value
1589
 
 
1590
 
        Returns:
1591
 
                the number in the given limits.
1592
 
 
1593
 
        Example:
1594
 
                >(12).limit(2, 6.5)  // returns 6.5
1595
 
                >(-4).limit(2, 6.5)  // returns 2
1596
 
                >(4.3).limit(2, 6.5) // returns 4.3
1597
 
        */
1598
 
 
1599
 
        limit: function(min, max){
1600
 
                return Math.min(max, Math.max(min, this));
1601
 
        },
1602
 
 
1603
 
        /*
1604
 
        Property: round
1605
 
                Returns the number rounded to specified precision.
1606
 
 
1607
 
        Arguments:
1608
 
                precision - integer, number of digits after the decimal point. Can also be negative or zero (default).
1609
 
 
1610
 
        Example:
1611
 
                >12.45.round() // returns 12
1612
 
                >12.45.round(1) // returns 12.5
1613
 
                >12.45.round(-1) // returns 10
1614
 
 
1615
 
        Returns:
1616
 
                The rounded number.
1617
 
        */
1618
 
 
1619
 
        round: function(precision){
1620
 
                precision = Math.pow(10, precision || 0);
1621
 
                return Math.round(this * precision) / precision;
1622
 
        },
1623
 
 
1624
 
        /*
1625
 
        Property: times
1626
 
                Executes a passed in function the specified number of times
1627
 
 
1628
 
        Arguments:
1629
 
                function - the function to be executed on each iteration of the loop
1630
 
 
1631
 
        Example:
1632
 
                >(4).times(alert);
1633
 
        */
1634
 
 
1635
 
        times: function(fn){
1636
 
                for (var i = 0; i < this; i++) fn(i);
1637
 
        }
1638
 
 
1639
 
});
1640
 
 
1641
 
/*
1642
 
Script: Element.js
1643
 
        Contains useful Element prototypes, to be used with the dollar function <$>.
1644
 
 
1645
 
License:
1646
 
        MIT-style license.
1647
 
 
1648
 
Credits:
1649
 
        - Some functions are inspired by those found in prototype.js <http://prototype.conio.net/> (c) 2005 Sam Stephenson sam [at] conio [dot] net, MIT-style license
1650
 
*/
1651
 
 
1652
 
/*
1653
 
Class: Element
1654
 
        Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>.
1655
 
*/
1656
 
 
1657
 
var Element = new Class({
1658
 
 
1659
 
        /*
1660
 
        Property: initialize
1661
 
                Creates a new element of the type passed in.
1662
 
 
1663
 
        Arguments:
1664
 
                el - string; the tag name for the element you wish to create. you can also pass in an element reference, in which case it will be extended.
1665
 
                props - object; the properties you want to add to your element.
1666
 
                Accepts the same keys as <Element.setProperties>, but also allows events and styles
1667
 
 
1668
 
        Props:
1669
 
                the key styles will be used as setStyles, the key events will be used as addEvents. any other key is used as setProperty.
1670
 
 
1671
 
        Example:
1672
 
                (start code)
1673
 
                new Element('a', {
1674
 
                        'styles': {
1675
 
                                'display': 'block',
1676
 
                                'border': '1px solid black'
1677
 
                        },
1678
 
                        'events': {
1679
 
                                'click': function(){
1680
 
                                        //aaa
1681
 
                                },
1682
 
                                'mousedown': function(){
1683
 
                                        //aaa
1684
 
                                }
1685
 
                        },
1686
 
                        'class': 'myClassSuperClass',
1687
 
                        'href': 'http://mad4milk.net'
1688
 
                });
1689
 
 
1690
 
                (end)
1691
 
        */
1692
 
 
1693
 
        initialize: function(el, props){
1694
 
                if ($type(el) == 'string'){
1695
 
                        if (window.ie && props && (props.name || props.type)){
1696
 
                                var name = (props.name) ? ' name="' + props.name + '"' : '';
1697
 
                                var type = (props.type) ? ' type="' + props.type + '"' : '';
1698
 
                                delete props.name;
1699
 
                                delete props.type;
1700
 
                                el = '<' + el + name + type + '>';
1701
 
                        }
1702
 
                        el = document.createElement(el);
1703
 
                }
1704
 
                el = $(el);
1705
 
                return (!props || !el) ? el : el.set(props);
1706
 
        }
1707
 
 
1708
 
});
1709
 
 
1710
 
/*
1711
 
Class: Elements
1712
 
        - Every dom function such as <$$>, or in general every function that returns a collection of nodes in mootools, returns them as an Elements class.
1713
 
        - The purpose of the Elements class is to allow <Element> methods to work also on <Elements> array.
1714
 
        - Elements is also an Array, so it accepts all the <Array> methods.
1715
 
        - Every node of the Elements instance is already extended with <$>.
1716
 
 
1717
 
Example:
1718
 
        >$$('myselector').each(function(el){
1719
 
        > //...
1720
 
        >});
1721
 
 
1722
 
        some iterations here, $$('myselector') is also an array.
1723
 
 
1724
 
        >$$('myselector').setStyle('color', 'red');
1725
 
        every element returned by $$('myselector') also accepts <Element> methods, in this example every element will be made red.
1726
 
*/
1727
 
 
1728
 
var Elements = new Class({
1729
 
 
1730
 
        initialize: function(elements){
1731
 
                return (elements) ? $extend(elements, this) : this;
1732
 
        }
1733
 
 
1734
 
});
1735
 
 
1736
 
Elements.extend = function(props){
1737
 
        for (var prop in props){
1738
 
                this.prototype[prop] = props[prop];
1739
 
                this[prop] = $native.generic(prop);
1740
 
        }
1741
 
};
1742
 
 
1743
 
/*
1744
 
Section: Utility Functions
1745
 
 
1746
 
Function: $
1747
 
        returns the element passed in with all the Element prototypes applied.
1748
 
 
1749
 
Arguments:
1750
 
        el - a reference to an actual element or a string representing the id of an element
1751
 
 
1752
 
Example:
1753
 
        >$('myElement') // gets a DOM element by id with all the Element prototypes applied.
1754
 
        >var div = document.getElementById('myElement');
1755
 
        >$(div) //returns an Element also with all the mootools extentions applied.
1756
 
 
1757
 
        You'll use this when you aren't sure if a variable is an actual element or an id, as
1758
 
        well as just shorthand for document.getElementById().
1759
 
 
1760
 
Returns:
1761
 
        a DOM element or false (if no id was found).
1762
 
 
1763
 
Note:
1764
 
        you need to call $ on an element only once to get all the prototypes.
1765
 
        But its no harm to call it multiple times, as it will detect if it has been already extended.
1766
 
*/
1767
 
 
1768
 
function $(el){
1769
 
        if (!el) return null;
1770
 
        if (el.htmlElement) return Garbage.collect(el);
1771
 
        if ([window, document].contains(el)) return el;
1772
 
        var type = $type(el);
1773
 
        if (type == 'string'){
1774
 
                el = document.getElementById(el);
1775
 
                type = (el) ? 'element' : false;
1776
 
        }
1777
 
        if (type != 'element') return null;
1778
 
        if (el.htmlElement) return Garbage.collect(el);
1779
 
        if (['object', 'embed'].contains(el.tagName.toLowerCase())) return el;
1780
 
        $extend(el, Element.prototype);
1781
 
        el.htmlElement = function(){};
1782
 
        return Garbage.collect(el);
1783
 
};
1784
 
 
1785
 
/*
1786
 
Function: $$
1787
 
        Selects, and extends DOM elements. Elements arrays returned with $$ will also accept all the <Element> methods.
1788
 
        The return type of element methods run through $$ is always an array. If the return array is only made by elements,
1789
 
        $$ will be applied automatically.
1790
 
 
1791
 
Arguments:
1792
 
        HTML Collections, arrays of elements, arrays of strings as element ids, elements, strings as selectors.
1793
 
        Any number of the above as arguments are accepted.
1794
 
 
1795
 
Note:
1796
 
        if you load <Element.Selectors.js>, $$ will also accept CSS Selectors, otherwise the only selectors supported are tag names.
1797
 
 
1798
 
Example:
1799
 
        >$$('a') //an array of all anchor tags on the page
1800
 
        >$$('a', 'b') //an array of all anchor and bold tags on the page
1801
 
        >$$('#myElement') //array containing only the element with id = myElement. (only with <Element.Selectors.js>)
1802
 
        >$$('#myElement a.myClass') //an array of all anchor tags with the class "myClass"
1803
 
        >//within the DOM element with id "myElement" (only with <Element.Selectors.js>)
1804
 
        >$$(myelement, myelement2, 'a', ['myid', myid2, 'myid3'], document.getElementsByTagName('div')) //an array containing:
1805
 
        >// the element referenced as myelement if existing,
1806
 
        >// the element referenced as myelement2 if existing,
1807
 
        >// all the elements with a as tag in the page,
1808
 
        >// the element with id = myid if existing
1809
 
        >// the element with id = myid2 if existing
1810
 
        >// the element with id = myid3 if existing
1811
 
        >// all the elements with div as tag in the page
1812
 
 
1813
 
Returns:
1814
 
        array - array of all the dom elements matched, extended with <$>.  Returns as <Elements>.
1815
 
*/
1816
 
 
1817
 
document.getElementsBySelector = document.getElementsByTagName;
1818
 
 
1819
 
function $$(){
1820
 
        var elements = [];
1821
 
        for (var i = 0, j = arguments.length; i < j; i++){
1822
 
                var selector = arguments[i];
1823
 
                switch($type(selector)){
1824
 
                        case 'element': elements.push(selector);
1825
 
                        case 'boolean': break;
1826
 
                        case false: break;
1827
 
                        case 'string': selector = document.getElementsBySelector(selector, true);
1828
 
                        default: elements.extend(selector);
1829
 
                }
1830
 
        }
1831
 
        return $$.unique(elements);
1832
 
};
1833
 
 
1834
 
$$.unique = function(array){
1835
 
        var elements = [];
1836
 
        for (var i = 0, l = array.length; i < l; i++){
1837
 
                if (array[i].$included) continue;
1838
 
                var element = $(array[i]);
1839
 
                if (element && !element.$included){
1840
 
                        element.$included = true;
1841
 
                        elements.push(element);
1842
 
                }
1843
 
        }
1844
 
        for (var n = 0, d = elements.length; n < d; n++) elements[n].$included = null;
1845
 
        return new Elements(elements);
1846
 
};
1847
 
 
1848
 
Elements.Multi = function(property){
1849
 
        return function(){
1850
 
                var args = arguments;
1851
 
                var items = [];
1852
 
                var elements = true;
1853
 
                for (var i = 0, j = this.length, returns; i < j; i++){
1854
 
                        returns = this[i][property].apply(this[i], args);
1855
 
                        if ($type(returns) != 'element') elements = false;
1856
 
                        items.push(returns);
1857
 
                };
1858
 
                return (elements) ? $$.unique(items) : items;
1859
 
        };
1860
 
};
1861
 
 
1862
 
Element.extend = function(properties){
1863
 
        for (var property in properties){
1864
 
                HTMLElement.prototype[property] = properties[property];
1865
 
                Element.prototype[property] = properties[property];
1866
 
                Element[property] = $native.generic(property);
1867
 
                var elementsProperty = (Array.prototype[property]) ? property + 'Elements' : property;
1868
 
                Elements.prototype[elementsProperty] = Elements.Multi(property);
1869
 
        }
1870
 
};
1871
 
 
1872
 
/*
1873
 
Class: Element
1874
 
        Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>.
1875
 
*/
1876
 
 
1877
 
Element.extend({
1878
 
 
1879
 
        /*
1880
 
        Property: set
1881
 
                you can set events, styles and properties with this shortcut. same as calling new Element.
1882
 
        */
1883
 
 
1884
 
        set: function(props){
1885
 
                for (var prop in props){
1886
 
                        var val = props[prop];
1887
 
                        switch(prop){
1888
 
                                case 'styles': this.setStyles(val); break;
1889
 
                                case 'events': if (this.addEvents) this.addEvents(val); break;
1890
 
                                case 'properties': this.setProperties(val); break;
1891
 
                                default: this.setProperty(prop, val);
1892
 
                        }
1893
 
                }
1894
 
                return this;
1895
 
        },
1896
 
 
1897
 
        inject: function(el, where){
1898
 
                el = $(el);
1899
 
                switch(where){
1900
 
                        case 'before': el.parentNode.insertBefore(this, el); break;
1901
 
                        case 'after':
1902
 
                                var next = el.getNext();
1903
 
                                if (!next) el.parentNode.appendChild(this);
1904
 
                                else el.parentNode.insertBefore(this, next);
1905
 
                                break;
1906
 
                        case 'top':
1907
 
                                var first = el.firstChild;
1908
 
                                if (first){
1909
 
                                        el.insertBefore(this, first);
1910
 
                                        break;
1911
 
                                }
1912
 
                        default: el.appendChild(this);
1913
 
                }
1914
 
                return this;
1915
 
        },
1916
 
 
1917
 
        /*
1918
 
        Property: injectBefore
1919
 
                Inserts the Element before the passed element.
1920
 
 
1921
 
        Arguments:
1922
 
                el - an element reference or the id of the element to be injected in.
1923
 
 
1924
 
        Example:
1925
 
                >html:
1926
 
                ><div id="myElement"></div>
1927
 
                ><div id="mySecondElement"></div>
1928
 
                >js:
1929
 
                >$('mySecondElement').injectBefore('myElement');
1930
 
                >resulting html:
1931
 
                ><div id="mySecondElement"></div>
1932
 
                ><div id="myElement"></div>
1933
 
        */
1934
 
 
1935
 
        injectBefore: function(el){
1936
 
                return this.inject(el, 'before');
1937
 
        },
1938
 
 
1939
 
        /*
1940
 
        Property: injectAfter
1941
 
                Same as <Element.injectBefore>, but inserts the element after.
1942
 
        */
1943
 
 
1944
 
        injectAfter: function(el){
1945
 
                return this.inject(el, 'after');
1946
 
        },
1947
 
 
1948
 
        /*
1949
 
        Property: injectInside
1950
 
                Same as <Element.injectBefore>, but inserts the element inside.
1951
 
        */
1952
 
 
1953
 
        injectInside: function(el){
1954
 
                return this.inject(el, 'bottom');
1955
 
        },
1956
 
 
1957
 
        /*
1958
 
        Property: injectTop
1959
 
                Same as <Element.injectInside>, but inserts the element inside, at the top.
1960
 
        */
1961
 
 
1962
 
        injectTop: function(el){
1963
 
                return this.inject(el, 'top');
1964
 
        },
1965
 
 
1966
 
        /*
1967
 
        Property: adopt
1968
 
                Inserts the passed elements inside the Element.
1969
 
 
1970
 
        Arguments:
1971
 
                accepts elements references, element ids as string, selectors ($$('stuff')) / array of elements, array of ids as strings and collections.
1972
 
        */
1973
 
 
1974
 
        adopt: function(){
1975
 
                var elements = [];
1976
 
                $each(arguments, function(argument){
1977
 
                        elements = elements.concat(argument);
1978
 
                });
1979
 
                $$(elements).inject(this);
1980
 
                return this;
1981
 
        },
1982
 
 
1983
 
        /*
1984
 
        Property: remove
1985
 
                Removes the Element from the DOM.
1986
 
 
1987
 
        Example:
1988
 
                >$('myElement').remove() //bye bye
1989
 
        */
1990
 
 
1991
 
        remove: function(){
1992
 
                return this.parentNode.removeChild(this);
1993
 
        },
1994
 
 
1995
 
        /*
1996
 
        Property: clone
1997
 
                Clones the Element and returns the cloned one.
1998
 
 
1999
 
        Arguments:
2000
 
                contents - boolean, when true the Element is cloned with childNodes, default true
2001
 
 
2002
 
        Returns:
2003
 
                the cloned element
2004
 
 
2005
 
        Example:
2006
 
                >var clone = $('myElement').clone().injectAfter('myElement');
2007
 
                >//clones the Element and append the clone after the Element.
2008
 
        */
2009
 
 
2010
 
        clone: function(contents){
2011
 
                var el = $(this.cloneNode(contents !== false));
2012
 
                if (!el.$events) return el;
2013
 
                el.$events = {};
2014
 
                for (var type in this.$events) el.$events[type] = {
2015
 
                        'keys': $A(this.$events[type].keys),
2016
 
                        'values': $A(this.$events[type].values)
2017
 
                };
2018
 
                return el.removeEvents();
2019
 
        },
2020
 
 
2021
 
        /*
2022
 
        Property: replaceWith
2023
 
                Replaces the Element with an element passed.
2024
 
 
2025
 
        Arguments:
2026
 
                el - a string representing the element to be injected in (myElementId, or div), or an element reference.
2027
 
                If you pass div or another tag, the element will be created.
2028
 
 
2029
 
        Returns:
2030
 
                the passed in element
2031
 
 
2032
 
        Example:
2033
 
                >$('myOldElement').replaceWith($('myNewElement')); //$('myOldElement') is gone, and $('myNewElement') is in its place.
2034
 
        */
2035
 
 
2036
 
        replaceWith: function(el){
2037
 
                el = $(el);
2038
 
                this.parentNode.replaceChild(el, this);
2039
 
                return el;
2040
 
        },
2041
 
 
2042
 
        /*
2043
 
        Property: appendText
2044
 
                Appends text node to a DOM element.
2045
 
 
2046
 
        Arguments:
2047
 
                text - the text to append.
2048
 
 
2049
 
        Example:
2050
 
                ><div id="myElement">hey</div>
2051
 
                >$('myElement').appendText(' howdy'); //myElement innerHTML is now "hey howdy"
2052
 
        */
2053
 
 
2054
 
        appendText: function(text){
2055
 
                this.appendChild(document.createTextNode(text));
2056
 
                return this;
2057
 
        },
2058
 
 
2059
 
        /*
2060
 
        Property: hasClass
2061
 
                Tests the Element to see if it has the passed in className.
2062
 
 
2063
 
        Returns:
2064
 
                true - the Element has the class
2065
 
                false - it doesn't
2066
 
 
2067
 
        Arguments:
2068
 
                className - string; the class name to test.
2069
 
 
2070
 
        Example:
2071
 
                ><div id="myElement" class="testClass"></div>
2072
 
                >$('myElement').hasClass('testClass'); //returns true
2073
 
        */
2074
 
 
2075
 
        hasClass: function(className){
2076
 
                return this.className.contains(className, ' ');
2077
 
        },
2078
 
 
2079
 
        /*
2080
 
        Property: addClass
2081
 
                Adds the passed in class to the Element, if the element doesnt already have it.
2082
 
 
2083
 
        Arguments:
2084
 
                className - string; the class name to add
2085
 
 
2086
 
        Example:
2087
 
                ><div id="myElement" class="testClass"></div>
2088
 
                >$('myElement').addClass('newClass'); //<div id="myElement" class="testClass newClass"></div>
2089
 
        */
2090
 
 
2091
 
        addClass: function(className){
2092
 
                if (!this.hasClass(className)) this.className = (this.className + ' ' + className).clean();
2093
 
                return this;
2094
 
        },
2095
 
 
2096
 
        /*
2097
 
        Property: removeClass
2098
 
                Works like <Element.addClass>, but removes the class from the element.
2099
 
        */
2100
 
 
2101
 
        removeClass: function(className){
2102
 
                this.className = this.className.replace(new RegExp('(^|\\s)' + className + '(?:\\s|$)'), '$1').clean();
2103
 
                return this;
2104
 
        },
2105
 
 
2106
 
        /*
2107
 
        Property: toggleClass
2108
 
                Adds or removes the passed in class name to the element, depending on if it's present or not.
2109
 
 
2110
 
        Arguments:
2111
 
                className - the class to add or remove
2112
 
 
2113
 
        Example:
2114
 
                ><div id="myElement" class="myClass"></div>
2115
 
                >$('myElement').toggleClass('myClass');
2116
 
                ><div id="myElement" class=""></div>
2117
 
                >$('myElement').toggleClass('myClass');
2118
 
                ><div id="myElement" class="myClass"></div>
2119
 
        */
2120
 
 
2121
 
        toggleClass: function(className){
2122
 
                return this.hasClass(className) ? this.removeClass(className) : this.addClass(className);
2123
 
        },
2124
 
 
2125
 
        /*
2126
 
        Property: setStyle
2127
 
                Sets a css property to the Element.
2128
 
 
2129
 
                Arguments:
2130
 
                        property - the property to set
2131
 
                        value - the value to which to set it; for numeric values that require "px" you can pass an integer
2132
 
 
2133
 
                Example:
2134
 
                        >$('myElement').setStyle('width', '300px'); //the width is now 300px
2135
 
                        >$('myElement').setStyle('width', 300); //the width is now 300px
2136
 
        */
2137
 
 
2138
 
        setStyle: function(property, value){
2139
 
                switch(property){
2140
 
                        case 'opacity': return this.setOpacity(parseFloat(value));
2141
 
                        case 'float': property = (window.ie) ? 'styleFloat' : 'cssFloat';
2142
 
                }
2143
 
                property = property.camelCase();
2144
 
                switch($type(value)){
2145
 
                        case 'number': if (!['zIndex', 'zoom'].contains(property)) value += 'px'; break;
2146
 
                        case 'array': value = 'rgb(' + value.join(',') + ')';
2147
 
                }
2148
 
                this.style[property] = value;
2149
 
                return this;
2150
 
        },
2151
 
 
2152
 
        /*
2153
 
        Property: setStyles
2154
 
                Applies a collection of styles to the Element.
2155
 
 
2156
 
        Arguments:
2157
 
                source - an object or string containing all the styles to apply. When its a string it overrides old style.
2158
 
 
2159
 
        Examples:
2160
 
                >$('myElement').setStyles({
2161
 
                >       border: '1px solid #000',
2162
 
                >       width: 300,
2163
 
                >       height: 400
2164
 
                >});
2165
 
 
2166
 
                OR
2167
 
 
2168
 
                >$('myElement').setStyles('border: 1px solid #000; width: 300px; height: 400px;');
2169
 
        */
2170
 
 
2171
 
        setStyles: function(source){
2172
 
                switch($type(source)){
2173
 
                        case 'object': Element.setMany(this, 'setStyle', source); break;
2174
 
                        case 'string': this.style.cssText = source;
2175
 
                }
2176
 
                return this;
2177
 
        },
2178
 
 
2179
 
        /*
2180
 
        Property: setOpacity
2181
 
                Sets the opacity of the Element, and sets also visibility == "hidden" if opacity == 0, and visibility = "visible" if opacity > 0.
2182
 
 
2183
 
        Arguments:
2184
 
                opacity - float; Accepts values from 0 to 1.
2185
 
 
2186
 
        Example:
2187
 
                >$('myElement').setOpacity(0.5) //make it 50% transparent
2188
 
        */
2189
 
 
2190
 
        setOpacity: function(opacity){
2191
 
                if (opacity == 0){
2192
 
                        if (this.style.visibility != "hidden") this.style.visibility = "hidden";
2193
 
                } else {
2194
 
                        if (this.style.visibility != "visible") this.style.visibility = "visible";
2195
 
                }
2196
 
                if (!this.currentStyle || !this.currentStyle.hasLayout) this.style.zoom = 1;
2197
 
                if (window.ie) this.style.filter = (opacity == 1) ? '' : "alpha(opacity=" + opacity * 100 + ")";
2198
 
                this.style.opacity = this.$tmp.opacity = opacity;
2199
 
                return this;
2200
 
        },
2201
 
 
2202
 
        /*
2203
 
        Property: getStyle
2204
 
                Returns the style of the Element given the property passed in.
2205
 
 
2206
 
        Arguments:
2207
 
                property - the css style property you want to retrieve
2208
 
 
2209
 
        Example:
2210
 
                >$('myElement').getStyle('width'); //returns "400px"
2211
 
                >//but you can also use
2212
 
                >$('myElement').getStyle('width').toInt(); //returns 400
2213
 
 
2214
 
        Returns:
2215
 
                the style as a string
2216
 
        */
2217
 
 
2218
 
        getStyle: function(property){
2219
 
                property = property.camelCase();
2220
 
                var result = this.style[property];
2221
 
                if (!$chk(result)){
2222
 
                        if (property == 'opacity') return this.$tmp.opacity;
2223
 
                        result = [];
2224
 
                        for (var style in Element.Styles){
2225
 
                                if (property == style){
2226
 
                                        Element.Styles[style].each(function(s){
2227
 
                                                var style = this.getStyle(s);
2228
 
                                                result.push(parseInt(style) ? style : '0px');
2229
 
                                        }, this);
2230
 
                                        if (property == 'border'){
2231
 
                                                var every = result.every(function(bit){
2232
 
                                                        return (bit == result[0]);
2233
 
                                                });
2234
 
                                                return (every) ? result[0] : false;
2235
 
                                        }
2236
 
                                        return result.join(' ');
2237
 
                                }
2238
 
                        }
2239
 
                        if (property.contains('border')){
2240
 
                                if (Element.Styles.border.contains(property)){
2241
 
                                        return ['Width', 'Style', 'Color'].map(function(p){
2242
 
                                                return this.getStyle(property + p);
2243
 
                                        }, this).join(' ');
2244
 
                                } else if (Element.borderShort.contains(property)){
2245
 
                                        return ['Top', 'Right', 'Bottom', 'Left'].map(function(p){
2246
 
                                                return this.getStyle('border' + p + property.replace('border', ''));
2247
 
                                        }, this).join(' ');
2248
 
                                }
2249
 
                        }
2250
 
                        if (document.defaultView) result = document.defaultView.getComputedStyle(this, null).getPropertyValue(property.hyphenate());
2251
 
                        else if (this.currentStyle) result = this.currentStyle[property];
2252
 
                }
2253
 
                if (window.ie) result = Element.fixStyle(property, result, this);
2254
 
                if (result && property.test(/color/i) && result.contains('rgb')){
2255
 
                        return result.split('rgb').splice(1,4).map(function(color){
2256
 
                                return color.rgbToHex();
2257
 
                        }).join(' ');
2258
 
                }
2259
 
                return result;
2260
 
        },
2261
 
 
2262
 
        /*
2263
 
        Property: getStyles
2264
 
                Returns an object of styles of the Element for each argument passed in.
2265
 
                Arguments:
2266
 
                properties - strings; any number of style properties
2267
 
        Example:
2268
 
                >$('myElement').getStyles('width','height','padding');
2269
 
                >//returns an object like:
2270
 
                >{width: "10px", height: "10px", padding: "10px 0px 10px 0px"}
2271
 
        */
2272
 
 
2273
 
        getStyles: function(){
2274
 
                return Element.getMany(this, 'getStyle', arguments);
2275
 
        },
2276
 
 
2277
 
        walk: function(brother, start){
2278
 
                brother += 'Sibling';
2279
 
                var el = (start) ? this[start] : this[brother];
2280
 
                while (el && $type(el) != 'element') el = el[brother];
2281
 
                return $(el);
2282
 
        },
2283
 
 
2284
 
        /*
2285
 
        Property: getPrevious
2286
 
                Returns the previousSibling of the Element, excluding text nodes.
2287
 
 
2288
 
        Example:
2289
 
                >$('myElement').getPrevious(); //get the previous DOM element from myElement
2290
 
 
2291
 
        Returns:
2292
 
                the sibling element or undefined if none found.
2293
 
        */
2294
 
 
2295
 
        getPrevious: function(){
2296
 
                return this.walk('previous');
2297
 
        },
2298
 
 
2299
 
        /*
2300
 
        Property: getNext
2301
 
                Works as Element.getPrevious, but tries to find the nextSibling.
2302
 
        */
2303
 
 
2304
 
        getNext: function(){
2305
 
                return this.walk('next');
2306
 
        },
2307
 
 
2308
 
        /*
2309
 
        Property: getFirst
2310
 
                Works as <Element.getPrevious>, but tries to find the firstChild.
2311
 
        */
2312
 
 
2313
 
        getFirst: function(){
2314
 
                return this.walk('next', 'firstChild');
2315
 
        },
2316
 
 
2317
 
        /*
2318
 
        Property: getLast
2319
 
                Works as <Element.getPrevious>, but tries to find the lastChild.
2320
 
        */
2321
 
 
2322
 
        getLast: function(){
2323
 
                return this.walk('previous', 'lastChild');
2324
 
        },
2325
 
 
2326
 
        /*
2327
 
        Property: getParent
2328
 
                returns the $(element.parentNode)
2329
 
        */
2330
 
 
2331
 
        getParent: function(){
2332
 
                return $(this.parentNode);
2333
 
        },
2334
 
 
2335
 
        /*
2336
 
        Property: getChildren
2337
 
                returns all the $(element.childNodes), excluding text nodes. Returns as <Elements>.
2338
 
        */
2339
 
 
2340
 
        getChildren: function(){
2341
 
                return $$(this.childNodes);
2342
 
        },
2343
 
 
2344
 
        /*
2345
 
        Property: hasChild
2346
 
                returns true if the passed in element is a child of the $(element).
2347
 
        */
2348
 
 
2349
 
        hasChild: function(el){
2350
 
                return !!$A(this.getElementsByTagName('*')).contains(el);
2351
 
        },
2352
 
 
2353
 
        /*
2354
 
        Property: getProperty
2355
 
                Gets the an attribute of the Element.
2356
 
 
2357
 
        Arguments:
2358
 
                property - string; the attribute to retrieve
2359
 
 
2360
 
        Example:
2361
 
                >$('myImage').getProperty('src') // returns whatever.gif
2362
 
 
2363
 
        Returns:
2364
 
                the value, or an empty string
2365
 
        */
2366
 
 
2367
 
        getProperty: function(property){
2368
 
                var index = Element.Properties[property];
2369
 
                if (index) return this[index];
2370
 
                var flag = Element.PropertiesIFlag[property] || 0;
2371
 
                if (!window.ie || flag) return this.getAttribute(property, flag);
2372
 
                var node = this.attributes[property];
2373
 
                return (node) ? node.nodeValue : null;
2374
 
        },
2375
 
 
2376
 
        /*
2377
 
        Property: removeProperty
2378
 
                Removes an attribute from the Element
2379
 
 
2380
 
        Arguments:
2381
 
                property - string; the attribute to remove
2382
 
        */
2383
 
 
2384
 
        removeProperty: function(property){
2385
 
                var index = Element.Properties[property];
2386
 
                if (index) this[index] = '';
2387
 
                else this.removeAttribute(property);
2388
 
                return this;
2389
 
        },
2390
 
 
2391
 
        /*
2392
 
        Property: getProperties
2393
 
                same as <Element.getStyles>, but for properties
2394
 
        */
2395
 
 
2396
 
        getProperties: function(){
2397
 
                return Element.getMany(this, 'getProperty', arguments);
2398
 
        },
2399
 
 
2400
 
        /*
2401
 
        Property: setProperty
2402
 
                Sets an attribute for the Element.
2403
 
 
2404
 
        Arguments:
2405
 
                property - string; the property to assign the value passed in
2406
 
                value - the value to assign to the property passed in
2407
 
 
2408
 
        Example:
2409
 
                >$('myImage').setProperty('src', 'whatever.gif'); //myImage now points to whatever.gif for its source
2410
 
        */
2411
 
 
2412
 
        setProperty: function(property, value){
2413
 
                var index = Element.Properties[property];
2414
 
                if (index) this[index] = value;
2415
 
                else this.setAttribute(property, value);
2416
 
                return this;
2417
 
        },
2418
 
 
2419
 
        /*
2420
 
        Property: setProperties
2421
 
                Sets numerous attributes for the Element.
2422
 
 
2423
 
        Arguments:
2424
 
                source - an object with key/value pairs.
2425
 
 
2426
 
        Example:
2427
 
                (start code)
2428
 
                $('myElement').setProperties({
2429
 
                        src: 'whatever.gif',
2430
 
                        alt: 'whatever dude'
2431
 
                });
2432
 
                <img src="whatever.gif" alt="whatever dude">
2433
 
                (end)
2434
 
        */
2435
 
 
2436
 
        setProperties: function(source){
2437
 
                return Element.setMany(this, 'setProperty', source);
2438
 
        },
2439
 
 
2440
 
        /*
2441
 
        Property: setHTML
2442
 
                Sets the innerHTML of the Element.
2443
 
 
2444
 
        Arguments:
2445
 
                html - string; the new innerHTML for the element.
2446
 
 
2447
 
        Example:
2448
 
                >$('myElement').setHTML(newHTML) //the innerHTML of myElement is now = newHTML
2449
 
        */
2450
 
 
2451
 
        setHTML: function(){
2452
 
                this.innerHTML = $A(arguments).join('');
2453
 
                return this;
2454
 
        },
2455
 
 
2456
 
        /*
2457
 
        Property: setText
2458
 
                Sets the inner text of the Element.
2459
 
 
2460
 
        Arguments:
2461
 
                text - string; the new text content for the element.
2462
 
 
2463
 
        Example:
2464
 
                >$('myElement').setText('some text') //the text of myElement is now = 'some text'
2465
 
        */
2466
 
 
2467
 
        setText: function(text){
2468
 
                var tag = this.getTag();
2469
 
                if (['style', 'script'].contains(tag)){
2470
 
                        if (window.ie){
2471
 
                                if (tag == 'style') this.styleSheet.cssText = text;
2472
 
                                else if (tag ==  'script') this.setProperty('text', text);
2473
 
                                return this;
2474
 
                        } else {
2475
 
                                this.removeChild(this.firstChild);
2476
 
                                return this.appendText(text);
2477
 
                        }
2478
 
                }
2479
 
                this[$defined(this.innerText) ? 'innerText' : 'textContent'] = text;
2480
 
                return this;
2481
 
        },
2482
 
 
2483
 
        /*
2484
 
        Property: getText
2485
 
                Gets the inner text of the Element.
2486
 
        */
2487
 
 
2488
 
        getText: function(){
2489
 
                var tag = this.getTag();
2490
 
                if (['style', 'script'].contains(tag)){
2491
 
                        if (window.ie){
2492
 
                                if (tag == 'style') return this.styleSheet.cssText;
2493
 
                                else if (tag ==  'script') return this.getProperty('text');
2494
 
                        } else {
2495
 
                                return this.innerHTML;
2496
 
                        }
2497
 
                }
2498
 
                return ($pick(this.innerText, this.textContent));
2499
 
        },
2500
 
 
2501
 
        /*
2502
 
        Property: getTag
2503
 
                Returns the tagName of the element in lower case.
2504
 
 
2505
 
        Example:
2506
 
                >$('myImage').getTag() // returns 'img'
2507
 
 
2508
 
        Returns:
2509
 
                The tag name in lower case
2510
 
        */
2511
 
 
2512
 
        getTag: function(){
2513
 
                return this.tagName.toLowerCase();
2514
 
        },
2515
 
 
2516
 
        /*
2517
 
        Property: empty
2518
 
                Empties an element of all its children.
2519
 
 
2520
 
        Example:
2521
 
                >$('myDiv').empty() // empties the Div and returns it
2522
 
 
2523
 
        Returns:
2524
 
                The element.
2525
 
        */
2526
 
 
2527
 
        empty: function(){
2528
 
                Garbage.trash(this.getElementsByTagName('*'));
2529
 
                return this.setHTML('');
2530
 
        }
2531
 
 
2532
 
});
2533
 
 
2534
 
Element.fixStyle = function(property, result, element){
2535
 
        if ($chk(parseInt(result))) return result;
2536
 
        if (['height', 'width'].contains(property)){
2537
 
                var values = (property == 'width') ? ['left', 'right'] : ['top', 'bottom'];
2538
 
                var size = 0;
2539
 
                values.each(function(value){
2540
 
                        size += element.getStyle('border-' + value + '-width').toInt() + element.getStyle('padding-' + value).toInt();
2541
 
                });
2542
 
                return element['offset' + property.capitalize()] - size + 'px';
2543
 
        } else if (property.test(/border(.+)Width|margin|padding/)){
2544
 
                return '0px';
2545
 
        }
2546
 
        return result;
2547
 
};
2548
 
 
2549
 
Element.Styles = {'border': [], 'padding': [], 'margin': []};
2550
 
['Top', 'Right', 'Bottom', 'Left'].each(function(direction){
2551
 
        for (var style in Element.Styles) Element.Styles[style].push(style + direction);
2552
 
});
2553
 
 
2554
 
Element.borderShort = ['borderWidth', 'borderStyle', 'borderColor'];
2555
 
 
2556
 
Element.getMany = function(el, method, keys){
2557
 
        var result = {};
2558
 
        $each(keys, function(key){
2559
 
                result[key] = el[method](key);
2560
 
        });
2561
 
        return result;
2562
 
};
2563
 
 
2564
 
Element.setMany = function(el, method, pairs){
2565
 
        for (var key in pairs) el[method](key, pairs[key]);
2566
 
        return el;
2567
 
};
2568
 
 
2569
 
Element.Properties = new Abstract({
2570
 
        'class': 'className', 'for': 'htmlFor', 'colspan': 'colSpan', 'rowspan': 'rowSpan',
2571
 
        'accesskey': 'accessKey', 'tabindex': 'tabIndex', 'maxlength': 'maxLength',
2572
 
        'readonly': 'readOnly', 'frameborder': 'frameBorder', 'value': 'value',
2573
 
        'disabled': 'disabled', 'checked': 'checked', 'multiple': 'multiple', 'selected': 'selected'
2574
 
});
2575
 
Element.PropertiesIFlag = {
2576
 
        'href': 2, 'src': 2
2577
 
};
2578
 
 
2579
 
Element.Methods = {
2580
 
        Listeners: {
2581
 
                addListener: function(type, fn){
2582
 
                        if (this.addEventListener) this.addEventListener(type, fn, false);
2583
 
                        else this.attachEvent('on' + type, fn);
2584
 
                        return this;
2585
 
                },
2586
 
 
2587
 
                removeListener: function(type, fn){
2588
 
                        if (this.removeEventListener) this.removeEventListener(type, fn, false);
2589
 
                        else this.detachEvent('on' + type, fn);
2590
 
                        return this;
2591
 
                }
2592
 
        }
2593
 
};
2594
 
 
2595
 
window.extend(Element.Methods.Listeners);
2596
 
document.extend(Element.Methods.Listeners);
2597
 
Element.extend(Element.Methods.Listeners);
2598
 
 
2599
 
var Garbage = {
2600
 
 
2601
 
        elements: [],
2602
 
 
2603
 
        collect: function(el){
2604
 
                if (!el.$tmp){
2605
 
                        Garbage.elements.push(el);
2606
 
                        el.$tmp = {'opacity': 1};
2607
 
                }
2608
 
                return el;
2609
 
        },
2610
 
 
2611
 
        trash: function(elements){
2612
 
                for (var i = 0, j = elements.length, el; i < j; i++){
2613
 
                        if (!(el = elements[i]) || !el.$tmp) continue;
2614
 
                        if (el.$events) el.fireEvent('trash').removeEvents();
2615
 
                        for (var p in el.$tmp) el.$tmp[p] = null;
2616
 
                        for (var d in Element.prototype) el[d] = null;
2617
 
                        Garbage.elements[Garbage.elements.indexOf(el)] = null;
2618
 
                        el.htmlElement = el.$tmp = el = null;
2619
 
                }
2620
 
                Garbage.elements.remove(null);
2621
 
        },
2622
 
 
2623
 
        empty: function(){
2624
 
                Garbage.collect(window);
2625
 
                Garbage.collect(document);
2626
 
                Garbage.trash(Garbage.elements);
2627
 
        }
2628
 
 
2629
 
};
2630
 
 
2631
 
window.addListener('beforeunload', function(){
2632
 
        window.addListener('unload', Garbage.empty);
2633
 
        if (window.ie) window.addListener('unload', CollectGarbage);
2634
 
});
2635
 
 
2636
 
/*
2637
 
Script: Element.Event.js
2638
 
        Contains the Event Class, Element methods to deal with Element events, custom Events, and the Function prototype bindWithEvent.
2639
 
 
2640
 
License:
2641
 
        MIT-style license.
2642
 
*/
2643
 
 
2644
 
/*
2645
 
Class: Event
2646
 
        Cross browser methods to manage events.
2647
 
 
2648
 
Arguments:
2649
 
        event - the event
2650
 
 
2651
 
Properties:
2652
 
        shift - true if the user pressed the shift
2653
 
        control - true if the user pressed the control
2654
 
        alt - true if the user pressed the alt
2655
 
        meta - true if the user pressed the meta key
2656
 
        wheel - the amount of third button scrolling
2657
 
        code - the keycode of the key pressed
2658
 
        page.x - the x position of the mouse, relative to the full window
2659
 
        page.y - the y position of the mouse, relative to the full window
2660
 
        client.x - the x position of the mouse, relative to the viewport
2661
 
        client.y - the y position of the mouse, relative to the viewport
2662
 
        key - the key pressed as a lowercase string. key also returns 'enter', 'up', 'down', 'left', 'right', 'space', 'backspace', 'delete', 'esc'. Handy for these special keys.
2663
 
        target - the event target
2664
 
        relatedTarget - the event related target
2665
 
 
2666
 
Example:
2667
 
        (start code)
2668
 
        $('myLink').onkeydown = function(event){
2669
 
                var event = new Event(event);
2670
 
                //event is now the Event class.
2671
 
                alert(event.key); //returns the lowercase letter pressed
2672
 
                alert(event.shift); //returns true if the key pressed is shift
2673
 
                if (event.key == 's' && event.control) alert('document saved');
2674
 
        };
2675
 
        (end)
2676
 
*/
2677
 
 
2678
 
var Event = new Class({
2679
 
 
2680
 
        initialize: function(event){
2681
 
                if (event && event.$extended) return event;
2682
 
                this.$extended = true;
2683
 
                event = event || window.event;
2684
 
                this.event = event;
2685
 
                this.type = event.type;
2686
 
                this.target = event.target || event.srcElement;
2687
 
                if (this.target.nodeType == 3) this.target = this.target.parentNode;
2688
 
                this.shift = event.shiftKey;
2689
 
                this.control = event.ctrlKey;
2690
 
                this.alt = event.altKey;
2691
 
                this.meta = event.metaKey;
2692
 
                if (['DOMMouseScroll', 'mousewheel'].contains(this.type)){
2693
 
                        this.wheel = (event.wheelDelta) ? event.wheelDelta / 120 : -(event.detail || 0) / 3;
2694
 
                } else if (this.type.contains('key')){
2695
 
                        this.code = event.which || event.keyCode;
2696
 
                        for (var name in Event.keys){
2697
 
                                if (Event.keys[name] == this.code){
2698
 
                                        this.key = name;
2699
 
                                        break;
2700
 
                                }
2701
 
                        }
2702
 
                        if (this.type == 'keydown'){
2703
 
                                var fKey = this.code - 111;
2704
 
                                if (fKey > 0 && fKey < 13) this.key = 'f' + fKey;
2705
 
                        }
2706
 
                        this.key = this.key || String.fromCharCode(this.code).toLowerCase();
2707
 
                } else if (this.type.test(/(click|mouse|menu)/)){
2708
 
                        this.page = {
2709
 
                                'x': event.pageX || event.clientX + document.documentElement.scrollLeft,
2710
 
                                'y': event.pageY || event.clientY + document.documentElement.scrollTop
2711
 
                        };
2712
 
                        this.client = {
2713
 
                                'x': event.pageX ? event.pageX - window.pageXOffset : event.clientX,
2714
 
                                'y': event.pageY ? event.pageY - window.pageYOffset : event.clientY
2715
 
                        };
2716
 
                        this.rightClick = (event.which == 3) || (event.button == 2);
2717
 
                        switch(this.type){
2718
 
                                case 'mouseover': this.relatedTarget = event.relatedTarget || event.fromElement; break;
2719
 
                                case 'mouseout': this.relatedTarget = event.relatedTarget || event.toElement;
2720
 
                        }
2721
 
                        this.fixRelatedTarget();
2722
 
                }
2723
 
                return this;
2724
 
        },
2725
 
 
2726
 
        /*
2727
 
        Property: stop
2728
 
                cross browser method to stop an event
2729
 
        */
2730
 
 
2731
 
        stop: function(){
2732
 
                return this.stopPropagation().preventDefault();
2733
 
        },
2734
 
 
2735
 
        /*
2736
 
        Property: stopPropagation
2737
 
                cross browser method to stop the propagation of an event
2738
 
        */
2739
 
 
2740
 
        stopPropagation: function(){
2741
 
                if (this.event.stopPropagation) this.event.stopPropagation();
2742
 
                else this.event.cancelBubble = true;
2743
 
                return this;
2744
 
        },
2745
 
 
2746
 
        /*
2747
 
        Property: preventDefault
2748
 
                cross browser method to prevent the default action of the event
2749
 
        */
2750
 
 
2751
 
        preventDefault: function(){
2752
 
                if (this.event.preventDefault) this.event.preventDefault();
2753
 
                else this.event.returnValue = false;
2754
 
                return this;
2755
 
        }
2756
 
 
2757
 
});
2758
 
 
2759
 
Event.fix = {
2760
 
 
2761
 
        relatedTarget: function(){
2762
 
                if (this.relatedTarget && this.relatedTarget.nodeType == 3) this.relatedTarget = this.relatedTarget.parentNode;
2763
 
        },
2764
 
 
2765
 
        relatedTargetGecko: function(){
2766
 
                try {Event.fix.relatedTarget.call(this);} catch(e){this.relatedTarget = this.target;}
2767
 
        }
2768
 
 
2769
 
};
2770
 
 
2771
 
Event.prototype.fixRelatedTarget = (window.gecko) ? Event.fix.relatedTargetGecko : Event.fix.relatedTarget;
2772
 
 
2773
 
/*
2774
 
Property: keys
2775
 
        you can add additional Event keys codes this way:
2776
 
 
2777
 
Example:
2778
 
        (start code)
2779
 
        Event.keys.whatever = 80;
2780
 
        $(myelement).addEvent(keydown, function(event){
2781
 
                event = new Event(event);
2782
 
                if (event.key == 'whatever') console.log(whatever key clicked).
2783
 
        });
2784
 
        (end)
2785
 
*/
2786
 
 
2787
 
Event.keys = new Abstract({
2788
 
        'enter': 13,
2789
 
        'up': 38,
2790
 
        'down': 40,
2791
 
        'left': 37,
2792
 
        'right': 39,
2793
 
        'esc': 27,
2794
 
        'space': 32,
2795
 
        'backspace': 8,
2796
 
        'tab': 9,
2797
 
        'delete': 46
2798
 
});
2799
 
 
2800
 
/*
2801
 
Class: Element
2802
 
        Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>.
2803
 
*/
2804
 
 
2805
 
Element.Methods.Events = {
2806
 
 
2807
 
        /*
2808
 
        Property: addEvent
2809
 
                Attaches an event listener to a DOM element.
2810
 
 
2811
 
        Arguments:
2812
 
                type - the event to monitor ('click', 'load', etc) without the prefix 'on'.
2813
 
                fn - the function to execute
2814
 
 
2815
 
        Example:
2816
 
                >$('myElement').addEvent('click', function(){alert('clicked!')});
2817
 
        */
2818
 
 
2819
 
        addEvent: function(type, fn){
2820
 
                this.$events = this.$events || {};
2821
 
                this.$events[type] = this.$events[type] || {'keys': [], 'values': []};
2822
 
                if (this.$events[type].keys.contains(fn)) return this;
2823
 
                this.$events[type].keys.push(fn);
2824
 
                var realType = type;
2825
 
                var custom = Element.Events[type];
2826
 
                if (custom){
2827
 
                        if (custom.add) custom.add.call(this, fn);
2828
 
                        if (custom.map) fn = custom.map;
2829
 
                        if (custom.type) realType = custom.type;
2830
 
                }
2831
 
                if (!this.addEventListener) fn = fn.create({'bind': this, 'event': true});
2832
 
                this.$events[type].values.push(fn);
2833
 
                return (Element.NativeEvents.contains(realType)) ? this.addListener(realType, fn) : this;
2834
 
        },
2835
 
 
2836
 
        /*
2837
 
        Property: removeEvent
2838
 
                Works as Element.addEvent, but instead removes the previously added event listener.
2839
 
        */
2840
 
 
2841
 
        removeEvent: function(type, fn){
2842
 
                if (!this.$events || !this.$events[type]) return this;
2843
 
                var pos = this.$events[type].keys.indexOf(fn);
2844
 
                if (pos == -1) return this;
2845
 
                var key = this.$events[type].keys.splice(pos,1)[0];
2846
 
                var value = this.$events[type].values.splice(pos,1)[0];
2847
 
                var custom = Element.Events[type];
2848
 
                if (custom){
2849
 
                        if (custom.remove) custom.remove.call(this, fn);
2850
 
                        if (custom.type) type = custom.type;
2851
 
                }
2852
 
                return (Element.NativeEvents.contains(type)) ? this.removeListener(type, value) : this;
2853
 
        },
2854
 
 
2855
 
        /*
2856
 
        Property: addEvents
2857
 
                As <addEvent>, but accepts an object and add multiple events at once.
2858
 
        */
2859
 
 
2860
 
        addEvents: function(source){
2861
 
                return Element.setMany(this, 'addEvent', source);
2862
 
        },
2863
 
 
2864
 
        /*
2865
 
        Property: removeEvents
2866
 
                removes all events of a certain type from an element. if no argument is passed in, removes all events.
2867
 
 
2868
 
        Arguments:
2869
 
                type - string; the event name (e.g. 'click')
2870
 
        */
2871
 
 
2872
 
        removeEvents: function(type){
2873
 
                if (!this.$events) return this;
2874
 
                if (!type){
2875
 
                        for (var evType in this.$events) this.removeEvents(evType);
2876
 
                        this.$events = null;
2877
 
                } else if (this.$events[type]){
2878
 
                        this.$events[type].keys.each(function(fn){
2879
 
                                this.removeEvent(type, fn);
2880
 
                        }, this);
2881
 
                        this.$events[type] = null;
2882
 
                }
2883
 
                return this;
2884
 
        },
2885
 
 
2886
 
        /*
2887
 
        Property: fireEvent
2888
 
                executes all events of the specified type present in the element.
2889
 
 
2890
 
        Arguments:
2891
 
                type - string; the event name (e.g. 'click')
2892
 
                args - array or single object; arguments to pass to the function; if more than one argument, must be an array
2893
 
                delay - (integer) delay (in ms) to wait to execute the event
2894
 
        */
2895
 
 
2896
 
        fireEvent: function(type, args, delay){
2897
 
                if (this.$events && this.$events[type]){
2898
 
                        this.$events[type].keys.each(function(fn){
2899
 
                                fn.create({'bind': this, 'delay': delay, 'arguments': args})();
2900
 
                        }, this);
2901
 
                }
2902
 
                return this;
2903
 
        },
2904
 
 
2905
 
        /*
2906
 
        Property: cloneEvents
2907
 
                Clones all events from an element to this element.
2908
 
 
2909
 
        Arguments:
2910
 
                from - element, copy all events from this element
2911
 
                type - optional, copies only events of this type
2912
 
        */
2913
 
 
2914
 
        cloneEvents: function(from, type){
2915
 
                if (!from.$events) return this;
2916
 
                if (!type){
2917
 
                        for (var evType in from.$events) this.cloneEvents(from, evType);
2918
 
                } else if (from.$events[type]){
2919
 
                        from.$events[type].keys.each(function(fn){
2920
 
                                this.addEvent(type, fn);
2921
 
                        }, this);
2922
 
                }
2923
 
                return this;
2924
 
        }
2925
 
 
2926
 
};
2927
 
 
2928
 
window.extend(Element.Methods.Events);
2929
 
document.extend(Element.Methods.Events);
2930
 
Element.extend(Element.Methods.Events);
2931
 
 
2932
 
/* Section: Custom Events */
2933
 
 
2934
 
Element.Events = new Abstract({
2935
 
 
2936
 
        /*
2937
 
        Event: mouseenter
2938
 
                In addition to the standard javascript events (load, mouseover, mouseout, click, etc.) <Event.js> contains two custom events
2939
 
                this event fires when the mouse enters the area of the dom element; will not be fired again if the mouse crosses over children of the element (unlike mouseover)
2940
 
 
2941
 
 
2942
 
        Example:
2943
 
                >$(myElement).addEvent('mouseenter', myFunction);
2944
 
        */
2945
 
 
2946
 
        'mouseenter': {
2947
 
                type: 'mouseover',
2948
 
                map: function(event){
2949
 
                        event = new Event(event);
2950
 
                        if (event.relatedTarget != this && !this.hasChild(event.relatedTarget)) this.fireEvent('mouseenter', event);
2951
 
                }
2952
 
        },
2953
 
 
2954
 
        /*
2955
 
        Event: mouseleave
2956
 
                this event fires when the mouse exits the area of the dom element; will not be fired again if the mouse crosses over children of the element (unlike mouseout)
2957
 
 
2958
 
 
2959
 
        Example:
2960
 
                >$(myElement).addEvent('mouseleave', myFunction);
2961
 
        */
2962
 
 
2963
 
        'mouseleave': {
2964
 
                type: 'mouseout',
2965
 
                map: function(event){
2966
 
                        event = new Event(event);
2967
 
                        if (event.relatedTarget != this && !this.hasChild(event.relatedTarget)) this.fireEvent('mouseleave', event);
2968
 
                }
2969
 
        },
2970
 
 
2971
 
        'mousewheel': {
2972
 
                type: (window.gecko) ? 'DOMMouseScroll' : 'mousewheel'
2973
 
        }
2974
 
 
2975
 
});
2976
 
 
2977
 
Element.NativeEvents = [
2978
 
        'click', 'dblclick', 'mouseup', 'mousedown', //mouse buttons
2979
 
        'mousewheel', 'DOMMouseScroll', //mouse wheel
2980
 
        'mouseover', 'mouseout', 'mousemove', //mouse movement
2981
 
        'keydown', 'keypress', 'keyup', //keys
2982
 
        'load', 'unload', 'beforeunload', 'resize', 'move', //window
2983
 
        'focus', 'blur', 'change', 'submit', 'reset', 'select', //forms elements
2984
 
        'error', 'abort', 'contextmenu', 'scroll' //misc
2985
 
];
2986
 
 
2987
 
/*
2988
 
Class: Function
2989
 
        A collection of The Function Object prototype methods.
2990
 
*/
2991
 
 
2992
 
Function.extend({
2993
 
 
2994
 
        /*
2995
 
        Property: bindWithEvent
2996
 
                automatically passes MooTools Event Class.
2997
 
 
2998
 
        Arguments:
2999
 
                bind - optional, the object that the "this" of the function will refer to.
3000
 
                args - optional, an argument to pass to the function; if more than one argument, it must be an array of arguments.
3001
 
 
3002
 
        Returns:
3003
 
                a function with the parameter bind as its "this" and as a pre-passed argument event or window.event, depending on the browser.
3004
 
 
3005
 
        Example:
3006
 
                >function myFunction(event){
3007
 
                >       alert(event.client.x) //returns the coordinates of the mouse..
3008
 
                >};
3009
 
                >myElement.addEvent('click', myFunction.bindWithEvent(myElement));
3010
 
        */
3011
 
 
3012
 
        bindWithEvent: function(bind, args){
3013
 
                return this.create({'bind': bind, 'arguments': args, 'event': Event});
3014
 
        }
3015
 
 
3016
 
});
3017
 
 
3018
 
 
3019
 
/*
3020
 
Script: Element.Filters.js
3021
 
        add Filters capability to <Elements>.
3022
 
 
3023
 
License:
3024
 
        MIT-style license.
3025
 
*/
3026
 
 
3027
 
/*
3028
 
Class: Elements
3029
 
        A collection of methods to be used with <$$> elements collections.
3030
 
*/
3031
 
 
3032
 
Elements.extend({
3033
 
        
3034
 
        /*
3035
 
        Property: filterByTag
3036
 
                Filters the collection by a specified tag name.
3037
 
                Returns a new Elements collection, while the original remains untouched.
3038
 
        */
3039
 
        
3040
 
        filterByTag: function(tag){
3041
 
                return new Elements(this.filter(function(el){
3042
 
                        return (Element.getTag(el) == tag);
3043
 
                }));
3044
 
        },
3045
 
        
3046
 
        /*
3047
 
        Property: filterByClass
3048
 
                Filters the collection by a specified class name.
3049
 
                Returns a new Elements collection, while the original remains untouched.
3050
 
        */
3051
 
        
3052
 
        filterByClass: function(className, nocash){
3053
 
                var elements = this.filter(function(el){
3054
 
                        return (el.className && el.className.contains(className, ' '));
3055
 
                });
3056
 
                return (nocash) ? elements : new Elements(elements);
3057
 
        },
3058
 
        
3059
 
        /*
3060
 
        Property: filterById
3061
 
                Filters the collection by a specified ID.
3062
 
                Returns a new Elements collection, while the original remains untouched.
3063
 
        */
3064
 
        
3065
 
        filterById: function(id, nocash){
3066
 
                var elements = this.filter(function(el){
3067
 
                        return (el.id == id);
3068
 
                });
3069
 
                return (nocash) ? elements : new Elements(elements);
3070
 
        },
3071
 
        
3072
 
        /*
3073
 
        Property: filterByAttribute
3074
 
                Filters the collection by a specified attribute.
3075
 
                Returns a new Elements collection, while the original remains untouched.
3076
 
                
3077
 
        Arguments:
3078
 
                name - the attribute name.
3079
 
                operator - optional, the attribute operator.
3080
 
                value - optional, the attribute value, only valid if the operator is specified.
3081
 
        */
3082
 
        
3083
 
        filterByAttribute: function(name, operator, value, nocash){
3084
 
                var elements = this.filter(function(el){
3085
 
                        var current = Element.getProperty(el, name);
3086
 
                        if (!current) return false;
3087
 
                        if (!operator) return true;
3088
 
                        switch(operator){
3089
 
                                case '=': return (current == value);
3090
 
                                case '*=': return (current.contains(value));
3091
 
                                case '^=': return (current.substr(0, value.length) == value);
3092
 
                                case '$=': return (current.substr(current.length - value.length) == value);
3093
 
                                case '!=': return (current != value);
3094
 
                                case '~=': return current.contains(value, ' ');
3095
 
                        }
3096
 
                        return false;
3097
 
                });
3098
 
                return (nocash) ? elements : new Elements(elements);
3099
 
        }
3100
 
 
3101
 
});
3102
 
 
3103
 
/*
3104
 
Script: Element.Selectors.js
3105
 
        Css Query related functions and <Element> extensions
3106
 
 
3107
 
License:
3108
 
        MIT-style license.
3109
 
*/
3110
 
 
3111
 
/* Section: Utility Functions */
3112
 
 
3113
 
/*
3114
 
Function: $E
3115
 
        Selects a single (i.e. the first found) Element based on the selector passed in and an optional filter element.
3116
 
        Returns as <Element>.
3117
 
 
3118
 
Arguments:
3119
 
        selector - string; the css selector to match
3120
 
        filter - optional; a DOM element to limit the scope of the selector match; defaults to document.
3121
 
 
3122
 
Example:
3123
 
        >$E('a', 'myElement') //find the first anchor tag inside the DOM element with id 'myElement'
3124
 
 
3125
 
Returns:
3126
 
        a DOM element - the first element that matches the selector
3127
 
*/
3128
 
 
3129
 
function $E(selector, filter){
3130
 
        return ($(filter) || document).getElement(selector);
3131
 
};
3132
 
 
3133
 
/*
3134
 
Function: $ES
3135
 
        Returns a collection of Elements that match the selector passed in limited to the scope of the optional filter.
3136
 
        See Also: <Element.getElements> for an alternate syntax.
3137
 
        Returns as <Elements>.
3138
 
 
3139
 
Returns:
3140
 
        an array of dom elements that match the selector within the filter
3141
 
 
3142
 
Arguments:
3143
 
        selector - string; css selector to match
3144
 
        filter - optional; a DOM element to limit the scope of the selector match; defaults to document.
3145
 
 
3146
 
Examples:
3147
 
        >$ES("a") //gets all the anchor tags; synonymous with $$("a")
3148
 
        >$ES('a','myElement') //get all the anchor tags within $('myElement')
3149
 
*/
3150
 
 
3151
 
function $ES(selector, filter){
3152
 
        return ($(filter) || document).getElementsBySelector(selector);
3153
 
};
3154
 
 
3155
 
$$.shared = {
3156
 
 
3157
 
        'regexp': /^(\w*|\*)(?:#([\w-]+)|\.([\w-]+))?(?:\[(\w+)(?:([!*^$]?=)["']?([^"'\]]*)["']?)?])?$/,
3158
 
        
3159
 
        'xpath': {
3160
 
 
3161
 
                getParam: function(items, context, param, i){
3162
 
                        var temp = [context.namespaceURI ? 'xhtml:' : '', param[1]];
3163
 
                        if (param[2]) temp.push('[@id="', param[2], '"]');
3164
 
                        if (param[3]) temp.push('[contains(concat(" ", @class, " "), " ', param[3], ' ")]');
3165
 
                        if (param[4]){
3166
 
                                if (param[5] && param[6]){
3167
 
                                        switch(param[5]){
3168
 
                                                case '*=': temp.push('[contains(@', param[4], ', "', param[6], '")]'); break;
3169
 
                                                case '^=': temp.push('[starts-with(@', param[4], ', "', param[6], '")]'); break;
3170
 
                                                case '$=': temp.push('[substring(@', param[4], ', string-length(@', param[4], ') - ', param[6].length, ' + 1) = "', param[6], '"]'); break;
3171
 
                                                case '=': temp.push('[@', param[4], '="', param[6], '"]'); break;
3172
 
                                                case '!=': temp.push('[@', param[4], '!="', param[6], '"]');
3173
 
                                        }
3174
 
                                } else {
3175
 
                                        temp.push('[@', param[4], ']');
3176
 
                                }
3177
 
                        }
3178
 
                        items.push(temp.join(''));
3179
 
                        return items;
3180
 
                },
3181
 
                
3182
 
                getItems: function(items, context, nocash){
3183
 
                        var elements = [];
3184
 
                        var xpath = document.evaluate('.//' + items.join('//'), context, $$.shared.resolver, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
3185
 
                        for (var i = 0, j = xpath.snapshotLength; i < j; i++) elements.push(xpath.snapshotItem(i));
3186
 
                        return (nocash) ? elements : new Elements(elements.map($));
3187
 
                }
3188
 
 
3189
 
        },
3190
 
        
3191
 
        'normal': {
3192
 
                
3193
 
                getParam: function(items, context, param, i){
3194
 
                        if (i == 0){
3195
 
                                if (param[2]){
3196
 
                                        var el = context.getElementById(param[2]);
3197
 
                                        if (!el || ((param[1] != '*') && (Element.getTag(el) != param[1]))) return false;
3198
 
                                        items = [el];
3199
 
                                } else {
3200
 
                                        items = $A(context.getElementsByTagName(param[1]));
3201
 
                                }
3202
 
                        } else {
3203
 
                                items = $$.shared.getElementsByTagName(items, param[1]);
3204
 
                                if (param[2]) items = Elements.filterById(items, param[2], true);
3205
 
                        }
3206
 
                        if (param[3]) items = Elements.filterByClass(items, param[3], true);
3207
 
                        if (param[4]) items = Elements.filterByAttribute(items, param[4], param[5], param[6], true);
3208
 
                        return items;
3209
 
                },
3210
 
 
3211
 
                getItems: function(items, context, nocash){
3212
 
                        return (nocash) ? items : $$.unique(items);
3213
 
                }
3214
 
 
3215
 
        },
3216
 
 
3217
 
        resolver: function(prefix){
3218
 
                return (prefix == 'xhtml') ? 'http://www.w3.org/1999/xhtml' : false;
3219
 
        },
3220
 
 
3221
 
        getElementsByTagName: function(context, tagName){
3222
 
                var found = [];
3223
 
                for (var i = 0, j = context.length; i < j; i++) found.extend(context[i].getElementsByTagName(tagName));
3224
 
                return found;
3225
 
        }
3226
 
 
3227
 
};
3228
 
 
3229
 
$$.shared.method = (window.xpath) ? 'xpath' : 'normal';
3230
 
 
3231
 
/*
3232
 
Class: Element
3233
 
        Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>.
3234
 
*/
3235
 
 
3236
 
Element.Methods.Dom = {
3237
 
 
3238
 
        /*
3239
 
        Property: getElements
3240
 
                Gets all the elements within an element that match the given (single) selector.
3241
 
                Returns as <Elements>.
3242
 
 
3243
 
        Arguments:
3244
 
                selector - string; the css selector to match
3245
 
 
3246
 
        Examples:
3247
 
                >$('myElement').getElements('a'); // get all anchors within myElement
3248
 
                >$('myElement').getElements('input[name=dialog]') //get all input tags with name 'dialog'
3249
 
                >$('myElement').getElements('input[name$=log]') //get all input tags with names ending with 'log'
3250
 
 
3251
 
        Notes:
3252
 
                Supports these operators in attribute selectors:
3253
 
 
3254
 
                - = : is equal to
3255
 
                - ^= : starts-with
3256
 
                - $= : ends-with
3257
 
                - != : is not equal to
3258
 
 
3259
 
                Xpath is used automatically for compliant browsers.
3260
 
        */
3261
 
 
3262
 
        getElements: function(selector, nocash){
3263
 
                var items = [];
3264
 
                selector = selector.trim().split(' ');
3265
 
                for (var i = 0, j = selector.length; i < j; i++){
3266
 
                        var sel = selector[i];
3267
 
                        var param = sel.match($$.shared.regexp);
3268
 
                        if (!param) break;
3269
 
                        param[1] = param[1] || '*';
3270
 
                        var temp = $$.shared[$$.shared.method].getParam(items, this, param, i);
3271
 
                        if (!temp) break;
3272
 
                        items = temp;
3273
 
                }
3274
 
                return $$.shared[$$.shared.method].getItems(items, this, nocash);
3275
 
        },
3276
 
 
3277
 
        /*
3278
 
        Property: getElement
3279
 
                Same as <Element.getElements>, but returns only the first. Alternate syntax for <$E>, where filter is the Element.
3280
 
                Returns as <Element>.
3281
 
 
3282
 
        Arguments:
3283
 
                selector - string; css selector
3284
 
        */
3285
 
 
3286
 
        getElement: function(selector){
3287
 
                return $(this.getElements(selector, true)[0] || false);
3288
 
        },
3289
 
 
3290
 
        /*
3291
 
        Property: getElementsBySelector
3292
 
                Same as <Element.getElements>, but allows for comma separated selectors, as in css. Alternate syntax for <$$>, where filter is the Element.
3293
 
                Returns as <Elements>.
3294
 
 
3295
 
        Arguments:
3296
 
                selector - string; css selector
3297
 
        */
3298
 
 
3299
 
        getElementsBySelector: function(selector, nocash){
3300
 
                var elements = [];
3301
 
                selector = selector.split(',');
3302
 
                for (var i = 0, j = selector.length; i < j; i++) elements = elements.concat(this.getElements(selector[i], true));
3303
 
                return (nocash) ? elements : $$.unique(elements);
3304
 
        }
3305
 
 
3306
 
};
3307
 
 
3308
 
Element.extend({
3309
 
 
3310
 
        /*
3311
 
        Property: getElementById
3312
 
                Targets an element with the specified id found inside the Element. Does not overwrite document.getElementById.
3313
 
 
3314
 
        Arguments:
3315
 
                id - string; the id of the element to find.
3316
 
        */
3317
 
 
3318
 
        getElementById: function(id){
3319
 
                var el = document.getElementById(id);
3320
 
                if (!el) return false;
3321
 
                for (var parent = el.parentNode; parent != this; parent = parent.parentNode){
3322
 
                        if (!parent) return false;
3323
 
                }
3324
 
                return el;
3325
 
        }/*compatibility*/,
3326
 
        
3327
 
        getElementsByClassName: function(className){ 
3328
 
                return this.getElements('.' + className); 
3329
 
        }
3330
 
        
3331
 
        /*end compatibility*/
3332
 
 
3333
 
});
3334
 
 
3335
 
document.extend(Element.Methods.Dom);
3336
 
Element.extend(Element.Methods.Dom);
3337
 
 
3338
 
/*
3339
 
Script: Element.Form.js
3340
 
        Contains Element prototypes to deal with Forms and their elements.
3341
 
 
3342
 
License:
3343
 
        MIT-style license.
3344
 
*/
3345
 
 
3346
 
/*
3347
 
Class: Element
3348
 
        Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>.
3349
 
*/
3350
 
 
3351
 
Element.extend({
3352
 
 
3353
 
        /*
3354
 
        Property: getValue
3355
 
                Returns the value of the Element, if its tag is textarea, select or input. getValue called on a multiple select will return an array.
3356
 
        */
3357
 
 
3358
 
        getValue: function(){
3359
 
                switch(this.getTag()){
3360
 
                        case 'select':
3361
 
                                var values = [];
3362
 
                                $each(this.options, function(option){
3363
 
                                        if (option.selected) values.push($pick(option.value, option.text));
3364
 
                                });
3365
 
                                return (this.multiple) ? values : values[0];
3366
 
                        case 'input': if (!(this.checked && ['checkbox', 'radio'].contains(this.type)) && !['hidden', 'text', 'password'].contains(this.type)) break;
3367
 
                        case 'textarea': return this.value;
3368
 
                }
3369
 
                return false;
3370
 
        },
3371
 
 
3372
 
        getFormElements: function(){
3373
 
                return $$(this.getElementsByTagName('input'), this.getElementsByTagName('select'), this.getElementsByTagName('textarea'));
3374
 
        },
3375
 
 
3376
 
        /*
3377
 
        Property: toQueryString
3378
 
                Reads the children inputs of the Element and generates a query string, based on their values. Used internally in <Ajax>
3379
 
 
3380
 
        Example:
3381
 
                (start code)
3382
 
                <form id="myForm" action="submit.php">
3383
 
                <input name="email" value="bob@bob.com">
3384
 
                <input name="zipCode" value="90210">
3385
 
                </form>
3386
 
 
3387
 
                <script>
3388
 
                 $('myForm').toQueryString()
3389
 
                </script>
3390
 
                (end)
3391
 
 
3392
 
                Returns:
3393
 
                        email=bob@bob.com&zipCode=90210
3394
 
        */
3395
 
 
3396
 
        toQueryString: function(){
3397
 
                var queryString = [];
3398
 
                this.getFormElements().each(function(el){
3399
 
                        var name = el.name;
3400
 
                        var value = el.getValue();
3401
 
                        if (value === false || !name || el.disabled) return;
3402
 
                        var qs = function(val){
3403
 
                                queryString.push(name + '=' + encodeURIComponent(val));
3404
 
                        };
3405
 
                        if ($type(value) == 'array') value.each(qs);
3406
 
                        else qs(value);
3407
 
                });
3408
 
                return queryString.join('&');
3409
 
        }
3410
 
 
3411
 
});
3412
 
 
3413
 
/*
3414
 
Script: Element.Dimensions.js
3415
 
        Contains Element prototypes to deal with Element size and position in space.
3416
 
 
3417
 
Note:
3418
 
        The functions in this script require n XHTML doctype.
3419
 
 
3420
 
License:
3421
 
        MIT-style license.
3422
 
*/
3423
 
 
3424
 
/*
3425
 
Class: Element
3426
 
        Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>.
3427
 
*/
3428
 
 
3429
 
Element.extend({
3430
 
 
3431
 
        /*
3432
 
        Property: scrollTo
3433
 
                Scrolls the element to the specified coordinated (if the element has an overflow)
3434
 
 
3435
 
        Arguments:
3436
 
                x - the x coordinate
3437
 
                y - the y coordinate
3438
 
 
3439
 
        Example:
3440
 
                >$('myElement').scrollTo(0, 100)
3441
 
        */
3442
 
 
3443
 
        scrollTo: function(x, y){
3444
 
                this.scrollLeft = x;
3445
 
                this.scrollTop = y;
3446
 
        },
3447
 
 
3448
 
        /*
3449
 
        Property: getSize
3450
 
                Return an Object representing the size/scroll values of the element.
3451
 
 
3452
 
        Example:
3453
 
                (start code)
3454
 
                $('myElement').getSize();
3455
 
                (end)
3456
 
 
3457
 
        Returns:
3458
 
                (start code)
3459
 
                {
3460
 
                        'scroll': {'x': 100, 'y': 100},
3461
 
                        'size': {'x': 200, 'y': 400},
3462
 
                        'scrollSize': {'x': 300, 'y': 500}
3463
 
                }
3464
 
                (end)
3465
 
        */
3466
 
 
3467
 
        getSize: function(){
3468
 
                return {
3469
 
                        'scroll': {'x': this.scrollLeft, 'y': this.scrollTop},
3470
 
                        'size': {'x': this.offsetWidth, 'y': this.offsetHeight},
3471
 
                        'scrollSize': {'x': this.scrollWidth, 'y': this.scrollHeight}
3472
 
                };
3473
 
        },
3474
 
 
3475
 
        /*
3476
 
        Property: getPosition
3477
 
                Returns the real offsets of the element.
3478
 
 
3479
 
        Arguments:
3480
 
                overflown - optional, an array of nested scrolling containers for scroll offset calculation, use this if your element is inside any element containing scrollbars
3481
 
 
3482
 
        Example:
3483
 
                >$('element').getPosition();
3484
 
 
3485
 
        Returns:
3486
 
                >{x: 100, y:500};
3487
 
        */
3488
 
 
3489
 
        getPosition: function(overflown){
3490
 
                overflown = overflown || [];
3491
 
                var el = this, left = 0, top = 0;
3492
 
                do {
3493
 
                        left += el.offsetLeft || 0;
3494
 
                        top += el.offsetTop || 0;
3495
 
                        el = el.offsetParent;
3496
 
                } while (el);
3497
 
                overflown.each(function(element){
3498
 
                        left -= element.scrollLeft || 0;
3499
 
                        top -= element.scrollTop || 0;
3500
 
                });
3501
 
                return {'x': left, 'y': top};
3502
 
        },
3503
 
 
3504
 
        /*
3505
 
        Property: getTop
3506
 
                Returns the distance from the top of the window to the Element.
3507
 
 
3508
 
        Arguments:
3509
 
                overflown - optional, an array of nested scrolling containers, see Element::getPosition
3510
 
        */
3511
 
 
3512
 
        getTop: function(overflown){
3513
 
                return this.getPosition(overflown).y;
3514
 
        },
3515
 
 
3516
 
        /*
3517
 
        Property: getLeft
3518
 
                Returns the distance from the left of the window to the Element.
3519
 
 
3520
 
        Arguments:
3521
 
                overflown - optional, an array of nested scrolling containers, see Element::getPosition
3522
 
        */
3523
 
 
3524
 
        getLeft: function(overflown){
3525
 
                return this.getPosition(overflown).x;
3526
 
        },
3527
 
 
3528
 
        /*
3529
 
        Property: getCoordinates
3530
 
                Returns an object with width, height, left, right, top, and bottom, representing the values of the Element
3531
 
 
3532
 
        Arguments:
3533
 
                overflown - optional, an array of nested scrolling containers, see Element::getPosition
3534
 
 
3535
 
        Example:
3536
 
                (start code)
3537
 
                var myValues = $('myElement').getCoordinates();
3538
 
                (end)
3539
 
 
3540
 
        Returns:
3541
 
                (start code)
3542
 
                {
3543
 
                        width: 200,
3544
 
                        height: 300,
3545
 
                        left: 100,
3546
 
                        top: 50,
3547
 
                        right: 300,
3548
 
                        bottom: 350
3549
 
                }
3550
 
                (end)
3551
 
        */
3552
 
 
3553
 
        getCoordinates: function(overflown){
3554
 
                var position = this.getPosition(overflown);
3555
 
                var obj = {
3556
 
                        'width': this.offsetWidth,
3557
 
                        'height': this.offsetHeight,
3558
 
                        'left': position.x,
3559
 
                        'top': position.y
3560
 
                };
3561
 
                obj.right = obj.left + obj.width;
3562
 
                obj.bottom = obj.top + obj.height;
3563
 
                return obj;
3564
 
        }
3565
 
 
3566
 
});
3567
 
 
3568
 
/*
3569
 
Script: Window.DomReady.js
3570
 
        Contains the custom event domready, for window.
3571
 
 
3572
 
License:
3573
 
        MIT-style license.
3574
 
*/
3575
 
 
3576
 
/* Section: Custom Events */
3577
 
 
3578
 
/*
3579
 
Event: domready
3580
 
        executes a function when the dom tree is loaded, without waiting for images. Only works when called from window.
3581
 
 
3582
 
Credits:
3583
 
        (c) Dean Edwards/Matthias Miller/John Resig, remastered for MooTools.
3584
 
 
3585
 
Arguments:
3586
 
        fn - the function to execute when the DOM is ready
3587
 
 
3588
 
Example:
3589
 
        > window.addEvent('domready', function(){
3590
 
        >       alert('the dom is ready');
3591
 
        > });
3592
 
*/
3593
 
 
3594
 
Element.Events.domready = {
3595
 
 
3596
 
        add: function(fn){
3597
 
                if (window.loaded){
3598
 
                        fn.call(this);
3599
 
                        return;
3600
 
                }
3601
 
                var domReady = function(){
3602
 
                        if (window.loaded) return;
3603
 
                        window.loaded = true;
3604
 
                        window.timer = $clear(window.timer);
3605
 
                        this.fireEvent('domready');
3606
 
                }.bind(this);
3607
 
                if (document.readyState && window.webkit){
3608
 
                        window.timer = function(){
3609
 
                                if (['loaded','complete'].contains(document.readyState)) domReady();
3610
 
                        }.periodical(50);
3611
 
                } else if (document.readyState && window.ie){
3612
 
                        if (!$('ie_ready')){
3613
 
                                var src = (window.location.protocol == 'https:') ? '://0' : 'javascript:void(0)';
3614
 
                                document.write('<script id="ie_ready" defer src="' + src + '"><\/script>');
3615
 
                                $('ie_ready').onreadystatechange = function(){
3616
 
                                        if (this.readyState == 'complete') domReady();
3617
 
                                };
3618
 
                        }
3619
 
                } else {
3620
 
                        window.addListener("load", domReady);
3621
 
                        document.addListener("DOMContentLoaded", domReady);
3622
 
                }
3623
 
        }
3624
 
 
3625
 
};
3626
 
 
3627
 
/*compatibility*/
3628
 
 
3629
 
window.onDomReady = function(fn){ 
3630
 
        return this.addEvent('domready', fn); 
3631
 
};
3632
 
 
3633
 
/*end compatibility*/
3634
 
 
3635
 
/*
3636
 
Script: Window.Size.js
3637
 
        Window cross-browser dimensions methods.
3638
 
        
3639
 
Note:
3640
 
        The Functions in this script require an XHTML doctype.
3641
 
 
3642
 
License:
3643
 
        MIT-style license.
3644
 
*/
3645
 
 
3646
 
/*
3647
 
Class: window
3648
 
        Cross browser methods to get various window dimensions.
3649
 
        Warning: All these methods require that the browser operates in strict mode, not quirks mode.
3650
 
*/
3651
 
 
3652
 
window.extend({
3653
 
 
3654
 
        /*
3655
 
        Property: getWidth
3656
 
                Returns an integer representing the width of the browser window (without the scrollbar).
3657
 
        */
3658
 
 
3659
 
        getWidth: function(){
3660
 
                if (this.webkit419) return this.innerWidth;
3661
 
                if (this.opera) return document.body.clientWidth;
3662
 
                return document.documentElement.clientWidth;
3663
 
        },
3664
 
 
3665
 
        /*
3666
 
        Property: getHeight
3667
 
                Returns an integer representing the height of the browser window (without the scrollbar).
3668
 
        */
3669
 
 
3670
 
        getHeight: function(){
3671
 
                if (this.webkit419) return this.innerHeight;
3672
 
                if (this.opera) return document.body.clientHeight;
3673
 
                return document.documentElement.clientHeight;
3674
 
        },
3675
 
 
3676
 
        /*
3677
 
        Property: getScrollWidth
3678
 
                Returns an integer representing the scrollWidth of the window.
3679
 
                This value is equal to or bigger than <getWidth>.
3680
 
 
3681
 
        See Also:
3682
 
                <http://developer.mozilla.org/en/docs/DOM:element.scrollWidth>
3683
 
        */
3684
 
 
3685
 
        getScrollWidth: function(){
3686
 
                if (this.ie) return Math.max(document.documentElement.offsetWidth, document.documentElement.scrollWidth);
3687
 
                if (this.webkit) return document.body.scrollWidth;
3688
 
                return document.documentElement.scrollWidth;
3689
 
        },
3690
 
 
3691
 
        /*
3692
 
        Property: getScrollHeight
3693
 
                Returns an integer representing the scrollHeight of the window.
3694
 
                This value is equal to or bigger than <getHeight>.
3695
 
 
3696
 
        See Also:
3697
 
                <http://developer.mozilla.org/en/docs/DOM:element.scrollHeight>
3698
 
        */
3699
 
 
3700
 
        getScrollHeight: function(){
3701
 
                if (this.ie) return Math.max(document.documentElement.offsetHeight, document.documentElement.scrollHeight);
3702
 
                if (this.webkit) return document.body.scrollHeight;
3703
 
                return document.documentElement.scrollHeight;
3704
 
        },
3705
 
 
3706
 
        /*
3707
 
        Property: getScrollLeft
3708
 
                Returns an integer representing the scrollLeft of the window (the number of pixels the window has scrolled from the left).
3709
 
 
3710
 
        See Also:
3711
 
                <http://developer.mozilla.org/en/docs/DOM:element.scrollLeft>
3712
 
        */
3713
 
 
3714
 
        getScrollLeft: function(){
3715
 
                return this.pageXOffset || document.documentElement.scrollLeft;
3716
 
        },
3717
 
 
3718
 
        /*
3719
 
        Property: getScrollTop
3720
 
                Returns an integer representing the scrollTop of the window (the number of pixels the window has scrolled from the top).
3721
 
 
3722
 
        See Also:
3723
 
                <http://developer.mozilla.org/en/docs/DOM:element.scrollTop>
3724
 
        */
3725
 
 
3726
 
        getScrollTop: function(){
3727
 
                return this.pageYOffset || document.documentElement.scrollTop;
3728
 
        },
3729
 
 
3730
 
        /*
3731
 
        Property: getSize
3732
 
                Same as <Element.getSize>
3733
 
        */
3734
 
 
3735
 
        getSize: function(){
3736
 
                return {
3737
 
                        'size': {'x': this.getWidth(), 'y': this.getHeight()},
3738
 
                        'scrollSize': {'x': this.getScrollWidth(), 'y': this.getScrollHeight()},
3739
 
                        'scroll': {'x': this.getScrollLeft(), 'y': this.getScrollTop()}
3740
 
                };
3741
 
        },
3742
 
 
3743
 
        //ignore
3744
 
        getPosition: function(){return {'x': 0, 'y': 0};}
3745
 
 
3746
 
});
3747
 
 
3748
 
/*
3749
 
Script: Fx.Base.js
3750
 
        Contains <Fx.Base>, the foundamentals of the MooTools Effects.
3751
 
 
3752
 
License:
3753
 
        MIT-style license.
3754
 
*/
3755
 
 
3756
 
var Fx = {};
3757
 
 
3758
 
/*
3759
 
Class: Fx.Base
3760
 
        Base class for the Effects.
3761
 
 
3762
 
Options:
3763
 
        transition - the equation to use for the effect see <Fx.Transitions>; default is <Fx.Transitions.Sine.easeInOut>
3764
 
        duration - the duration of the effect in ms; 500 is the default.
3765
 
        unit - the unit is 'px' by default (other values include things like 'em' for fonts or '%').
3766
 
        wait - boolean: to wait or not to wait for a current transition to end before running another of the same instance. defaults to true.
3767
 
        fps - the frames per second for the transition; default is 50
3768
 
        
3769
 
Events:
3770
 
        onStart - the function to execute as the effect begins; nothing (<Class.empty>) by default.
3771
 
        onComplete - the function to execute after the effect has processed; nothing (<Class.empty>) by default.
3772
 
        onCancel - the function to execute when you manually stop the effect.
3773
 
*/
3774
 
 
3775
 
Fx.Base = new Class({
3776
 
 
3777
 
        options: {
3778
 
                onStart: Class.empty,
3779
 
                onComplete: Class.empty,
3780
 
                onCancel: Class.empty,
3781
 
                transition: function(p){
3782
 
                        return -(Math.cos(Math.PI * p) - 1) / 2;
3783
 
                },
3784
 
                duration: 500,
3785
 
                unit: 'px',
3786
 
                wait: true,
3787
 
                fps: 50
3788
 
        },
3789
 
 
3790
 
        initialize: function(options){
3791
 
                this.element = this.element || null;
3792
 
                this.setOptions(options);
3793
 
                if (this.options.initialize) this.options.initialize.call(this);
3794
 
        },
3795
 
 
3796
 
        step: function(){
3797
 
                var time = $time();
3798
 
                if (time < this.time + this.options.duration){
3799
 
                        this.delta = this.options.transition((time - this.time) / this.options.duration);
3800
 
                        this.setNow();
3801
 
                        this.increase();
3802
 
                } else {
3803
 
                        this.stop(true);
3804
 
                        this.set(this.to);
3805
 
                        this.fireEvent('onComplete', this.element, 10);
3806
 
                        this.callChain();
3807
 
                }
3808
 
        },
3809
 
 
3810
 
        /*
3811
 
        Property: set
3812
 
                Immediately sets the value with no transition.
3813
 
 
3814
 
        Arguments:
3815
 
                to - the point to jump to
3816
 
 
3817
 
        Example:
3818
 
                >var myFx = new Fx.Style('myElement', 'opacity').set(0); //will make it immediately transparent
3819
 
        */
3820
 
 
3821
 
        set: function(to){
3822
 
                this.now = to;
3823
 
                this.increase();
3824
 
                return this;
3825
 
        },
3826
 
 
3827
 
        setNow: function(){
3828
 
                this.now = this.compute(this.from, this.to);
3829
 
        },
3830
 
 
3831
 
        compute: function(from, to){
3832
 
                return (to - from) * this.delta + from;
3833
 
        },
3834
 
 
3835
 
        /*
3836
 
        Property: start
3837
 
                Executes an effect from one position to the other.
3838
 
 
3839
 
        Arguments:
3840
 
                from - integer: staring value
3841
 
                to - integer: the ending value
3842
 
 
3843
 
        Examples:
3844
 
                >var myFx = new Fx.Style('myElement', 'opacity').start(0,1); //display a transition from transparent to opaque.
3845
 
        */
3846
 
 
3847
 
        start: function(from, to){
3848
 
                if (!this.options.wait) this.stop();
3849
 
                else if (this.timer) return this;
3850
 
                this.from = from;
3851
 
                this.to = to;
3852
 
                this.change = this.to - this.from;
3853
 
                this.time = $time();
3854
 
                this.timer = this.step.periodical(Math.round(1000 / this.options.fps), this);
3855
 
                this.fireEvent('onStart', this.element);
3856
 
                return this;
3857
 
        },
3858
 
 
3859
 
        /*
3860
 
        Property: stop
3861
 
                Stops the transition.
3862
 
        */
3863
 
 
3864
 
        stop: function(end){
3865
 
                if (!this.timer) return this;
3866
 
                this.timer = $clear(this.timer);
3867
 
                if (!end) this.fireEvent('onCancel', this.element);
3868
 
                return this;
3869
 
        }/*compatibility*/,
3870
 
        
3871
 
        custom: function(from, to){
3872
 
                return this.start(from, to);
3873
 
        },
3874
 
 
3875
 
        clearTimer: function(end){
3876
 
                return this.stop(end);
3877
 
        }
3878
 
 
3879
 
        /*end compatibility*/
3880
 
 
3881
 
});
3882
 
 
3883
 
Fx.Base.implement(new Chain, new Events, new Options);
3884
 
 
3885
 
/*
3886
 
Script: Fx.CSS.js
3887
 
        Css parsing class for effects. Required by <Fx.Style>, <Fx.Styles>, <Fx.Elements>. No documentation needed, as its used internally.
3888
 
 
3889
 
License:
3890
 
        MIT-style license.
3891
 
*/
3892
 
 
3893
 
Fx.CSS = {
3894
 
 
3895
 
        select: function(property, to){
3896
 
                if (property.test(/color/i)) return this.Color;
3897
 
                var type = $type(to);
3898
 
                if ((type == 'array') || (type == 'string' && to.contains(' '))) return this.Multi;
3899
 
                return this.Single;
3900
 
        },
3901
 
 
3902
 
        parse: function(el, property, fromTo){
3903
 
                if (!fromTo.push) fromTo = [fromTo];
3904
 
                var from = fromTo[0], to = fromTo[1];
3905
 
                if (!$chk(to)){
3906
 
                        to = from;
3907
 
                        from = el.getStyle(property);
3908
 
                }
3909
 
                var css = this.select(property, to);
3910
 
                return {'from': css.parse(from), 'to': css.parse(to), 'css': css};
3911
 
        }
3912
 
 
3913
 
};
3914
 
 
3915
 
Fx.CSS.Single = {
3916
 
 
3917
 
        parse: function(value){
3918
 
                return parseFloat(value);
3919
 
        },
3920
 
 
3921
 
        getNow: function(from, to, fx){
3922
 
                return fx.compute(from, to);
3923
 
        },
3924
 
 
3925
 
        getValue: function(value, unit, property){
3926
 
                if (unit == 'px' && property != 'opacity') value = Math.round(value);
3927
 
                return value + unit;
3928
 
        }
3929
 
 
3930
 
};
3931
 
 
3932
 
Fx.CSS.Multi = {
3933
 
 
3934
 
        parse: function(value){
3935
 
                return value.push ? value : value.split(' ').map(function(v){
3936
 
                        return parseFloat(v);
3937
 
                });
3938
 
        },
3939
 
 
3940
 
        getNow: function(from, to, fx){
3941
 
                var now = [];
3942
 
                for (var i = 0; i < from.length; i++) now[i] = fx.compute(from[i], to[i]);
3943
 
                return now;
3944
 
        },
3945
 
 
3946
 
        getValue: function(value, unit, property){
3947
 
                if (unit == 'px' && property != 'opacity') value = value.map(Math.round);
3948
 
                return value.join(unit + ' ') + unit;
3949
 
        }
3950
 
 
3951
 
};
3952
 
 
3953
 
Fx.CSS.Color = {
3954
 
 
3955
 
        parse: function(value){
3956
 
                return value.push ? value : value.hexToRgb(true);
3957
 
        },
3958
 
 
3959
 
        getNow: function(from, to, fx){
3960
 
                var now = [];
3961
 
                for (var i = 0; i < from.length; i++) now[i] = Math.round(fx.compute(from[i], to[i]));
3962
 
                return now;
3963
 
        },
3964
 
 
3965
 
        getValue: function(value){
3966
 
                return 'rgb(' + value.join(',') + ')';
3967
 
        }
3968
 
 
3969
 
};
3970
 
 
3971
 
/*
3972
 
Script: Fx.Style.js
3973
 
        Contains <Fx.Style>
3974
 
 
3975
 
License:
3976
 
        MIT-style license.
3977
 
*/
3978
 
 
3979
 
/*
3980
 
Class: Fx.Style
3981
 
        The Style effect, used to transition any css property from one value to another. Includes colors.
3982
 
        Colors must be in hex format.
3983
 
        Inherits methods, properties, options and events from <Fx.Base>.
3984
 
 
3985
 
Arguments:
3986
 
        el - the $(element) to apply the style transition to
3987
 
        property - the property to transition
3988
 
        options - the Fx.Base options (see: <Fx.Base>)
3989
 
 
3990
 
Example:
3991
 
        >var marginChange = new Fx.Style('myElement', 'margin-top', {duration:500});
3992
 
        >marginChange.start(10, 100);
3993
 
*/
3994
 
 
3995
 
Fx.Style = Fx.Base.extend({
3996
 
 
3997
 
        initialize: function(el, property, options){
3998
 
                this.element = $(el);
3999
 
                this.property = property;
4000
 
                this.parent(options);
4001
 
        },
4002
 
 
4003
 
        /*
4004
 
        Property: hide
4005
 
                Same as <Fx.Base.set> (0); hides the element immediately without transition.
4006
 
        */
4007
 
 
4008
 
        hide: function(){
4009
 
                return this.set(0);
4010
 
        },
4011
 
 
4012
 
        setNow: function(){
4013
 
                this.now = this.css.getNow(this.from, this.to, this);
4014
 
        },
4015
 
 
4016
 
        /*
4017
 
        Property: set
4018
 
                Sets the element's css property (specified at instantiation) to the specified value immediately.
4019
 
 
4020
 
        Example:
4021
 
                (start code)
4022
 
                var marginChange = new Fx.Style('myElement', 'margin-top', {duration:500});
4023
 
                marginChange.set(10); //margin-top is set to 10px immediately
4024
 
                (end)
4025
 
        */
4026
 
 
4027
 
        set: function(to){
4028
 
                this.css = Fx.CSS.select(this.property, to);
4029
 
                return this.parent(this.css.parse(to));
4030
 
        },
4031
 
 
4032
 
        /*
4033
 
        Property: start
4034
 
                Displays the transition to the value/values passed in
4035
 
 
4036
 
        Arguments:
4037
 
                from - (integer; optional) the starting position for the transition
4038
 
                to - (integer) the ending position for the transition
4039
 
 
4040
 
        Note:
4041
 
                If you provide only one argument, the transition will use the current css value for its starting value.
4042
 
 
4043
 
        Example:
4044
 
                (start code)
4045
 
                var marginChange = new Fx.Style('myElement', 'margin-top', {duration:500});
4046
 
                marginChange.start(10); //tries to read current margin top value and goes from current to 10
4047
 
                (end)
4048
 
        */
4049
 
 
4050
 
        start: function(from, to){
4051
 
                if (this.timer && this.options.wait) return this;
4052
 
                var parsed = Fx.CSS.parse(this.element, this.property, [from, to]);
4053
 
                this.css = parsed.css;
4054
 
                return this.parent(parsed.from, parsed.to);
4055
 
        },
4056
 
 
4057
 
        increase: function(){
4058
 
                this.element.setStyle(this.property, this.css.getValue(this.now, this.options.unit, this.property));
4059
 
        }
4060
 
 
4061
 
});
4062
 
 
4063
 
/*
4064
 
Class: Element
4065
 
        Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>.
4066
 
*/
4067
 
 
4068
 
Element.extend({
4069
 
 
4070
 
        /*
4071
 
        Property: effect
4072
 
                Applies an <Fx.Style> to the Element; This a shortcut for <Fx.Style>.
4073
 
 
4074
 
        Arguments:
4075
 
                property - (string) the css property to alter
4076
 
                options - (object; optional) key/value set of options (see <Fx.Style>)
4077
 
 
4078
 
        Example:
4079
 
                >var myEffect = $('myElement').effect('height', {duration: 1000, transition: Fx.Transitions.linear});
4080
 
                >myEffect.start(10, 100);
4081
 
                >//OR
4082
 
                >$('myElement').effect('height', {duration: 1000, transition: Fx.Transitions.linear}).start(10,100);
4083
 
        */
4084
 
 
4085
 
        effect: function(property, options){
4086
 
                return new Fx.Style(this, property, options);
4087
 
        }
4088
 
 
4089
 
});
4090
 
 
4091
 
/*
4092
 
Script: Fx.Styles.js
4093
 
        Contains <Fx.Styles>
4094
 
 
4095
 
License:
4096
 
        MIT-style license.
4097
 
*/
4098
 
 
4099
 
/*
4100
 
Class: Fx.Styles
4101
 
        Allows you to animate multiple css properties at once;
4102
 
        Colors must be in hex format.
4103
 
        Inherits methods, properties, options and events from <Fx.Base>.
4104
 
 
4105
 
Arguments:
4106
 
        el - the $(element) to apply the styles transition to
4107
 
        options - the fx options (see: <Fx.Base>)
4108
 
 
4109
 
Example:
4110
 
        (start code)
4111
 
        var myEffects = new Fx.Styles('myElement', {duration: 1000, transition: Fx.Transitions.linear});
4112
 
 
4113
 
        //height from 10 to 100 and width from 900 to 300
4114
 
        myEffects.start({
4115
 
                'height': [10, 100],
4116
 
                'width': [900, 300]
4117
 
        });
4118
 
 
4119
 
        //or height from current height to 100 and width from current width to 300
4120
 
        myEffects.start({
4121
 
                'height': 100,
4122
 
                'width': 300
4123
 
        });
4124
 
        (end)
4125
 
*/
4126
 
 
4127
 
Fx.Styles = Fx.Base.extend({
4128
 
 
4129
 
        initialize: function(el, options){
4130
 
                this.element = $(el);
4131
 
                this.parent(options);
4132
 
        },
4133
 
 
4134
 
        setNow: function(){
4135
 
                for (var p in this.from) this.now[p] = this.css[p].getNow(this.from[p], this.to[p], this);
4136
 
        },
4137
 
 
4138
 
        set: function(to){
4139
 
                var parsed = {};
4140
 
                this.css = {};
4141
 
                for (var p in to){
4142
 
                        this.css[p] = Fx.CSS.select(p, to[p]);
4143
 
                        parsed[p] = this.css[p].parse(to[p]);
4144
 
                }
4145
 
                return this.parent(parsed);
4146
 
        },
4147
 
 
4148
 
        /*
4149
 
        Property: start
4150
 
                Executes a transition for any number of css properties in tandem.
4151
 
 
4152
 
        Arguments:
4153
 
                obj - an object containing keys that specify css properties to alter and values that specify either the from/to values (as an array) or just the end value (an integer).
4154
 
 
4155
 
        Example:
4156
 
                see <Fx.Styles>
4157
 
        */
4158
 
 
4159
 
        start: function(obj){
4160
 
                if (this.timer && this.options.wait) return this;
4161
 
                this.now = {};
4162
 
                this.css = {};
4163
 
                var from = {}, to = {};
4164
 
                for (var p in obj){
4165
 
                        var parsed = Fx.CSS.parse(this.element, p, obj[p]);
4166
 
                        from[p] = parsed.from;
4167
 
                        to[p] = parsed.to;
4168
 
                        this.css[p] = parsed.css;
4169
 
                }
4170
 
                return this.parent(from, to);
4171
 
        },
4172
 
 
4173
 
        increase: function(){
4174
 
                for (var p in this.now) this.element.setStyle(p, this.css[p].getValue(this.now[p], this.options.unit, p));
4175
 
        }
4176
 
 
4177
 
});
4178
 
 
4179
 
/*
4180
 
Class: Element
4181
 
        Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>.
4182
 
*/
4183
 
 
4184
 
Element.extend({
4185
 
 
4186
 
        /*
4187
 
        Property: effects
4188
 
                Applies an <Fx.Styles> to the Element; This a shortcut for <Fx.Styles>.
4189
 
 
4190
 
        Example:
4191
 
                >var myEffects = $(myElement).effects({duration: 1000, transition: Fx.Transitions.Sine.easeInOut});
4192
 
                >myEffects.start({'height': [10, 100], 'width': [900, 300]});
4193
 
        */
4194
 
 
4195
 
        effects: function(options){
4196
 
                return new Fx.Styles(this, options);
4197
 
        }
4198
 
 
4199
 
});
4200
 
 
4201
 
/*
4202
 
Script: Fx.Elements.js
4203
 
        Contains <Fx.Elements>
4204
 
 
4205
 
License:
4206
 
        MIT-style license.
4207
 
*/
4208
 
 
4209
 
/*
4210
 
Class: Fx.Elements
4211
 
        Fx.Elements allows you to apply any number of styles transitions to a selection of elements. Includes colors (must be in hex format).
4212
 
        Inherits methods, properties, options and events from <Fx.Base>.
4213
 
 
4214
 
Arguments:
4215
 
        elements - a collection of elements the effects will be applied to.
4216
 
        options - same as <Fx.Base> options.
4217
 
*/
4218
 
 
4219
 
Fx.Elements = Fx.Base.extend({
4220
 
 
4221
 
        initialize: function(elements, options){
4222
 
                this.elements = $$(elements);
4223
 
                this.parent(options);
4224
 
        },
4225
 
 
4226
 
        setNow: function(){
4227
 
                for (var i in this.from){
4228
 
                        var iFrom = this.from[i], iTo = this.to[i], iCss = this.css[i], iNow = this.now[i] = {};
4229
 
                        for (var p in iFrom) iNow[p] = iCss[p].getNow(iFrom[p], iTo[p], this);
4230
 
                }
4231
 
        },
4232
 
 
4233
 
        set: function(to){
4234
 
                var parsed = {};
4235
 
                this.css = {};
4236
 
                for (var i in to){
4237
 
                        var iTo = to[i], iCss = this.css[i] = {}, iParsed = parsed[i] = {};
4238
 
                        for (var p in iTo){
4239
 
                                iCss[p] = Fx.CSS.select(p, iTo[p]);
4240
 
                                iParsed[p] = iCss[p].parse(iTo[p]);
4241
 
                        }
4242
 
                }
4243
 
                return this.parent(parsed);
4244
 
        },
4245
 
 
4246
 
        /*
4247
 
        Property: start
4248
 
                Applies the passed in style transitions to each object named (see example). Each item in the collection is refered to as a numerical string ("1" for instance). The first item is "0", the second "1", etc.
4249
 
 
4250
 
        Example:
4251
 
                (start code)
4252
 
                var myElementsEffects = new Fx.Elements($$('a'));
4253
 
                myElementsEffects.start({
4254
 
                        '0': { //let's change the first element's opacity and width
4255
 
                                'opacity': [0,1],
4256
 
                                'width': [100,200]
4257
 
                        },
4258
 
                        '4': { //and the fifth one's opacity
4259
 
                                'opacity': [0.2, 0.5]
4260
 
                        }
4261
 
                });
4262
 
                (end)
4263
 
        */
4264
 
 
4265
 
        start: function(obj){
4266
 
                if (this.timer && this.options.wait) return this;
4267
 
                this.now = {};
4268
 
                this.css = {};
4269
 
                var from = {}, to = {};
4270
 
                for (var i in obj){
4271
 
                        var iProps = obj[i], iFrom = from[i] = {}, iTo = to[i] = {}, iCss = this.css[i] = {};
4272
 
                        for (var p in iProps){
4273
 
                                var parsed = Fx.CSS.parse(this.elements[i], p, iProps[p]);
4274
 
                                iFrom[p] = parsed.from;
4275
 
                                iTo[p] = parsed.to;
4276
 
                                iCss[p] = parsed.css;
4277
 
                        }
4278
 
                }
4279
 
                return this.parent(from, to);
4280
 
        },
4281
 
 
4282
 
        increase: function(){
4283
 
                for (var i in this.now){
4284
 
                        var iNow = this.now[i], iCss = this.css[i];
4285
 
                        for (var p in iNow) this.elements[i].setStyle(p, iCss[p].getValue(iNow[p], this.options.unit, p));
4286
 
                }
4287
 
        }
4288
 
 
4289
 
});
4290
 
 
4291
 
/*
4292
 
Script: Fx.Scroll.js
4293
 
        Contains <Fx.Scroll>
4294
 
 
4295
 
License:
4296
 
        MIT-style license.
4297
 
*/
4298
 
 
4299
 
/*
4300
 
Class: Fx.Scroll
4301
 
        Scroll any element with an overflow, including the window element.
4302
 
        Inherits methods, properties, options and events from <Fx.Base>.
4303
 
 
4304
 
Note:
4305
 
        Fx.Scroll requires an XHTML doctype.
4306
 
 
4307
 
Arguments:
4308
 
        element - the element to scroll
4309
 
        options - optional, see Options below.
4310
 
 
4311
 
Options:
4312
 
        all the Fx.Base options and events, plus:
4313
 
        offset - the distance for the scrollTo point/element. an Object with x/y properties.
4314
 
        overflown - an array of nested scrolling containers, see <Element.getPosition>
4315
 
*/
4316
 
 
4317
 
Fx.Scroll = Fx.Base.extend({
4318
 
 
4319
 
        options: {
4320
 
                overflown: [],
4321
 
                offset: {'x': 0, 'y': 0},
4322
 
                wheelStops: true
4323
 
        },
4324
 
 
4325
 
        initialize: function(element, options){
4326
 
                this.now = [];
4327
 
                this.element = $(element);
4328
 
                this.bound = {'stop': this.stop.bind(this, false)};
4329
 
                this.parent(options);
4330
 
                if (this.options.wheelStops){
4331
 
                        this.addEvent('onStart', function(){
4332
 
                                document.addEvent('mousewheel', this.bound.stop);
4333
 
                        }.bind(this));
4334
 
                        this.addEvent('onComplete', function(){
4335
 
                                document.removeEvent('mousewheel', this.bound.stop);
4336
 
                        }.bind(this));
4337
 
                }
4338
 
        },
4339
 
 
4340
 
        setNow: function(){
4341
 
                for (var i = 0; i < 2; i++) this.now[i] = this.compute(this.from[i], this.to[i]);
4342
 
        },
4343
 
 
4344
 
        /*
4345
 
        Property: scrollTo
4346
 
                Scrolls the chosen element to the x/y coordinates.
4347
 
 
4348
 
        Arguments:
4349
 
                x - the x coordinate to scroll the element to
4350
 
                y - the y coordinate to scroll the element to
4351
 
        */
4352
 
 
4353
 
        scrollTo: function(x, y){
4354
 
                if (this.timer && this.options.wait) return this;
4355
 
                var el = this.element.getSize();
4356
 
                var values = {'x': x, 'y': y};
4357
 
                for (var z in el.size){
4358
 
                        var max = el.scrollSize[z] - el.size[z];
4359
 
                        if ($chk(values[z])) values[z] = ($type(values[z]) == 'number') ? values[z].limit(0, max) : max;
4360
 
                        else values[z] = el.scroll[z];
4361
 
                        values[z] += this.options.offset[z];
4362
 
                }
4363
 
                return this.start([el.scroll.x, el.scroll.y], [values.x, values.y]);
4364
 
        },
4365
 
 
4366
 
        /*
4367
 
        Property: toTop
4368
 
                Scrolls the chosen element to its maximum top.
4369
 
        */
4370
 
 
4371
 
        toTop: function(){
4372
 
                return this.scrollTo(false, 0);
4373
 
        },
4374
 
 
4375
 
        /*
4376
 
        Property: toBottom
4377
 
                Scrolls the chosen element to its maximum bottom.
4378
 
        */
4379
 
 
4380
 
        toBottom: function(){
4381
 
                return this.scrollTo(false, 'full');
4382
 
        },
4383
 
 
4384
 
        /*
4385
 
        Property: toLeft
4386
 
                Scrolls the chosen element to its maximum left.
4387
 
        */
4388
 
 
4389
 
        toLeft: function(){
4390
 
                return this.scrollTo(0, false);
4391
 
        },
4392
 
 
4393
 
        /*
4394
 
        Property: toRight
4395
 
                Scrolls the chosen element to its maximum right.
4396
 
        */
4397
 
 
4398
 
        toRight: function(){
4399
 
                return this.scrollTo('full', false);
4400
 
        },
4401
 
 
4402
 
        /*
4403
 
        Property: toElement
4404
 
                Scrolls the specified element to the position the passed in element is found.
4405
 
 
4406
 
        Arguments:
4407
 
                el - the $(element) to scroll the window to
4408
 
        */
4409
 
 
4410
 
        toElement: function(el){
4411
 
                var parent = this.element.getPosition(this.options.overflown);
4412
 
                var target = $(el).getPosition(this.options.overflown);
4413
 
                return this.scrollTo(target.x - parent.x, target.y - parent.y);
4414
 
        },
4415
 
 
4416
 
        increase: function(){
4417
 
                this.element.scrollTo(this.now[0], this.now[1]);
4418
 
        }
4419
 
 
4420
 
});
4421
 
 
4422
 
/*
4423
 
Script: Fx.Slide.js
4424
 
        Contains <Fx.Slide>
4425
 
 
4426
 
License:
4427
 
        MIT-style license.
4428
 
*/
4429
 
 
4430
 
/*
4431
 
Class: Fx.Slide
4432
 
        The slide effect; slides an element in horizontally or vertically, the contents will fold inside.
4433
 
        Inherits methods, properties, options and events from <Fx.Base>.
4434
 
        
4435
 
Note:
4436
 
        Fx.Slide requires an XHTML doctype.
4437
 
 
4438
 
Options:
4439
 
        mode - set it to vertical or horizontal. Defaults to vertical.
4440
 
        options - all the <Fx.Base> options
4441
 
 
4442
 
Example:
4443
 
        (start code)
4444
 
        var mySlider = new Fx.Slide('myElement', {duration: 500});
4445
 
        mySlider.toggle() //toggle the slider up and down.
4446
 
        (end)
4447
 
*/
4448
 
 
4449
 
Fx.Slide = Fx.Base.extend({
4450
 
 
4451
 
        options: {
4452
 
                mode: 'vertical'
4453
 
        },
4454
 
 
4455
 
        initialize: function(el, options){
4456
 
                this.element = $(el);
4457
 
                this.wrapper = new Element('div', {'styles': $extend(this.element.getStyles('margin'), {'overflow': 'hidden'})}).injectAfter(this.element).adopt(this.element);
4458
 
                this.element.setStyle('margin', 0);
4459
 
                this.setOptions(options);
4460
 
                this.now = [];
4461
 
                this.parent(this.options);
4462
 
                this.open = true;
4463
 
                this.addEvent('onComplete', function(){
4464
 
                        this.open = (this.now[0] === 0);
4465
 
                });
4466
 
                if (window.webkit419) this.addEvent('onComplete', function(){
4467
 
                        if (this.open) this.element.remove().inject(this.wrapper);
4468
 
                });
4469
 
        },
4470
 
 
4471
 
        setNow: function(){
4472
 
                for (var i = 0; i < 2; i++) this.now[i] = this.compute(this.from[i], this.to[i]);
4473
 
        },
4474
 
 
4475
 
        vertical: function(){
4476
 
                this.margin = 'margin-top';
4477
 
                this.layout = 'height';
4478
 
                this.offset = this.element.offsetHeight;
4479
 
        },
4480
 
 
4481
 
        horizontal: function(){
4482
 
                this.margin = 'margin-left';
4483
 
                this.layout = 'width';
4484
 
                this.offset = this.element.offsetWidth;
4485
 
        },
4486
 
 
4487
 
        /*
4488
 
        Property: slideIn
4489
 
                Slides the elements in view horizontally or vertically.
4490
 
 
4491
 
        Arguments:
4492
 
                mode - (optional, string) 'horizontal' or 'vertical'; defaults to options.mode.
4493
 
        */
4494
 
 
4495
 
        slideIn: function(mode){
4496
 
                this[mode || this.options.mode]();
4497
 
                return this.start([this.element.getStyle(this.margin).toInt(), this.wrapper.getStyle(this.layout).toInt()], [0, this.offset]);
4498
 
        },
4499
 
 
4500
 
        /*
4501
 
        Property: slideOut
4502
 
                Sides the elements out of view horizontally or vertically.
4503
 
 
4504
 
        Arguments:
4505
 
                mode - (optional, string) 'horizontal' or 'vertical'; defaults to options.mode.
4506
 
        */
4507
 
 
4508
 
        slideOut: function(mode){
4509
 
                this[mode || this.options.mode]();
4510
 
                return this.start([this.element.getStyle(this.margin).toInt(), this.wrapper.getStyle(this.layout).toInt()], [-this.offset, 0]);
4511
 
        },
4512
 
 
4513
 
        /*
4514
 
        Property: hide
4515
 
                Hides the element without a transition.
4516
 
 
4517
 
        Arguments:
4518
 
                mode - (optional, string) 'horizontal' or 'vertical'; defaults to options.mode.
4519
 
        */
4520
 
 
4521
 
        hide: function(mode){
4522
 
                this[mode || this.options.mode]();
4523
 
                this.open = false;
4524
 
                return this.set([-this.offset, 0]);
4525
 
        },
4526
 
 
4527
 
        /*
4528
 
        Property: show
4529
 
                Shows the element without a transition.
4530
 
 
4531
 
        Arguments:
4532
 
                mode - (optional, string) 'horizontal' or 'vertical'; defaults to options.mode.
4533
 
        */
4534
 
 
4535
 
        show: function(mode){
4536
 
                this[mode || this.options.mode]();
4537
 
                this.open = true;
4538
 
                return this.set([0, this.offset]);
4539
 
        },
4540
 
 
4541
 
        /*
4542
 
        Property: toggle
4543
 
                Slides in or Out the element, depending on its state
4544
 
 
4545
 
        Arguments:
4546
 
                mode - (optional, string) 'horizontal' or 'vertical'; defaults to options.mode.
4547
 
 
4548
 
        */
4549
 
 
4550
 
        toggle: function(mode){
4551
 
                if (this.wrapper.offsetHeight == 0 || this.wrapper.offsetWidth == 0) return this.slideIn(mode);
4552
 
                return this.slideOut(mode);
4553
 
        },
4554
 
 
4555
 
        increase: function(){
4556
 
                this.element.setStyle(this.margin, this.now[0] + this.options.unit);
4557
 
                this.wrapper.setStyle(this.layout, this.now[1] + this.options.unit);
4558
 
        }
4559
 
 
4560
 
});
4561
 
 
4562
 
/*
4563
 
Script: Fx.Transitions.js
4564
 
        Effects transitions, to be used with all the effects.
4565
 
 
4566
 
License:
4567
 
        MIT-style license.
4568
 
 
4569
 
Credits:
4570
 
        Easing Equations by Robert Penner, <http://www.robertpenner.com/easing/>, modified & optimized to be used with mootools.
4571
 
*/
4572
 
 
4573
 
/*
4574
 
Class: Fx.Transitions
4575
 
        A collection of tweening transitions for use with the <Fx.Base> classes.
4576
 
 
4577
 
Example:
4578
 
        >//Elastic.easeOut with default values:
4579
 
        >new Fx.Style('margin', {transition: Fx.Transitions.Elastic.easeOut});
4580
 
        >//Elastic.easeOut with user-defined value for elasticity.
4581
 
        > var myTransition = new Fx.Transition(Fx.Transitions.Elastic, 3);
4582
 
        >new Fx.Style('margin', {transition: myTransition.easeOut});
4583
 
 
4584
 
See also:
4585
 
        http://www.robertpenner.com/easing/
4586
 
*/
4587
 
 
4588
 
Fx.Transition = function(transition, params){
4589
 
        params = params || [];
4590
 
        if ($type(params) != 'array') params = [params];
4591
 
        return $extend(transition, {
4592
 
                easeIn: function(pos){
4593
 
                        return transition(pos, params);
4594
 
                },
4595
 
                easeOut: function(pos){
4596
 
                        return 1 - transition(1 - pos, params);
4597
 
                },
4598
 
                easeInOut: function(pos){
4599
 
                        return (pos <= 0.5) ? transition(2 * pos, params) / 2 : (2 - transition(2 * (1 - pos), params)) / 2;
4600
 
                }
4601
 
        });
4602
 
};
4603
 
 
4604
 
Fx.Transitions = new Abstract({
4605
 
 
4606
 
        /*
4607
 
        Property: linear
4608
 
                displays a linear transition.
4609
 
 
4610
 
        Graph:
4611
 
                (see Linear.png)
4612
 
        */
4613
 
 
4614
 
        linear: function(p){
4615
 
                return p;
4616
 
        }
4617
 
 
4618
 
});
4619
 
 
4620
 
Fx.Transitions.extend = function(transitions){
4621
 
        for (var transition in transitions){
4622
 
                Fx.Transitions[transition] = new Fx.Transition(transitions[transition]);
4623
 
                /*compatibility*/
4624
 
                Fx.Transitions.compat(transition);
4625
 
                /*end compatibility*/
4626
 
        }
4627
 
};
4628
 
 
4629
 
/*compatibility*/
4630
 
 
4631
 
Fx.Transitions.compat = function(transition){
4632
 
        ['In', 'Out', 'InOut'].each(function(easeType){
4633
 
                Fx.Transitions[transition.toLowerCase() + easeType] = Fx.Transitions[transition]['ease' + easeType];
4634
 
        });
4635
 
};
4636
 
 
4637
 
/*end compatibility*/
4638
 
 
4639
 
Fx.Transitions.extend({
4640
 
 
4641
 
        /*
4642
 
        Property: Quad
4643
 
                displays a quadratic transition. Must be used as Quad.easeIn or Quad.easeOut or Quad.easeInOut
4644
 
 
4645
 
        Graph:
4646
 
                (see Quad.png)
4647
 
        */
4648
 
 
4649
 
        //auto generated
4650
 
 
4651
 
        /*
4652
 
        Property: Cubic
4653
 
                displays a cubicular transition. Must be used as Cubic.easeIn or Cubic.easeOut or Cubic.easeInOut
4654
 
 
4655
 
        Graph:
4656
 
                (see Cubic.png)
4657
 
        */
4658
 
 
4659
 
        //auto generated
4660
 
 
4661
 
        /*
4662
 
        Property: Quart
4663
 
                displays a quartetic transition. Must be used as Quart.easeIn or Quart.easeOut or Quart.easeInOut
4664
 
 
4665
 
        Graph:
4666
 
                (see Quart.png)
4667
 
        */
4668
 
 
4669
 
        //auto generated
4670
 
 
4671
 
        /*
4672
 
        Property: Quint
4673
 
                displays a quintic transition. Must be used as Quint.easeIn or Quint.easeOut or Quint.easeInOut
4674
 
 
4675
 
        Graph:
4676
 
                (see Quint.png)
4677
 
        */
4678
 
 
4679
 
        //auto generated
4680
 
 
4681
 
        /*
4682
 
        Property: Pow
4683
 
                Used to generate Quad, Cubic, Quart and Quint.
4684
 
                By default is p^6.
4685
 
 
4686
 
        Graph:
4687
 
                (see Pow.png)
4688
 
        */
4689
 
 
4690
 
        Pow: function(p, x){
4691
 
                return Math.pow(p, x[0] || 6);
4692
 
        },
4693
 
 
4694
 
        /*
4695
 
        Property: Expo
4696
 
                displays a exponential transition. Must be used as Expo.easeIn or Expo.easeOut or Expo.easeInOut
4697
 
 
4698
 
        Graph:
4699
 
                (see Expo.png)
4700
 
        */
4701
 
 
4702
 
        Expo: function(p){
4703
 
                return Math.pow(2, 8 * (p - 1));
4704
 
        },
4705
 
 
4706
 
        /*
4707
 
        Property: Circ
4708
 
                displays a circular transition. Must be used as Circ.easeIn or Circ.easeOut or Circ.easeInOut
4709
 
 
4710
 
        Graph:
4711
 
                (see Circ.png)
4712
 
        */
4713
 
 
4714
 
        Circ: function(p){
4715
 
                return 1 - Math.sin(Math.acos(p));
4716
 
        },
4717
 
 
4718
 
 
4719
 
        /*
4720
 
        Property: Sine
4721
 
                displays a sineousidal transition. Must be used as Sine.easeIn or Sine.easeOut or Sine.easeInOut
4722
 
 
4723
 
        Graph:
4724
 
                (see Sine.png)
4725
 
        */
4726
 
 
4727
 
        Sine: function(p){
4728
 
                return 1 - Math.sin((1 - p) * Math.PI / 2);
4729
 
        },
4730
 
 
4731
 
        /*
4732
 
        Property: Back
4733
 
                makes the transition go back, then all forth. Must be used as Back.easeIn or Back.easeOut or Back.easeInOut
4734
 
 
4735
 
        Graph:
4736
 
                (see Back.png)
4737
 
        */
4738
 
 
4739
 
        Back: function(p, x){
4740
 
                x = x[0] || 1.618;
4741
 
                return Math.pow(p, 2) * ((x + 1) * p - x);
4742
 
        },
4743
 
 
4744
 
        /*
4745
 
        Property: Bounce
4746
 
                makes the transition bouncy. Must be used as Bounce.easeIn or Bounce.easeOut or Bounce.easeInOut
4747
 
 
4748
 
        Graph:
4749
 
                (see Bounce.png)
4750
 
        */
4751
 
 
4752
 
        Bounce: function(p){
4753
 
                var value;
4754
 
                for (var a = 0, b = 1; 1; a += b, b /= 2){
4755
 
                        if (p >= (7 - 4 * a) / 11){
4756
 
                                value = - Math.pow((11 - 6 * a - 11 * p) / 4, 2) + b * b;
4757
 
                                break;
4758
 
                        }
4759
 
                }
4760
 
                return value;
4761
 
        },
4762
 
 
4763
 
        /*
4764
 
        Property: Elastic
4765
 
                Elastic curve. Must be used as Elastic.easeIn or Elastic.easeOut or Elastic.easeInOut
4766
 
 
4767
 
        Graph:
4768
 
                (see Elastic.png)
4769
 
        */
4770
 
 
4771
 
        Elastic: function(p, x){
4772
 
                return Math.pow(2, 10 * --p) * Math.cos(20 * p * Math.PI * (x[0] || 1) / 3);
4773
 
        }
4774
 
 
4775
 
});
4776
 
 
4777
 
['Quad', 'Cubic', 'Quart', 'Quint'].each(function(transition, i){
4778
 
        Fx.Transitions[transition] = new Fx.Transition(function(p){
4779
 
                return Math.pow(p, [i + 2]);
4780
 
        });
4781
 
        
4782
 
        /*compatibility*/
4783
 
        Fx.Transitions.compat(transition);
4784
 
        /*end compatibility*/
4785
 
});
4786
 
 
4787
 
/*
4788
 
Script: Drag.Base.js
4789
 
        Contains <Drag.Base>, <Element.makeResizable>
4790
 
 
4791
 
License:
4792
 
        MIT-style license.
4793
 
*/
4794
 
 
4795
 
var Drag = {};
4796
 
 
4797
 
/*
4798
 
Class: Drag.Base
4799
 
        Modify two css properties of an element based on the position of the mouse.
4800
 
        
4801
 
Note:
4802
 
        Drag.Base requires an XHTML doctype.
4803
 
 
4804
 
Arguments:
4805
 
        el - the $(element) to apply the transformations to.
4806
 
        options - optional. The options object.
4807
 
 
4808
 
Options:
4809
 
        handle - the $(element) to act as the handle for the draggable element. defaults to the $(element) itself.
4810
 
        modifiers - an object. see Modifiers Below.
4811
 
        limit - an object, see Limit below.
4812
 
        grid - optional, distance in px for snap-to-grid dragging
4813
 
        snap - optional, the distance you have to drag before the element starts to respond to the drag. defaults to false
4814
 
 
4815
 
        modifiers:
4816
 
                x - string, the style you want to modify when the mouse moves in an horizontal direction. defaults to 'left'
4817
 
                y - string, the style you want to modify when the mouse moves in a vertical direction. defaults to 'top'
4818
 
 
4819
 
        limit:
4820
 
                x - array with start and end limit relative to modifiers.x
4821
 
                y - array with start and end limit relative to modifiers.y
4822
 
                
4823
 
Events:
4824
 
        onStart - optional, function to execute when the user starts to drag (on mousedown);
4825
 
        onComplete - optional, function to execute when the user completes the drag.
4826
 
        onDrag - optional, function to execute at every step of the drag
4827
 
*/
4828
 
 
4829
 
Drag.Base = new Class({
4830
 
 
4831
 
        options: {
4832
 
                handle: false,
4833
 
                unit: 'px',
4834
 
                onStart: Class.empty,
4835
 
                onBeforeStart: Class.empty,
4836
 
                onComplete: Class.empty,
4837
 
                onSnap: Class.empty,
4838
 
                onDrag: Class.empty,
4839
 
                limit: false,
4840
 
                modifiers: {x: 'left', y: 'top'},
4841
 
                grid: false,
4842
 
                snap: 6
4843
 
        },
4844
 
 
4845
 
        initialize: function(el, options){
4846
 
                this.setOptions(options);
4847
 
                this.element = $(el);
4848
 
                this.handle = $(this.options.handle) || this.element;
4849
 
                this.mouse = {'now': {}, 'pos': {}};
4850
 
                this.value = {'start': {}, 'now': {}};
4851
 
                this.bound = {
4852
 
                        'start': this.start.bindWithEvent(this),
4853
 
                        'check': this.check.bindWithEvent(this),
4854
 
                        'drag': this.drag.bindWithEvent(this),
4855
 
                        'stop': this.stop.bind(this)
4856
 
                };
4857
 
                this.attach();
4858
 
                if (this.options.initialize) this.options.initialize.call(this);
4859
 
        },
4860
 
 
4861
 
        attach: function(){
4862
 
                this.handle.addEvent('mousedown', this.bound.start);
4863
 
                return this;
4864
 
        },
4865
 
 
4866
 
        detach: function(){
4867
 
                this.handle.removeEvent('mousedown', this.bound.start);
4868
 
                return this;
4869
 
        },
4870
 
 
4871
 
        start: function(event){
4872
 
                this.fireEvent('onBeforeStart', this.element);
4873
 
                this.mouse.start = event.page;
4874
 
                var limit = this.options.limit;
4875
 
                this.limit = {'x': [], 'y': []};
4876
 
                for (var z in this.options.modifiers){
4877
 
                        if (!this.options.modifiers[z]) continue;
4878
 
                        this.value.now[z] = this.element.getStyle(this.options.modifiers[z]).toInt();
4879
 
                        this.mouse.pos[z] = event.page[z] - this.value.now[z];
4880
 
                        if (limit && limit[z]){
4881
 
                                for (var i = 0; i < 2; i++){
4882
 
                                        if ($chk(limit[z][i])) this.limit[z][i] = ($type(limit[z][i]) == 'function') ? limit[z][i]() : limit[z][i];
4883
 
                                }
4884
 
                        }
4885
 
                }
4886
 
                if ($type(this.options.grid) == 'number') this.options.grid = {'x': this.options.grid, 'y': this.options.grid};
4887
 
                document.addListener('mousemove', this.bound.check);
4888
 
                document.addListener('mouseup', this.bound.stop);
4889
 
                this.fireEvent('onStart', this.element);
4890
 
                event.stop();
4891
 
        },
4892
 
 
4893
 
        check: function(event){
4894
 
                var distance = Math.round(Math.sqrt(Math.pow(event.page.x - this.mouse.start.x, 2) + Math.pow(event.page.y - this.mouse.start.y, 2)));
4895
 
                if (distance > this.options.snap){
4896
 
                        document.removeListener('mousemove', this.bound.check);
4897
 
                        document.addListener('mousemove', this.bound.drag);
4898
 
                        this.drag(event);
4899
 
                        this.fireEvent('onSnap', this.element);
4900
 
                }
4901
 
                event.stop();
4902
 
        },
4903
 
 
4904
 
        drag: function(event){
4905
 
                this.out = false;
4906
 
                this.mouse.now = event.page;
4907
 
                for (var z in this.options.modifiers){
4908
 
                        if (!this.options.modifiers[z]) continue;
4909
 
                        this.value.now[z] = this.mouse.now[z] - this.mouse.pos[z];
4910
 
                        if (this.limit[z]){
4911
 
                                if ($chk(this.limit[z][1]) && (this.value.now[z] > this.limit[z][1])){
4912
 
                                        this.value.now[z] = this.limit[z][1];
4913
 
                                        this.out = true;
4914
 
                                } else if ($chk(this.limit[z][0]) && (this.value.now[z] < this.limit[z][0])){
4915
 
                                        this.value.now[z] = this.limit[z][0];
4916
 
                                        this.out = true;
4917
 
                                }
4918
 
                        }
4919
 
                        if (this.options.grid[z]) this.value.now[z] -= (this.value.now[z] % this.options.grid[z]);
4920
 
                        this.element.setStyle(this.options.modifiers[z], this.value.now[z] + this.options.unit);
4921
 
                }
4922
 
                this.fireEvent('onDrag', this.element);
4923
 
                event.stop();
4924
 
        },
4925
 
 
4926
 
        stop: function(){
4927
 
                document.removeListener('mousemove', this.bound.check);
4928
 
                document.removeListener('mousemove', this.bound.drag);
4929
 
                document.removeListener('mouseup', this.bound.stop);
4930
 
                this.fireEvent('onComplete', this.element);
4931
 
        }
4932
 
 
4933
 
});
4934
 
 
4935
 
Drag.Base.implement(new Events, new Options);
4936
 
 
4937
 
/*
4938
 
Class: Element
4939
 
        Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>.
4940
 
*/
4941
 
 
4942
 
Element.extend({
4943
 
 
4944
 
        /*
4945
 
        Property: makeResizable
4946
 
                Makes an element resizable (by dragging) with the supplied options.
4947
 
 
4948
 
        Arguments:
4949
 
                options - see <Drag.Base> for acceptable options.
4950
 
        */
4951
 
 
4952
 
        makeResizable: function(options){
4953
 
                return new Drag.Base(this, $merge({modifiers: {x: 'width', y: 'height'}}, options));
4954
 
        }
4955
 
 
4956
 
});
4957
 
 
4958
 
/*
4959
 
Script: Drag.Move.js
4960
 
        Contains <Drag.Move>, <Element.makeDraggable>
4961
 
 
4962
 
License:
4963
 
        MIT-style license.
4964
 
*/
4965
 
 
4966
 
/*
4967
 
Class: Drag.Move
4968
 
        Extends <Drag.Base>, has additional functionality for dragging an element, support snapping and droppables.
4969
 
        Drag.move supports either position absolute or relative. If no position is found, absolute will be set.
4970
 
        Inherits methods, properties, options and events from <Drag.Base>.
4971
 
 
4972
 
Note:
4973
 
        Drag.Move requires an XHTML doctype.
4974
 
 
4975
 
Arguments:
4976
 
        el - the $(element) to apply the drag to.
4977
 
        options - optional. see Options below.
4978
 
 
4979
 
Options:
4980
 
        all the drag.Base options, plus:
4981
 
        container - an element, will fill automatically limiting options based on the $(element) size and position. defaults to false (no limiting)
4982
 
        droppables - an array of elements you can drop your draggable to.
4983
 
        overflown - an array of nested scrolling containers, see Element::getPosition
4984
 
*/
4985
 
 
4986
 
Drag.Move = Drag.Base.extend({
4987
 
 
4988
 
        options: {
4989
 
                droppables: [],
4990
 
                container: false,
4991
 
                overflown: []
4992
 
        },
4993
 
 
4994
 
        initialize: function(el, options){
4995
 
                this.setOptions(options);
4996
 
                this.element = $(el);
4997
 
                this.droppables = $$(this.options.droppables);
4998
 
                this.container = $(this.options.container);
4999
 
                this.position = {'element': this.element.getStyle('position'), 'container': false};
5000
 
                if (this.container) this.position.container = this.container.getStyle('position');
5001
 
                if (!['relative', 'absolute', 'fixed'].contains(this.position.element)) this.position.element = 'absolute';
5002
 
                var top = this.element.getStyle('top').toInt();
5003
 
                var left = this.element.getStyle('left').toInt();
5004
 
                if (this.position.element == 'absolute' && !['relative', 'absolute', 'fixed'].contains(this.position.container)){
5005
 
                        top = $chk(top) ? top : this.element.getTop(this.options.overflown);
5006
 
                        left = $chk(left) ? left : this.element.getLeft(this.options.overflown);
5007
 
                } else {
5008
 
                        top = $chk(top) ? top : 0;
5009
 
                        left = $chk(left) ? left : 0;
5010
 
                }
5011
 
                this.element.setStyles({'top': top, 'left': left, 'position': this.position.element});
5012
 
                this.parent(this.element);
5013
 
        },
5014
 
 
5015
 
        start: function(event){
5016
 
                this.overed = null;
5017
 
                if (this.container){
5018
 
                        var cont = this.container.getCoordinates();
5019
 
                        var el = this.element.getCoordinates();
5020
 
                        if (this.position.element == 'absolute' && !['relative', 'absolute', 'fixed'].contains(this.position.container)){
5021
 
                                this.options.limit = {
5022
 
                                        'x': [cont.left, cont.right - el.width],
5023
 
                                        'y': [cont.top, cont.bottom - el.height]
5024
 
                                };
5025
 
                        } else {
5026
 
                                this.options.limit = {
5027
 
                                        'y': [0, cont.height - el.height],
5028
 
                                        'x': [0, cont.width - el.width]
5029
 
                                };
5030
 
                        }
5031
 
                }
5032
 
                this.parent(event);
5033
 
        },
5034
 
 
5035
 
        drag: function(event){
5036
 
                this.parent(event);
5037
 
                var overed = this.out ? false : this.droppables.filter(this.checkAgainst, this).getLast();
5038
 
                if (this.overed != overed){
5039
 
                        if (this.overed) this.overed.fireEvent('leave', [this.element, this]);
5040
 
                        this.overed = overed ? overed.fireEvent('over', [this.element, this]) : null;
5041
 
                }
5042
 
                return this;
5043
 
        },
5044
 
 
5045
 
        checkAgainst: function(el){
5046
 
                el = el.getCoordinates(this.options.overflown);
5047
 
                var now = this.mouse.now;
5048
 
                return (now.x > el.left && now.x < el.right && now.y < el.bottom && now.y > el.top);
5049
 
        },
5050
 
 
5051
 
        stop: function(){
5052
 
                if (this.overed && !this.out) this.overed.fireEvent('drop', [this.element, this]);
5053
 
                else this.element.fireEvent('emptydrop', this);
5054
 
                this.parent();
5055
 
                return this;
5056
 
        }
5057
 
 
5058
 
});
5059
 
 
5060
 
/*
5061
 
Class: Element
5062
 
        Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>.
5063
 
*/
5064
 
 
5065
 
Element.extend({
5066
 
 
5067
 
        /*
5068
 
        Property: makeDraggable
5069
 
                Makes an element draggable with the supplied options.
5070
 
 
5071
 
        Arguments:
5072
 
                options - see <Drag.Move> and <Drag.Base> for acceptable options.
5073
 
        */
5074
 
 
5075
 
        makeDraggable: function(options){
5076
 
                return new Drag.Move(this, options);
5077
 
        }
5078
 
 
5079
 
});
5080
 
 
5081
 
/*
5082
 
Script: XHR.js
5083
 
        Contains the basic XMLHttpRequest Class Wrapper.
5084
 
 
5085
 
License:
5086
 
        MIT-style license.
5087
 
*/
5088
 
 
5089
 
/*
5090
 
Class: XHR
5091
 
        Basic XMLHttpRequest Wrapper.
5092
 
 
5093
 
Arguments:
5094
 
        options - an object with options names as keys. See options below.
5095
 
 
5096
 
Options:
5097
 
        method - 'post' or 'get' - the protocol for the request; optional, defaults to 'post'.
5098
 
        async - boolean: asynchronous option; true uses asynchronous requests. Defaults to true.
5099
 
        encoding - the encoding, defaults to utf-8.
5100
 
        autoCancel - cancels the already running request if another one is sent. defaults to false.
5101
 
        headers - accepts an object, that will be set to request headers.
5102
 
        
5103
 
Events:
5104
 
        onRequest - function to execute when the XHR request is fired.
5105
 
        onSuccess - function to execute when the XHR request completes.
5106
 
        onStateChange - function to execute when the state of the XMLHttpRequest changes.
5107
 
        onFailure - function to execute when the state of the XMLHttpRequest changes.
5108
 
 
5109
 
Properties:
5110
 
        running - true if the request is running.
5111
 
        response - object, text and xml as keys. You can access this property in the onSuccess event.
5112
 
 
5113
 
Example:
5114
 
        >var myXHR = new XHR({method: 'get'}).send('http://site.com/requestHandler.php', 'name=john&lastname=dorian');
5115
 
*/
5116
 
 
5117
 
var XHR = new Class({
5118
 
 
5119
 
        options: {
5120
 
                method: 'post',
5121
 
                async: true,
5122
 
                onRequest: Class.empty,
5123
 
                onSuccess: Class.empty,
5124
 
                onFailure: Class.empty,
5125
 
                urlEncoded: true,
5126
 
                encoding: 'utf-8',
5127
 
                autoCancel: false,
5128
 
                headers: {}
5129
 
        },
5130
 
 
5131
 
        setTransport: function(){
5132
 
                this.transport = (window.XMLHttpRequest) ? new XMLHttpRequest() : (window.ie ? new ActiveXObject('Microsoft.XMLHTTP') : false);
5133
 
                return this;
5134
 
        },
5135
 
 
5136
 
        initialize: function(options){
5137
 
                this.setTransport().setOptions(options);
5138
 
                this.options.isSuccess = this.options.isSuccess || this.isSuccess;
5139
 
                this.headers = {};
5140
 
                if (this.options.urlEncoded && this.options.method == 'post'){
5141
 
                        var encoding = (this.options.encoding) ? '; charset=' + this.options.encoding : '';
5142
 
                        this.setHeader('Content-type', 'application/x-www-form-urlencoded' + encoding);
5143
 
                }
5144
 
                if (this.options.initialize) this.options.initialize.call(this);
5145
 
        },
5146
 
 
5147
 
        onStateChange: function(){
5148
 
                if (this.transport.readyState != 4 || !this.running) return;
5149
 
                this.running = false;
5150
 
                var status = 0;
5151
 
                try {status = this.transport.status;} catch(e){};
5152
 
                if (this.options.isSuccess.call(this, status)) this.onSuccess();
5153
 
                else this.onFailure();
5154
 
                this.transport.onreadystatechange = Class.empty;
5155
 
        },
5156
 
 
5157
 
        isSuccess: function(status){
5158
 
                return ((status >= 200) && (status < 300));
5159
 
        },
5160
 
 
5161
 
        onSuccess: function(){
5162
 
                this.response = {
5163
 
                        'text': this.transport.responseText,
5164
 
                        'xml': this.transport.responseXML
5165
 
                };
5166
 
                this.fireEvent('onSuccess', [this.response.text, this.response.xml]);
5167
 
                this.callChain();
5168
 
        },
5169
 
 
5170
 
        onFailure: function(){
5171
 
                this.fireEvent('onFailure', this.transport);
5172
 
        },
5173
 
 
5174
 
        /*
5175
 
        Property: setHeader
5176
 
                Add/modify an header for the request. It will not override headers from the options.
5177
 
 
5178
 
        Example:
5179
 
                >var myXhr = new XHR(url, {method: 'get', headers: {'X-Request': 'JSON'}});
5180
 
                >myXhr.setHeader('Last-Modified','Sat, 1 Jan 2005 05:00:00 GMT');
5181
 
        */
5182
 
 
5183
 
        setHeader: function(name, value){
5184
 
                this.headers[name] = value;
5185
 
                return this;
5186
 
        },
5187
 
 
5188
 
        /*
5189
 
        Property: send
5190
 
                Opens the XHR connection and sends the data. Data has to be null or a string.
5191
 
 
5192
 
        Example:
5193
 
                >var myXhr = new XHR({method: 'post'});
5194
 
                >myXhr.send(url, querystring);
5195
 
                >
5196
 
                >var syncXhr = new XHR({async: false, method: 'post'});
5197
 
                >syncXhr.send(url, null);
5198
 
                >
5199
 
        */
5200
 
 
5201
 
        send: function(url, data){
5202
 
                if (this.options.autoCancel) this.cancel();
5203
 
                else if (this.running) return this;
5204
 
                this.running = true;
5205
 
                if (data && this.options.method == 'get'){
5206
 
                        url = url + (url.contains('?') ? '&' : '?') + data;
5207
 
                        data = null;
5208
 
                }
5209
 
                this.transport.open(this.options.method.toUpperCase(), url, this.options.async);
5210
 
                this.transport.onreadystatechange = this.onStateChange.bind(this);
5211
 
                if ((this.options.method == 'post') && this.transport.overrideMimeType) this.setHeader('Connection', 'close');
5212
 
                $extend(this.headers, this.options.headers);
5213
 
                for (var type in this.headers) try {this.transport.setRequestHeader(type, this.headers[type]);} catch(e){};
5214
 
                this.fireEvent('onRequest');
5215
 
                this.transport.send($pick(data, null));
5216
 
                return this;
5217
 
        },
5218
 
 
5219
 
        /*
5220
 
        Property: cancel
5221
 
                Cancels the running request. No effect if the request is not running.
5222
 
 
5223
 
        Example:
5224
 
                >var myXhr = new XHR({method: 'get'}).send(url);
5225
 
                >myXhr.cancel();
5226
 
        */
5227
 
 
5228
 
        cancel: function(){
5229
 
                if (!this.running) return this;
5230
 
                this.running = false;
5231
 
                this.transport.abort();
5232
 
                this.transport.onreadystatechange = Class.empty;
5233
 
                this.setTransport();
5234
 
                this.fireEvent('onCancel');
5235
 
                return this;
5236
 
        }
5237
 
 
5238
 
});
5239
 
 
5240
 
XHR.implement(new Chain, new Events, new Options);
5241
 
 
5242
 
/*
5243
 
Script: Ajax.js
5244
 
        Contains the <Ajax> class. Also contains methods to generate querystings from forms and Objects.
5245
 
 
5246
 
Credits:
5247
 
        Loosely based on the version from prototype.js <http://prototype.conio.net>
5248
 
 
5249
 
License:
5250
 
        MIT-style license.
5251
 
*/
5252
 
 
5253
 
/*
5254
 
Class: Ajax
5255
 
        An Ajax class, For all your asynchronous needs.
5256
 
        Inherits methods, properties, options and events from <XHR>.
5257
 
 
5258
 
Arguments:
5259
 
        url - the url pointing to the server-side script.
5260
 
        options - optional, an object containing options.
5261
 
 
5262
 
Options:
5263
 
        data - you can write parameters here. Can be a querystring, an object or a Form element.
5264
 
        update - $(element) to insert the response text of the XHR into, upon completion of the request.
5265
 
        evalScripts - boolean; default is false. Execute scripts in the response text onComplete. When the response is javascript the whole response is evaluated.
5266
 
        evalResponse - boolean; default is false. Force global evalulation of the whole response, no matter what content-type it is.
5267
 
        
5268
 
Events:
5269
 
        onComplete - function to execute when the ajax request completes.
5270
 
 
5271
 
Example:
5272
 
        >var myAjax = new Ajax(url, {method: 'get'}).request();
5273
 
*/
5274
 
 
5275
 
var Ajax = XHR.extend({
5276
 
 
5277
 
        options: {
5278
 
                data: null,
5279
 
                update: null,
5280
 
                onComplete: Class.empty,
5281
 
                evalScripts: false,
5282
 
                evalResponse: false
5283
 
        },
5284
 
 
5285
 
        initialize: function(url, options){
5286
 
                this.addEvent('onSuccess', this.onComplete);
5287
 
                this.setOptions(options);
5288
 
                /*compatibility*/
5289
 
                this.options.data = this.options.data || this.options.postBody;
5290
 
                /*end compatibility*/
5291
 
                if (!['post', 'get'].contains(this.options.method)){
5292
 
                        this._method = '_method=' + this.options.method;
5293
 
                        this.options.method = 'post';
5294
 
                }
5295
 
                this.parent();
5296
 
                this.setHeader('X-Requested-With', 'XMLHttpRequest');
5297
 
                this.setHeader('Accept', 'text/javascript, text/html, application/xml, text/xml, */*');
5298
 
                this.url = url;
5299
 
        },
5300
 
 
5301
 
        onComplete: function(){
5302
 
                if (this.options.update) $(this.options.update).empty().setHTML(this.response.text);
5303
 
                if (this.options.evalScripts || this.options.evalResponse) this.evalScripts();
5304
 
                this.fireEvent('onComplete', [this.response.text, this.response.xml], 20);
5305
 
        },
5306
 
 
5307
 
        /*
5308
 
        Property: request
5309
 
                Executes the ajax request.
5310
 
 
5311
 
        Example:
5312
 
                >var myAjax = new Ajax(url, {method: 'get'});
5313
 
                >myAjax.request();
5314
 
 
5315
 
                OR
5316
 
 
5317
 
                >new Ajax(url, {method: 'get'}).request();
5318
 
        */
5319
 
 
5320
 
        request: function(data){
5321
 
                data = data || this.options.data;
5322
 
                switch($type(data)){
5323
 
                        case 'element': data = $(data).toQueryString(); break;
5324
 
                        case 'object': data = Object.toQueryString(data);
5325
 
                }
5326
 
                if (this._method) data = (data) ? [this._method, data].join('&') : this._method;
5327
 
                return this.send(this.url, data);
5328
 
        },
5329
 
 
5330
 
        /*
5331
 
        Property: evalScripts
5332
 
                Executes scripts in the response text
5333
 
        */
5334
 
 
5335
 
        evalScripts: function(){
5336
 
                var script, scripts;
5337
 
                if (this.options.evalResponse || (/(ecma|java)script/).test(this.getHeader('Content-type'))) scripts = this.response.text;
5338
 
                else {
5339
 
                        scripts = [];
5340
 
                        var regexp = /<script[^>]*>([\s\S]*?)<\/script>/gi;
5341
 
                        while ((script = regexp.exec(this.response.text))) scripts.push(script[1]);
5342
 
                        scripts = scripts.join('\n');
5343
 
                }
5344
 
                if (scripts) (window.execScript) ? window.execScript(scripts) : window.setTimeout(scripts, 0);
5345
 
        },
5346
 
 
5347
 
        /*
5348
 
        Property: getHeader
5349
 
                Returns the given response header or null
5350
 
        */
5351
 
 
5352
 
        getHeader: function(name){
5353
 
                try {return this.transport.getResponseHeader(name);} catch(e){};
5354
 
                return null;
5355
 
        }
5356
 
 
5357
 
});
5358
 
 
5359
 
/* Section: Object related Functions */
5360
 
 
5361
 
/*
5362
 
Function: Object.toQueryString
5363
 
        Generates a querystring from key/pair values in an object
5364
 
 
5365
 
Arguments:
5366
 
        source - the object to generate the querystring from.
5367
 
 
5368
 
Returns:
5369
 
        the query string.
5370
 
 
5371
 
Example:
5372
 
        >Object.toQueryString({apple: "red", lemon: "yellow"}); //returns "apple=red&lemon=yellow"
5373
 
*/
5374
 
 
5375
 
Object.toQueryString = function(source){
5376
 
        var queryString = [];
5377
 
        for (var property in source) queryString.push(encodeURIComponent(property) + '=' + encodeURIComponent(source[property]));
5378
 
        return queryString.join('&');
5379
 
};
5380
 
 
5381
 
/*
5382
 
Class: Element
5383
 
        Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>.
5384
 
*/
5385
 
 
5386
 
Element.extend({
5387
 
 
5388
 
        /*
5389
 
        Property: send
5390
 
                Sends a form with an ajax post request
5391
 
 
5392
 
        Arguments:
5393
 
                options - option collection for ajax request. See <Ajax> for the options list.
5394
 
 
5395
 
        Returns:
5396
 
                The Ajax Class Instance
5397
 
 
5398
 
        Example:
5399
 
                (start code)
5400
 
                <form id="myForm" action="submit.php">
5401
 
                <input name="email" value="bob@bob.com">
5402
 
                <input name="zipCode" value="90210">
5403
 
                </form>
5404
 
                <script>
5405
 
                $('myForm').send()
5406
 
                </script>
5407
 
                (end)
5408
 
        */
5409
 
 
5410
 
        send: function(options){
5411
 
                return new Ajax(this.getProperty('action'), $merge({data: this.toQueryString()}, options, {method: 'post'})).request();
5412
 
        }
5413
 
 
5414
 
});
5415
 
 
5416
 
/*
5417
 
Script: Cookie.js
5418
 
        A cookie reader/creator
5419
 
 
5420
 
Credits:
5421
 
        based on the functions by Peter-Paul Koch (http://quirksmode.org)
5422
 
*/
5423
 
 
5424
 
/*
5425
 
Class: Cookie
5426
 
        Class for creating, getting, and removing cookies.
5427
 
*/
5428
 
 
5429
 
var Cookie = new Abstract({
5430
 
 
5431
 
        options: {
5432
 
                domain: false,
5433
 
                path: false,
5434
 
                duration: false,
5435
 
                secure: false
5436
 
        },
5437
 
 
5438
 
        /*
5439
 
        Property: set
5440
 
                Sets a cookie in the browser.
5441
 
 
5442
 
        Arguments:
5443
 
                key - the key (name) for the cookie
5444
 
                value - the value to set, cannot contain semicolons
5445
 
                options - an object representing the Cookie options. See Options below. Default values are stored in Cookie.options.
5446
 
 
5447
 
        Options:
5448
 
                domain - the domain the Cookie belongs to. If you want to share the cookie with pages located on a different domain, you have to set this value. Defaults to the current domain.
5449
 
                path - the path the Cookie belongs to. If you want to share the cookie with pages located in a different path, you have to set this value, for example to "/" to share the cookie with all pages on the domain. Defaults to the current path.
5450
 
                duration - the duration of the Cookie before it expires, in days.
5451
 
                                        If set to false or 0, the cookie will be a session cookie that expires when the browser is closed. This is default.
5452
 
                secure - Stored cookie information can be accessed only from a secure environment.
5453
 
 
5454
 
        Returns:
5455
 
                An object with the options, the key and the value. You can give it as first parameter to Cookie.remove.
5456
 
 
5457
 
        Example:
5458
 
                >Cookie.set('username', 'Harald'); // session cookie (duration is false), or ...
5459
 
                >Cookie.set('username', 'JackBauer', {duration: 1}); // save this for 1 day
5460
 
 
5461
 
        */
5462
 
 
5463
 
        set: function(key, value, options){
5464
 
                options = $merge(this.options, options);
5465
 
                value = encodeURIComponent(value);
5466
 
                if (options.domain) value += '; domain=' + options.domain;
5467
 
                if (options.path) value += '; path=' + options.path;
5468
 
                if (options.duration){
5469
 
                        var date = new Date();
5470
 
                        date.setTime(date.getTime() + options.duration * 24 * 60 * 60 * 1000);
5471
 
                        value += '; expires=' + date.toGMTString();
5472
 
                }
5473
 
                if (options.secure) value += '; secure';
5474
 
                document.cookie = key + '=' + value;
5475
 
                return $extend(options, {'key': key, 'value': value});
5476
 
        },
5477
 
 
5478
 
        /*
5479
 
        Property: get
5480
 
                Gets the value of a cookie.
5481
 
 
5482
 
        Arguments:
5483
 
                key - the name of the cookie you wish to retrieve.
5484
 
 
5485
 
        Returns:
5486
 
                The cookie string value, or false if not found.
5487
 
 
5488
 
        Example:
5489
 
                >Cookie.get("username") //returns JackBauer
5490
 
        */
5491
 
 
5492
 
        get: function(key){
5493
 
                var value = document.cookie.match('(?:^|;)\\s*' + key.escapeRegExp() + '=([^;]*)');
5494
 
                return value ? decodeURIComponent(value[1]) : false;
5495
 
        },
5496
 
 
5497
 
        /*
5498
 
        Property: remove
5499
 
                Removes a cookie from the browser.
5500
 
 
5501
 
        Arguments:
5502
 
                cookie - the name of the cookie to remove or a previous cookie (for domains)
5503
 
                options - optional. you can also pass the domain and path here. Same as options in <Cookie.set>
5504
 
 
5505
 
        Examples:
5506
 
                >Cookie.remove('username') //bye-bye JackBauer, cya in 24 hours
5507
 
                >
5508
 
                >var myCookie = Cookie.set('username', 'Aaron', {domain: 'mootools.net'}); // Cookie.set returns an object with all values need to remove the cookie
5509
 
                >Cookie.remove(myCookie);
5510
 
        */
5511
 
 
5512
 
        remove: function(cookie, options){
5513
 
                if ($type(cookie) == 'object') this.set(cookie.key, '', $merge(cookie, {duration: -1}));
5514
 
                else this.set(cookie, '', $merge(options, {duration: -1}));
5515
 
        }
5516
 
 
5517
 
});
5518
 
 
5519
 
/*
5520
 
Script: Json.js
5521
 
        Simple Json parser and Stringyfier, See: <http://www.json.org/>
5522
 
 
5523
 
License:
5524
 
        MIT-style license.
5525
 
*/
5526
 
 
5527
 
/*
5528
 
Class: Json
5529
 
        Simple Json parser and Stringyfier, See: <http://www.json.org/>
5530
 
*/
5531
 
 
5532
 
var Json = {
5533
 
 
5534
 
        /*
5535
 
        Property: toString
5536
 
                Converts an object to a string, to be passed in server-side scripts as a parameter. Although its not normal usage for this class, this method can also be used to convert functions and arrays to strings.
5537
 
 
5538
 
        Arguments:
5539
 
                obj - the object to convert to string
5540
 
 
5541
 
        Returns:
5542
 
                A json string
5543
 
 
5544
 
        Example:
5545
 
                (start code)
5546
 
                Json.toString({apple: 'red', lemon: 'yellow'}); '{"apple":"red","lemon":"yellow"}'
5547
 
                (end)
5548
 
        */
5549
 
 
5550
 
        toString: function(obj){
5551
 
                switch($type(obj)){
5552
 
                        case 'string':
5553
 
                                return '"' + obj.replace(/(["\\])/g, '\\$1') + '"';
5554
 
                        case 'array':
5555
 
                                return '[' + obj.map(Json.toString).join(',') + ']';
5556
 
                        case 'object':
5557
 
                                var string = [];
5558
 
                                for (var property in obj) string.push(Json.toString(property) + ':' + Json.toString(obj[property]));
5559
 
                                return '{' + string.join(',') + '}';
5560
 
                        case 'number':
5561
 
                                if (isFinite(obj)) break;
5562
 
                        case false:
5563
 
                                return 'null';
5564
 
                }
5565
 
                return String(obj);
5566
 
        },
5567
 
 
5568
 
        /*
5569
 
        Property: evaluate
5570
 
                converts a json string to an javascript Object.
5571
 
 
5572
 
        Arguments:
5573
 
                str - the string to evaluate. if its not a string, it returns false.
5574
 
                secure - optionally, performs syntax check on json string. Defaults to false.
5575
 
 
5576
 
        Credits:
5577
 
                Json test regexp is by Douglas Crockford <http://crockford.org>.
5578
 
 
5579
 
        Example:
5580
 
                >var myObject = Json.evaluate('{"apple":"red","lemon":"yellow"}');
5581
 
                >//myObject will become {apple: 'red', lemon: 'yellow'}
5582
 
        */
5583
 
 
5584
 
        evaluate: function(str, secure){
5585
 
                return (($type(str) != 'string') || (secure && !str.test(/^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/))) ? null : eval('(' + str + ')');
5586
 
        }
5587
 
 
5588
 
};
5589
 
 
5590
 
/*
5591
 
Script: Json.Remote.js
5592
 
        Contains <Json.Remote>.
5593
 
 
5594
 
License:
5595
 
        MIT-style license.
5596
 
*/
5597
 
 
5598
 
/*
5599
 
Class: Json.Remote
5600
 
        Wrapped XHR with automated sending and receiving of Javascript Objects in Json Format.
5601
 
        Inherits methods, properties, options and events from <XHR>.
5602
 
 
5603
 
Arguments:
5604
 
        url - the url you want to send your object to.
5605
 
        options - see <XHR> options
5606
 
 
5607
 
Example:
5608
 
        this code will send user information based on name/last name
5609
 
        (start code)
5610
 
        var jSonRequest = new Json.Remote("http://site.com/tellMeAge.php", {onComplete: function(person){
5611
 
                alert(person.age); //is 25 years
5612
 
                alert(person.height); //is 170 cm
5613
 
                alert(person.weight); //is 120 kg
5614
 
        }}).send({'name': 'John', 'lastName': 'Doe'});
5615
 
        (end)
5616
 
*/
5617
 
 
5618
 
Json.Remote = XHR.extend({
5619
 
 
5620
 
        initialize: function(url, options){
5621
 
                this.url = url;
5622
 
                this.addEvent('onSuccess', this.onComplete);
5623
 
                this.parent(options);
5624
 
                this.setHeader('X-Request', 'JSON');
5625
 
        },
5626
 
 
5627
 
        send: function(obj){
5628
 
                return this.parent(this.url, 'json=' + Json.toString(obj));
5629
 
        },
5630
 
 
5631
 
        onComplete: function(){
5632
 
                this.fireEvent('onComplete', [Json.evaluate(this.response.text, this.options.secure)]);
5633
 
        }
5634
 
 
5635
 
});
5636
 
 
5637
 
/*
5638
 
Script: Assets.js
5639
 
        provides dynamic loading for images, css and javascript files.
5640
 
 
5641
 
License:
5642
 
        MIT-style license.
5643
 
*/
5644
 
 
5645
 
var Asset = new Abstract({
5646
 
 
5647
 
        /*
5648
 
        Property: javascript
5649
 
                Injects a javascript file in the page.
5650
 
 
5651
 
        Arguments:
5652
 
                source - the path of the javascript file
5653
 
                properties - some additional attributes you might want to add to the script element
5654
 
 
5655
 
        Example:
5656
 
                > new Asset.javascript('/scripts/myScript.js', {id: 'myScript'});
5657
 
        */
5658
 
 
5659
 
        javascript: function(source, properties){
5660
 
                properties = $merge({
5661
 
                        'onload': Class.empty
5662
 
                }, properties);
5663
 
                var script = new Element('script', {'src': source}).addEvents({
5664
 
                        'load': properties.onload,
5665
 
                        'readystatechange': function(){
5666
 
                                if (this.readyState == 'complete') this.fireEvent('load');
5667
 
                        }
5668
 
                });
5669
 
                delete properties.onload;
5670
 
                return script.setProperties(properties).inject(document.head);
5671
 
        },
5672
 
 
5673
 
        /*
5674
 
        Property: css
5675
 
                Injects a css file in the page.
5676
 
 
5677
 
        Arguments:
5678
 
                source - the path of the css file
5679
 
                properties - some additional attributes you might want to add to the link element
5680
 
 
5681
 
        Example:
5682
 
                > new Asset.css('/css/myStyle.css', {id: 'myStyle', title: 'myStyle'});
5683
 
        */
5684
 
 
5685
 
        css: function(source, properties){
5686
 
                return new Element('link', $merge({
5687
 
                        'rel': 'stylesheet', 'media': 'screen', 'type': 'text/css', 'href': source
5688
 
                }, properties)).inject(document.head);
5689
 
        },
5690
 
 
5691
 
        /*
5692
 
        Property: image
5693
 
                Preloads an image and returns the img element. does not inject it to the page.
5694
 
 
5695
 
        Arguments:
5696
 
                source - the path of the image file
5697
 
                properties - some additional attributes you might want to add to the img element
5698
 
 
5699
 
        Example:
5700
 
                > new Asset.image('/images/myImage.png', {id: 'myImage', title: 'myImage', onload: myFunction});
5701
 
 
5702
 
        Returns:
5703
 
                the img element. you can inject it anywhere you want with <Element.injectInside>/<Element.injectAfter>/<Element.injectBefore>
5704
 
        */
5705
 
 
5706
 
        image: function(source, properties){
5707
 
                properties = $merge({
5708
 
                        'onload': Class.empty,
5709
 
                        'onabort': Class.empty,
5710
 
                        'onerror': Class.empty
5711
 
                }, properties);
5712
 
                var image = new Image();
5713
 
                image.src = source;
5714
 
                var element = new Element('img', {'src': source});
5715
 
                ['load', 'abort', 'error'].each(function(type){
5716
 
                        var event = properties['on' + type];
5717
 
                        delete properties['on' + type];
5718
 
                        element.addEvent(type, function(){
5719
 
                                this.removeEvent(type, arguments.callee);
5720
 
                                event.call(this);
5721
 
                        });
5722
 
                });
5723
 
                if (image.width && image.height) element.fireEvent('load', element, 1);
5724
 
                return element.setProperties(properties);
5725
 
        },
5726
 
 
5727
 
        /*
5728
 
        Property: images
5729
 
                Preloads an array of images (as strings) and returns an array of img elements. does not inject them to the page.
5730
 
 
5731
 
        Arguments:
5732
 
                sources - array, the paths of the image files
5733
 
                options - object, see below
5734
 
 
5735
 
        Options:
5736
 
                onComplete - a function to execute when all image files are loaded in the browser's cache
5737
 
                onProgress - a function to execute when one image file is loaded in the browser's cache
5738
 
 
5739
 
        Example:
5740
 
                (start code)
5741
 
                new Asset.images(['/images/myImage.png', '/images/myImage2.gif'], {
5742
 
                        onComplete: function(){
5743
 
                                alert('all images loaded!');
5744
 
                        }
5745
 
                });
5746
 
                (end)
5747
 
 
5748
 
        Returns:
5749
 
                the img elements as $$. you can inject them anywhere you want with <Element.injectInside>/<Element.injectAfter>/<Element.injectBefore>
5750
 
        */
5751
 
 
5752
 
        images: function(sources, options){
5753
 
                options = $merge({
5754
 
                        onComplete: Class.empty,
5755
 
                        onProgress: Class.empty
5756
 
                }, options);
5757
 
                if (!sources.push) sources = [sources];
5758
 
                var images = [];
5759
 
                var counter = 0;
5760
 
                sources.each(function(source){
5761
 
                        var img = new Asset.image(source, {
5762
 
                                'onload': function(){
5763
 
                                        options.onProgress.call(this, counter);
5764
 
                                        counter++;
5765
 
                                        if (counter == sources.length) options.onComplete();
5766
 
                                }
5767
 
                        });
5768
 
                        images.push(img);
5769
 
                });
5770
 
                return new Elements(images);
5771
 
        }
5772
 
 
5773
 
});
5774
 
 
5775
 
/*
5776
 
Script: Hash.js
5777
 
        Contains the class Hash.
5778
 
 
5779
 
License:
5780
 
        MIT-style license.
5781
 
*/
5782
 
 
5783
 
/*
5784
 
Class: Hash
5785
 
        It wraps an object that it uses internally as a map. The user must use set(), get(), and remove() to add/change, retrieve and remove values, it must not access the internal object directly. null/undefined values are allowed.
5786
 
 
5787
 
Note:
5788
 
        Each hash instance has the length property.
5789
 
 
5790
 
Arguments:
5791
 
        obj - an object to convert into a Hash instance.
5792
 
 
5793
 
Example:
5794
 
        (start code)
5795
 
        var hash = new Hash({a: 'hi', b: 'world', c: 'howdy'});
5796
 
        hash.remove('b'); // b is removed.
5797
 
        hash.set('c', 'hello');
5798
 
        hash.get('c'); // returns 'hello'
5799
 
        hash.length // returns 2 (a and c)
5800
 
        (end)
5801
 
*/
5802
 
 
5803
 
var Hash = new Class({
5804
 
 
5805
 
        length: 0,
5806
 
 
5807
 
        initialize: function(object){
5808
 
                this.obj = object || {};
5809
 
                this.setLength();
5810
 
        },
5811
 
 
5812
 
        /*
5813
 
        Property: get
5814
 
                Retrieves a value from the hash.
5815
 
 
5816
 
        Arguments:
5817
 
                key - The key
5818
 
 
5819
 
        Returns:
5820
 
                The value
5821
 
        */
5822
 
 
5823
 
        get: function(key){
5824
 
                return (this.hasKey(key)) ? this.obj[key] : null;
5825
 
        },
5826
 
 
5827
 
        /*
5828
 
        Property: hasKey
5829
 
                Check the presence of a specified key-value pair in the hash.
5830
 
 
5831
 
        Arguments:
5832
 
                key - The key
5833
 
 
5834
 
        Returns:
5835
 
                True if the Hash contains a value for the specified key, otherwise false
5836
 
        */
5837
 
 
5838
 
        hasKey: function(key){
5839
 
                return (key in this.obj);
5840
 
        },
5841
 
 
5842
 
        /*
5843
 
        Property: set
5844
 
                Adds a key-value pair to the hash or replaces a previous value associated with the key.
5845
 
 
5846
 
        Arguments:
5847
 
                key - The key
5848
 
                value - The value
5849
 
        */
5850
 
 
5851
 
        set: function(key, value){
5852
 
                if (!this.hasKey(key)) this.length++;
5853
 
                this.obj[key] = value;
5854
 
                return this;
5855
 
        },
5856
 
 
5857
 
        setLength: function(){
5858
 
                this.length = 0;
5859
 
                for (var p in this.obj) this.length++;
5860
 
                return this;
5861
 
        },
5862
 
 
5863
 
        /*
5864
 
        Property: remove
5865
 
                Removes a key-value pair from the hash.
5866
 
 
5867
 
        Arguments:
5868
 
                key - The key
5869
 
        */
5870
 
 
5871
 
        remove: function(key){
5872
 
                if (this.hasKey(key)){
5873
 
                        delete this.obj[key];
5874
 
                        this.length--;
5875
 
                }
5876
 
                return this;
5877
 
        },
5878
 
 
5879
 
        /*
5880
 
        Property: each
5881
 
                Calls a function for each key-value pair. The first argument passed to the function will be the value, the second one will be the key, like $each.
5882
 
 
5883
 
        Arguments:
5884
 
                fn - The function to call for each key-value pair
5885
 
                bind - Optional, the object that will be referred to as "this" in the function
5886
 
        */
5887
 
 
5888
 
        each: function(fn, bind){
5889
 
                $each(this.obj, fn, bind);
5890
 
        },
5891
 
 
5892
 
        /*
5893
 
        Property: extend
5894
 
                Extends the current hash with an object containing key-value pairs. Values for duplicate keys will be replaced by the new ones.
5895
 
 
5896
 
        Arguments:
5897
 
                obj - An object containing key-value pairs
5898
 
        */
5899
 
 
5900
 
        extend: function(obj){
5901
 
                $extend(this.obj, obj);
5902
 
                return this.setLength();
5903
 
        },
5904
 
 
5905
 
        /*
5906
 
        Property: merge
5907
 
                Merges the current hash with multiple objects.
5908
 
        */
5909
 
 
5910
 
        merge: function(){
5911
 
                this.obj = $merge.apply(null, [this.obj].extend(arguments));
5912
 
                return this.setLength();
5913
 
        },
5914
 
 
5915
 
        /*
5916
 
        Property: empty
5917
 
                Empties all hash values properties and values.
5918
 
        */
5919
 
 
5920
 
        empty: function(){
5921
 
                this.obj = {};
5922
 
                this.length = 0;
5923
 
                return this;
5924
 
        },
5925
 
 
5926
 
        /*
5927
 
        Property: keys
5928
 
                Returns an array containing all the keys, in the same order as the values returned by <Hash.values>.
5929
 
 
5930
 
        Returns:
5931
 
                An array containing all the keys of the hash
5932
 
        */
5933
 
 
5934
 
        keys: function(){
5935
 
                var keys = [];
5936
 
                for (var property in this.obj) keys.push(property);
5937
 
                return keys;
5938
 
        },
5939
 
 
5940
 
        /*
5941
 
        Property: values
5942
 
                Returns an array containing all the values, in the same order as the keys returned by <Hash.keys>.
5943
 
 
5944
 
        Returns:
5945
 
                An array containing all the values of the hash
5946
 
        */
5947
 
 
5948
 
        values: function(){
5949
 
                var values = [];
5950
 
                for (var property in this.obj) values.push(this.obj[property]);
5951
 
                return values;
5952
 
        }
5953
 
 
5954
 
});
5955
 
 
5956
 
/* Section: Utility Functions */
5957
 
 
5958
 
/*
5959
 
Function: $H
5960
 
        Shortcut to create a Hash from an Object.
5961
 
*/
5962
 
 
5963
 
function $H(obj){
5964
 
        return new Hash(obj);
5965
 
};
5966
 
 
5967
 
/*
5968
 
Script: Hash.Cookie.js
5969
 
        Stores and loads an Hash as a cookie using Json format.
5970
 
*/
5971
 
 
5972
 
/*
5973
 
Class: Hash.Cookie
5974
 
        Inherits all the methods from <Hash>, additional methods are save and load.
5975
 
        Hash json string has a limit of 4kb (4096byte), so be careful with your Hash size.
5976
 
        Creating a new instance automatically loads the data from the Cookie into the Hash.
5977
 
        If the Hash is emptied, the cookie is also removed.
5978
 
 
5979
 
Arguments:
5980
 
        name - the key (name) for the cookie
5981
 
        options - options are identical to <Cookie> and are simply passed along to it.
5982
 
                In addition, it has the autoSave option, to save the cookie at every operation. defaults to true.
5983
 
 
5984
 
Example:
5985
 
        (start code)
5986
 
        var fruits = new Hash.Cookie('myCookieName', {duration: 3600});
5987
 
        fruits.extend({
5988
 
                'lemon': 'yellow',
5989
 
                'apple': 'red'
5990
 
        });
5991
 
        fruits.set('melon', 'green');
5992
 
        fruits.get('lemon'); // yellow
5993
 
 
5994
 
        // ... on another page ... values load automatically
5995
 
 
5996
 
        var fruits = new Hash.Cookie('myCookieName', {duration: 365});
5997
 
        fruits.get('melon'); // green
5998
 
 
5999
 
        fruits.erase(); // delete cookie
6000
 
        (end)
6001
 
*/
6002
 
 
6003
 
Hash.Cookie = Hash.extend({
6004
 
 
6005
 
        initialize: function(name, options){
6006
 
                this.name = name;
6007
 
                this.options = $extend({'autoSave': true}, options || {});
6008
 
                this.load();
6009
 
        },
6010
 
 
6011
 
        /*
6012
 
        Property: save
6013
 
                Saves the Hash to the cookie. If the hash is empty, removes the cookie.
6014
 
 
6015
 
        Returns:
6016
 
                Returns false when the JSON string cookie is too long (4kb), otherwise true.
6017
 
 
6018
 
        Example:
6019
 
                (start code)
6020
 
                var login = new Hash.Cookie('userstatus', {autoSave: false});
6021
 
 
6022
 
                login.extend({
6023
 
                        'username': 'John',
6024
 
                        'credentials': [4, 7, 9]
6025
 
                });
6026
 
                login.set('last_message', 'User logged in!');
6027
 
 
6028
 
                login.save(); // finally save the Hash
6029
 
                (end)
6030
 
        */
6031
 
 
6032
 
        save: function(){
6033
 
                if (this.length == 0){
6034
 
                        Cookie.remove(this.name, this.options);
6035
 
                        return true;
6036
 
                }
6037
 
                var str = Json.toString(this.obj);
6038
 
                if (str.length > 4096) return false; //cookie would be truncated!
6039
 
                Cookie.set(this.name, str, this.options);
6040
 
                return true;
6041
 
        },
6042
 
        
6043
 
        /*
6044
 
        Property: load
6045
 
                Loads the cookie and assigns it to the Hash.
6046
 
        */
6047
 
 
6048
 
        load: function(){
6049
 
                this.obj = Json.evaluate(Cookie.get(this.name), true) || {};
6050
 
                this.setLength();
6051
 
        }
6052
 
 
6053
 
});
6054
 
 
6055
 
Hash.Cookie.Methods = {};
6056
 
['extend', 'set', 'merge', 'empty', 'remove'].each(function(method){
6057
 
        Hash.Cookie.Methods[method] = function(){
6058
 
                Hash.prototype[method].apply(this, arguments);
6059
 
                if (this.options.autoSave) this.save();
6060
 
                return this;
6061
 
        };
6062
 
});
6063
 
Hash.Cookie.implement(Hash.Cookie.Methods);
6064
 
 
6065
 
/*
6066
 
Script: Color.js
6067
 
        Contains the Color class.
6068
 
 
6069
 
License:
6070
 
        MIT-style license.
6071
 
*/
6072
 
 
6073
 
/*
6074
 
Class: Color
6075
 
        Creates a new Color Object, which is an array with some color specific methods.
6076
 
Arguments:
6077
 
        color - the hex, the RGB array or the HSB array of the color to create. For HSB colors, you need to specify the second argument.
6078
 
        type - a string representing the type of the color to create. needs to be specified if you intend to create the color with HSB values, or an array of HEX values. Can be 'rgb', 'hsb' or 'hex'.
6079
 
 
6080
 
Example:
6081
 
        (start code)
6082
 
        var black = new Color('#000');
6083
 
        var purple = new Color([255,0,255]);
6084
 
        // mix black with white and purple, each time at 10% of the new color
6085
 
        var darkpurple = black.mix('#fff', purple, 10);
6086
 
        $('myDiv').setStyle('background-color', darkpurple);
6087
 
        (end)
6088
 
*/
6089
 
 
6090
 
var Color = new Class({
6091
 
 
6092
 
        initialize: function(color, type){
6093
 
                type = type || (color.push ? 'rgb' : 'hex');
6094
 
                var rgb, hsb;
6095
 
                switch(type){
6096
 
                        case 'rgb':
6097
 
                                rgb = color;
6098
 
                                hsb = rgb.rgbToHsb();
6099
 
                                break;
6100
 
                        case 'hsb':
6101
 
                                rgb = color.hsbToRgb();
6102
 
                                hsb = color;
6103
 
                                break;
6104
 
                        default:
6105
 
                                rgb = color.hexToRgb(true);
6106
 
                                hsb = rgb.rgbToHsb();
6107
 
                }
6108
 
                rgb.hsb = hsb;
6109
 
                rgb.hex = rgb.rgbToHex();
6110
 
                return $extend(rgb, Color.prototype);
6111
 
        },
6112
 
 
6113
 
        /*
6114
 
        Property: mix
6115
 
                Mixes two or more colors with the Color.
6116
 
                
6117
 
        Arguments:
6118
 
                color - a color to mix. you can use as arguments how many colors as you want to mix with the original one.
6119
 
                alpha - if you use a number as the last argument, it will be threated as the amount of the color to mix.
6120
 
        */
6121
 
 
6122
 
        mix: function(){
6123
 
                var colors = $A(arguments);
6124
 
                var alpha = ($type(colors[colors.length - 1]) == 'number') ? colors.pop() : 50;
6125
 
                var rgb = this.copy();
6126
 
                colors.each(function(color){
6127
 
                        color = new Color(color);
6128
 
                        for (var i = 0; i < 3; i++) rgb[i] = Math.round((rgb[i] / 100 * (100 - alpha)) + (color[i] / 100 * alpha));
6129
 
                });
6130
 
                return new Color(rgb, 'rgb');
6131
 
        },
6132
 
 
6133
 
        /*
6134
 
        Property: invert
6135
 
                Inverts the Color.
6136
 
        */
6137
 
 
6138
 
        invert: function(){
6139
 
                return new Color(this.map(function(value){
6140
 
                        return 255 - value;
6141
 
                }));
6142
 
        },
6143
 
 
6144
 
        /*
6145
 
        Property: setHue
6146
 
                Modifies the hue of the Color, and returns a new one.
6147
 
        
6148
 
        Arguments:
6149
 
                value - the hue to set
6150
 
        */
6151
 
 
6152
 
        setHue: function(value){
6153
 
                return new Color([value, this.hsb[1], this.hsb[2]], 'hsb');
6154
 
        },
6155
 
 
6156
 
        /*
6157
 
        Property: setSaturation
6158
 
                Changes the saturation of the Color, and returns a new one.
6159
 
        
6160
 
        Arguments:
6161
 
                percent - the percentage of the saturation to set
6162
 
        */
6163
 
 
6164
 
        setSaturation: function(percent){
6165
 
                return new Color([this.hsb[0], percent, this.hsb[2]], 'hsb');
6166
 
        },
6167
 
 
6168
 
        /*
6169
 
        Property: setBrightness
6170
 
                Changes the brightness of the Color, and returns a new one.
6171
 
        
6172
 
        Arguments:
6173
 
                percent - the percentage of the brightness to set
6174
 
        */
6175
 
 
6176
 
        setBrightness: function(percent){
6177
 
                return new Color([this.hsb[0], this.hsb[1], percent], 'hsb');
6178
 
        }
6179
 
 
6180
 
});
6181
 
 
6182
 
/* Section: Utility Functions */
6183
 
 
6184
 
/*
6185
 
Function: $RGB
6186
 
        Shortcut to create a new color, based on red, green, blue values.
6187
 
 
6188
 
Arguments:
6189
 
        r - (integer) red value (0-255)
6190
 
        g - (integer) green value (0-255)
6191
 
        b - (integer) blue value (0-255)
6192
 
 
6193
 
*/
6194
 
 
6195
 
function $RGB(r, g, b){
6196
 
        return new Color([r, g, b], 'rgb');
6197
 
};
6198
 
 
6199
 
/*
6200
 
Function: $HSB
6201
 
        Shortcut to create a new color, based on hue, saturation, brightness values.
6202
 
 
6203
 
Arguments:
6204
 
        h - (integer) hue value (0-100)
6205
 
        s - (integer) saturation value (0-100)
6206
 
        b - (integer) brightness value (0-100)
6207
 
*/
6208
 
 
6209
 
function $HSB(h, s, b){
6210
 
        return new Color([h, s, b], 'hsb');
6211
 
};
6212
 
 
6213
 
/*
6214
 
Class: Array
6215
 
        A collection of The Array Object prototype methods.
6216
 
*/
6217
 
 
6218
 
Array.extend({
6219
 
        
6220
 
        /*
6221
 
        Property: rgbToHsb
6222
 
                Converts a RGB array to an HSB array.
6223
 
 
6224
 
        Returns:
6225
 
                the HSB array.
6226
 
        */
6227
 
 
6228
 
        rgbToHsb: function(){
6229
 
                var red = this[0], green = this[1], blue = this[2];
6230
 
                var hue, saturation, brightness;
6231
 
                var max = Math.max(red, green, blue), min = Math.min(red, green, blue);
6232
 
                var delta = max - min;
6233
 
                brightness = max / 255;
6234
 
                saturation = (max != 0) ? delta / max : 0;
6235
 
                if (saturation == 0){
6236
 
                        hue = 0;
6237
 
                } else {
6238
 
                        var rr = (max - red) / delta;
6239
 
                        var gr = (max - green) / delta;
6240
 
                        var br = (max - blue) / delta;
6241
 
                        if (red == max) hue = br - gr;
6242
 
                        else if (green == max) hue = 2 + rr - br;
6243
 
                        else hue = 4 + gr - rr;
6244
 
                        hue /= 6;
6245
 
                        if (hue < 0) hue++;
6246
 
                }
6247
 
                return [Math.round(hue * 360), Math.round(saturation * 100), Math.round(brightness * 100)];
6248
 
        },
6249
 
 
6250
 
        /*
6251
 
        Property: hsbToRgb
6252
 
                Converts an HSB array to an RGB array.
6253
 
 
6254
 
        Returns:
6255
 
                the RGB array.
6256
 
        */
6257
 
 
6258
 
        hsbToRgb: function(){
6259
 
                var br = Math.round(this[2] / 100 * 255);
6260
 
                if (this[1] == 0){
6261
 
                        return [br, br, br];
6262
 
                } else {
6263
 
                        var hue = this[0] % 360;
6264
 
                        var f = hue % 60;
6265
 
                        var p = Math.round((this[2] * (100 - this[1])) / 10000 * 255);
6266
 
                        var q = Math.round((this[2] * (6000 - this[1] * f)) / 600000 * 255);
6267
 
                        var t = Math.round((this[2] * (6000 - this[1] * (60 - f))) / 600000 * 255);
6268
 
                        switch(Math.floor(hue / 60)){
6269
 
                                case 0: return [br, t, p];
6270
 
                                case 1: return [q, br, p];
6271
 
                                case 2: return [p, br, t];
6272
 
                                case 3: return [p, q, br];
6273
 
                                case 4: return [t, p, br];
6274
 
                                case 5: return [br, p, q];
6275
 
                        }
6276
 
                }
6277
 
                return false;
6278
 
        }
6279
 
 
6280
 
});
6281
 
 
6282
 
/*
6283
 
Script: Scroller.js
6284
 
        Contains the <Scroller>.
6285
 
 
6286
 
License:
6287
 
        MIT-style license.
6288
 
*/
6289
 
 
6290
 
/*
6291
 
Class: Scroller
6292
 
        The Scroller is a class to scroll any element with an overflow (including the window) when the mouse cursor reaches certain buondaries of that element.
6293
 
        You must call its start method to start listening to mouse movements.
6294
 
 
6295
 
Note:
6296
 
        The Scroller requires an XHTML doctype.
6297
 
 
6298
 
Arguments:
6299
 
        element - required, the element to scroll.
6300
 
        options - optional, see options below, and <Fx.Base> options.
6301
 
 
6302
 
Options:
6303
 
        area - integer, the necessary boundaries to make the element scroll.
6304
 
        velocity - integer, velocity ratio, the modifier for the window scrolling speed.
6305
 
 
6306
 
Events:
6307
 
        onChange - optionally, when the mouse reaches some boundaries, you can choose to alter some other values, instead of the scrolling offsets.
6308
 
                Automatically passes as parameters x and y values.
6309
 
*/
6310
 
 
6311
 
var Scroller = new Class({
6312
 
 
6313
 
        options: {
6314
 
                area: 20,
6315
 
                velocity: 1,
6316
 
                onChange: function(x, y){
6317
 
                        this.element.scrollTo(x, y);
6318
 
                }
6319
 
        },
6320
 
 
6321
 
        initialize: function(element, options){
6322
 
                this.setOptions(options);
6323
 
                this.element = $(element);
6324
 
                this.mousemover = ([window, document].contains(element)) ? $(document.body) : this.element;
6325
 
        },
6326
 
 
6327
 
        /*
6328
 
        Property: start
6329
 
                The scroller starts listening to mouse movements.
6330
 
        */
6331
 
 
6332
 
        start: function(){
6333
 
                this.coord = this.getCoords.bindWithEvent(this);
6334
 
                this.mousemover.addListener('mousemove', this.coord);
6335
 
        },
6336
 
 
6337
 
        /*
6338
 
        Property: stop
6339
 
                The scroller stops listening to mouse movements.
6340
 
        */
6341
 
 
6342
 
        stop: function(){
6343
 
                this.mousemover.removeListener('mousemove', this.coord);
6344
 
                this.timer = $clear(this.timer);
6345
 
        },
6346
 
 
6347
 
        getCoords: function(event){
6348
 
                this.page = (this.element == window) ? event.client : event.page;
6349
 
                if (!this.timer) this.timer = this.scroll.periodical(50, this);
6350
 
        },
6351
 
 
6352
 
        scroll: function(){
6353
 
                var el = this.element.getSize();
6354
 
                var pos = this.element.getPosition();
6355
 
 
6356
 
                var change = {'x': 0, 'y': 0};
6357
 
                for (var z in this.page){
6358
 
                        if (this.page[z] < (this.options.area + pos[z]) && el.scroll[z] != 0)
6359
 
                                change[z] = (this.page[z] - this.options.area - pos[z]) * this.options.velocity;
6360
 
                        else if (this.page[z] + this.options.area > (el.size[z] + pos[z]) && el.scroll[z] + el.size[z] != el.scrollSize[z])
6361
 
                                change[z] = (this.page[z] - el.size[z] + this.options.area - pos[z]) * this.options.velocity;
6362
 
                }
6363
 
                if (change.y || change.x) this.fireEvent('onChange', [el.scroll.x + change.x, el.scroll.y + change.y]);
6364
 
        }
6365
 
 
6366
 
});
6367
 
 
6368
 
Scroller.implement(new Events, new Options);
6369
 
 
6370
 
/*
6371
 
Script: Slider.js
6372
 
        Contains <Slider>
6373
 
 
6374
 
License:
6375
 
        MIT-style license.
6376
 
*/
6377
 
 
6378
 
/*
6379
 
Class: Slider
6380
 
        Creates a slider with two elements: a knob and a container. Returns the values.
6381
 
        
6382
 
Note:
6383
 
        The Slider requires an XHTML doctype.
6384
 
 
6385
 
Arguments:
6386
 
        element - the knob container
6387
 
        knob - the handle
6388
 
        options - see Options below
6389
 
 
6390
 
Options:
6391
 
        steps - the number of steps for your slider.
6392
 
        mode - either 'horizontal' or 'vertical'. defaults to horizontal.
6393
 
        offset - relative offset for knob position. default to 0.
6394
 
        
6395
 
Events:
6396
 
        onChange - a function to fire when the value changes.
6397
 
        onComplete - a function to fire when you're done dragging.
6398
 
        onTick - optionally, you can alter the onTick behavior, for example displaying an effect of the knob moving to the desired position.
6399
 
                Passes as parameter the new position.
6400
 
*/
6401
 
 
6402
 
var Slider = new Class({
6403
 
 
6404
 
        options: {
6405
 
                onChange: Class.empty,
6406
 
                onComplete: Class.empty,
6407
 
                onTick: function(pos){
6408
 
                        this.knob.setStyle(this.p, pos);
6409
 
                },
6410
 
                mode: 'horizontal',
6411
 
                steps: 100,
6412
 
                offset: 0
6413
 
        },
6414
 
 
6415
 
        initialize: function(el, knob, options){
6416
 
                this.element = $(el);
6417
 
                this.knob = $(knob);
6418
 
                this.setOptions(options);
6419
 
                this.previousChange = -1;
6420
 
                this.previousEnd = -1;
6421
 
                this.step = -1;
6422
 
                this.element.addEvent('mousedown', this.clickedElement.bindWithEvent(this));
6423
 
                var mod, offset;
6424
 
                switch(this.options.mode){
6425
 
                        case 'horizontal':
6426
 
                                this.z = 'x';
6427
 
                                this.p = 'left';
6428
 
                                mod = {'x': 'left', 'y': false};
6429
 
                                offset = 'offsetWidth';
6430
 
                                break;
6431
 
                        case 'vertical':
6432
 
                                this.z = 'y';
6433
 
                                this.p = 'top';
6434
 
                                mod = {'x': false, 'y': 'top'};
6435
 
                                offset = 'offsetHeight';
6436
 
                }
6437
 
                this.max = this.element[offset] - this.knob[offset] + (this.options.offset * 2);
6438
 
                this.half = this.knob[offset]/2;
6439
 
                this.getPos = this.element['get' + this.p.capitalize()].bind(this.element);
6440
 
                this.knob.setStyle('position', 'relative').setStyle(this.p, - this.options.offset);
6441
 
                var lim = {};
6442
 
                lim[this.z] = [- this.options.offset, this.max - this.options.offset];
6443
 
                this.drag = new Drag.Base(this.knob, {
6444
 
                        limit: lim,
6445
 
                        modifiers: mod,
6446
 
                        snap: 0,
6447
 
                        onStart: function(){
6448
 
                                this.draggedKnob();
6449
 
                        }.bind(this),
6450
 
                        onDrag: function(){
6451
 
                                this.draggedKnob();
6452
 
                        }.bind(this),
6453
 
                        onComplete: function(){
6454
 
                                this.draggedKnob();
6455
 
                                this.end();
6456
 
                        }.bind(this)
6457
 
                });
6458
 
                if (this.options.initialize) this.options.initialize.call(this);
6459
 
        },
6460
 
 
6461
 
        /*
6462
 
        Property: set
6463
 
                The slider will get the step you pass.
6464
 
 
6465
 
        Arguments:
6466
 
                step - one integer
6467
 
        */
6468
 
 
6469
 
        set: function(step){
6470
 
                this.step = step.limit(0, this.options.steps);
6471
 
                this.checkStep();
6472
 
                this.end();
6473
 
                this.fireEvent('onTick', this.toPosition(this.step));
6474
 
                return this;
6475
 
        },
6476
 
 
6477
 
        clickedElement: function(event){
6478
 
                var position = event.page[this.z] - this.getPos() - this.half;
6479
 
                position = position.limit(-this.options.offset, this.max -this.options.offset);
6480
 
                this.step = this.toStep(position);
6481
 
                this.checkStep();
6482
 
                this.end();
6483
 
                this.fireEvent('onTick', position);
6484
 
        },
6485
 
 
6486
 
        draggedKnob: function(){
6487
 
                this.step = this.toStep(this.drag.value.now[this.z]);
6488
 
                this.checkStep();
6489
 
        },
6490
 
 
6491
 
        checkStep: function(){
6492
 
                if (this.previousChange != this.step){
6493
 
                        this.previousChange = this.step;
6494
 
                        this.fireEvent('onChange', this.step);
6495
 
                }
6496
 
        },
6497
 
 
6498
 
        end: function(){
6499
 
                if (this.previousEnd !== this.step){
6500
 
                        this.previousEnd = this.step;
6501
 
                        this.fireEvent('onComplete', this.step + '');
6502
 
                }
6503
 
        },
6504
 
 
6505
 
        toStep: function(position){
6506
 
                return Math.round((position + this.options.offset) / this.max * this.options.steps);
6507
 
        },
6508
 
 
6509
 
        toPosition: function(step){
6510
 
                return this.max * step / this.options.steps;
6511
 
        }
6512
 
 
6513
 
});
6514
 
 
6515
 
Slider.implement(new Events);
6516
 
Slider.implement(new Options);
6517
 
 
6518
 
/*
6519
 
Script: SmoothScroll.js
6520
 
        Contains <SmoothScroll>
6521
 
 
6522
 
License:
6523
 
        MIT-style license.
6524
 
*/
6525
 
 
6526
 
/*
6527
 
Class: SmoothScroll
6528
 
        Auto targets all the anchors in a page and display a smooth scrolling effect upon clicking them.
6529
 
        Inherits methods, properties, options and events from <Fx.Scroll>.
6530
 
 
6531
 
Note:
6532
 
        SmoothScroll requires an XHTML doctype.
6533
 
 
6534
 
Arguments:
6535
 
        options - the Fx.Scroll options (see: <Fx.Scroll>) plus links, a collection of elements you want your smoothscroll on. Defaults to document.links.
6536
 
 
6537
 
Example:
6538
 
        >new SmoothScroll();
6539
 
*/
6540
 
 
6541
 
var SmoothScroll = Fx.Scroll.extend({
6542
 
 
6543
 
        initialize: function(options){
6544
 
                this.parent(window, options);
6545
 
                this.links = (this.options.links) ? $$(this.options.links) : $$(document.links);
6546
 
                var location = window.location.href.match(/^[^#]*/)[0] + '#';
6547
 
                this.links.each(function(link){
6548
 
                        if (link.href.indexOf(location) != 0) return;
6549
 
                        var anchor = link.href.substr(location.length);
6550
 
                        if (anchor && $(anchor)) this.useLink(link, anchor);
6551
 
                }, this);
6552
 
                if (!window.webkit419) this.addEvent('onComplete', function(){
6553
 
                        window.location.hash = this.anchor;
6554
 
                });
6555
 
        },
6556
 
 
6557
 
        useLink: function(link, anchor){
6558
 
                link.addEvent('click', function(event){
6559
 
                        this.anchor = anchor;
6560
 
                        this.toElement(anchor);
6561
 
                        event.stop();
6562
 
                }.bindWithEvent(this));
6563
 
        }
6564
 
 
6565
 
});
6566
 
 
6567
 
/*
6568
 
Script: Sortables.js
6569
 
        Contains <Sortables> Class.
6570
 
 
6571
 
License:
6572
 
        MIT-style license.
6573
 
*/
6574
 
 
6575
 
/*
6576
 
Class: Sortables
6577
 
        Creates an interface for <Drag.Base> and drop, resorting of a list.
6578
 
 
6579
 
Note:
6580
 
        The Sortables require an XHTML doctype.
6581
 
 
6582
 
Arguments:
6583
 
        list - required, the list that will become sortable.
6584
 
        options - an Object, see options below.
6585
 
 
6586
 
Options:
6587
 
        handles - a collection of elements to be used for drag handles. defaults to the elements.
6588
 
        
6589
 
Events:
6590
 
        onStart - function executed when the item starts dragging
6591
 
        onComplete - function executed when the item ends dragging
6592
 
*/
6593
 
 
6594
 
var Sortables = new Class({
6595
 
 
6596
 
        options: {
6597
 
                handles: false,
6598
 
                onStart: Class.empty,
6599
 
                onComplete: Class.empty,
6600
 
                ghost: true,
6601
 
                snap: 3,
6602
 
                onDragStart: function(element, ghost){
6603
 
                        ghost.setStyle('opacity', 0.7);
6604
 
                        element.setStyle('opacity', 0.7);
6605
 
                },
6606
 
                onDragComplete: function(element, ghost){
6607
 
                        element.setStyle('opacity', 1);
6608
 
                        ghost.remove();
6609
 
                        this.trash.remove();
6610
 
                }
6611
 
        },
6612
 
 
6613
 
        initialize: function(list, options){
6614
 
                this.setOptions(options);
6615
 
                this.list = $(list);
6616
 
                this.elements = this.list.getChildren();
6617
 
                this.handles = (this.options.handles) ? $$(this.options.handles) : this.elements;
6618
 
                this.bound = {
6619
 
                        'start': [],
6620
 
                        'moveGhost': this.moveGhost.bindWithEvent(this)
6621
 
                };
6622
 
                for (var i = 0, l = this.handles.length; i < l; i++){
6623
 
                        this.bound.start[i] = this.start.bindWithEvent(this, this.elements[i]);
6624
 
                }
6625
 
                this.attach();
6626
 
                if (this.options.initialize) this.options.initialize.call(this);
6627
 
                this.bound.move = this.move.bindWithEvent(this);
6628
 
                this.bound.end = this.end.bind(this);
6629
 
        },
6630
 
 
6631
 
        attach: function(){
6632
 
                this.handles.each(function(handle, i){
6633
 
                        handle.addEvent('mousedown', this.bound.start[i]);
6634
 
                }, this);
6635
 
        },
6636
 
 
6637
 
        detach: function(){
6638
 
                this.handles.each(function(handle, i){
6639
 
                        handle.removeEvent('mousedown', this.bound.start[i]);
6640
 
                }, this);
6641
 
        },
6642
 
 
6643
 
        start: function(event, el){
6644
 
                this.active = el;
6645
 
                this.coordinates = this.list.getCoordinates();
6646
 
                if (this.options.ghost){
6647
 
                        var position = el.getPosition();
6648
 
                        this.offset = event.page.y - position.y;
6649
 
                        this.trash = new Element('div').inject(document.body);
6650
 
                        this.ghost = el.clone().inject(this.trash).setStyles({
6651
 
                                'position': 'absolute',
6652
 
                                'left': position.x,
6653
 
                                'top': event.page.y - this.offset
6654
 
                        });
6655
 
                        document.addListener('mousemove', this.bound.moveGhost);
6656
 
                        this.fireEvent('onDragStart', [el, this.ghost]);
6657
 
                }
6658
 
                document.addListener('mousemove', this.bound.move);
6659
 
                document.addListener('mouseup', this.bound.end);
6660
 
                this.fireEvent('onStart', el);
6661
 
                event.stop();
6662
 
        },
6663
 
 
6664
 
        moveGhost: function(event){
6665
 
                var value = event.page.y - this.offset;
6666
 
                value = value.limit(this.coordinates.top, this.coordinates.bottom - this.ghost.offsetHeight);
6667
 
                this.ghost.setStyle('top', value);
6668
 
                event.stop();
6669
 
        },
6670
 
 
6671
 
        move: function(event){
6672
 
                var now = event.page.y;
6673
 
                this.previous = this.previous || now;
6674
 
                var up = ((this.previous - now) > 0);
6675
 
                var prev = this.active.getPrevious();
6676
 
                var next = this.active.getNext();
6677
 
                if (prev && up && now < prev.getCoordinates().bottom) this.active.injectBefore(prev);
6678
 
                if (next && !up && now > next.getCoordinates().top) this.active.injectAfter(next);
6679
 
                this.previous = now;
6680
 
        },
6681
 
 
6682
 
        serialize: function(converter){
6683
 
                return this.list.getChildren().map(converter || function(el){
6684
 
                        return this.elements.indexOf(el);
6685
 
                }, this);
6686
 
        },
6687
 
 
6688
 
        end: function(){
6689
 
                this.previous = null;
6690
 
                document.removeListener('mousemove', this.bound.move);
6691
 
                document.removeListener('mouseup', this.bound.end);
6692
 
                if (this.options.ghost){
6693
 
                        document.removeListener('mousemove', this.bound.moveGhost);
6694
 
                        this.fireEvent('onDragComplete', [this.active, this.ghost]);
6695
 
                }
6696
 
                this.fireEvent('onComplete', this.active);
6697
 
        }
6698
 
 
6699
 
});
6700
 
 
6701
 
Sortables.implement(new Events, new Options);
6702
 
 
6703
 
/*
6704
 
Script: Tips.js
6705
 
        Tooltips, BubbleTips, whatever they are, they will appear on mouseover
6706
 
 
6707
 
License:
6708
 
        MIT-style license.
6709
 
 
6710
 
Credits:
6711
 
        The idea behind Tips.js is based on Bubble Tooltips (<http://web-graphics.com/mtarchive/001717.php>) by Alessandro Fulcitiniti <http://web-graphics.com>
6712
 
*/
6713
 
 
6714
 
/*
6715
 
Class: Tips
6716
 
        Display a tip on any element with a title and/or href.
6717
 
 
6718
 
Note:
6719
 
        Tips requires an XHTML doctype.
6720
 
 
6721
 
Arguments:
6722
 
        elements - a collection of elements to apply the tooltips to on mouseover.
6723
 
        options - an object. See options Below.
6724
 
 
6725
 
Options:
6726
 
        maxTitleChars - the maximum number of characters to display in the title of the tip. defaults to 30.
6727
 
        showDelay - the delay the onShow method is called. (defaults to 100 ms)
6728
 
        hideDelay - the delay the onHide method is called. (defaults to 100 ms)
6729
 
 
6730
 
        className - the prefix for your tooltip classNames. defaults to 'tool'.
6731
 
 
6732
 
                the whole tooltip will have as classname: tool-tip
6733
 
 
6734
 
                the title will have as classname: tool-title
6735
 
 
6736
 
                the text will have as classname: tool-text
6737
 
 
6738
 
        offsets - the distance of your tooltip from the mouse. an Object with x/y properties.
6739
 
        fixed - if set to true, the toolTip will not follow the mouse.
6740
 
        
6741
 
Events:
6742
 
        onShow - optionally you can alter the default onShow behaviour with this option (like displaying a fade in effect);
6743
 
        onHide - optionally you can alter the default onHide behaviour with this option (like displaying a fade out effect);
6744
 
 
6745
 
Example:
6746
 
        (start code)
6747
 
        <img src="/images/i.png" title="The body of the tooltip is stored in the title" class="toolTipImg"/>
6748
 
        <script>
6749
 
                var myTips = new Tips($$('.toolTipImg'), {
6750
 
                        maxTitleChars: 50       //I like my captions a little long
6751
 
                });
6752
 
        </script>
6753
 
        (end)
6754
 
 
6755
 
Note:
6756
 
        The title of the element will always be used as the tooltip body. If you put :: on your title, the text before :: will become the tooltip title.
6757
 
*/
6758
 
 
6759
 
var Tips = new Class({
6760
 
 
6761
 
        options: {
6762
 
                onShow: function(tip){
6763
 
                        tip.setStyle('visibility', 'visible');
6764
 
                },
6765
 
                onHide: function(tip){
6766
 
                        tip.setStyle('visibility', 'hidden');
6767
 
                },
6768
 
                maxTitleChars: 30,
6769
 
                showDelay: 100,
6770
 
                hideDelay: 100,
6771
 
                className: 'tool',
6772
 
                offsets: {'x': 16, 'y': 16},
6773
 
                fixed: false
6774
 
        },
6775
 
 
6776
 
        initialize: function(elements, options){
6777
 
                this.setOptions(options);
6778
 
                this.toolTip = new Element('div', {
6779
 
                        'class': this.options.className + '-tip',
6780
 
                        'styles': {
6781
 
                                'position': 'absolute',
6782
 
                                'top': '0',
6783
 
                                'left': '0',
6784
 
                                'visibility': 'hidden'
6785
 
                        }
6786
 
                }).inject(document.body);
6787
 
                this.wrapper = new Element('div').inject(this.toolTip);
6788
 
                $$(elements).each(this.build, this);
6789
 
                if (this.options.initialize) this.options.initialize.call(this);
6790
 
        },
6791
 
 
6792
 
        build: function(el){
6793
 
                el.$tmp.myTitle = (el.href && el.getTag() == 'a') ? el.href.replace('http://', '') : (el.rel || false);
6794
 
                if (el.title){
6795
 
                        var dual = el.title.split('::');
6796
 
                        if (dual.length > 1){
6797
 
                                el.$tmp.myTitle = dual[0].trim();
6798
 
                                el.$tmp.myText = dual[1].trim();
6799
 
                        } else {
6800
 
                                el.$tmp.myText = el.title;
6801
 
                        }
6802
 
                        el.removeAttribute('title');
6803
 
                } else {
6804
 
                        el.$tmp.myText = false;
6805
 
                }
6806
 
                if (el.$tmp.myTitle && el.$tmp.myTitle.length > this.options.maxTitleChars) el.$tmp.myTitle = el.$tmp.myTitle.substr(0, this.options.maxTitleChars - 1) + "&hellip;";
6807
 
                el.addEvent('mouseenter', function(event){
6808
 
                        this.start(el);
6809
 
                        if (!this.options.fixed) this.locate(event);
6810
 
                        else this.position(el);
6811
 
                }.bind(this));
6812
 
                if (!this.options.fixed) el.addEvent('mousemove', this.locate.bindWithEvent(this));
6813
 
                var end = this.end.bind(this);
6814
 
                el.addEvent('mouseleave', end);
6815
 
                el.addEvent('trash', end);
6816
 
        },
6817
 
 
6818
 
        start: function(el){
6819
 
                this.wrapper.empty();
6820
 
                if (el.$tmp.myTitle){
6821
 
                        this.title = new Element('span').inject(new Element('div', {'class': this.options.className + '-title'}).inject(this.wrapper)).setHTML(el.$tmp.myTitle);
6822
 
                }
6823
 
                if (el.$tmp.myText){
6824
 
                        this.text = new Element('span').inject(new Element('div', {'class': this.options.className + '-text'}).inject(this.wrapper)).setHTML(el.$tmp.myText);
6825
 
                }
6826
 
                $clear(this.timer);
6827
 
                this.timer = this.show.delay(this.options.showDelay, this);
6828
 
        },
6829
 
 
6830
 
        end: function(event){
6831
 
                $clear(this.timer);
6832
 
                this.timer = this.hide.delay(this.options.hideDelay, this);
6833
 
        },
6834
 
 
6835
 
        position: function(element){
6836
 
                var pos = element.getPosition();
6837
 
                this.toolTip.setStyles({
6838
 
                        'left': pos.x + this.options.offsets.x,
6839
 
                        'top': pos.y + this.options.offsets.y
6840
 
                });
6841
 
        },
6842
 
 
6843
 
        locate: function(event){
6844
 
                var win = {'x': window.getWidth(), 'y': window.getHeight()};
6845
 
                var scroll = {'x': window.getScrollLeft(), 'y': window.getScrollTop()};
6846
 
                var tip = {'x': this.toolTip.offsetWidth, 'y': this.toolTip.offsetHeight};
6847
 
                var prop = {'x': 'left', 'y': 'top'};
6848
 
                for (var z in prop){
6849
 
                        var pos = event.page[z] + this.options.offsets[z];
6850
 
                        if ((pos + tip[z] - scroll[z]) > win[z]) pos = event.page[z] - this.options.offsets[z] - tip[z];
6851
 
                        this.toolTip.setStyle(prop[z], pos);
6852
 
                };
6853
 
        },
6854
 
 
6855
 
        show: function(){
6856
 
                if (this.options.timeout) this.timer = this.hide.delay(this.options.timeout, this);
6857
 
                this.fireEvent('onShow', [this.toolTip]);
6858
 
        },
6859
 
 
6860
 
        hide: function(){
6861
 
                this.fireEvent('onHide', [this.toolTip]);
6862
 
        }
6863
 
 
6864
 
});
6865
 
 
6866
 
Tips.implement(new Events, new Options);
6867
 
 
6868
 
/*
6869
 
Script: Group.js
6870
 
        For Grouping Classes or Elements Events. The Event added to the Group will fire when all of the events of the items of the group are fired.
6871
 
 
6872
 
License:
6873
 
        MIT-style license.
6874
 
*/
6875
 
 
6876
 
/*
6877
 
Class: Group
6878
 
        An "Utility" Class.
6879
 
 
6880
 
Arguments:
6881
 
        List of Class instances
6882
 
 
6883
 
Example:
6884
 
        (start code)
6885
 
        xhr1 = new Ajax('data.js', {evalScript: true});
6886
 
        xhr2 = new Ajax('abstraction.js', {evalScript: true});
6887
 
        xhr3 = new Ajax('template.js', {evalScript: true});
6888
 
 
6889
 
        var group = new Group(xhr1, xhr2, xhr3);
6890
 
        group.addEvent('onComplete', function(){
6891
 
                alert('All Scripts loaded');
6892
 
        });
6893
 
 
6894
 
        xhr1.request();
6895
 
        xhr2.request();
6896
 
        xhr3.request();
6897
 
        (end)
6898
 
 
6899
 
*/
6900
 
 
6901
 
var Group = new Class({
6902
 
 
6903
 
        initialize: function(){
6904
 
                this.instances = $A(arguments);
6905
 
                this.events = {};
6906
 
                this.checker = {};
6907
 
        },
6908
 
 
6909
 
        /*
6910
 
        Property: addEvent
6911
 
                adds an event to the stack of events of the Class instances.
6912
 
 
6913
 
        Arguments:
6914
 
                type - string; the event name (e.g. 'onComplete')
6915
 
                fn - function to execute when all instances fired this event
6916
 
        */
6917
 
 
6918
 
        addEvent: function(type, fn){
6919
 
                this.checker[type] = this.checker[type] || {};
6920
 
                this.events[type] = this.events[type] || [];
6921
 
                if (this.events[type].contains(fn)) return false;
6922
 
                else this.events[type].push(fn);
6923
 
                this.instances.each(function(instance, i){
6924
 
                        instance.addEvent(type, this.check.bind(this, [type, instance, i]));
6925
 
                }, this);
6926
 
                return this;
6927
 
        },
6928
 
 
6929
 
        check: function(type, instance, i){
6930
 
                this.checker[type][i] = true;
6931
 
                var every = this.instances.every(function(current, j){
6932
 
                        return this.checker[type][j] || false;
6933
 
                }, this);
6934
 
                if (!every) return;
6935
 
                this.checker[type] = {};
6936
 
                this.events[type].each(function(event){
6937
 
                        event.call(this, this.instances, instance);
6938
 
                }, this);
6939
 
        }
6940
 
 
6941
 
});
6942
 
 
6943
 
/*
6944
 
Script: Accordion.js
6945
 
        Contains <Accordion>
6946
 
 
6947
 
License:
6948
 
        MIT-style license.
6949
 
*/
6950
 
 
6951
 
/*
6952
 
Class: Accordion
6953
 
        The Accordion class creates a group of elements that are toggled when their handles are clicked. When one elements toggles in, the others toggles back.
6954
 
        Inherits methods, properties, options and events from <Fx.Elements>.
6955
 
        
6956
 
Note:
6957
 
        The Accordion requires an XHTML doctype.
6958
 
 
6959
 
Arguments:
6960
 
        togglers - required, a collection of elements, the elements handlers that will be clickable.
6961
 
        elements - required, a collection of elements the transitions will be applied to.
6962
 
        options - optional, see options below, and <Fx.Base> options and events.
6963
 
 
6964
 
Options:
6965
 
        show - integer, the Index of the element to show at start.
6966
 
        display - integer, the Index of the element to show at start (with a transition). defaults to 0.
6967
 
        fixedHeight - integer, if you want the elements to have a fixed height. defaults to false.
6968
 
        fixedWidth - integer, if you want the elements to have a fixed width. defaults to false.
6969
 
        height - boolean, will add a height transition to the accordion if true. defaults to true.
6970
 
        opacity - boolean, will add an opacity transition to the accordion if true. defaults to true.
6971
 
        width - boolean, will add a width transition to the accordion if true. defaults to false, css mastery is required to make this work!
6972
 
        alwaysHide - boolean, will allow to hide all elements if true, instead of always keeping one element shown. defaults to false.
6973
 
        
6974
 
Events:
6975
 
        onActive - function to execute when an element starts to show
6976
 
        onBackground - function to execute when an element starts to hide
6977
 
*/
6978
 
 
6979
 
var Accordion = Fx.Elements.extend({
6980
 
 
6981
 
        options: {
6982
 
                onActive: Class.empty,
6983
 
                onBackground: Class.empty,
6984
 
                display: 0,
6985
 
                show: false,
6986
 
                height: true,
6987
 
                width: false,
6988
 
                opacity: true,
6989
 
                fixedHeight: false,
6990
 
                fixedWidth: false,
6991
 
                wait: false,
6992
 
                alwaysHide: false
6993
 
        },
6994
 
 
6995
 
        initialize: function(){
6996
 
                var options, togglers, elements, container;
6997
 
                $each(arguments, function(argument, i){
6998
 
                        switch($type(argument)){
6999
 
                                case 'object': options = argument; break;
7000
 
                                case 'element': container = $(argument); break;
7001
 
                                default:
7002
 
                                        var temp = $$(argument);
7003
 
                                        if (!togglers) togglers = temp;
7004
 
                                        else elements = temp;
7005
 
                        }
7006
 
                });
7007
 
                this.togglers = togglers || [];
7008
 
                this.elements = elements || [];
7009
 
                this.container = $(container);
7010
 
                this.setOptions(options);
7011
 
                this.previous = -1;
7012
 
                if (this.options.alwaysHide) this.options.wait = true;
7013
 
                if ($chk(this.options.show)){
7014
 
                        this.options.display = false;
7015
 
                        this.previous = this.options.show;
7016
 
                }
7017
 
                if (this.options.start){
7018
 
                        this.options.display = false;
7019
 
                        this.options.show = false;
7020
 
                }
7021
 
                this.effects = {};
7022
 
                if (this.options.opacity) this.effects.opacity = 'fullOpacity';
7023
 
                if (this.options.width) this.effects.width = this.options.fixedWidth ? 'fullWidth' : 'offsetWidth';
7024
 
                if (this.options.height) this.effects.height = this.options.fixedHeight ? 'fullHeight' : 'scrollHeight';
7025
 
                for (var i = 0, l = this.togglers.length; i < l; i++) this.addSection(this.togglers[i], this.elements[i]);
7026
 
                this.elements.each(function(el, i){
7027
 
                        if (this.options.show === i){
7028
 
                                this.fireEvent('onActive', [this.togglers[i], el]);
7029
 
                        } else {
7030
 
                                for (var fx in this.effects) el.setStyle(fx, 0);
7031
 
                        }
7032
 
                }, this);
7033
 
                this.parent(this.elements);
7034
 
                if ($chk(this.options.display)) this.display(this.options.display);
7035
 
        },
7036
 
 
7037
 
        /*
7038
 
        Property: addSection
7039
 
                Dynamically adds a new section into the accordion at the specified position.
7040
 
 
7041
 
        Arguments:
7042
 
                toggler - (dom element) the element that toggles the accordion section open.
7043
 
                element - (dom element) the element that stretches open when the toggler is clicked.
7044
 
                pos - (integer) the index where these objects are to be inserted within the accordion.
7045
 
        */
7046
 
 
7047
 
        addSection: function(toggler, element, pos){
7048
 
                toggler = $(toggler);
7049
 
                element = $(element);
7050
 
                var test = this.togglers.contains(toggler);
7051
 
                var len = this.togglers.length;
7052
 
                this.togglers.include(toggler);
7053
 
                this.elements.include(element);
7054
 
                if (len && (!test || pos)){
7055
 
                        pos = $pick(pos, len - 1);
7056
 
                        toggler.injectBefore(this.togglers[pos]);
7057
 
                        element.injectAfter(toggler);
7058
 
                } else if (this.container && !test){
7059
 
                        toggler.inject(this.container);
7060
 
                        element.inject(this.container);
7061
 
                }
7062
 
                var idx = this.togglers.indexOf(toggler);
7063
 
                toggler.addEvent('click', this.display.bind(this, idx));
7064
 
                if (this.options.height) element.setStyles({'padding-top': 0, 'border-top': 'none', 'padding-bottom': 0, 'border-bottom': 'none'});
7065
 
                if (this.options.width) element.setStyles({'padding-left': 0, 'border-left': 'none', 'padding-right': 0, 'border-right': 'none'});
7066
 
                element.fullOpacity = 1;
7067
 
                if (this.options.fixedWidth) element.fullWidth = this.options.fixedWidth;
7068
 
                if (this.options.fixedHeight) element.fullHeight = this.options.fixedHeight;
7069
 
                element.setStyle('overflow', 'hidden');
7070
 
                if (!test){
7071
 
                        for (var fx in this.effects) element.setStyle(fx, 0);
7072
 
                }
7073
 
                return this;
7074
 
        },
7075
 
 
7076
 
        /*
7077
 
        Property: display
7078
 
                Shows a specific section and hides all others. Useful when triggering an accordion from outside.
7079
 
 
7080
 
        Arguments:
7081
 
                index - integer, the index of the item to show, or the actual element to show.
7082
 
        */
7083
 
 
7084
 
        display: function(index){
7085
 
                index = ($type(index) == 'element') ? this.elements.indexOf(index) : index;
7086
 
                if ((this.timer && this.options.wait) || (index === this.previous && !this.options.alwaysHide)) return this;
7087
 
                this.previous = index;
7088
 
                var obj = {};
7089
 
                this.elements.each(function(el, i){
7090
 
                        obj[i] = {};
7091
 
                        var hide = (i != index) || (this.options.alwaysHide && (el.offsetHeight > 0));
7092
 
                        this.fireEvent(hide ? 'onBackground' : 'onActive', [this.togglers[i], el]);
7093
 
                        for (var fx in this.effects) obj[i][fx] = hide ? 0 : el[this.effects[fx]];
7094
 
                }, this);
7095
 
                return this.start(obj);
7096
 
        },
7097
 
 
7098
 
        showThisHideOpen: function(index){return this.display(index);}
7099
 
 
7100
 
});
7101
 
 
7102
 
Fx.Accordion = Accordion;