~noskcaj/ubuntu/utopic/jquery/merge

« back to all changes in this revision

Viewing changes to src/sizzle/speed/frameworks/dojo.js

  • Committer: Bazaar Package Importer
  • Author(s): Marcelo Jorge Vieira (metal)
  • Date: 2011-05-29 20:21:27 UTC
  • mfrom: (0.1.8 upstream)
  • Revision ID: james.westby@ubuntu.com-20110529202127-yo710urpsj87oqnh
Tags: 1.6.1-1
New upstream release (Closes: #628052)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
        Copyright (c) 2004-2008, The Dojo Foundation All Rights Reserved.
3
 
        Available via Academic Free License >= 2.1 OR the modified BSD license.
4
 
        see: http://dojotoolkit.org/license for details
5
 
*/
6
 
 
7
 
/*
8
 
        This is a compiled version of Dojo, built for deployment and not for
9
 
        development. To get an editable version, please visit:
10
 
 
11
 
                http://dojotoolkit.org
12
 
 
13
 
        for documentation and information on getting the source.
14
 
*/
15
 
 
16
 
;(function(){
17
 
 
18
 
        /*
19
 
        dojo, dijit, and dojox must always be the first three, and in that order.
20
 
        djConfig.scopeMap = [
21
 
                ["dojo", "fojo"],
22
 
                ["dijit", "fijit"],
23
 
                ["dojox", "fojox"]
24
 
        
25
 
        ]
26
 
        */
27
 
 
28
 
        /**Build will replace this comment with a scoped djConfig **/
29
 
 
30
 
        //The null below can be relaced by a build-time value used instead of djConfig.scopeMap.
31
 
        var sMap = null;
32
 
 
33
 
        //See if new scopes need to be defined.
34
 
        if((sMap || (typeof djConfig != "undefined" && djConfig.scopeMap)) && (typeof window != "undefined")){
35
 
                var scopeDef = "", scopePrefix = "", scopeSuffix = "", scopeMap = {}, scopeMapRev = {};
36
 
                sMap = sMap || djConfig.scopeMap;
37
 
                for(var i = 0; i < sMap.length; i++){
38
 
                        //Make local variables, then global variables that use the locals.
39
 
                        var newScope = sMap[i];
40
 
                        scopeDef += "var " + newScope[0] + " = {}; " + newScope[1] + " = " + newScope[0] + ";" + newScope[1] + "._scopeName = '" + newScope[1] + "';";
41
 
                        scopePrefix += (i == 0 ? "" : ",") + newScope[0];
42
 
                        scopeSuffix += (i == 0 ? "" : ",") + newScope[1];
43
 
                        scopeMap[newScope[0]] = newScope[1];
44
 
                        scopeMapRev[newScope[1]] = newScope[0];
45
 
                }
46
 
 
47
 
                eval(scopeDef + "dojo._scopeArgs = [" + scopeSuffix + "];");
48
 
 
49
 
                dojo._scopePrefixArgs = scopePrefix;
50
 
                dojo._scopePrefix = "(function(" + scopePrefix + "){";
51
 
                dojo._scopeSuffix = "})(" + scopeSuffix + ")";
52
 
                dojo._scopeMap = scopeMap;
53
 
                dojo._scopeMapRev = scopeMapRev;
54
 
        }
55
 
 
56
 
/*=====
57
 
// note:
58
 
//              'djConfig' does not exist under 'dojo.*' so that it can be set before the
59
 
//              'dojo' variable exists.
60
 
// note:
61
 
//              Setting any of these variables *after* the library has loaded does
62
 
//              nothing at all.
63
 
 
64
 
djConfig = {
65
 
        // summary:
66
 
        //              Application code can set the global 'djConfig' prior to loading
67
 
        //              the library to override certain global settings for how dojo works.
68
 
        //
69
 
        // isDebug: Boolean
70
 
        //              Defaults to `false`. If set to `true`, ensures that Dojo provides
71
 
        //              extended debugging feedback via Firebug. If Firebug is not available
72
 
        //              on your platform, setting `isDebug` to `true` will force Dojo to
73
 
        //              pull in (and display) the version of Firebug Lite which is
74
 
        //              integrated into the Dojo distribution, thereby always providing a
75
 
        //              debugging/logging console when `isDebug` is enabled. Note that
76
 
        //              Firebug's `console.*` methods are ALWAYS defined by Dojo. If
77
 
        //              `isDebug` is false and you are on a platform without Firebug, these
78
 
        //              methods will be defined as no-ops.
79
 
        isDebug: false,
80
 
        // debugAtAllCosts: Boolean
81
 
        //              Defaults to `false`. If set to `true`, this triggers an alternate
82
 
        //              mode of the package system in which dependencies are detected and
83
 
        //              only then are resources evaluated in dependency order via
84
 
        //              `<script>` tag inclusion. This may double-request resources and
85
 
        //              cause problems with scripts which expect `dojo.require()` to
86
 
        //              preform synchronously. `debugAtAllCosts` can be an invaluable
87
 
        //              debugging aid, but when using it, ensure that all code which
88
 
        //              depends on Dojo modules is wrapped in `dojo.addOnLoad()` handlers.
89
 
        //              Due to the somewhat unpredictable side-effects of using
90
 
        //              `debugAtAllCosts`, it is strongly recommended that you enable this
91
 
        //              flag as a last resort. `debugAtAllCosts` has no effect when loading
92
 
        //              resources across domains. For usage information, see the
93
 
        //              [Dojo Book](http://dojotoolkit.org/book/book-dojo/part-4-meta-dojo-making-your-dojo-code-run-faster-and-better/debugging-facilities/deb)
94
 
        debugAtAllCosts: false,
95
 
        // locale: String
96
 
        //              The locale to assume for loading localized resources in this page,
97
 
        //              specified according to [RFC 3066](http://www.ietf.org/rfc/rfc3066.txt).
98
 
        //              Must be specified entirely in lowercase, e.g. `en-us` and `zh-cn`.
99
 
        //              See the documentation for `dojo.i18n` and `dojo.requireLocalization`
100
 
        //              for details on loading localized resources. If no locale is specified,
101
 
        //              Dojo assumes the locale of the user agent, according to `navigator.userLanguage`
102
 
        //              or `navigator.language` properties.
103
 
        locale: undefined,
104
 
        // extraLocale: Array
105
 
        //              No default value. Specifies additional locales whose
106
 
        //              resources should also be loaded alongside the default locale when
107
 
        //              calls to `dojo.requireLocalization()` are processed.
108
 
        extraLocale: undefined,
109
 
        // baseUrl: String
110
 
        //              The directory in which `dojo.js` is located. Under normal
111
 
        //              conditions, Dojo auto-detects the correct location from which it
112
 
        //              was loaded. You may need to manually configure `baseUrl` in cases
113
 
        //              where you have renamed `dojo.js` or in which `<base>` tags confuse
114
 
        //              some browsers (e.g. IE 6). The variable `dojo.baseUrl` is assigned
115
 
        //              either the value of `djConfig.baseUrl` if one is provided or the
116
 
        //              auto-detected root if not. Other modules are located relative to
117
 
        //              this path.
118
 
        baseUrl: undefined,
119
 
        // modulePaths: Object
120
 
        //              A map of module names to paths relative to `dojo.baseUrl`. The
121
 
        //              key/value pairs correspond directly to the arguments which
122
 
        //              `dojo.registerModulePath` accepts. Specifiying
123
 
        //              `djConfig.modulePaths = { "foo": "../../bar" }` is the equivalent
124
 
        //              of calling `dojo.registerModulePath("foo", "../../bar");`. Multiple
125
 
        //              modules may be configured via `djConfig.modulePaths`.
126
 
        modulePaths: {},
127
 
        // afterOnLoad: Boolean 
128
 
        //              Indicates Dojo was added to the page after the page load. In this case
129
 
        //              Dojo will not wait for the page DOMContentLoad/load events and fire
130
 
        //              its dojo.addOnLoad callbacks after making sure all outstanding
131
 
        //              dojo.required modules have loaded.
132
 
        afterOnLoad: false,
133
 
        // addOnLoad: Function or Array
134
 
        //              Adds a callback via dojo.addOnLoad. Useful when Dojo is added after
135
 
        //              the page loads and djConfig.afterOnLoad is true. Supports the same
136
 
        //              arguments as dojo.addOnLoad. When using a function reference, use
137
 
        //              `djConfig.addOnLoad = function(){};`. For object with function name use
138
 
        //              `djConfig.addOnLoad = [myObject, "functionName"];` and for object with
139
 
        //              function reference use
140
 
        //              `djConfig.addOnLoad = [myObject, function(){}];`
141
 
        addOnLoad: null,
142
 
        // require: Array
143
 
        //              An array of module names to be loaded immediately after dojo.js has been included
144
 
        //              in a page. 
145
 
        require: []
146
 
}
147
 
=====*/
148
 
 
149
 
(function(){
150
 
        // firebug stubs
151
 
 
152
 
        // if((!this["console"])||(!console["firebug"])){
153
 
 
154
 
        if(!this["console"]){
155
 
                this.console = {
156
 
                };
157
 
        }
158
 
 
159
 
        //      Be careful to leave 'log' always at the end
160
 
        var cn = [
161
 
                "assert", "count", "debug", "dir", "dirxml", "error", "group",
162
 
                "groupEnd", "info", "profile", "profileEnd", "time", "timeEnd",
163
 
                "trace", "warn", "log" 
164
 
        ];
165
 
        var i=0, tn;
166
 
        while((tn=cn[i++])){
167
 
                if(!console[tn]){
168
 
                        (function(){
169
 
                                var tcn = tn+"";
170
 
                                console[tcn] = ('log' in console) ? function(){ 
171
 
                                        var a = Array.apply({}, arguments);
172
 
                                        a.unshift(tcn+":");
173
 
                                        console["log"](a.join(" "));
174
 
                                } : function(){}
175
 
                        })();
176
 
                }
177
 
        }
178
 
 
179
 
        //TODOC:  HOW TO DOC THIS?
180
 
        // dojo is the root variable of (almost all) our public symbols -- make sure it is defined.
181
 
        if(typeof dojo == "undefined"){
182
 
                this.dojo = {
183
 
                        _scopeName: "dojo",
184
 
                        _scopePrefix: "",
185
 
                        _scopePrefixArgs: "",
186
 
                        _scopeSuffix: "",
187
 
                        _scopeMap: {},
188
 
                        _scopeMapRev: {}
189
 
                };
190
 
        }
191
 
 
192
 
        var d = dojo;
193
 
 
194
 
        //Need placeholders for dijit and dojox for scoping code.
195
 
        if(typeof dijit == "undefined"){
196
 
                this.dijit = {_scopeName: "dijit"};
197
 
        }
198
 
        if(typeof dojox == "undefined"){
199
 
                this.dojox = {_scopeName: "dojox"};
200
 
        }
201
 
        
202
 
        if(!d._scopeArgs){
203
 
                d._scopeArgs = [dojo, dijit, dojox];
204
 
        }
205
 
 
206
 
/*=====
207
 
dojo.global = {
208
 
        //      summary:
209
 
        //              Alias for the global scope
210
 
        //              (e.g. the window object in a browser).
211
 
        //      description:
212
 
        //              Refer to 'dojo.global' rather than referring to window to ensure your
213
 
        //              code runs correctly in contexts other than web browsers (e.g. Rhino on a server).
214
 
}
215
 
=====*/
216
 
        d.global = this;
217
 
 
218
 
        d.config =/*===== djConfig = =====*/{
219
 
                isDebug: false,
220
 
                debugAtAllCosts: false
221
 
        };
222
 
 
223
 
        if(typeof djConfig != "undefined"){
224
 
                for(var opt in djConfig){
225
 
                        d.config[opt] = djConfig[opt];
226
 
                }
227
 
        }
228
 
 
229
 
        var _platforms = ["Browser", "Rhino", "Spidermonkey", "Mobile"];
230
 
        var t;
231
 
        while((t=_platforms.shift())){
232
 
                d["is"+t] = false;
233
 
        }
234
 
 
235
 
/*=====
236
 
        // Override locale setting, if specified
237
 
        dojo.locale = {
238
 
                // summary: the locale as defined by Dojo (read-only)
239
 
        };
240
 
=====*/
241
 
        dojo.locale = d.config.locale;
242
 
        
243
 
        var rev = "$Rev: 15385 $".match(/\d+/);
244
 
 
245
 
        dojo.version = {
246
 
                // summary: 
247
 
                //              version number of dojo
248
 
                //      major: Integer
249
 
                //              Major version. If total version is "1.2.0beta1", will be 1
250
 
                //      minor: Integer
251
 
                //              Minor version. If total version is "1.2.0beta1", will be 2
252
 
                //      patch: Integer
253
 
                //              Patch version. If total version is "1.2.0beta1", will be 0
254
 
                //      flag: String
255
 
                //              Descriptor flag. If total version is "1.2.0beta1", will be "beta1"
256
 
                //      revision: Number
257
 
                //              The SVN rev from which dojo was pulled
258
 
                major: 1, minor: 2, patch: 0, flag: "",
259
 
                revision: rev ? +rev[0] : 999999, //FIXME: use NaN?
260
 
                toString: function(){
261
 
                        with(d.version){
262
 
                                return major + "." + minor + "." + patch + flag + " (" + revision + ")";        // String
263
 
                        }
264
 
                }
265
 
        }
266
 
 
267
 
        // Register with the OpenAjax hub
268
 
        if(typeof OpenAjax != "undefined"){
269
 
                OpenAjax.hub.registerLibrary(dojo._scopeName, "http://dojotoolkit.org", d.version.toString());
270
 
        }
271
 
 
272
 
        dojo._mixin = function(/*Object*/ obj, /*Object*/ props){
273
 
                // summary:
274
 
                //              Adds all properties and methods of props to obj. This addition
275
 
                //              is "prototype extension safe", so that instances of objects
276
 
                //              will not pass along prototype defaults.
277
 
                var tobj = {};
278
 
                for(var x in props){
279
 
                        // the "tobj" condition avoid copying properties in "props"
280
 
                        // inherited from Object.prototype.  For example, if obj has a custom
281
 
                        // toString() method, don't overwrite it with the toString() method
282
 
                        // that props inherited from Object.prototype
283
 
                        if(tobj[x] === undefined || tobj[x] != props[x]){
284
 
                                obj[x] = props[x];
285
 
                        }
286
 
                }
287
 
                // IE doesn't recognize custom toStrings in for..in
288
 
                if(d["isIE"] && props){
289
 
                        var p = props.toString;
290
 
                        if(typeof p == "function" && p != obj.toString && p != tobj.toString &&
291
 
                                p != "\nfunction toString() {\n    [native code]\n}\n"){
292
 
                                        obj.toString = props.toString;
293
 
                        }
294
 
                }
295
 
                return obj; // Object
296
 
        }
297
 
 
298
 
        dojo.mixin = function(/*Object*/obj, /*Object...*/props){
299
 
                // summary:     
300
 
                //              Adds all properties and methods of props to obj and returns the
301
 
                //              (now modified) obj.
302
 
                //      description:
303
 
                //              `dojo.mixin` can mix multiple source objects into a
304
 
                //              destionation object which is then returned. Unlike regular
305
 
                //              `for...in` iteration, `dojo.mixin` is also smart about avoiding
306
 
                //              extensions which other toolkits may unwisely add to the root
307
 
                //              object prototype
308
 
                //      obj:
309
 
                //              The object to mix properties into. Also the return value.
310
 
                //      props:
311
 
                //              One or more objects whose values are successively copied into
312
 
                //              obj. If more than one of these objects contain the same value,
313
 
                //              the one specified last in the function call will "win".
314
 
                //      example:
315
 
                //              make a shallow copy of an object
316
 
                //      |       var copy = dojo.mixin({}, source);
317
 
                //      example:
318
 
                //              many class constructors often take an object which specifies
319
 
                //              values to be configured on the object. In this case, it is
320
 
                //              often simplest to call `dojo.mixin` on the `this` object:
321
 
                //      |       dojo.declare("acme.Base", null, {
322
 
                //      |               constructor: function(properties){
323
 
                //      |                       // property configuration:
324
 
                //      |                       dojo.mixin(this, properties);
325
 
                //      |       
326
 
                //      |                       
327
 
                //      |                       //  ...
328
 
                //      |               },
329
 
                //      |               quip: "I wasn't born yesterday, you know - I've seen movies.",
330
 
                //      |               // ...
331
 
                //      |       });
332
 
                //      |
333
 
                //      |       // create an instance of the class and configure it
334
 
                //      |       var b = new acme.Base({quip: "That's what it does!" });
335
 
                //      example:
336
 
                //              copy in properties from multiple objects
337
 
                //      |       var flattened = dojo.mixin(
338
 
                //      |               {
339
 
                //      |                       name: "Frylock",
340
 
                //      |                       braces: true
341
 
                //      |               },
342
 
                //      |               {
343
 
                //      |                       name: "Carl Brutanananadilewski"
344
 
                //      |               }
345
 
                //      |       );
346
 
                //      |       
347
 
                //      |       // will print "Carl Brutanananadilewski"
348
 
                //      |       
349
 
                //      |       // will print "true"
350
 
                //      |       
351
 
                for(var i=1, l=arguments.length; i<l; i++){
352
 
                        d._mixin(obj, arguments[i]);
353
 
                }
354
 
                return obj; // Object
355
 
        }
356
 
 
357
 
        dojo._getProp = function(/*Array*/parts, /*Boolean*/create, /*Object*/context){
358
 
                var obj=context || d.global;
359
 
                for(var i=0, p; obj && (p=parts[i]); i++){
360
 
                        if(i == 0 && this._scopeMap[p]){
361
 
                                p = this._scopeMap[p];
362
 
                        }
363
 
                        obj = (p in obj ? obj[p] : (create ? obj[p]={} : undefined));
364
 
                }
365
 
                return obj; // mixed
366
 
        }
367
 
 
368
 
        dojo.setObject = function(/*String*/name, /*Object*/value, /*Object?*/context){
369
 
                // summary: 
370
 
                //              Set a property from a dot-separated string, such as "A.B.C"
371
 
                //      description: 
372
 
                //              Useful for longer api chains where you have to test each object in
373
 
                //              the chain, or when you have an object reference in string format.
374
 
                //              Objects are created as needed along `path`. Returns the passed
375
 
                //              value if setting is successful or `undefined` if not.
376
 
                //      name:   
377
 
                //              Path to a property, in the form "A.B.C".
378
 
                //      context:
379
 
                //              Optional. Object to use as root of path. Defaults to
380
 
                //              `dojo.global`.
381
 
                //      example:
382
 
                //              set the value of `foo.bar.baz`, regardless of whether
383
 
                //              intermediate objects already exist:
384
 
                //      |       dojo.setObject("foo.bar.baz", value);
385
 
                //      example:
386
 
                //              without `dojo.setObject`, we often see code like this:
387
 
                //      |       // ensure that intermediate objects are available
388
 
                //      |       if(!obj["parent"]){ obj.parent = {}; }
389
 
                //      |       if(!obj.parent["child"]){ obj.parent.child= {}; }
390
 
                //      |       // now we can safely set the property
391
 
                //      |       obj.parent.child.prop = "some value";
392
 
                //              wheras with `dojo.setObject`, we can shorten that to:
393
 
                //      |       dojo.setObject("parent.child.prop", "some value", obj);
394
 
                var parts=name.split("."), p=parts.pop(), obj=d._getProp(parts, true, context);
395
 
                return obj && p ? (obj[p]=value) : undefined; // Object
396
 
        }
397
 
 
398
 
        dojo.getObject = function(/*String*/name, /*Boolean*/create, /*Object*/context){
399
 
                // summary: 
400
 
                //              Get a property from a dot-separated string, such as "A.B.C"
401
 
                //      description: 
402
 
                //              Useful for longer api chains where you have to test each object in
403
 
                //              the chain, or when you have an object reference in string format.
404
 
                //      name:   
405
 
                //              Path to an property, in the form "A.B.C".
406
 
                //      context:
407
 
                //              Optional. Object to use as root of path. Defaults to
408
 
                //              'dojo.global'. Null may be passed.
409
 
                //      create: 
410
 
                //              Optional. Defaults to `false`. If `true`, Objects will be
411
 
                //              created at any point along the 'path' that is undefined.
412
 
                return d._getProp(name.split("."), create, context); // Object
413
 
        }
414
 
 
415
 
        dojo.exists = function(/*String*/name, /*Object?*/obj){
416
 
                //      summary: 
417
 
                //              determine if an object supports a given method
418
 
                //      description: 
419
 
                //              useful for longer api chains where you have to test each object in
420
 
                //              the chain
421
 
                //      name:   
422
 
                //              Path to an object, in the form "A.B.C".
423
 
                //      obj:
424
 
                //              Object to use as root of path. Defaults to
425
 
                //              'dojo.global'. Null may be passed.
426
 
                //      example:
427
 
                //      |       // define an object
428
 
                //      |       var foo = {
429
 
                //      |               bar: { }
430
 
                //      |       };
431
 
                //      |
432
 
                //      |       // search the global scope
433
 
                //      |       dojo.exists("foo.bar"); // true
434
 
                //      |       dojo.exists("foo.bar.baz"); // false
435
 
                //      |
436
 
                //      |       // search from a particular scope
437
 
                //      |       dojo.exists("bar", foo); // true
438
 
                //      |       dojo.exists("bar.baz", foo); // false
439
 
                return !!d.getObject(name, false, obj); // Boolean
440
 
        }
441
 
 
442
 
 
443
 
        dojo["eval"] = function(/*String*/ scriptFragment){
444
 
                //      summary: 
445
 
                //              Perform an evaluation in the global scope. Use this rather than
446
 
                //              calling 'eval()' directly.
447
 
                //      description: 
448
 
                //              Placed in a separate function to minimize size of trapped
449
 
                //              exceptions. Calling eval() directly from some other scope may
450
 
                //              complicate tracebacks on some platforms.
451
 
                //      returns:
452
 
                //              The result of the evaluation. Often `undefined`
453
 
 
454
 
 
455
 
                // note:
456
 
                //       - JSC eval() takes an optional second argument which can be 'unsafe'.
457
 
                //       - Mozilla/SpiderMonkey eval() takes an optional second argument which is the
458
 
                //       scope object for new symbols.
459
 
 
460
 
                // FIXME: investigate Joseph Smarr's technique for IE:
461
 
                //              http://josephsmarr.com/2007/01/31/fixing-eval-to-use-global-scope-in-ie/
462
 
                //      see also:
463
 
                //              http://trac.dojotoolkit.org/ticket/744
464
 
                return d.global.eval ? d.global.eval(scriptFragment) : eval(scriptFragment);    // Object
465
 
        }
466
 
 
467
 
        /*=====
468
 
                dojo.deprecated = function(behaviour, extra, removal){
469
 
                        //      summary: 
470
 
                        //              Log a debug message to indicate that a behavior has been
471
 
                        //              deprecated.
472
 
                        //      behaviour: String
473
 
                        //              The API or behavior being deprecated. Usually in the form
474
 
                        //              of "myApp.someFunction()".
475
 
                        //      extra: String?
476
 
                        //              Text to append to the message. Often provides advice on a
477
 
                        //              new function or facility to achieve the same goal during
478
 
                        //              the deprecation period.
479
 
                        //      removal: String?
480
 
                        //              Text to indicate when in the future the behavior will be
481
 
                        //              removed. Usually a version number.
482
 
                        //      example:
483
 
                        //      |       dojo.deprecated("myApp.getTemp()", "use myApp.getLocaleTemp() instead", "1.0");
484
 
                }
485
 
 
486
 
                dojo.experimental = function(moduleName, extra){
487
 
                        //      summary: Marks code as experimental.
488
 
                        //      description: 
489
 
                        //              This can be used to mark a function, file, or module as
490
 
                        //              experimental.  Experimental code is not ready to be used, and the
491
 
                        //              APIs are subject to change without notice.  Experimental code may be
492
 
                        //              completed deleted without going through the normal deprecation
493
 
                        //              process.
494
 
                        //      moduleName: String
495
 
                        //              The name of a module, or the name of a module file or a specific
496
 
                        //              function
497
 
                        //      extra: String?
498
 
                        //              some additional message for the user
499
 
                        //      example:
500
 
                        //      |       dojo.experimental("dojo.data.Result");
501
 
                        //      example:
502
 
                        //      |       dojo.experimental("dojo.weather.toKelvin()", "PENDING approval from NOAA");
503
 
                }
504
 
        =====*/
505
 
 
506
 
        //Real functions declared in dojo._firebug.firebug.
507
 
        d.deprecated = d.experimental = function(){};
508
 
 
509
 
})();
510
 
// vim:ai:ts=4:noet
511
 
 
512
 
/*
513
 
 * loader.js - A bootstrap module.  Runs before the hostenv_*.js file. Contains
514
 
 * all of the package loading methods.
515
 
 */
516
 
 
517
 
(function(){
518
 
        var d = dojo;
519
 
 
520
 
        d.mixin(d, {
521
 
                _loadedModules: {},
522
 
                _inFlightCount: 0,
523
 
                _hasResource: {},
524
 
 
525
 
                _modulePrefixes: {
526
 
                        dojo:   {       name: "dojo", value: "." },
527
 
                        // dojox:       {       name: "dojox", value: "../dojox" },
528
 
                        // dijit:       {       name: "dijit", value: "../dijit" },
529
 
                        doh:    {       name: "doh", value: "../util/doh" },
530
 
                        tests:  {       name: "tests", value: "tests" }
531
 
                },
532
 
 
533
 
                _moduleHasPrefix: function(/*String*/module){
534
 
                        // summary: checks to see if module has been established
535
 
                        var mp = this._modulePrefixes;
536
 
                        return !!(mp[module] && mp[module].value); // Boolean
537
 
                },
538
 
 
539
 
                _getModulePrefix: function(/*String*/module){
540
 
                        // summary: gets the prefix associated with module
541
 
                        var mp = this._modulePrefixes;
542
 
                        if(this._moduleHasPrefix(module)){
543
 
                                return mp[module].value; // String
544
 
                        }
545
 
                        return module; // String
546
 
                },
547
 
 
548
 
                _loadedUrls: [],
549
 
 
550
 
                //WARNING: 
551
 
                //              This variable is referenced by packages outside of bootstrap:
552
 
                //              FloatingPane.js and undo/browser.js
553
 
                _postLoad: false,
554
 
                
555
 
                //Egad! Lots of test files push on this directly instead of using dojo.addOnLoad.
556
 
                _loaders: [],
557
 
                _unloaders: [],
558
 
                _loadNotifying: false
559
 
        });
560
 
 
561
 
 
562
 
                dojo._loadPath = function(/*String*/relpath, /*String?*/module, /*Function?*/cb){
563
 
                //      summary:
564
 
                //              Load a Javascript module given a relative path
565
 
                //
566
 
                //      description:
567
 
                //              Loads and interprets the script located at relpath, which is
568
 
                //              relative to the script root directory.  If the script is found but
569
 
                //              its interpretation causes a runtime exception, that exception is
570
 
                //              not caught by us, so the caller will see it.  We return a true
571
 
                //              value if and only if the script is found.
572
 
                //
573
 
                // relpath: 
574
 
                //              A relative path to a script (no leading '/', and typically ending
575
 
                //              in '.js').
576
 
                // module: 
577
 
                //              A module whose existance to check for after loading a path.  Can be
578
 
                //              used to determine success or failure of the load.
579
 
                // cb: 
580
 
                //              a callback function to pass the result of evaluating the script
581
 
 
582
 
                var uri = ((relpath.charAt(0) == '/' || relpath.match(/^\w+:/)) ? "" : this.baseUrl) + relpath;
583
 
                try{
584
 
                        return !module ? this._loadUri(uri, cb) : this._loadUriAndCheck(uri, module, cb); // Boolean
585
 
                }catch(e){
586
 
                        console.error(e);
587
 
                        return false; // Boolean
588
 
                }
589
 
        }
590
 
 
591
 
        dojo._loadUri = function(/*String*/uri, /*Function?*/cb){
592
 
                //      summary:
593
 
                //              Loads JavaScript from a URI
594
 
                //      description:
595
 
                //              Reads the contents of the URI, and evaluates the contents.  This is
596
 
                //              used to load modules as well as resource bundles. Returns true if
597
 
                //              it succeeded. Returns false if the URI reading failed.  Throws if
598
 
                //              the evaluation throws.
599
 
                //      uri: a uri which points at the script to be loaded
600
 
                //      cb: 
601
 
                //              a callback function to process the result of evaluating the script
602
 
                //              as an expression, typically used by the resource bundle loader to
603
 
                //              load JSON-style resources
604
 
 
605
 
                if(this._loadedUrls[uri]){
606
 
                        return true; // Boolean
607
 
                }
608
 
                var contents = this._getText(uri, true);
609
 
                if(!contents){ return false; } // Boolean
610
 
                this._loadedUrls[uri] = true;
611
 
                this._loadedUrls.push(uri);
612
 
                if(cb){
613
 
                        contents = '('+contents+')';
614
 
                }else{
615
 
                        //Only do the scoping if no callback. If a callback is specified,
616
 
                        //it is most likely the i18n bundle stuff.
617
 
                        contents = this._scopePrefix + contents + this._scopeSuffix;
618
 
                }
619
 
                if(d.isMoz){ contents += "\r\n//@ sourceURL=" + uri; } // debugging assist for Firebug
620
 
                var value = d["eval"](contents);
621
 
                if(cb){ cb(value); }
622
 
                return true; // Boolean
623
 
        }
624
 
        
625
 
        // FIXME: probably need to add logging to this method
626
 
        dojo._loadUriAndCheck = function(/*String*/uri, /*String*/moduleName, /*Function?*/cb){
627
 
                // summary: calls loadUri then findModule and returns true if both succeed
628
 
                var ok = false;
629
 
                try{
630
 
                        ok = this._loadUri(uri, cb);
631
 
                }catch(e){
632
 
                        console.error("failed loading " + uri + " with error: " + e);
633
 
                }
634
 
                return !!(ok && this._loadedModules[moduleName]); // Boolean
635
 
        }
636
 
 
637
 
        dojo.loaded = function(){
638
 
                // summary:
639
 
                //              signal fired when initial environment and package loading is
640
 
                //              complete. You may use dojo.addOnLoad() or dojo.connect() to
641
 
                //              this method in order to handle initialization tasks that
642
 
                //              require the environment to be initialized. In a browser host,
643
 
                //              declarative widgets will be constructed when this function
644
 
                //              finishes runing.
645
 
                this._loadNotifying = true;
646
 
                this._postLoad = true;
647
 
                var mll = d._loaders;
648
 
 
649
 
                //Clear listeners so new ones can be added
650
 
                //For other xdomain package loads after the initial load.
651
 
                this._loaders = [];
652
 
 
653
 
                for(var x = 0; x < mll.length; x++){
654
 
                        mll[x]();
655
 
                }
656
 
 
657
 
                this._loadNotifying = false;
658
 
                
659
 
                //Make sure nothing else got added to the onload queue
660
 
                //after this first run. If something did, and we are not waiting for any
661
 
                //more inflight resources, run again.
662
 
                if(d._postLoad && d._inFlightCount == 0 && mll.length){
663
 
                        d._callLoaded();
664
 
                }
665
 
        }
666
 
 
667
 
        dojo.unloaded = function(){
668
 
                // summary:
669
 
                //              signal fired by impending environment destruction. You may use
670
 
                //              dojo.addOnUnload() or dojo.connect() to this method to perform
671
 
                //              page/application cleanup methods. See dojo.addOnUnload for more info.
672
 
                var mll = this._unloaders;
673
 
                while(mll.length){
674
 
                        (mll.pop())();
675
 
                }
676
 
        }
677
 
 
678
 
        d._onto = function(arr, obj, fn){
679
 
                if(!fn){
680
 
                        arr.push(obj);
681
 
                }else if(fn){
682
 
                        var func = (typeof fn == "string") ? obj[fn] : fn;
683
 
                        arr.push(function(){ func.call(obj); });
684
 
                }
685
 
        }
686
 
 
687
 
        dojo.addOnLoad = function(/*Object?*/obj, /*String|Function*/functionName){
688
 
                // summary:
689
 
                //              Registers a function to be triggered after the DOM has finished
690
 
                //              loading and widgets declared in markup have been instantiated.
691
 
                //              Images and CSS files may or may not have finished downloading when
692
 
                //              the specified function is called.  (Note that widgets' CSS and HTML
693
 
                //              code is guaranteed to be downloaded before said widgets are
694
 
                //              instantiated.)
695
 
                // example:
696
 
                //      |       dojo.addOnLoad(functionPointer);
697
 
                //      |       dojo.addOnLoad(object, "functionName");
698
 
                //      |       dojo.addOnLoad(object, function(){ /* ... */});
699
 
 
700
 
                d._onto(d._loaders, obj, functionName);
701
 
 
702
 
                //Added for xdomain loading. dojo.addOnLoad is used to
703
 
                //indicate callbacks after doing some dojo.require() statements.
704
 
                //In the xdomain case, if all the requires are loaded (after initial
705
 
                //page load), then immediately call any listeners.
706
 
                if(d._postLoad && d._inFlightCount == 0 && !d._loadNotifying){
707
 
                        d._callLoaded();
708
 
                }
709
 
        }
710
 
 
711
 
        //Support calling dojo.addOnLoad via djConfig.addOnLoad. Support all the
712
 
        //call permutations of dojo.addOnLoad. Mainly useful when dojo is added
713
 
        //to the page after the page has loaded.
714
 
        var dca = d.config.addOnLoad;
715
 
        if(dca){
716
 
                d.addOnLoad[(dca instanceof Array ? "apply" : "call")](d, dca);
717
 
        }
718
 
 
719
 
        dojo.addOnUnload = function(/*Object?*/obj, /*String|Function?*/functionName){
720
 
                // summary:
721
 
                //              registers a function to be triggered when the page unloads. In a browser
722
 
                //              enviroment, the functions will be triggered during the window.onbeforeunload
723
 
                //              event. Be careful doing work during window.onbeforeunload. onbeforeunload
724
 
                //              can be triggered if a link to download a file is clicked, or if the link is a
725
 
                //              javascript: link. In these cases, the onbeforeunload event fires, but the
726
 
                //              document is not actually destroyed. So be careful about doing destructive
727
 
                //              operations in a dojo.addOnUnload callback.
728
 
                // example:
729
 
                //      |       dojo.addOnUnload(functionPointer)
730
 
                //      |       dojo.addOnUnload(object, "functionName")
731
 
                //      |       dojo.addOnUnload(object, function(){ /* ... */});
732
 
 
733
 
                d._onto(d._unloaders, obj, functionName);
734
 
        }
735
 
 
736
 
        dojo._modulesLoaded = function(){
737
 
                if(d._postLoad){ return; }
738
 
                if(d._inFlightCount > 0){ 
739
 
                        console.warn("files still in flight!");
740
 
                        return;
741
 
                }
742
 
                d._callLoaded();
743
 
        }
744
 
 
745
 
        dojo._callLoaded = function(){
746
 
 
747
 
                // The "object" check is for IE, and the other opera check fixes an
748
 
                // issue in Opera where it could not find the body element in some
749
 
                // widget test cases.  For 0.9, maybe route all browsers through the
750
 
                // setTimeout (need protection still for non-browser environments
751
 
                // though). This might also help the issue with FF 2.0 and freezing
752
 
                // issues where we try to do sync xhr while background css images are
753
 
                // being loaded (trac #2572)? Consider for 0.9.
754
 
                if(typeof setTimeout == "object" || (dojo.config.useXDomain && d.isOpera)){
755
 
                        if(dojo.isAIR){
756
 
                                setTimeout(function(){dojo.loaded();}, 0);
757
 
                        }else{
758
 
                                setTimeout(dojo._scopeName + ".loaded();", 0);
759
 
                        }
760
 
                }else{
761
 
                        d.loaded();
762
 
                }
763
 
        }
764
 
 
765
 
        dojo._getModuleSymbols = function(/*String*/modulename){
766
 
                // summary:
767
 
                //              Converts a module name in dotted JS notation to an array
768
 
                //              representing the path in the source tree
769
 
                var syms = modulename.split(".");
770
 
                for(var i = syms.length; i>0; i--){
771
 
                        var parentModule = syms.slice(0, i).join(".");
772
 
                        if((i==1) && !this._moduleHasPrefix(parentModule)){             
773
 
                                // Support default module directory (sibling of dojo) for top-level modules 
774
 
                                syms[0] = "../" + syms[0];
775
 
                        }else{
776
 
                                var parentModulePath = this._getModulePrefix(parentModule);
777
 
                                if(parentModulePath != parentModule){
778
 
                                        syms.splice(0, i, parentModulePath);
779
 
                                        break;
780
 
                                }
781
 
                        }
782
 
                }
783
 
                // 
784
 
                return syms; // Array
785
 
        }
786
 
 
787
 
        dojo._global_omit_module_check = false;
788
 
 
789
 
        dojo.loadInit = function(/*Function*/init){
790
 
                //      summary:
791
 
                //              Executes a function that needs to be executed for the loader's dojo.requireIf
792
 
                //              resolutions to work. This is needed mostly for the xdomain loader case where
793
 
                //              a function needs to be executed to set up the possible values for a dojo.requireIf
794
 
                //              call.
795
 
                //      init:
796
 
                //              a function reference. Executed immediately.
797
 
                //      description: This function is mainly a marker for the xdomain loader to know parts of
798
 
                //              code that needs be executed outside the function wrappper that is placed around modules.
799
 
                //              The init function could be executed more than once, and it should make no assumptions
800
 
                //              on what is loaded, or what modules are available. Only the functionality in Dojo Base
801
 
                //              is allowed to be used. Avoid using this method. For a valid use case,
802
 
                //              see the source for dojox.gfx.
803
 
                init();
804
 
        }
805
 
 
806
 
        dojo._loadModule = dojo.require = function(/*String*/moduleName, /*Boolean?*/omitModuleCheck){
807
 
                //      summary:
808
 
                //              loads a Javascript module from the appropriate URI
809
 
                //      moduleName:
810
 
                //              module name to load, using periods for separators,
811
 
                //               e.g. "dojo.date.locale".  Module paths are de-referenced by dojo's
812
 
                //              internal mapping of locations to names and are disambiguated by
813
 
                //              longest prefix. See `dojo.registerModulePath()` for details on
814
 
                //              registering new modules.
815
 
                //      omitModuleCheck:
816
 
                //              if `true`, omitModuleCheck skips the step of ensuring that the
817
 
                //              loaded file actually defines the symbol it is referenced by.
818
 
                //              For example if it called as `dojo.require("a.b.c")` and the
819
 
                //              file located at `a/b/c.js` does not define an object `a.b.c`,
820
 
                //              and exception will be throws whereas no exception is raised
821
 
                //              when called as `dojo.require("a.b.c", true)`
822
 
                //      description:
823
 
                //              `dojo.require("A.B")` first checks to see if symbol A.B is
824
 
                //              defined. If it is, it is simply returned (nothing to do).
825
 
                //      
826
 
                //              If it is not defined, it will look for `A/B.js` in the script root
827
 
                //              directory.
828
 
                //      
829
 
                //              `dojo.require` throws an excpetion if it cannot find a file
830
 
                //              to load, or if the symbol `A.B` is not defined after loading.
831
 
                //      
832
 
                //              It returns the object `A.B`.
833
 
                //      
834
 
                //              `dojo.require()` does nothing about importing symbols into
835
 
                //              the current namespace.  It is presumed that the caller will
836
 
                //              take care of that. For example, to import all symbols into a
837
 
                //              local block, you might write:
838
 
                //      
839
 
                //              |       with (dojo.require("A.B")) {
840
 
                //              |               ...
841
 
                //              |       }
842
 
                //      
843
 
                //              And to import just the leaf symbol to a local variable:
844
 
                //      
845
 
                //              |       var B = dojo.require("A.B");
846
 
                //              |       ...
847
 
                //      returns: the required namespace object
848
 
                omitModuleCheck = this._global_omit_module_check || omitModuleCheck;
849
 
 
850
 
                //Check if it is already loaded.
851
 
                var module = this._loadedModules[moduleName];
852
 
                if(module){
853
 
                        return module;
854
 
                }
855
 
 
856
 
                // convert periods to slashes
857
 
                var relpath = this._getModuleSymbols(moduleName).join("/") + '.js';
858
 
 
859
 
                var modArg = (!omitModuleCheck) ? moduleName : null;
860
 
                var ok = this._loadPath(relpath, modArg);
861
 
 
862
 
                if(!ok && !omitModuleCheck){
863
 
                        throw new Error("Could not load '" + moduleName + "'; last tried '" + relpath + "'");
864
 
                }
865
 
 
866
 
                // check that the symbol was defined
867
 
                // Don't bother if we're doing xdomain (asynchronous) loading.
868
 
                if(!omitModuleCheck && !this._isXDomain){
869
 
                        // pass in false so we can give better error
870
 
                        module = this._loadedModules[moduleName];
871
 
                        if(!module){
872
 
                                throw new Error("symbol '" + moduleName + "' is not defined after loading '" + relpath + "'"); 
873
 
                        }
874
 
                }
875
 
 
876
 
                return module;
877
 
        }
878
 
 
879
 
        dojo.provide = function(/*String*/ resourceName){
880
 
                //      summary:
881
 
                //              Each javascript source file must have at least one
882
 
                //              `dojo.provide()` call at the top of the file, corresponding to
883
 
                //              the file name.  For example, `js/dojo/foo.js` must have
884
 
                //              `dojo.provide("dojo.foo");` before any calls to
885
 
                //              `dojo.require()` are made.
886
 
                //      description:
887
 
                //              Each javascript source file is called a resource.  When a
888
 
                //              resource is loaded by the browser, `dojo.provide()` registers
889
 
                //              that it has been loaded.
890
 
                //      
891
 
                //              For backwards compatibility reasons, in addition to registering
892
 
                //              the resource, `dojo.provide()` also ensures that the javascript
893
 
                //              object for the module exists.  For example,
894
 
                //              `dojo.provide("dojox.data.FlickrStore")`, in addition to
895
 
                //              registering that `FlickrStore.js` is a resource for the
896
 
                //              `dojox.data` module, will ensure that the `dojox.data`
897
 
                //              javascript object exists, so that calls like 
898
 
                //              `dojo.data.foo = function(){ ... }` don't fail.
899
 
                //
900
 
                //              In the case of a build where multiple javascript source files
901
 
                //              are combined into one bigger file (similar to a .lib or .jar
902
 
                //              file), that file may contain multiple dojo.provide() calls, to
903
 
                //              note that it includes multiple resources.
904
 
 
905
 
                //Make sure we have a string.
906
 
                resourceName = resourceName + "";
907
 
                return (d._loadedModules[resourceName] = d.getObject(resourceName, true)); // Object
908
 
        }
909
 
 
910
 
        //Start of old bootstrap2:
911
 
 
912
 
        dojo.platformRequire = function(/*Object*/modMap){
913
 
                //      summary:
914
 
                //              require one or more modules based on which host environment
915
 
                //              Dojo is currently operating in
916
 
                //      description:
917
 
                //              This method takes a "map" of arrays which one can use to
918
 
                //              optionally load dojo modules. The map is indexed by the
919
 
                //              possible dojo.name_ values, with two additional values:
920
 
                //              "default" and "common". The items in the "default" array will
921
 
                //              be loaded if none of the other items have been choosen based on
922
 
                //              dojo.name_, set by your host environment. The items in the
923
 
                //              "common" array will *always* be loaded, regardless of which
924
 
                //              list is chosen.
925
 
                //      example:
926
 
                //              |       dojo.platformRequire({
927
 
                //              |               browser: [
928
 
                //              |                       "foo.sample", // simple module
929
 
                //              |                       "foo.test",
930
 
                //              |                       ["foo.bar.baz", true] // skip object check in _loadModule (dojo.require)
931
 
                //              |               ],
932
 
                //              |               default: [ "foo.sample._base" ],
933
 
                //              |               common: [ "important.module.common" ]
934
 
                //              |       });
935
 
 
936
 
                var common = modMap.common || [];
937
 
                var result = common.concat(modMap[d._name] || modMap["default"] || []);
938
 
 
939
 
                for(var x=0; x<result.length; x++){
940
 
                        var curr = result[x];
941
 
                        if(curr.constructor == Array){
942
 
                                d._loadModule.apply(d, curr);
943
 
                        }else{
944
 
                                d._loadModule(curr);
945
 
                        }
946
 
                }
947
 
        }
948
 
 
949
 
        dojo.requireIf = function(/*Boolean*/ condition, /*String*/ resourceName){
950
 
                // summary:
951
 
                //              If the condition is true then call dojo.require() for the specified
952
 
                //              resource
953
 
                if(condition === true){
954
 
                        // FIXME: why do we support chained require()'s here? does the build system?
955
 
                        var args = [];
956
 
                        for(var i = 1; i < arguments.length; i++){ 
957
 
                                args.push(arguments[i]);
958
 
                        }
959
 
                        d.require.apply(d, args);
960
 
                }
961
 
        }
962
 
 
963
 
        dojo.requireAfterIf = d.requireIf;
964
 
 
965
 
        dojo.registerModulePath = function(/*String*/module, /*String*/prefix){
966
 
                //      summary: 
967
 
                //              maps a module name to a path
968
 
                //      description: 
969
 
                //              An unregistered module is given the default path of ../[module],
970
 
                //              relative to Dojo root. For example, module acme is mapped to
971
 
                //              ../acme.  If you want to use a different module name, use
972
 
                //              dojo.registerModulePath. 
973
 
                //      example:
974
 
                //              If your dojo.js is located at this location in the web root:
975
 
                //      |       /myapp/js/dojo/dojo/dojo.js
976
 
                //              and your modules are located at:
977
 
                //      |       /myapp/js/foo/bar.js
978
 
                //      |       /myapp/js/foo/baz.js
979
 
                //      |       /myapp/js/foo/thud/xyzzy.js
980
 
                //              Your application can tell Dojo to locate the "foo" namespace by calling:
981
 
                //      |       dojo.registerModulePath("foo", "../../foo");
982
 
                //              At which point you can then use dojo.require() to load the
983
 
                //              modules (assuming they provide() the same things which are
984
 
                //              required). The full code might be:
985
 
                //      |       <script type="text/javascript" 
986
 
                //      |               src="/myapp/js/dojo/dojo/dojo.js"></script>
987
 
                //      |       <script type="text/javascript">
988
 
                //      |               dojo.registerModulePath("foo", "../../foo");
989
 
                //      |               dojo.require("foo.bar");
990
 
                //      |               dojo.require("foo.baz");
991
 
                //      |               dojo.require("foo.thud.xyzzy");
992
 
                //      |       </script>
993
 
                d._modulePrefixes[module] = { name: module, value: prefix };
994
 
        }
995
 
 
996
 
        dojo.requireLocalization = function(/*String*/moduleName, /*String*/bundleName, /*String?*/locale, /*String?*/availableFlatLocales){
997
 
                // summary:
998
 
                //              Declares translated resources and loads them if necessary, in the
999
 
                //              same style as dojo.require.  Contents of the resource bundle are
1000
 
                //              typically strings, but may be any name/value pair, represented in
1001
 
                //              JSON format.  See also `dojo.i18n.getLocalization`.
1002
 
                //
1003
 
                // description:
1004
 
                //              Load translated resource bundles provided underneath the "nls"
1005
 
                //              directory within a package.  Translated resources may be located in
1006
 
                //              different packages throughout the source tree.  
1007
 
                //
1008
 
                //              Each directory is named for a locale as specified by RFC 3066,
1009
 
                //              (http://www.ietf.org/rfc/rfc3066.txt), normalized in lowercase.
1010
 
                //              Note that the two bundles in the example do not define all the
1011
 
                //              same variants.  For a given locale, bundles will be loaded for
1012
 
                //              that locale and all more general locales above it, including a
1013
 
                //              fallback at the root directory.  For example, a declaration for
1014
 
                //              the "de-at" locale will first load `nls/de-at/bundleone.js`,
1015
 
                //              then `nls/de/bundleone.js` and finally `nls/bundleone.js`.  The
1016
 
                //              data will be flattened into a single Object so that lookups
1017
 
                //              will follow this cascading pattern.  An optional build step can
1018
 
                //              preload the bundles to avoid data redundancy and the multiple
1019
 
                //              network hits normally required to load these resources.
1020
 
                //
1021
 
                // moduleName: 
1022
 
                //              name of the package containing the "nls" directory in which the
1023
 
                //              bundle is found
1024
 
                //
1025
 
                // bundleName: 
1026
 
                //              bundle name, i.e. the filename without the '.js' suffix
1027
 
                //
1028
 
                // locale: 
1029
 
                //              the locale to load (optional)  By default, the browser's user
1030
 
                //              locale as defined by dojo.locale
1031
 
                //
1032
 
                // availableFlatLocales: 
1033
 
                //              A comma-separated list of the available, flattened locales for this
1034
 
                //              bundle. This argument should only be set by the build process.
1035
 
                //
1036
 
                //      example:
1037
 
                //              A particular widget may define one or more resource bundles,
1038
 
                //              structured in a program as follows, where moduleName is
1039
 
                //              mycode.mywidget and bundleNames available include bundleone and
1040
 
                //              bundletwo:
1041
 
                //      |               ...
1042
 
                //      |       mycode/
1043
 
                //      |               mywidget/
1044
 
                //      |                       nls/
1045
 
                //      |                               bundleone.js (the fallback translation, English in this example)
1046
 
                //      |                               bundletwo.js (also a fallback translation)
1047
 
                //      |                               de/
1048
 
                //      |                                       bundleone.js
1049
 
                //      |                                       bundletwo.js
1050
 
                //      |                               de-at/
1051
 
                //      |                                       bundleone.js
1052
 
                //      |                               en/
1053
 
                //      |                                       (empty; use the fallback translation)
1054
 
                //      |                               en-us/
1055
 
                //      |                                       bundleone.js
1056
 
                //      |                               en-gb/
1057
 
                //      |                                       bundleone.js
1058
 
                //      |                               es/
1059
 
                //      |                                       bundleone.js
1060
 
                //      |                                       bundletwo.js
1061
 
                //      |                                 ...etc
1062
 
                //      |                               ...
1063
 
                //
1064
 
 
1065
 
                d.require("dojo.i18n");
1066
 
                d.i18n._requireLocalization.apply(d.hostenv, arguments);
1067
 
        };
1068
 
 
1069
 
 
1070
 
        var ore = new RegExp("^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?$");
1071
 
        var ire = new RegExp("^((([^\\[:]+):)?([^@]+)@)?(\\[([^\\]]+)\\]|([^\\[:]*))(:([0-9]+))?$");
1072
 
 
1073
 
        dojo._Url = function(/*dojo._Url||String...*/){
1074
 
                // summary: 
1075
 
                //              Constructor to create an object representing a URL.
1076
 
                //              It is marked as private, since we might consider removing
1077
 
                //              or simplifying it.
1078
 
                // description: 
1079
 
                //              Each argument is evaluated in order relative to the next until
1080
 
                //              a canonical uri is produced. To get an absolute Uri relative to
1081
 
                //              the current document use:
1082
 
                //              new dojo._Url(document.baseURI, url)
1083
 
 
1084
 
                var n = null;
1085
 
 
1086
 
                var _a = arguments;
1087
 
                var uri = [_a[0]];
1088
 
                // resolve uri components relative to each other
1089
 
                for(var i = 1; i<_a.length; i++){
1090
 
                        if(!_a[i]){ continue; }
1091
 
 
1092
 
                        // Safari doesn't support this.constructor so we have to be explicit
1093
 
                        // FIXME: Tracked (and fixed) in Webkit bug 3537.
1094
 
                        //              http://bugs.webkit.org/show_bug.cgi?id=3537
1095
 
                        var relobj = new d._Url(_a[i]+"");
1096
 
                        var uriobj = new d._Url(uri[0]+"");
1097
 
 
1098
 
                        if(
1099
 
                                relobj.path == "" &&
1100
 
                                !relobj.scheme &&
1101
 
                                !relobj.authority &&
1102
 
                                !relobj.query
1103
 
                        ){
1104
 
                                if(relobj.fragment != n){
1105
 
                                        uriobj.fragment = relobj.fragment;
1106
 
                                }
1107
 
                                relobj = uriobj;
1108
 
                        }else if(!relobj.scheme){
1109
 
                                relobj.scheme = uriobj.scheme;
1110
 
 
1111
 
                                if(!relobj.authority){
1112
 
                                        relobj.authority = uriobj.authority;
1113
 
 
1114
 
                                        if(relobj.path.charAt(0) != "/"){
1115
 
                                                var path = uriobj.path.substring(0,
1116
 
                                                        uriobj.path.lastIndexOf("/") + 1) + relobj.path;
1117
 
 
1118
 
                                                var segs = path.split("/");
1119
 
                                                for(var j = 0; j < segs.length; j++){
1120
 
                                                        if(segs[j] == "."){
1121
 
                                                                // flatten "./" references
1122
 
                                                                if(j == segs.length - 1){
1123
 
                                                                        segs[j] = "";
1124
 
                                                                }else{
1125
 
                                                                        segs.splice(j, 1);
1126
 
                                                                        j--;
1127
 
                                                                }
1128
 
                                                        }else if(j > 0 && !(j == 1 && segs[0] == "") &&
1129
 
                                                                segs[j] == ".." && segs[j-1] != ".."){
1130
 
                                                                // flatten "../" references
1131
 
                                                                if(j == (segs.length - 1)){
1132
 
                                                                        segs.splice(j, 1);
1133
 
                                                                        segs[j - 1] = "";
1134
 
                                                                }else{
1135
 
                                                                        segs.splice(j - 1, 2);
1136
 
                                                                        j -= 2;
1137
 
                                                                }
1138
 
                                                        }
1139
 
                                                }
1140
 
                                                relobj.path = segs.join("/");
1141
 
                                        }
1142
 
                                }
1143
 
                        }
1144
 
 
1145
 
                        uri = [];
1146
 
                        if(relobj.scheme){ 
1147
 
                                uri.push(relobj.scheme, ":");
1148
 
                        }
1149
 
                        if(relobj.authority){
1150
 
                                uri.push("//", relobj.authority);
1151
 
                        }
1152
 
                        uri.push(relobj.path);
1153
 
                        if(relobj.query){
1154
 
                                uri.push("?", relobj.query);
1155
 
                        }
1156
 
                        if(relobj.fragment){
1157
 
                                uri.push("#", relobj.fragment);
1158
 
                        }
1159
 
                }
1160
 
 
1161
 
                this.uri = uri.join("");
1162
 
 
1163
 
                // break the uri into its main components
1164
 
                var r = this.uri.match(ore);
1165
 
 
1166
 
                this.scheme = r[2] || (r[1] ? "" : n);
1167
 
                this.authority = r[4] || (r[3] ? "" : n);
1168
 
                this.path = r[5]; // can never be undefined
1169
 
                this.query = r[7] || (r[6] ? "" : n);
1170
 
                this.fragment  = r[9] || (r[8] ? "" : n);
1171
 
 
1172
 
                if(this.authority != n){
1173
 
                        // server based naming authority
1174
 
                        r = this.authority.match(ire);
1175
 
 
1176
 
                        this.user = r[3] || n;
1177
 
                        this.password = r[4] || n;
1178
 
                        this.host = r[6] || r[7]; // ipv6 || ipv4
1179
 
                        this.port = r[9] || n;
1180
 
                }
1181
 
        }
1182
 
 
1183
 
        dojo._Url.prototype.toString = function(){ return this.uri; };
1184
 
 
1185
 
        dojo.moduleUrl = function(/*String*/module, /*dojo._Url||String*/url){
1186
 
                //      summary: 
1187
 
                //              Returns a `dojo._Url` object relative to a module.
1188
 
                //      example:
1189
 
                //      |       var pngPath = dojo.moduleUrl("acme","images/small.png");
1190
 
                //      |        // list the object properties
1191
 
                //      |       // create an image and set it's source to pngPath's value:
1192
 
                //      |       var img = document.createElement("img");
1193
 
                //      |       // NOTE: we assign the string representation of the url object
1194
 
                //      |       img.src = pngPath.toString(); 
1195
 
                //      |       // add our image to the document
1196
 
                //      |       dojo.body().appendChild(img);
1197
 
                //      example: 
1198
 
                //              you may de-reference as far as you like down the package
1199
 
                //              hierarchy.  This is sometimes handy to avoid lenghty relative
1200
 
                //              urls or for building portable sub-packages. In this example,
1201
 
                //              the `acme.widget` and `acme.util` directories may be located
1202
 
                //              under different roots (see `dojo.registerModulePath`) but the
1203
 
                //              the modules which reference them can be unaware of their
1204
 
                //              relative locations on the filesystem:
1205
 
                //      |       // somewhere in a configuration block
1206
 
                //      |       dojo.registerModulePath("acme.widget", "../../acme/widget");
1207
 
                //      |       dojo.registerModulePath("acme.util", "../../util");
1208
 
                //      |       
1209
 
                //      |       // ...
1210
 
                //      |       
1211
 
                //      |       // code in a module using acme resources
1212
 
                //      |       var tmpltPath = dojo.moduleUrl("acme.widget","templates/template.html");
1213
 
                //      |       var dataPath = dojo.moduleUrl("acme.util","resources/data.json");
1214
 
 
1215
 
                var loc = d._getModuleSymbols(module).join('/');
1216
 
                if(!loc){ return null; }
1217
 
                if(loc.lastIndexOf("/") != loc.length-1){
1218
 
                        loc += "/";
1219
 
                }
1220
 
                
1221
 
                //If the path is an absolute path (starts with a / or is on another
1222
 
                //domain/xdomain) then don't add the baseUrl.
1223
 
                var colonIndex = loc.indexOf(":");
1224
 
                if(loc.charAt(0) != "/" && (colonIndex == -1 || colonIndex > loc.indexOf("/"))){
1225
 
                        loc = d.baseUrl + loc;
1226
 
                }
1227
 
 
1228
 
                return new d._Url(loc, url); // String
1229
 
        }
1230
 
})();
1231
 
 
1232
 
/*=====
1233
 
dojo.isBrowser = {
1234
 
        //      example:
1235
 
        //      |       if(dojo.isBrowser){ ... }
1236
 
};
1237
 
 
1238
 
dojo.isFF = {
1239
 
        //      example:
1240
 
        //      |       if(dojo.isFF > 1){ ... }
1241
 
};
1242
 
 
1243
 
dojo.isIE = {
1244
 
        // example:
1245
 
        //      |       if(dojo.isIE > 6){
1246
 
        //      |               // we are IE7
1247
 
        //      |       }
1248
 
};
1249
 
 
1250
 
dojo.isSafari = {
1251
 
        //      example:
1252
 
        //      |       if(dojo.isSafari){ ... }
1253
 
        //      example: 
1254
 
        //              Detect iPhone:
1255
 
        //      |       if(dojo.isSafari && navigator.userAgent.indexOf("iPhone") != -1){ 
1256
 
        //      |               // we are iPhone. Note, iPod touch reports "iPod" above and fails this test.
1257
 
        //      |       }
1258
 
};
1259
 
 
1260
 
dojo = {
1261
 
        // isBrowser: Boolean
1262
 
        //              True if the client is a web-browser
1263
 
        isBrowser: true,
1264
 
        //      isFF: Number | undefined
1265
 
        //              Version as a Number if client is FireFox. undefined otherwise. Corresponds to
1266
 
        //              major detected FireFox version (1.5, 2, 3, etc.)
1267
 
        isFF: 2,
1268
 
        //      isIE: Number | undefined
1269
 
        //              Version as a Number if client is MSIE(PC). undefined otherwise. Corresponds to
1270
 
        //              major detected IE version (6, 7, 8, etc.)
1271
 
        isIE: 6,
1272
 
        //      isKhtml: Number | undefined
1273
 
        //              Version as a Number if client is a KTHML-derived browser (Konqueror,
1274
 
        //              Safari, etc.). undefined otherwise. Corresponds to major detected version.
1275
 
        isKhtml: 0,
1276
 
        //      isMozilla: Number | undefined
1277
 
        //              Version as a Number if client is a Mozilla-based browser (Firefox,
1278
 
        //              SeaMonkey). undefined otherwise. Corresponds to major detected version.
1279
 
        isMozilla: 0,
1280
 
        //      isOpera: Number | undefined
1281
 
        //              Version as a Number if client is Opera. undefined otherwise. Corresponds to
1282
 
        //              major detected version.
1283
 
        isOpera: 0,
1284
 
        //      isSafari: Number | undefined
1285
 
        //              Version as a Number if client is Safari or iPhone. undefined otherwise.
1286
 
        isSafari: 0
1287
 
}
1288
 
=====*/
1289
 
 
1290
 
if(typeof window != 'undefined'){
1291
 
        dojo.isBrowser = true;
1292
 
        dojo._name = "browser";
1293
 
 
1294
 
 
1295
 
        // attempt to figure out the path to dojo if it isn't set in the config
1296
 
        (function(){
1297
 
                var d = dojo;
1298
 
                // this is a scope protection closure. We set browser versions and grab
1299
 
                // the URL we were loaded from here.
1300
 
 
1301
 
                // grab the node we were loaded from
1302
 
                if(document && document.getElementsByTagName){
1303
 
                        var scripts = document.getElementsByTagName("script");
1304
 
                        var rePkg = /dojo(\.xd)?\.js(\W|$)/i;
1305
 
                        for(var i = 0; i < scripts.length; i++){
1306
 
                                var src = scripts[i].getAttribute("src");
1307
 
                                if(!src){ continue; }
1308
 
                                var m = src.match(rePkg);
1309
 
                                if(m){
1310
 
                                        // find out where we came from
1311
 
                                        if(!d.config.baseUrl){
1312
 
                                                d.config.baseUrl = src.substring(0, m.index);
1313
 
                                        }
1314
 
                                        // and find out if we need to modify our behavior
1315
 
                                        var cfg = scripts[i].getAttribute("djConfig");
1316
 
                                        if(cfg){
1317
 
                                                var cfgo = eval("({ "+cfg+" })");
1318
 
                                                for(var x in cfgo){
1319
 
                                                        dojo.config[x] = cfgo[x];
1320
 
                                                }
1321
 
                                        }
1322
 
                                        break; // "first Dojo wins"
1323
 
                                }
1324
 
                        }
1325
 
                }
1326
 
                d.baseUrl = d.config.baseUrl;
1327
 
 
1328
 
                // fill in the rendering support information in dojo.render.*
1329
 
                var n = navigator;
1330
 
                var dua = n.userAgent;
1331
 
                var dav = n.appVersion;
1332
 
                var tv = parseFloat(dav);
1333
 
 
1334
 
                if(dua.indexOf("Opera") >= 0){ d.isOpera = tv; }
1335
 
                // safari detection derived from:
1336
 
                //              http://developer.apple.com/internet/safari/faq.html#anchor2
1337
 
                //              http://developer.apple.com/internet/safari/uamatrix.html
1338
 
                var index = Math.max(dav.indexOf("WebKit"), dav.indexOf("Safari"), 0);
1339
 
                if(index){
1340
 
                        // try to grab the explicit Safari version first. If we don't get
1341
 
                        // one, look for 419.3+ as the indication that we're on something
1342
 
                        // "Safari 3-ish". Lastly, default to "Safari 2" handling.
1343
 
                        d.isSafari = parseFloat(dav.split("Version/")[1]) ||
1344
 
                                (parseFloat(dav.substr(index + 7)) > 419.3) ? 3 : 2;
1345
 
                }
1346
 
                if(dua.indexOf("AdobeAIR") >= 0){ d.isAIR = 1; }
1347
 
                if(dav.indexOf("Konqueror") >= 0 || d.isSafari){ d.isKhtml =  tv; }
1348
 
                if(dua.indexOf("Gecko") >= 0 && !d.isKhtml){ d.isMozilla = d.isMoz = tv; }
1349
 
                if(d.isMoz){
1350
 
                        d.isFF = parseFloat(dua.split("Firefox/")[1]) || undefined;
1351
 
                }
1352
 
                if(document.all && !d.isOpera){
1353
 
                        d.isIE = parseFloat(dav.split("MSIE ")[1]) || undefined;
1354
 
                }
1355
 
 
1356
 
                //Workaround to get local file loads of dojo to work on IE 7
1357
 
                //by forcing to not use native xhr.
1358
 
                if(dojo.isIE && window.location.protocol === "file:"){
1359
 
                        dojo.config.ieForceActiveXXhr=true;
1360
 
                }
1361
 
 
1362
 
                var cm = document.compatMode;
1363
 
                d.isQuirks = cm == "BackCompat" || cm == "QuirksMode" || d.isIE < 6;
1364
 
 
1365
 
                // TODO: is the HTML LANG attribute relevant?
1366
 
                d.locale = dojo.config.locale || (d.isIE ? n.userLanguage : n.language).toLowerCase();
1367
 
 
1368
 
                // These are in order of decreasing likelihood; this will change in time.
1369
 
                d._XMLHTTP_PROGIDS = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'];
1370
 
 
1371
 
                d._xhrObj = function(){
1372
 
                        // summary: 
1373
 
                        //              does the work of portably generating a new XMLHTTPRequest
1374
 
                        //              object.
1375
 
                        var http = null;
1376
 
                        var last_e = null;
1377
 
                        if(!dojo.isIE || !dojo.config.ieForceActiveXXhr){
1378
 
                                try{ http = new XMLHttpRequest(); }catch(e){}
1379
 
                        }
1380
 
                        if(!http){
1381
 
                                for(var i=0; i<3; ++i){
1382
 
                                        var progid = d._XMLHTTP_PROGIDS[i];
1383
 
                                        try{
1384
 
                                                http = new ActiveXObject(progid);
1385
 
                                        }catch(e){
1386
 
                                                last_e = e;
1387
 
                                        }
1388
 
 
1389
 
                                        if(http){
1390
 
                                                d._XMLHTTP_PROGIDS = [progid];  // so faster next time
1391
 
                                                break;
1392
 
                                        }
1393
 
                                }
1394
 
                        }
1395
 
 
1396
 
                        if(!http){
1397
 
                                throw new Error("XMLHTTP not available: "+last_e);
1398
 
                        }
1399
 
 
1400
 
                        return http; // XMLHTTPRequest instance
1401
 
                }
1402
 
 
1403
 
                d._isDocumentOk = function(http){
1404
 
                        var stat = http.status || 0;
1405
 
                        return (stat >= 200 && stat < 300) ||   // Boolean
1406
 
                                stat == 304 ||                                          // allow any 2XX response code
1407
 
                                stat == 1223 ||                                                 // get it out of the cache
1408
 
                                (!stat && (location.protocol=="file:" || location.protocol=="chrome:") ); // Internet Explorer mangled the status code
1409
 
                }
1410
 
 
1411
 
                //See if base tag is in use.
1412
 
                //This is to fix http://trac.dojotoolkit.org/ticket/3973,
1413
 
                //but really, we need to find out how to get rid of the dojo._Url reference
1414
 
                //below and still have DOH work with the dojo.i18n test following some other
1415
 
                //test that uses the test frame to load a document (trac #2757).
1416
 
                //Opera still has problems, but perhaps a larger issue of base tag support
1417
 
                //with XHR requests (hasBase is true, but the request is still made to document
1418
 
                //path, not base path).
1419
 
                var owloc = window.location+"";
1420
 
                var base = document.getElementsByTagName("base");
1421
 
                var hasBase = (base && base.length > 0);
1422
 
 
1423
 
                d._getText = function(/*URI*/ uri, /*Boolean*/ fail_ok){
1424
 
                        // summary: Read the contents of the specified uri and return those contents.
1425
 
                        // uri:
1426
 
                        //              A relative or absolute uri. If absolute, it still must be in
1427
 
                        //              the same "domain" as we are.
1428
 
                        // fail_ok:
1429
 
                        //              Default false. If fail_ok and loading fails, return null
1430
 
                        //              instead of throwing.
1431
 
                        // returns: The response text. null is returned when there is a
1432
 
                        //              failure and failure is okay (an exception otherwise)
1433
 
 
1434
 
                        // alert("_getText: " + uri);
1435
 
 
1436
 
                        // NOTE: must be declared before scope switches ie. this._xhrObj()
1437
 
                        var http = this._xhrObj();
1438
 
 
1439
 
                        if(!hasBase && dojo._Url){
1440
 
                                uri = (new dojo._Url(owloc, uri)).toString();
1441
 
                        }
1442
 
                        /*
1443
 
                        
1444
 
                        
1445
 
                        alert(uri);
1446
 
                        */
1447
 
 
1448
 
                        if(d.config.cacheBust){
1449
 
                                //Make sure we have a string before string methods are used on uri
1450
 
                                uri += "";
1451
 
                                uri += (uri.indexOf("?") == -1 ? "?" : "&") + String(d.config.cacheBust).replace(/\W+/g,"");
1452
 
                        }
1453
 
 
1454
 
                        http.open('GET', uri, false);
1455
 
                        try{
1456
 
                                http.send(null);
1457
 
                                // alert(http);
1458
 
                                if(!d._isDocumentOk(http)){
1459
 
                                        var err = Error("Unable to load "+uri+" status:"+ http.status);
1460
 
                                        err.status = http.status;
1461
 
                                        err.responseText = http.responseText;
1462
 
                                        throw err;
1463
 
                                }
1464
 
                        }catch(e){
1465
 
                                if(fail_ok){ return null; } // null
1466
 
                                // rethrow the exception
1467
 
                                throw e;
1468
 
                        }
1469
 
                        return http.responseText; // String
1470
 
                }
1471
 
                
1472
 
                d._windowUnloaders = [];
1473
 
                
1474
 
                d.windowUnloaded = function(){
1475
 
                        // summary:
1476
 
                        //              signal fired by impending window destruction. You may use
1477
 
                        //              dojo.addOnWIndowUnload() or dojo.connect() to this method to perform
1478
 
                        //              page/application cleanup methods. See dojo.addOnWindowUnload for more info.
1479
 
                        var mll = this._windowUnloaders;
1480
 
                        while(mll.length){
1481
 
                                (mll.pop())();
1482
 
                        }
1483
 
                }
1484
 
 
1485
 
                d.addOnWindowUnload = function(/*Object?*/obj, /*String|Function?*/functionName){
1486
 
                        // summary:
1487
 
                        //              registers a function to be triggered when window.onunload fires.
1488
 
                        //              Be careful trying to modify the DOM or access JavaScript properties
1489
 
                        //              during this phase of page unloading: they may not always be available.
1490
 
                        //              Consider dojo.addOnUnload() if you need to modify the DOM or do heavy
1491
 
                        //              JavaScript work.
1492
 
                        // example:
1493
 
                        //      |       dojo.addOnWindowUnload(functionPointer)
1494
 
                        //      |       dojo.addOnWindowUnload(object, "functionName")
1495
 
                        //      |       dojo.addOnWindowUnload(object, function(){ /* ... */});
1496
 
        
1497
 
                        d._onto(d._windowUnloaders, obj, functionName);
1498
 
                }
1499
 
        })();
1500
 
 
1501
 
        dojo._initFired = false;
1502
 
        //      BEGIN DOMContentLoaded, from Dean Edwards (http://dean.edwards.name/weblog/2006/06/again/)
1503
 
        dojo._loadInit = function(e){
1504
 
                dojo._initFired = true;
1505
 
                // allow multiple calls, only first one will take effect
1506
 
                // A bug in khtml calls events callbacks for document for event which isnt supported
1507
 
                // for example a created contextmenu event calls DOMContentLoaded, workaround
1508
 
                var type = (e && e.type) ? e.type.toLowerCase() : "load";
1509
 
                if(arguments.callee.initialized || (type != "domcontentloaded" && type != "load")){ return; }
1510
 
                arguments.callee.initialized = true;
1511
 
                if("_khtmlTimer" in dojo){
1512
 
                        clearInterval(dojo._khtmlTimer);
1513
 
                        delete dojo._khtmlTimer;
1514
 
                }
1515
 
 
1516
 
                if(dojo._inFlightCount == 0){
1517
 
                        dojo._modulesLoaded();
1518
 
                }
1519
 
        }
1520
 
 
1521
 
        dojo._fakeLoadInit = function(){
1522
 
                dojo._loadInit({type: "load"});
1523
 
        }
1524
 
 
1525
 
        if(!dojo.config.afterOnLoad){
1526
 
                //      START DOMContentLoaded
1527
 
                // Mozilla and Opera 9 expose the event we could use
1528
 
                if(document.addEventListener){
1529
 
                        // NOTE: 
1530
 
                        //              due to a threading issue in Firefox 2.0, we can't enable
1531
 
                        //              DOMContentLoaded on that platform. For more information, see:
1532
 
                        //              http://trac.dojotoolkit.org/ticket/1704
1533
 
                        if(dojo.isOpera || dojo.isFF >= 3 || (dojo.isMoz && dojo.config.enableMozDomContentLoaded === true)){
1534
 
                                document.addEventListener("DOMContentLoaded", dojo._loadInit, null);
1535
 
                        }
1536
 
        
1537
 
                        //      mainly for Opera 8.5, won't be fired if DOMContentLoaded fired already.
1538
 
                        //  also used for Mozilla because of trac #1640
1539
 
                        window.addEventListener("load", dojo._loadInit, null);
1540
 
                }
1541
 
        
1542
 
                if(dojo.isAIR){
1543
 
                        window.addEventListener("load", dojo._loadInit, null);
1544
 
                }else if(/(WebKit|khtml)/i.test(navigator.userAgent)){ // sniff
1545
 
                        dojo._khtmlTimer = setInterval(function(){
1546
 
                                if(/loaded|complete/.test(document.readyState)){
1547
 
                                        dojo._loadInit(); // call the onload handler
1548
 
                                }
1549
 
                        }, 10);
1550
 
                }
1551
 
                //      END DOMContentLoaded
1552
 
        }
1553
 
 
1554
 
        (function(){
1555
 
                var _w = window;
1556
 
                var _handleNodeEvent = function(/*String*/evtName, /*Function*/fp){
1557
 
                        // summary:
1558
 
                        //              non-destructively adds the specified function to the node's
1559
 
                        //              evtName handler.
1560
 
                        // evtName: should be in the form "onclick" for "onclick" handlers.
1561
 
                        // Make sure you pass in the "on" part.
1562
 
                        var oldHandler = _w[evtName] || function(){};
1563
 
                        _w[evtName] = function(){
1564
 
                                fp.apply(_w, arguments);
1565
 
                                oldHandler.apply(_w, arguments);
1566
 
                        };
1567
 
                };
1568
 
 
1569
 
                if(dojo.isIE){
1570
 
                        //      for Internet Explorer. readyState will not be achieved on init
1571
 
                        //      call, but dojo doesn't need it however, we'll include it
1572
 
                        //      because we don't know if there are other functions added that
1573
 
                        //      might.  Note that this has changed because the build process
1574
 
                        //      strips all comments -- including conditional ones.
1575
 
                        if(!dojo.config.afterOnLoad){
1576
 
                                document.write('<scr'+'ipt defer src="//:" '
1577
 
                                        + 'onreadystatechange="if(this.readyState==\'complete\'){' + dojo._scopeName + '._loadInit();}">'
1578
 
                                        + '</scr'+'ipt>'
1579
 
                                );
1580
 
                        }
1581
 
 
1582
 
                        try{
1583
 
                                document.namespaces.add("v","urn:schemas-microsoft-com:vml");
1584
 
                                document.createStyleSheet().addRule("v\\:*", "behavior:url(#default#VML)");
1585
 
                        }catch(e){}
1586
 
                }
1587
 
 
1588
 
                // FIXME: dojo.unloaded requires dojo scope, so using anon function wrapper.
1589
 
                _handleNodeEvent("onbeforeunload", function() { dojo.unloaded(); });
1590
 
                _handleNodeEvent("onunload", function() { dojo.windowUnloaded(); });
1591
 
        })();
1592
 
 
1593
 
        /*
1594
 
        OpenAjax.subscribe("OpenAjax", "onload", function(){
1595
 
                if(dojo._inFlightCount == 0){
1596
 
                        dojo._modulesLoaded();
1597
 
                }
1598
 
        });
1599
 
 
1600
 
        OpenAjax.subscribe("OpenAjax", "onunload", function(){
1601
 
                dojo.unloaded();
1602
 
        });
1603
 
        */
1604
 
} //if (typeof window != 'undefined')
1605
 
 
1606
 
//Register any module paths set up in djConfig. Need to do this
1607
 
//in the hostenvs since hostenv_browser can read djConfig from a
1608
 
//script tag's attribute.
1609
 
(function(){
1610
 
        var mp = dojo.config["modulePaths"];
1611
 
        if(mp){
1612
 
                for(var param in mp){
1613
 
                        dojo.registerModulePath(param, mp[param]);
1614
 
                }
1615
 
        }
1616
 
})();
1617
 
 
1618
 
//Load debug code if necessary.
1619
 
if(dojo.config.isDebug){
1620
 
        dojo.require("dojo._firebug.firebug");
1621
 
}
1622
 
 
1623
 
if(dojo.config.debugAtAllCosts){
1624
 
        dojo.config.useXDomain = true;
1625
 
        dojo.require("dojo._base._loader.loader_xd");
1626
 
        dojo.require("dojo._base._loader.loader_debug");
1627
 
        dojo.require("dojo.i18n");
1628
 
}
1629
 
 
1630
 
if(!dojo._hasResource["dojo._base.lang"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
1631
 
dojo._hasResource["dojo._base.lang"] = true;
1632
 
dojo.provide("dojo._base.lang");
1633
 
 
1634
 
// Crockford (ish) functions
1635
 
 
1636
 
dojo.isString = function(/*anything*/ it){
1637
 
        //      summary:
1638
 
        //              Return true if it is a String
1639
 
        return !!arguments.length && it != null && (typeof it == "string" || it instanceof String); // Boolean
1640
 
}
1641
 
 
1642
 
dojo.isArray = function(/*anything*/ it){
1643
 
        //      summary:
1644
 
        //              Return true if it is an Array
1645
 
        return it && (it instanceof Array || typeof it == "array"); // Boolean
1646
 
}
1647
 
 
1648
 
/*=====
1649
 
dojo.isFunction = function(it){
1650
 
        // summary: Return true if it is a Function
1651
 
        // it: anything
1652
 
        return; // Boolean
1653
 
}
1654
 
=====*/
1655
 
 
1656
 
dojo.isFunction = (function(){
1657
 
        var _isFunction = function(/*anything*/ it){
1658
 
                return it && (typeof it == "function" || it instanceof Function); // Boolean
1659
 
        };
1660
 
 
1661
 
        return dojo.isSafari ?
1662
 
                // only slow this down w/ gratuitious casting in Safari since it's what's b0rken
1663
 
                function(/*anything*/ it){
1664
 
                        if(typeof it == "function" && it == "[object NodeList]"){ return false; }
1665
 
                        return _isFunction(it); // Boolean
1666
 
                } : _isFunction;
1667
 
})();
1668
 
 
1669
 
dojo.isObject = function(/*anything*/ it){
1670
 
        // summary: 
1671
 
        //              Returns true if it is a JavaScript object (or an Array, a Function
1672
 
        //              or null)
1673
 
        return it !== undefined &&
1674
 
                (it === null || typeof it == "object" || dojo.isArray(it) || dojo.isFunction(it)); // Boolean
1675
 
}
1676
 
 
1677
 
dojo.isArrayLike = function(/*anything*/ it){
1678
 
        //      summary:
1679
 
        //              similar to dojo.isArray() but more permissive
1680
 
        //      description:
1681
 
        //              Doesn't strongly test for "arrayness".  Instead, settles for "isn't
1682
 
        //              a string or number and has a length property". Arguments objects
1683
 
        //              and DOM collections will return true when passed to
1684
 
        //              dojo.isArrayLike(), but will return false when passed to
1685
 
        //              dojo.isArray().
1686
 
        //      returns:
1687
 
        //              If it walks like a duck and quicks like a duck, return `true`
1688
 
        var d = dojo;
1689
 
        return it && it !== undefined && // Boolean
1690
 
                // keep out built-in constructors (Number, String, ...) which have length
1691
 
                // properties
1692
 
                !d.isString(it) && !d.isFunction(it) &&
1693
 
                !(it.tagName && it.tagName.toLowerCase() == 'form') &&
1694
 
                (d.isArray(it) || isFinite(it.length));
1695
 
}
1696
 
 
1697
 
dojo.isAlien = function(/*anything*/ it){
1698
 
        // summary: 
1699
 
        //              Returns true if it is a built-in function or some other kind of
1700
 
        //              oddball that *should* report as a function but doesn't
1701
 
        return it && !dojo.isFunction(it) && /\{\s*\[native code\]\s*\}/.test(String(it)); // Boolean
1702
 
}
1703
 
 
1704
 
dojo.extend = function(/*Object*/ constructor, /*Object...*/ props){
1705
 
        // summary:
1706
 
        //              Adds all properties and methods of props to constructor's
1707
 
        //              prototype, making them available to all instances created with
1708
 
        //              constructor.
1709
 
        for(var i=1, l=arguments.length; i<l; i++){
1710
 
                dojo._mixin(constructor.prototype, arguments[i]);
1711
 
        }
1712
 
        return constructor; // Object
1713
 
}
1714
 
 
1715
 
dojo._hitchArgs = function(scope, method /*,...*/){
1716
 
        var pre = dojo._toArray(arguments, 2);
1717
 
        var named = dojo.isString(method);
1718
 
        return function(){
1719
 
                // arrayify arguments
1720
 
                var args = dojo._toArray(arguments);
1721
 
                // locate our method
1722
 
                var f = named ? (scope||dojo.global)[method] : method;
1723
 
                // invoke with collected args
1724
 
                return f && f.apply(scope || this, pre.concat(args)); // mixed
1725
 
        } // Function
1726
 
}
1727
 
 
1728
 
dojo.hitch = function(/*Object*/scope, /*Function|String*/method /*,...*/){
1729
 
        //      summary: 
1730
 
        //              Returns a function that will only ever execute in the a given scope. 
1731
 
        //              This allows for easy use of object member functions
1732
 
        //              in callbacks and other places in which the "this" keyword may
1733
 
        //              otherwise not reference the expected scope. 
1734
 
        //              Any number of default positional arguments may be passed as parameters 
1735
 
        //              beyond "method".
1736
 
        //              Each of these values will be used to "placehold" (similar to curry)
1737
 
        //              for the hitched function. 
1738
 
        //      scope: 
1739
 
        //              The scope to use when method executes. If method is a string, 
1740
 
        //              scope is also the object containing method.
1741
 
        //      method:
1742
 
        //              A function to be hitched to scope, or the name of the method in
1743
 
        //              scope to be hitched.
1744
 
        //      example:
1745
 
        //      |       dojo.hitch(foo, "bar")(); 
1746
 
        //              runs foo.bar() in the scope of foo
1747
 
        //      example:
1748
 
        //      |       dojo.hitch(foo, myFunction);
1749
 
        //              returns a function that runs myFunction in the scope of foo
1750
 
        if(arguments.length > 2){
1751
 
                return dojo._hitchArgs.apply(dojo, arguments); // Function
1752
 
        }
1753
 
        if(!method){
1754
 
                method = scope;
1755
 
                scope = null;
1756
 
        }
1757
 
        if(dojo.isString(method)){
1758
 
                scope = scope || dojo.global;
1759
 
                if(!scope[method]){ throw(['dojo.hitch: scope["', method, '"] is null (scope="', scope, '")'].join('')); }
1760
 
                return function(){ return scope[method].apply(scope, arguments || []); }; // Function
1761
 
        }
1762
 
        return !scope ? method : function(){ return method.apply(scope, arguments || []); }; // Function
1763
 
}
1764
 
 
1765
 
/*=====
1766
 
dojo.delegate = function(obj, props){
1767
 
        //      summary:
1768
 
        //              returns a new object which "looks" to obj for properties which it
1769
 
        //              does not have a value for. Optionally takes a bag of properties to
1770
 
        //              seed the returned object with initially. 
1771
 
        //      description:
1772
 
        //              This is a small implementaton of the Boodman/Crockford delegation
1773
 
        //              pattern in JavaScript. An intermediate object constructor mediates
1774
 
        //              the prototype chain for the returned object, using it to delegate
1775
 
        //              down to obj for property lookup when object-local lookup fails.
1776
 
        //              This can be thought of similarly to ES4's "wrap", save that it does
1777
 
        //              not act on types but rather on pure objects.
1778
 
        //      obj:
1779
 
        //              The object to delegate to for properties not found directly on the
1780
 
        //              return object or in props.
1781
 
        //      props:
1782
 
        //              an object containing properties to assign to the returned object
1783
 
        //      returns:
1784
 
        //              an Object of anonymous type
1785
 
        //      example:
1786
 
        //      |       var foo = { bar: "baz" };
1787
 
        //      |       var thinger = dojo.delegate(foo, { thud: "xyzzy"});
1788
 
        //      |       thinger.bar == "baz"; // delegated to foo
1789
 
        //      |       foo.thud == undefined; // by definition
1790
 
        //      |       thinger.thud == "xyzzy"; // mixed in from props
1791
 
        //      |       foo.bar = "thonk";
1792
 
        //      |       thinger.bar == "thonk"; // still delegated to foo's bar
1793
 
}
1794
 
=====*/
1795
 
 
1796
 
dojo.delegate = dojo._delegate = (function(){
1797
 
        // boodman/crockford delegation w/ cornford optimization
1798
 
        function TMP(){};
1799
 
        return function(obj, props){
1800
 
                TMP.prototype = obj;
1801
 
                var tmp = new TMP();
1802
 
                if(props){
1803
 
                        dojo._mixin(tmp, props);
1804
 
                }
1805
 
                return tmp; // Object
1806
 
        }
1807
 
})();
1808
 
 
1809
 
/*=====
1810
 
dojo._toArray = function(obj, offset, startWith){
1811
 
        //      summary:
1812
 
        //              Converts an array-like object (i.e. arguments, DOMCollection) to an
1813
 
        //              array. Returns a new Array with the elements of obj.
1814
 
        //      obj: Object
1815
 
        //              the object to "arrayify". We expect the object to have, at a
1816
 
        //              minimum, a length property which corresponds to integer-indexed
1817
 
        //              properties.
1818
 
        //      offset: Number?
1819
 
        //              the location in obj to start iterating from. Defaults to 0.
1820
 
        //              Optional.
1821
 
        //      startWith: Array?
1822
 
        //              An array to pack with the properties of obj. If provided,
1823
 
        //              properties in obj are appended at the end of startWith and
1824
 
        //              startWith is the returned array.
1825
 
}
1826
 
=====*/
1827
 
 
1828
 
(function(){
1829
 
        var efficient = function(obj, offset, startWith){
1830
 
                return (startWith||[]).concat(Array.prototype.slice.call(obj, offset||0));
1831
 
        };
1832
 
 
1833
 
        var slow = function(obj, offset, startWith){
1834
 
                var arr = startWith||[]; 
1835
 
                for(var x = offset || 0; x < obj.length; x++){ 
1836
 
                        arr.push(obj[x]); 
1837
 
                } 
1838
 
                return arr;
1839
 
        };
1840
 
 
1841
 
        dojo._toArray = (!dojo.isIE) ? efficient : function(obj){
1842
 
                return ((obj.item) ? slow : efficient).apply(this, arguments);
1843
 
        };
1844
 
 
1845
 
})();
1846
 
 
1847
 
dojo.partial = function(/*Function|String*/method /*, ...*/){
1848
 
        //      summary:
1849
 
        //              similar to hitch() except that the scope object is left to be
1850
 
        //              whatever the execution context eventually becomes.
1851
 
        //      description:
1852
 
        //              Calling dojo.partial is the functional equivalent of calling:
1853
 
        //              |       dojo.hitch(null, funcName, ...);
1854
 
        var arr = [ null ];
1855
 
        return dojo.hitch.apply(dojo, arr.concat(dojo._toArray(arguments))); // Function
1856
 
}
1857
 
 
1858
 
dojo.clone = function(/*anything*/ o){
1859
 
        // summary:
1860
 
        //              Clones objects (including DOM nodes) and all children.
1861
 
        //              Warning: do not clone cyclic structures.
1862
 
        if(!o){ return o; }
1863
 
        if(dojo.isArray(o)){
1864
 
                var r = [];
1865
 
                for(var i = 0; i < o.length; ++i){
1866
 
                        r.push(dojo.clone(o[i]));
1867
 
                }
1868
 
                return r; // Array
1869
 
        }
1870
 
        if(!dojo.isObject(o)){
1871
 
                return o;       /*anything*/
1872
 
        }
1873
 
        if(o.nodeType && o.cloneNode){ // isNode
1874
 
                return o.cloneNode(true); // Node
1875
 
        }
1876
 
        if(o instanceof Date){
1877
 
                return new Date(o.getTime());   // Date
1878
 
        }
1879
 
        // Generic objects
1880
 
        var r = new o.constructor(); // specific to dojo.declare()'d classes!
1881
 
        for(var i in o){
1882
 
                if(!(i in r) || r[i] != o[i]){
1883
 
                        r[i] = dojo.clone(o[i]);
1884
 
                }
1885
 
        }
1886
 
        return r; // Object
1887
 
}
1888
 
 
1889
 
dojo.trim = function(/*String*/ str){
1890
 
        // summary: 
1891
 
        //              trims whitespaces from both sides of the string
1892
 
        // description:
1893
 
        //              This version of trim() was selected for inclusion into the base due
1894
 
        //              to its compact size and relatively good performance (see Steven
1895
 
        //              Levithan's blog:
1896
 
        //              http://blog.stevenlevithan.com/archives/faster-trim-javascript).
1897
 
        //              The fastest but longest version of this function is located at
1898
 
        //              dojo.string.trim()
1899
 
        return str.replace(/^\s\s*/, '').replace(/\s\s*$/, ''); // String
1900
 
}
1901
 
 
1902
 
}
1903
 
 
1904
 
if(!dojo._hasResource["dojo._base.declare"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
1905
 
dojo._hasResource["dojo._base.declare"] = true;
1906
 
dojo.provide("dojo._base.declare");
1907
 
 
1908
 
 
1909
 
// this file courtesy of the TurboAjax Group, licensed under a Dojo CLA
1910
 
 
1911
 
dojo.declare = function(/*String*/ className, /*Function|Function[]*/ superclass, /*Object*/ props){
1912
 
        //      summary: 
1913
 
        //              Create a feature-rich constructor from compact notation
1914
 
        //      className:
1915
 
        //              The name of the constructor (loosely, a "class")
1916
 
        //              stored in the "declaredClass" property in the created prototype
1917
 
        //      superclass:
1918
 
        //              May be null, a Function, or an Array of Functions. If an array, 
1919
 
        //              the first element is used as the prototypical ancestor and
1920
 
        //              any following Functions become mixin ancestors.
1921
 
        //      props:
1922
 
        //              An object whose properties are copied to the
1923
 
        //              created prototype.
1924
 
        //              Add an instance-initialization function by making it a property 
1925
 
        //              named "constructor".
1926
 
        //      description:
1927
 
        //              Create a constructor using a compact notation for inheritance and
1928
 
        //              prototype extension. 
1929
 
        //
1930
 
        //              All superclasses (including mixins) must be Functions (not simple Objects).
1931
 
        //
1932
 
        //              Mixin ancestors provide a type of multiple inheritance. Prototypes of mixin 
1933
 
        //              ancestors are copied to the new class: changes to mixin prototypes will
1934
 
        //              not affect classes to which they have been mixed in.
1935
 
        //
1936
 
        //              "className" is cached in "declaredClass" property of the new class.
1937
 
        //
1938
 
        //      example:
1939
 
        //      |       dojo.declare("my.classes.bar", my.classes.foo, {
1940
 
        //      |               // properties to be added to the class prototype
1941
 
        //      |               someValue: 2,
1942
 
        //      |               // initialization function
1943
 
        //      |               constructor: function(){
1944
 
        //      |                       this.myComplicatedObject = new ReallyComplicatedObject(); 
1945
 
        //      |               },
1946
 
        //      |               // other functions
1947
 
        //      |               someMethod: function(){ 
1948
 
        //      |                       doStuff(); 
1949
 
        //      |               }
1950
 
        //      |       );
1951
 
 
1952
 
        // process superclass argument
1953
 
        var dd = arguments.callee, mixins;
1954
 
        if(dojo.isArray(superclass)){
1955
 
                mixins = superclass;
1956
 
                superclass = mixins.shift();
1957
 
        }
1958
 
        // construct intermediate classes for mixins
1959
 
        if(mixins){
1960
 
                dojo.forEach(mixins, function(m){
1961
 
                        if(!m){ throw(className + ": mixin #" + i + " is null"); } // It's likely a required module is not loaded
1962
 
                        superclass = dd._delegate(superclass, m);
1963
 
                });
1964
 
        }
1965
 
        // create constructor
1966
 
        var ctor = dd._delegate(superclass);
1967
 
        // extend with "props"
1968
 
        props = props || {};
1969
 
        ctor.extend(props);
1970
 
        // more prototype decoration
1971
 
        dojo.extend(ctor, {declaredClass: className, _constructor: props.constructor/*, preamble: null*/});
1972
 
        // special help for IE
1973
 
        ctor.prototype.constructor = ctor;
1974
 
        // create named reference
1975
 
        return dojo.setObject(className, ctor); // Function
1976
 
};
1977
 
 
1978
 
dojo.mixin(dojo.declare, {
1979
 
        _delegate: function(base, mixin){
1980
 
                var bp = (base||0).prototype, mp = (mixin||0).prototype, dd=dojo.declare;
1981
 
                // fresh constructor, fresh prototype
1982
 
                var ctor = dd._makeCtor();
1983
 
                // cache ancestry
1984
 
                dojo.mixin(ctor, {superclass: bp, mixin: mp, extend: dd._extend});
1985
 
                // chain prototypes
1986
 
                if(base){ctor.prototype = dojo._delegate(bp);}
1987
 
                // add mixin and core
1988
 
                dojo.extend(ctor, dd._core, mp||0, {_constructor: null, preamble: null});
1989
 
                // special help for IE
1990
 
                ctor.prototype.constructor = ctor;
1991
 
                // name this class for debugging
1992
 
                ctor.prototype.declaredClass = (bp||0).declaredClass + '_' + (mp||0).declaredClass;
1993
 
                return ctor;
1994
 
        },
1995
 
        _extend: function(props){
1996
 
                var i, fn;
1997
 
                for(i in props){ if(dojo.isFunction(fn=props[i]) && !0[i]){fn.nom=i;fn.ctor=this;} }
1998
 
                dojo.extend(this, props);
1999
 
        },
2000
 
        _makeCtor: function(){
2001
 
                // we have to make a function, but don't want to close over anything
2002
 
                return function(){ this._construct(arguments); };
2003
 
        },
2004
 
        _core: { 
2005
 
                _construct: function(args){
2006
 
                        var c=args.callee, s=c.superclass, ct=s&&s.constructor, m=c.mixin, mct=m&&m.constructor, a=args, ii, fn;
2007
 
                        // side-effect of = used on purpose here, lint may complain, don't try this at home
2008
 
                        if(a[0]){ 
2009
 
                                // FIXME: preambles for each mixin should be allowed
2010
 
                                // FIXME: 
2011
 
                                //              should we allow the preamble here NOT to modify the
2012
 
                                //              default args, but instead to act on each mixin
2013
 
                                //              independently of the class instance being constructed
2014
 
                                //              (for impedence matching)?
2015
 
 
2016
 
                                // allow any first argument w/ a "preamble" property to act as a
2017
 
                                // class preamble (not exclusive of the prototype preamble)
2018
 
                                if(/*dojo.isFunction*/((fn = a[0].preamble))){ 
2019
 
                                        a = fn.apply(this, a) || a; 
2020
 
                                }
2021
 
                        } 
2022
 
                        // prototype preamble
2023
 
                        if((fn = c.prototype.preamble)){a = fn.apply(this, a) || a;}
2024
 
                        // FIXME: 
2025
 
                        //              need to provide an optional prototype-settable
2026
 
                        //              "_explicitSuper" property which disables this
2027
 
                        // initialize superclass
2028
 
                        if(ct&&ct.apply){ct.apply(this, a);}
2029
 
                        // initialize mixin
2030
 
                        if(mct&&mct.apply){mct.apply(this, a);}
2031
 
                        // initialize self
2032
 
                        if((ii=c.prototype._constructor)){ii.apply(this, args);}
2033
 
                        // post construction
2034
 
                        if(this.constructor.prototype==c.prototype && (ct=this.postscript)){ ct.apply(this, args); }
2035
 
                },
2036
 
                _findMixin: function(mixin){
2037
 
                        var c = this.constructor, p, m;
2038
 
                        while(c){
2039
 
                                p = c.superclass;
2040
 
                                m = c.mixin;
2041
 
                                if(m==mixin || (m instanceof mixin.constructor)){return p;}
2042
 
                                if(m && m._findMixin && (m=m._findMixin(mixin))){return m;}
2043
 
                                c = p && p.constructor;
2044
 
                        }
2045
 
                },
2046
 
                _findMethod: function(name, method, ptype, has){
2047
 
                        // consciously trading readability for bytes and speed in this low-level method
2048
 
                        var p=ptype, c, m, f;
2049
 
                        do{
2050
 
                                c = p.constructor;
2051
 
                                m = c.mixin;
2052
 
                                // find method by name in our mixin ancestor
2053
 
                                if(m && (m=this._findMethod(name, method, m, has))){return m;}
2054
 
                                // if we found a named method that either exactly-is or exactly-is-not 'method'
2055
 
                                if((f=p[name])&&(has==(f==method))){return p;}
2056
 
                                // ascend chain
2057
 
                                p = c.superclass;
2058
 
                        }while(p);
2059
 
                        // if we couldn't find an ancestor in our primary chain, try a mixin chain
2060
 
                        return !has && (p=this._findMixin(ptype)) && this._findMethod(name, method, p, has);
2061
 
                },
2062
 
                inherited: function(name, args, newArgs){
2063
 
                        // optionalize name argument
2064
 
                        var a = arguments;
2065
 
                        if(!dojo.isString(a[0])){newArgs=args; args=name; name=args.callee.nom;}
2066
 
                        a = newArgs||args;
2067
 
                        var c = args.callee, p = this.constructor.prototype, fn, mp;
2068
 
                        // if not an instance override
2069
 
                        if(this[name] != c || p[name] == c){
2070
 
                                // start from memoized prototype, or
2071
 
                                // find a prototype that has property 'name' == 'c'
2072
 
                                mp = (c.ctor||0).superclass || this._findMethod(name, c, p, true);
2073
 
                                if(!mp){throw(this.declaredClass + ': inherited method "' + name + '" mismatch');}
2074
 
                                // find a prototype that has property 'name' != 'c'
2075
 
                                p = this._findMethod(name, c, mp, false);
2076
 
                        }
2077
 
                        // we expect 'name' to be in prototype 'p'
2078
 
                        fn = p && p[name];
2079
 
                        if(!fn){throw(mp.declaredClass + ': inherited method "' + name + '" not found');}
2080
 
                        // if the function exists, invoke it in our scope
2081
 
                        return fn.apply(this, a);
2082
 
                }
2083
 
        }
2084
 
});
2085
 
 
2086
 
}
2087
 
 
2088
 
if(!dojo._hasResource["dojo._base.connect"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
2089
 
dojo._hasResource["dojo._base.connect"] = true;
2090
 
dojo.provide("dojo._base.connect");
2091
 
 
2092
 
 
2093
 
// this file courtesy of the TurboAjax Group, licensed under a Dojo CLA
2094
 
 
2095
 
// low-level delegation machinery
2096
 
dojo._listener = {
2097
 
        // create a dispatcher function
2098
 
        getDispatcher: function(){
2099
 
                // following comments pulled out-of-line to prevent cloning them 
2100
 
                // in the returned function.
2101
 
                // - indices (i) that are really in the array of listeners (ls) will 
2102
 
                //   not be in Array.prototype. This is the 'sparse array' trick
2103
 
                //   that keeps us safe from libs that take liberties with built-in 
2104
 
                //   objects
2105
 
                // - listener is invoked with current scope (this)
2106
 
                return function(){
2107
 
                        var ap=Array.prototype, c=arguments.callee, ls=c._listeners, t=c.target;
2108
 
                        // return value comes from original target function
2109
 
                        var r = t && t.apply(this, arguments);
2110
 
                        // make local copy of listener array so it is immutable during processing
2111
 
                        var lls;
2112
 
                                                                                        lls = [].concat(ls);
2113
 
                                                        
2114
 
                        // invoke listeners after target function
2115
 
                        for(var i in lls){
2116
 
                                if(!(i in ap)){
2117
 
                                        lls[i].apply(this, arguments);
2118
 
                                }
2119
 
                        }
2120
 
                        // return value comes from original target function
2121
 
                        return r;
2122
 
                }
2123
 
        },
2124
 
        // add a listener to an object
2125
 
        add: function(/*Object*/ source, /*String*/ method, /*Function*/ listener){
2126
 
                // Whenever 'method' is invoked, 'listener' will have the same scope.
2127
 
                // Trying to supporting a context object for the listener led to 
2128
 
                // complexity. 
2129
 
                // Non trivial to provide 'once' functionality here
2130
 
                // because listener could be the result of a dojo.hitch call,
2131
 
                // in which case two references to the same hitch target would not
2132
 
                // be equivalent. 
2133
 
                source = source || dojo.global;
2134
 
                // The source method is either null, a dispatcher, or some other function
2135
 
                var f = source[method];
2136
 
                // Ensure a dispatcher
2137
 
                if(!f||!f._listeners){
2138
 
                        var d = dojo._listener.getDispatcher();
2139
 
                        // original target function is special
2140
 
                        d.target = f;
2141
 
                        // dispatcher holds a list of listeners
2142
 
                        d._listeners = []; 
2143
 
                        // redirect source to dispatcher
2144
 
                        f = source[method] = d;
2145
 
                }
2146
 
                // The contract is that a handle is returned that can 
2147
 
                // identify this listener for disconnect. 
2148
 
                //
2149
 
                // The type of the handle is private. Here is it implemented as Integer. 
2150
 
                // DOM event code has this same contract but handle is Function 
2151
 
                // in non-IE browsers.
2152
 
                //
2153
 
                // We could have separate lists of before and after listeners.
2154
 
                return f._listeners.push(listener) ; /*Handle*/
2155
 
        },
2156
 
        // remove a listener from an object
2157
 
        remove: function(/*Object*/ source, /*String*/ method, /*Handle*/ handle){
2158
 
                var f = (source||dojo.global)[method];
2159
 
                // remember that handle is the index+1 (0 is not a valid handle)
2160
 
                if(f && f._listeners && handle--){
2161
 
                        delete f._listeners[handle];
2162
 
                }
2163
 
        }
2164
 
};
2165
 
 
2166
 
// Multiple delegation for arbitrary methods.
2167
 
 
2168
 
// This unit knows nothing about DOM, 
2169
 
// but we include DOM aware 
2170
 
// documentation and dontFix
2171
 
// argument here to help the autodocs.
2172
 
// Actual DOM aware code is in event.js.
2173
 
 
2174
 
dojo.connect = function(/*Object|null*/ obj, 
2175
 
                                                /*String*/ event, 
2176
 
                                                /*Object|null*/ context, 
2177
 
                                                /*String|Function*/ method,
2178
 
                                                /*Boolean*/ dontFix){
2179
 
        // summary:
2180
 
        //              Create a link that calls one function when another executes. 
2181
 
        //
2182
 
        // description:
2183
 
        //              Connects method to event, so that after event fires, method
2184
 
        //              does too. All connected functions are passed the same arguments as
2185
 
        //              the event function was initially called with. You may connect as
2186
 
        //              many methods to event as needed.
2187
 
        //
2188
 
        //              event must be a string. If obj is null, dojo.global is used.
2189
 
        //
2190
 
        //              null arguments may simply be omitted.
2191
 
        //
2192
 
        //              obj[event] can resolve to a function or undefined (null). 
2193
 
        //              If obj[event] is null, it is assigned a function.
2194
 
        //
2195
 
        //              The return value is a handle that is needed to 
2196
 
        //              remove this connection with dojo.disconnect.
2197
 
        //
2198
 
        // obj: 
2199
 
        //              The source object for the event function. 
2200
 
        //              Defaults to dojo.global if null.
2201
 
        //              If obj is a DOM node, the connection is delegated 
2202
 
        //              to the DOM event manager (unless dontFix is true).
2203
 
        //
2204
 
        // event:
2205
 
        //              String name of the event function in obj. 
2206
 
        //              I.e. identifies a property obj[event].
2207
 
        //
2208
 
        // context: 
2209
 
        //              The object that method will receive as "this".
2210
 
        //
2211
 
        //              If context is null and method is a function, then method
2212
 
        //              inherits the context of event.
2213
 
        //      
2214
 
        //              If method is a string then context must be the source 
2215
 
        //              object object for method (context[method]). If context is null,
2216
 
        //              dojo.global is used.
2217
 
        //
2218
 
        // method:
2219
 
        //              A function reference, or name of a function in context. 
2220
 
        //              The function identified by method fires after event does. 
2221
 
        //              method receives the same arguments as the event.
2222
 
        //              See context argument comments for information on method's scope.
2223
 
        //
2224
 
        // dontFix:
2225
 
        //              If obj is a DOM node, set dontFix to true to prevent delegation 
2226
 
        //              of this connection to the DOM event manager. 
2227
 
        //
2228
 
        // example:
2229
 
        //              When obj.onchange(), do ui.update():
2230
 
        //      |       dojo.connect(obj, "onchange", ui, "update");
2231
 
        //      |       dojo.connect(obj, "onchange", ui, ui.update); // same
2232
 
        //
2233
 
        // example:
2234
 
        //              Using return value for disconnect:
2235
 
        //      |       var link = dojo.connect(obj, "onchange", ui, "update");
2236
 
        //      |       ...
2237
 
        //      |       dojo.disconnect(link);
2238
 
        //
2239
 
        // example:
2240
 
        //              When onglobalevent executes, watcher.handler is invoked:
2241
 
        //      |       dojo.connect(null, "onglobalevent", watcher, "handler");
2242
 
        //
2243
 
        // example:
2244
 
        //              When ob.onCustomEvent executes, customEventHandler is invoked:
2245
 
        //      |       dojo.connect(ob, "onCustomEvent", null, "customEventHandler");
2246
 
        //      |       dojo.connect(ob, "onCustomEvent", "customEventHandler"); // same
2247
 
        //
2248
 
        // example:
2249
 
        //              When ob.onCustomEvent executes, customEventHandler is invoked
2250
 
        //              with the same scope (this):
2251
 
        //      |       dojo.connect(ob, "onCustomEvent", null, customEventHandler);
2252
 
        //      |       dojo.connect(ob, "onCustomEvent", customEventHandler); // same
2253
 
        //
2254
 
        // example:
2255
 
        //              When globalEvent executes, globalHandler is invoked
2256
 
        //              with the same scope (this):
2257
 
        //      |       dojo.connect(null, "globalEvent", null, globalHandler);
2258
 
        //      |       dojo.connect("globalEvent", globalHandler); // same
2259
 
 
2260
 
        // normalize arguments
2261
 
        var a=arguments, args=[], i=0;
2262
 
        // if a[0] is a String, obj was ommited
2263
 
        args.push(dojo.isString(a[0]) ? null : a[i++], a[i++]);
2264
 
        // if the arg-after-next is a String or Function, context was NOT omitted
2265
 
        var a1 = a[i+1];
2266
 
        args.push(dojo.isString(a1)||dojo.isFunction(a1) ? a[i++] : null, a[i++]);
2267
 
        // absorb any additional arguments
2268
 
        for(var l=a.length; i<l; i++){  args.push(a[i]); }
2269
 
        // do the actual work
2270
 
        return dojo._connect.apply(this, args); /*Handle*/
2271
 
}
2272
 
 
2273
 
// used by non-browser hostenvs. always overriden by event.js
2274
 
dojo._connect = function(obj, event, context, method){
2275
 
        var l=dojo._listener, h=l.add(obj, event, dojo.hitch(context, method)); 
2276
 
        return [obj, event, h, l]; // Handle
2277
 
}
2278
 
 
2279
 
dojo.disconnect = function(/*Handle*/ handle){
2280
 
        // summary:
2281
 
        //              Remove a link created by dojo.connect.
2282
 
        // description:
2283
 
        //              Removes the connection between event and the method referenced by handle.
2284
 
        // handle:
2285
 
        //              the return value of the dojo.connect call that created the connection.
2286
 
        if(handle && handle[0] !== undefined){
2287
 
                dojo._disconnect.apply(this, handle);
2288
 
                // let's not keep this reference
2289
 
                delete handle[0];
2290
 
        }
2291
 
}
2292
 
 
2293
 
dojo._disconnect = function(obj, event, handle, listener){
2294
 
        listener.remove(obj, event, handle);
2295
 
}
2296
 
 
2297
 
// topic publish/subscribe
2298
 
 
2299
 
dojo._topics = {};
2300
 
 
2301
 
dojo.subscribe = function(/*String*/ topic, /*Object|null*/ context, /*String|Function*/ method){
2302
 
        //      summary:
2303
 
        //              Attach a listener to a named topic. The listener function is invoked whenever the
2304
 
        //              named topic is published (see: dojo.publish).
2305
 
        //              Returns a handle which is needed to unsubscribe this listener.
2306
 
        //      context:
2307
 
        //              Scope in which method will be invoked, or null for default scope.
2308
 
        //      method:
2309
 
        //              The name of a function in context, or a function reference. This is the function that
2310
 
        //              is invoked when topic is published.
2311
 
        //      example:
2312
 
        //      |       dojo.subscribe("alerts", null, function(caption, message){ alert(caption + "\n" + message); };
2313
 
        //      |       dojo.publish("alerts", [ "read this", "hello world" ]);                                                                                                                                 
2314
 
 
2315
 
        // support for 2 argument invocation (omitting context) depends on hitch
2316
 
        return [topic, dojo._listener.add(dojo._topics, topic, dojo.hitch(context, method))]; /*Handle*/
2317
 
}
2318
 
 
2319
 
dojo.unsubscribe = function(/*Handle*/ handle){
2320
 
        //      summary:
2321
 
        //              Remove a topic listener. 
2322
 
        //      handle:
2323
 
        //              The handle returned from a call to subscribe.
2324
 
        //      example:
2325
 
        //      |       var alerter = dojo.subscribe("alerts", null, function(caption, message){ alert(caption + "\n" + message); };
2326
 
        //      |       ...
2327
 
        //      |       dojo.unsubscribe(alerter);
2328
 
        if(handle){
2329
 
                dojo._listener.remove(dojo._topics, handle[0], handle[1]);
2330
 
        }
2331
 
}
2332
 
 
2333
 
dojo.publish = function(/*String*/ topic, /*Array*/ args){
2334
 
        //      summary:
2335
 
        //              Invoke all listener method subscribed to topic.
2336
 
        //      topic:
2337
 
        //              The name of the topic to publish.
2338
 
        //      args:
2339
 
        //              An array of arguments. The arguments will be applied 
2340
 
        //              to each topic subscriber (as first class parameters, via apply).
2341
 
        //      example:
2342
 
        //      |       dojo.subscribe("alerts", null, function(caption, message){ alert(caption + "\n" + message); };
2343
 
        //      |       dojo.publish("alerts", [ "read this", "hello world" ]); 
2344
 
 
2345
 
        // Note that args is an array, which is more efficient vs variable length
2346
 
        // argument list.  Ideally, var args would be implemented via Array
2347
 
        // throughout the APIs.
2348
 
        var f = dojo._topics[topic];
2349
 
        if(f){
2350
 
                f.apply(this, args||[]);
2351
 
        }
2352
 
}
2353
 
 
2354
 
dojo.connectPublisher = function(       /*String*/ topic, 
2355
 
                                                                        /*Object|null*/ obj, 
2356
 
                                                                        /*String*/ event){
2357
 
        //      summary:
2358
 
        //              Ensure that everytime obj.event() is called, a message is published
2359
 
        //              on the topic. Returns a handle which can be passed to
2360
 
        //              dojo.disconnect() to disable subsequent automatic publication on
2361
 
        //              the topic.
2362
 
        //      topic:
2363
 
        //              The name of the topic to publish.
2364
 
        //      obj: 
2365
 
        //              The source object for the event function. Defaults to dojo.global
2366
 
        //              if null.
2367
 
        //      event:
2368
 
        //              The name of the event function in obj. 
2369
 
        //              I.e. identifies a property obj[event].
2370
 
        //      example:
2371
 
        //      |       dojo.connectPublisher("/ajax/start", dojo, "xhrGet");
2372
 
        var pf = function(){ dojo.publish(topic, arguments); }
2373
 
        return (event) ? dojo.connect(obj, event, pf) : dojo.connect(obj, pf); //Handle
2374
 
};
2375
 
 
2376
 
}
2377
 
 
2378
 
if(!dojo._hasResource["dojo._base.Deferred"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
2379
 
dojo._hasResource["dojo._base.Deferred"] = true;
2380
 
dojo.provide("dojo._base.Deferred");
2381
 
 
2382
 
 
2383
 
dojo.Deferred = function(/*Function?*/ canceller){
2384
 
        // summary:
2385
 
        //              Encapsulates a sequence of callbacks in response to a value that
2386
 
        //              may not yet be available.  This is modeled after the Deferred class
2387
 
        //              from Twisted <http://twistedmatrix.com>.
2388
 
        // description:
2389
 
        //              JavaScript has no threads, and even if it did, threads are hard.
2390
 
        //              Deferreds are a way of abstracting non-blocking events, such as the
2391
 
        //              final response to an XMLHttpRequest. Deferreds create a promise to
2392
 
        //              return a response a some point in the future and an easy way to
2393
 
        //              register your interest in receiving that response.
2394
 
        //
2395
 
        //              The most important methods for Deffered users are:
2396
 
        //
2397
 
        //                      * addCallback(handler)
2398
 
        //                      * addErrback(handler)
2399
 
        //                      * callback(result)
2400
 
        //                      * errback(result)
2401
 
        //
2402
 
        //              In general, when a function returns a Deferred, users then "fill
2403
 
        //              in" the second half of the contract by registering callbacks and
2404
 
        //              error handlers. You may register as many callback and errback
2405
 
        //              handlers as you like and they will be executed in the order
2406
 
        //              registered when a result is provided. Usually this result is
2407
 
        //              provided as the result of an asynchronous operation. The code
2408
 
        //              "managing" the Deferred (the code that made the promise to provide
2409
 
        //              an answer later) will use the callback() and errback() methods to
2410
 
        //              communicate with registered listeners about the result of the
2411
 
        //              operation. At this time, all registered result handlers are called
2412
 
        //              *with the most recent result value*.
2413
 
        //
2414
 
        //              Deferred callback handlers are treated as a chain, and each item in
2415
 
        //              the chain is required to return a value that will be fed into
2416
 
        //              successive handlers. The most minimal callback may be registered
2417
 
        //              like this:
2418
 
        //
2419
 
        //              |       var d = new dojo.Deferred();
2420
 
        //              |       d.addCallback(function(result){ return result; });
2421
 
        //
2422
 
        //              Perhaps the most common mistake when first using Deferreds is to
2423
 
        //              forget to return a value (in most cases, the value you were
2424
 
        //              passed).
2425
 
        //
2426
 
        //              The sequence of callbacks is internally represented as a list of
2427
 
        //              2-tuples containing the callback/errback pair.  For example, the
2428
 
        //              following call sequence:
2429
 
        //              
2430
 
        //              |       var d = new dojo.Deferred();
2431
 
        //              |       d.addCallback(myCallback);
2432
 
        //              |       d.addErrback(myErrback);
2433
 
        //              |       d.addBoth(myBoth);
2434
 
        //              |       d.addCallbacks(myCallback, myErrback);
2435
 
        //
2436
 
        //              is translated into a Deferred with the following internal
2437
 
        //              representation:
2438
 
        //
2439
 
        //              |       [
2440
 
        //              |               [myCallback, null],
2441
 
        //              |               [null, myErrback],
2442
 
        //              |               [myBoth, myBoth],
2443
 
        //              |               [myCallback, myErrback]
2444
 
        //              |       ]
2445
 
        //
2446
 
        //              The Deferred also keeps track of its current status (fired).  Its
2447
 
        //              status may be one of three things:
2448
 
        //
2449
 
        //                      * -1: no value yet (initial condition)
2450
 
        //                      * 0: success
2451
 
        //                      * 1: error
2452
 
        //      
2453
 
        //              A Deferred will be in the error state if one of the following three
2454
 
        //              conditions are met:
2455
 
        //
2456
 
        //                      1. The result given to callback or errback is "instanceof" Error
2457
 
        //                      2. The previous callback or errback raised an exception while
2458
 
        //                         executing
2459
 
        //                      3. The previous callback or errback returned a value
2460
 
        //                         "instanceof" Error
2461
 
        //
2462
 
        //              Otherwise, the Deferred will be in the success state. The state of
2463
 
        //              the Deferred determines the next element in the callback sequence
2464
 
        //              to run.
2465
 
        //
2466
 
        //              When a callback or errback occurs with the example deferred chain,
2467
 
        //              something equivalent to the following will happen (imagine
2468
 
        //              that exceptions are caught and returned):
2469
 
        //
2470
 
        //              |       // d.callback(result) or d.errback(result)
2471
 
        //              |       if(!(result instanceof Error)){
2472
 
        //              |               result = myCallback(result);
2473
 
        //              |       }
2474
 
        //              |       if(result instanceof Error){
2475
 
        //              |               result = myErrback(result);
2476
 
        //              |       }
2477
 
        //              |       result = myBoth(result);
2478
 
        //              |       if(result instanceof Error){
2479
 
        //              |               result = myErrback(result);
2480
 
        //              |       }else{
2481
 
        //              |               result = myCallback(result);
2482
 
        //              |       }
2483
 
        //
2484
 
        //              The result is then stored away in case another step is added to the
2485
 
        //              callback sequence.      Since the Deferred already has a value
2486
 
        //              available, any new callbacks added will be called immediately.
2487
 
        //
2488
 
        //              There are two other "advanced" details about this implementation
2489
 
        //              that are useful:
2490
 
        //
2491
 
        //              Callbacks are allowed to return Deferred instances themselves, so
2492
 
        //              you can build complicated sequences of events with ease.
2493
 
        //
2494
 
        //              The creator of the Deferred may specify a canceller.  The canceller
2495
 
        //              is a function that will be called if Deferred.cancel is called
2496
 
        //              before the Deferred fires. You can use this to implement clean
2497
 
        //              aborting of an XMLHttpRequest, etc. Note that cancel will fire the
2498
 
        //              deferred with a CancelledError (unless your canceller returns
2499
 
        //              another kind of error), so the errbacks should be prepared to
2500
 
        //              handle that error for cancellable Deferreds.
2501
 
        // example:
2502
 
        //      |       var deferred = new dojo.Deferred();
2503
 
        //      |       setTimeout(function(){ deferred.callback({success: true}); }, 1000);
2504
 
        //      |       return deferred;
2505
 
        // example:
2506
 
        //              Deferred objects are often used when making code asynchronous. It
2507
 
        //              may be easiest to write functions in a synchronous manner and then
2508
 
        //              split code using a deferred to trigger a response to a long-lived
2509
 
        //              operation. For example, instead of register a callback function to
2510
 
        //              denote when a rendering operation completes, the function can
2511
 
        //              simply return a deferred:
2512
 
        //
2513
 
        //              |       // callback style:
2514
 
        //              |       function renderLotsOfData(data, callback){
2515
 
        //              |               var success = false
2516
 
        //              |               try{
2517
 
        //              |                       for(var x in data){
2518
 
        //              |                               renderDataitem(data[x]);
2519
 
        //              |                       }
2520
 
        //              |                       success = true;
2521
 
        //              |               }catch(e){ }
2522
 
        //              |               if(callback){
2523
 
        //              |                       callback(success);
2524
 
        //              |               }
2525
 
        //              |       }
2526
 
        //
2527
 
        //              |       // using callback style
2528
 
        //              |       renderLotsOfData(someDataObj, function(success){
2529
 
        //              |               // handles success or failure
2530
 
        //              |               if(!success){
2531
 
        //              |                       promptUserToRecover();
2532
 
        //              |               }
2533
 
        //              |       });
2534
 
        //              |       // NOTE: no way to add another callback here!!
2535
 
        // example:
2536
 
        //              Using a Deferred doesn't simplify the sending code any, but it
2537
 
        //              provides a standard interface for callers and senders alike,
2538
 
        //              providing both with a simple way to service multiple callbacks for
2539
 
        //              an operation and freeing both sides from worrying about details
2540
 
        //              such as "did this get called already?". With Deferreds, new
2541
 
        //              callbacks can be added at any time.
2542
 
        //
2543
 
        //              |       // Deferred style:
2544
 
        //              |       function renderLotsOfData(data){
2545
 
        //              |               var d = new dojo.Deferred();
2546
 
        //              |               try{
2547
 
        //              |                       for(var x in data){
2548
 
        //              |                               renderDataitem(data[x]);
2549
 
        //              |                       }
2550
 
        //              |                       d.callback(true);
2551
 
        //              |               }catch(e){ 
2552
 
        //              |                       d.errback(new Error("rendering failed"));
2553
 
        //              |               }
2554
 
        //              |               return d;
2555
 
        //              |       }
2556
 
        //
2557
 
        //              |       // using Deferred style
2558
 
        //              |       renderLotsOfData(someDataObj).addErrback(function(){
2559
 
        //              |               promptUserToRecover();
2560
 
        //              |       });
2561
 
        //              |       // NOTE: addErrback and addCallback both return the Deferred
2562
 
        //              |       // again, so we could chain adding callbacks or save the
2563
 
        //              |       // deferred for later should we need to be notified again.
2564
 
        // example:
2565
 
        //              In this example, renderLotsOfData is syncrhonous and so both
2566
 
        //              versions are pretty artificial. Putting the data display on a
2567
 
        //              timeout helps show why Deferreds rock:
2568
 
        //
2569
 
        //              |       // Deferred style and async func
2570
 
        //              |       function renderLotsOfData(data){
2571
 
        //              |               var d = new dojo.Deferred();
2572
 
        //              |               setTimeout(function(){
2573
 
        //              |                       try{
2574
 
        //              |                               for(var x in data){
2575
 
        //              |                                       renderDataitem(data[x]);
2576
 
        //              |                               }
2577
 
        //              |                               d.callback(true);
2578
 
        //              |                       }catch(e){ 
2579
 
        //              |                               d.errback(new Error("rendering failed"));
2580
 
        //              |                       }
2581
 
        //              |               }, 100);
2582
 
        //              |               return d;
2583
 
        //              |       }
2584
 
        //
2585
 
        //              |       // using Deferred style
2586
 
        //              |       renderLotsOfData(someDataObj).addErrback(function(){
2587
 
        //              |               promptUserToRecover();
2588
 
        //              |       });
2589
 
        //
2590
 
        //              Note that the caller doesn't have to change his code at all to
2591
 
        //              handle the asynchronous case.
2592
 
 
2593
 
        this.chain = [];
2594
 
        this.id = this._nextId();
2595
 
        this.fired = -1;
2596
 
        this.paused = 0;
2597
 
        this.results = [null, null];
2598
 
        this.canceller = canceller;
2599
 
        this.silentlyCancelled = false;
2600
 
};
2601
 
 
2602
 
dojo.extend(dojo.Deferred, {
2603
 
        /*
2604
 
        makeCalled: function(){
2605
 
                // summary:
2606
 
                //              returns a new, empty deferred, which is already in the called
2607
 
                //              state. Calling callback() or errback() on this deferred will
2608
 
                //              yeild an error and adding new handlers to it will result in
2609
 
                //              them being called immediately.
2610
 
                var deferred = new dojo.Deferred();
2611
 
                deferred.callback();
2612
 
                return deferred;
2613
 
        },
2614
 
 
2615
 
        toString: function(){
2616
 
                var state;
2617
 
                if(this.fired == -1){
2618
 
                        state = 'unfired';
2619
 
                }else{
2620
 
                        state = this.fired ? 'success' : 'error';
2621
 
                }
2622
 
                return 'Deferred(' + this.id + ', ' + state + ')';
2623
 
        },
2624
 
        */
2625
 
 
2626
 
        _nextId: (function(){
2627
 
                var n = 1;
2628
 
                return function(){ return n++; };
2629
 
        })(),
2630
 
 
2631
 
        cancel: function(){
2632
 
                // summary:     
2633
 
                //              Cancels a Deferred that has not yet received a value, or is
2634
 
                //              waiting on another Deferred as its value.
2635
 
                // description:
2636
 
                //              If a canceller is defined, the canceller is called. If the
2637
 
                //              canceller did not return an error, or there was no canceller,
2638
 
                //              then the errback chain is started.
2639
 
                var err;
2640
 
                if(this.fired == -1){
2641
 
                        if(this.canceller){
2642
 
                                err = this.canceller(this);
2643
 
                        }else{
2644
 
                                this.silentlyCancelled = true;
2645
 
                        }
2646
 
                        if(this.fired == -1){
2647
 
                                if(!(err instanceof Error)){
2648
 
                                        var res = err;
2649
 
                                        err = new Error("Deferred Cancelled");
2650
 
                                        err.dojoType = "cancel";
2651
 
                                        err.cancelResult = res;
2652
 
                                }
2653
 
                                this.errback(err);
2654
 
                        }
2655
 
                }else if(       (this.fired == 0) &&
2656
 
                                        (this.results[0] instanceof dojo.Deferred)
2657
 
                ){
2658
 
                        this.results[0].cancel();
2659
 
                }
2660
 
        },
2661
 
                        
2662
 
 
2663
 
        _resback: function(res){
2664
 
                // summary:
2665
 
                //              The private primitive that means either callback or errback
2666
 
                this.fired = ((res instanceof Error) ? 1 : 0);
2667
 
                this.results[this.fired] = res;
2668
 
                this._fire();
2669
 
        },
2670
 
 
2671
 
        _check: function(){
2672
 
                if(this.fired != -1){
2673
 
                        if(!this.silentlyCancelled){
2674
 
                                throw new Error("already called!");
2675
 
                        }
2676
 
                        this.silentlyCancelled = false;
2677
 
                        return;
2678
 
                }
2679
 
        },
2680
 
 
2681
 
        callback: function(res){
2682
 
                //      summary:        
2683
 
                //              Begin the callback sequence with a non-error value.
2684
 
                
2685
 
                /*
2686
 
                callback or errback should only be called once on a given
2687
 
                Deferred.
2688
 
                */
2689
 
                this._check();
2690
 
                this._resback(res);
2691
 
        },
2692
 
 
2693
 
        errback: function(/*Error*/res){
2694
 
                //      summary: 
2695
 
                //              Begin the callback sequence with an error result.
2696
 
                this._check();
2697
 
                if(!(res instanceof Error)){
2698
 
                        res = new Error(res);
2699
 
                }
2700
 
                this._resback(res);
2701
 
        },
2702
 
 
2703
 
        addBoth: function(/*Function|Object*/cb, /*String?*/cbfn){
2704
 
                //      summary:
2705
 
                //              Add the same function as both a callback and an errback as the
2706
 
                //              next element on the callback sequence.This is useful for code
2707
 
                //              that you want to guarantee to run, e.g. a finalizer.
2708
 
                var enclosed = dojo.hitch.apply(dojo, arguments);
2709
 
                return this.addCallbacks(enclosed, enclosed); // dojo.Deferred
2710
 
        },
2711
 
 
2712
 
        addCallback: function(/*Function|Object*/cb, /*String?*/cbfn /*...*/){
2713
 
                //      summary: 
2714
 
                //              Add a single callback to the end of the callback sequence.
2715
 
                return this.addCallbacks(dojo.hitch.apply(dojo, arguments)); // dojo.Deferred
2716
 
        },
2717
 
 
2718
 
        addErrback: function(cb, cbfn){
2719
 
                //      summary: 
2720
 
                //              Add a single callback to the end of the callback sequence.
2721
 
                return this.addCallbacks(null, dojo.hitch.apply(dojo, arguments)); // dojo.Deferred
2722
 
        },
2723
 
 
2724
 
        addCallbacks: function(cb, eb){
2725
 
                // summary: 
2726
 
                //              Add separate callback and errback to the end of the callback
2727
 
                //              sequence.
2728
 
                this.chain.push([cb, eb])
2729
 
                if(this.fired >= 0){
2730
 
                        this._fire();
2731
 
                }
2732
 
                return this; // dojo.Deferred
2733
 
        },
2734
 
 
2735
 
        _fire: function(){
2736
 
                // summary: 
2737
 
                //              Used internally to exhaust the callback sequence when a result
2738
 
                //              is available.
2739
 
                var chain = this.chain;
2740
 
                var fired = this.fired;
2741
 
                var res = this.results[fired];
2742
 
                var self = this;
2743
 
                var cb = null;
2744
 
                while(
2745
 
                        (chain.length > 0) &&
2746
 
                        (this.paused == 0)
2747
 
                ){
2748
 
                        // Array
2749
 
                        var f = chain.shift()[fired];
2750
 
                        if(!f){ continue; }
2751
 
                        var func = function(){
2752
 
                                var ret = f(res);
2753
 
                                //If no response, then use previous response.
2754
 
                                if(typeof ret != "undefined"){
2755
 
                                        res = ret;
2756
 
                                }
2757
 
                                fired = ((res instanceof Error) ? 1 : 0);
2758
 
                                if(res instanceof dojo.Deferred){
2759
 
                                        cb = function(res){
2760
 
                                                self._resback(res);
2761
 
                                                // inlined from _pause()
2762
 
                                                self.paused--;
2763
 
                                                if(
2764
 
                                                        (self.paused == 0) && 
2765
 
                                                        (self.fired >= 0)
2766
 
                                                ){
2767
 
                                                        self._fire();
2768
 
                                                }
2769
 
                                        }
2770
 
                                        // inlined from _unpause
2771
 
                                        this.paused++;
2772
 
                                }
2773
 
                        };
2774
 
                        if(dojo.config.isDebug){
2775
 
                                func.call(this);
2776
 
                        }else{
2777
 
                                try{
2778
 
                                        func.call(this);
2779
 
                                }catch(err){
2780
 
                                        fired = 1;
2781
 
                                        res = err;
2782
 
                                }
2783
 
                        }
2784
 
                }
2785
 
                this.fired = fired;
2786
 
                this.results[fired] = res;
2787
 
                if((cb)&&(this.paused)){
2788
 
                        // this is for "tail recursion" in case the dependent
2789
 
                        // deferred is already fired
2790
 
                        res.addBoth(cb);
2791
 
                }
2792
 
        }
2793
 
});
2794
 
 
2795
 
}
2796
 
 
2797
 
if(!dojo._hasResource["dojo._base.json"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
2798
 
dojo._hasResource["dojo._base.json"] = true;
2799
 
dojo.provide("dojo._base.json");
2800
 
 
2801
 
dojo.fromJson = function(/*String*/ json){
2802
 
        // summary:
2803
 
        //              Parses a [JSON](http://json.org) string to return a JavaScript object.  Throws for invalid JSON strings.
2804
 
        // json: 
2805
 
        //              a string literal of a JSON item, for instance:
2806
 
        //                      `'{ "foo": [ "bar", 1, { "baz": "thud" } ] }'`
2807
 
 
2808
 
        return eval("(" + json + ")"); // Object
2809
 
}
2810
 
 
2811
 
dojo._escapeString = function(/*String*/str){
2812
 
        //summary:
2813
 
        //              Adds escape sequences for non-visual characters, double quote and
2814
 
        //              backslash and surrounds with double quotes to form a valid string
2815
 
        //              literal.
2816
 
        return ('"' + str.replace(/(["\\])/g, '\\$1') + '"').
2817
 
                replace(/[\f]/g, "\\f").replace(/[\b]/g, "\\b").replace(/[\n]/g, "\\n").
2818
 
                replace(/[\t]/g, "\\t").replace(/[\r]/g, "\\r"); // string
2819
 
}
2820
 
 
2821
 
dojo.toJsonIndentStr = "\t";
2822
 
dojo.toJson = function(/*Object*/ it, /*Boolean?*/ prettyPrint, /*String?*/ _indentStr){
2823
 
        // summary:
2824
 
        //              Returns a [JSON](http://json.org) serialization of an object.
2825
 
        //
2826
 
        // description:
2827
 
        //              Returns a [JSON](http://json.org) serialization of an object.
2828
 
        //              Note that this doesn't check for infinite recursion, so don't do that!
2829
 
        //
2830
 
        // it:
2831
 
        //              an object to be serialized. Objects may define their own
2832
 
        //              serialization via a special "__json__" or "json" function
2833
 
        //              property. If a specialized serializer has been defined, it will
2834
 
        //              be used as a fallback.
2835
 
        //
2836
 
        // prettyPrint:
2837
 
        //              if true, we indent objects and arrays to make the output prettier.
2838
 
        //              The variable dojo.toJsonIndentStr is used as the indent string 
2839
 
        //              -- to use something other than the default (tab), 
2840
 
        //              change that variable before calling dojo.toJson().
2841
 
        //
2842
 
        // _indentStr:
2843
 
        //              private variable for recursive calls when pretty printing, do not use.
2844
 
 
2845
 
        if(it === undefined){
2846
 
                return "undefined";
2847
 
        }
2848
 
        var objtype = typeof it;
2849
 
        if(objtype == "number" || objtype == "boolean"){
2850
 
                return it + "";
2851
 
        }
2852
 
        if(it === null){
2853
 
                return "null";
2854
 
        }
2855
 
        if(dojo.isString(it)){ 
2856
 
                return dojo._escapeString(it); 
2857
 
        }
2858
 
        // recurse
2859
 
        var recurse = arguments.callee;
2860
 
        // short-circuit for objects that support "json" serialization
2861
 
        // if they return "self" then just pass-through...
2862
 
        var newObj;
2863
 
        _indentStr = _indentStr || "";
2864
 
        var nextIndent = prettyPrint ? _indentStr + dojo.toJsonIndentStr : "";
2865
 
        var tf = it.__json__||it.json;
2866
 
        if(dojo.isFunction(tf)){
2867
 
                newObj = tf.call(it);
2868
 
                if(it !== newObj){
2869
 
                        return recurse(newObj, prettyPrint, nextIndent);
2870
 
                }
2871
 
        }
2872
 
        if(it.nodeType && it.cloneNode){ // isNode
2873
 
                // we can't seriailize DOM nodes as regular objects because they have cycles
2874
 
                // DOM nodes could be serialized with something like outerHTML, but
2875
 
                // that can be provided by users in the form of .json or .__json__ function.
2876
 
                throw new Error("Can't serialize DOM nodes");
2877
 
        }
2878
 
 
2879
 
        var sep = prettyPrint ? " " : "";
2880
 
        var newLine = prettyPrint ? "\n" : "";
2881
 
 
2882
 
        // array
2883
 
        if(dojo.isArray(it)){
2884
 
                var res = dojo.map(it, function(obj){
2885
 
                        var val = recurse(obj, prettyPrint, nextIndent);
2886
 
                        if(typeof val != "string"){
2887
 
                                val = "undefined";
2888
 
                        }
2889
 
                        return newLine + nextIndent + val;
2890
 
                });
2891
 
                return "[" + res.join("," + sep) + newLine + _indentStr + "]";
2892
 
        }
2893
 
        /*
2894
 
        // look in the registry
2895
 
        try {
2896
 
                window.o = it;
2897
 
                newObj = dojo.json.jsonRegistry.match(it);
2898
 
                return recurse(newObj, prettyPrint, nextIndent);
2899
 
        }catch(e){
2900
 
                // 
2901
 
        }
2902
 
        // it's a function with no adapter, skip it
2903
 
        */
2904
 
        if(objtype == "function"){
2905
 
                return null; // null
2906
 
        }
2907
 
        // generic object code path
2908
 
        var output = [], key;
2909
 
        for(key in it){
2910
 
                var keyStr, val;
2911
 
                if(typeof key == "number"){
2912
 
                        keyStr = '"' + key + '"';
2913
 
                }else if(typeof key == "string"){
2914
 
                        keyStr = dojo._escapeString(key);
2915
 
                }else{
2916
 
                        // skip non-string or number keys
2917
 
                        continue;
2918
 
                }
2919
 
                val = recurse(it[key], prettyPrint, nextIndent);
2920
 
                if(typeof val != "string"){
2921
 
                        // skip non-serializable values
2922
 
                        continue;
2923
 
                }
2924
 
                // FIXME: use += on Moz!!
2925
 
                //       MOW NOTE: using += is a pain because you have to account for the dangling comma...
2926
 
                output.push(newLine + nextIndent + keyStr + ":" + sep + val);
2927
 
        }
2928
 
        return "{" + output.join("," + sep) + newLine + _indentStr + "}"; // String
2929
 
}
2930
 
 
2931
 
}
2932
 
 
2933
 
if(!dojo._hasResource["dojo._base.array"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
2934
 
dojo._hasResource["dojo._base.array"] = true;
2935
 
 
2936
 
dojo.provide("dojo._base.array");
2937
 
 
2938
 
(function(){
2939
 
        var _getParts = function(arr, obj, cb){
2940
 
                return [ 
2941
 
                        dojo.isString(arr) ? arr.split("") : arr, 
2942
 
                        obj || dojo.global,
2943
 
                        // FIXME: cache the anonymous functions we create here?
2944
 
                        dojo.isString(cb) ? new Function("item", "index", "array", cb) : cb
2945
 
                ];
2946
 
        };
2947
 
 
2948
 
        dojo.mixin(dojo, {
2949
 
                indexOf: function(      /*Array*/               array, 
2950
 
                                                        /*Object*/              value,
2951
 
                                                        /*Integer?*/    fromIndex,
2952
 
                                                        /*Boolean?*/    findLast){
2953
 
                        // summary:
2954
 
                        //              locates the first index of the provided value in the
2955
 
                        //              passed array. If the value is not found, -1 is returned.
2956
 
                        // description:
2957
 
                        //              For details on this method, see:
2958
 
                        //                      http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:indexOf
2959
 
 
2960
 
                        var step = 1, end = array.length || 0, i = 0;
2961
 
                        if(findLast){
2962
 
                                i = end - 1;
2963
 
                                step = end = -1;
2964
 
                        }
2965
 
                        if(fromIndex != undefined){ i = fromIndex; }
2966
 
                        if((findLast && i > end) || i < end){
2967
 
                                for(; i != end; i += step){
2968
 
                                        if(array[i] == value){ return i; }
2969
 
                                }
2970
 
                        }
2971
 
                        return -1;      // Number
2972
 
                },
2973
 
 
2974
 
                lastIndexOf: function(/*Array*/array, /*Object*/value, /*Integer?*/fromIndex){
2975
 
                        // summary:
2976
 
                        //              locates the last index of the provided value in the passed
2977
 
                        //              array. If the value is not found, -1 is returned.
2978
 
                        // description:
2979
 
                        //              For details on this method, see:
2980
 
                        //                      http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:lastIndexOf
2981
 
                        return dojo.indexOf(array, value, fromIndex, true); // Number
2982
 
                },
2983
 
 
2984
 
                forEach: function(/*Array|String*/arr, /*Function|String*/callback, /*Object?*/thisObject){
2985
 
                        //      summary:
2986
 
                        //              for every item in arr, callback is invoked. Return values are ignored.
2987
 
                        //      arr:
2988
 
                        //              the array to iterate over. If a string, operates on individual characters.
2989
 
                        //      callback:
2990
 
                        //              a function is invoked with three arguments: item, index, and array
2991
 
                        //      thisObject:
2992
 
                        //              may be used to scope the call to callback
2993
 
                        //      description:
2994
 
                        //              This function corresponds to the JavaScript 1.6
2995
 
                        //              Array.forEach() method. For more details, see:
2996
 
                        //                      http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:forEach
2997
 
                        //      example:
2998
 
                        //      |       // log out all members of the array:
2999
 
                        //      |       dojo.forEach(
3000
 
                        //      |               [ "thinger", "blah", "howdy", 10 ],
3001
 
                        //      |               function(item){
3002
 
                        //      |                       
3003
 
                        //      |               }
3004
 
                        //      |       );
3005
 
                        //      example:
3006
 
                        //      |       // log out the members and their indexes
3007
 
                        //      |       dojo.forEach(
3008
 
                        //      |               [ "thinger", "blah", "howdy", 10 ],
3009
 
                        //      |               function(item, idx, arr){
3010
 
                        //      |                       
3011
 
                        //      |               }
3012
 
                        //      |       );
3013
 
                        //      example:
3014
 
                        //      |       // use a scoped object member as the callback
3015
 
                        //      |       
3016
 
                        //      |       var obj = {
3017
 
                        //      |               prefix: "logged via obj.callback:", 
3018
 
                        //      |               callback: function(item){
3019
 
                        //      |                       
3020
 
                        //      |               }
3021
 
                        //      |       };
3022
 
                        //      |       
3023
 
                        //      |       // specifying the scope function executes the callback in that scope
3024
 
                        //      |       dojo.forEach(
3025
 
                        //      |               [ "thinger", "blah", "howdy", 10 ],
3026
 
                        //      |               obj.callback,
3027
 
                        //      |               obj
3028
 
                        //      |       );
3029
 
                        //      |       
3030
 
                        //      |       // alternately, we can accomplish the same thing with dojo.hitch()
3031
 
                        //      |       dojo.forEach(
3032
 
                        //      |               [ "thinger", "blah", "howdy", 10 ],
3033
 
                        //      |               dojo.hitch(obj, "callback")
3034
 
                        //      |       );
3035
 
 
3036
 
                        // match the behavior of the built-in forEach WRT empty arrs
3037
 
                        if(!arr || !arr.length){ return; }
3038
 
 
3039
 
                        // FIXME: there are several ways of handilng thisObject. Is
3040
 
                        // dojo.global always the default context?
3041
 
                        var _p = _getParts(arr, thisObject, callback); arr = _p[0];
3042
 
                        for(var i=0,l=arr.length; i<l; ++i){ 
3043
 
                                _p[2].call(_p[1], arr[i], i, arr);
3044
 
                        }
3045
 
                },
3046
 
 
3047
 
                _everyOrSome: function(/*Boolean*/every, /*Array|String*/arr, /*Function|String*/callback, /*Object?*/thisObject){
3048
 
                        var _p = _getParts(arr, thisObject, callback); arr = _p[0];
3049
 
                        for(var i=0,l=arr.length; i<l; ++i){
3050
 
                                var result = !!_p[2].call(_p[1], arr[i], i, arr);
3051
 
                                if(every ^ result){
3052
 
                                        return result; // Boolean
3053
 
                                }
3054
 
                        }
3055
 
                        return every; // Boolean
3056
 
                },
3057
 
 
3058
 
                every: function(/*Array|String*/arr, /*Function|String*/callback, /*Object?*/thisObject){
3059
 
                        // summary:
3060
 
                        //              Determines whether or not every item in arr satisfies the
3061
 
                        //              condition implemented by callback.
3062
 
                        // arr:
3063
 
                        //              the array to iterate on. If a string, operates on individual characters.
3064
 
                        // callback:
3065
 
                        //              a function is invoked with three arguments: item, index,
3066
 
                        //              and array and returns true if the condition is met.
3067
 
                        // thisObject:
3068
 
                        //              may be used to scope the call to callback
3069
 
                        // description:
3070
 
                        //              This function corresponds to the JavaScript 1.6
3071
 
                        //              Array.every() method. For more details, see:
3072
 
                        //                      http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:every
3073
 
                        // example:
3074
 
                        //      |       // returns false
3075
 
                        //      |       dojo.every([1, 2, 3, 4], function(item){ return item>1; });
3076
 
                        // example:
3077
 
                        //      |       // returns true 
3078
 
                        //      |       dojo.every([1, 2, 3, 4], function(item){ return item>0; });
3079
 
                        return this._everyOrSome(true, arr, callback, thisObject); // Boolean
3080
 
                },
3081
 
 
3082
 
                some: function(/*Array|String*/arr, /*Function|String*/callback, /*Object?*/thisObject){
3083
 
                        // summary:
3084
 
                        //              Determines whether or not any item in arr satisfies the
3085
 
                        //              condition implemented by callback.
3086
 
                        // arr:
3087
 
                        //              the array to iterate over. If a string, operates on individual characters.
3088
 
                        // callback:
3089
 
                        //              a function is invoked with three arguments: item, index,
3090
 
                        //              and array and returns true if the condition is met.
3091
 
                        // thisObject:
3092
 
                        //              may be used to scope the call to callback
3093
 
                        // description:
3094
 
                        //              This function corresponds to the JavaScript 1.6
3095
 
                        //              Array.some() method. For more details, see:
3096
 
                        //                      http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:some
3097
 
                        // example:
3098
 
                        //      |       // is true
3099
 
                        //      |       dojo.some([1, 2, 3, 4], function(item){ return item>1; });
3100
 
                        // example:
3101
 
                        //      |       // is false
3102
 
                        //      |       dojo.some([1, 2, 3, 4], function(item){ return item<1; });
3103
 
                        return this._everyOrSome(false, arr, callback, thisObject); // Boolean
3104
 
                },
3105
 
 
3106
 
                map: function(/*Array|String*/arr, /*Function|String*/callback, /*Function?*/thisObject){
3107
 
                        // summary:
3108
 
                        //              applies callback to each element of arr and returns
3109
 
                        //              an Array with the results
3110
 
                        // arr:
3111
 
                        //              the array to iterate on. If a string, operates on
3112
 
                        //              individual characters.
3113
 
                        // callback:
3114
 
                        //              a function is invoked with three arguments, (item, index,
3115
 
                        //              array),  and returns a value
3116
 
                        // thisObject:
3117
 
                        //              may be used to scope the call to callback
3118
 
                        // description:
3119
 
                        //              This function corresponds to the JavaScript 1.6 Array.map()
3120
 
                        //              method. For more details, see:
3121
 
                        //                      http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:map
3122
 
                        // example:
3123
 
                        //      |       // returns [2, 3, 4, 5]
3124
 
                        //      |       dojo.map([1, 2, 3, 4], function(item){ return item+1 });
3125
 
 
3126
 
                        var _p = _getParts(arr, thisObject, callback); arr = _p[0];
3127
 
                        var outArr = (arguments[3] ? (new arguments[3]()) : []);
3128
 
                        for(var i=0,l=arr.length; i<l; ++i){
3129
 
                                outArr.push(_p[2].call(_p[1], arr[i], i, arr));
3130
 
                        }
3131
 
                        return outArr; // Array
3132
 
                },
3133
 
 
3134
 
                filter: function(/*Array*/arr, /*Function|String*/callback, /*Object?*/thisObject){
3135
 
                        // summary:
3136
 
                        //              Returns a new Array with those items from arr that match the
3137
 
                        //              condition implemented by callback.
3138
 
                        // arr:
3139
 
                        //              the array to iterate over.
3140
 
                        // callback:
3141
 
                        //              a function that is invoked with three arguments (item,
3142
 
                        //              index, array). The return of this function is expected to
3143
 
                        //              be a boolean which determines whether the passed-in item
3144
 
                        //              will be included in the returned array.
3145
 
                        // thisObject:
3146
 
                        //              may be used to scope the call to callback
3147
 
                        // description:
3148
 
                        //              This function corresponds to the JavaScript 1.6
3149
 
                        //              Array.filter() method. For more details, see:
3150
 
                        //                      http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:filter
3151
 
                        // example:
3152
 
                        //      |       // returns [2, 3, 4]
3153
 
                        //      |       dojo.filter([1, 2, 3, 4], function(item){ return item>1; });
3154
 
 
3155
 
                        var _p = _getParts(arr, thisObject, callback); arr = _p[0];
3156
 
                        var outArr = [];
3157
 
                        for(var i=0,l=arr.length; i<l; ++i){
3158
 
                                if(_p[2].call(_p[1], arr[i], i, arr)){
3159
 
                                        outArr.push(arr[i]);
3160
 
                                }
3161
 
                        }
3162
 
                        return outArr; // Array
3163
 
                }
3164
 
        });
3165
 
})();
3166
 
 
3167
 
}
3168
 
 
3169
 
if(!dojo._hasResource["dojo._base.Color"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
3170
 
dojo._hasResource["dojo._base.Color"] = true;
3171
 
dojo.provide("dojo._base.Color");
3172
 
 
3173
 
 
3174
 
 
3175
 
dojo.Color = function(/*Array|String|Object*/ color){
3176
 
        // summary:
3177
 
        //              takes a named string, hex string, array of rgb or rgba values,
3178
 
        //              an object with r, g, b, and a properties, or another dojo.Color object
3179
 
        if(color){ this.setColor(color); }
3180
 
};
3181
 
 
3182
 
// FIXME: there's got to be a more space-efficient way to encode or discover these!!  Use hex?
3183
 
dojo.Color.named = {
3184
 
        black:      [0,0,0],
3185
 
        silver:     [192,192,192],
3186
 
        gray:       [128,128,128],
3187
 
        white:      [255,255,255],
3188
 
        maroon:         [128,0,0],
3189
 
        red:        [255,0,0],
3190
 
        purple:         [128,0,128],
3191
 
        fuchsia:        [255,0,255],
3192
 
        green:      [0,128,0],
3193
 
        lime:       [0,255,0],
3194
 
        olive:          [128,128,0],
3195
 
        yellow:         [255,255,0],
3196
 
        navy:       [0,0,128],
3197
 
        blue:       [0,0,255],
3198
 
        teal:           [0,128,128],
3199
 
        aqua:           [0,255,255]
3200
 
};
3201
 
 
3202
 
 
3203
 
dojo.extend(dojo.Color, {
3204
 
        r: 255, g: 255, b: 255, a: 1,
3205
 
        _set: function(r, g, b, a){
3206
 
                var t = this; t.r = r; t.g = g; t.b = b; t.a = a;
3207
 
        },
3208
 
        setColor: function(/*Array|String|Object*/ color){
3209
 
                // summary:
3210
 
                //              takes a named string, hex string, array of rgb or rgba values,
3211
 
                //              an object with r, g, b, and a properties, or another dojo.Color object
3212
 
                var d = dojo;
3213
 
                if(d.isString(color)){
3214
 
                        d.colorFromString(color, this);
3215
 
                }else if(d.isArray(color)){
3216
 
                        d.colorFromArray(color, this);
3217
 
                }else{
3218
 
                        this._set(color.r, color.g, color.b, color.a);
3219
 
                        if(!(color instanceof d.Color)){ this.sanitize(); }
3220
 
                }
3221
 
                return this;    // dojo.Color
3222
 
        },
3223
 
        sanitize: function(){
3224
 
                // summary:
3225
 
                //              makes sure that the object has correct attributes
3226
 
                // description: 
3227
 
                //              the default implementation does nothing, include dojo.colors to
3228
 
                //              augment it to real checks
3229
 
                return this;    // dojo.Color
3230
 
        },
3231
 
        toRgb: function(){
3232
 
                // summary: returns 3 component array of rgb values
3233
 
                var t = this;
3234
 
                return [t.r, t.g, t.b]; // Array
3235
 
        },
3236
 
        toRgba: function(){
3237
 
                // summary: returns a 4 component array of rgba values
3238
 
                var t = this;
3239
 
                return [t.r, t.g, t.b, t.a];    // Array
3240
 
        },
3241
 
        toHex: function(){
3242
 
                // summary: returns a css color string in hexadecimal representation
3243
 
                var arr = dojo.map(["r", "g", "b"], function(x){
3244
 
                        var s = this[x].toString(16);
3245
 
                        return s.length < 2 ? "0" + s : s;
3246
 
                }, this);
3247
 
                return "#" + arr.join("");      // String
3248
 
        },
3249
 
        toCss: function(/*Boolean?*/ includeAlpha){
3250
 
                // summary: returns a css color string in rgb(a) representation
3251
 
                var t = this, rgb = t.r + ", " + t.g + ", " + t.b;
3252
 
                return (includeAlpha ? "rgba(" + rgb + ", " + t.a : "rgb(" + rgb) + ")";        // String
3253
 
        },
3254
 
        toString: function(){
3255
 
                // summary: returns a visual representation of the color
3256
 
                return this.toCss(true); // String
3257
 
        }
3258
 
});
3259
 
 
3260
 
dojo.blendColors = function(
3261
 
        /*dojo.Color*/ start, 
3262
 
        /*dojo.Color*/ end, 
3263
 
        /*Number*/ weight,
3264
 
        /*dojo.Color?*/ obj
3265
 
){
3266
 
        // summary: 
3267
 
        //              blend colors end and start with weight from 0 to 1, 0.5 being a 50/50 blend,
3268
 
        //              can reuse a previously allocated dojo.Color object for the result
3269
 
        var d = dojo, t = obj || new dojo.Color();
3270
 
        d.forEach(["r", "g", "b", "a"], function(x){
3271
 
                t[x] = start[x] + (end[x] - start[x]) * weight;
3272
 
                if(x != "a"){ t[x] = Math.round(t[x]); }
3273
 
        });
3274
 
        return t.sanitize();    // dojo.Color
3275
 
};
3276
 
 
3277
 
dojo.colorFromRgb = function(/*String*/ color, /*dojo.Color?*/ obj){
3278
 
        // summary: get rgb(a) array from css-style color declarations
3279
 
        var m = color.toLowerCase().match(/^rgba?\(([\s\.,0-9]+)\)/);
3280
 
        return m && dojo.colorFromArray(m[1].split(/\s*,\s*/), obj);    // dojo.Color
3281
 
};
3282
 
 
3283
 
dojo.colorFromHex = function(/*String*/ color, /*dojo.Color?*/ obj){
3284
 
        // summary: converts a hex string with a '#' prefix to a color object.
3285
 
        //      Supports 12-bit #rgb shorthand.
3286
 
        var d = dojo, t = obj || new d.Color(),
3287
 
                bits = (color.length == 4) ? 4 : 8,
3288
 
                mask = (1 << bits) - 1;
3289
 
        color = Number("0x" + color.substr(1));
3290
 
        if(isNaN(color)){
3291
 
                return null; // dojo.Color
3292
 
        }
3293
 
        d.forEach(["b", "g", "r"], function(x){
3294
 
                var c = color & mask;
3295
 
                color >>= bits;
3296
 
                t[x] = bits == 4 ? 17 * c : c;
3297
 
        });
3298
 
        t.a = 1;
3299
 
        return t;       // dojo.Color
3300
 
};
3301
 
 
3302
 
dojo.colorFromArray = function(/*Array*/ a, /*dojo.Color?*/ obj){
3303
 
        // summary: builds a color from 1, 2, 3, or 4 element array
3304
 
        var t = obj || new dojo.Color();
3305
 
        t._set(Number(a[0]), Number(a[1]), Number(a[2]), Number(a[3]));
3306
 
        if(isNaN(t.a)){ t.a = 1; }
3307
 
        return t.sanitize();    // dojo.Color
3308
 
};
3309
 
 
3310
 
dojo.colorFromString = function(/*String*/ str, /*dojo.Color?*/ obj){
3311
 
        //      summary:
3312
 
        //              parses str for a color value.
3313
 
        //      description:
3314
 
        //              Acceptable input values for str may include arrays of any form
3315
 
        //              accepted by dojo.colorFromArray, hex strings such as "#aaaaaa", or
3316
 
        //              rgb or rgba strings such as "rgb(133, 200, 16)" or "rgba(10, 10,
3317
 
        //              10, 50)"
3318
 
        //      returns:
3319
 
        //              a dojo.Color object. If obj is passed, it will be the return value.
3320
 
        var a = dojo.Color.named[str];
3321
 
        return a && dojo.colorFromArray(a, obj) || dojo.colorFromRgb(str, obj) || dojo.colorFromHex(str, obj);
3322
 
};
3323
 
 
3324
 
}
3325
 
 
3326
 
if(!dojo._hasResource["dojo._base"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
3327
 
dojo._hasResource["dojo._base"] = true;
3328
 
dojo.provide("dojo._base");
3329
 
 
3330
 
 
3331
 
 
3332
 
 
3333
 
 
3334
 
 
3335
 
 
3336
 
 
3337
 
 
3338
 
}
3339
 
 
3340
 
if(!dojo._hasResource["dojo._base.window"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
3341
 
dojo._hasResource["dojo._base.window"] = true;
3342
 
dojo.provide("dojo._base.window");
3343
 
 
3344
 
/*=====
3345
 
dojo.doc = {
3346
 
        // summary:
3347
 
        //              Alias for the current document. 'dojo.doc' can be modified
3348
 
        //              for temporary context shifting. Also see dojo.withDoc().
3349
 
        // description:
3350
 
        //    Refer to dojo.doc rather
3351
 
        //    than referring to 'window.document' to ensure your code runs
3352
 
        //    correctly in managed contexts.
3353
 
        // example:
3354
 
        //      |       n.appendChild(dojo.doc.createElement('div'));
3355
 
}
3356
 
=====*/
3357
 
dojo.doc = window["document"] || null;
3358
 
 
3359
 
dojo.body = function(){
3360
 
        // summary:
3361
 
        //              Return the body element of the document
3362
 
        //              return the body object associated with dojo.doc
3363
 
        // example:
3364
 
        //      |       dojo.body().appendChild(dojo.doc.createElement('div'));
3365
 
 
3366
 
        // Note: document.body is not defined for a strict xhtml document
3367
 
        // Would like to memoize this, but dojo.doc can change vi dojo.withDoc().
3368
 
        return dojo.doc.body || dojo.doc.getElementsByTagName("body")[0]; // Node
3369
 
}
3370
 
 
3371
 
dojo.setContext = function(/*Object*/globalObject, /*DocumentElement*/globalDocument){
3372
 
        // summary:
3373
 
        //              changes the behavior of many core Dojo functions that deal with
3374
 
        //              namespace and DOM lookup, changing them to work in a new global
3375
 
        //              context (e.g., an iframe). The varibles dojo.global and dojo.doc
3376
 
        //              are modified as a result of calling this function and the result of
3377
 
        //              `dojo.body()` likewise differs.
3378
 
        dojo.global = globalObject;
3379
 
        dojo.doc = globalDocument;
3380
 
};
3381
 
 
3382
 
dojo._fireCallback = function(callback, context, cbArguments){
3383
 
        if(context && dojo.isString(callback)){
3384
 
                callback = context[callback];
3385
 
        }
3386
 
        return callback.apply(context, cbArguments || [ ]);
3387
 
}
3388
 
 
3389
 
dojo.withGlobal = function(     /*Object*/globalObject, 
3390
 
                                                        /*Function*/callback, 
3391
 
                                                        /*Object?*/thisObject, 
3392
 
                                                        /*Array?*/cbArguments){
3393
 
        // summary:
3394
 
        //              Call callback with globalObject as dojo.global and
3395
 
        //              globalObject.document as dojo.doc. If provided, globalObject
3396
 
        //              will be executed in the context of object thisObject
3397
 
        // description:
3398
 
        //              When callback() returns or throws an error, the dojo.global
3399
 
        //              and dojo.doc will be restored to its previous state.
3400
 
        var rval;
3401
 
        var oldGlob = dojo.global;
3402
 
        var oldDoc = dojo.doc;
3403
 
        try{
3404
 
                dojo.setContext(globalObject, globalObject.document);
3405
 
                rval = dojo._fireCallback(callback, thisObject, cbArguments);
3406
 
        }finally{
3407
 
                dojo.setContext(oldGlob, oldDoc);
3408
 
        }
3409
 
        return rval;
3410
 
}
3411
 
 
3412
 
dojo.withDoc = function(        /*Object*/documentObject, 
3413
 
                                                        /*Function*/callback, 
3414
 
                                                        /*Object?*/thisObject, 
3415
 
                                                        /*Array?*/cbArguments){
3416
 
        // summary:
3417
 
        //              Call callback with documentObject as dojo.doc. If provided,
3418
 
        //              callback will be executed in the context of object thisObject
3419
 
        // description:
3420
 
        //              When callback() returns or throws an error, the dojo.doc will
3421
 
        //              be restored to its previous state.
3422
 
        var rval;
3423
 
        var oldDoc = dojo.doc;
3424
 
        try{
3425
 
                dojo.doc = documentObject;
3426
 
                rval = dojo._fireCallback(callback, thisObject, cbArguments);
3427
 
        }finally{
3428
 
                dojo.doc = oldDoc;
3429
 
        }
3430
 
        return rval;
3431
 
};
3432
 
 
3433
 
}
3434
 
 
3435
 
if(!dojo._hasResource["dojo._base.event"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
3436
 
dojo._hasResource["dojo._base.event"] = true;
3437
 
dojo.provide("dojo._base.event");
3438
 
 
3439
 
 
3440
 
// this file courtesy of the TurboAjax Group, licensed under a Dojo CLA
3441
 
 
3442
 
(function(){
3443
 
        // DOM event listener machinery
3444
 
        var del = (dojo._event_listener = {
3445
 
                add: function(/*DOMNode*/node, /*String*/name, /*Function*/fp){
3446
 
                        if(!node){return;} 
3447
 
                        name = del._normalizeEventName(name);
3448
 
                        fp = del._fixCallback(name, fp);
3449
 
                        var oname = name;
3450
 
                        if(!dojo.isIE && (name == "mouseenter" || name == "mouseleave")){
3451
 
                                var ofp = fp;
3452
 
                                //oname = name;
3453
 
                                name = (name == "mouseenter") ? "mouseover" : "mouseout";
3454
 
                                fp = function(e){
3455
 
                                        // check tagName to fix a FF2 bug with invalid nodes (hidden child DIV of INPUT)
3456
 
                                        // which causes isDecendant to return false which causes
3457
 
                                        // spurious, and more importantly, incorrect mouse events to fire.
3458
 
                                        // TODO: remove tagName check when Firefox 2 is no longer supported
3459
 
                                        try{ e.relatedTarget.tagName; } catch(e2){ return; }
3460
 
                                        if(!dojo.isDescendant(e.relatedTarget, node)){
3461
 
                                                // e.type = oname; // FIXME: doesn't take? SJM: event.type is generally immutable.
3462
 
                                                return ofp.call(this, e); 
3463
 
                                        }
3464
 
                                }
3465
 
                        }
3466
 
                        node.addEventListener(name, fp, false);
3467
 
                        return fp; /*Handle*/
3468
 
                },
3469
 
                remove: function(/*DOMNode*/node, /*String*/event, /*Handle*/handle){
3470
 
                        // summary:
3471
 
                        //              clobbers the listener from the node
3472
 
                        // node:
3473
 
                        //              DOM node to attach the event to
3474
 
                        // event:
3475
 
                        //              the name of the handler to remove the function from
3476
 
                        // handle:
3477
 
                        //              the handle returned from add
3478
 
                        if (node){
3479
 
                                event = del._normalizeEventName(event);
3480
 
                                if(!dojo.isIE && (event == "mouseenter" || event == "mouseleave")){
3481
 
                                        event = (event == "mouseenter") ? "mouseover" : "mouseout";
3482
 
                                }
3483
 
 
3484
 
                                node.removeEventListener(event, handle, false);
3485
 
                        }
3486
 
                },
3487
 
                _normalizeEventName: function(/*String*/name){
3488
 
                        // Generally, name should be lower case, unless it is special
3489
 
                        // somehow (e.g. a Mozilla DOM event).
3490
 
                        // Remove 'on'.
3491
 
                        return name.slice(0,2) =="on" ? name.slice(2) : name;
3492
 
                },
3493
 
                _fixCallback: function(/*String*/name, fp){
3494
 
                        // By default, we only invoke _fixEvent for 'keypress'
3495
 
                        // If code is added to _fixEvent for other events, we have
3496
 
                        // to revisit this optimization.
3497
 
                        // This also applies to _fixEvent overrides for Safari and Opera
3498
 
                        // below.
3499
 
                        return name != "keypress" ? fp : function(e){ return fp.call(this, del._fixEvent(e, this)); };
3500
 
                },
3501
 
                _fixEvent: function(evt, sender){
3502
 
                        // _fixCallback only attaches us to keypress.
3503
 
                        // Switch on evt.type anyway because we might 
3504
 
                        // be called directly from dojo.fixEvent.
3505
 
                        switch(evt.type){
3506
 
                                case "keypress":
3507
 
                                        del._setKeyChar(evt);
3508
 
                                        break;
3509
 
                        }
3510
 
                        return evt;
3511
 
                },
3512
 
                _setKeyChar: function(evt){
3513
 
                        evt.keyChar = evt.charCode ? String.fromCharCode(evt.charCode) : '';
3514
 
                        evt.charOrCode = evt.keyChar || evt.keyCode;
3515
 
                },
3516
 
                // For IE and Safari: some ctrl-key combinations (mostly w/punctuation) do not emit a char code in IE
3517
 
                // we map those virtual key codes to ascii here
3518
 
                // not valid for all (non-US) keyboards, so maybe we shouldn't bother
3519
 
                _punctMap: { 
3520
 
                        106:42, 
3521
 
                        111:47, 
3522
 
                        186:59, 
3523
 
                        187:43, 
3524
 
                        188:44, 
3525
 
                        189:45, 
3526
 
                        190:46, 
3527
 
                        191:47, 
3528
 
                        192:96, 
3529
 
                        219:91, 
3530
 
                        220:92, 
3531
 
                        221:93, 
3532
 
                        222:39 
3533
 
                }
3534
 
        });
3535
 
 
3536
 
        // DOM events
3537
 
        
3538
 
        dojo.fixEvent = function(/*Event*/evt, /*DOMNode*/sender){
3539
 
                // summary:
3540
 
                //              normalizes properties on the event object including event
3541
 
                //              bubbling methods, keystroke normalization, and x/y positions
3542
 
                // evt: Event
3543
 
                //              native event object
3544
 
                // sender: DOMNode
3545
 
                //              node to treat as "currentTarget"
3546
 
                return del._fixEvent(evt, sender);
3547
 
        }
3548
 
 
3549
 
        dojo.stopEvent = function(/*Event*/evt){
3550
 
                // summary:
3551
 
                //              prevents propagation and clobbers the default action of the
3552
 
                //              passed event
3553
 
                // evt: Event
3554
 
                //              The event object. If omitted, window.event is used on IE.
3555
 
                evt.preventDefault();
3556
 
                evt.stopPropagation();
3557
 
                // NOTE: below, this method is overridden for IE
3558
 
        }
3559
 
 
3560
 
        // the default listener to use on dontFix nodes, overriden for IE
3561
 
        var node_listener = dojo._listener;
3562
 
        
3563
 
        // Unify connect and event listeners
3564
 
        dojo._connect = function(obj, event, context, method, dontFix){
3565
 
                // FIXME: need a more strict test
3566
 
                var isNode = obj && (obj.nodeType||obj.attachEvent||obj.addEventListener);
3567
 
                // choose one of three listener options: raw (connect.js), DOM event on a Node, custom event on a Node
3568
 
                // we need the third option to provide leak prevention on broken browsers (IE)
3569
 
                var lid = !isNode ? 0 : (!dontFix ? 1 : 2), l = [dojo._listener, del, node_listener][lid];
3570
 
                // create a listener
3571
 
                var h = l.add(obj, event, dojo.hitch(context, method));
3572
 
                // formerly, the disconnect package contained "l" directly, but if client code
3573
 
                // leaks the disconnect package (by connecting it to a node), referencing "l" 
3574
 
                // compounds the problem.
3575
 
                // instead we return a listener id, which requires custom _disconnect below.
3576
 
                // return disconnect package
3577
 
                return [ obj, event, h, lid ];
3578
 
        }
3579
 
 
3580
 
        dojo._disconnect = function(obj, event, handle, listener){
3581
 
                ([dojo._listener, del, node_listener][listener]).remove(obj, event, handle);
3582
 
        }
3583
 
 
3584
 
        // Constants
3585
 
 
3586
 
        // Public: client code should test
3587
 
        // keyCode against these named constants, as the
3588
 
        // actual codes can vary by browser.
3589
 
        dojo.keys = {
3590
 
                // summary: definitions for common key values
3591
 
                BACKSPACE: 8,
3592
 
                TAB: 9,
3593
 
                CLEAR: 12,
3594
 
                ENTER: 13,
3595
 
                SHIFT: 16,
3596
 
                CTRL: 17,
3597
 
                ALT: 18,
3598
 
                PAUSE: 19,
3599
 
                CAPS_LOCK: 20,
3600
 
                ESCAPE: 27,
3601
 
                SPACE: 32,
3602
 
                PAGE_UP: 33,
3603
 
                PAGE_DOWN: 34,
3604
 
                END: 35,
3605
 
                HOME: 36,
3606
 
                LEFT_ARROW: 37,
3607
 
                UP_ARROW: 38,
3608
 
                RIGHT_ARROW: 39,
3609
 
                DOWN_ARROW: 40,
3610
 
                INSERT: 45,
3611
 
                DELETE: 46,
3612
 
                HELP: 47,
3613
 
                LEFT_WINDOW: 91,
3614
 
                RIGHT_WINDOW: 92,
3615
 
                SELECT: 93,
3616
 
                NUMPAD_0: 96,
3617
 
                NUMPAD_1: 97,
3618
 
                NUMPAD_2: 98,
3619
 
                NUMPAD_3: 99,
3620
 
                NUMPAD_4: 100,
3621
 
                NUMPAD_5: 101,
3622
 
                NUMPAD_6: 102,
3623
 
                NUMPAD_7: 103,
3624
 
                NUMPAD_8: 104,
3625
 
                NUMPAD_9: 105,
3626
 
                NUMPAD_MULTIPLY: 106,
3627
 
                NUMPAD_PLUS: 107,
3628
 
                NUMPAD_ENTER: 108,
3629
 
                NUMPAD_MINUS: 109,
3630
 
                NUMPAD_PERIOD: 110,
3631
 
                NUMPAD_DIVIDE: 111,
3632
 
                F1: 112,
3633
 
                F2: 113,
3634
 
                F3: 114,
3635
 
                F4: 115,
3636
 
                F5: 116,
3637
 
                F6: 117,
3638
 
                F7: 118,
3639
 
                F8: 119,
3640
 
                F9: 120,
3641
 
                F10: 121,
3642
 
                F11: 122,
3643
 
                F12: 123,
3644
 
                F13: 124,
3645
 
                F14: 125,
3646
 
                F15: 126,
3647
 
                NUM_LOCK: 144,
3648
 
                SCROLL_LOCK: 145
3649
 
        };
3650
 
        
3651
 
        // IE event normalization
3652
 
        if(dojo.isIE){ 
3653
 
                var _trySetKeyCode = function(e, code){
3654
 
                        try{
3655
 
                                // squelch errors when keyCode is read-only
3656
 
                                // (e.g. if keyCode is ctrl or shift)
3657
 
                                return (e.keyCode = code);
3658
 
                        }catch(e){
3659
 
                                return 0;
3660
 
                        }
3661
 
                }
3662
 
 
3663
 
                // by default, use the standard listener
3664
 
                var iel = dojo._listener;
3665
 
                var listenersName = dojo._ieListenersName = "_" + dojo._scopeName + "_listeners";
3666
 
                // dispatcher tracking property
3667
 
                if(!dojo.config._allow_leaks){
3668
 
                        // custom listener that handles leak protection for DOM events
3669
 
                        node_listener = iel = dojo._ie_listener = {
3670
 
                                // support handler indirection: event handler functions are 
3671
 
                                // referenced here. Event dispatchers hold only indices.
3672
 
                                handlers: [],
3673
 
                                // add a listener to an object
3674
 
                                add: function(/*Object*/ source, /*String*/ method, /*Function*/ listener){
3675
 
                                        source = source || dojo.global;
3676
 
                                        var f = source[method];
3677
 
                                        if(!f||!f[listenersName]){
3678
 
                                                var d = dojo._getIeDispatcher();
3679
 
                                                // original target function is special
3680
 
                                                d.target = f && (ieh.push(f) - 1);
3681
 
                                                // dispatcher holds a list of indices into handlers table
3682
 
                                                d[listenersName] = [];
3683
 
                                                // redirect source to dispatcher
3684
 
                                                f = source[method] = d;
3685
 
                                        }
3686
 
                                        return f[listenersName].push(ieh.push(listener) - 1) ; /*Handle*/
3687
 
                                },
3688
 
                                // remove a listener from an object
3689
 
                                remove: function(/*Object*/ source, /*String*/ method, /*Handle*/ handle){
3690
 
                                        var f = (source||dojo.global)[method], l = f && f[listenersName];
3691
 
                                        if(f && l && handle--){
3692
 
                                                delete ieh[l[handle]];
3693
 
                                                delete l[handle];
3694
 
                                        }
3695
 
                                }
3696
 
                        };
3697
 
                        // alias used above
3698
 
                        var ieh = iel.handlers;
3699
 
                }
3700
 
 
3701
 
                dojo.mixin(del, {
3702
 
                        add: function(/*DOMNode*/node, /*String*/event, /*Function*/fp){
3703
 
                                if(!node){return;} // undefined
3704
 
                                event = del._normalizeEventName(event);
3705
 
                                if(event=="onkeypress"){
3706
 
                                        // we need to listen to onkeydown to synthesize
3707
 
                                        // keypress events that otherwise won't fire
3708
 
                                        // on IE
3709
 
                                        var kd = node.onkeydown;
3710
 
                                        if(!kd || !kd[listenersName] || !kd._stealthKeydownHandle){
3711
 
                                                var h = del.add(node, "onkeydown", del._stealthKeyDown);
3712
 
                                                kd = node.onkeydown;
3713
 
                                                kd._stealthKeydownHandle = h;
3714
 
                                                kd._stealthKeydownRefs = 1;
3715
 
                                        }else{
3716
 
                                                kd._stealthKeydownRefs++;
3717
 
                                        }
3718
 
                                }
3719
 
                                return iel.add(node, event, del._fixCallback(fp));
3720
 
                        },
3721
 
                        remove: function(/*DOMNode*/node, /*String*/event, /*Handle*/handle){
3722
 
                                event = del._normalizeEventName(event);
3723
 
                                iel.remove(node, event, handle); 
3724
 
                                if(event=="onkeypress"){
3725
 
                                        var kd = node.onkeydown;
3726
 
                                        if(--kd._stealthKeydownRefs <= 0){
3727
 
                                                iel.remove(node, "onkeydown", kd._stealthKeydownHandle);
3728
 
                                                delete kd._stealthKeydownHandle;
3729
 
                                        }
3730
 
                                }
3731
 
                        },
3732
 
                        _normalizeEventName: function(/*String*/eventName){
3733
 
                                // Generally, eventName should be lower case, unless it is
3734
 
                                // special somehow (e.g. a Mozilla event)
3735
 
                                // ensure 'on'
3736
 
                                return eventName.slice(0,2) != "on" ? "on" + eventName : eventName;
3737
 
                        },
3738
 
                        _nop: function(){},
3739
 
                        _fixEvent: function(/*Event*/evt, /*DOMNode*/sender){
3740
 
                                // summary:
3741
 
                                //              normalizes properties on the event object including event
3742
 
                                //              bubbling methods, keystroke normalization, and x/y positions
3743
 
                                // evt: native event object
3744
 
                                // sender: node to treat as "currentTarget"
3745
 
                                if(!evt){
3746
 
                                        var w = sender && (sender.ownerDocument || sender.document || sender).parentWindow || window;
3747
 
                                        evt = w.event; 
3748
 
                                }
3749
 
                                if(!evt){return(evt);}
3750
 
                                evt.target = evt.srcElement; 
3751
 
                                evt.currentTarget = (sender || evt.srcElement); 
3752
 
                                evt.layerX = evt.offsetX;
3753
 
                                evt.layerY = evt.offsetY;
3754
 
                                // FIXME: scroll position query is duped from dojo.html to
3755
 
                                // avoid dependency on that entire module. Now that HTML is in
3756
 
                                // Base, we should convert back to something similar there.
3757
 
                                var se = evt.srcElement, doc = (se && se.ownerDocument) || document;
3758
 
                                // DO NOT replace the following to use dojo.body(), in IE, document.documentElement should be used
3759
 
                                // here rather than document.body
3760
 
                                var docBody = ((dojo.isIE < 6) || (doc["compatMode"] == "BackCompat")) ? doc.body : doc.documentElement;
3761
 
                                var offset = dojo._getIeDocumentElementOffset();
3762
 
                                evt.pageX = evt.clientX + dojo._fixIeBiDiScrollLeft(docBody.scrollLeft || 0) - offset.x;
3763
 
                                evt.pageY = evt.clientY + (docBody.scrollTop || 0) - offset.y;
3764
 
                                if(evt.type == "mouseover"){ 
3765
 
                                        evt.relatedTarget = evt.fromElement;
3766
 
                                }
3767
 
                                if(evt.type == "mouseout"){ 
3768
 
                                        evt.relatedTarget = evt.toElement;
3769
 
                                }
3770
 
                                evt.stopPropagation = del._stopPropagation;
3771
 
                                evt.preventDefault = del._preventDefault;
3772
 
                                return del._fixKeys(evt);
3773
 
                        },
3774
 
                        _fixKeys: function(evt){
3775
 
                                switch(evt.type){
3776
 
                                        case "keypress":
3777
 
                                                var c = ("charCode" in evt ? evt.charCode : evt.keyCode);
3778
 
                                                if (c==10){
3779
 
                                                        // CTRL-ENTER is CTRL-ASCII(10) on IE, but CTRL-ENTER on Mozilla
3780
 
                                                        c=0;
3781
 
                                                        evt.keyCode = 13;
3782
 
                                                }else if(c==13||c==27){
3783
 
                                                        c=0; // Mozilla considers ENTER and ESC non-printable
3784
 
                                                }else if(c==3){
3785
 
                                                        c=99; // Mozilla maps CTRL-BREAK to CTRL-c
3786
 
                                                }
3787
 
                                                // Mozilla sets keyCode to 0 when there is a charCode
3788
 
                                                // but that stops the event on IE.
3789
 
                                                evt.charCode = c;
3790
 
                                                del._setKeyChar(evt);
3791
 
                                                break;
3792
 
                                }
3793
 
                                return evt;
3794
 
                        },
3795
 
                        _stealthKeyDown: function(evt){
3796
 
                                // IE doesn't fire keypress for most non-printable characters.
3797
 
                                // other browsers do, we simulate it here.
3798
 
                                var kp = evt.currentTarget.onkeypress;
3799
 
                                // only works if kp exists and is a dispatcher
3800
 
                                if(!kp || !kp[listenersName]){ return; }
3801
 
                                // munge key/charCode
3802
 
                                var k=evt.keyCode;
3803
 
                                // These are Windows Virtual Key Codes
3804
 
                                // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/WinUI/WindowsUserInterface/UserInput/VirtualKeyCodes.asp
3805
 
                                var unprintable = (k!=13)&&(k!=32)&&(k!=27)&&(k<48||k>90)&&(k<96||k>111)&&(k<186||k>192)&&(k<219||k>222);
3806
 
                                // synthesize keypress for most unprintables and CTRL-keys
3807
 
                                if(unprintable||evt.ctrlKey){
3808
 
                                        var c = unprintable ? 0 : k;
3809
 
                                        if(evt.ctrlKey){
3810
 
                                                if(k==3 || k==13){
3811
 
                                                        return; // IE will post CTRL-BREAK, CTRL-ENTER as keypress natively 
3812
 
                                                }else if(c>95 && c<106){ 
3813
 
                                                        c -= 48; // map CTRL-[numpad 0-9] to ASCII
3814
 
                                                }else if((!evt.shiftKey)&&(c>=65&&c<=90)){ 
3815
 
                                                        c += 32; // map CTRL-[A-Z] to lowercase
3816
 
                                                }else{ 
3817
 
                                                        c = del._punctMap[c] || c; // map other problematic CTRL combinations to ASCII
3818
 
                                                }
3819
 
                                        }
3820
 
                                        // simulate a keypress event
3821
 
                                        var faux = del._synthesizeEvent(evt, {type: 'keypress', faux: true, charCode: c});
3822
 
                                        kp.call(evt.currentTarget, faux);
3823
 
                                        evt.cancelBubble = faux.cancelBubble;
3824
 
                                        evt.returnValue = faux.returnValue;
3825
 
                                        _trySetKeyCode(evt, faux.keyCode);
3826
 
                                }
3827
 
                        },
3828
 
                        // Called in Event scope
3829
 
                        _stopPropagation: function(){
3830
 
                                this.cancelBubble = true; 
3831
 
                        },
3832
 
                        _preventDefault: function(){
3833
 
                                // Setting keyCode to 0 is the only way to prevent certain keypresses (namely
3834
 
                                // ctrl-combinations that correspond to menu accelerator keys).
3835
 
                                // Otoh, it prevents upstream listeners from getting this information
3836
 
                                // Try to split the difference here by clobbering keyCode only for ctrl 
3837
 
                                // combinations. If you still need to access the key upstream, bubbledKeyCode is
3838
 
                                // provided as a workaround.
3839
 
                                this.bubbledKeyCode = this.keyCode;
3840
 
                                if(this.ctrlKey){_trySetKeyCode(this, 0);}
3841
 
                                this.returnValue = false;
3842
 
                        }
3843
 
                });
3844
 
                                
3845
 
                // override stopEvent for IE
3846
 
                dojo.stopEvent = function(evt){
3847
 
                        evt = evt || window.event;
3848
 
                        del._stopPropagation.call(evt);
3849
 
                        del._preventDefault.call(evt);
3850
 
                }
3851
 
        }
3852
 
 
3853
 
        del._synthesizeEvent = function(evt, props){
3854
 
                        var faux = dojo.mixin({}, evt, props);
3855
 
                        del._setKeyChar(faux);
3856
 
                        // FIXME: would prefer to use dojo.hitch: dojo.hitch(evt, evt.preventDefault); 
3857
 
                        // but it throws an error when preventDefault is invoked on Safari
3858
 
                        // does Event.preventDefault not support "apply" on Safari?
3859
 
                        faux.preventDefault = function(){ evt.preventDefault(); }; 
3860
 
                        faux.stopPropagation = function(){ evt.stopPropagation(); }; 
3861
 
                        return faux;
3862
 
        }
3863
 
        
3864
 
        // Opera event normalization
3865
 
        if(dojo.isOpera){
3866
 
                dojo.mixin(del, {
3867
 
                        _fixEvent: function(evt, sender){
3868
 
                                switch(evt.type){
3869
 
                                        case "keypress":
3870
 
                                                var c = evt.which;
3871
 
                                                if(c==3){
3872
 
                                                        c=99; // Mozilla maps CTRL-BREAK to CTRL-c
3873
 
                                                }
3874
 
                                                // can't trap some keys at all, like INSERT and DELETE
3875
 
                                                // there is no differentiating info between DELETE and ".", or INSERT and "-"
3876
 
                                                c = ((c<41)&&(!evt.shiftKey) ? 0 : c);
3877
 
                                                if((evt.ctrlKey)&&(!evt.shiftKey)&&(c>=65)&&(c<=90)){
3878
 
                                                        // lowercase CTRL-[A-Z] keys
3879
 
                                                        c += 32;
3880
 
                                                }
3881
 
                                                return del._synthesizeEvent(evt, { charCode: c });
3882
 
                                }
3883
 
                                return evt;
3884
 
                        }
3885
 
                });
3886
 
        }
3887
 
 
3888
 
        // Safari event normalization
3889
 
        if(dojo.isSafari){
3890
 
                del._add = del.add;
3891
 
                del._remove = del.remove;
3892
 
 
3893
 
                dojo.mixin(del, {
3894
 
                        add: function(/*DOMNode*/node, /*String*/event, /*Function*/fp){
3895
 
                                if(!node){return;} // undefined
3896
 
                                var handle = del._add(node, event, fp);
3897
 
                                if(del._normalizeEventName(event) == "keypress"){
3898
 
                                        // we need to listen to onkeydown to synthesize
3899
 
                                        // keypress events that otherwise won't fire
3900
 
                                        // in Safari 3.1+: https://lists.webkit.org/pipermail/webkit-dev/2007-December/002992.html
3901
 
                                        handle._stealthKeyDownHandle = del._add(node, "keydown", function(evt){
3902
 
                                                //A variation on the IE _stealthKeydown function
3903
 
                                                //Synthesize an onkeypress event, but only for unprintable characters.
3904
 
                                                var k=evt.keyCode;
3905
 
                                                // These are Windows Virtual Key Codes
3906
 
                                                // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/WinUI/WindowsUserInterface/UserInput/VirtualKeyCodes.asp
3907
 
                                                var unprintable = (k!=13)&&(k!=32)&&(k!=27)&&(k<48||k>90)&&(k<96||k>111)&&(k<186||k>192)&&(k<219||k>222);
3908
 
                                                // synthesize keypress for most unprintables and CTRL-keys
3909
 
                                                if(unprintable||evt.ctrlKey){
3910
 
                                                        var c = unprintable ? 0 : k;
3911
 
                                                        if(evt.ctrlKey){
3912
 
                                                                if(k==3 || k==13){
3913
 
                                                                        return; // IE will post CTRL-BREAK, CTRL-ENTER as keypress natively 
3914
 
                                                                }else if(c>95 && c<106){ 
3915
 
                                                                        c -= 48; // map CTRL-[numpad 0-9] to ASCII
3916
 
                                                                }else if((!evt.shiftKey)&&(c>=65&&c<=90)){ 
3917
 
                                                                        c += 32; // map CTRL-[A-Z] to lowercase
3918
 
                                                                }else{ 
3919
 
                                                                        c = del._punctMap[c] || c; // map other problematic CTRL combinations to ASCII
3920
 
                                                                }
3921
 
                                                        }
3922
 
                                                        // simulate a keypress event
3923
 
                                                        var faux = del._synthesizeEvent(evt, {type: 'keypress', faux: true, charCode: c});
3924
 
                                                        fp.call(evt.currentTarget, faux);
3925
 
                                                }
3926
 
                                        });
3927
 
                                }
3928
 
                                return handle; /*Handle*/
3929
 
                        },
3930
 
 
3931
 
                        remove: function(/*DOMNode*/node, /*String*/event, /*Handle*/handle){
3932
 
                                if(node){
3933
 
                                        if(handle._stealthKeyDownHandle){
3934
 
                                                del._remove(node, "keydown", handle._stealthKeyDownHandle);
3935
 
                                        }
3936
 
                                        del._remove(node, event, handle);
3937
 
                                }
3938
 
                        },
3939
 
                        _fixEvent: function(evt, sender){
3940
 
                                switch(evt.type){
3941
 
                                        case "keypress":
3942
 
                                                if(evt.faux){ return evt; }
3943
 
                                                var c = evt.charCode;
3944
 
                                                c = c>=32? c : 0;
3945
 
                                                return del._synthesizeEvent(evt, {charCode: c, faux: true});
3946
 
                                }
3947
 
                                return evt;
3948
 
                        }
3949
 
                });
3950
 
        }
3951
 
})();
3952
 
 
3953
 
if(dojo.isIE){
3954
 
        // keep this out of the closure
3955
 
        // closing over 'iel' or 'ieh' b0rks leak prevention
3956
 
        // ls[i] is an index into the master handler array
3957
 
        dojo._ieDispatcher = function(args, sender){
3958
 
                var ap=Array.prototype, h=dojo._ie_listener.handlers, c=args.callee, ls=c[dojo._ieListenersName], t=h[c.target];
3959
 
                // return value comes from original target function
3960
 
                var r = t && t.apply(sender, args);
3961
 
                // make local copy of listener array so it's immutable during processing
3962
 
                var lls = [].concat(ls);
3963
 
                // invoke listeners after target function
3964
 
                for(var i in lls){
3965
 
                        if(!(i in ap)){
3966
 
                                h[lls[i]].apply(sender, args);
3967
 
                        }
3968
 
                }
3969
 
                return r;
3970
 
        }
3971
 
        dojo._getIeDispatcher = function(){
3972
 
                // ensure the returned function closes over nothing ("new Function" apparently doesn't close)
3973
 
                return new Function(dojo._scopeName + "._ieDispatcher(arguments, this)"); // function
3974
 
        }
3975
 
        // keep this out of the closure to reduce RAM allocation
3976
 
        dojo._event_listener._fixCallback = function(fp){
3977
 
                var f = dojo._event_listener._fixEvent;
3978
 
                return function(e){ return fp.call(this, f(e, this)); };
3979
 
        }
3980
 
}
3981
 
 
3982
 
}
3983
 
 
3984
 
if(!dojo._hasResource["dojo._base.html"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
3985
 
dojo._hasResource["dojo._base.html"] = true;
3986
 
 
3987
 
dojo.provide("dojo._base.html");
3988
 
 
3989
 
// FIXME: need to add unit tests for all the semi-public methods
3990
 
 
3991
 
try{
3992
 
        document.execCommand("BackgroundImageCache", false, true);
3993
 
}catch(e){
3994
 
        // sane browsers don't have cache "issues"
3995
 
}
3996
 
 
3997
 
// =============================
3998
 
// DOM Functions
3999
 
// =============================
4000
 
 
4001
 
/*=====
4002
 
dojo.byId = function(id, doc){
4003
 
        //      summary:
4004
 
        //              Returns DOM node with matching `id` attribute or `null` 
4005
 
        //              if not found, similar to "$" function in another library.
4006
 
        //              If `id` is a DomNode, this function is a no-op.
4007
 
        //
4008
 
        //      id: String|DOMNode
4009
 
        //              A string to match an HTML id attribute or a reference to a DOM Node
4010
 
        //
4011
 
        //      doc: Document?
4012
 
        //              Document to work in. Defaults to the current value of
4013
 
        //              dojo.doc.  Can be used to retrieve
4014
 
        //              node references from other documents.
4015
 
=====*/
4016
 
if(dojo.isIE || dojo.isOpera){
4017
 
        dojo.byId = function(id, doc){
4018
 
                if(dojo.isString(id)){
4019
 
                        var _d = doc || dojo.doc;
4020
 
                        var te = _d.getElementById(id);
4021
 
                        // attributes.id.value is better than just id in case the 
4022
 
                        // user has a name=id inside a form
4023
 
                        if(te && te.attributes.id.value == id){
4024
 
                                return te;
4025
 
                        }else{
4026
 
                                var eles = _d.all[id];
4027
 
                                if(!eles || !eles.length){ return eles; }
4028
 
                                // if more than 1, choose first with the correct id
4029
 
                                var i=0;
4030
 
                                while((te=eles[i++])){
4031
 
                                        if(te.attributes.id.value == id){ return te; }
4032
 
                                }
4033
 
                        }
4034
 
                }else{
4035
 
                        return id; // DomNode
4036
 
                }
4037
 
        }
4038
 
}else{
4039
 
        dojo.byId = function(id, doc){
4040
 
                return dojo.isString(id) ? (doc || dojo.doc).getElementById(id) : id; // DomNode
4041
 
        }
4042
 
}
4043
 
/*=====
4044
 
}
4045
 
=====*/
4046
 
 
4047
 
(function(){
4048
 
        var d = dojo;
4049
 
 
4050
 
        var _destroyContainer = null;
4051
 
        dojo.addOnWindowUnload(function(){
4052
 
                _destroyContainer=null; //prevent IE leak
4053
 
        });
4054
 
 
4055
 
        dojo._destroyElement = function(/*String||DomNode*/node){
4056
 
                // summary:
4057
 
                //              removes node from its parent, clobbers it and all of its
4058
 
                //              children.
4059
 
                //      node:
4060
 
                //              the element to be destroyed, either as an ID or a reference
4061
 
 
4062
 
                node = d.byId(node);
4063
 
                try{
4064
 
                        if(!_destroyContainer || _destroyContainer.ownerDocument != node.ownerDocument){
4065
 
                                _destroyContainer = node.ownerDocument.createElement("div");
4066
 
                        }
4067
 
                        _destroyContainer.appendChild(node.parentNode ? node.parentNode.removeChild(node) : node);
4068
 
                        // NOTE: see http://trac.dojotoolkit.org/ticket/2931. This may be a bug and not a feature
4069
 
                        _destroyContainer.innerHTML = ""; 
4070
 
                }catch(e){
4071
 
                        /* squelch */
4072
 
                }
4073
 
        };
4074
 
 
4075
 
        dojo.isDescendant = function(/*DomNode|String*/node, /*DomNode|String*/ancestor){
4076
 
                //      summary:
4077
 
                //              Returns true if node is a descendant of ancestor
4078
 
                //      node: id or node reference to test
4079
 
                //      ancestor: id or node reference of potential parent to test against
4080
 
                try{
4081
 
                        node = d.byId(node);
4082
 
                        ancestor = d.byId(ancestor);
4083
 
                        while(node){
4084
 
                                if(node === ancestor){
4085
 
                                        return true; // Boolean
4086
 
                                }
4087
 
                                node = node.parentNode;
4088
 
                        }
4089
 
                }catch(e){ /* squelch, return false */ }
4090
 
                return false; // Boolean
4091
 
        };
4092
 
 
4093
 
        dojo.setSelectable = function(/*DomNode|String*/node, /*Boolean*/selectable){
4094
 
                //      summary: enable or disable selection on a node
4095
 
                //      node:
4096
 
                //              id or reference to node
4097
 
                //      selectable:
4098
 
                node = d.byId(node);
4099
 
                if(d.isMozilla){
4100
 
                        node.style.MozUserSelect = selectable ? "" : "none";
4101
 
                }else if(d.isKhtml){
4102
 
                        node.style.KhtmlUserSelect = selectable ? "auto" : "none";
4103
 
                }else if(d.isIE){
4104
 
                        var v = (node.unselectable = selectable ? "" : "on");
4105
 
                        d.query("*", node).forEach("item.unselectable = '"+v+"'");
4106
 
                }
4107
 
                //FIXME: else?  Opera?
4108
 
        };
4109
 
 
4110
 
        var _insertBefore = function(/*Node*/node, /*Node*/ref){
4111
 
                ref.parentNode.insertBefore(node, ref);
4112
 
                return true;    //      boolean
4113
 
        }
4114
 
 
4115
 
        var _insertAfter = function(/*Node*/node, /*Node*/ref){
4116
 
                //      summary:
4117
 
                //              Try to insert node after ref
4118
 
                var pn = ref.parentNode;
4119
 
                if(ref == pn.lastChild){
4120
 
                        pn.appendChild(node);
4121
 
                }else{
4122
 
                        return _insertBefore(node, ref.nextSibling);    //      boolean
4123
 
                }
4124
 
                return true;    //      boolean
4125
 
        }
4126
 
 
4127
 
        dojo.place = function(/*String|DomNode*/node, /*String|DomNode*/refNode, /*String?|Number?*/position){
4128
 
                //      summary:
4129
 
                //              Attempt to insert node into the DOM, choosing from various positioning options.
4130
 
                //              Returns true if successful, false otherwise.
4131
 
                //      node: 
4132
 
                //              id or node reference to place relative to refNode
4133
 
                //      refNode: 
4134
 
                //              id or node reference to use as basis for placement
4135
 
                //      position:
4136
 
                //              string noting the position of node relative to refNode or a
4137
 
                //              number indicating the location in the childNodes collection of refNode. 
4138
 
                //              Accepted string values are:
4139
 
                //              * before
4140
 
                //              * after
4141
 
                //              * first
4142
 
                //              * last
4143
 
                //
4144
 
                //              "first" and "last" indicate positions as children of refNode.  position defaults
4145
 
                //              to "last" if not specified
4146
 
 
4147
 
                // FIXME: need to write tests for this!!!!
4148
 
                if(!node || !refNode){
4149
 
                        return false;   //      boolean 
4150
 
                }
4151
 
                node = d.byId(node);
4152
 
                refNode = d.byId(refNode);
4153
 
                if(typeof position == "number"){
4154
 
                        var cn = refNode.childNodes;
4155
 
                        if(!cn.length || cn.length <= position){
4156
 
                                refNode.appendChild(node);
4157
 
                                return true;
4158
 
                        }
4159
 
                        return _insertBefore(node, position <= 0 ? refNode.firstChild : cn[position]);
4160
 
                }
4161
 
                switch(position){
4162
 
                        case "before":
4163
 
                                return _insertBefore(node, refNode);    //      boolean
4164
 
                        case "after":
4165
 
                                return _insertAfter(node, refNode);             //      boolean
4166
 
                        case "first":
4167
 
                                if(refNode.firstChild){
4168
 
                                        return _insertBefore(node, refNode.firstChild); //      boolean
4169
 
                                }
4170
 
                                // else fallthrough...
4171
 
                        default: // aka: last
4172
 
                                refNode.appendChild(node);
4173
 
                                return true;    //      boolean
4174
 
                }
4175
 
        }
4176
 
 
4177
 
        // Box functions will assume this model.
4178
 
        // On IE/Opera, BORDER_BOX will be set if the primary document is in quirks mode.
4179
 
        // Can be set to change behavior of box setters.
4180
 
        
4181
 
        // can be either:
4182
 
        //      "border-box"
4183
 
        //      "content-box" (default)
4184
 
        dojo.boxModel = "content-box";
4185
 
        
4186
 
        // We punt per-node box mode testing completely.
4187
 
        // If anybody cares, we can provide an additional (optional) unit 
4188
 
        // that overrides existing code to include per-node box sensitivity.
4189
 
 
4190
 
        // Opera documentation claims that Opera 9 uses border-box in BackCompat mode.
4191
 
        // but experiments (Opera 9.10.8679 on Windows Vista) indicate that it actually continues to use content-box.
4192
 
        // IIRC, earlier versions of Opera did in fact use border-box.
4193
 
        // Opera guys, this is really confusing. Opera being broken in quirks mode is not our fault.
4194
 
 
4195
 
        if(d.isIE /*|| dojo.isOpera*/){
4196
 
                var _dcm = document.compatMode;
4197
 
                // client code may have to adjust if compatMode varies across iframes
4198
 
                d.boxModel = _dcm == "BackCompat" || _dcm == "QuirksMode" || d.isIE<6 ? "border-box" : "content-box"; // FIXME: remove IE < 6 support?
4199
 
        }
4200
 
 
4201
 
        // =============================
4202
 
        // Style Functions
4203
 
        // =============================
4204
 
        
4205
 
        // getComputedStyle drives most of the style code.
4206
 
        // Wherever possible, reuse the returned object.
4207
 
        //
4208
 
        // API functions below that need to access computed styles accept an 
4209
 
        // optional computedStyle parameter.
4210
 
        // If this parameter is omitted, the functions will call getComputedStyle themselves.
4211
 
        // This way, calling code can access computedStyle once, and then pass the reference to 
4212
 
        // multiple API functions. 
4213
 
 
4214
 
/*=====
4215
 
        dojo.getComputedStyle = function(node){
4216
 
                //      summary:
4217
 
                //              Returns a "computed style" object.
4218
 
                //
4219
 
                //      description:
4220
 
                //              Gets a "computed style" object which can be used to gather
4221
 
                //              information about the current state of the rendered node. 
4222
 
                //
4223
 
                //              Note that this may behave differently on different browsers.
4224
 
                //              Values may have different formats and value encodings across
4225
 
                //              browsers.
4226
 
                //
4227
 
                //              Note also that this method is expensive.  Wherever possible,
4228
 
                //              reuse the returned object.
4229
 
                //
4230
 
                //              Use the dojo.style() method for more consistent (pixelized)
4231
 
                //              return values.
4232
 
                //
4233
 
                //      node: DOMNode
4234
 
                //              A reference to a DOM node. Does NOT support taking an
4235
 
                //              ID string for speed reasons.
4236
 
                //      example:
4237
 
                //      |       dojo.getComputedStyle(dojo.byId('foo')).borderWidth;
4238
 
                return; // CSS2Properties
4239
 
        }
4240
 
=====*/
4241
 
 
4242
 
        // Although we normally eschew argument validation at this
4243
 
        // level, here we test argument 'node' for (duck)type.
4244
 
        // Argument node must also implement Element.  (Note: we check
4245
 
        // against HTMLElement rather than Element for interop with prototype.js)
4246
 
        // Because 'document' is the 'parentNode' of 'body'
4247
 
        // it is frequently sent to this function even 
4248
 
        // though it is not Element.
4249
 
        var gcs;
4250
 
        if(d.isSafari){
4251
 
                gcs = function(/*DomNode*/node){
4252
 
                        var s;
4253
 
                        if(node instanceof HTMLElement){
4254
 
                                var dv = node.ownerDocument.defaultView;
4255
 
                                s = dv.getComputedStyle(node, null);
4256
 
                                if(!s && node.style){ 
4257
 
                                        node.style.display = ""; 
4258
 
                                        s = dv.getComputedStyle(node, null);
4259
 
                                }
4260
 
                        }
4261
 
                        return s || {};
4262
 
                }; 
4263
 
        }else if(d.isIE){
4264
 
                gcs = function(node){
4265
 
                        // IE (as of 7) doesn't expose Element like sane browsers
4266
 
                        return node.nodeType == 1 /* ELEMENT_NODE*/ ? node.currentStyle : {};
4267
 
                };
4268
 
        }else{
4269
 
                gcs = function(node){
4270
 
                        return node instanceof HTMLElement ? 
4271
 
                                node.ownerDocument.defaultView.getComputedStyle(node, null) : {};
4272
 
                };
4273
 
        }
4274
 
        dojo.getComputedStyle = gcs;
4275
 
 
4276
 
        if(!d.isIE){
4277
 
                dojo._toPixelValue = function(element, value){
4278
 
                        // style values can be floats, client code may want
4279
 
                        // to round for integer pixels.
4280
 
                        return parseFloat(value) || 0; 
4281
 
                };
4282
 
        }else{
4283
 
                dojo._toPixelValue = function(element, avalue){
4284
 
                        if(!avalue){ return 0; }
4285
 
                        // on IE7, medium is usually 4 pixels
4286
 
                        if(avalue=="medium"){ return 4; }
4287
 
                        // style values can be floats, client code may
4288
 
                        // want to round this value for integer pixels.
4289
 
                        if(avalue.slice && (avalue.slice(-2)=='px')){ return parseFloat(avalue); }
4290
 
                        with(element){
4291
 
                                var sLeft = style.left;
4292
 
                                var rsLeft = runtimeStyle.left;
4293
 
                                runtimeStyle.left = currentStyle.left;
4294
 
                                try{
4295
 
                                        // 'avalue' may be incompatible with style.left, which can cause IE to throw
4296
 
                                        // this has been observed for border widths using "thin", "medium", "thick" constants
4297
 
                                        // those particular constants could be trapped by a lookup
4298
 
                                        // but perhaps there are more
4299
 
                                        style.left = avalue;
4300
 
                                        avalue = style.pixelLeft;
4301
 
                                }catch(e){
4302
 
                                        avalue = 0;
4303
 
                                }
4304
 
                                style.left = sLeft;
4305
 
                                runtimeStyle.left = rsLeft;
4306
 
                        }
4307
 
                        return avalue;
4308
 
                }
4309
 
        }
4310
 
        var px = d._toPixelValue;
4311
 
 
4312
 
        // FIXME: there opacity quirks on FF that we haven't ported over. Hrm.
4313
 
        /*=====
4314
 
        dojo._getOpacity = function(node){
4315
 
                        //      summary:
4316
 
                        //              Returns the current opacity of the passed node as a
4317
 
                        //              floating-point value between 0 and 1.
4318
 
                        //      node: DomNode
4319
 
                        //              a reference to a DOM node. Does NOT support taking an
4320
 
                        //              ID string for speed reasons.
4321
 
                        //      returns: Number between 0 and 1
4322
 
                        return; // Number
4323
 
        }
4324
 
        =====*/
4325
 
 
4326
 
        var astr = "DXImageTransform.Microsoft.Alpha";
4327
 
        var af = function(n, f){ 
4328
 
                try{
4329
 
                        return n.filters.item(astr);
4330
 
                }catch(e){
4331
 
                        return f ? {} : null;
4332
 
                }
4333
 
        }
4334
 
 
4335
 
        dojo._getOpacity = d.isIE ? function(node){
4336
 
                try{
4337
 
                        return af(node).Opacity / 100; // Number
4338
 
                }catch(e){
4339
 
                        return 1; // Number
4340
 
                }
4341
 
        } : function(node){
4342
 
                return gcs(node).opacity;
4343
 
        };
4344
 
 
4345
 
        /*=====
4346
 
        dojo._setOpacity = function(node, opacity){
4347
 
                        //      summary:
4348
 
                        //              set the opacity of the passed node portably. Returns the
4349
 
                        //              new opacity of the node.
4350
 
                        //      node: DOMNode
4351
 
                        //              a reference to a DOM node. Does NOT support taking an
4352
 
                        //              ID string for performance reasons.
4353
 
                        //      opacity: Number
4354
 
                        //              A Number between 0 and 1. 0 specifies transparent.
4355
 
                        //      returns: Number between 0 and 1
4356
 
                        return; // Number
4357
 
        }
4358
 
        =====*/
4359
 
 
4360
 
        dojo._setOpacity = d.isIE ? function(/*DomNode*/node, /*Number*/opacity){
4361
 
                var ov = opacity * 100;
4362
 
                node.style.zoom = 1.0;
4363
 
 
4364
 
                // on IE7 Alpha(Filter opacity=100) makes text look fuzzy so disable it altogether (bug #2661),
4365
 
                //but still update the opacity value so we can get a correct reading if it is read later.
4366
 
                af(node, 1).Enabled = (opacity == 1 ? false : true);
4367
 
 
4368
 
                if(!af(node)){
4369
 
                        node.style.filter += " progid:"+astr+"(Opacity="+ov+")";
4370
 
                }else{
4371
 
                        af(node, 1).Opacity = ov;
4372
 
                }
4373
 
 
4374
 
                if(node.nodeName.toLowerCase() == "tr"){
4375
 
                        d.query("> td", node).forEach(function(i){
4376
 
                                d._setOpacity(i, opacity);
4377
 
                        });
4378
 
                }
4379
 
                return opacity;
4380
 
        } : function(node, opacity){
4381
 
                return node.style.opacity = opacity;
4382
 
        };
4383
 
 
4384
 
        var _pixelNamesCache = {
4385
 
                left: true, top: true
4386
 
        };
4387
 
        var _pixelRegExp = /margin|padding|width|height|max|min|offset/;  // |border
4388
 
        var _toStyleValue = function(node, type, value){
4389
 
                type = type.toLowerCase(); // FIXME: should we really be doing string case conversion here? Should we cache it? Need to profile!
4390
 
                if(d.isIE){
4391
 
                        if(value == "auto"){
4392
 
                                if(type == "height"){ return node.offsetHeight; }
4393
 
                                if(type == "width"){ return node.offsetWidth; }
4394
 
                        }
4395
 
                        if(type == "fontweight"){
4396
 
                                switch(value){
4397
 
                                        case 700: return "bold";
4398
 
                                        case 400:
4399
 
                                        default: return "normal";
4400
 
                                }
4401
 
                        }
4402
 
                }
4403
 
                if(!(type in _pixelNamesCache)){
4404
 
                        _pixelNamesCache[type] = _pixelRegExp.test(type);
4405
 
                }
4406
 
                return _pixelNamesCache[type] ? px(node, value) : value;
4407
 
        }
4408
 
 
4409
 
        var _floatStyle = d.isIE ? "styleFloat" : "cssFloat";
4410
 
        var _floatAliases = { "cssFloat": _floatStyle, "styleFloat": _floatStyle, "float": _floatStyle };
4411
 
        
4412
 
        // public API
4413
 
        
4414
 
        dojo.style = function(  /*DomNode|String*/ node, 
4415
 
                                                        /*String?|Object?*/ style, 
4416
 
                                                        /*String?*/ value){
4417
 
                //      summary:
4418
 
                //              Accesses styles on a node. If 2 arguments are
4419
 
                //              passed, acts as a getter. If 3 arguments are passed, acts
4420
 
                //              as a setter.
4421
 
                //      node:
4422
 
                //              id or reference to node to get/set style for
4423
 
                //      style:
4424
 
                //              the style property to set in DOM-accessor format
4425
 
                //              ("borderWidth", not "border-width") or an object with key/value
4426
 
                //              pairs suitable for setting each property.
4427
 
                //      value:
4428
 
                //              If passed, sets value on the node for style, handling
4429
 
                //              cross-browser concerns.
4430
 
                //      example:
4431
 
                //              Passing only an ID or node returns the computed style object of
4432
 
                //              the node:
4433
 
                //      |       dojo.style("thinger");
4434
 
                //      example:
4435
 
                //              Passing a node and a style property returns the current
4436
 
                //              normalized, computed value for that property:
4437
 
                //      |       dojo.style("thinger", "opacity"); // 1 by default
4438
 
                //
4439
 
                //      example:
4440
 
                //              Passing a node, a style property, and a value changes the
4441
 
                //              current display of the node and returns the new computed value
4442
 
                //      |       dojo.style("thinger", "opacity", 0.5); // == 0.5
4443
 
                //
4444
 
                //      example:
4445
 
                //              Passing a node, an object-style style property sets each of the values in turn and returns the computed style object of the node:
4446
 
                //      |       dojo.style("thinger", {
4447
 
                //      |               "opacity": 0.5,
4448
 
                //      |               "border": "3px solid black",
4449
 
                //      |               "height": 300
4450
 
                //      |       });
4451
 
                //
4452
 
                //      example:
4453
 
                //              When the CSS style property is hyphenated, the JavaScript property is camelCased.
4454
 
                //              font-size becomes fontSize, and so on.
4455
 
                //      |       dojo.style("thinger",{
4456
 
                //      |               fontSize:"14pt",
4457
 
                //      |               letterSpacing:"1.2em"
4458
 
                //      |       });
4459
 
                //
4460
 
                //      example:
4461
 
                //              dojo.NodeList implements .style() using the same syntax, omitting the "node" parameter, calling
4462
 
                //              dojo.style() on every element of the list. See: dojo.query and dojo.NodeList
4463
 
                //      |       dojo.query(".someClassName").style("visibility","hidden");
4464
 
                //      |       // or
4465
 
                //      |       dojo.query("#baz > div").style({
4466
 
                //      |               opacity:0.75,
4467
 
                //      |               fontSize:"13pt"
4468
 
                //      |       });
4469
 
 
4470
 
                var n = d.byId(node), args = arguments.length, op = (style=="opacity");
4471
 
                style = _floatAliases[style] || style;
4472
 
                if(args == 3){
4473
 
                        return op ? d._setOpacity(n, value) : n.style[style] = value; /*Number*/
4474
 
                }
4475
 
                if(args == 2 && op){
4476
 
                        return d._getOpacity(n);
4477
 
                }
4478
 
                var s = gcs(n);
4479
 
                if(args == 2 && !d.isString(style)){
4480
 
                        for(var x in style){
4481
 
                                d.style(node, x, style[x]);
4482
 
                        }
4483
 
                        return s;
4484
 
                }
4485
 
                return (args == 1) ? s : _toStyleValue(n, style, s[style]||n.style[style]); /* CSS2Properties||String||Number */
4486
 
        }
4487
 
 
4488
 
        // =============================
4489
 
        // Box Functions
4490
 
        // =============================
4491
 
 
4492
 
        dojo._getPadExtents = function(/*DomNode*/n, /*Object*/computedStyle){
4493
 
                //      summary:
4494
 
                //              Returns object with special values specifically useful for node
4495
 
                //              fitting.
4496
 
                //
4497
 
                //              * l/t = left/top padding (respectively)
4498
 
                //              * w = the total of the left and right padding 
4499
 
                //              * h = the total of the top and bottom padding
4500
 
                //
4501
 
                //              If 'node' has position, l/t forms the origin for child nodes. 
4502
 
                //              The w/h are used for calculating boxes.
4503
 
                //              Normally application code will not need to invoke this
4504
 
                //              directly, and will use the ...box... functions instead.
4505
 
                var 
4506
 
                        s = computedStyle||gcs(n), 
4507
 
                        l = px(n, s.paddingLeft), 
4508
 
                        t = px(n, s.paddingTop);
4509
 
                return { 
4510
 
                        l: l,
4511
 
                        t: t,
4512
 
                        w: l+px(n, s.paddingRight),
4513
 
                        h: t+px(n, s.paddingBottom)
4514
 
                };
4515
 
        }
4516
 
 
4517
 
        dojo._getBorderExtents = function(/*DomNode*/n, /*Object*/computedStyle){
4518
 
                //      summary:
4519
 
                //              returns an object with properties useful for noting the border
4520
 
                //              dimensions.
4521
 
                //
4522
 
                //              * l/t = the sum of left/top border (respectively)
4523
 
                //              * w = the sum of the left and right border
4524
 
                //              * h = the sum of the top and bottom border
4525
 
                //
4526
 
                //              The w/h are used for calculating boxes.
4527
 
                //              Normally application code will not need to invoke this
4528
 
                //              directly, and will use the ...box... functions instead.
4529
 
                var 
4530
 
                        ne = "none",
4531
 
                        s = computedStyle||gcs(n), 
4532
 
                        bl = (s.borderLeftStyle != ne ? px(n, s.borderLeftWidth) : 0),
4533
 
                        bt = (s.borderTopStyle != ne ? px(n, s.borderTopWidth) : 0);
4534
 
                return { 
4535
 
                        l: bl,
4536
 
                        t: bt,
4537
 
                        w: bl + (s.borderRightStyle!=ne ? px(n, s.borderRightWidth) : 0),
4538
 
                        h: bt + (s.borderBottomStyle!=ne ? px(n, s.borderBottomWidth) : 0)
4539
 
                };
4540
 
        }
4541
 
 
4542
 
        dojo._getPadBorderExtents = function(/*DomNode*/n, /*Object*/computedStyle){
4543
 
                //      summary:
4544
 
                //              returns object with properties useful for box fitting with
4545
 
                //              regards to padding.
4546
 
                //
4547
 
                //              * l/t = the sum of left/top padding and left/top border (respectively)
4548
 
                //              * w = the sum of the left and right padding and border
4549
 
                //              * h = the sum of the top and bottom padding and border
4550
 
                //
4551
 
                //              The w/h are used for calculating boxes.
4552
 
                //              Normally application code will not need to invoke this
4553
 
                //              directly, and will use the ...box... functions instead.
4554
 
                var 
4555
 
                        s = computedStyle||gcs(n), 
4556
 
                        p = d._getPadExtents(n, s),
4557
 
                        b = d._getBorderExtents(n, s);
4558
 
                return { 
4559
 
                        l: p.l + b.l,
4560
 
                        t: p.t + b.t,
4561
 
                        w: p.w + b.w,
4562
 
                        h: p.h + b.h
4563
 
                };
4564
 
        }
4565
 
 
4566
 
        dojo._getMarginExtents = function(n, computedStyle){
4567
 
                //      summary:
4568
 
                //              returns object with properties useful for box fitting with
4569
 
                //              regards to box margins (i.e., the outer-box).
4570
 
                //
4571
 
                //              * l/t = marginLeft, marginTop, respectively
4572
 
                //              * w = total width, margin inclusive
4573
 
                //              * h = total height, margin inclusive
4574
 
                //
4575
 
                //              The w/h are used for calculating boxes.
4576
 
                //              Normally application code will not need to invoke this
4577
 
                //              directly, and will use the ...box... functions instead.
4578
 
                var 
4579
 
                        s = computedStyle||gcs(n), 
4580
 
                        l = px(n, s.marginLeft),
4581
 
                        t = px(n, s.marginTop),
4582
 
                        r = px(n, s.marginRight),
4583
 
                        b = px(n, s.marginBottom);
4584
 
                if(d.isSafari && (s.position != "absolute")){
4585
 
                        // FIXME: Safari's version of the computed right margin
4586
 
                        // is the space between our right edge and the right edge 
4587
 
                        // of our offsetParent. 
4588
 
                        // What we are looking for is the actual margin value as 
4589
 
                        // determined by CSS.
4590
 
                        // Hack solution is to assume left/right margins are the same.
4591
 
                        r = l;
4592
 
                }
4593
 
                return { 
4594
 
                        l: l,
4595
 
                        t: t,
4596
 
                        w: l+r,
4597
 
                        h: t+b
4598
 
                };
4599
 
        }
4600
 
 
4601
 
        // Box getters work in any box context because offsetWidth/clientWidth
4602
 
        // are invariant wrt box context
4603
 
        //
4604
 
        // They do *not* work for display: inline objects that have padding styles
4605
 
        // because the user agent ignores padding (it's bogus styling in any case)
4606
 
        //
4607
 
        // Be careful with IMGs because they are inline or block depending on 
4608
 
        // browser and browser mode.
4609
 
 
4610
 
        // Although it would be easier to read, there are not separate versions of 
4611
 
        // _getMarginBox for each browser because:
4612
 
        // 1. the branching is not expensive
4613
 
        // 2. factoring the shared code wastes cycles (function call overhead)
4614
 
        // 3. duplicating the shared code wastes bytes
4615
 
        
4616
 
        dojo._getMarginBox = function(/*DomNode*/node, /*Object*/computedStyle){
4617
 
                // summary:
4618
 
                //              returns an object that encodes the width, height, left and top
4619
 
                //              positions of the node's margin box.
4620
 
                var s = computedStyle||gcs(node), me = d._getMarginExtents(node, s);
4621
 
                var l = node.offsetLeft - me.l, t = node.offsetTop - me.t, p = node.parentNode;
4622
 
                if(d.isMoz){
4623
 
                        // Mozilla:
4624
 
                        // If offsetParent has a computed overflow != visible, the offsetLeft is decreased
4625
 
                        // by the parent's border.
4626
 
                        // We don't want to compute the parent's style, so instead we examine node's
4627
 
                        // computed left/top which is more stable.
4628
 
                        var sl = parseFloat(s.left), st = parseFloat(s.top);
4629
 
                        if(!isNaN(sl) && !isNaN(st)){
4630
 
                                l = sl, t = st;
4631
 
                        }else{
4632
 
                                // If child's computed left/top are not parseable as a number (e.g. "auto"), we
4633
 
                                // have no choice but to examine the parent's computed style.
4634
 
                                if(p && p.style){
4635
 
                                        var pcs = gcs(p);
4636
 
                                        if(pcs.overflow != "visible"){
4637
 
                                                var be = d._getBorderExtents(p, pcs);
4638
 
                                                l += be.l, t += be.t;
4639
 
                                        }
4640
 
                                }
4641
 
                        }
4642
 
                }else if(d.isOpera){
4643
 
                        // On Opera, offsetLeft includes the parent's border
4644
 
                        if(p){
4645
 
                                var be = d._getBorderExtents(p);
4646
 
                                l -= be.l;
4647
 
                                t -= be.t;
4648
 
                        }
4649
 
                }
4650
 
                return { 
4651
 
                        l: l, 
4652
 
                        t: t, 
4653
 
                        w: node.offsetWidth + me.w, 
4654
 
                        h: node.offsetHeight + me.h 
4655
 
                };
4656
 
        }
4657
 
        
4658
 
        dojo._getContentBox = function(node, computedStyle){
4659
 
                // summary:
4660
 
                //              Returns an object that encodes the width, height, left and top
4661
 
                //              positions of the node's content box, irrespective of the
4662
 
                //              current box model.
4663
 
 
4664
 
                // clientWidth/Height are important since the automatically account for scrollbars
4665
 
                // fallback to offsetWidth/Height for special cases (see #3378)
4666
 
                var s=computedStyle||gcs(node), pe=d._getPadExtents(node, s), be=d._getBorderExtents(node, s), w=node.clientWidth, h;
4667
 
                if(!w){
4668
 
                        w=node.offsetWidth, h=node.offsetHeight;
4669
 
                }else{
4670
 
                        h=node.clientHeight, be.w = be.h = 0; 
4671
 
                }
4672
 
                // On Opera, offsetLeft includes the parent's border
4673
 
                if(d.isOpera){ pe.l += be.l; pe.t += be.t; };
4674
 
                return { 
4675
 
                        l: pe.l, 
4676
 
                        t: pe.t, 
4677
 
                        w: w - pe.w - be.w, 
4678
 
                        h: h - pe.h - be.h
4679
 
                };
4680
 
        }
4681
 
 
4682
 
        dojo._getBorderBox = function(node, computedStyle){
4683
 
                var s=computedStyle||gcs(node), pe=d._getPadExtents(node, s), cb=d._getContentBox(node, s);
4684
 
                return { 
4685
 
                        l: cb.l - pe.l, 
4686
 
                        t: cb.t - pe.t, 
4687
 
                        w: cb.w + pe.w, 
4688
 
                        h: cb.h + pe.h
4689
 
                };
4690
 
        }
4691
 
 
4692
 
        // Box setters depend on box context because interpretation of width/height styles
4693
 
        // vary wrt box context.
4694
 
        //
4695
 
        // The value of dojo.boxModel is used to determine box context.
4696
 
        // dojo.boxModel can be set directly to change behavior.
4697
 
        //
4698
 
        // Beware of display: inline objects that have padding styles
4699
 
        // because the user agent ignores padding (it's a bogus setup anyway)
4700
 
        //
4701
 
        // Be careful with IMGs because they are inline or block depending on 
4702
 
        // browser and browser mode.
4703
 
        // 
4704
 
        // Elements other than DIV may have special quirks, like built-in
4705
 
        // margins or padding, or values not detectable via computedStyle.
4706
 
        // In particular, margins on TABLE do not seems to appear 
4707
 
        // at all in computedStyle on Mozilla.
4708
 
        
4709
 
        dojo._setBox = function(/*DomNode*/node, /*Number?*/l, /*Number?*/t, /*Number?*/w, /*Number?*/h, /*String?*/u){
4710
 
                //      summary:
4711
 
                //              sets width/height/left/top in the current (native) box-model
4712
 
                //              dimentions. Uses the unit passed in u.
4713
 
                //      node: DOM Node reference. Id string not supported for performance reasons.
4714
 
                //      l: optional. left offset from parent.
4715
 
                //      t: optional. top offset from parent.
4716
 
                //      w: optional. width in current box model.
4717
 
                //      h: optional. width in current box model.
4718
 
                //      u: optional. unit measure to use for other measures. Defaults to "px".
4719
 
                u = u || "px";
4720
 
                var s = node.style;
4721
 
                if(!isNaN(l)){ s.left = l+u; }
4722
 
                if(!isNaN(t)){ s.top = t+u; }
4723
 
                if(w>=0){ s.width = w+u; }
4724
 
                if(h>=0){ s.height = h+u; }
4725
 
        }
4726
 
 
4727
 
        dojo._isButtonTag = function(/*DomNode*/node) {
4728
 
                // summary:
4729
 
                //              True if the node is BUTTON or INPUT.type="button".
4730
 
                return node.tagName == "BUTTON" 
4731
 
                        || node.tagName=="INPUT" && node.getAttribute("type").toUpperCase() == "BUTTON"; // boolean
4732
 
        }
4733
 
        
4734
 
        dojo._usesBorderBox = function(/*DomNode*/node){
4735
 
                //      summary: 
4736
 
                //              True if the node uses border-box layout.
4737
 
 
4738
 
                // We could test the computed style of node to see if a particular box
4739
 
                // has been specified, but there are details and we choose not to bother.
4740
 
                
4741
 
                // TABLE and BUTTON (and INPUT type=button) are always border-box by default.
4742
 
                // If you have assigned a different box to either one via CSS then
4743
 
                // box functions will break.
4744
 
                
4745
 
                var n = node.tagName;
4746
 
                return d.boxModel=="border-box" || n=="TABLE" || dojo._isButtonTag(node); // boolean
4747
 
        }
4748
 
 
4749
 
        dojo._setContentSize = function(/*DomNode*/node, /*Number*/widthPx, /*Number*/heightPx, /*Object*/computedStyle){
4750
 
                //      summary:
4751
 
                //              Sets the size of the node's contents, irrespective of margins,
4752
 
                //              padding, or borders.
4753
 
                if(d._usesBorderBox(node)){
4754
 
                        var pb = d._getPadBorderExtents(node, computedStyle);
4755
 
                        if(widthPx >= 0){ widthPx += pb.w; }
4756
 
                        if(heightPx >= 0){ heightPx += pb.h; }
4757
 
                }
4758
 
                d._setBox(node, NaN, NaN, widthPx, heightPx);
4759
 
        }
4760
 
 
4761
 
        dojo._setMarginBox = function(/*DomNode*/node,  /*Number?*/leftPx, /*Number?*/topPx, 
4762
 
                                                                                                        /*Number?*/widthPx, /*Number?*/heightPx, 
4763
 
                                                                                                        /*Object*/computedStyle){
4764
 
                //      summary:
4765
 
                //              sets the size of the node's margin box and placement
4766
 
                //              (left/top), irrespective of box model. Think of it as a
4767
 
                //              passthrough to dojo._setBox that handles box-model vagaries for
4768
 
                //              you.
4769
 
 
4770
 
                var s = computedStyle||gcs(node);
4771
 
                // Some elements have special padding, margin, and box-model settings. 
4772
 
                // To use box functions you may need to set padding, margin explicitly.
4773
 
                // Controlling box-model is harder, in a pinch you might set dojo.boxModel.
4774
 
                var bb=d._usesBorderBox(node),
4775
 
                                pb=bb ? _nilExtents : d._getPadBorderExtents(node, s);
4776
 
                if (dojo.isSafari) {
4777
 
                        // on Safari (3.1.2), button nodes with no explicit size have a default margin
4778
 
                        // setting an explicit size eliminates the margin.
4779
 
                        // We have to swizzle the width to get correct margin reading.
4780
 
                        if (dojo._isButtonTag(node)){
4781
 
                                var ns = node.style;
4782
 
                                if (widthPx>=0 && !ns.width) { ns.width = "4px"; }
4783
 
                                if (heightPx>=0 && !ns.height) { ns.height = "4px"; }
4784
 
                        }
4785
 
                }
4786
 
                var mb=d._getMarginExtents(node, s);
4787
 
                if(widthPx>=0){ widthPx = Math.max(widthPx - pb.w - mb.w, 0); }
4788
 
                if(heightPx>=0){ heightPx = Math.max(heightPx - pb.h - mb.h, 0); }
4789
 
                d._setBox(node, leftPx, topPx, widthPx, heightPx);
4790
 
        }
4791
 
        
4792
 
        var _nilExtents = { l:0, t:0, w:0, h:0 };
4793
 
 
4794
 
        // public API
4795
 
        
4796
 
        dojo.marginBox = function(/*DomNode|String*/node, /*Object?*/box){
4797
 
                //      summary:
4798
 
                //              Getter/setter for the margin-box of node.
4799
 
                //      description: 
4800
 
                //              Returns an object in the expected format of box (regardless
4801
 
                //              if box is passed). The object might look like:
4802
 
                //                      `{ l: 50, t: 200, w: 300: h: 150 }`
4803
 
                //              for a node offset from its parent 50px to the left, 200px from
4804
 
                //              the top with a margin width of 300px and a margin-height of
4805
 
                //              150px.
4806
 
                //      node:
4807
 
                //              id or reference to DOM Node to get/set box for
4808
 
                //      box:
4809
 
                //              If passed, denotes that dojo.marginBox() should
4810
 
                //              update/set the margin box for node. Box is an object in the
4811
 
                //              above format. All properties are optional if passed.
4812
 
                var n=d.byId(node), s=gcs(n), b=box;
4813
 
                return !b ? d._getMarginBox(n, s) : d._setMarginBox(n, b.l, b.t, b.w, b.h, s); // Object
4814
 
        }
4815
 
 
4816
 
        dojo.contentBox = function(/*DomNode|String*/node, /*Object?*/box){
4817
 
                //      summary:
4818
 
                //              Getter/setter for the content-box of node.
4819
 
                //      description:
4820
 
                //              Returns an object in the expected format of box (regardless if box is passed).
4821
 
                //              The object might look like:
4822
 
                //                      `{ l: 50, t: 200, w: 300: h: 150 }`
4823
 
                //              for a node offset from its parent 50px to the left, 200px from
4824
 
                //              the top with a content width of 300px and a content-height of
4825
 
                //              150px. Note that the content box may have a much larger border
4826
 
                //              or margin box, depending on the box model currently in use and
4827
 
                //              CSS values set/inherited for node.
4828
 
                //      node:
4829
 
                //              id or reference to DOM Node to get/set box for
4830
 
                //      box:
4831
 
                //              If passed, denotes that dojo.contentBox() should
4832
 
                //              update/set the content box for node. Box is an object in the
4833
 
                //              above format. All properties are optional if passed.
4834
 
                var n=d.byId(node), s=gcs(n), b=box;
4835
 
                return !b ? d._getContentBox(n, s) : d._setContentSize(n, b.w, b.h, s); // Object
4836
 
        }
4837
 
        
4838
 
        // =============================
4839
 
        // Positioning 
4840
 
        // =============================
4841
 
        
4842
 
        var _sumAncestorProperties = function(node, prop){
4843
 
                if(!(node = (node||0).parentNode)){return 0};
4844
 
                var val, retVal = 0, _b = d.body();
4845
 
                while(node && node.style){
4846
 
                        if(gcs(node).position == "fixed"){
4847
 
                                return 0;
4848
 
                        }
4849
 
                        val = node[prop];
4850
 
                        if(val){
4851
 
                                retVal += val - 0;
4852
 
                                // opera and khtml #body & #html has the same values, we only
4853
 
                                // need one value
4854
 
                                if(node == _b){ break; }
4855
 
                        }
4856
 
                        node = node.parentNode;
4857
 
                }
4858
 
                return retVal;  //      integer
4859
 
        }
4860
 
 
4861
 
        dojo._docScroll = function(){
4862
 
                var 
4863
 
                        _b = d.body(),
4864
 
                        _w = d.global,
4865
 
                        de = d.doc.documentElement;
4866
 
                return {
4867
 
                        y: (_w.pageYOffset || de.scrollTop || _b.scrollTop || 0),
4868
 
                        x: (_w.pageXOffset || d._fixIeBiDiScrollLeft(de.scrollLeft) || _b.scrollLeft || 0)
4869
 
                };
4870
 
        };
4871
 
        
4872
 
        dojo._isBodyLtr = function(){
4873
 
                //FIXME: could check html and body tags directly instead of computed style?  need to ignore case, accept empty values
4874
 
                return !("_bodyLtr" in d) ? 
4875
 
                        d._bodyLtr = gcs(d.body()).direction == "ltr" :
4876
 
                        d._bodyLtr; // Boolean 
4877
 
        }
4878
 
        
4879
 
        dojo._getIeDocumentElementOffset = function(){
4880
 
                // summary
4881
 
                // The following values in IE contain an offset:
4882
 
                //     event.clientX 
4883
 
                //     event.clientY 
4884
 
                //     node.getBoundingClientRect().left
4885
 
                //     node.getBoundingClientRect().top
4886
 
                // But other position related values do not contain this offset, such as
4887
 
                // node.offsetLeft, node.offsetTop, node.style.left and node.style.top.
4888
 
                // The offset is always (2, 2) in LTR direction. When the body is in RTL
4889
 
                // direction, the offset counts the width of left scroll bar's width.
4890
 
                // This function computes the actual offset.
4891
 
 
4892
 
                //NOTE: assumes we're being called in an IE browser
4893
 
 
4894
 
                var de = d.doc.documentElement;
4895
 
                //FIXME: use this instead?                      var de = d.compatMode == "BackCompat" ? d.body : d.documentElement;
4896
 
 
4897
 
                return (d.isIE >= 7) ?
4898
 
                        {x: de.getBoundingClientRect().left, y: de.getBoundingClientRect().top}
4899
 
                :
4900
 
                        // IE 6.0
4901
 
                        {x: d._isBodyLtr() || window.parent == window ?
4902
 
                                de.clientLeft : de.offsetWidth - de.clientWidth - de.clientLeft, 
4903
 
                                y: de.clientTop}; // Object
4904
 
        };
4905
 
        
4906
 
        dojo._fixIeBiDiScrollLeft = function(/*Integer*/ scrollLeft){
4907
 
                // In RTL direction, scrollLeft should be a negative value, but IE 
4908
 
                // returns a positive one. All codes using documentElement.scrollLeft
4909
 
                // must call this function to fix this error, otherwise the position
4910
 
                // will offset to right when there is a horizontal scrollbar.
4911
 
                var dd = d.doc;
4912
 
                if(d.isIE && !dojo._isBodyLtr()){
4913
 
                        var de = dd.compatMode == "BackCompat" ? dd.body : dd.documentElement;
4914
 
                        return scrollLeft + de.clientWidth - de.scrollWidth; // Integer
4915
 
                }
4916
 
                return scrollLeft; // Integer
4917
 
        }
4918
 
 
4919
 
        dojo._abs = function(/*DomNode*/node, /*Boolean?*/includeScroll){
4920
 
                //      summary:
4921
 
                //              Gets the position of the passed element relative to
4922
 
                //              the viewport (if includeScroll==false), or relative to the
4923
 
                //              document root (if includeScroll==true).
4924
 
                //
4925
 
                //              Returns an object of the form:
4926
 
                //                      { x: 100, y: 300 }
4927
 
                //              if includeScroll is passed, the x and y values will include any
4928
 
                //              document offsets that may affect the position relative to the
4929
 
                //              viewport.
4930
 
 
4931
 
                // FIXME: need to decide in the brave-new-world if we're going to be
4932
 
                // margin-box or border-box.
4933
 
                var ownerDocument = node.ownerDocument;
4934
 
                var ret = {
4935
 
                        x: 0,
4936
 
                        y: 0
4937
 
                };
4938
 
 
4939
 
                // targetBoxType == "border-box"
4940
 
                var db = d.body();
4941
 
                if(d.isIE || (d.isFF >= 3)){
4942
 
                        var client = node.getBoundingClientRect();
4943
 
                        var cs;
4944
 
                        if(d.isFF){
4945
 
                                // in FF3 you have to subract the document element margins
4946
 
                                var dv = node.ownerDocument.defaultView;
4947
 
                                cs=dv.getComputedStyle(db.parentNode, null);
4948
 
                        }
4949
 
                        var offset = (d.isIE) ? d._getIeDocumentElementOffset() : { x: px(db.parentNode,cs.marginLeft), y: px(db.parentNode,cs.marginTop)};
4950
 
                        ret.x = client.left - offset.x;
4951
 
                        ret.y = client.top - offset.y;
4952
 
                }else{
4953
 
                        if(node["offsetParent"]){
4954
 
                                var endNode;
4955
 
                                // in Safari, if the node is an absolutely positioned child of
4956
 
                                // the body and the body has a margin the offset of the child
4957
 
                                // and the body contain the body's margins, so we need to end
4958
 
                                // at the body
4959
 
                                // FIXME: getting contrary results to the above in latest WebKit.
4960
 
                                if(d.isSafari &&
4961
 
                                        //(node.style.getPropertyValue("position") == "absolute") &&
4962
 
                                        (gcs(node).position == "absolute") &&
4963
 
                                        (node.parentNode == db)){
4964
 
                                        endNode = db;
4965
 
                                }else{
4966
 
                                        endNode = db.parentNode;
4967
 
                                }
4968
 
                                // Opera seems to be double counting for some elements
4969
 
                                var cs=gcs(node);
4970
 
                                var n=node;
4971
 
                                if(d.isOpera&&cs.position!="absolute"){
4972
 
                                        n=n.offsetParent;
4973
 
                                }
4974
 
                                ret.x -= _sumAncestorProperties(n, "scrollLeft");
4975
 
                                ret.y -= _sumAncestorProperties(n, "scrollTop");
4976
 
 
4977
 
                                var curnode = node;
4978
 
                                do{
4979
 
                                        var n = curnode.offsetLeft;
4980
 
                                        //FIXME: ugly hack to workaround the submenu in 
4981
 
                                        //popupmenu2 does not shown up correctly in opera. 
4982
 
                                        //Someone have a better workaround?
4983
 
                                        if(!d.isOpera || n > 0){
4984
 
                                                ret.x += isNaN(n) ? 0 : n;
4985
 
                                        }
4986
 
                                        var t = curnode.offsetTop;
4987
 
                                        ret.y += isNaN(t) ? 0 : t;
4988
 
                                        var cs = gcs(curnode);
4989
 
                                        if(curnode != node){
4990
 
                                                if(d.isSafari){
4991
 
                                                        ret.x += px(curnode, cs.borderLeftWidth);
4992
 
                                                        ret.y += px(curnode, cs.borderTopWidth);
4993
 
                                                }else if(d.isFF){
4994
 
                                                        // tried left+right with differently sized left/right borders
4995
 
                                                        // it really is 2xleft border in FF, not left+right, even in RTL!
4996
 
                                                        ret.x += 2*px(curnode,cs.borderLeftWidth);
4997
 
                                                        ret.y += 2*px(curnode,cs.borderTopWidth);
4998
 
                                                }
4999
 
                                        }
5000
 
                                        // static children in a static div in FF2 are affected by the div's border as well
5001
 
                                        // but offsetParent will skip this div!
5002
 
                                        if(d.isFF&&cs.position=="static"){
5003
 
                                                var parent=curnode.parentNode;
5004
 
                                                while(parent!=curnode.offsetParent){
5005
 
                                                        var pcs=gcs(parent);
5006
 
                                                        if(pcs.position=="static"){
5007
 
                                                                ret.x += px(curnode,pcs.borderLeftWidth);
5008
 
                                                                ret.y += px(curnode,pcs.borderTopWidth);
5009
 
                                                        }
5010
 
                                                        parent=parent.parentNode;
5011
 
                                                }
5012
 
                                        }
5013
 
                                        curnode = curnode.offsetParent;
5014
 
                                }while((curnode != endNode) && curnode);
5015
 
                        }else if(node.x && node.y){
5016
 
                                ret.x += isNaN(node.x) ? 0 : node.x;
5017
 
                                ret.y += isNaN(node.y) ? 0 : node.y;
5018
 
                        }
5019
 
                }
5020
 
                // account for document scrolling
5021
 
                // if offsetParent is used, ret value already includes scroll position
5022
 
                // so we may have to actually remove that value if !includeScroll
5023
 
                if(includeScroll){
5024
 
                        var scroll = d._docScroll();
5025
 
                        ret.y += scroll.y;
5026
 
                        ret.x += scroll.x;
5027
 
                }
5028
 
 
5029
 
                return ret; // object
5030
 
        }
5031
 
 
5032
 
        // FIXME: need a setter for coords or a moveTo!!
5033
 
        dojo.coords = function(/*DomNode|String*/node, /*Boolean?*/includeScroll){
5034
 
                //      summary:
5035
 
                //              Returns an object that measures margin box width/height and
5036
 
                //              absolute positioning data from dojo._abs().
5037
 
                //
5038
 
                //      description:
5039
 
                //              Returns an object that measures margin box width/height and
5040
 
                //              absolute positioning data from dojo._abs().
5041
 
                //              Return value will be in the form:
5042
 
                //                      `{ l: 50, t: 200, w: 300: h: 150, x: 100, y: 300 }`
5043
 
                //              Does not act as a setter. If includeScroll is passed, the x and
5044
 
                //              y params are affected as one would expect in dojo._abs().
5045
 
                var n=d.byId(node), s=gcs(n), mb=d._getMarginBox(n, s);
5046
 
                var abs = d._abs(n, includeScroll);
5047
 
                mb.x = abs.x;
5048
 
                mb.y = abs.y;
5049
 
                return mb;
5050
 
        }
5051
 
 
5052
 
        // =============================
5053
 
        // Element attribute Functions
5054
 
        // =============================
5055
 
 
5056
 
        var ieLT8 = d.isIE < 8;
5057
 
 
5058
 
        var _fixAttrName = function(/*String*/name){
5059
 
                switch(name.toLowerCase()){
5060
 
                        case "tabindex":
5061
 
                                // Internet Explorer will only set or remove tabindex
5062
 
                                // if it is spelled "tabIndex"
5063
 
                                // 
5064
 
                                return ieLT8 ? "tabIndex" : "tabindex";
5065
 
                        case "for": case "htmlfor":
5066
 
                                // to pick up for attrib set in markup via getAttribute() IE<8 uses "htmlFor" and others use "for"
5067
 
                                // get/setAttribute works in all as long use same value for both get/set
5068
 
                                return ieLT8 ? "htmlFor" : "for";
5069
 
                        case "class" :
5070
 
                                return d.isIE ? "className" : "class";
5071
 
                        default:
5072
 
                                return name;
5073
 
                }
5074
 
        }
5075
 
 
5076
 
        // non-deprecated HTML4 attributes with default values
5077
 
        // http://www.w3.org/TR/html401/index/attributes.html
5078
 
        // FF and Safari will return the default values if you
5079
 
        // access the attributes via a property but not
5080
 
        // via getAttribute()
5081
 
        var _attrProps = {
5082
 
                colspan: "colSpan",
5083
 
                enctype: "enctype",
5084
 
                frameborder: "frameborder",
5085
 
                method: "method",
5086
 
                rowspan: "rowSpan",
5087
 
                scrolling: "scrolling",
5088
 
                shape: "shape",
5089
 
                span: "span",
5090
 
                type: "type",
5091
 
                valuetype: "valueType"
5092
 
        }
5093
 
 
5094
 
        dojo.hasAttr = function(/*DomNode|String*/node, /*String*/name){
5095
 
                //      summary:
5096
 
                //              Returns true if the requested attribute is specified on the
5097
 
                //              given element, and false otherwise.
5098
 
                //      node:
5099
 
                //              id or reference to the element to check
5100
 
                //      name:
5101
 
                //              the name of the attribute
5102
 
                //      returns:
5103
 
                //              true if the requested attribute is specified on the
5104
 
                //              given element, and false otherwise
5105
 
                node = d.byId(node);
5106
 
                var fixName = _fixAttrName(name);
5107
 
                fixName = fixName == "htmlFor" ? "for" : fixName; //IE<8 uses htmlFor except in this case
5108
 
                var attr = node.getAttributeNode && node.getAttributeNode(fixName);
5109
 
                return attr ? attr.specified : false; // Boolean
5110
 
        }
5111
 
 
5112
 
        var _evtHdlrMap = {
5113
 
                
5114
 
        }
5115
 
 
5116
 
        var _ctr = 0;
5117
 
        var _attrId = dojo._scopeName + "attrid";
5118
 
 
5119
 
        dojo.attr = function(/*DomNode|String*/node, /*String|Object*/name, /*String?*/value){
5120
 
                //      summary:
5121
 
                //              Gets or sets an attribute on an HTML element.
5122
 
                //      description:
5123
 
                //              Handles normalized getting and setting of attributes on DOM
5124
 
                //              Nodes. If 2 arguments are passed, and a the second argumnt is a
5125
 
                //              string, acts as a getter.
5126
 
                //      
5127
 
                //              If a third argument is passed, or if the second argumnt is a
5128
 
                //              map of attributes, acts as a setter.
5129
 
                //
5130
 
                //              When passing functions as values, note that they will not be
5131
 
                //              directly assigned to slots on the node, but rather the default
5132
 
                //              behavior will be removed and the new behavior will be added
5133
 
                //              using `dojo.connect()`, meaning that event handler properties
5134
 
                //              will be normalized and that some caveats with regards to
5135
 
                //              non-standard behaviors for onsubmit apply. Namely that you
5136
 
                //              should cancel form submission using `dojo.stopEvent()` on the
5137
 
                //              passed event object instead of returning a boolean value from
5138
 
                //              the handler itself.
5139
 
                //      node:
5140
 
                //              id or reference to the element to get or set the attribute on
5141
 
                //      name:
5142
 
                //              the name of the attribute to get or set.
5143
 
                //      value:
5144
 
                //              The value to set for the attribute
5145
 
                //      returns:
5146
 
                //              when used as a getter, the value of the requested attribute
5147
 
                //              or null if that attribute does not have a specified or
5148
 
                //              default value;
5149
 
                //
5150
 
                //              when user as a setter, undefined
5151
 
                //
5152
 
                //      example:
5153
 
                //      |       // get the current value of the "foo" attribute on a node
5154
 
                //      |       dojo.attr(dojo.byId("nodeId"), "foo");
5155
 
                //      |       // or we can just pass the id:
5156
 
                //      |       dojo.attr("nodeId", "foo");
5157
 
                //
5158
 
                //      example:
5159
 
                //      |       // use attr() to set the tab index
5160
 
                //      |       dojo.attr("nodeId", "tabindex", 3);
5161
 
                //      |
5162
 
                //
5163
 
                //      example:
5164
 
                //      |       // set multiple values at once, including event handlers:
5165
 
                //      |       dojo.attr("formId", {
5166
 
                //      |               "foo": "bar",
5167
 
                //      |               "tabindex": -1,
5168
 
                //      |               "method": "POST",
5169
 
                //      |               "onsubmit": function(e){
5170
 
                //      |                       // stop submitting the form. Note that the IE behavior
5171
 
                //      |                       // of returning true or false will have no effect here
5172
 
                //      |                       // since our handler is connect()ed to the built-in
5173
 
                //      |                       // onsubmit behavior and so we need to use
5174
 
                //      |                       // dojo.stopEvent() to ensure that the submission
5175
 
                //      |                       // doesn't proceed.
5176
 
                //      |                       dojo.stopEvent(e);
5177
 
                //      |
5178
 
                //      |                       // submit the form with Ajax
5179
 
                //      |                       dojo.xhrPost({ form: "formId" });
5180
 
                //      |               }
5181
 
                //      |       });
5182
 
 
5183
 
                var args = arguments.length;
5184
 
                if(args == 2 && !d.isString(name)){
5185
 
                        for(var x in name){ d.attr(node, x, name[x]); }
5186
 
                        return;
5187
 
                }
5188
 
                node = d.byId(node);
5189
 
                name = _fixAttrName(name);
5190
 
                if(args == 3){
5191
 
                        // FIXME:
5192
 
                        //              what about when the name is "style" and value is an object?
5193
 
                        //              It seems natural to pass it in to dojo.style(node,
5194
 
                        //              value)...should we support this?
5195
 
                        if(d.isFunction(value)){
5196
 
                                // clobber if we can
5197
 
                                var attrId = d.attr(node, _attrId);
5198
 
                                if(!attrId){
5199
 
                                        attrId = _ctr++;
5200
 
                                        d.attr(node, _attrId, attrId);
5201
 
                                }
5202
 
                                if(!_evtHdlrMap[attrId]){
5203
 
                                        _evtHdlrMap[attrId] = {};
5204
 
                                }
5205
 
                                var h = _evtHdlrMap[attrId][name];
5206
 
                                if(h){
5207
 
                                        d.disconnect(h);
5208
 
                                }else{
5209
 
                                        try{
5210
 
                                                delete node[name];
5211
 
                                        }catch(e){}
5212
 
                                }
5213
 
 
5214
 
                                // ensure that event objects are normalized, etc.
5215
 
                                _evtHdlrMap[attrId][name] = d.connect(node, name, value);
5216
 
 
5217
 
                        }else if(
5218
 
                                (typeof value == "boolean")|| // e.g. onsubmit, disabled
5219
 
                                (name == "innerHTML")
5220
 
                        ){
5221
 
                                node[name] = value;
5222
 
                        }else if((name == "style")&&(!d.isString(value))){
5223
 
                                d.style(node, value);
5224
 
                        }else{
5225
 
                                node.setAttribute(name, value);
5226
 
                        }
5227
 
                        return;
5228
 
                }else{
5229
 
                        // should we access this attribute via a property or
5230
 
                        // via getAttribute()?
5231
 
                        var prop = _attrProps[name.toLowerCase()];
5232
 
                        if(prop){
5233
 
                                return node[prop];
5234
 
                        }else{
5235
 
                                var attrValue = node[name];
5236
 
                                return (typeof attrValue == 'boolean' || typeof attrValue == 'function') ? attrValue
5237
 
                                        : (d.hasAttr(node, name) ? node.getAttribute(name) : null);
5238
 
                        }
5239
 
                }
5240
 
        }
5241
 
 
5242
 
        dojo.removeAttr = function(/*DomNode|String*/node, /*String*/name){
5243
 
                //      summary:
5244
 
                //              Removes an attribute from an HTML element.
5245
 
                //      node:
5246
 
                //              id or reference to the element to remove the attribute from
5247
 
                //      name:
5248
 
                //              the name of the attribute to remove
5249
 
                d.byId(node).removeAttribute(_fixAttrName(name));
5250
 
        }
5251
 
 
5252
 
        /*
5253
 
        dojo.createElement = function(type, attrs, parent, position){
5254
 
                // TODO: need to finish this!
5255
 
        }
5256
 
        */
5257
 
 
5258
 
        // =============================
5259
 
        // (CSS) Class Functions
5260
 
        // =============================
5261
 
        var _className = "className";
5262
 
 
5263
 
        dojo.hasClass = function(/*DomNode|String*/node, /*String*/classStr){
5264
 
                //      summary:
5265
 
                //              Returns whether or not the specified classes are a portion of the
5266
 
                //              class list currently applied to the node. 
5267
 
                return ((" "+ d.byId(node)[_className] +" ").indexOf(" "+ classStr +" ") >= 0);  // Boolean
5268
 
        };
5269
 
 
5270
 
        dojo.addClass = function(/*DomNode|String*/node, /*String*/classStr){
5271
 
                //      summary:
5272
 
                //              Adds the specified classes to the end of the class list on the
5273
 
                //              passed node.
5274
 
                node = d.byId(node);
5275
 
                var cls = node[_className];
5276
 
                if((" "+ cls +" ").indexOf(" " + classStr + " ") < 0){
5277
 
                        node[_className] = cls + (cls ? ' ' : '') + classStr;
5278
 
                }
5279
 
        };
5280
 
 
5281
 
        dojo.removeClass = function(/*DomNode|String*/node, /*String*/classStr){
5282
 
                // summary: Removes the specified classes from node.
5283
 
                node = d.byId(node);
5284
 
                var t = d.trim((" " + node[_className] + " ").replace(" " + classStr + " ", " "));
5285
 
                if(node[_className] != t){ node[_className] = t; }
5286
 
        };
5287
 
 
5288
 
        dojo.toggleClass = function(/*DomNode|String*/node, /*String*/classStr, /*Boolean?*/condition){
5289
 
                //      summary:        
5290
 
                //              Adds a class to node if not present, or removes if present.
5291
 
                //              Pass a boolean condition if you want to explicitly add or remove.
5292
 
                //      condition:
5293
 
                //              If passed, true means to add the class, false means to remove.
5294
 
                if(condition === undefined){
5295
 
                        condition = !d.hasClass(node, classStr);
5296
 
                }
5297
 
                d[condition ? "addClass" : "removeClass"](node, classStr);
5298
 
        };
5299
 
 
5300
 
})();
5301
 
 
5302
 
}
5303
 
 
5304
 
if(!dojo._hasResource["dojo._base.NodeList"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
5305
 
dojo._hasResource["dojo._base.NodeList"] = true;
5306
 
dojo.provide("dojo._base.NodeList");
5307
 
 
5308
 
 
5309
 
 
5310
 
(function(){
5311
 
 
5312
 
        var d = dojo;
5313
 
 
5314
 
        var tnl = function(arr){
5315
 
                // decorate an array to make it look like a NodeList
5316
 
                arr.constructor = dojo.NodeList;
5317
 
                dojo._mixin(arr, dojo.NodeList.prototype);
5318
 
                return arr;
5319
 
        }
5320
 
 
5321
 
        var _mapIntoDojo = function(func, alwaysThis){
5322
 
                // returns a function which, when executed in the scope of its caller,
5323
 
                // applies the passed arguments to a particular dojo.* function (named
5324
 
                // in func) and aggregates the returns. if alwaysThis is true, it
5325
 
                // always returns the scope object and not the collected returns from
5326
 
                // the Dojo method
5327
 
                return function(){
5328
 
                        var _a = arguments;
5329
 
                        var aa = d._toArray(_a, 0, [null]);
5330
 
                        var s = this.map(function(i){
5331
 
                                aa[0] = i;
5332
 
                                return d[func].apply(d, aa);
5333
 
                        });
5334
 
                        return (alwaysThis || ( (_a.length > 1) || !d.isString(_a[0]) )) ? this : s; // String||dojo.NodeList
5335
 
                }
5336
 
        };
5337
 
 
5338
 
        dojo.NodeList = function(){
5339
 
                //      summary:
5340
 
                //              dojo.NodeList is as subclass of Array which adds syntactic 
5341
 
                //              sugar for chaining, common iteration operations, animation, 
5342
 
                //              and node manipulation. NodeLists are most often returned as
5343
 
                //              the result of dojo.query() calls.
5344
 
                //      example:
5345
 
                //              create a node list from a node
5346
 
                //              |       new dojo.NodeList(dojo.byId("foo"));
5347
 
 
5348
 
                return tnl(Array.apply(null, arguments));
5349
 
        }
5350
 
 
5351
 
        dojo.NodeList._wrap = tnl;
5352
 
 
5353
 
        dojo.extend(dojo.NodeList, {
5354
 
                // http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array#Methods
5355
 
 
5356
 
                // FIXME: handle return values for #3244
5357
 
                //              http://trac.dojotoolkit.org/ticket/3244
5358
 
                
5359
 
                // FIXME:
5360
 
                //              need to wrap or implement:
5361
 
                //                      join (perhaps w/ innerHTML/outerHTML overload for toString() of items?)
5362
 
                //                      reduce
5363
 
                //                      reduceRight
5364
 
 
5365
 
                slice: function(/*===== begin, end =====*/){
5366
 
                        // summary:
5367
 
                        //              Returns a new NodeList, maintaining this one in place
5368
 
                        // description:
5369
 
                        //              This method behaves exactly like the Array.slice method
5370
 
                        //              with the caveat that it returns a dojo.NodeList and not a
5371
 
                        //              raw Array. For more details, see:
5372
 
                        //                      http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:slice
5373
 
                        // begin: Integer
5374
 
                        //              Can be a positive or negative integer, with positive
5375
 
                        //              integers noting the offset to begin at, and negative
5376
 
                        //              integers denoting an offset from the end (i.e., to the left
5377
 
                        //              of the end)
5378
 
                        // end: Integer?
5379
 
                        //              Optional parameter to describe what position relative to
5380
 
                        //              the NodeList's zero index to end the slice at. Like begin,
5381
 
                        //              can be positive or negative.
5382
 
                        var a = d._toArray(arguments);
5383
 
                        return tnl(a.slice.apply(this, a));
5384
 
                },
5385
 
 
5386
 
                splice: function(/*===== index, howmany, item =====*/){
5387
 
                        // summary:
5388
 
                        //              Returns a new NodeList, manipulating this NodeList based on
5389
 
                        //              the arguments passed, potentially splicing in new elements
5390
 
                        //              at an offset, optionally deleting elements
5391
 
                        // description:
5392
 
                        //              This method behaves exactly like the Array.splice method
5393
 
                        //              with the caveat that it returns a dojo.NodeList and not a
5394
 
                        //              raw Array. For more details, see:
5395
 
                        //                      <http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:splice>
5396
 
                        // index: Integer
5397
 
                        //              begin can be a positive or negative integer, with positive
5398
 
                        //              integers noting the offset to begin at, and negative
5399
 
                        //              integers denoting an offset from the end (i.e., to the left
5400
 
                        //              of the end)
5401
 
                        // howmany: Integer?
5402
 
                        //              Optional parameter to describe what position relative to
5403
 
                        //              the NodeList's zero index to end the slice at. Like begin,
5404
 
                        //              can be positive or negative.
5405
 
                        // item: Object...?
5406
 
                        //              Any number of optional parameters may be passed in to be
5407
 
                        //              spliced into the NodeList
5408
 
                        // returns:
5409
 
                        //              dojo.NodeList
5410
 
                        var a = d._toArray(arguments);
5411
 
                        return tnl(a.splice.apply(this, a));
5412
 
                },
5413
 
 
5414
 
                concat: function(/*===== item =====*/){
5415
 
                        // summary:
5416
 
                        //              Returns a new NodeList comprised of items in this NodeList
5417
 
                        //              as well as items passed in as parameters
5418
 
                        // description:
5419
 
                        //              This method behaves exactly like the Array.concat method
5420
 
                        //              with the caveat that it returns a dojo.NodeList and not a
5421
 
                        //              raw Array. For more details, see:
5422
 
                        //                      <http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:concat>
5423
 
                        // item: Object...?
5424
 
                        //              Any number of optional parameters may be passed in to be
5425
 
                        //              spliced into the NodeList
5426
 
                        // returns:
5427
 
                        //              dojo.NodeList
5428
 
                        var a = d._toArray(arguments, 0, [this]);
5429
 
                        return tnl(a.concat.apply([], a));
5430
 
                },
5431
 
                
5432
 
                indexOf: function(/*Object*/ value, /*Integer?*/ fromIndex){
5433
 
                        //      summary:
5434
 
                        //              see dojo.indexOf(). The primary difference is that the acted-on 
5435
 
                        //              array is implicitly this NodeList
5436
 
                        // value:
5437
 
                        //              The value to search for.
5438
 
                        // fromIndex:
5439
 
                        //              The loction to start searching from. Optional. Defaults to 0.
5440
 
                        //      description:
5441
 
                        //              For more details on the behavior of indexOf, see:
5442
 
                        //                      <http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:indexOf>
5443
 
                        //      returns:
5444
 
                        //              Positive Integer or 0 for a match, -1 of not found.
5445
 
                        return d.indexOf(this, value, fromIndex); // Integer
5446
 
                },
5447
 
 
5448
 
                lastIndexOf: function(/*===== value, fromIndex =====*/){
5449
 
                        // summary:
5450
 
                        //              see dojo.lastIndexOf(). The primary difference is that the
5451
 
                        //              acted-on array is implicitly this NodeList
5452
 
                        //      description:
5453
 
                        //              For more details on the behavior of lastIndexOf, see:
5454
 
                        //                      <http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:lastIndexOf>
5455
 
                        // value: Object
5456
 
                        //              The value to search for.
5457
 
                        // fromIndex: Integer?
5458
 
                        //              The loction to start searching from. Optional. Defaults to 0.
5459
 
                        // returns:
5460
 
                        //              Positive Integer or 0 for a match, -1 of not found.
5461
 
                        return d.lastIndexOf.apply(d, d._toArray(arguments, 0, [this])); // Integer
5462
 
                },
5463
 
 
5464
 
                every: function(/*Function*/callback, /*Object?*/thisObject){
5465
 
                        //      summary:
5466
 
                        //              see `dojo.every()` and:
5467
 
                        //                      <http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:every>
5468
 
                        //              Takes the same structure of arguments and returns as
5469
 
                        //              dojo.every() with the caveat that the passed array is
5470
 
                        //              implicitly this NodeList
5471
 
                        return d.every(this, callback, thisObject); // Boolean
5472
 
                },
5473
 
 
5474
 
                some: function(/*Function*/callback, /*Object?*/thisObject){
5475
 
                        //      summary:
5476
 
                        //              see dojo.some() and:
5477
 
                        //                      http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:some
5478
 
                        //              Takes the same structure of arguments and returns as
5479
 
                        //              dojo.some() with the caveat that the passed array is
5480
 
                        //              implicitly this NodeList
5481
 
                        return d.some(this, callback, thisObject); // Boolean
5482
 
                },
5483
 
 
5484
 
                map: function(/*Function*/ func, /*Function?*/ obj){
5485
 
                        //      summary:
5486
 
                        //              see dojo.map(). The primary difference is that the acted-on
5487
 
                        //              array is implicitly this NodeList and the return is a
5488
 
                        //              dojo.NodeList (a subclass of Array)
5489
 
 
5490
 
                        return d.map(this, func, obj, d.NodeList); // dojo.NodeList
5491
 
                },
5492
 
 
5493
 
                forEach: function(callback, thisObj){
5494
 
                        //      summary:
5495
 
                        //              see dojo.forEach(). The primary difference is that the acted-on 
5496
 
                        //              array is implicitly this NodeList
5497
 
 
5498
 
                        d.forEach(this, callback, thisObj);
5499
 
                        // non-standard return to allow easier chaining
5500
 
                        return this; // dojo.NodeList 
5501
 
                },
5502
 
 
5503
 
                // custom methods
5504
 
                
5505
 
                coords: function(){
5506
 
                        //      summary:
5507
 
                        //              Returns the box objects all elements in a node list as
5508
 
                        //              an Array (*not* a NodeList)
5509
 
                        
5510
 
                        return d.map(this, d.coords); // Array
5511
 
                },
5512
 
 
5513
 
                /*=====
5514
 
                attr: function(property, value){
5515
 
                        //      summary:
5516
 
                        //              gets or sets the DOM attribute for every element in the
5517
 
                        //              NodeList
5518
 
                        //      property: String
5519
 
                        //              the attribute to get/set
5520
 
                        //      value: String?
5521
 
                        //              optional. The value to set the property to
5522
 
                        //      returns:
5523
 
                        //              if no value is passed, the result is an array of attribute values
5524
 
                        //              If a value is passed, the return is this NodeList
5525
 
                        return; // dojo.NodeList
5526
 
                        return; // Array
5527
 
                },
5528
 
 
5529
 
                style: function(property, value){
5530
 
                        //      summary:
5531
 
                        //              gets or sets the CSS property for every element in the NodeList
5532
 
                        //      property: String
5533
 
                        //              the CSS property to get/set, in JavaScript notation
5534
 
                        //              ("lineHieght" instead of "line-height") 
5535
 
                        //      value: String?
5536
 
                        //              optional. The value to set the property to
5537
 
                        //      returns:
5538
 
                        //              if no value is passed, the result is an array of strings.
5539
 
                        //              If a value is passed, the return is this NodeList
5540
 
                        return; // dojo.NodeList
5541
 
                        return; // Array
5542
 
                },
5543
 
 
5544
 
                addClass: function(className){
5545
 
                        //      summary:
5546
 
                        //              adds the specified class to every node in the list
5547
 
                        //      className: String
5548
 
                        //              the CSS class to add
5549
 
                        return; // dojo.NodeList
5550
 
                },
5551
 
 
5552
 
                removeClass: function(className){
5553
 
                        //      summary:
5554
 
                        //              removes the specified class from every node in the list
5555
 
                        //      className: String
5556
 
                        //              the CSS class to add
5557
 
                        //      returns:
5558
 
                        //              dojo.NodeList, this list
5559
 
                        return; // dojo.NodeList
5560
 
                },
5561
 
 
5562
 
                toggleClass: function(className, condition){
5563
 
                        //      summary:
5564
 
                        //              Adds a class to node if not present, or removes if present.
5565
 
                        //              Pass a boolean condition if you want to explicitly add or remove.
5566
 
                        //      condition: Boolean?
5567
 
                        //              If passed, true means to add the class, false means to remove.
5568
 
                        //      className: String
5569
 
                        //              the CSS class to add
5570
 
                        return; // dojo.NodeList
5571
 
                },
5572
 
 
5573
 
                connect: function(methodName, objOrFunc, funcName){
5574
 
                        //      summary:
5575
 
                        //              attach event handlers to every item of the NodeList. Uses dojo.connect()
5576
 
                        //              so event properties are normalized
5577
 
                        //      methodName: String
5578
 
                        //              the name of the method to attach to. For DOM events, this should be
5579
 
                        //              the lower-case name of the event
5580
 
                        //      objOrFunc: Object|Function|String
5581
 
                        //              if 2 arguments are passed (methodName, objOrFunc), objOrFunc should
5582
 
                        //              reference a function or be the name of the function in the global
5583
 
                        //              namespace to attach. If 3 arguments are provided
5584
 
                        //              (methodName, objOrFunc, funcName), objOrFunc must be the scope to 
5585
 
                        //              locate the bound function in
5586
 
                        //      funcName: String?
5587
 
                        //              optional. A string naming the function in objOrFunc to bind to the
5588
 
                        //              event. May also be a function reference.
5589
 
                        //      example:
5590
 
                        //              add an onclick handler to every button on the page
5591
 
                        //              |       dojo.query("div:nth-child(odd)").connect("onclick", function(e){
5592
 
                        //              |               
5593
 
                        //              |       });
5594
 
                        // example:
5595
 
                        //              attach foo.bar() to every odd div's onmouseover
5596
 
                        //              |       dojo.query("div:nth-child(odd)").connect("onmouseover", foo, "bar");
5597
 
                },
5598
 
                =====*/
5599
 
                attr: _mapIntoDojo("attr"),
5600
 
                style: _mapIntoDojo("style"),
5601
 
                addClass: _mapIntoDojo("addClass", true),
5602
 
                removeClass: _mapIntoDojo("removeClass", true),
5603
 
                toggleClass: _mapIntoDojo("toggleClass", true),
5604
 
                connect: _mapIntoDojo("connect", true),
5605
 
 
5606
 
                // FIXME: connectPublisher()? connectRunOnce()?
5607
 
 
5608
 
                place: function(/*String||Node*/ queryOrNode, /*String*/ position){
5609
 
                        //      summary:
5610
 
                        //              places elements of this node list relative to the first element matched
5611
 
                        //              by queryOrNode. Returns the original NodeList.
5612
 
                        //      queryOrNode:
5613
 
                        //              may be a string representing any valid CSS3 selector or a DOM node.
5614
 
                        //              In the selector case, only the first matching element will be used 
5615
 
                        //              for relative positioning.
5616
 
                        //      position:
5617
 
                        //              can be one of:
5618
 
                        //                      * "last"||"end" (default)
5619
 
                        //                      * "first||"start"
5620
 
                        //                      * "before"
5621
 
                        //                      * "after"
5622
 
                        //              or an offset in the childNodes property
5623
 
                        var item = d.query(queryOrNode)[0];
5624
 
                        return this.forEach(function(i){ d.place(i, item, position); }); // dojo.NodeList
5625
 
                },
5626
 
 
5627
 
                orphan: function(/*String?*/ simpleFilter){
5628
 
                        //      summary:
5629
 
                        //              removes elements in this list that match the simple
5630
 
                        //              filter from their parents and returns them as a new
5631
 
                        //              NodeList.
5632
 
                        //      simpleFilter:
5633
 
                        //              single-expression CSS filter
5634
 
                        //      returns:
5635
 
                        //              `dojo.NodeList` containing the orpahned elements 
5636
 
                        return (simpleFilter ? d._filterQueryResult(this, simpleFilter) : this). // dojo.NodeList
5637
 
                                forEach("if(item.parentNode){ item.parentNode.removeChild(item); }"); 
5638
 
                },
5639
 
 
5640
 
                adopt: function(/*String||Array||DomNode*/ queryOrListOrNode, /*String?*/ position){
5641
 
                        //      summary:
5642
 
                        //              places any/all elements in queryOrListOrNode at a
5643
 
                        //              position relative to the first element in this list.
5644
 
                        //              Returns a dojo.NodeList of the adopted elements.
5645
 
                        //      queryOrListOrNode:
5646
 
                        //              a DOM node or a query string or a query result.
5647
 
                        //              Represents the nodes to be adopted relative to the
5648
 
                        //              first element of this NodeList.
5649
 
                        //      position:
5650
 
                        //              can be one of:
5651
 
                        //                      * "last"||"end" (default)
5652
 
                        //                      * "first||"start"
5653
 
                        //                      * "before"
5654
 
                        //                      * "after"
5655
 
                        //              or an offset in the childNodes property
5656
 
                        var item = this[0];
5657
 
                        return d.query(queryOrListOrNode).forEach(function(ai){ // dojo.NodeList
5658
 
                                d.place(ai, item, position || "last"); 
5659
 
                        });
5660
 
                },
5661
 
 
5662
 
                // FIXME: do we need this?
5663
 
                query: function(/*String*/ queryStr){
5664
 
                        //      summary:
5665
 
                        //              Returns a new, flattened NodeList. Elements of the new list
5666
 
                        //              satisfy the passed query but use elements of the
5667
 
                        //              current NodeList as query roots.
5668
 
 
5669
 
                        if(!queryStr){ return this; }
5670
 
 
5671
 
                        // FIXME: probably slow
5672
 
                        // FIXME: use map?
5673
 
                        var ret = d.NodeList();
5674
 
                        this.forEach(function(item){
5675
 
                                // FIXME: why would we ever get undefined here?
5676
 
                                ret = ret.concat(d.query(queryStr, item).filter(function(subItem){ return (subItem !== undefined); }));
5677
 
                        });
5678
 
                        return ret; // dojo.NodeList
5679
 
                },
5680
 
 
5681
 
                filter: function(/*String*/ simpleQuery){
5682
 
                        //      summary:
5683
 
                        //              "masks" the built-in javascript filter() method to support
5684
 
                        //              passing a simple string filter in addition to supporting
5685
 
                        //              filtering function objects.
5686
 
                        //      example:
5687
 
                        //              "regular" JS filter syntax as exposed in dojo.filter:
5688
 
                        //              |       dojo.query("*").filter(function(item){
5689
 
                        //              |               // highlight every paragraph
5690
 
                        //              |               return (item.nodeName == "p");
5691
 
                        //              |       }).styles("backgroundColor", "yellow");
5692
 
                        // example:
5693
 
                        //              the same filtering using a CSS selector
5694
 
                        //              |       dojo.query("*").filter("p").styles("backgroundColor", "yellow");
5695
 
 
5696
 
                        var items = this;
5697
 
                        var _a = arguments;
5698
 
                        var r = d.NodeList();
5699
 
                        var rp = function(t){ 
5700
 
                                if(t !== undefined){
5701
 
                                        r.push(t); 
5702
 
                                }
5703
 
                        }
5704
 
                        if(d.isString(simpleQuery)){
5705
 
                                items = d._filterQueryResult(this, _a[0]);
5706
 
                                if(_a.length == 1){
5707
 
                                        // if we only got a string query, pass back the filtered results
5708
 
                                        return items; // dojo.NodeList
5709
 
                                }
5710
 
                                // if we got a callback, run it over the filtered items
5711
 
                                _a.shift();
5712
 
                        }
5713
 
                        // handle the (callback, [thisObject]) case
5714
 
                        d.forEach(d.filter(items, _a[0], _a[1]), rp);
5715
 
                        return r; // dojo.NodeList
5716
 
                },
5717
 
                
5718
 
                /*
5719
 
                // FIXME: should this be "copyTo" and include parenting info?
5720
 
                clone: function(){
5721
 
                        // summary:
5722
 
                        //              creates node clones of each element of this list
5723
 
                        //              and returns a new list containing the clones
5724
 
                },
5725
 
                */
5726
 
 
5727
 
                addContent: function(/*String*/ content, /*String||Integer?*/ position){
5728
 
                        //      summary:
5729
 
                        //              add a node or some HTML as a string to every item in the list. 
5730
 
                        //              Returns the original list.
5731
 
                        //      description:
5732
 
                        //              a copy of the HTML content is added to each item in the
5733
 
                        //              list, with an optional position argument. If no position
5734
 
                        //              argument is provided, the content is appended to the end of
5735
 
                        //              each item.
5736
 
                        //      content:
5737
 
                        //              the HTML in string format to add at position to every item
5738
 
                        //      position:
5739
 
                        //              can be one of:
5740
 
                        //                      * "last"||"end" (default)
5741
 
                        //                      * "first||"start"
5742
 
                        //                      * "before"
5743
 
                        //                      * "after"
5744
 
                        //              or an offset in the childNodes property
5745
 
                        //      example:
5746
 
                        //              appends content to the end if the position is ommitted
5747
 
                        //      |       dojo.query("h3 > p").addContent("hey there!");
5748
 
                        //      example:
5749
 
                        //              add something to the front of each element that has a "thinger" property:
5750
 
                        //      |       dojo.query("[thinger]").addContent("...", "first");
5751
 
                        //      example:
5752
 
                        //              adds a header before each element of the list
5753
 
                        //      |       dojo.query(".note").addContent("<h4>NOTE:</h4>", "before");
5754
 
                        var ta = d.doc.createElement("span");
5755
 
                        if(d.isString(content)){
5756
 
                                ta.innerHTML = content;
5757
 
                        }else{
5758
 
                                ta.appendChild(content);
5759
 
                        }
5760
 
                        if(position === undefined){
5761
 
                                position = "last";
5762
 
                        }
5763
 
                        var ct = (position == "first" || position == "after") ? "lastChild" : "firstChild";
5764
 
                        this.forEach(function(item){
5765
 
                                var tn = ta.cloneNode(true);
5766
 
                                while(tn[ct]){
5767
 
                                        d.place(tn[ct], item, position);
5768
 
                                }
5769
 
                        });
5770
 
                        return this; // dojo.NodeList
5771
 
                },
5772
 
 
5773
 
                empty: function(){
5774
 
                        //      summary:
5775
 
                        //              clears all content from each node in the list
5776
 
                        return this.forEach("item.innerHTML='';"); // dojo.NodeList
5777
 
 
5778
 
                        // FIXME: should we be checking for and/or disposing of widgets below these nodes?
5779
 
                },
5780
 
                
5781
 
                instantiate: function(/*String|Object*/ declaredClass, /*Object?*/ properties){
5782
 
                        //      summary:
5783
 
                        //              Create a new instance of a specified class, using the
5784
 
                        //              specified properties and each node in the nodeList as a
5785
 
                        //              srcNodeRef
5786
 
                        //
5787
 
                        var c = d.isFunction(declaredClass) ? declaredClass : d.getObject(declaredClass);
5788
 
                        return this.forEach(function(i){
5789
 
                                new c(properties||{},i);
5790
 
                        }) // dojo.NodeList
5791
 
                },
5792
 
 
5793
 
                at: function(/*===== index =====*/){
5794
 
                        //      summary:
5795
 
                        //              Returns a new NodeList comprised of items in this NodeList
5796
 
                        //              at the given index or indices.
5797
 
                        //      index: Integer...
5798
 
                        //              One or more 0-based indices of items in the current NodeList.
5799
 
                        //      returns:
5800
 
                        //              dojo.NodeList
5801
 
                        var nl = new dojo.NodeList();
5802
 
                        dojo.forEach(arguments, function(i) { if(this[i]) { nl.push(this[i]); } }, this);
5803
 
                        return nl; // dojo.NodeList
5804
 
                }
5805
 
 
5806
 
        });
5807
 
 
5808
 
        // syntactic sugar for DOM events
5809
 
        d.forEach([
5810
 
                "blur", "focus", "click", "keydown", "keypress", "keyup", "mousedown",
5811
 
                "mouseenter", "mouseleave", "mousemove", "mouseout", "mouseover",
5812
 
                "mouseup", "submit", "load", "error"
5813
 
                ], function(evt){
5814
 
                        var _oe = "on"+evt;
5815
 
                        d.NodeList.prototype[_oe] = function(a, b){
5816
 
                                return this.connect(_oe, a, b);
5817
 
                        }
5818
 
                                // FIXME: should these events trigger publishes?
5819
 
                                /*
5820
 
                                return (a ? this.connect(_oe, a, b) : 
5821
 
                                                        this.forEach(function(n){  
5822
 
                                                                // FIXME:
5823
 
                                                                //              listeners get buried by
5824
 
                                                                //              addEventListener and can't be dug back
5825
 
                                                                //              out to be triggered externally.
5826
 
                                                                // see:
5827
 
                                                                //              http://developer.mozilla.org/en/docs/DOM:element
5828
 
 
5829
 
                                                                
5830
 
 
5831
 
                                                                // FIXME: need synthetic event support!
5832
 
                                                                var _e = { target: n, faux: true, type: evt };
5833
 
                                                                // dojo._event_listener._synthesizeEvent({}, { target: n, faux: true, type: evt });
5834
 
                                                                try{ n[evt](_e); }catch(e){  }
5835
 
                                                                try{ n[_oe](_e); }catch(e){  }
5836
 
                                                        })
5837
 
                                );
5838
 
                        }
5839
 
                        */
5840
 
                }
5841
 
        );
5842
 
 
5843
 
})();
5844
 
 
5845
 
}
5846
 
 
5847
 
if(!dojo._hasResource["dojo._base.query"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
5848
 
dojo._hasResource["dojo._base.query"] = true;
5849
 
dojo.provide("dojo._base.query");
5850
 
 
5851
 
 
5852
 
/*
5853
 
        dojo.query() architectural overview:
5854
 
 
5855
 
                dojo.query is a relatively full-featured CSS3 query library. It is
5856
 
                designed to take any valid CSS3 selector and return the nodes matching
5857
 
                the selector. To do this quickly, it processes queries in several
5858
 
                steps, applying caching where profitable.
5859
 
                
5860
 
                The steps (roughly in reverse order of the way they appear in the code):
5861
 
                        1.) check to see if we already have a "query dispatcher"
5862
 
                                - if so, use that with the given parameterization. Skip to step 4.
5863
 
                        2.) attempt to determine which branch to dispatch the query to:
5864
 
                                - JS (optimized DOM iteration)
5865
 
                                - xpath (for browsers that support it and where it's fast)
5866
 
                                - native (not available in any browser yet)
5867
 
                        3.) tokenize and convert to executable "query dispatcher"
5868
 
                                - this is where the lion's share of the complexity in the
5869
 
                                  system lies. In the DOM version, the query dispatcher is
5870
 
                                  assembled as a chain of "yes/no" test functions pertaining to
5871
 
                                  a section of a simple query statement (".blah:nth-child(odd)"
5872
 
                                  but not "div div", which is 2 simple statements). Individual
5873
 
                                  statement dispatchers are cached (to prevent re-definition)
5874
 
                                  as are entire dispatch chains (to make re-execution of the
5875
 
                                  same query fast)
5876
 
                                - in the xpath path, tokenization yields a concatenation of
5877
 
                                  parameterized xpath selectors. As with the DOM version, both
5878
 
                                  simple selector blocks and overall evaluators are cached to
5879
 
                                  prevent re-defintion
5880
 
                        4.) the resulting query dispatcher is called in the passed scope (by default the top-level document)
5881
 
                                - for DOM queries, this results in a recursive, top-down
5882
 
                                  evaluation of nodes based on each simple query section
5883
 
                                - xpath queries can, thankfully, be executed in one shot
5884
 
                        5.) matched nodes are pruned to ensure they are unique
5885
 
*/
5886
 
 
5887
 
;(function(){
5888
 
        // define everything in a closure for compressability reasons. "d" is an
5889
 
        // alias to "dojo" since it's so frequently used. This seems a
5890
 
        // transformation that the build system could perform on a per-file basis.
5891
 
 
5892
 
        ////////////////////////////////////////////////////////////////////////
5893
 
        // Utility code
5894
 
        ////////////////////////////////////////////////////////////////////////
5895
 
 
5896
 
        var d = dojo;
5897
 
        var childNodesName = dojo.isIE ? "children" : "childNodes";
5898
 
        var caseSensitive = false;
5899
 
 
5900
 
        var getQueryParts = function(query){
5901
 
                // summary: state machine for query tokenization
5902
 
                if(">~+".indexOf(query.charAt(query.length-1)) >= 0){
5903
 
                        query += " *"
5904
 
                }
5905
 
                query += " "; // ensure that we terminate the state machine
5906
 
 
5907
 
                var ts = function(s, e){
5908
 
                        return d.trim(query.slice(s, e));
5909
 
                }
5910
 
 
5911
 
                // the overall data graph of the full query, as represented by queryPart objects
5912
 
                var qparts = []; 
5913
 
                // state keeping vars
5914
 
                var inBrackets = -1;
5915
 
                var inParens = -1;
5916
 
                var inMatchFor = -1;
5917
 
                var inPseudo = -1;
5918
 
                var inClass = -1;
5919
 
                var inId = -1;
5920
 
                var inTag = -1;
5921
 
                var lc = ""; // the last character
5922
 
                var cc = ""; // the current character
5923
 
                var pStart;
5924
 
                // iteration vars
5925
 
                var x = 0; // index in the query
5926
 
                var ql = query.length;
5927
 
                var currentPart = null; // data structure representing the entire clause
5928
 
                var _cp = null; // the current pseudo or attr matcher
5929
 
 
5930
 
                var endTag = function(){
5931
 
                        if(inTag >= 0){
5932
 
                                var tv = (inTag == x) ? null : ts(inTag, x); // .toLowerCase();
5933
 
                                currentPart[ (">~+".indexOf(tv) < 0) ? "tag" : "oper" ] = tv;
5934
 
                                inTag = -1;
5935
 
                        }
5936
 
                }
5937
 
 
5938
 
                var endId = function(){
5939
 
                        if(inId >= 0){
5940
 
                                currentPart.id = ts(inId, x).replace(/\\/g, "");
5941
 
                                inId = -1;
5942
 
                        }
5943
 
                }
5944
 
 
5945
 
                var endClass = function(){
5946
 
                        if(inClass >= 0){
5947
 
                                currentPart.classes.push(ts(inClass+1, x).replace(/\\/g, ""));
5948
 
                                inClass = -1;
5949
 
                        }
5950
 
                }
5951
 
 
5952
 
                var endAll = function(){
5953
 
                        endId(); endTag(); endClass();
5954
 
                }
5955
 
 
5956
 
                for(; lc=cc, cc=query.charAt(x),x<ql; x++){
5957
 
                        if(lc == "\\"){ continue; }
5958
 
                        if(!currentPart){
5959
 
                                // NOTE: I hate all this alloc, but it's shorter than writing tons of if's
5960
 
                                pStart = x;
5961
 
                                currentPart = {
5962
 
                                        query: null,
5963
 
                                        pseudos: [],
5964
 
                                        attrs: [],
5965
 
                                        classes: [],
5966
 
                                        tag: null,
5967
 
                                        oper: null,
5968
 
                                        id: null
5969
 
                                };
5970
 
                                inTag = x;
5971
 
                        }
5972
 
 
5973
 
                        if(inBrackets >= 0){
5974
 
                                // look for a the close first
5975
 
                                if(cc == "]"){
5976
 
                                        if(!_cp.attr){
5977
 
                                                _cp.attr = ts(inBrackets+1, x);
5978
 
                                        }else{
5979
 
                                                _cp.matchFor = ts((inMatchFor||inBrackets+1), x);
5980
 
                                        }
5981
 
                                        var cmf = _cp.matchFor;
5982
 
                                        if(cmf){
5983
 
                                                if(     (cmf.charAt(0) == '"') || (cmf.charAt(0)  == "'") ){
5984
 
                                                        _cp.matchFor = cmf.substring(1, cmf.length-1);
5985
 
                                                }
5986
 
                                        }
5987
 
                                        currentPart.attrs.push(_cp);
5988
 
                                        _cp = null; // necessaray?
5989
 
                                        inBrackets = inMatchFor = -1;
5990
 
                                }else if(cc == "="){
5991
 
                                        var addToCc = ("|~^$*".indexOf(lc) >=0 ) ? lc : "";
5992
 
                                        _cp.type = addToCc+cc;
5993
 
                                        _cp.attr = ts(inBrackets+1, x-addToCc.length);
5994
 
                                        inMatchFor = x+1;
5995
 
                                }
5996
 
                                // now look for other clause parts
5997
 
                        }else if(inParens >= 0){
5998
 
                                if(cc == ")"){
5999
 
                                        if(inPseudo >= 0){
6000
 
                                                _cp.value = ts(inParens+1, x);
6001
 
                                        }
6002
 
                                        inPseudo = inParens = -1;
6003
 
                                }
6004
 
                        }else if(cc == "#"){
6005
 
                                endAll();
6006
 
                                inId = x+1;
6007
 
                        }else if(cc == "."){
6008
 
                                endAll();
6009
 
                                inClass = x;
6010
 
                        }else if(cc == ":"){
6011
 
                                endAll();
6012
 
                                inPseudo = x;
6013
 
                        }else if(cc == "["){
6014
 
                                endAll();
6015
 
                                inBrackets = x;
6016
 
                                _cp = {
6017
 
                                        /*=====
6018
 
                                        attr: null, type: null, matchFor: null
6019
 
                                        =====*/
6020
 
                                };
6021
 
                        }else if(cc == "("){
6022
 
                                if(inPseudo >= 0){
6023
 
                                        _cp = { 
6024
 
                                                name: ts(inPseudo+1, x), 
6025
 
                                                value: null
6026
 
                                        }
6027
 
                                        currentPart.pseudos.push(_cp);
6028
 
                                }
6029
 
                                inParens = x;
6030
 
                        }else if(cc == " " && lc != cc){
6031
 
                                // note that we expect the string to be " " terminated
6032
 
                                endAll();
6033
 
                                if(inPseudo >= 0){
6034
 
                                        currentPart.pseudos.push({ name: ts(inPseudo+1, x) });
6035
 
                                }
6036
 
                                currentPart.hasLoops = (        
6037
 
                                                currentPart.pseudos.length || 
6038
 
                                                currentPart.attrs.length || 
6039
 
                                                currentPart.classes.length      );
6040
 
                                currentPart.query = ts(pStart, x);
6041
 
                                currentPart.otag = currentPart.tag = (currentPart["oper"]) ? null : (currentPart.tag || "*");
6042
 
                                if(currentPart.tag){ // FIXME: not valid in case-sensitive documents
6043
 
                                        currentPart.tag = currentPart.tag.toUpperCase();
6044
 
                                }
6045
 
                                qparts.push(currentPart);
6046
 
                                currentPart = null;
6047
 
                        }
6048
 
                }
6049
 
                return qparts;
6050
 
        };
6051
 
        
6052
 
 
6053
 
        ////////////////////////////////////////////////////////////////////////
6054
 
        // XPath query code
6055
 
        ////////////////////////////////////////////////////////////////////////
6056
 
 
6057
 
        // this array is a lookup used to generate an attribute matching function.
6058
 
        // There is a similar lookup/generator list for the DOM branch with similar
6059
 
        // calling semantics.
6060
 
        var xPathAttrs = {
6061
 
                "*=": function(attr, value){
6062
 
                        return "[contains(@"+attr+", '"+ value +"')]";
6063
 
                },
6064
 
                "^=": function(attr, value){
6065
 
                        return "[starts-with(@"+attr+", '"+ value +"')]";
6066
 
                },
6067
 
                "$=": function(attr, value){
6068
 
                        return "[substring(@"+attr+", string-length(@"+attr+")-"+(value.length-1)+")='"+value+"']";
6069
 
                },
6070
 
                "~=": function(attr, value){
6071
 
                        return "[contains(concat(' ',@"+attr+",' '), ' "+ value +" ')]";
6072
 
                },
6073
 
                "|=": function(attr, value){
6074
 
                        return "[contains(concat(' ',@"+attr+",' '), ' "+ value +"-')]";
6075
 
                },
6076
 
                "=": function(attr, value){
6077
 
                        return "[@"+attr+"='"+ value +"']";
6078
 
                }
6079
 
        };
6080
 
 
6081
 
        // takes a list of attribute searches, the overall query, a function to
6082
 
        // generate a default matcher, and a closure-bound method for providing a
6083
 
        // matching function that generates whatever type of yes/no distinguisher
6084
 
        // the query method needs. The method is a bit tortured and hard to read
6085
 
        // because it needs to be used in both the XPath and DOM branches.
6086
 
        var handleAttrs = function(     attrList, 
6087
 
                                                                query, 
6088
 
                                                                getDefault, 
6089
 
                                                                handleMatch){
6090
 
                d.forEach(query.attrs, function(attr){
6091
 
                        var matcher;
6092
 
                        // type, attr, matchFor
6093
 
                        if(attr.type && attrList[attr.type]){
6094
 
                                matcher = attrList[attr.type](attr.attr, attr.matchFor);
6095
 
                        }else if(attr.attr.length){
6096
 
                                matcher = getDefault(attr.attr);
6097
 
                        }
6098
 
                        if(matcher){ handleMatch(matcher); }
6099
 
                });
6100
 
        }
6101
 
 
6102
 
        var buildPath = function(query){
6103
 
                var xpath = ".";
6104
 
                var qparts = getQueryParts(d.trim(query));
6105
 
                while(qparts.length){
6106
 
                        var tqp = qparts.shift();
6107
 
                        var prefix;
6108
 
                        var postfix = "";
6109
 
                        if(tqp.oper == ">"){
6110
 
                                prefix = "/";
6111
 
                                // prefix = "/child::*";
6112
 
                                tqp = qparts.shift();
6113
 
                        }else if(tqp.oper == "~"){
6114
 
                                prefix = "/following-sibling::"; // get element following siblings
6115
 
                                tqp = qparts.shift();
6116
 
                        }else if(tqp.oper == "+"){
6117
 
                                // FIXME: 
6118
 
                                //              fails when selecting subsequent siblings by node type
6119
 
                                //              because the position() checks the position in the list
6120
 
                                //              of matching elements and not the localized siblings
6121
 
                                prefix = "/following-sibling::";
6122
 
                                postfix = "[position()=1]";
6123
 
                                tqp = qparts.shift();
6124
 
                        }else{
6125
 
                                prefix = "//";
6126
 
                                // prefix = "/descendant::*"
6127
 
                        }
6128
 
 
6129
 
                        // get the tag name (if any)
6130
 
 
6131
 
                        xpath += prefix + tqp.tag + postfix;
6132
 
                        
6133
 
                        // check to see if it's got an id. Needs to come first in xpath.
6134
 
                        if(tqp.id){
6135
 
                                xpath += "[@id='"+tqp.id+"'][1]";
6136
 
                        }
6137
 
 
6138
 
                        d.forEach(tqp.classes, function(cn){
6139
 
                                var cnl = cn.length;
6140
 
                                var padding = " ";
6141
 
                                if(cn.charAt(cnl-1) == "*"){
6142
 
                                        padding = ""; cn = cn.substr(0, cnl-1);
6143
 
                                }
6144
 
                                xpath += 
6145
 
                                        "[contains(concat(' ',@class,' '), ' "+
6146
 
                                        cn + padding + "')]";
6147
 
                        });
6148
 
 
6149
 
                        handleAttrs(xPathAttrs, tqp, 
6150
 
                                function(condition){
6151
 
                                                return "[@"+condition+"]";
6152
 
                                },
6153
 
                                function(matcher){
6154
 
                                        xpath += matcher;
6155
 
                                }
6156
 
                        );
6157
 
 
6158
 
                        // FIXME: need to implement pseudo-class checks!!
6159
 
                };
6160
 
                return xpath;
6161
 
        };
6162
 
 
6163
 
        var _xpathFuncCache = {};
6164
 
        var getXPathFunc = function(path){
6165
 
                if(_xpathFuncCache[path]){
6166
 
                        return _xpathFuncCache[path];
6167
 
                }
6168
 
 
6169
 
                var doc = d.doc;
6170
 
                // don't need to memoize. The closure scope handles it for us.
6171
 
                var xpath = buildPath(path);
6172
 
 
6173
 
                var tf = function(parent){
6174
 
                        // XPath query strings are memoized.
6175
 
 
6176
 
                        var ret = [];
6177
 
                        var xpathResult;
6178
 
                        var tdoc = doc;
6179
 
                        if(parent){
6180
 
                                tdoc = (parent.nodeType == 9) ? parent : parent.ownerDocument;
6181
 
                        }
6182
 
                        try{
6183
 
                                xpathResult = tdoc.evaluate(xpath, parent, null, 
6184
 
                                                                                                // XPathResult.UNORDERED_NODE_ITERATOR_TYPE, null);
6185
 
                                                                                                XPathResult.ANY_TYPE, null);
6186
 
                        }catch(e){
6187
 
                                
6188
 
                                
6189
 
                        }
6190
 
                        var result = xpathResult.iterateNext();
6191
 
                        while(result){
6192
 
                                ret.push(result);
6193
 
                                result = xpathResult.iterateNext();
6194
 
                        }
6195
 
                        return ret;
6196
 
                }
6197
 
                return _xpathFuncCache[path] = tf;
6198
 
        };
6199
 
 
6200
 
        /*
6201
 
        d.xPathMatch = function(query){
6202
 
                // XPath based DOM query system. Handles a small subset of CSS
6203
 
                // selectors, subset is identical to the non-XPath version of this
6204
 
                // function. 
6205
 
 
6206
 
                return getXPathFunc(query)();
6207
 
        }
6208
 
        */
6209
 
 
6210
 
        ////////////////////////////////////////////////////////////////////////
6211
 
        // DOM query code
6212
 
        ////////////////////////////////////////////////////////////////////////
6213
 
 
6214
 
        var _filtersCache = {};
6215
 
        var _simpleFiltersCache = {};
6216
 
 
6217
 
        // the basic building block of the yes/no chaining system. agree(f1, f2)
6218
 
        // generates a new function which returns the boolean results of both of
6219
 
        // the passed functions to a single logical-anded result.
6220
 
        var agree = function(first, second){
6221
 
                if(!first){ return second; }
6222
 
                if(!second){ return first; }
6223
 
 
6224
 
                return function(){
6225
 
                        return first.apply(window, arguments) && second.apply(window, arguments);
6226
 
                }
6227
 
        }
6228
 
 
6229
 
        var _childElements = function(root){
6230
 
                var ret = [];
6231
 
                var te, x = 0, tret = root[childNodesName];
6232
 
                while((te = tret[x++])){
6233
 
                        if(te.nodeType == 1){ ret.push(te); }
6234
 
                }
6235
 
                return ret;
6236
 
        }
6237
 
 
6238
 
        var _nextSiblings = function(root, single){
6239
 
                var ret = [];
6240
 
                var te = root;
6241
 
                while(te = te.nextSibling){
6242
 
                        if(te.nodeType == 1){
6243
 
                                ret.push(te);
6244
 
                                if(single){ break; }
6245
 
                        }
6246
 
                }
6247
 
                return ret;
6248
 
        }
6249
 
 
6250
 
        // FIXME:
6251
 
        //              we need to re-write the way "~" and "+" selectors are handled since
6252
 
        //              the left-hand selector simply modifies the right (which is the
6253
 
        //              actual search selector). We need to locate on search selector
6254
 
        //              instead of modifier to speed up these searches.
6255
 
 
6256
 
        var _filterDown = function(element, queryParts, matchArr, idx){
6257
 
                // NOTE:
6258
 
                //              in the fast path! this function is called recursively and for
6259
 
                //              every run of a query.
6260
 
                var nidx = idx+1;
6261
 
                var isFinal = (queryParts.length == nidx);
6262
 
                var tqp = queryParts[idx];
6263
 
 
6264
 
                // see if we can constrain our next level to direct children
6265
 
                if(tqp.oper){
6266
 
                        // find some eligable children to search
6267
 
                        var ecn = (tqp.oper == ">") ? 
6268
 
                                _childElements(element) :
6269
 
                                _nextSiblings(element, (tqp.oper == "+"));
6270
 
 
6271
 
                        if(!ecn || !ecn.length){
6272
 
                                return;
6273
 
                        }
6274
 
                        nidx++;
6275
 
                        isFinal = (queryParts.length == nidx);
6276
 
                        // kinda janky, too much array alloc
6277
 
                        var tf = getFilterFunc(queryParts[idx+1]);
6278
 
                        // for(var x=ecn.length-1, te; x>=0, te=ecn[x]; x--){
6279
 
                        for(var x=0, ecnl=ecn.length, te; x<ecnl, te=ecn[x]; x++){
6280
 
                                if(tf(te)){
6281
 
                                        if(isFinal){
6282
 
                                                matchArr.push(te);
6283
 
                                        }else{
6284
 
                                                _filterDown(te, queryParts, matchArr, nidx);
6285
 
                                        }
6286
 
                                }
6287
 
                                /*
6288
 
                                if(x==0){
6289
 
                                        break;
6290
 
                                }
6291
 
                                */
6292
 
                        }
6293
 
                }
6294
 
 
6295
 
                // otherwise, keep going down, unless we'er at the end
6296
 
                var candidates = getElementsFunc(tqp)(element);
6297
 
                if(isFinal){
6298
 
                        while(candidates.length){
6299
 
                                matchArr.push(candidates.shift());
6300
 
                        }
6301
 
                        /*
6302
 
                        candidates.unshift(0, matchArr.length-1);
6303
 
                        matchArr.splice.apply(matchArr, candidates);
6304
 
                        */
6305
 
                }else{
6306
 
                        // if we're not yet at the bottom, keep going!
6307
 
                        while(candidates.length){
6308
 
                                _filterDown(candidates.shift(), queryParts, matchArr, nidx);
6309
 
                        }
6310
 
                }
6311
 
        }
6312
 
 
6313
 
        var filterDown = function(elements, queryParts){
6314
 
                var ret = [];
6315
 
 
6316
 
                // for every root, get the elements that match the descendant selector
6317
 
                // for(var x=elements.length-1, te; x>=0, te=elements[x]; x--){
6318
 
                var x = elements.length - 1, te;
6319
 
                while((te = elements[x--])){
6320
 
                        _filterDown(te, queryParts, ret, 0);
6321
 
                }
6322
 
                return ret;
6323
 
        }
6324
 
 
6325
 
        var getFilterFunc = function(q){
6326
 
                // note: query can't have spaces!
6327
 
                if(_filtersCache[q.query]){
6328
 
                        return _filtersCache[q.query];
6329
 
                }
6330
 
                var ff = null;
6331
 
 
6332
 
                // does it have a tagName component?
6333
 
                if(q.tag){
6334
 
                        if(q.tag == "*"){
6335
 
                                ff = agree(ff, 
6336
 
                                        function(elem){
6337
 
                                                return (elem.nodeType == 1);
6338
 
                                        }
6339
 
                                );
6340
 
                        }else{
6341
 
                                // tag name match
6342
 
                                ff = agree(ff, 
6343
 
                                        function(elem){
6344
 
                                                return (
6345
 
                                                        (elem.nodeType == 1) &&
6346
 
                                                        (q[ caseSensitive ? "otag" : "tag" ] == elem.tagName)
6347
 
                                                        // (q.tag == elem.tagName.toLowerCase())
6348
 
                                                );
6349
 
                                                // return isTn;
6350
 
                                        }
6351
 
                                );
6352
 
                        }
6353
 
                }
6354
 
 
6355
 
                // does the node have an ID?
6356
 
                if(q.id){
6357
 
                        ff = agree(ff, 
6358
 
                                function(elem){
6359
 
                                        return (
6360
 
                                                (elem.nodeType == 1) &&
6361
 
                                                (elem.id == q.id)
6362
 
                                        );
6363
 
                                }
6364
 
                        );
6365
 
                }
6366
 
 
6367
 
                if(q.hasLoops){
6368
 
                        // if we have other query param parts, make sure we add them to the
6369
 
                        // filter chain
6370
 
                        ff = agree(ff, getSimpleFilterFunc(q));
6371
 
                }
6372
 
 
6373
 
                return _filtersCache[q.query] = ff;
6374
 
        }
6375
 
 
6376
 
        var getNodeIndex = function(node){
6377
 
                // NOTE: 
6378
 
                //              we could have a more accurate caching mechanism by invalidating
6379
 
                //              caches after the query has finished, but I think that'd lead to
6380
 
                //              significantly more cache churn than the cache would provide
6381
 
                //              value for in the common case. Generally, we're more
6382
 
                //              conservative (and therefore, more accurate) than jQuery and
6383
 
                //              DomQuery WRT node node indexes, but there may be corner cases
6384
 
                //              in which we fall down.  How much we care about them is TBD.
6385
 
 
6386
 
                var pn = node.parentNode;
6387
 
                var pnc = pn.childNodes;
6388
 
 
6389
 
                // check to see if we can trust the cache. If not, re-key the whole
6390
 
                // thing and return our node match from that.
6391
 
 
6392
 
                var nidx = -1;
6393
 
                var child = pn.firstChild;
6394
 
                if(!child){
6395
 
                        return nidx;
6396
 
                }
6397
 
 
6398
 
                var ci = node["__cachedIndex"];
6399
 
                var cl = pn["__cachedLength"];
6400
 
 
6401
 
                // only handle cache building if we've gone out of sync
6402
 
                if(((typeof cl == "number")&&(cl != pnc.length))||(typeof ci != "number")){
6403
 
                        // rip though the whole set, building cache indexes as we go
6404
 
                        pn["__cachedLength"] = pnc.length;
6405
 
                        var idx = 1;
6406
 
                        do{
6407
 
                                // we only assign indexes for nodes with nodeType == 1, as per:
6408
 
                                //              http://www.w3.org/TR/css3-selectors/#nth-child-pseudo
6409
 
                                // only elements are counted in the search order, and they
6410
 
                                // begin at 1 for the first child's index
6411
 
 
6412
 
                                if(child === node){
6413
 
                                        nidx = idx;
6414
 
                                }
6415
 
                                if(child.nodeType == 1){
6416
 
                                        child["__cachedIndex"] = idx;
6417
 
                                        idx++;
6418
 
                                }
6419
 
                                child = child.nextSibling;
6420
 
                        }while(child);
6421
 
                }else{
6422
 
                        // NOTE: 
6423
 
                        //              could be incorrect in some cases (node swaps involving the
6424
 
                        //              passed node, etc.), but we ignore those due to the relative
6425
 
                        //              unlikelihood of that occuring
6426
 
                        nidx = ci;
6427
 
                }
6428
 
                return nidx;
6429
 
        }
6430
 
 
6431
 
        var firedCount = 0;
6432
 
 
6433
 
        var blank = "";
6434
 
        var _getAttr = function(elem, attr){
6435
 
                if(attr == "class"){
6436
 
                        return elem.className || blank;
6437
 
                }
6438
 
                if(attr == "for"){
6439
 
                        return elem.htmlFor || blank;
6440
 
                }
6441
 
                if(attr == "style"){
6442
 
                        return elem.style.cssText || blank;
6443
 
                }
6444
 
                return elem.getAttribute(attr, 2) || blank;
6445
 
        }
6446
 
 
6447
 
        var attrs = {
6448
 
                "*=": function(attr, value){
6449
 
                        return function(elem){
6450
 
                                // E[foo*="bar"]
6451
 
                                //              an E element whose "foo" attribute value contains
6452
 
                                //              the substring "bar"
6453
 
                                return (_getAttr(elem, attr).indexOf(value)>=0);
6454
 
                        }
6455
 
                },
6456
 
                "^=": function(attr, value){
6457
 
                        // E[foo^="bar"]
6458
 
                        //              an E element whose "foo" attribute value begins exactly
6459
 
                        //              with the string "bar"
6460
 
                        return function(elem){
6461
 
                                return (_getAttr(elem, attr).indexOf(value)==0);
6462
 
                        }
6463
 
                },
6464
 
                "$=": function(attr, value){
6465
 
                        // E[foo$="bar"]        
6466
 
                        //              an E element whose "foo" attribute value ends exactly
6467
 
                        //              with the string "bar"
6468
 
                        var tval = " "+value;
6469
 
                        return function(elem){
6470
 
                                var ea = " "+_getAttr(elem, attr);
6471
 
                                return (ea.lastIndexOf(value)==(ea.length-value.length));
6472
 
                        }
6473
 
                },
6474
 
                "~=": function(attr, value){
6475
 
                        // E[foo~="bar"]        
6476
 
                        //              an E element whose "foo" attribute value is a list of
6477
 
                        //              space-separated values, one of which is exactly equal
6478
 
                        //              to "bar"
6479
 
 
6480
 
                        // return "[contains(concat(' ',@"+attr+",' '), ' "+ value +" ')]";
6481
 
                        var tval = " "+value+" ";
6482
 
                        return function(elem){
6483
 
                                var ea = " "+_getAttr(elem, attr)+" ";
6484
 
                                return (ea.indexOf(tval)>=0);
6485
 
                        }
6486
 
                },
6487
 
                "|=": function(attr, value){
6488
 
                        // E[hreflang|="en"]
6489
 
                        //              an E element whose "hreflang" attribute has a
6490
 
                        //              hyphen-separated list of values beginning (from the
6491
 
                        //              left) with "en"
6492
 
                        var valueDash = " "+value+"-";
6493
 
                        return function(elem){
6494
 
                                var ea = " "+(elem.getAttribute(attr, 2) || "");
6495
 
                                return (
6496
 
                                        (ea == value) ||
6497
 
                                        (ea.indexOf(valueDash)==0)
6498
 
                                );
6499
 
                        }
6500
 
                },
6501
 
                "=": function(attr, value){
6502
 
                        return function(elem){
6503
 
                                return (_getAttr(elem, attr) == value);
6504
 
                        }
6505
 
                }
6506
 
        };
6507
 
 
6508
 
        var pseudos = {
6509
 
                "checked": function(name, condition){
6510
 
                        return function(elem){
6511
 
                                return !!d.attr(elem, "checked");
6512
 
                        }
6513
 
                },
6514
 
                "first-child": function(name, condition){
6515
 
                        return function(elem){
6516
 
                                if(elem.nodeType != 1){ return false; }
6517
 
                                // check to see if any of the previous siblings are elements
6518
 
                                var fc = elem.previousSibling;
6519
 
                                while(fc && (fc.nodeType != 1)){
6520
 
                                        fc = fc.previousSibling;
6521
 
                                }
6522
 
                                return (!fc);
6523
 
                        }
6524
 
                },
6525
 
                "last-child": function(name, condition){
6526
 
                        return function(elem){
6527
 
                                if(elem.nodeType != 1){ return false; }
6528
 
                                // check to see if any of the next siblings are elements
6529
 
                                var nc = elem.nextSibling;
6530
 
                                while(nc && (nc.nodeType != 1)){
6531
 
                                        nc = nc.nextSibling;
6532
 
                                }
6533
 
                                return (!nc);
6534
 
                        }
6535
 
                },
6536
 
                "empty": function(name, condition){
6537
 
                        return function(elem){
6538
 
                                // DomQuery and jQuery get this wrong, oddly enough.
6539
 
                                // The CSS 3 selectors spec is pretty explicit about
6540
 
                                // it, too.
6541
 
                                var cn = elem.childNodes;
6542
 
                                var cnl = elem.childNodes.length;
6543
 
                                // if(!cnl){ return true; }
6544
 
                                for(var x=cnl-1; x >= 0; x--){
6545
 
                                        var nt = cn[x].nodeType;
6546
 
                                        if((nt == 1)||(nt == 3)){ return false; }
6547
 
                                }
6548
 
                                return true;
6549
 
                        }
6550
 
                },
6551
 
                "contains": function(name, condition){
6552
 
                        return function(elem){
6553
 
                                // FIXME: I dislike this version of "contains", as
6554
 
                                // whimsical attribute could set it off. An inner-text
6555
 
                                // based version might be more accurate, but since
6556
 
                                // jQuery and DomQuery also potentially get this wrong,
6557
 
                                // I'm leaving it for now.
6558
 
                                if(condition.charAt(0)=='"' || condition.charAt(0)=="'"){//remove quote
6559
 
                                        condition=condition.substr(1,condition.length-2);
6560
 
                                }
6561
 
                                return (elem.innerHTML.indexOf(condition) >= 0);
6562
 
                        }
6563
 
                },
6564
 
                "not": function(name, condition){
6565
 
                        var ntf = getFilterFunc(getQueryParts(condition)[0]);
6566
 
                        return function(elem){
6567
 
                                return (!ntf(elem));
6568
 
                        }
6569
 
                },
6570
 
                "nth-child": function(name, condition){
6571
 
                        var pi = parseInt;
6572
 
                        if(condition == "odd"){
6573
 
                                condition = "2n+1";
6574
 
                        }else if(condition == "even"){
6575
 
                                condition = "2n";
6576
 
                        }
6577
 
                        if(condition.indexOf("n") != -1){
6578
 
                                var tparts = condition.split("n", 2);
6579
 
                                var pred = tparts[0] ? (tparts[0]=='-'?-1:pi(tparts[0])) : 1;
6580
 
                                var idx = tparts[1] ? pi(tparts[1]) : 0;
6581
 
                                var lb = 0, ub = -1;
6582
 
                                if(pred>0){
6583
 
                                        if(idx<0){
6584
 
                                                idx = (idx % pred) && (pred + (idx % pred));
6585
 
                                        }else if(idx>0){
6586
 
                                                if(idx >= pred){
6587
 
                                                        lb = idx - idx % pred;
6588
 
                                                }
6589
 
                                                idx = idx % pred;
6590
 
                                        }
6591
 
                                }else if(pred<0){
6592
 
                                        pred *= -1;
6593
 
                                        if(idx>0){
6594
 
                                                ub = idx;
6595
 
                                                idx = idx % pred;
6596
 
                                        } //idx has to be greater than 0 when pred is negative; shall we throw an error here?
6597
 
                                }
6598
 
                                if(pred>0){
6599
 
                                        return function(elem){
6600
 
                                                var i=getNodeIndex(elem);
6601
 
                                                return (i>=lb) && (ub<0 || i<=ub) && ((i % pred) == idx);
6602
 
                                        }
6603
 
                                }else{
6604
 
                                        condition=idx;
6605
 
                                }
6606
 
                        }
6607
 
                        //if(condition.indexOf("n") == -1){
6608
 
                        var ncount = pi(condition);
6609
 
                        return function(elem){
6610
 
                                return (getNodeIndex(elem) == ncount);
6611
 
                        }
6612
 
                }
6613
 
        };
6614
 
 
6615
 
        var defaultGetter = (d.isIE) ? function(cond){
6616
 
                var clc = cond.toLowerCase();
6617
 
                return function(elem){
6618
 
                        return elem[cond]||elem[clc];
6619
 
                }
6620
 
        } : function(cond){
6621
 
                return function(elem){
6622
 
                        return (elem && elem.getAttribute && elem.hasAttribute(cond));
6623
 
                }
6624
 
        };
6625
 
 
6626
 
        var getSimpleFilterFunc = function(query){
6627
 
 
6628
 
                var fcHit = (_simpleFiltersCache[query.query]||_filtersCache[query.query]);
6629
 
                if(fcHit){ return fcHit; }
6630
 
 
6631
 
                var ff = null;
6632
 
 
6633
 
                // the only case where we'll need the tag name is if we came from an ID query
6634
 
                if(query.id){ // do we have an ID component?
6635
 
                        if(query.tag != "*"){
6636
 
                                ff = agree(ff, function(elem){
6637
 
                                        return (elem.tagName == query[ caseSensitive ? "otag" : "tag" ]);
6638
 
                                });
6639
 
                        }
6640
 
                }
6641
 
 
6642
 
                // if there's a class in our query, generate a match function for it
6643
 
                d.forEach(query.classes, function(cname, idx, arr){
6644
 
                        // get the class name
6645
 
                        var isWildcard = cname.charAt(cname.length-1) == "*";
6646
 
                        if(isWildcard){
6647
 
                                cname = cname.substr(0, cname.length-1);
6648
 
                        }
6649
 
                        // I dislike the regex thing, even if memozied in a cache, but it's VERY short
6650
 
                        var re = new RegExp("(?:^|\\s)" + cname + (isWildcard ? ".*" : "") + "(?:\\s|$)");
6651
 
                        ff = agree(ff, function(elem){
6652
 
                                return re.test(elem.className);
6653
 
                        });
6654
 
                        ff.count = idx;
6655
 
                });
6656
 
 
6657
 
                d.forEach(query.pseudos, function(pseudo){
6658
 
                        if(pseudos[pseudo.name]){
6659
 
                                ff = agree(ff, pseudos[pseudo.name](pseudo.name, pseudo.value));
6660
 
                        }
6661
 
                });
6662
 
 
6663
 
                handleAttrs(attrs, query, defaultGetter,
6664
 
                        function(tmatcher){ ff = agree(ff, tmatcher); }
6665
 
                );
6666
 
                if(!ff){
6667
 
                        ff = function(){ return true; };
6668
 
                }
6669
 
                return _simpleFiltersCache[query.query] = ff;
6670
 
        }
6671
 
 
6672
 
        var _getElementsFuncCache = { };
6673
 
 
6674
 
        var getElementsFunc = function(query, root){
6675
 
                var fHit = _getElementsFuncCache[query.query];
6676
 
                if(fHit){ return fHit; }
6677
 
 
6678
 
                // NOTE: this function is in the fast path! not memoized!!!
6679
 
 
6680
 
                // the query doesn't contain any spaces, so there's only so many
6681
 
                // things it could be
6682
 
 
6683
 
                if(query.id && !query.hasLoops && !query.tag){
6684
 
                        // ID-only query. Easy.
6685
 
                        return _getElementsFuncCache[query.query] = function(root){
6686
 
                                // FIXME: if root != document, check for parenting!
6687
 
                                return [ d.byId(query.id) ];
6688
 
                        }
6689
 
                }
6690
 
 
6691
 
                var filterFunc = getSimpleFilterFunc(query);
6692
 
 
6693
 
                var retFunc;
6694
 
                if(query.tag && query.id && !query.hasLoops){
6695
 
                        // we got a filtered ID search (e.g., "h4#thinger")
6696
 
                        retFunc = function(root){
6697
 
                                var te = d.byId(query.id, (root.ownerDocument||root)); //root itself may be a document
6698
 
                                if(filterFunc(te)){
6699
 
                                        return [ te ];
6700
 
                                }
6701
 
                        }
6702
 
                }else{
6703
 
                        var tret;
6704
 
 
6705
 
                        if(!query.hasLoops){
6706
 
                                // it's just a plain-ol elements-by-tag-name query from the root
6707
 
                                retFunc = function(root){
6708
 
                                        var ret = [];
6709
 
                                        var te, x=0, tret = root.getElementsByTagName(query[ caseSensitive ? "otag" : "tag"]);
6710
 
                                        while((te = tret[x++])){
6711
 
                                                ret.push(te);
6712
 
                                        }
6713
 
                                        return ret;
6714
 
                                }
6715
 
                        }else{
6716
 
                                retFunc = function(root){
6717
 
                                        var ret = [];
6718
 
                                        var te, x = 0, tret = root.getElementsByTagName(query[ caseSensitive ? "otag" : "tag"]);
6719
 
                                        while((te = tret[x++])){
6720
 
                                                if(filterFunc(te)){
6721
 
                                                        ret.push(te);
6722
 
                                                }
6723
 
                                        }
6724
 
                                        return ret;
6725
 
                                }
6726
 
                        }
6727
 
                }
6728
 
                return _getElementsFuncCache[query.query] = retFunc;
6729
 
        }
6730
 
 
6731
 
        var _partsCache = {};
6732
 
 
6733
 
        ////////////////////////////////////////////////////////////////////////
6734
 
        // the query runner
6735
 
        ////////////////////////////////////////////////////////////////////////
6736
 
 
6737
 
        // this is the second level of spliting, from full-length queries (e.g.,
6738
 
        // "div.foo .bar") into simple query expressions (e.g., ["div.foo",
6739
 
        // ".bar"])
6740
 
        var _queryFuncCache = {
6741
 
                "*": d.isIE ? 
6742
 
                        function(root){ 
6743
 
                                        return root.all;
6744
 
                        } : 
6745
 
                        function(root){
6746
 
                                 return root.getElementsByTagName("*");
6747
 
                        },
6748
 
                "~": _nextSiblings,
6749
 
                "+": function(root){ return _nextSiblings(root, true); },
6750
 
                ">": _childElements
6751
 
        };
6752
 
 
6753
 
        var getStepQueryFunc = function(query){
6754
 
                // if it's trivial, get a fast-path dispatcher
6755
 
                var qparts = getQueryParts(d.trim(query));
6756
 
                // if(query[query.length-1] == ">"){ query += " *"; }
6757
 
                if(qparts.length == 1){
6758
 
                        var tt = getElementsFunc(qparts[0]);
6759
 
                        tt.nozip = true; // FIXME: is this right? Shouldn't this be wrapped in a closure to mark the return?
6760
 
                        return tt;
6761
 
                }
6762
 
 
6763
 
                // otherwise, break it up and return a runner that iterates over the parts recursively
6764
 
                var sqf = function(root){
6765
 
                        var localQueryParts = qparts.slice(0); // clone the src arr
6766
 
                        var candidates;
6767
 
                        if(localQueryParts[0].oper == ">"){ // FIXME: what if it's + or ~?
6768
 
                                candidates = [ root ];
6769
 
                                // root = document;
6770
 
                        }else{
6771
 
                                candidates = getElementsFunc(localQueryParts.shift())(root);
6772
 
                        }
6773
 
                        return filterDown(candidates, localQueryParts);
6774
 
                }
6775
 
                return sqf;
6776
 
        }
6777
 
 
6778
 
        // a specialized method that implements our primoridal "query optimizer".
6779
 
        // This allows us to dispatch queries to the fastest subsystem we can get.
6780
 
        var _getQueryFunc = (
6781
 
                // NOTE: 
6782
 
                //              XPath on the Webkit is slower than it's DOM iteration for most
6783
 
                //              test cases
6784
 
                // FIXME: 
6785
 
                //              we should try to capture some runtime speed data for each query
6786
 
                //              function to determine on the fly if we should stick w/ the
6787
 
                //              potentially optimized variant or if we should try something
6788
 
                //              new.
6789
 
                (document["evaluate"] && !d.isSafari) ? 
6790
 
                function(query, root){
6791
 
                        // has xpath support that's faster than DOM
6792
 
                        var qparts = query.split(" ");
6793
 
                        // can we handle it?
6794
 
                        if(     (!caseSensitive) && // not strictly necessaray, but simplifies lots of stuff
6795
 
                                (document["evaluate"]) &&
6796
 
                                (query.indexOf(":") == -1) &&
6797
 
                                (query.indexOf("+") == -1) // skip direct sibling matches. See line ~344
6798
 
                        ){
6799
 
                                // dojo.debug(query);
6800
 
                                // should we handle it?
6801
 
 
6802
 
                                // kind of a lame heuristic, but it works
6803
 
                                if(     
6804
 
                                        // a "div div div" style query
6805
 
                                        ((qparts.length > 2)&&(query.indexOf(">") == -1))||
6806
 
                                        // or something else with moderate complexity. kinda janky
6807
 
                                        (qparts.length > 3)||
6808
 
                                        (query.indexOf("[")>=0)||
6809
 
                                        // or if it's a ".thinger" query
6810
 
                                        ((1 == qparts.length)&&(0 <= query.indexOf(".")))
6811
 
 
6812
 
                                ){
6813
 
                                        // use get and cache a xpath runner for this selector
6814
 
                                        return getXPathFunc(query);
6815
 
                                }
6816
 
                        }
6817
 
 
6818
 
                        // fallthrough
6819
 
                        return getStepQueryFunc(query);
6820
 
                } : getStepQueryFunc
6821
 
        );
6822
 
        // uncomment to disable XPath for testing and tuning the DOM path
6823
 
        // _getQueryFunc = getStepQueryFunc;
6824
 
 
6825
 
        // FIXME: we've got problems w/ the NodeList query()/filter() functions if we go XPath for everything
6826
 
 
6827
 
        // uncomment to disable DOM queries for testing and tuning XPath
6828
 
        // _getQueryFunc = getXPathFunc;
6829
 
 
6830
 
        // this is the primary caching for full-query results. The query dispatcher
6831
 
        // functions are generated here and then pickled for hash lookup in the
6832
 
        // future
6833
 
        var getQueryFunc = function(query){
6834
 
                // return a cached version if one is available
6835
 
                var qcz = query.charAt(0);
6836
 
                if(d.doc["querySelectorAll"] && 
6837
 
                        ( (!d.isSafari) || (d.isSafari > 3.1) ) && // see #5832
6838
 
                        // as per CSS 3, we can't currently start w/ combinator:
6839
 
                        //              http://www.w3.org/TR/css3-selectors/#w3cselgrammar
6840
 
                        (">+~".indexOf(qcz) == -1)
6841
 
                ){
6842
 
                        return function(root){
6843
 
                                var r = root.querySelectorAll(query);
6844
 
                                r.nozip = true; // skip expensive duplication checks and just wrap in a NodeList
6845
 
                                return r;
6846
 
                        };
6847
 
                }
6848
 
                if(_queryFuncCache[query]){ return _queryFuncCache[query]; }
6849
 
                if(0 > query.indexOf(",")){
6850
 
                        // if it's not a compound query (e.g., ".foo, .bar"), cache and return a dispatcher
6851
 
                        return _queryFuncCache[query] = _getQueryFunc(query);
6852
 
                }else{
6853
 
                        // if it's a complex query, break it up into it's constituent parts
6854
 
                        // and return a dispatcher that will merge the parts when run
6855
 
 
6856
 
                        // var parts = query.split(", ");
6857
 
                        var parts = query.split(/\s*,\s*/);
6858
 
                        var tf = function(root){
6859
 
                                var pindex = 0; // avoid array alloc for every invocation
6860
 
                                var ret = [];
6861
 
                                var tp;
6862
 
                                while((tp = parts[pindex++])){
6863
 
                                        ret = ret.concat(_getQueryFunc(tp, tp.indexOf(" "))(root));
6864
 
                                }
6865
 
                                return ret;
6866
 
                        }
6867
 
                        // ...cache and return
6868
 
                        return _queryFuncCache[query] = tf;
6869
 
                }
6870
 
        }
6871
 
 
6872
 
        // FIXME: 
6873
 
        //              Dean's Base2 uses a system whereby queries themselves note if
6874
 
        //              they'll need duplicate filtering. We need to get on that plan!!
6875
 
 
6876
 
        // attempt to efficiently determine if an item in a list is a dupe,
6877
 
        // returning a list of "uniques", hopefully in doucment order
6878
 
        var _zipIdx = 0;
6879
 
        var _zip = function(arr){
6880
 
                if(arr && arr.nozip){ return d.NodeList._wrap(arr); }
6881
 
                var ret = new d.NodeList();
6882
 
                if(!arr){ return ret; }
6883
 
                if(arr[0]){
6884
 
                        ret.push(arr[0]);
6885
 
                }
6886
 
                if(arr.length < 2){ return ret; }
6887
 
 
6888
 
                _zipIdx++;
6889
 
                
6890
 
                // we have to fork here for IE and XML docs because we can't set
6891
 
                // expandos on their nodes (apparently). *sigh*
6892
 
                if(d.isIE && caseSensitive){
6893
 
                        var szidx = _zipIdx+"";
6894
 
                        arr[0].setAttribute("_zipIdx", szidx);
6895
 
                        for(var x = 1, te; te = arr[x]; x++){
6896
 
                                if(arr[x].getAttribute("_zipIdx") != szidx){ 
6897
 
                                        ret.push(te);
6898
 
                                }
6899
 
                                te.setAttribute("_zipIdx", szidx);
6900
 
                        }
6901
 
                }else{
6902
 
                        arr[0]["_zipIdx"] = _zipIdx;
6903
 
                        for(var x = 1, te; te = arr[x]; x++){
6904
 
                                if(arr[x]["_zipIdx"] != _zipIdx){ 
6905
 
                                        ret.push(te);
6906
 
                                }
6907
 
                                te["_zipIdx"] = _zipIdx;
6908
 
                        }
6909
 
                }
6910
 
                // FIXME: should we consider stripping these properties?
6911
 
                return ret;
6912
 
        }
6913
 
 
6914
 
        // the main executor
6915
 
        d.query = function(/*String*/ query, /*String|DOMNode?*/ root){
6916
 
                //      summary:
6917
 
                //              Returns nodes which match the given CSS3 selector, searching the
6918
 
                //              entire document by default but optionally taking a node to scope
6919
 
                //              the search by. Returns an instance of dojo.NodeList.
6920
 
                //      description:
6921
 
                //              dojo.query() is the swiss army knife of DOM node manipulation in
6922
 
                //              Dojo. Much like Prototype's "$$" (bling-bling) function or JQuery's
6923
 
                //              "$" function, dojo.query provides robust, high-performance
6924
 
                //              CSS-based node selector support with the option of scoping searches
6925
 
                //              to a particular sub-tree of a document.
6926
 
                //
6927
 
                //              Supported Selectors:
6928
 
                //              --------------------
6929
 
                //
6930
 
                //              dojo.query() supports a rich set of CSS3 selectors, including:
6931
 
                //
6932
 
                //                      * class selectors (e.g., `.foo`)
6933
 
                //                      * node type selectors like `span`
6934
 
                //                      * ` ` descendant selectors
6935
 
                //                      * `>` child element selectors 
6936
 
                //                      * `#foo` style ID selectors
6937
 
                //                      * `*` universal selector
6938
 
                //                      * `~`, the immediately preceeded-by sibling selector
6939
 
                //                      * `+`, the preceeded-by sibling selector
6940
 
                //                      * attribute queries:
6941
 
                //                      |       * `[foo]` attribute presence selector
6942
 
                //                      |       * `[foo='bar']` attribute value exact match
6943
 
                //                      |       * `[foo~='bar']` attribute value list item match
6944
 
                //                      |       * `[foo^='bar']` attribute start match
6945
 
                //                      |       * `[foo$='bar']` attribute end match
6946
 
                //                      |       * `[foo*='bar']` attribute substring match
6947
 
                //                      * `:first-child`, `:last-child` positional selectors
6948
 
                //                      * `:empty` content emtpy selector
6949
 
                //                      * `:empty` content emtpy selector
6950
 
                //                      * `:checked` pseudo selector
6951
 
                //                      * `:nth-child(n)`, `:nth-child(2n+1)` style positional calculations
6952
 
                //                      * `:nth-child(even)`, `:nth-child(odd)` positional selectors
6953
 
                //                      * `:not(...)` negation pseudo selectors
6954
 
                //
6955
 
                //              Any legal combination of these selectors will work with
6956
 
                //              `dojo.query()`, including compound selectors ("," delimited).
6957
 
                //              Very complex and useful searches can be constructed with this
6958
 
                //              palette of selectors and when combined with functions for
6959
 
                //              maniplation presented by dojo.NodeList, many types of DOM
6960
 
                //              manipulation operations become very straightforward.
6961
 
                //              
6962
 
                //              Unsupported Selectors:
6963
 
                //              ----------------------
6964
 
                //
6965
 
                //              While dojo.query handles many CSS3 selectors, some fall outside of
6966
 
                //              what's resaonable for a programmatic node querying engine to
6967
 
                //              handle. Currently unsupported selectors include:
6968
 
                //              
6969
 
                //                      * namespace-differentiated selectors of any form
6970
 
                //                      * all `::` pseduo-element selectors
6971
 
                //                      * certain pseduo-selectors which don't get a lot of day-to-day use:
6972
 
                //                      |       * `:root`, `:lang()`, `:target`, `:focus`
6973
 
                //                      * all visual and state selectors:
6974
 
                //                      |       * `:root`, `:active`, `:hover`, `:visisted`, `:link`,
6975
 
                //                                `:enabled`, `:disabled`
6976
 
                //                      * `:*-of-type` pseudo selectors
6977
 
                //              
6978
 
                //              dojo.query and XML Documents:
6979
 
                //              -----------------------------
6980
 
                //              
6981
 
                //              `dojo.query` currently only supports searching XML documents
6982
 
                //              whose tags and attributes are 100% lower-case. This is a known
6983
 
                //              limitation and will [be addressed soon](http://trac.dojotoolkit.org/ticket/3866)
6984
 
                //              Non-selector Queries:
6985
 
                //              ---------------------
6986
 
                //
6987
 
                //              If something other than a String is passed for the query,
6988
 
                //              `dojo.query` will return a new `dojo.NodeList` constructed from
6989
 
                //              that parameter alone and all further processing will stop. This
6990
 
                //              means that if you have a reference to a node or NodeList, you
6991
 
                //              can quickly construct a new NodeList from the original by
6992
 
                //              calling `dojo.query(node)` or `dojo.query(list)`.
6993
 
                //
6994
 
                //      query:
6995
 
                //              The CSS3 expression to match against. For details on the syntax of
6996
 
                //              CSS3 selectors, see <http://www.w3.org/TR/css3-selectors/#selectors>
6997
 
                //      root:
6998
 
                //              A DOMNode (or node id) to scope the search from. Optional.
6999
 
                //      returns: dojo.NodeList
7000
 
                //              An instance of `dojo.NodeList`. Many methods are available on
7001
 
                //              NodeLists for searching, iterating, manipulating, and handling
7002
 
                //              events on the matched nodes in the returned list.
7003
 
                //      example:
7004
 
                //              search the entire document for elements with the class "foo":
7005
 
                //      |       dojo.query(".foo");
7006
 
                //              these elements will match:
7007
 
                //      |       <span class="foo"></span>
7008
 
                //      |       <span class="foo bar"></span>
7009
 
                //      |       <p class="thud foo"></p>
7010
 
                //      example:
7011
 
                //              search the entire document for elements with the classes "foo" *and* "bar":
7012
 
                //      |       dojo.query(".foo.bar");
7013
 
                //              these elements will match:
7014
 
                //      |       <span class="foo bar"></span>
7015
 
                //              while these will not:
7016
 
                //      |       <span class="foo"></span>
7017
 
                //      |       <p class="thud foo"></p>
7018
 
                //      example:
7019
 
                //              find `<span>` elements which are descendants of paragraphs and
7020
 
                //              which have a "highlighted" class:
7021
 
                //      |       dojo.query("p span.highlighted");
7022
 
                //              the innermost span in this fragment matches:
7023
 
                //      |       <p class="foo">
7024
 
                //      |               <span>...
7025
 
                //      |                       <span class="highlighted foo bar">...</span>
7026
 
                //      |               </span>
7027
 
                //      |       </p>
7028
 
                //      example:
7029
 
                //              set an "odd" class on all odd table rows inside of the table
7030
 
                //              `#tabular_data`, using the `>` (direct child) selector to avoid
7031
 
                //              affecting any nested tables:
7032
 
                //      |       dojo.query("#tabular_data > tbody > tr:nth-child(odd)").addClass("odd");
7033
 
                //      example:
7034
 
                //              remove all elements with the class "error" from the document
7035
 
                //              and store them in a list:
7036
 
                //      |       var errors = dojo.query(".error").orphan();
7037
 
                //      example:
7038
 
                //              add an onclick handler to every submit button in the document
7039
 
                //              which causes the form to be sent via Ajax instead:
7040
 
                //      |       dojo.query("input[type='submit']").onclick(function(e){
7041
 
                //      |               dojo.stopEvent(e); // prevent sending the form
7042
 
                //      |               var btn = e.target;
7043
 
                //      |               dojo.xhrPost({
7044
 
                //      |                       form: btn.form,
7045
 
                //      |                       load: function(data){
7046
 
                //      |                               // replace the form with the response
7047
 
                //      |                               var div = dojo.doc.createElement("div");
7048
 
                //      |                               dojo.place(div, btn.form, "after");
7049
 
                //      |                               div.innerHTML = data;
7050
 
                //      |                               dojo.style(btn.form, "display", "none");
7051
 
                //      |                       }
7052
 
                //      |               });
7053
 
                //      |       });
7054
 
 
7055
 
 
7056
 
                // NOTE: elementsById is not currently supported
7057
 
                // NOTE: ignores xpath-ish queries for now
7058
 
 
7059
 
                if(query.constructor == d.NodeList){
7060
 
                        return query;
7061
 
                }
7062
 
                if(!d.isString(query)){
7063
 
                        return new d.NodeList(query); // dojo.NodeList
7064
 
                }
7065
 
                if(d.isString(root)){
7066
 
                        root = d.byId(root);
7067
 
                }
7068
 
 
7069
 
                root = root||d.doc;
7070
 
                var od = root.ownerDocument||root.documentElement;
7071
 
                caseSensitive = (root.contentType && root.contentType=="application/xml") || (!!od) && (d.isIE ? od.xml : (root.xmlVersion||od.xmlVersion));
7072
 
                return _zip(getQueryFunc(query)(root)); // dojo.NodeList
7073
 
        }
7074
 
 
7075
 
        /*
7076
 
        // exposing this was a mistake
7077
 
        d.query.attrs = attrs;
7078
 
        */
7079
 
        // exposing this because new pseudo matches are only executed through the
7080
 
        // DOM query path (never through the xpath optimizing branch)
7081
 
        d.query.pseudos = pseudos;
7082
 
 
7083
 
        // one-off function for filtering a NodeList based on a simple selector
7084
 
        d._filterQueryResult = function(nodeList, simpleFilter){
7085
 
                var tnl = new d.NodeList();
7086
 
                var ff = (simpleFilter) ? getFilterFunc(getQueryParts(simpleFilter)[0]) : function(){ return true; };
7087
 
                for(var x = 0, te; te = nodeList[x]; x++){
7088
 
                        if(ff(te)){ tnl.push(te); }
7089
 
                }
7090
 
                return tnl;
7091
 
        }
7092
 
})();
7093
 
 
7094
 
}
7095
 
 
7096
 
if(!dojo._hasResource["dojo._base.xhr"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
7097
 
dojo._hasResource["dojo._base.xhr"] = true;
7098
 
dojo.provide("dojo._base.xhr");
7099
 
 
7100
 
 
7101
 
 
7102
 
 
7103
 
 
7104
 
(function(){
7105
 
        var _d = dojo;
7106
 
        function setValue(/*Object*/obj, /*String*/name, /*String*/value){
7107
 
                //summary:
7108
 
                //              For the named property in object, set the value. If a value
7109
 
                //              already exists and it is a string, convert the value to be an
7110
 
                //              array of values.
7111
 
                var val = obj[name];
7112
 
                if(_d.isString(val)){
7113
 
                        obj[name] = [val, value];
7114
 
                }else if(_d.isArray(val)){
7115
 
                        val.push(value);
7116
 
                }else{
7117
 
                        obj[name] = value;
7118
 
                }
7119
 
        }
7120
 
 
7121
 
        dojo.formToObject = function(/*DOMNode||String*/ formNode){
7122
 
                // summary:
7123
 
                //              dojo.formToObject returns the values encoded in an HTML form as
7124
 
                //              string properties in an object which it then returns. Disabled form
7125
 
                //              elements, buttons, and other non-value form elements are skipped.
7126
 
                //              Multi-select elements are returned as an array of string values.
7127
 
                // description:
7128
 
                //              This form:
7129
 
                //
7130
 
                //              |       <form id="test_form">
7131
 
                //              |               <input type="text" name="blah" value="blah">
7132
 
                //              |               <input type="text" name="no_value" value="blah" disabled>
7133
 
                //              |               <input type="button" name="no_value2" value="blah">
7134
 
                //              |               <select type="select" multiple name="multi" size="5">
7135
 
                //              |                       <option value="blah">blah</option>
7136
 
                //              |                       <option value="thud" selected>thud</option>
7137
 
                //              |                       <option value="thonk" selected>thonk</option>
7138
 
                //              |               </select>
7139
 
                //              |       </form>
7140
 
                //
7141
 
                //              yields this object structure as the result of a call to
7142
 
                //              formToObject():
7143
 
                //
7144
 
                //              |       { 
7145
 
                //              |               blah: "blah",
7146
 
                //              |               multi: [
7147
 
                //              |                       "thud",
7148
 
                //              |                       "thonk"
7149
 
                //              |               ]
7150
 
                //              |       };
7151
 
 
7152
 
                var ret = {};
7153
 
                var exclude = "file|submit|image|reset|button|";
7154
 
                _d.forEach(dojo.byId(formNode).elements, function(item){
7155
 
                        var _in = item.name;
7156
 
                        var type = (item.type||"").toLowerCase();
7157
 
                        if(_in && type && exclude.indexOf(type) == -1 && !item.disabled){
7158
 
                                if(type == "radio" || type == "checkbox"){
7159
 
                                        if(item.checked){ setValue(ret, _in, item.value); }
7160
 
                                }else if(item.multiple){
7161
 
                                        ret[_in] = [];
7162
 
                                        _d.query("option", item).forEach(function(opt){
7163
 
                                                if(opt.selected){
7164
 
                                                        setValue(ret, _in, opt.value);
7165
 
                                                }
7166
 
                                        });
7167
 
                                }else{ 
7168
 
                                        setValue(ret, _in, item.value);
7169
 
                                        if(type == "image"){
7170
 
                                                ret[_in+".x"] = ret[_in+".y"] = ret[_in].x = ret[_in].y = 0;
7171
 
                                        }
7172
 
                                }
7173
 
                        }
7174
 
                });
7175
 
                return ret; // Object
7176
 
        }
7177
 
 
7178
 
        dojo.objectToQuery = function(/*Object*/ map){
7179
 
                //      summary:
7180
 
                //              takes a name/value mapping object and returns a string representing
7181
 
                //              a URL-encoded version of that object.
7182
 
                //      example:
7183
 
                //              this object:
7184
 
                //
7185
 
                //              |       { 
7186
 
                //              |               blah: "blah",
7187
 
                //              |               multi: [
7188
 
                //              |                       "thud",
7189
 
                //              |                       "thonk"
7190
 
                //              |               ]
7191
 
                //              |       };
7192
 
                //
7193
 
                //      yields the following query string:
7194
 
                //      
7195
 
                //      |       "blah=blah&multi=thud&multi=thonk"
7196
 
 
7197
 
                // FIXME: need to implement encodeAscii!!
7198
 
                var enc = encodeURIComponent;
7199
 
                var pairs = [];
7200
 
                var backstop = {};
7201
 
                for(var name in map){
7202
 
                        var value = map[name];
7203
 
                        if(value != backstop[name]){
7204
 
                                var assign = enc(name) + "=";
7205
 
                                if(_d.isArray(value)){
7206
 
                                        for(var i=0; i < value.length; i++){
7207
 
                                                pairs.push(assign + enc(value[i]));
7208
 
                                        }
7209
 
                                }else{
7210
 
                                        pairs.push(assign + enc(value));
7211
 
                                }
7212
 
                        }
7213
 
                }
7214
 
                return pairs.join("&"); // String
7215
 
        }
7216
 
 
7217
 
        dojo.formToQuery = function(/*DOMNode||String*/ formNode){
7218
 
                // summary:
7219
 
                //              Returns a URL-encoded string representing the form passed as either a
7220
 
                //              node or string ID identifying the form to serialize
7221
 
                return _d.objectToQuery(_d.formToObject(formNode)); // String
7222
 
        }
7223
 
 
7224
 
        dojo.formToJson = function(/*DOMNode||String*/ formNode, /*Boolean?*/prettyPrint){
7225
 
                // summary:
7226
 
                //              return a serialized JSON string from a form node or string
7227
 
                //              ID identifying the form to serialize
7228
 
                return _d.toJson(_d.formToObject(formNode), prettyPrint); // String
7229
 
        }
7230
 
 
7231
 
        dojo.queryToObject = function(/*String*/ str){
7232
 
                // summary:
7233
 
                //              returns an object representing a de-serialized query section of a
7234
 
                //              URL. Query keys with multiple values are returned in an array.
7235
 
                // description:
7236
 
                //              This string:
7237
 
                //
7238
 
                //      |               "foo=bar&foo=baz&thinger=%20spaces%20=blah&zonk=blarg&"
7239
 
                //              
7240
 
                //              results in this object structure:
7241
 
                //
7242
 
                //      |               {
7243
 
                //      |                       foo: [ "bar", "baz" ],
7244
 
                //      |                       thinger: " spaces =blah",
7245
 
                //      |                       zonk: "blarg"
7246
 
                //      |               }
7247
 
                //      
7248
 
                //              Note that spaces and other urlencoded entities are correctly
7249
 
                //              handled.
7250
 
 
7251
 
                // FIXME: should we grab the URL string if we're not passed one?
7252
 
                var ret = {};
7253
 
                var qp = str.split("&");
7254
 
                var dec = decodeURIComponent;
7255
 
                _d.forEach(qp, function(item){
7256
 
                        if(item.length){
7257
 
                                var parts = item.split("=");
7258
 
                                var name = dec(parts.shift());
7259
 
                                var val = dec(parts.join("="));
7260
 
                                if(_d.isString(ret[name])){
7261
 
                                        ret[name] = [ret[name]];
7262
 
                                }
7263
 
                                if(_d.isArray(ret[name])){
7264
 
                                        ret[name].push(val);
7265
 
                                }else{
7266
 
                                        ret[name] = val;
7267
 
                                }
7268
 
                        }
7269
 
                });
7270
 
                return ret; // Object
7271
 
        }
7272
 
 
7273
 
        /*
7274
 
                from refactor.txt:
7275
 
 
7276
 
                all bind() replacement APIs take the following argument structure:
7277
 
 
7278
 
                        {
7279
 
                                url: "blah.html",
7280
 
 
7281
 
                                // all below are optional, but must be supported in some form by
7282
 
                                // every IO API
7283
 
                                timeout: 1000, // milliseconds
7284
 
                                handleAs: "text", // replaces the always-wrong "mimetype"
7285
 
                                content: { 
7286
 
                                        key: "value"
7287
 
                                },
7288
 
 
7289
 
                                // browser-specific, MAY be unsupported
7290
 
                                sync: true, // defaults to false
7291
 
                                form: dojo.byId("someForm") 
7292
 
                        }
7293
 
        */
7294
 
 
7295
 
        // need to block async callbacks from snatching this thread as the result
7296
 
        // of an async callback might call another sync XHR, this hangs khtml forever
7297
 
        // must checked by watchInFlight()
7298
 
 
7299
 
        dojo._blockAsync = false;
7300
 
 
7301
 
        dojo._contentHandlers = {
7302
 
                "text": function(xhr){ return xhr.responseText; },
7303
 
                "json": function(xhr){
7304
 
                        return _d.fromJson(xhr.responseText || null);
7305
 
                },
7306
 
                "json-comment-filtered": function(xhr){ 
7307
 
                        // NOTE: the json-comment-filtered option was implemented to prevent
7308
 
                        // "JavaScript Hijacking", but it is less secure than standard JSON. Use
7309
 
                        // standard JSON instead. JSON prefixing can be used to subvert hijacking.
7310
 
                        if(!dojo.config.useCommentedJson){
7311
 
                                console.warn("Consider using the standard mimetype:application/json."
7312
 
                                        + " json-commenting can introduce security issues. To"
7313
 
                                        + " decrease the chances of hijacking, use the standard the 'json' handler and"
7314
 
                                        + " prefix your json with: {}&&\n"
7315
 
                                        + "Use djConfig.useCommentedJson=true to turn off this message.");
7316
 
                        }
7317
 
 
7318
 
                        var value = xhr.responseText;
7319
 
                        var cStartIdx = value.indexOf("\/*");
7320
 
                        var cEndIdx = value.lastIndexOf("*\/");
7321
 
                        if(cStartIdx == -1 || cEndIdx == -1){
7322
 
                                throw new Error("JSON was not comment filtered");
7323
 
                        }
7324
 
                        return _d.fromJson(value.substring(cStartIdx+2, cEndIdx));
7325
 
                },
7326
 
                "javascript": function(xhr){ 
7327
 
                        // FIXME: try Moz and IE specific eval variants?
7328
 
                        return _d.eval(xhr.responseText);
7329
 
                },
7330
 
                "xml": function(xhr){ 
7331
 
                        var result = xhr.responseXML;
7332
 
                        if(_d.isIE && (!result || result.documentElement == null)){
7333
 
                                _d.forEach(["MSXML2", "Microsoft", "MSXML", "MSXML3"], function(prefix){
7334
 
                                        try{
7335
 
                                                var dom = new ActiveXObject(prefix + ".XMLDOM");
7336
 
                                                dom.async = false;
7337
 
                                                dom.loadXML(xhr.responseText);
7338
 
                                                result = dom;
7339
 
                                        }catch(e){ /* Not available. Squelch and try next one. */ }
7340
 
                                });
7341
 
                        }
7342
 
                        return result; // DOMDocument
7343
 
                }
7344
 
        };
7345
 
 
7346
 
        dojo._contentHandlers["json-comment-optional"] = function(xhr){
7347
 
                var handlers = _d._contentHandlers;
7348
 
                if(xhr.responseText && xhr.responseText.indexOf("\/*") != -1){
7349
 
                        return handlers["json-comment-filtered"](xhr);
7350
 
                }else{
7351
 
                        return handlers["json"](xhr);
7352
 
                }
7353
 
        };
7354
 
 
7355
 
        /*=====
7356
 
        dojo.__IoArgs = function(){
7357
 
                //      url: String
7358
 
                //              URL to server endpoint.
7359
 
                //      content: Object?
7360
 
                //              Contains properties with string values. These
7361
 
                //              properties will be serialized as name1=value2 and
7362
 
                //              passed in the request.
7363
 
                //      timeout: Integer?
7364
 
                //              Milliseconds to wait for the response. If this time
7365
 
                //              passes, the then error callbacks are called.
7366
 
                //      form: DOMNode?
7367
 
                //              DOM node for a form. Used to extract the form values
7368
 
                //              and send to the server.
7369
 
                //      preventCache: Boolean?
7370
 
                //              Default is false. If true, then a
7371
 
                //              "dojo.preventCache" parameter is sent in the request
7372
 
                //              with a value that changes with each request
7373
 
                //              (timestamp). Useful only with GET-type requests.
7374
 
                //      handleAs: String?
7375
 
                //              Acceptable values depend on the type of IO
7376
 
                //              transport (see specific IO calls for more information).
7377
 
                //      load: Function?
7378
 
                //              function(response, ioArgs){} response is of type Object, ioArgs
7379
 
                //              is of type dojo.__IoCallbackArgs.  This function will be
7380
 
                //              called on a successful HTTP response code.
7381
 
                //      error: Function?
7382
 
                //              function(response, ioArgs){} response is of type Object, ioArgs
7383
 
                //              is of type dojo.__IoCallbackArgs. This function will
7384
 
                //              be called when the request fails due to a network or server error, the url
7385
 
                //              is invalid, etc. It will also be called if the load or handle callback throws an
7386
 
                //              exception, unless djConfig.isDebug is true.  This allows deployed applications
7387
 
                //              to continue to run even when a logic error happens in the callback, while making
7388
 
                //              it easier to troubleshoot while in debug mode.
7389
 
                //      handle: Function?
7390
 
                //              function(response, ioArgs){} response is of type Object, ioArgs
7391
 
                //              is of type dojo.__IoCallbackArgs.  This function will
7392
 
                //              be called at the end of every request, whether or not an error occurs.
7393
 
                this.url = url;
7394
 
                this.content = content;
7395
 
                this.timeout = timeout;
7396
 
                this.form = form;
7397
 
                this.preventCache = preventCache;
7398
 
                this.handleAs = handleAs;
7399
 
                this.load = load;
7400
 
                this.error = error;
7401
 
                this.handle = handle;
7402
 
        }
7403
 
        =====*/
7404
 
 
7405
 
        /*=====
7406
 
        dojo.__IoCallbackArgs = function(args, xhr, url, query, handleAs, id, canDelete, json){
7407
 
                //      args: Object
7408
 
                //              the original object argument to the IO call.
7409
 
                //      xhr: XMLHttpRequest
7410
 
                //              For XMLHttpRequest calls only, the
7411
 
                //              XMLHttpRequest object that was used for the
7412
 
                //              request.
7413
 
                //      url: String
7414
 
                //              The final URL used for the call. Many times it
7415
 
                //              will be different than the original args.url
7416
 
                //              value.
7417
 
                //      query: String
7418
 
                //              For non-GET requests, the
7419
 
                //              name1=value1&name2=value2 parameters sent up in
7420
 
                //              the request.
7421
 
                //      handleAs: String
7422
 
                //              The final indicator on how the response will be
7423
 
                //              handled.
7424
 
                //      id: String
7425
 
                //              For dojo.io.script calls only, the internal
7426
 
                //              script ID used for the request.
7427
 
                //      canDelete: Boolean
7428
 
                //              For dojo.io.script calls only, indicates
7429
 
                //              whether the script tag that represents the
7430
 
                //              request can be deleted after callbacks have
7431
 
                //              been called. Used internally to know when
7432
 
                //              cleanup can happen on JSONP-type requests.
7433
 
                //      json: Object
7434
 
                //              For dojo.io.script calls only: holds the JSON
7435
 
                //              response for JSONP-type requests. Used
7436
 
                //              internally to hold on to the JSON responses.
7437
 
                //              You should not need to access it directly --
7438
 
                //              the same object should be passed to the success
7439
 
                //              callbacks directly.
7440
 
                this.args = args;
7441
 
                this.xhr = xhr;
7442
 
                this.url = url;
7443
 
                this.query = query;
7444
 
                this.handleAs = handleAs;
7445
 
                this.id = id;
7446
 
                this.canDelete = canDelete;
7447
 
                this.json = json;
7448
 
        }
7449
 
        =====*/
7450
 
 
7451
 
 
7452
 
 
7453
 
        dojo._ioSetArgs = function(/*dojo.__IoArgs*/args,
7454
 
                        /*Function*/canceller,
7455
 
                        /*Function*/okHandler,
7456
 
                        /*Function*/errHandler){
7457
 
                //      summary: 
7458
 
                //              sets up the Deferred and ioArgs property on the Deferred so it
7459
 
                //              can be used in an io call.
7460
 
                //      args:
7461
 
                //              The args object passed into the public io call. Recognized properties on
7462
 
                //              the args object are:
7463
 
                //      canceller:
7464
 
                //              The canceller function used for the Deferred object. The function
7465
 
                //              will receive one argument, the Deferred object that is related to the
7466
 
                //              canceller.
7467
 
                //      okHandler:
7468
 
                //              The first OK callback to be registered with Deferred. It has the opportunity
7469
 
                //              to transform the OK response. It will receive one argument -- the Deferred
7470
 
                //              object returned from this function.
7471
 
                //      errHandler:
7472
 
                //              The first error callback to be registered with Deferred. It has the opportunity
7473
 
                //              to do cleanup on an error. It will receive two arguments: error (the 
7474
 
                //              Error object) and dfd, the Deferred object returned from this function.
7475
 
 
7476
 
                var ioArgs = {args: args, url: args.url};
7477
 
 
7478
 
                //Get values from form if requestd.
7479
 
                var formObject = null;
7480
 
                if(args.form){ 
7481
 
                        var form = _d.byId(args.form);
7482
 
                        //IE requires going through getAttributeNode instead of just getAttribute in some form cases, 
7483
 
                        //so use it for all.  See #2844
7484
 
                        var actnNode = form.getAttributeNode("action");
7485
 
                        ioArgs.url = ioArgs.url || (actnNode ? actnNode.value : null); 
7486
 
                        formObject = _d.formToObject(form);
7487
 
                }
7488
 
 
7489
 
                // set up the query params
7490
 
                var miArgs = [{}];
7491
 
        
7492
 
                if(formObject){
7493
 
                        // potentially over-ride url-provided params w/ form values
7494
 
                        miArgs.push(formObject);
7495
 
                }
7496
 
                if(args.content){
7497
 
                        // stuff in content over-rides what's set by form
7498
 
                        miArgs.push(args.content);
7499
 
                }
7500
 
                if(args.preventCache){
7501
 
                        miArgs.push({"dojo.preventCache": new Date().valueOf()});
7502
 
                }
7503
 
                ioArgs.query = _d.objectToQuery(_d.mixin.apply(null, miArgs));
7504
 
        
7505
 
                // .. and the real work of getting the deferred in order, etc.
7506
 
                ioArgs.handleAs = args.handleAs || "text";
7507
 
                var d = new _d.Deferred(canceller);
7508
 
                d.addCallbacks(okHandler, function(error){
7509
 
                        return errHandler(error, d);
7510
 
                });
7511
 
 
7512
 
                //Support specifying load, error and handle callback functions from the args.
7513
 
                //For those callbacks, the "this" object will be the args object.
7514
 
                //The callbacks will get the deferred result value as the
7515
 
                //first argument and the ioArgs object as the second argument.
7516
 
                var ld = args.load;
7517
 
                if(ld && _d.isFunction(ld)){
7518
 
                        d.addCallback(function(value){
7519
 
                                return ld.call(args, value, ioArgs);
7520
 
                        });
7521
 
                }
7522
 
                var err = args.error;
7523
 
                if(err && _d.isFunction(err)){
7524
 
                        d.addErrback(function(value){
7525
 
                                return err.call(args, value, ioArgs);
7526
 
                        });
7527
 
                }
7528
 
                var handle = args.handle;
7529
 
                if(handle && _d.isFunction(handle)){
7530
 
                        d.addBoth(function(value){
7531
 
                                return handle.call(args, value, ioArgs);
7532
 
                        });
7533
 
                }
7534
 
                
7535
 
                d.ioArgs = ioArgs;
7536
 
        
7537
 
                // FIXME: need to wire up the xhr object's abort method to something
7538
 
                // analagous in the Deferred
7539
 
                return d;
7540
 
        }
7541
 
 
7542
 
        var _deferredCancel = function(/*Deferred*/dfd){
7543
 
                //summary: canceller function for dojo._ioSetArgs call.
7544
 
                
7545
 
                dfd.canceled = true;
7546
 
                var xhr = dfd.ioArgs.xhr;
7547
 
                var _at = typeof xhr.abort;
7548
 
                if(_at == "function" || _at == "object" || _at == "unknown"){
7549
 
                        xhr.abort();
7550
 
                }
7551
 
                var err = dfd.ioArgs.error;
7552
 
                if(!err){
7553
 
                        err = new Error("xhr cancelled");
7554
 
                        err.dojoType="cancel";
7555
 
                }
7556
 
                return err;
7557
 
        }
7558
 
        var _deferredOk = function(/*Deferred*/dfd){
7559
 
                //summary: okHandler function for dojo._ioSetArgs call.
7560
 
 
7561
 
                var ret = _d._contentHandlers[dfd.ioArgs.handleAs](dfd.ioArgs.xhr);
7562
 
                return (typeof ret == "undefined") ? null : ret;
7563
 
        }
7564
 
        var _deferError = function(/*Error*/error, /*Deferred*/dfd){
7565
 
                //summary: errHandler function for dojo._ioSetArgs call.
7566
 
 
7567
 
                
7568
 
                return error;
7569
 
        }
7570
 
 
7571
 
        // avoid setting a timer per request. It degrades performance on IE
7572
 
        // something fierece if we don't use unified loops.
7573
 
        var _inFlightIntvl = null;
7574
 
        var _inFlight = [];
7575
 
        var _watchInFlight = function(){
7576
 
                //summary: 
7577
 
                //              internal method that checks each inflight XMLHttpRequest to see
7578
 
                //              if it has completed or if the timeout situation applies.
7579
 
                
7580
 
                var now = (new Date()).getTime();
7581
 
                // make sure sync calls stay thread safe, if this callback is called
7582
 
                // during a sync call and this results in another sync call before the
7583
 
                // first sync call ends the browser hangs
7584
 
                if(!_d._blockAsync){
7585
 
                        // we need manual loop because we often modify _inFlight (and therefore 'i') while iterating
7586
 
                        // note: the second clause is an assigment on purpose, lint may complain
7587
 
                        for(var i = 0, tif; i < _inFlight.length && (tif = _inFlight[i]); i++){
7588
 
                                var dfd = tif.dfd;
7589
 
                                var func = function(){
7590
 
                                        if(!dfd || dfd.canceled || !tif.validCheck(dfd)){
7591
 
                                                _inFlight.splice(i--, 1); 
7592
 
                                        }else if(tif.ioCheck(dfd)){
7593
 
                                                _inFlight.splice(i--, 1);
7594
 
                                                tif.resHandle(dfd);
7595
 
                                        }else if(dfd.startTime){
7596
 
                                                //did we timeout?
7597
 
                                                if(dfd.startTime + (dfd.ioArgs.args.timeout || 0) < now){
7598
 
                                                        _inFlight.splice(i--, 1);
7599
 
                                                        var err = new Error("timeout exceeded");
7600
 
                                                        err.dojoType = "timeout";
7601
 
                                                        dfd.errback(err);
7602
 
                                                        //Cancel the request so the io module can do appropriate cleanup.
7603
 
                                                        dfd.cancel();
7604
 
                                                }
7605
 
                                        }
7606
 
                                };
7607
 
                                if(dojo.config.isDebug){
7608
 
                                        func.call(this);
7609
 
                                }else{
7610
 
                                        try{
7611
 
                                                func.call(this);
7612
 
                                        }catch(e){
7613
 
                                                dfd.errback(e);
7614
 
                                        }
7615
 
                                }
7616
 
                        }
7617
 
                }
7618
 
 
7619
 
                if(!_inFlight.length){
7620
 
                        clearInterval(_inFlightIntvl);
7621
 
                        _inFlightIntvl = null;
7622
 
                        return;
7623
 
                }
7624
 
 
7625
 
        }
7626
 
 
7627
 
        dojo._ioCancelAll = function(){
7628
 
                //summary: Cancels all pending IO requests, regardless of IO type
7629
 
                //(xhr, script, iframe).
7630
 
                try{
7631
 
                        _d.forEach(_inFlight, function(i){
7632
 
                                try{
7633
 
                                        i.dfd.cancel();
7634
 
                                }catch(e){/*squelch*/}
7635
 
                        });
7636
 
                }catch(e){/*squelch*/}
7637
 
        }
7638
 
 
7639
 
        //Automatically call cancel all io calls on unload
7640
 
        //in IE for trac issue #2357.
7641
 
        if(_d.isIE){
7642
 
                _d.addOnWindowUnload(_d._ioCancelAll);
7643
 
        }
7644
 
 
7645
 
        _d._ioWatch = function(/*Deferred*/dfd,
7646
 
                /*Function*/validCheck,
7647
 
                /*Function*/ioCheck,
7648
 
                /*Function*/resHandle){
7649
 
                //summary: watches the io request represented by dfd to see if it completes.
7650
 
                //dfd:
7651
 
                //              The Deferred object to watch.
7652
 
                //validCheck:
7653
 
                //              Function used to check if the IO request is still valid. Gets the dfd
7654
 
                //              object as its only argument.
7655
 
                //ioCheck:
7656
 
                //              Function used to check if basic IO call worked. Gets the dfd
7657
 
                //              object as its only argument.
7658
 
                //resHandle:
7659
 
                //              Function used to process response. Gets the dfd
7660
 
                //              object as its only argument.
7661
 
                if(dfd.ioArgs.args.timeout){
7662
 
                        dfd.startTime = (new Date()).getTime();
7663
 
                }
7664
 
                _inFlight.push({dfd: dfd, validCheck: validCheck, ioCheck: ioCheck, resHandle: resHandle});
7665
 
                if(!_inFlightIntvl){
7666
 
                        _inFlightIntvl = setInterval(_watchInFlight, 50);
7667
 
                }
7668
 
                _watchInFlight(); // handle sync requests
7669
 
        }
7670
 
 
7671
 
        var _defaultContentType = "application/x-www-form-urlencoded";
7672
 
 
7673
 
        var _validCheck = function(/*Deferred*/dfd){
7674
 
                return dfd.ioArgs.xhr.readyState; //boolean
7675
 
        }
7676
 
        var _ioCheck = function(/*Deferred*/dfd){
7677
 
                return 4 == dfd.ioArgs.xhr.readyState; //boolean
7678
 
        }
7679
 
        var _resHandle = function(/*Deferred*/dfd){
7680
 
                var xhr = dfd.ioArgs.xhr;
7681
 
                if(_d._isDocumentOk(xhr)){
7682
 
                        dfd.callback(dfd);
7683
 
                }else{
7684
 
                        var err = new Error("Unable to load " + dfd.ioArgs.url + " status:" + xhr.status);
7685
 
                        err.status = xhr.status;
7686
 
                        err.responseText = xhr.responseText;
7687
 
                        dfd.errback(err);
7688
 
                }
7689
 
        }
7690
 
 
7691
 
        dojo._ioAddQueryToUrl = function(/*dojo.__IoCallbackArgs*/ioArgs){
7692
 
                //summary: Adds query params discovered by the io deferred construction to the URL.
7693
 
                //Only use this for operations which are fundamentally GET-type operations.
7694
 
                if(ioArgs.query.length){
7695
 
                        ioArgs.url += (ioArgs.url.indexOf("?") == -1 ? "?" : "&") + ioArgs.query;
7696
 
                        ioArgs.query = null;
7697
 
                }               
7698
 
        }
7699
 
 
7700
 
        /*=====
7701
 
        dojo.declare("dojo.__XhrArgs", dojo.__IoArgs, {
7702
 
                constructor: function(){
7703
 
                        //      summary:
7704
 
                        //              In addition to the properties listed for the dojo._IoArgs type,
7705
 
                        //              the following properties are allowed for dojo.xhr* methods.
7706
 
                        //      handleAs: String?
7707
 
                        //              Acceptable values are: text (default), json, json-comment-optional,
7708
 
                        //              json-comment-filtered, javascript, xml
7709
 
                        //      sync: Boolean?
7710
 
                        //              false is default. Indicates whether the request should
7711
 
                        //              be a synchronous (blocking) request.
7712
 
                        //      headers: Object?
7713
 
                        //              Additional HTTP headers to send in the request.
7714
 
                        this.handleAs = handleAs;
7715
 
                        this.sync = sync;
7716
 
                        this.headers = headers;
7717
 
                }
7718
 
        });
7719
 
        =====*/
7720
 
 
7721
 
        dojo.xhr = function(/*String*/ method, /*dojo.__XhrArgs*/ args, /*Boolean?*/ hasBody){
7722
 
                //      summary:
7723
 
                //              Sends an HTTP request with the given method.
7724
 
                //      description:
7725
 
                //              Sends an HTTP request with the given method.
7726
 
                //              See also dojo.xhrGet(), xhrPost(), xhrPut() and dojo.xhrDelete() for shortcuts
7727
 
                //              for those HTTP methods. There are also methods for "raw" PUT and POST methods
7728
 
                //              via dojo.rawXhrPut() and dojo.rawXhrPost() respectively.
7729
 
                //      method:
7730
 
                //              HTTP method to be used, such as GET, POST, PUT, DELETE.  Should be uppercase.
7731
 
                //      hasBody:
7732
 
                //              If the request has an HTTP body, then pass true for hasBody.
7733
 
 
7734
 
                //Make the Deferred object for this xhr request.
7735
 
                var dfd = _d._ioSetArgs(args, _deferredCancel, _deferredOk, _deferError);
7736
 
 
7737
 
                //Pass the args to _xhrObj, to allow xhr iframe proxy interceptions.
7738
 
                dfd.ioArgs.xhr = _d._xhrObj(dfd.ioArgs.args);
7739
 
 
7740
 
                if(hasBody){
7741
 
                        if("postData" in args){
7742
 
                                dfd.ioArgs.query = args.postData;
7743
 
                        }else if("putData" in args){
7744
 
                                dfd.ioArgs.query = args.putData;
7745
 
                        }
7746
 
                }else{
7747
 
                        _d._ioAddQueryToUrl(dfd.ioArgs);
7748
 
                }
7749
 
 
7750
 
                // IE 6 is a steaming pile. It won't let you call apply() on the native function (xhr.open).
7751
 
                // workaround for IE6's apply() "issues"
7752
 
                var ioArgs = dfd.ioArgs;
7753
 
                var xhr = ioArgs.xhr;
7754
 
                xhr.open(method, ioArgs.url, args.sync !== true, args.user || undefined, args.password || undefined);
7755
 
                if(args.headers){
7756
 
                        for(var hdr in args.headers){
7757
 
                                if(hdr.toLowerCase() === "content-type" && !args.contentType){
7758
 
                                        args.contentType = args.headers[hdr];
7759
 
                                }else{
7760
 
                                        xhr.setRequestHeader(hdr, args.headers[hdr]);
7761
 
                                }
7762
 
                        }
7763
 
                }
7764
 
                // FIXME: is this appropriate for all content types?
7765
 
                xhr.setRequestHeader("Content-Type", args.contentType || _defaultContentType);
7766
 
                if(!args.headers || !args.headers["X-Requested-With"]){
7767
 
                        xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
7768
 
                }
7769
 
                // FIXME: set other headers here!
7770
 
                if(dojo.config.isDebug){
7771
 
                        xhr.send(ioArgs.query);
7772
 
                }else{
7773
 
                        try{
7774
 
                                xhr.send(ioArgs.query);
7775
 
                        }catch(e){
7776
 
                                dfd.ioArgs.error = e;
7777
 
                                dfd.cancel();
7778
 
                        }
7779
 
                }
7780
 
                _d._ioWatch(dfd, _validCheck, _ioCheck, _resHandle);
7781
 
                xhr = null;
7782
 
                return dfd; // dojo.Deferred
7783
 
        }
7784
 
 
7785
 
        dojo.xhrGet = function(/*dojo.__XhrArgs*/ args){
7786
 
                //      summary: 
7787
 
                //              Sends an HTTP GET request to the server.
7788
 
                return _d.xhr("GET", args); // dojo.Deferred
7789
 
        }
7790
 
 
7791
 
        dojo.rawXhrPost = dojo.xhrPost = function(/*dojo.__XhrArgs*/ args){
7792
 
                //      summary:
7793
 
                //              Sends an HTTP POST request to the server. In addtion to the properties
7794
 
                //              listed for the dojo.__XhrArgs type, the following property is allowed:
7795
 
                //      postData:
7796
 
                //              String. Send raw data in the body of the POST request.
7797
 
                return _d.xhr("POST", args, true); // dojo.Deferred
7798
 
        }
7799
 
 
7800
 
        dojo.rawXhrPut = dojo.xhrPut = function(/*dojo.__XhrArgs*/ args){
7801
 
                //      summary:
7802
 
                //              Sends an HTTP PUT request to the server. In addtion to the properties
7803
 
                //              listed for the dojo.__XhrArgs type, the following property is allowed:
7804
 
                //      putData:
7805
 
                //              String. Send raw data in the body of the PUT request.
7806
 
                return _d.xhr("PUT", args, true); // dojo.Deferred
7807
 
        }
7808
 
 
7809
 
        dojo.xhrDelete = function(/*dojo.__XhrArgs*/ args){
7810
 
                //      summary:
7811
 
                //              Sends an HTTP DELETE request to the server.
7812
 
                return _d.xhr("DELETE", args); //dojo.Deferred
7813
 
        }
7814
 
 
7815
 
        /*
7816
 
        dojo.wrapForm = function(formNode){
7817
 
                //summary:
7818
 
                //              A replacement for FormBind, but not implemented yet.
7819
 
 
7820
 
                // FIXME: need to think harder about what extensions to this we might
7821
 
                // want. What should we allow folks to do w/ this? What events to
7822
 
                // set/send?
7823
 
                throw new Error("dojo.wrapForm not yet implemented");
7824
 
        }
7825
 
        */
7826
 
})();
7827
 
 
7828
 
}
7829
 
 
7830
 
if(!dojo._hasResource["dojo._base.fx"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
7831
 
dojo._hasResource["dojo._base.fx"] = true;
7832
 
dojo.provide("dojo._base.fx");
7833
 
 
7834
 
 
7835
 
 
7836
 
 
7837
 
 
7838
 
 
7839
 
/*
7840
 
        Animation losely package based on Dan Pupius' work, contributed under CLA: 
7841
 
                http://pupius.co.uk/js/Toolkit.Drawing.js
7842
 
*/
7843
 
(function(){ 
7844
 
 
7845
 
        var d = dojo;
7846
 
        
7847
 
        dojo._Line = function(/*int*/ start, /*int*/ end){
7848
 
                //      summary:
7849
 
                //              dojo._Line is the object used to generate values from a start value
7850
 
                //              to an end value
7851
 
                //      start: int
7852
 
                //              Beginning value for range
7853
 
                //      end: int
7854
 
                //              Ending value for range
7855
 
                this.start = start;
7856
 
                this.end = end;
7857
 
                this.getValue = function(/*float*/ n){
7858
 
                        //      summary: returns the point on the line
7859
 
                        //      n: a floating point number greater than 0 and less than 1
7860
 
                        return ((this.end - this.start) * n) + this.start; // Decimal
7861
 
                }
7862
 
        }
7863
 
        
7864
 
        d.declare("dojo._Animation", null, {
7865
 
                //      summary
7866
 
                //              A generic animation class that fires callbacks into its handlers
7867
 
                //              object at various states. Nearly all dojo animation functions
7868
 
                //              return an instance of this method, usually without calling the
7869
 
                //              .play() method beforehand. Therefore, you will likely need to
7870
 
                //              call .play() on instances of dojo._Animation when one is
7871
 
                //              returned.
7872
 
                constructor: function(/*Object*/ args){
7873
 
                        d.mixin(this, args);
7874
 
                        if(d.isArray(this.curve)){
7875
 
                                /* curve: Array
7876
 
                                        pId: a */
7877
 
                                this.curve = new d._Line(this.curve[0], this.curve[1]);
7878
 
                        }
7879
 
                },
7880
 
                
7881
 
                // duration: Integer
7882
 
                //      The time in milliseonds the animation will take to run
7883
 
                duration: 350,
7884
 
        
7885
 
        /*=====
7886
 
                // curve: dojo._Line||Array
7887
 
                //      A two element array of start and end values, or a dojo._Line instance to be
7888
 
                //      used in the Animation. 
7889
 
                curve: null,
7890
 
        
7891
 
                // easing: Function
7892
 
                //      A Function to adjust the acceleration (or deceleration) of the progress 
7893
 
                //      across a dojo._Line
7894
 
                easing: null,
7895
 
        =====*/
7896
 
        
7897
 
                // repeat: Integer
7898
 
                //      The number of times to loop the animation
7899
 
                repeat: 0,
7900
 
        
7901
 
                // rate: Integer
7902
 
                //      the time in milliseconds to wait before advancing to next frame 
7903
 
                //      (used as a fps timer: rate/1000 = fps)
7904
 
                rate: 10 /* 100 fps */,
7905
 
        
7906
 
        /*===== 
7907
 
                // delay: Integer
7908
 
                //      The time in milliseconds to wait before starting animation after it has been .play()'ed
7909
 
                delay: null,
7910
 
        
7911
 
                // events
7912
 
                //
7913
 
                // beforeBegin: Event
7914
 
                //      Synthetic event fired before a dojo._Animation begins playing (synchronous)
7915
 
                beforeBegin: null,
7916
 
        
7917
 
                // onBegin: Event
7918
 
                //      Synthetic event fired as a dojo._Animation begins playing (useful?)
7919
 
                onBegin: null,
7920
 
        
7921
 
                // onAnimate: Event
7922
 
                //      Synthetic event fired at each interval of a dojo._Animation
7923
 
                onAnimate: null,
7924
 
        
7925
 
                // onEnd: Event
7926
 
                //      Synthetic event fired after the final frame of a dojo._Animation
7927
 
                onEnd: null,
7928
 
        
7929
 
                // onPlay: Event
7930
 
                //      Synthetic event fired any time a dojo._Animation is play()'ed
7931
 
                onPlay: null,
7932
 
        
7933
 
                // onPause: Event
7934
 
                //      Synthetic event fired when a dojo._Animation is paused
7935
 
                onPause: null,
7936
 
        
7937
 
                // onStop: Event
7938
 
                //      Synthetic event fires when a dojo._Animation is stopped
7939
 
                onStop: null,
7940
 
        
7941
 
        =====*/
7942
 
        
7943
 
                _percent: 0,
7944
 
                _startRepeatCount: 0,
7945
 
        
7946
 
                _fire: function(/*Event*/ evt, /*Array?*/ args){
7947
 
                        //      summary:
7948
 
                        //              Convenience function.  Fire event "evt" and pass it the
7949
 
                        //              arguments specified in "args".
7950
 
                        //      evt:
7951
 
                        //              The event to fire.
7952
 
                        //      args:
7953
 
                        //              The arguments to pass to the event.
7954
 
                        if(this[evt]){
7955
 
                                if(dojo.config.isDebug){
7956
 
                                        this[evt].apply(this, args||[]);
7957
 
                                }else{
7958
 
                                        try{
7959
 
                                                this[evt].apply(this, args||[]);
7960
 
                                        }catch(e){
7961
 
                                                // squelch and log because we shouldn't allow exceptions in
7962
 
                                                // synthetic event handlers to cause the internal timer to run
7963
 
                                                // amuck, potentially pegging the CPU. I'm not a fan of this
7964
 
                                                // squelch, but hopefully logging will make it clear what's
7965
 
                                                // going on
7966
 
                                                console.error("exception in animation handler for:", evt);
7967
 
                                                console.error(e);
7968
 
                                        }
7969
 
                                }
7970
 
                        }
7971
 
                        return this; // dojo._Animation
7972
 
                },
7973
 
 
7974
 
                play: function(/*int?*/ delay, /*Boolean?*/ gotoStart){
7975
 
                        // summary:
7976
 
                        //              Start the animation.
7977
 
                        // delay:
7978
 
                        //              How many milliseconds to delay before starting.
7979
 
                        // gotoStart:
7980
 
                        //              If true, starts the animation from the beginning; otherwise,
7981
 
                        //              starts it from its current position.
7982
 
                        var _t = this;
7983
 
                        if(gotoStart){
7984
 
                                _t._stopTimer();
7985
 
                                _t._active = _t._paused = false;
7986
 
                                _t._percent = 0;
7987
 
                        }else if(_t._active && !_t._paused){
7988
 
                                return _t; // dojo._Animation
7989
 
                        }
7990
 
        
7991
 
                        _t._fire("beforeBegin");
7992
 
        
7993
 
                        var de = delay||_t.delay;
7994
 
                        var _p = dojo.hitch(_t, "_play", gotoStart);
7995
 
                        if(de > 0){
7996
 
                                setTimeout(_p, de);
7997
 
                                return _t; // dojo._Animation
7998
 
                        }
7999
 
                        _p();
8000
 
                        return _t;
8001
 
                },
8002
 
        
8003
 
                _play: function(gotoStart){
8004
 
                        var _t = this;
8005
 
                        _t._startTime = new Date().valueOf();
8006
 
                        if(_t._paused){
8007
 
                                _t._startTime -= _t.duration * _t._percent;
8008
 
                        }
8009
 
                        _t._endTime = _t._startTime + _t.duration;
8010
 
        
8011
 
                        _t._active = true;
8012
 
                        _t._paused = false;
8013
 
        
8014
 
                        var value = _t.curve.getValue(_t._percent);
8015
 
                        if(!_t._percent){
8016
 
                                if(!_t._startRepeatCount){
8017
 
                                        _t._startRepeatCount = _t.repeat;
8018
 
                                }
8019
 
                                _t._fire("onBegin", [value]);
8020
 
                        }
8021
 
        
8022
 
                        _t._fire("onPlay", [value]);
8023
 
        
8024
 
                        _t._cycle();
8025
 
                        return _t; // dojo._Animation
8026
 
                },
8027
 
        
8028
 
                pause: function(){
8029
 
                        // summary: Pauses a running animation.
8030
 
                        this._stopTimer();
8031
 
                        if(!this._active){ return this; /*dojo._Animation*/ }
8032
 
                        this._paused = true;
8033
 
                        this._fire("onPause", [this.curve.getValue(this._percent)]);
8034
 
                        return this; // dojo._Animation
8035
 
                },
8036
 
        
8037
 
                gotoPercent: function(/*Decimal*/ percent, /*Boolean?*/ andPlay){
8038
 
                        //      summary:
8039
 
                        //              Sets the progress of the animation.
8040
 
                        //      percent:
8041
 
                        //              A percentage in decimal notation (between and including 0.0 and 1.0).
8042
 
                        //      andPlay:
8043
 
                        //              If true, play the animation after setting the progress.
8044
 
                        this._stopTimer();
8045
 
                        this._active = this._paused = true;
8046
 
                        this._percent = percent;
8047
 
                        if(andPlay){ this.play(); }
8048
 
                        return this; // dojo._Animation
8049
 
                },
8050
 
        
8051
 
                stop: function(/*boolean?*/ gotoEnd){
8052
 
                        // summary: Stops a running animation.
8053
 
                        // gotoEnd: If true, the animation will end.
8054
 
                        if(!this._timer){ return this; /* dojo._Animation */ }
8055
 
                        this._stopTimer();
8056
 
                        if(gotoEnd){
8057
 
                                this._percent = 1;
8058
 
                        }
8059
 
                        this._fire("onStop", [this.curve.getValue(this._percent)]);
8060
 
                        this._active = this._paused = false;
8061
 
                        return this; // dojo._Animation
8062
 
                },
8063
 
        
8064
 
                status: function(){
8065
 
                        // summary: Returns a string token representation of the status of
8066
 
                        //                      the animation, one of: "paused", "playing", "stopped"
8067
 
                        if(this._active){
8068
 
                                return this._paused ? "paused" : "playing"; // String
8069
 
                        }
8070
 
                        return "stopped"; // String
8071
 
                },
8072
 
        
8073
 
                _cycle: function(){
8074
 
                        var _t = this;
8075
 
                        if(_t._active){
8076
 
                                var curr = new Date().valueOf();
8077
 
                                var step = (curr - _t._startTime) / (_t._endTime - _t._startTime);
8078
 
        
8079
 
                                if(step >= 1){
8080
 
                                        step = 1;
8081
 
                                }
8082
 
                                _t._percent = step;
8083
 
        
8084
 
                                // Perform easing
8085
 
                                if(_t.easing){
8086
 
                                        step = _t.easing(step);
8087
 
                                }
8088
 
        
8089
 
                                _t._fire("onAnimate", [_t.curve.getValue(step)]);
8090
 
        
8091
 
                                if(_t._percent < 1){
8092
 
                                        _t._startTimer();
8093
 
                                }else{
8094
 
                                        _t._active = false;
8095
 
        
8096
 
                                        if(_t.repeat > 0){
8097
 
                                                _t.repeat--;
8098
 
                                                _t.play(null, true);
8099
 
                                        }else if(_t.repeat == -1){
8100
 
                                                _t.play(null, true);
8101
 
                                        }else{
8102
 
                                                if(_t._startRepeatCount){
8103
 
                                                        _t.repeat = _t._startRepeatCount;
8104
 
                                                        _t._startRepeatCount = 0;
8105
 
                                                }
8106
 
                                        }
8107
 
                                        _t._percent = 0;
8108
 
                                        _t._fire("onEnd");
8109
 
                                        _t._stopTimer();
8110
 
                                }
8111
 
                        }
8112
 
                        return _t; // dojo._Animation
8113
 
                }
8114
 
        });
8115
 
 
8116
 
        var ctr = 0;
8117
 
        var _globalTimerList = [];
8118
 
        var runner = {
8119
 
                run: function(){ }
8120
 
        };
8121
 
        var timer = null;
8122
 
        dojo._Animation.prototype._startTimer = function(){
8123
 
                // this._timer = setTimeout(dojo.hitch(this, "_cycle"), this.rate);
8124
 
                if(!this._timer){
8125
 
                        this._timer = d.connect(runner, "run", this, "_cycle");
8126
 
                        ctr++;
8127
 
                }
8128
 
                if(!timer){
8129
 
                        timer = setInterval(d.hitch(runner, "run"), this.rate);
8130
 
                }
8131
 
        };
8132
 
 
8133
 
        dojo._Animation.prototype._stopTimer = function(){
8134
 
                if(this._timer){
8135
 
                        d.disconnect(this._timer);
8136
 
                        this._timer = null;
8137
 
                        ctr--;
8138
 
                }
8139
 
                if(ctr <= 0){
8140
 
                        clearInterval(timer);
8141
 
                        timer = null;
8142
 
                        ctr = 0;
8143
 
                }
8144
 
        };
8145
 
 
8146
 
        var _makeFadeable = (d.isIE) ? function(node){
8147
 
                // only set the zoom if the "tickle" value would be the same as the
8148
 
                // default
8149
 
                var ns = node.style;
8150
 
                // don't set the width to auto if it didn't already cascade that way.
8151
 
                // We don't want to f anyones designs
8152
 
                if(!ns.width.length && d.style(node, "width") == "auto"){
8153
 
                        ns.width = "auto";
8154
 
                }
8155
 
        } : function(){};
8156
 
 
8157
 
        dojo._fade = function(/*Object*/ args){
8158
 
                //      summary: 
8159
 
                //              Returns an animation that will fade the node defined by
8160
 
                //              args.node from the start to end values passed (args.start
8161
 
                //              args.end) (end is mandatory, start is optional)
8162
 
 
8163
 
                args.node = d.byId(args.node);
8164
 
                var fArgs = d.mixin({ properties: {} }, args);
8165
 
                var props = (fArgs.properties.opacity = {});
8166
 
                props.start = !("start" in fArgs) ?
8167
 
                        function(){ 
8168
 
                                return Number(d.style(fArgs.node, "opacity")); 
8169
 
                        } : fArgs.start;
8170
 
                props.end = fArgs.end;
8171
 
 
8172
 
                var anim = d.animateProperty(fArgs);
8173
 
                d.connect(anim, "beforeBegin", d.partial(_makeFadeable, fArgs.node));
8174
 
 
8175
 
                return anim; // dojo._Animation
8176
 
        }
8177
 
 
8178
 
        /*=====
8179
 
        dojo.__FadeArgs = function(node, duration, easing){
8180
 
                //      node: DOMNode|String
8181
 
                //              The node referenced in the animation
8182
 
                //      duration: Integer?
8183
 
                //              Duration of the animation in milliseconds.
8184
 
                //      easing: Function?
8185
 
                //              An easing function.
8186
 
                this.node = node;
8187
 
                this.duration = duration;
8188
 
                this.easing = easing;
8189
 
        }
8190
 
        =====*/
8191
 
 
8192
 
        dojo.fadeIn = function(/*dojo.__FadeArgs*/ args){
8193
 
                // summary: 
8194
 
                //              Returns an animation that will fade node defined in 'args' from
8195
 
                //              its current opacity to fully opaque.
8196
 
                return d._fade(d.mixin({ end: 1 }, args)); // dojo._Animation
8197
 
        }
8198
 
 
8199
 
        dojo.fadeOut = function(/*dojo.__FadeArgs*/  args){
8200
 
                // summary: 
8201
 
                //              Returns an animation that will fade node defined in 'args'
8202
 
                //              from its current opacity to fully transparent.
8203
 
                return d._fade(d.mixin({ end: 0 }, args)); // dojo._Animation
8204
 
        }
8205
 
 
8206
 
        dojo._defaultEasing = function(/*Decimal?*/ n){
8207
 
                // summary: The default easing function for dojo._Animation(s)
8208
 
                return 0.5 + ((Math.sin((n + 1.5) * Math.PI))/2);
8209
 
        }
8210
 
 
8211
 
        var PropLine = function(properties){
8212
 
                // PropLine is an internal class which is used to model the values of
8213
 
                // an a group of CSS properties across an animation lifecycle. In
8214
 
                // particular, the "getValue" function handles getting interpolated
8215
 
                // values between start and end for a particular CSS value.
8216
 
                this._properties = properties;
8217
 
                for(var p in properties){
8218
 
                        var prop = properties[p];
8219
 
                        if(prop.start instanceof d.Color){
8220
 
                                // create a reusable temp color object to keep intermediate results
8221
 
                                prop.tempColor = new d.Color();
8222
 
                        }
8223
 
                }
8224
 
                this.getValue = function(r){
8225
 
                        var ret = {};
8226
 
                        for(var p in this._properties){
8227
 
                                var prop = this._properties[p];
8228
 
                                var start = prop.start;
8229
 
                                if(start instanceof d.Color){
8230
 
                                        ret[p] = d.blendColors(start, prop.end, r, prop.tempColor).toCss();
8231
 
                                }else if(!d.isArray(start)){
8232
 
                                        ret[p] = ((prop.end - start) * r) + start + (p != "opacity" ? prop.units||"px" : "");
8233
 
                                }
8234
 
                        }
8235
 
                        return ret;
8236
 
                }
8237
 
        }
8238
 
 
8239
 
        /*=====
8240
 
        dojo.declare("dojo.__AnimArgs", [dojo.__FadeArgs], {
8241
 
                // Properties: Object?
8242
 
                //      A hash map of style properties to Objects describing the transition,
8243
 
                //      such as the properties of dojo._Line with an additional 'unit' property
8244
 
                properties: {}
8245
 
                
8246
 
                //TODOC: add event callbacks
8247
 
        });
8248
 
        =====*/
8249
 
 
8250
 
        dojo.animateProperty = function(/*dojo.__AnimArgs*/ args){
8251
 
                //      summary: 
8252
 
                //              Returns an animation that will transition the properties of
8253
 
                //              node defined in 'args' depending how they are defined in
8254
 
                //              'args.properties'
8255
 
                //
8256
 
                // description:
8257
 
                //              dojo.animateProperty is the foundation of most dojo.fx
8258
 
                //              animations. It takes an object of "properties" corresponding to
8259
 
                //              style properties, and animates them in parallel over a set
8260
 
                //              duration.
8261
 
                //      
8262
 
                //      example:
8263
 
                //              A simple animation that changes the width of the specified node.
8264
 
                //      |       dojo.animateProperty({ 
8265
 
                //      |               node: "nodeId",
8266
 
                //      |               properties: { width: 400 },
8267
 
                //      |       }).play();
8268
 
                //              Dojo figures out the start value for the width and converts the
8269
 
                //              integer specified for the width to the more expressive but
8270
 
                //              verbose form `{ width: { end: '400', units: 'px' } }` which you
8271
 
                //              can also specify directly
8272
 
                //
8273
 
                //      example:
8274
 
                //              Animate width, height, and padding over 2 seconds... the
8275
 
                //              pedantic way:
8276
 
                //      |       dojo.animateProperty({ node: node, duration:2000,
8277
 
                //      |               properties: {
8278
 
                //      |                       width: { start: '200', end: '400', unit:"px" },
8279
 
                //      |                       height: { start:'200', end: '400', unit:"px" },
8280
 
                //      |                       paddingTop: { start:'5', end:'50', unit:"px" } 
8281
 
                //      |               }
8282
 
                //      |       }).play();
8283
 
                //              Note 'paddingTop' is used over 'padding-top'. Multi-name CSS properties
8284
 
                //              are written using "mixed case", as the hyphen is illegal as an object key.
8285
 
                //              
8286
 
                //      example:
8287
 
                //              Plug in a different easing function and register a callback for
8288
 
                //              when the animation ends. Easing functions accept values between
8289
 
                //              zero and one and return a value on that basis. In this case, an
8290
 
                //              exponential-in curve.
8291
 
                //      |       dojo.animateProperty({ 
8292
 
                //      |               node: "nodeId",
8293
 
                //      |               // dojo figures out the start value
8294
 
                //      |               properties: { width: { end: 400 } },
8295
 
                //      |               easing: function(n){
8296
 
                //      |                       return (n==0) ? 0 : Math.pow(2, 10 * (n - 1));
8297
 
                //      |               },
8298
 
                //      |               onEnd: function(){
8299
 
                //      |                       // called when the animation finishes
8300
 
                //      |               }
8301
 
                //      |       }).play(500); // delay playing half a second
8302
 
                //
8303
 
                //      example:
8304
 
                //              Like all `dojo._Animation`s, animateProperty returns a handle to the
8305
 
                //              Animation instance, which fires the events common to Dojo FX. Use `dojo.connect`
8306
 
                //              to access these events outside of the Animation definiton:
8307
 
                //      |       var anim = dojo.animateProperty({
8308
 
                //      |               node:"someId",
8309
 
                //      |               properties:{
8310
 
                //      |                       width:400, height:500
8311
 
                //      |               }
8312
 
                //      |       });
8313
 
                //      |       dojo.connect(anim,"onEnd", function(){
8314
 
                //      |               
8315
 
                //      |       });
8316
 
                //      |       // play the animation now:
8317
 
                //      |       anim.play();
8318
 
                
8319
 
                args.node = d.byId(args.node);
8320
 
                if(!args.easing){ args.easing = d._defaultEasing; }
8321
 
 
8322
 
                var anim = new d._Animation(args);
8323
 
                d.connect(anim, "beforeBegin", anim, function(){
8324
 
                        var pm = {};
8325
 
                        for(var p in this.properties){
8326
 
                                // Make shallow copy of properties into pm because we overwrite
8327
 
                                // some values below. In particular if start/end are functions
8328
 
                                // we don't want to overwrite them or the functions won't be
8329
 
                                // called if the animation is reused.
8330
 
                                if(p == "width" || p == "height"){
8331
 
                                        this.node.display = "block";
8332
 
                                }
8333
 
                                var prop = this.properties[p];
8334
 
                                prop = pm[p] = d.mixin({}, (d.isObject(prop) ? prop: { end: prop }));
8335
 
 
8336
 
                                if(d.isFunction(prop.start)){
8337
 
                                        prop.start = prop.start();
8338
 
                                }
8339
 
                                if(d.isFunction(prop.end)){
8340
 
                                        prop.end = prop.end();
8341
 
                                }
8342
 
                                var isColor = (p.toLowerCase().indexOf("color") >= 0);
8343
 
                                function getStyle(node, p){
8344
 
                                        // dojo.style(node, "height") can return "auto" or "" on IE; this is more reliable:
8345
 
                                        var v = ({height: node.offsetHeight, width: node.offsetWidth})[p];
8346
 
                                        if(v !== undefined){ return v; }
8347
 
                                        v = d.style(node, p);
8348
 
                                        return (p=="opacity") ? Number(v) : (isColor ? v : parseFloat(v));
8349
 
                                }
8350
 
                                if(!("end" in prop)){
8351
 
                                        prop.end = getStyle(this.node, p);
8352
 
                                }else if(!("start" in prop)){
8353
 
                                        prop.start = getStyle(this.node, p);
8354
 
                                }
8355
 
 
8356
 
                                if(isColor){
8357
 
                                        prop.start = new d.Color(prop.start);
8358
 
                                        prop.end = new d.Color(prop.end);
8359
 
                                }else{
8360
 
                                        prop.start = (p == "opacity") ? Number(prop.start) : parseFloat(prop.start);
8361
 
                                }
8362
 
                        }
8363
 
                        this.curve = new PropLine(pm);
8364
 
                });
8365
 
                d.connect(anim, "onAnimate", d.hitch(d, "style", anim.node));
8366
 
                return anim; // dojo._Animation
8367
 
        }
8368
 
 
8369
 
        dojo.anim = function(   /*DOMNode|String*/      node, 
8370
 
                                                        /*Object*/                      properties, 
8371
 
                                                        /*Integer?*/            duration, 
8372
 
                                                        /*Function?*/           easing, 
8373
 
                                                        /*Function?*/           onEnd,
8374
 
                                                        /*Integer?*/            delay){
8375
 
                //      summary:
8376
 
                //              A simpler interface to `dojo.animateProperty()`, also returns
8377
 
                //              an instance of `dojo._Animation` but begins the animation
8378
 
                //              immediately, unlike nearly every other Dojo animation API.
8379
 
                //      description:
8380
 
                //              `dojo.anim` is a simpler (but somewhat less powerful) version
8381
 
                //              of `dojo.animateProperty`.  It uses defaults for many basic properties
8382
 
                //              and allows for positional parameters to be used in place of the
8383
 
                //              packed "property bag" which is used for other Dojo animation
8384
 
                //              methods.
8385
 
                //
8386
 
                //              The `dojo._Animation` object returned from `dojo.anim` will be
8387
 
                //              already playing when it is returned from this function, so
8388
 
                //              calling play() on it again is (usually) a no-op.
8389
 
                //      node:
8390
 
                //              a DOM node or the id of a node to animate CSS properties on
8391
 
                //      duration:
8392
 
                //              The number of milliseconds over which the animation
8393
 
                //              should run. Defaults to the global animation default duration
8394
 
                //              (350ms).
8395
 
                //      easing:
8396
 
                //              An easing function over which to calculate acceleration
8397
 
                //              and deceleration of the animation through its duration.
8398
 
                //              A default easing algorithm is provided, but you may
8399
 
                //              plug in any you wish. A large selection of easing algorithms
8400
 
                //              are available in `dojo.fx.easing`.
8401
 
                //      onEnd:
8402
 
                //              A function to be called when the animation finishes
8403
 
                //              running.
8404
 
                //      delay:
8405
 
                //              The number of milliseconds to delay beginning the
8406
 
                //              animation by. The default is 0.
8407
 
                //      example:
8408
 
                //              Fade out a node
8409
 
                //      |       dojo.anim("id", { opacity: 0 });
8410
 
                //      example:
8411
 
                //              Fade out a node over a full second
8412
 
                //      |       dojo.anim("id", { opacity: 0 }, 1000);
8413
 
                return d.animateProperty({ 
8414
 
                        node: node,
8415
 
                        duration: duration||d._Animation.prototype.duration,
8416
 
                        properties: properties,
8417
 
                        easing: easing,
8418
 
                        onEnd: onEnd 
8419
 
                }).play(delay||0);
8420
 
        }
8421
 
})();
8422
 
 
8423
 
}
8424
 
 
8425
 
if(!dojo._hasResource["dojo._base.browser"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
8426
 
dojo._hasResource["dojo._base.browser"] = true;
8427
 
dojo.provide("dojo._base.browser");
8428
 
 
8429
 
 
8430
 
 
8431
 
 
8432
 
 
8433
 
 
8434
 
 
8435
 
 
8436
 
 
8437
 
//Need this to be the last code segment in base, so do not place any
8438
 
//dojo.requireIf calls in this file. Otherwise, due to how the build system
8439
 
//puts all requireIf dependencies after the current file, the require calls
8440
 
//could be called before all of base is defined.
8441
 
if(dojo.config.require){
8442
 
        dojo.forEach(dojo.config.require, "dojo['require'](item);");
8443
 
}
8444
 
 
8445
 
}
8446
 
 
8447
 
        //INSERT dojo.i18n._preloadLocalizations HERE
8448
 
 
8449
 
        if(dojo.config.afterOnLoad && dojo.isBrowser){
8450
 
                //Dojo is being added to the page after page load, so just trigger
8451
 
                //the init sequence after a timeout. Using a timeout so the rest of this
8452
 
                //script gets evaluated properly. This work needs to happen after the
8453
 
                //dojo.config.require work done in dojo._base.
8454
 
                window.setTimeout(dojo._fakeLoadInit, 1000);
8455
 
        }
8456
 
 
8457
 
})();
8458