]> git.wh0rd.org Git - tt-rss.git/blob - lib/dojo/dojo.js.uncompressed.js
upgrade dojo to 1.8.3 (refs #570)
[tt-rss.git] / lib / dojo / dojo.js.uncompressed.js
1 /*
2         Copyright (c) 2004-2012, 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 an optimized version of Dojo, built for deployment and not for
9         development. To get sources and documentation, please visit:
10
11                 http://dojotoolkit.org
12 */
13
14 (function(
15         userConfig,
16         defaultConfig
17 ){
18         // summary:
19         //              This is the "source loader" and is the entry point for Dojo during development. You may also load Dojo with
20         //              any AMD-compliant loader via the package main module dojo/main.
21         // description:
22         //              This is the "source loader" for Dojo. It provides an AMD-compliant loader that can be configured
23         //              to operate in either synchronous or asynchronous modes. After the loader is defined, dojo is loaded
24         //              IAW the package main module dojo/main. In the event you wish to use a foreign loader, you may load dojo as a package
25         //              via the package main module dojo/main and this loader is not required; see dojo/package.json for details.
26         //
27         //              In order to keep compatibility with the v1.x line, this loader includes additional machinery that enables
28         //              the dojo.provide, dojo.require et al API. This machinery is loaded by default, but may be dynamically removed
29         //              via the has.js API and statically removed via the build system.
30         //
31         //              This loader includes sniffing machinery to determine the environment; the following environments are supported:
32         //
33         //              - browser
34         //              - node.js
35         //              - rhino
36         //
37         //              This is the so-called "source loader". As such, it includes many optional features that may be discadred by
38         //              building a customized verion with the build system.
39
40         // Design and Implementation Notes
41         //
42         // This is a dojo-specific adaption of bdLoad, donated to the dojo foundation by Altoviso LLC.
43         //
44         // This function defines an AMD-compliant (http://wiki.commonjs.org/wiki/Modules/AsynchronousDefinition)
45         // loader that can be configured to operate in either synchronous or asynchronous modes.
46         //
47         // Since this machinery implements a loader, it does not have the luxury of using a load system and/or
48         // leveraging a utility library. This results in an unpleasantly long file; here is a road map of the contents:
49         //
50         //       1. Small library for use implementing the loader.
51         //       2. Define the has.js API; this is used throughout the loader to bracket features.
52         //       3. Define the node.js and rhino sniffs and sniff.
53         //       4. Define the loader's data.
54         //       5. Define the configuration machinery.
55         //       6. Define the script element sniffing machinery and sniff for configuration data.
56         //       7. Configure the loader IAW the provided user, default, and sniffing data.
57         //       8. Define the global require function.
58         //       9. Define the module resolution machinery.
59         //      10. Define the module and plugin module definition machinery
60         //      11. Define the script injection machinery.
61         //      12. Define the window load detection.
62         //      13. Define the logging API.
63         //      14. Define the tracing API.
64         //      16. Define the AMD define function.
65         //      17. Define the dojo v1.x provide/require machinery--so called "legacy" modes.
66         //      18. Publish global variables.
67         //
68         // Language and Acronyms and Idioms
69         //
70         // moduleId: a CJS module identifier, (used for public APIs)
71         // mid: moduleId (used internally)
72         // packageId: a package identifier (used for public APIs)
73         // pid: packageId (used internally); the implied system or default package has pid===""
74         // pack: package is used internally to reference a package object (since javascript has reserved words including "package")
75         // prid: plugin resource identifier
76         // The integer constant 1 is used in place of true and 0 in place of false.
77
78         // define a minimal library to help build the loader
79         var     noop = function(){
80                 },
81
82                 isEmpty = function(it){
83                         for(var p in it){
84                                 return 0;
85                         }
86                         return 1;
87                 },
88
89                 toString = {}.toString,
90
91                 isFunction = function(it){
92                         return toString.call(it) == "[object Function]";
93                 },
94
95                 isString = function(it){
96                         return toString.call(it) == "[object String]";
97                 },
98
99                 isArray = function(it){
100                         return toString.call(it) == "[object Array]";
101                 },
102
103                 forEach = function(vector, callback){
104                         if(vector){
105                                 for(var i = 0; i < vector.length;){
106                                         callback(vector[i++]);
107                                 }
108                         }
109                 },
110
111                 mix = function(dest, src){
112                         for(var p in src){
113                                 dest[p] = src[p];
114                         }
115                         return dest;
116                 },
117
118                 makeError = function(error, info){
119                         return mix(new Error(error), {src:"dojoLoader", info:info});
120                 },
121
122                 uidSeed = 1,
123
124                 uid = function(){
125                         // Returns a unique indentifier (within the lifetime of the document) of the form /_d+/.
126                         return "_" + uidSeed++;
127                 },
128
129                 // FIXME: how to doc window.require() api
130
131                 // this will be the global require function; define it immediately so we can start hanging things off of it
132                 req = function(
133                         config,           //(object, optional) hash of configuration properties
134                         dependencies, //(array of commonjs.moduleId, optional) list of modules to be loaded before applying callback
135                         callback          //(function, optional) lamda expression to apply to module values implied by dependencies
136                 ){
137                         return contextRequire(config, dependencies, callback, 0, req);
138                 },
139
140                 // the loader uses the has.js API to control feature inclusion/exclusion; define then use throughout
141                 global = this,
142
143                 doc = global.document,
144
145                 element = doc && doc.createElement("DiV"),
146
147                 has = req.has = function(name){
148                         return isFunction(hasCache[name]) ? (hasCache[name] = hasCache[name](global, doc, element)) : hasCache[name];
149                 },
150
151                 hasCache = has.cache = defaultConfig.hasCache;
152
153         has.add = function(name, test, now, force){
154                 (hasCache[name]===undefined || force) && (hasCache[name] = test);
155                 return now && has(name);
156         };
157
158          0 && has.add("host-node", userConfig.has && "host-node" in userConfig.has ?
159                 userConfig.has["host-node"] :
160                 (typeof process == "object" && process.versions && process.versions.node && process.versions.v8));
161         if( 0 ){
162                 // fixup the default config for node.js environment
163                 require("./_base/configNode.js").config(defaultConfig);
164                 // remember node's require (with respect to baseUrl==dojo's root)
165                 defaultConfig.loaderPatch.nodeRequire = require;
166         }
167
168          0 && has.add("host-rhino", userConfig.has && "host-rhino" in userConfig.has ?
169                 userConfig.has["host-rhino"] :
170                 (typeof load == "function" && (typeof Packages == "function" || typeof Packages == "object")));
171         if( 0 ){
172                 // owing to rhino's lame feature that hides the source of the script, give the user a way to specify the baseUrl...
173                 for(var baseUrl = userConfig.baseUrl || ".", arg, rhinoArgs = this.arguments, i = 0; i < rhinoArgs.length;){
174                         arg = (rhinoArgs[i++] + "").split("=");
175                         if(arg[0] == "baseUrl"){
176                                 baseUrl = arg[1];
177                                 break;
178                         }
179                 }
180                 load(baseUrl + "/_base/configRhino.js");
181                 rhinoDojoConfig(defaultConfig, baseUrl, rhinoArgs);
182         }
183
184         // userConfig has tests override defaultConfig has tests; do this after the environment detection because
185         // the environment detection usually sets some has feature values in the hasCache.
186         for(var p in userConfig.has){
187                 has.add(p, userConfig.has[p], 0, 1);
188         }
189
190         //
191         // define the loader data
192         //
193
194         // the loader will use these like symbols if the loader has the traceApi; otherwise
195         // define magic numbers so that modules can be provided as part of defaultConfig
196         var     requested = 1,
197                 arrived = 2,
198                 nonmodule = 3,
199                 executing = 4,
200                 executed = 5;
201
202         if( 0 ){
203                 // these make debugging nice; but using strings for symbols is a gross rookie error; don't do it for production code
204                 requested = "requested";
205                 arrived = "arrived";
206                 nonmodule = "not-a-module";
207                 executing = "executing";
208                 executed = "executed";
209         }
210
211         var legacyMode = 0,
212                 sync = "sync",
213                 xd = "xd",
214                 syncExecStack = [],
215                 dojoRequirePlugin = 0,
216                 checkDojoRequirePlugin = noop,
217                 transformToAmd = noop,
218                 getXhr;
219         if( 1 ){
220                 req.isXdUrl = noop;
221
222                 req.initSyncLoader = function(dojoRequirePlugin_, checkDojoRequirePlugin_, transformToAmd_){
223                         // the first dojo/_base/loader loaded gets to define these variables; they are designed to work
224                         // in the presense of zero to many mapped dojo/_base/loaders
225                         if(!dojoRequirePlugin){
226                                 dojoRequirePlugin = dojoRequirePlugin_;
227                                 checkDojoRequirePlugin = checkDojoRequirePlugin_;
228                                 transformToAmd = transformToAmd_;
229                         }
230
231                         return {
232                                 sync:sync,
233                                 requested:requested,
234                                 arrived:arrived,
235                                 nonmodule:nonmodule,
236                                 executing:executing,
237                                 executed:executed,
238                                 syncExecStack:syncExecStack,
239                                 modules:modules,
240                                 execQ:execQ,
241                                 getModule:getModule,
242                                 injectModule:injectModule,
243                                 setArrived:setArrived,
244                                 signal:signal,
245                                 finishExec:finishExec,
246                                 execModule:execModule,
247                                 dojoRequirePlugin:dojoRequirePlugin,
248                                 getLegacyMode:function(){return legacyMode;},
249                                 guardCheckComplete:guardCheckComplete
250                         };
251                 };
252
253                 if( 1 ){
254                         // in legacy sync mode, the loader needs a minimal XHR library
255
256                         var locationProtocol = location.protocol,
257                                 locationHost = location.host;
258                         req.isXdUrl = function(url){
259                                 if(/^\./.test(url)){
260                                         // begins with a dot is always relative to page URL; therefore not xdomain
261                                         return false;
262                                 }
263                                 if(/^\/\//.test(url)){
264                                         // for v1.6- backcompat, url starting with // indicates xdomain
265                                         return true;
266                                 }
267                                 // get protocol and host
268                                 // \/+ takes care of the typical file protocol that looks like file:///drive/path/to/file
269                                 // locationHost is falsy if file protocol => if locationProtocol matches and is "file:", || will return false
270                                 var match = url.match(/^([^\/\:]+\:)\/+([^\/]+)/);
271                                 return match && (match[1] != locationProtocol || (locationHost && match[2] != locationHost));
272                         };
273
274
275                         // note: to get the file:// protocol to work in FF, you must set security.fileuri.strict_origin_policy to false in about:config
276                          1 || has.add("dojo-xhr-factory", 1);
277                         has.add("dojo-force-activex-xhr",  1  && !doc.addEventListener && window.location.protocol == "file:");
278                         has.add("native-xhr", typeof XMLHttpRequest != "undefined");
279                         if(has("native-xhr") && !has("dojo-force-activex-xhr")){
280                                 getXhr = function(){
281                                         return new XMLHttpRequest();
282                                 };
283                         }else{
284                                 // if in the browser an old IE; find an xhr
285                                 for(var XMLHTTP_PROGIDS = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'], progid, i = 0; i < 3;){
286                                         try{
287                                                 progid = XMLHTTP_PROGIDS[i++];
288                                                 if(new ActiveXObject(progid)){
289                                                         // this progid works; therefore, use it from now on
290                                                         break;
291                                                 }
292                                         }catch(e){
293                                                 // squelch; we're just trying to find a good ActiveX progid
294                                                 // if they all fail, then progid ends up as the last attempt and that will signal the error
295                                                 // the first time the client actually tries to exec an xhr
296                                         }
297                                 }
298                                 getXhr = function(){
299                                         return new ActiveXObject(progid);
300                                 };
301                         }
302                         req.getXhr = getXhr;
303
304                         has.add("dojo-gettext-api", 1);
305                         req.getText = function(url, async, onLoad){
306                                 var xhr = getXhr();
307                                 xhr.open('GET', fixupUrl(url), false);
308                                 xhr.send(null);
309                                 if(xhr.status == 200 || (!location.host && !xhr.status)){
310                                         if(onLoad){
311                                                 onLoad(xhr.responseText, async);
312                                         }
313                                 }else{
314                                         throw makeError("xhrFailed", xhr.status);
315                                 }
316                                 return xhr.responseText;
317                         };
318                 }
319         }else{
320                 req.async = 1;
321         }
322
323         //
324         // loader eval
325         //
326         var eval_ =
327                 // use the function constructor so our eval is scoped close to (but not in) in the global space with minimal pollution
328                 new Function('return eval(arguments[0]);');
329
330         req.eval =
331                 function(text, hint){
332                         return eval_(text + "\r\n////@ sourceURL=" + hint);
333                 };
334
335         //
336         // loader micro events API
337         //
338         var listenerQueues = {},
339                 error = "error",
340                 signal = req.signal = function(type, args){
341                         var queue = listenerQueues[type];
342                         // notice we run a copy of the queue; this allows listeners to add/remove
343                         // other listeners without affecting this particular signal
344                         forEach(queue && queue.slice(0), function(listener){
345                                 listener.apply(null, isArray(args) ? args : [args]);
346                         });
347                 },
348                 on = req.on = function(type, listener){
349                         // notice a queue is not created until a client actually connects
350                         var queue = listenerQueues[type] || (listenerQueues[type] = []);
351                         queue.push(listener);
352                         return {
353                                 remove:function(){
354                                         for(var i = 0; i<queue.length; i++){
355                                                 if(queue[i]===listener){
356                                                         queue.splice(i, 1);
357                                                         return;
358                                                 }
359                                         }
360                                 }
361                         };
362                 };
363
364         // configuration machinery; with an optimized/built defaultConfig, all configuration machinery can be discarded
365         // lexical variables hold key loader data structures to help with minification; these may be completely,
366         // one-time initialized by defaultConfig for optimized/built versions
367         var
368                 aliases
369                         // a vector of pairs of [regexs or string, replacement] => (alias, actual)
370                         = [],
371
372                 paths
373                         // CommonJS paths
374                         = {},
375
376                 pathsMapProg
377                         // list of (from-path, to-path, regex, length) derived from paths;
378                         // a "program" to apply paths; see computeMapProg
379                         = [],
380
381                 packs
382                         // a map from packageId to package configuration object; see fixupPackageInfo
383                         = {},
384
385                 map = req.map
386                         // AMD map config variable; dojo/_base/kernel needs req.map to figure out the scope map
387                         = {},
388
389                 mapProgs
390                         // vector of quads as described by computeMapProg; map-key is AMD map key, map-value is AMD map value
391                         = [],
392
393                 modules
394                         // A hash:(mid) --> (module-object) the module namespace
395                         //
396                         // pid: the package identifier to which the module belongs (e.g., "dojo"); "" indicates the system or default package
397                         // mid: the fully-resolved (i.e., mappings have been applied) module identifier without the package identifier (e.g., "dojo/io/script")
398                         // url: the URL from which the module was retrieved
399                         // pack: the package object of the package to which the module belongs
400                         // executed: 0 => not executed; executing => in the process of tranversing deps and running factory; executed => factory has been executed
401                         // deps: the dependency vector for this module (vector of modules objects)
402                         // def: the factory for this module
403                         // result: the result of the running the factory for this module
404                         // injected: (0 | requested | arrived) the status of the module; nonmodule means the resource did not call define
405                         // load: plugin load function; applicable only for plugins
406                         //
407                         // Modules go through several phases in creation:
408                         //
409                         // 1. Requested: some other module's definition or a require application contained the requested module in
410                         //        its dependency vector or executing code explicitly demands a module via req.require.
411                         //
412                         // 2. Injected: a script element has been appended to the insert-point element demanding the resource implied by the URL
413                         //
414                         // 3. Loaded: the resource injected in [2] has been evalated.
415                         //
416                         // 4. Defined: the resource contained a define statement that advised the loader about the module. Notice that some
417                         //        resources may just contain a bundle of code and never formally define a module via define
418                         //
419                         // 5. Evaluated: the module was defined via define and the loader has evaluated the factory and computed a result.
420                         = {},
421
422                 cacheBust
423                         // query string to append to module URLs to bust browser cache
424                         = "",
425
426                 cache
427                         // hash:(mid | url)-->(function | string)
428                         //
429                         // A cache of resources. The resources arrive via a config.cache object, which is a hash from either mid --> function or
430                         // url --> string. The url key is distinguished from the mid key by always containing the prefix "url:". url keys as provided
431                         // by config.cache always have a string value that represents the contents of the resource at the given url. mid keys as provided
432                         // by configl.cache always have a function value that causes the same code to execute as if the module was script injected.
433                         //
434                         // Both kinds of key-value pairs are entered into cache via the function consumePendingCache, which may relocate keys as given
435                         // by any mappings *iff* the config.cache was received as part of a module resource request.
436                         //
437                         // Further, for mid keys, the implied url is computed and the value is entered into that key as well. This allows mapped modules
438                         // to retrieve cached items that may have arrived consequent to another namespace.
439                         //
440                          = {},
441
442                 urlKeyPrefix
443                         // the prefix to prepend to a URL key in the cache.
444                         = "url:",
445
446                 pendingCacheInsert
447                         // hash:(mid)-->(function)
448                         //
449                         // Gives a set of cache modules pending entry into cache. When cached modules are published to the loader, they are
450                         // entered into pendingCacheInsert; modules are then pressed into cache upon (1) AMD define or (2) upon receiving another
451                         // independent set of cached modules. (1) is the usual case, and this case allows normalizing mids given in the pending
452                         // cache for the local configuration, possibly relocating modules.
453                          = {},
454
455                 dojoSniffConfig
456                         // map of configuration variables
457                         // give the data-dojo-config as sniffed from the document (if any)
458                         = {};
459
460         if( 1 ){
461                 var consumePendingCacheInsert = function(referenceModule){
462                                 var p, item, match, now, m;
463                                 for(p in pendingCacheInsert){
464                                         item = pendingCacheInsert[p];
465                                         match = p.match(/^url\:(.+)/);
466                                         if(match){
467                                                 cache[urlKeyPrefix + toUrl(match[1], referenceModule)] =  item;
468                                         }else if(p=="*now"){
469                                                 now = item;
470                                         }else if(p!="*noref"){
471                                                 m = getModuleInfo(p, referenceModule);
472                                                 cache[m.mid] = cache[urlKeyPrefix + m.url] = item;
473                                         }
474                                 }
475                                 if(now){
476                                         now(createRequire(referenceModule));
477                                 }
478                                 pendingCacheInsert = {};
479                         },
480
481                         escapeString = function(s){
482                                 return s.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, function(c){ return "\\" + c; });
483                         },
484
485                         computeMapProg = function(map, dest){
486                                 // This routine takes a map as represented by a JavaScript object and initializes dest, a vector of
487                                 // quads of (map-key, map-value, refex-for-map-key, length-of-map-key), sorted decreasing by length-
488                                 // of-map-key. The regex looks for the map-key followed by either "/" or end-of-string at the beginning
489                                 // of a the search source. Notice the map-value is irrelevent to the algorithm
490                                 dest.splice(0, dest.length);
491                                 for(var p in map){
492                                         dest.push([
493                                                 p,
494                                                 map[p],
495                                                 new RegExp("^" + escapeString(p) + "(\/|$)"),
496                                                 p.length]);
497                                 }
498                                 dest.sort(function(lhs, rhs){ return rhs[3] - lhs[3]; });
499                                 return dest;
500                         },
501
502                         fixupPackageInfo = function(packageInfo){
503                                 // calculate the precise (name, location, main, mappings) for a package
504                                 var name = packageInfo.name;
505                                 if(!name){
506                                         // packageInfo must be a string that gives the name
507                                         name = packageInfo;
508                                         packageInfo = {name:name};
509                                 }
510                                 packageInfo = mix({main:"main"}, packageInfo);
511                                 packageInfo.location = packageInfo.location ? packageInfo.location : name;
512
513                                 // packageMap is depricated in favor of AMD map
514                                 if(packageInfo.packageMap){
515                                         map[name] = packageInfo.packageMap;
516                                 }
517
518                                 if(!packageInfo.main.indexOf("./")){
519                                         packageInfo.main = packageInfo.main.substring(2);
520                                 }
521
522                                 // now that we've got a fully-resolved package object, push it into the configuration
523                                 packs[name] = packageInfo;
524                         },
525
526                         delayedModuleConfig
527                                 // module config cannot be consummed until the loader is completely initialized; therefore, all
528                                 // module config detected during booting is memorized and applied at the end of loader initialization
529                                 // TODO: this is a bit of a kludge; all config should be moved to end of loader initialization, but
530                                 // we'll delay this chore and do it with a final loader 1.x cleanup after the 2.x loader prototyping is complete
531                                 = [],
532
533
534                         config = function(config, booting, referenceModule){
535                                 for(var p in config){
536                                         if(p=="waitSeconds"){
537                                                 req.waitms = (config[p] || 0) * 1000;
538                                         }
539                                         if(p=="cacheBust"){
540                                                 cacheBust = config[p] ? (isString(config[p]) ? config[p] : (new Date()).getTime() + "") : "";
541                                         }
542                                         if(p=="baseUrl" || p=="combo"){
543                                                 req[p] = config[p];
544                                         }
545                                         if( 1  && p=="async"){
546                                                 // falsy or "sync" => legacy sync loader
547                                                 // "xd" => sync but loading xdomain tree and therefore loading asynchronously (not configurable, set automatically by the loader)
548                                                 // "legacyAsync" => permanently in "xd" by choice
549                                                 // "debugAtAllCosts" => trying to load everything via script injection (not implemented)
550                                                 // otherwise, must be truthy => AMD
551                                                 // legacyMode: sync | legacyAsync | xd | false
552                                                 var mode = config[p];
553                                                 req.legacyMode = legacyMode = (isString(mode) && /sync|legacyAsync/.test(mode) ? mode : (!mode ? sync : false));
554                                                 req.async = !legacyMode;
555                                         }
556                                         if(config[p]!==hasCache){
557                                                 // accumulate raw config info for client apps which can use this to pass their own config
558                                                 req.rawConfig[p] = config[p];
559                                                 p!="has" && has.add("config-"+p, config[p], 0, booting);
560                                         }
561                                 }
562
563                                 // make sure baseUrl exists
564                                 if(!req.baseUrl){
565                                         req.baseUrl = "./";
566                                 }
567                                 // make sure baseUrl ends with a slash
568                                 if(!/\/$/.test(req.baseUrl)){
569                                         req.baseUrl += "/";
570                                 }
571
572                                 // now do the special work for has, packages, packagePaths, paths, aliases, and cache
573
574                                 for(p in config.has){
575                                         has.add(p, config.has[p], 0, booting);
576                                 }
577
578                                 // for each package found in any packages config item, augment the packs map owned by the loader
579                                 forEach(config.packages, fixupPackageInfo);
580
581                                 // for each packagePath found in any packagePaths config item, augment the packageConfig
582                                 // packagePaths is depricated; remove in 2.0
583                                 for(baseUrl in config.packagePaths){
584                                         forEach(config.packagePaths[baseUrl], function(packageInfo){
585                                                 var location = baseUrl + "/" + packageInfo;
586                                                 if(isString(packageInfo)){
587                                                         packageInfo = {name:packageInfo};
588                                                 }
589                                                 packageInfo.location = location;
590                                                 fixupPackageInfo(packageInfo);
591                                         });
592                                 }
593
594                                 // notice that computeMapProg treats the dest as a reference; therefore, if/when that variable
595                                 // is published (see dojo-publish-privates), the published variable will always hold a valid value.
596
597                                 // this must come after all package processing since package processing may mutate map
598                                 computeMapProg(mix(map, config.map), mapProgs);
599                                 forEach(mapProgs, function(item){
600                                         item[1] = computeMapProg(item[1], []);
601                                         if(item[0]=="*"){
602                                                 mapProgs.star = item;
603                                         }
604                                 });
605
606                                 // push in any paths and recompute the internal pathmap
607                                 computeMapProg(mix(paths, config.paths), pathsMapProg);
608
609                                 // aliases
610                                 forEach(config.aliases, function(pair){
611                                         if(isString(pair[0])){
612                                                 pair[0] = new RegExp("^" + escapeString(pair[0]) + "$");
613                                         }
614                                         aliases.push(pair);
615                                 });
616
617                                 if(booting){
618                                         delayedModuleConfig.push({config:config.config});
619                                 }else{
620                                         for(p in config.config){
621                                                 var module = getModule(p, referenceModule);
622                                                 module.config = mix(module.config || {}, config.config[p]);
623                                         }
624                                 }
625
626                                 // push in any new cache values
627                                 if(config.cache){
628                                         consumePendingCacheInsert();
629                                         pendingCacheInsert = config.cache;
630                                         if(config.cache["*noref"]){
631                                                 consumePendingCacheInsert();
632                                         }
633                                 }
634
635                                 signal("config", [config, req.rawConfig]);
636                         };
637
638                 //
639                 // execute the various sniffs; userConfig can override and value
640                 //
641
642                 if(has("dojo-cdn") ||  1 ){
643                         // the sniff regex looks for a src attribute ending in dojo.js, optionally preceeded with a path.
644                         // match[3] returns the path to dojo.js (if any) without the trailing slash. This is used for the
645                         // dojo location on CDN deployments and baseUrl when either/both of these are not provided
646                         // explicitly in the config data; this is the 1.6- behavior.
647
648                         var scripts = doc.getElementsByTagName("script"),
649                                 i = 0,
650                                 script, dojoDir, src, match;
651                         while(i < scripts.length){
652                                 script = scripts[i++];
653                                 if((src = script.getAttribute("src")) && (match = src.match(/(((.*)\/)|^)dojo\.js(\W|$)/i))){
654                                         // sniff dojoDir and baseUrl
655                                         dojoDir = match[3] || "";
656                                         defaultConfig.baseUrl = defaultConfig.baseUrl || dojoDir;
657
658                                         // sniff configuration on attribute in script element
659                                         src = (script.getAttribute("data-dojo-config") || script.getAttribute("djConfig"));
660                                         if(src){
661                                                 dojoSniffConfig = req.eval("({ " + src + " })", "data-dojo-config");
662                                         }
663
664                                         // sniff requirejs attribute
665                                         if( 0 ){
666                                                 var dataMain = script.getAttribute("data-main");
667                                                 if(dataMain){
668                                                         dojoSniffConfig.deps = dojoSniffConfig.deps || [dataMain];
669                                                 }
670                                         }
671                                         break;
672                                 }
673                         }
674                 }
675
676                 if( 0 ){
677                         // pass down doh.testConfig from parent as if it were a data-dojo-config
678                         try{
679                                 if(window.parent != window && window.parent.require){
680                                         var doh = window.parent.require("doh");
681                                         doh && mix(dojoSniffConfig, doh.testConfig);
682                                 }
683                         }catch(e){}
684                 }
685
686                 // configure the loader; let the user override defaults
687                 req.rawConfig = {};
688                 config(defaultConfig, 1);
689
690                 // do this before setting userConfig/sniffConfig to allow userConfig/sniff overrides
691                 if(has("dojo-cdn")){
692                         packs.dojo.location = dojoDir;
693                         if(dojoDir){
694                                 dojoDir += "/";
695                         }
696                         packs.dijit.location = dojoDir + "../dijit/";
697                         packs.dojox.location = dojoDir + "../dojox/";
698                 }
699
700                 config(userConfig, 1);
701                 config(dojoSniffConfig, 1);
702
703         }else{
704                 // no config API, assume defaultConfig has everything the loader needs...for the entire lifetime of the application
705                 paths = defaultConfig.paths;
706                 pathsMapProg = defaultConfig.pathsMapProg;
707                 packs = defaultConfig.packs;
708                 aliases = defaultConfig.aliases;
709                 mapProgs = defaultConfig.mapProgs;
710                 modules = defaultConfig.modules;
711                 cache = defaultConfig.cache;
712                 cacheBust = defaultConfig.cacheBust;
713
714                 // remember the default config for other processes (e.g., dojo/config)
715                 req.rawConfig = defaultConfig;
716         }
717
718
719         if( 0 ){
720                 req.combo = req.combo || {add:noop};
721                 var     comboPending = 0,
722                         combosPending = [],
723                         comboPendingTimer = null;
724         }
725
726
727         // build the loader machinery iaw configuration, including has feature tests
728         var     injectDependencies = function(module){
729                         // checkComplete!=0 holds the idle signal; we're not idle if we're injecting dependencies
730                         guardCheckComplete(function(){
731                                 forEach(module.deps, injectModule);
732                                 if( 0  && comboPending && !comboPendingTimer){
733                                         comboPendingTimer = setTimeout(function() {
734                                                 comboPending = 0;
735                                                 comboPendingTimer = null;
736                                                 req.combo.done(function(mids, url) {
737                                                         var onLoadCallback= function(){
738                                                                 // defQ is a vector of module definitions 1-to-1, onto mids
739                                                                 runDefQ(0, mids);
740                                                                 checkComplete();
741                                                         };
742                                                         combosPending.push(mids);
743                                                         injectingModule = mids;
744                                                         req.injectUrl(url, onLoadCallback, mids);
745                                                         injectingModule = 0;
746                                                 }, req);
747                                         }, 0);
748                                 }
749                         });
750                 },
751
752                 contextRequire = function(a1, a2, a3, referenceModule, contextRequire){
753                         var module, syntheticMid;
754                         if(isString(a1)){
755                                 // signature is (moduleId)
756                                 module = getModule(a1, referenceModule, true);
757                                 if(module && module.executed){
758                                         return module.result;
759                                 }
760                                 throw makeError("undefinedModule", a1);
761                         }
762                         if(!isArray(a1)){
763                                 // a1 is a configuration
764                                 config(a1, 0, referenceModule);
765
766                                 // juggle args; (a2, a3) may be (dependencies, callback)
767                                 a1 = a2;
768                                 a2 = a3;
769                         }
770                         if(isArray(a1)){
771                                 // signature is (requestList [,callback])
772                                 if(!a1.length){
773                                         a2 && a2();
774                                 }else{
775                                         syntheticMid = "require*" + uid();
776
777                                         // resolve the request list with respect to the reference module
778                                         for(var mid, deps = [], i = 0; i < a1.length;){
779                                                 mid = a1[i++];
780                                                 deps.push(getModule(mid, referenceModule));
781                                         }
782
783                                         // construct a synthetic module to control execution of the requestList, and, optionally, callback
784                                         module = mix(makeModuleInfo("", syntheticMid, 0, ""), {
785                                                 injected: arrived,
786                                                 deps: deps,
787                                                 def: a2 || noop,
788                                                 require: referenceModule ? referenceModule.require : req,
789                                                 gc: 1 //garbage collect
790                                         });
791                                         modules[module.mid] = module;
792
793                                         // checkComplete!=0 holds the idle signal; we're not idle if we're injecting dependencies
794                                         injectDependencies(module);
795
796                                         // try to immediately execute
797                                         // if already traversing a factory tree, then strict causes circular dependency to abort the execution; maybe
798                                         // it's possible to execute this require later after the current traversal completes and avoid the circular dependency.
799                                         // ...but *always* insist on immediate in synch mode
800                                         var strict = checkCompleteGuard && legacyMode!=sync;
801                                         guardCheckComplete(function(){
802                                                 execModule(module, strict);
803                                         });
804                                         if(!module.executed){
805                                                 // some deps weren't on board or circular dependency detected and strict; therefore, push into the execQ
806                                                 execQ.push(module);
807                                         }
808                                         checkComplete();
809                                 }
810                         }
811                         return contextRequire;
812                 },
813
814                 createRequire = function(module){
815                         if(!module){
816                                 return req;
817                         }
818                         var result = module.require;
819                         if(!result){
820                                 result = function(a1, a2, a3){
821                                         return contextRequire(a1, a2, a3, module, result);
822                                 };
823                                 module.require = mix(result, req);
824                                 result.module = module;
825                                 result.toUrl = function(name){
826                                         return toUrl(name, module);
827                                 };
828                                 result.toAbsMid = function(mid){
829                                         return toAbsMid(mid, module);
830                                 };
831                                 if( 0 ){
832                                         result.undef = function(mid){
833                                                 req.undef(mid, module);
834                                         };
835                                 }
836                                 if( 1 ){
837                                         result.syncLoadNls = function(mid){
838                                                 var nlsModuleInfo = getModuleInfo(mid, module),
839                                                         nlsModule = modules[nlsModuleInfo.mid];
840                                                 if(!nlsModule || !nlsModule.executed){
841                                                         cached = cache[nlsModuleInfo.mid] || cache[urlKeyPrefix + nlsModuleInfo.url];
842                                                         if(cached){
843                                                                 evalModuleText(cached);
844                                                                 nlsModule = modules[nlsModuleInfo.mid];
845                                                         }
846                                                 }
847                                                 return nlsModule && nlsModule.executed && nlsModule.result;
848                                         };
849                                 }
850
851                         }
852                         return result;
853                 },
854
855                 execQ =
856                         // The list of modules that need to be evaluated.
857                         [],
858
859                 defQ =
860                         // The queue of define arguments sent to loader.
861                         [],
862
863                 waiting =
864                         // The set of modules upon which the loader is waiting for definition to arrive
865                         {},
866
867                 setRequested = function(module){
868                         module.injected = requested;
869                         waiting[module.mid] = 1;
870                         if(module.url){
871                                 waiting[module.url] = module.pack || 1;
872                         }
873                         startTimer();
874                 },
875
876                 setArrived = function(module){
877                         module.injected = arrived;
878                         delete waiting[module.mid];
879                         if(module.url){
880                                 delete waiting[module.url];
881                         }
882                         if(isEmpty(waiting)){
883                                 clearTimer();
884                                  1  && legacyMode==xd && (legacyMode = sync);
885                         }
886                 },
887
888                 execComplete = req.idle =
889                         // says the loader has completed (or not) its work
890                         function(){
891                                 return !defQ.length && isEmpty(waiting) && !execQ.length && !checkCompleteGuard;
892                         },
893
894                 runMapProg = function(targetMid, map){
895                         // search for targetMid in map; return the map item if found; falsy otherwise
896                         if(map){
897                         for(var i = 0; i < map.length; i++){
898                                 if(map[i][2].test(targetMid)){
899                                         return map[i];
900                                 }
901                         }
902                         }
903                         return 0;
904                 },
905
906                 compactPath = function(path){
907                         var result = [],
908                                 segment, lastSegment;
909                         path = path.replace(/\\/g, '/').split('/');
910                         while(path.length){
911                                 segment = path.shift();
912                                 if(segment==".." && result.length && lastSegment!=".."){
913                                         result.pop();
914                                         lastSegment = result[result.length - 1];
915                                 }else if(segment!="."){
916                                         result.push(lastSegment= segment);
917                                 } // else ignore "."
918                         }
919                         return result.join("/");
920                 },
921
922                 makeModuleInfo = function(pid, mid, pack, url){
923                         if( 1 ){
924                                 var xd= req.isXdUrl(url);
925                                 return {pid:pid, mid:mid, pack:pack, url:url, executed:0, def:0, isXd:xd, isAmd:!!(xd || (packs[pid] && packs[pid].isAmd))};
926                         }else{
927                                 return {pid:pid, mid:mid, pack:pack, url:url, executed:0, def:0};
928                         }
929                 },
930
931                 getModuleInfo_ = function(mid, referenceModule, packs, modules, baseUrl, mapProgs, pathsMapProg, alwaysCreate){
932                         // arguments are passed instead of using lexical variables so that this function my be used independent of the loader (e.g., the builder)
933                         // alwaysCreate is useful in this case so that getModuleInfo never returns references to real modules owned by the loader
934                         var pid, pack, midInPackage, mapProg, mapItem, url, result, isRelative, requestedMid;
935                         requestedMid = mid;
936                         isRelative = /^\./.test(mid);
937                         if(/(^\/)|(\:)|(\.js$)/.test(mid) || (isRelative && !referenceModule)){
938                                 // absolute path or protocol of .js filetype, or relative path but no reference module and therefore relative to page
939                                 // whatever it is, it's not a module but just a URL of some sort
940                                 // note: pid===0 indicates the routine is returning an unmodified mid
941
942                                 return makeModuleInfo(0, mid, 0, mid);
943                         }else{
944                                 // relative module ids are relative to the referenceModule; get rid of any dots
945                                 mid = compactPath(isRelative ? (referenceModule.mid + "/../" + mid) : mid);
946                                 if(/^\./.test(mid)){
947                                         throw makeError("irrationalPath", mid);
948                                 }
949                                 // at this point, mid is an absolute mid
950
951                                 // map the mid
952                                 if(referenceModule){
953                                         mapItem = runMapProg(referenceModule.mid, mapProgs);
954                                 }
955                                 mapItem = mapItem || mapProgs.star;
956                                 mapItem = mapItem && runMapProg(mid, mapItem[1]);
957
958                                 if(mapItem){
959                                         mid = mapItem[1] + mid.substring(mapItem[3]);
960                                         }
961
962                                 match = mid.match(/^([^\/]+)(\/(.+))?$/);
963                                 pid = match ? match[1] : "";
964                                 if((pack = packs[pid])){
965                                         mid = pid + "/" + (midInPackage = (match[3] || pack.main));
966                                 }else{
967                                         pid = "";
968                                 }
969
970                                 // search aliases
971                                 var candidateLength = 0,
972                                         candidate = 0;
973                                 forEach(aliases, function(pair){
974                                         var match = mid.match(pair[0]);
975                                         if(match && match.length>candidateLength){
976                                                 candidate = isFunction(pair[1]) ? mid.replace(pair[0], pair[1]) : pair[1];
977                                         }
978                                 });
979                                 if(candidate){
980                                         return getModuleInfo_(candidate, 0, packs, modules, baseUrl, mapProgs, pathsMapProg, alwaysCreate);
981                                 }
982
983                                 result = modules[mid];
984                                 if(result){
985                                         return alwaysCreate ? makeModuleInfo(result.pid, result.mid, result.pack, result.url) : modules[mid];
986                                 }
987                         }
988                         // get here iff the sought-after module does not yet exist; therefore, we need to compute the URL given the
989                         // fully resolved (i.e., all relative indicators and package mapping resolved) module id
990
991                         // note: pid!==0 indicates the routine is returning a url that has .js appended unmodified mid
992                         mapItem = runMapProg(mid, pathsMapProg);
993                         if(mapItem){
994                                 url = mapItem[1] + mid.substring(mapItem[3]);
995                         }else if(pid){
996                                 url = pack.location + "/" + midInPackage;
997                         }else if(has("config-tlmSiblingOfDojo")){
998                                 url = "../" + mid;
999                         }else{
1000                                 url = mid;
1001                         }
1002                         // if result is not absolute, add baseUrl
1003                         if(!(/(^\/)|(\:)/.test(url))){
1004                                 url = baseUrl + url;
1005                         }
1006                         url += ".js";
1007                         return makeModuleInfo(pid, mid, pack, compactPath(url));
1008                 },
1009
1010                 getModuleInfo = function(mid, referenceModule){
1011                         return getModuleInfo_(mid, referenceModule, packs, modules, req.baseUrl, mapProgs, pathsMapProg);
1012                 },
1013
1014                 resolvePluginResourceId = function(plugin, prid, referenceModule){
1015                         return plugin.normalize ? plugin.normalize(prid, function(mid){return toAbsMid(mid, referenceModule);}) : toAbsMid(prid, referenceModule);
1016                 },
1017
1018                 dynamicPluginUidGenerator = 0,
1019
1020                 getModule = function(mid, referenceModule, immediate){
1021                         // compute and optionally construct (if necessary) the module implied by the mid with respect to referenceModule
1022                         var match, plugin, prid, result;
1023                         match = mid.match(/^(.+?)\!(.*)$/);
1024                         if(match){
1025                                 // name was <plugin-module>!<plugin-resource-id>
1026                                 plugin = getModule(match[1], referenceModule, immediate);
1027
1028                                 if( 1  && legacyMode == sync && !plugin.executed){
1029                                         injectModule(plugin);
1030                                         if(plugin.injected===arrived && !plugin.executed){
1031                                                 guardCheckComplete(function(){
1032                                                         execModule(plugin);
1033                                                 });
1034                                         }
1035                                         if(plugin.executed){
1036                                                 promoteModuleToPlugin(plugin);
1037                                         }else{
1038                                                 // we are in xdomain mode for some reason
1039                                                 execQ.unshift(plugin);
1040                                         }
1041                                 }
1042
1043
1044
1045                                 if(plugin.executed === executed && !plugin.load){
1046                                         // executed the module not knowing it was a plugin
1047                                         promoteModuleToPlugin(plugin);
1048                                 }
1049
1050                                 // if the plugin has not been loaded, then can't resolve the prid and  must assume this plugin is dynamic until we find out otherwise
1051                                 if(plugin.load){
1052                                         prid = resolvePluginResourceId(plugin, match[2], referenceModule);
1053                                         mid = (plugin.mid + "!" + (plugin.dynamic ? ++dynamicPluginUidGenerator + "!" : "") + prid);
1054                                 }else{
1055                                         prid = match[2];
1056                                         mid = plugin.mid + "!" + (++dynamicPluginUidGenerator) + "!waitingForPlugin";
1057                                 }
1058                                 result = {plugin:plugin, mid:mid, req:createRequire(referenceModule), prid:prid};
1059                         }else{
1060                                 result = getModuleInfo(mid, referenceModule);
1061                         }
1062                         return modules[result.mid] || (!immediate && (modules[result.mid] = result));
1063                 },
1064
1065                 toAbsMid = req.toAbsMid = function(mid, referenceModule){
1066                         return getModuleInfo(mid, referenceModule).mid;
1067                 },
1068
1069                 toUrl = req.toUrl = function(name, referenceModule){
1070                         var moduleInfo = getModuleInfo(name+"/x", referenceModule),
1071                                 url= moduleInfo.url;
1072                         return fixupUrl(moduleInfo.pid===0 ?
1073                                 // if pid===0, then name had a protocol or absolute path; either way, toUrl is the identify function in such cases
1074                                 name :
1075                                 // "/x.js" since getModuleInfo automatically appends ".js" and we appended "/x" to make name look likde a module id
1076                                 url.substring(0, url.length-5)
1077                         );
1078                 },
1079
1080                 nonModuleProps = {
1081                         injected: arrived,
1082                         executed: executed,
1083                         def: nonmodule,
1084                         result: nonmodule
1085                 },
1086
1087                 makeCjs = function(mid){
1088                         return modules[mid] = mix({mid:mid}, nonModuleProps);
1089                 },
1090
1091                 cjsRequireModule = makeCjs("require"),
1092                 cjsExportsModule = makeCjs("exports"),
1093                 cjsModuleModule = makeCjs("module"),
1094
1095                 runFactory = function(module, args){
1096                         req.trace("loader-run-factory", [module.mid]);
1097                         var factory = module.def,
1098                                 result;
1099                          1  && syncExecStack.unshift(module);
1100                         if(has("config-dojo-loader-catches")){
1101                                 try{
1102                                         result= isFunction(factory) ? factory.apply(null, args) : factory;
1103                                 }catch(e){
1104                                         signal(error, module.result = makeError("factoryThrew", [module, e]));
1105                                 }
1106                         }else{
1107                                 result= isFunction(factory) ? factory.apply(null, args) : factory;
1108                         }
1109                         module.result = result===undefined && module.cjs ? module.cjs.exports : result;
1110                          1  && syncExecStack.shift(module);
1111                 },
1112
1113                 abortExec = {},
1114
1115                 defOrder = 0,
1116
1117                 promoteModuleToPlugin = function(pluginModule){
1118                         var plugin = pluginModule.result;
1119                         pluginModule.dynamic = plugin.dynamic;
1120                         pluginModule.normalize = plugin.normalize;
1121                         pluginModule.load = plugin.load;
1122                         return pluginModule;
1123                 },
1124
1125                 resolvePluginLoadQ = function(plugin){
1126                         // plugins is a newly executed module that has a loadQ waiting to run
1127
1128                         // step 1: traverse the loadQ and fixup the mid and prid; remember the map from original mid to new mid
1129                         // recall the original mid was created before the plugin was on board and therefore it was impossible to
1130                         // compute the final mid; accordingly, prid may or may not change, but the mid will definitely change
1131                         var map = {};
1132                         forEach(plugin.loadQ, function(pseudoPluginResource){
1133                                 // manufacture and insert the real module in modules
1134                                 var prid = resolvePluginResourceId(plugin, pseudoPluginResource.prid, pseudoPluginResource.req.module),
1135                                         mid = plugin.dynamic ? pseudoPluginResource.mid.replace(/waitingForPlugin$/, prid) : (plugin.mid + "!" + prid),
1136                                         pluginResource = mix(mix({}, pseudoPluginResource), {mid:mid, prid:prid, injected:0});
1137                                 if(!modules[mid]){
1138                                         // create a new (the real) plugin resource and inject it normally now that the plugin is on board
1139                                         injectPlugin(modules[mid] = pluginResource);
1140                                 } // else this was a duplicate request for the same (plugin, rid) for a nondynamic plugin
1141
1142                                 // pluginResource is really just a placeholder with the wrong mid (because we couldn't calculate it until the plugin was on board)
1143                                 // mark is as arrived and delete it from modules; the real module was requested above
1144                                 map[pseudoPluginResource.mid] = modules[mid];
1145                                 setArrived(pseudoPluginResource);
1146                                 delete modules[pseudoPluginResource.mid];
1147                         });
1148                         plugin.loadQ = 0;
1149
1150                         // step2: replace all references to any placeholder modules with real modules
1151                         var substituteModules = function(module){
1152                                 for(var replacement, deps = module.deps || [], i = 0; i<deps.length; i++){
1153                                         replacement = map[deps[i].mid];
1154                                         if(replacement){
1155                                                 deps[i] = replacement;
1156                                         }
1157                                 }
1158                         };
1159                         for(var p in modules){
1160                                 substituteModules(modules[p]);
1161                         }
1162                         forEach(execQ, substituteModules);
1163                 },
1164
1165                 finishExec = function(module){
1166                         req.trace("loader-finish-exec", [module.mid]);
1167                         module.executed = executed;
1168                         module.defOrder = defOrder++;
1169                          1  && forEach(module.provides, function(cb){ cb(); });
1170                         if(module.loadQ){
1171                                 // the module was a plugin
1172                                 promoteModuleToPlugin(module);
1173                                 resolvePluginLoadQ(module);
1174                         }
1175                         // remove all occurences of this module from the execQ
1176                         for(i = 0; i < execQ.length;){
1177                                 if(execQ[i] === module){
1178                                         execQ.splice(i, 1);
1179                                 }else{
1180                                         i++;
1181                                 }
1182                         }
1183                         // delete references to synthetic modules
1184                         if (/^require\*/.test(module.mid)) {
1185                                 delete modules[module.mid];
1186                         }
1187                 },
1188
1189                 circleTrace = [],
1190
1191                 execModule = function(module, strict){
1192                         // run the dependency vector, then run the factory for module
1193                         if(module.executed === executing){
1194                                 req.trace("loader-circular-dependency", [circleTrace.concat(module.mid).join("->")]);
1195                                 return (!module.def || strict) ? abortExec :  (module.cjs && module.cjs.exports);
1196                         }
1197                         // at this point the module is either not executed or fully executed
1198
1199
1200                         if(!module.executed){
1201                                 if(!module.def){
1202                                         return abortExec;
1203                                 }
1204                                 var mid = module.mid,
1205                                         deps = module.deps || [],
1206                                         arg, argResult,
1207                                         args = [],
1208                                         i = 0;
1209
1210                                 if( 0 ){
1211                                         circleTrace.push(mid);
1212                                         req.trace("loader-exec-module", ["exec", circleTrace.length, mid]);
1213                                 }
1214
1215                                 // for circular dependencies, assume the first module encountered was executed OK
1216                                 // modules that circularly depend on a module that has not run its factory will get
1217                                 // the premade cjs.exports===module.result. They can take a reference to this object and/or
1218                                 // add properties to it. When the module finally runs its factory, the factory can
1219                                 // read/write/replace this object. Notice that so long as the object isn't replaced, any
1220                                 // reference taken earlier while walking the deps list is still valid.
1221                                 module.executed = executing;
1222                                 while(i < deps.length){
1223                                         arg = deps[i++];
1224                                         argResult = ((arg === cjsRequireModule) ? createRequire(module) :
1225                                                                         ((arg === cjsExportsModule) ? module.cjs.exports :
1226                                                                                 ((arg === cjsModuleModule) ? module.cjs :
1227                                                                                         execModule(arg, strict))));
1228                                         if(argResult === abortExec){
1229                                                 module.executed = 0;
1230                                                 req.trace("loader-exec-module", ["abort", mid]);
1231                                                  0  && circleTrace.pop();
1232                                                 return abortExec;
1233                                         }
1234                                         args.push(argResult);
1235                                 }
1236                                 runFactory(module, args);
1237                                 finishExec(module);
1238                                  0  && circleTrace.pop();
1239                         }
1240                         // at this point the module is guaranteed fully executed
1241
1242                         return module.result;
1243                 },
1244
1245
1246                 checkCompleteGuard = 0,
1247
1248                 guardCheckComplete = function(proc){
1249                         try{
1250                                 checkCompleteGuard++;
1251                                 proc();
1252                         }finally{
1253                                 checkCompleteGuard--;
1254                         }
1255                         if(execComplete()){
1256                                 signal("idle", []);
1257                         }
1258                 },
1259
1260                 checkComplete = function(){
1261                         // keep going through the execQ as long as at least one factory is executed
1262                         // plugins, recursion, cached modules all make for many execution path possibilities
1263                         if(checkCompleteGuard){
1264                                 return;
1265                         }
1266                         guardCheckComplete(function(){
1267                                 checkDojoRequirePlugin();
1268                                 for(var currentDefOrder, module, i = 0; i < execQ.length;){
1269                                         currentDefOrder = defOrder;
1270                                         module = execQ[i];
1271                                         execModule(module);
1272                                         if(currentDefOrder!=defOrder){
1273                                                 // defOrder was bumped one or more times indicating something was executed (note, this indicates
1274                                                 // the execQ was modified, maybe a lot (for example a later module causes an earlier module to execute)
1275                                                 checkDojoRequirePlugin();
1276                                                 i = 0;
1277                                         }else{
1278                                                 // nothing happened; check the next module in the exec queue
1279                                                 i++;
1280                                         }
1281                                 }
1282                         });
1283                 };
1284
1285
1286         if( 0 ){
1287                 req.undef = function(moduleId, referenceModule){
1288                         // In order to reload a module, it must be undefined (this routine) and then re-requested.
1289                         // This is useful for testing frameworks (at least).
1290                         var module = getModule(moduleId, referenceModule);
1291                         setArrived(module);
1292                         delete modules[module.mid];
1293                 };
1294         }
1295
1296         if( 1 ){
1297                 if(has("dojo-loader-eval-hint-url")===undefined){
1298                         has.add("dojo-loader-eval-hint-url", 1);
1299                 }
1300
1301                 var fixupUrl= function(url){
1302                                 url += ""; // make sure url is a Javascript string (some paths may be a Java string)
1303                                 return url + (cacheBust ? ((/\?/.test(url) ? "&" : "?") + cacheBust) : "");
1304                         },
1305
1306                         injectPlugin = function(
1307                                 module
1308                         ){
1309                                 // injects the plugin module given by module; may have to inject the plugin itself
1310                                 var plugin = module.plugin;
1311
1312                                 if(plugin.executed === executed && !plugin.load){
1313                                         // executed the module not knowing it was a plugin
1314                                         promoteModuleToPlugin(plugin);
1315                                 }
1316
1317                                 var onLoad = function(def){
1318                                                 module.result = def;
1319                                                 setArrived(module);
1320                                                 finishExec(module);
1321                                                 checkComplete();
1322                                         };
1323
1324                                 if(plugin.load){
1325                                         plugin.load(module.prid, module.req, onLoad);
1326                                 }else if(plugin.loadQ){
1327                                         plugin.loadQ.push(module);
1328                                 }else{
1329                                         // the unshift instead of push is important: we don't want plugins to execute as
1330                                         // dependencies of some other module because this may cause circles when the plugin
1331                                         // loadQ is run; also, generally, we want plugins to run early since they may load
1332                                         // several other modules and therefore can potentially unblock many modules
1333                                         plugin.loadQ = [module];
1334                                         execQ.unshift(plugin);
1335                                         injectModule(plugin);
1336                                 }
1337                         },
1338
1339                         // for IE, injecting a module may result in a recursive execution if the module is in the cache
1340
1341                         cached = 0,
1342
1343                         injectingModule = 0,
1344
1345                         injectingCachedModule = 0,
1346
1347                         evalModuleText = function(text, module){
1348                                 // see def() for the injectingCachedModule bracket; it simply causes a short, safe curcuit
1349                                 if(has("config-stripStrict")){
1350                                         text = text.replace(/"use strict"/g, '');
1351                                 }
1352                                 injectingCachedModule = 1;
1353                                 if(has("config-dojo-loader-catches")){
1354                                         try{
1355                                                 if(text===cached){
1356                                                         cached.call(null);
1357                                                 }else{
1358                                                         req.eval(text, has("dojo-loader-eval-hint-url") ? module.url : module.mid);
1359                                                 }
1360                                         }catch(e){
1361                                                 signal(error, makeError("evalModuleThrew", module));
1362                                         }
1363                                 }else{
1364                                         if(text===cached){
1365                                                 cached.call(null);
1366                                         }else{
1367                                                 req.eval(text, has("dojo-loader-eval-hint-url") ? module.url : module.mid);
1368                                         }
1369                                 }
1370                                 injectingCachedModule = 0;
1371                         },
1372
1373                         injectModule = function(module){
1374                                 // Inject the module. In the browser environment, this means appending a script element into
1375                                 // the document; in other environments, it means loading a file.
1376                                 //
1377                                 // If in synchronous mode, then get the module synchronously if it's not xdomainLoading.
1378
1379                                 var mid = module.mid,
1380                                         url = module.url;
1381                                 if(module.executed || module.injected || waiting[mid] || (module.url && ((module.pack && waiting[module.url]===module.pack) || waiting[module.url]==1))){
1382                                         return;
1383                                 }
1384                                 setRequested(module);
1385
1386                                 if( 0 ){
1387                                         var viaCombo = 0;
1388                                         if(module.plugin && module.plugin.isCombo){
1389                                                 // a combo plugin; therefore, must be handled by combo service
1390                                                 // the prid should have already been converted to a URL (if required by the plugin) during
1391                                                 // the normalze process; in any event, there is no way for the loader to know how to
1392                                                 // to the conversion; therefore the third argument is zero
1393                                                 req.combo.add(module.plugin.mid, module.prid, 0, req);
1394                                                 viaCombo = 1;
1395                                         }else if(!module.plugin){
1396                                                 viaCombo = req.combo.add(0, module.mid, module.url, req);
1397                                         }
1398                                         if(viaCombo){
1399                                                 comboPending= 1;
1400                                                 return;
1401                                         }
1402                                 }
1403
1404                                 if(module.plugin){
1405                                         injectPlugin(module);
1406                                         return;
1407                                 } // else a normal module (not a plugin)
1408
1409
1410                                 var onLoadCallback = function(){
1411                                         runDefQ(module);
1412                                         if(module.injected !== arrived){
1413                                                 // the script that contained the module arrived and has been executed yet
1414                                                 // nothing was added to the defQ (so it wasn't an AMD module) and the module
1415                                                 // wasn't marked as arrived by dojo.provide (so it wasn't a v1.6- module);
1416                                                 // therefore, it must not have been a module; adjust state accordingly
1417                                                 setArrived(module);
1418                                                 mix(module, nonModuleProps);
1419                                                 req.trace("loader-define-nonmodule", [module.url]);
1420                                         }
1421
1422                                         if( 1  && legacyMode){
1423                                                 // must call checkComplete even in for sync loader because we may be in xdomainLoading mode;
1424                                                 // but, if xd loading, then don't call checkComplete until out of the current sync traversal
1425                                                 // in order to preserve order of execution of the dojo.required modules
1426                                                 !syncExecStack.length && checkComplete();
1427                                         }else{
1428                                                 checkComplete();
1429                                         }
1430                                 };
1431                                 cached = cache[mid] || cache[urlKeyPrefix + module.url];
1432                                 if(cached){
1433                                         req.trace("loader-inject", ["cache", module.mid, url]);
1434                                         evalModuleText(cached, module);
1435                                         onLoadCallback();
1436                                         return;
1437                                 }
1438                                 if( 1  && legacyMode){
1439                                         if(module.isXd){
1440                                                 // switch to async mode temporarily; if current legacyMode!=sync, then is must be one of {legacyAsync, xd, false}
1441                                                 legacyMode==sync && (legacyMode = xd);
1442                                                 // fall through and load via script injection
1443                                         }else if(module.isAmd && legacyMode!=sync){
1444                                                 // fall through and load via script injection
1445                                         }else{
1446                                                 // mode may be sync, xd/legacyAsync, or async; module may be AMD or legacy; but module is always located on the same domain
1447                                                 var xhrCallback = function(text){
1448                                                         if(legacyMode==sync){
1449                                                                 // the top of syncExecStack gives the current synchronously executing module; the loader needs
1450                                                                 // to know this if it has to switch to async loading in the middle of evaluating a legacy module
1451                                                                 // this happens when a modules dojo.require's a module that must be loaded async because it's xdomain
1452                                                                 // (using unshift/shift because there is no back() methods for Javascript arrays)
1453                                                                 syncExecStack.unshift(module);
1454                                                                 evalModuleText(text, module);
1455                                                                 syncExecStack.shift();
1456
1457                                                                 // maybe the module was an AMD module
1458                                                                 runDefQ(module);
1459
1460                                                                 // legacy modules never get to defineModule() => cjs and injected never set; also evaluation implies executing
1461                                                                 if(!module.cjs){
1462                                                                         setArrived(module);
1463                                                                         finishExec(module);
1464                                                                 }
1465
1466                                                                 if(module.finish){
1467                                                                         // while synchronously evaluating this module, dojo.require was applied referencing a module
1468                                                                         // that had to be loaded async; therefore, the loader stopped answering all dojo.require
1469                                                                         // requests so they could be answered completely in the correct sequence; module.finish gives
1470                                                                         // the list of dojo.requires that must be re-applied once all target modules are available;
1471                                                                         // make a synthetic module to execute the dojo.require's in the correct order
1472
1473                                                                         // compute a guarnateed-unique mid for the synthetic finish module; remember the finish vector; remove it from the reference module
1474                                                                         // TODO: can we just leave the module.finish...what's it hurting?
1475                                                                         var finishMid = mid + "*finish",
1476                                                                                 finish = module.finish;
1477                                                                         delete module.finish;
1478
1479                                                                         def(finishMid, ["dojo", ("dojo/require!" + finish.join(",")).replace(/\./g, "/")], function(dojo){
1480                                                                                 forEach(finish, function(mid){ dojo.require(mid); });
1481                                                                         });
1482                                                                         // unshift, not push, which causes the current traversal to be reattempted from the top
1483                                                                         execQ.unshift(getModule(finishMid));
1484                                                                 }
1485                                                                 onLoadCallback();
1486                                                         }else{
1487                                                                 text = transformToAmd(module, text);
1488                                                                 if(text){
1489                                                                         evalModuleText(text, module);
1490                                                                         onLoadCallback();
1491                                                                 }else{
1492                                                                         // if transformToAmd returned falsy, then the module was already AMD and it can be script-injected
1493                                                                         // do so to improve debugability(even though it means another download...which probably won't happen with a good browser cache)
1494                                                                         injectingModule = module;
1495                                                                         req.injectUrl(fixupUrl(url), onLoadCallback, module);
1496                                                                         injectingModule = 0;
1497                                                                 }
1498                                                         }
1499                                                 };
1500
1501                                                 req.trace("loader-inject", ["xhr", module.mid, url, legacyMode!=sync]);
1502                                                 if(has("config-dojo-loader-catches")){
1503                                                         try{
1504                                                                 req.getText(url, legacyMode!=sync, xhrCallback);
1505                                                         }catch(e){
1506                                                                 signal(error, makeError("xhrInjectFailed", [module, e]));
1507                                                         }
1508                                                 }else{
1509                                                         req.getText(url, legacyMode!=sync, xhrCallback);
1510                                                 }
1511                                                 return;
1512                                         }
1513                                 } // else async mode or fell through in xdomain loading mode; either way, load by script injection
1514                                 req.trace("loader-inject", ["script", module.mid, url]);
1515                                 injectingModule = module;
1516                                 req.injectUrl(fixupUrl(url), onLoadCallback, module);
1517                                 injectingModule = 0;
1518                         },
1519
1520                         defineModule = function(module, deps, def){
1521                                 req.trace("loader-define-module", [module.mid, deps]);
1522
1523                                 if( 0  && module.plugin && module.plugin.isCombo){
1524                                         // the module is a plugin resource loaded by the combo service
1525                                         // note: check for module.plugin should be enough since normal plugin resources should
1526                                         // not follow this path; module.plugin.isCombo is future-proofing belt and suspenders
1527                                         module.result = isFunction(def) ? def() : def;
1528                                         setArrived(module);
1529                                         finishExec(module);
1530                                         return module;
1531                                 };
1532
1533                                 var mid = module.mid;
1534                                 if(module.injected === arrived){
1535                                         signal(error, makeError("multipleDefine", module));
1536                                         return module;
1537                                 }
1538                                 mix(module, {
1539                                         deps: deps,
1540                                         def: def,
1541                                         cjs: {
1542                                                 id: module.mid,
1543                                                 uri: module.url,
1544                                                 exports: (module.result = {}),
1545                                                 setExports: function(exports){
1546                                                         module.cjs.exports = exports;
1547                                                 },
1548                                                 config:function(){
1549                                                         return module.config;
1550                                                 }
1551                                         }
1552                                 });
1553
1554                                 // resolve deps with respect to this module
1555                                 for(var i = 0; i < deps.length; i++){
1556                                         deps[i] = getModule(deps[i], module);
1557                                 }
1558
1559                                 if( 1  && legacyMode && !waiting[mid]){
1560                                         // the module showed up without being asked for; it was probably in a <script> element
1561                                         injectDependencies(module);
1562                                         execQ.push(module);
1563                                         checkComplete();
1564                                 }
1565                                 setArrived(module);
1566
1567                                 if(!isFunction(def) && !deps.length){
1568                                         module.result = def;
1569                                         finishExec(module);
1570                                 }
1571
1572                                 return module;
1573                         },
1574
1575                         runDefQ = function(referenceModule, mids){
1576                                 // defQ is an array of [id, dependencies, factory]
1577                                 // mids (if any) is a vector of mids given by a combo service
1578                                 var definedModules = [],
1579                                         module, args;
1580                                 while(defQ.length){
1581                                         args = defQ.shift();
1582                                         mids && (args[0]= mids.shift());
1583                                         // explicit define indicates possible multiple modules in a single file; delay injecting dependencies until defQ fully
1584                                         // processed since modules earlier in the queue depend on already-arrived modules that are later in the queue
1585                                         // TODO: what if no args[0] and no referenceModule
1586                                         module = (args[0] && getModule(args[0])) || referenceModule;
1587                                         definedModules.push([module, args[1], args[2]]);
1588                                 }
1589                                 consumePendingCacheInsert(referenceModule);
1590                                 forEach(definedModules, function(args){
1591                                         injectDependencies(defineModule.apply(null, args));
1592                                 });
1593                         };
1594         }
1595
1596         var timerId = 0,
1597                 clearTimer = noop,
1598                 startTimer = noop;
1599         if( 1 ){
1600                 // Timer machinery that monitors how long the loader is waiting and signals an error when the timer runs out.
1601                 clearTimer = function(){
1602                         timerId && clearTimeout(timerId);
1603                         timerId = 0;
1604                 },
1605
1606                 startTimer = function(){
1607                         clearTimer();
1608                         if(req.waitms){
1609                                 timerId = window.setTimeout(function(){
1610                                         clearTimer();
1611                                         signal(error, makeError("timeout", waiting));
1612                                 }, req.waitms);
1613                         }
1614                 };
1615         }
1616
1617         if( 1 ){
1618                 // the typically unnecessary !! in front of doc.attachEvent is due to an opera bug; see #15096
1619                 has.add("ie-event-behavior", !!doc.attachEvent && (typeof opera === "undefined" || opera.toString() != "[object Opera]"));
1620         }
1621
1622         if( 1  && ( 1  ||  1 )){
1623                 var domOn = function(node, eventName, ieEventName, handler){
1624                                 // Add an event listener to a DOM node using the API appropriate for the current browser;
1625                                 // return a function that will disconnect the listener.
1626                                 if(!has("ie-event-behavior")){
1627                                         node.addEventListener(eventName, handler, false);
1628                                         return function(){
1629                                                 node.removeEventListener(eventName, handler, false);
1630                                         };
1631                                 }else{
1632                                         node.attachEvent(ieEventName, handler);
1633                                         return function(){
1634                                                 node.detachEvent(ieEventName, handler);
1635                                         };
1636                                 }
1637                         },
1638                         windowOnLoadListener = domOn(window, "load", "onload", function(){
1639                                 req.pageLoaded = 1;
1640                                 doc.readyState!="complete" && (doc.readyState = "complete");
1641                                 windowOnLoadListener();
1642                         });
1643
1644                 if( 1 ){
1645                         // if the loader is on the page, there must be at least one script element
1646                         // getting its parent and then doing insertBefore solves the "Operation Aborted"
1647                         // error in IE from appending to a node that isn't properly closed; see
1648                         // dojo/tests/_base/loader/requirejs/simple-badbase.html for an example
1649                         var sibling = doc.getElementsByTagName("script")[0],
1650                                 insertPoint= sibling.parentNode;
1651                         req.injectUrl = function(url, callback, owner){
1652                                 // insert a script element to the insert-point element with src=url;
1653                                 // apply callback upon detecting the script has loaded.
1654
1655                                 var node = owner.node = doc.createElement("script"),
1656                                         onLoad = function(e){
1657                                                 e = e || window.event;
1658                                                 var node = e.target || e.srcElement;
1659                                                 if(e.type === "load" || /complete|loaded/.test(node.readyState)){
1660                                                         loadDisconnector();
1661                                                         errorDisconnector();
1662                                                         callback && callback();
1663                                                 }
1664                                         },
1665                                         loadDisconnector = domOn(node, "load", "onreadystatechange", onLoad),
1666                                         errorDisconnector = domOn(node, "error", "onerror", function(e){
1667                                                 loadDisconnector();
1668                                                 errorDisconnector();
1669                                                 signal(error, makeError("scriptError", [url, e]));
1670                                         });
1671
1672                                 node.type = "text/javascript";
1673                                 node.charset = "utf-8";
1674                                 node.src = url;
1675                                 insertPoint.insertBefore(node, sibling);
1676                                 return node;
1677                         };
1678                 }
1679         }
1680
1681         if( 1 ){
1682                 req.log = function(){
1683                         try{
1684                                 for(var i = 0; i < arguments.length; i++){
1685                                         console.log(arguments[i]);
1686                                 }
1687                         }catch(e){}
1688                 };
1689         }else{
1690                 req.log = noop;
1691         }
1692
1693         if( 0 ){
1694                 var trace = req.trace = function(
1695                         group,  // the trace group to which this application belongs
1696                         args    // the contents of the trace
1697                 ){
1698                         ///
1699                         // Tracing interface by group.
1700                         //
1701                         // Sends the contents of args to the console iff (req.trace.on && req.trace[group])
1702
1703                         if(trace.on && trace.group[group]){
1704                                 signal("trace", [group, args]);
1705                                 for(var arg, dump = [], text= "trace:" + group + (args.length ? (":" + args[0]) : ""), i= 1; i<args.length;){
1706                                         arg = args[i++];
1707                                         if(isString(arg)){
1708                                                 text += ", " + arg;
1709                                         }else{
1710                                                 dump.push(arg);
1711                                         }
1712                                 }
1713                                 req.log(text);
1714                                 dump.length && dump.push(".");
1715                                 req.log.apply(req, dump);
1716                         }
1717                 };
1718                 mix(trace, {
1719                         on:1,
1720                         group:{},
1721                         set:function(group, value){
1722                                 if(isString(group)){
1723                                         trace.group[group]= value;
1724                                 }else{
1725                                         mix(trace.group, group);
1726                                 }
1727                         }
1728                 });
1729                 trace.set(mix(mix(mix({}, defaultConfig.trace), userConfig.trace), dojoSniffConfig.trace));
1730                 on("config", function(config){
1731                         config.trace && trace.set(config.trace);
1732                 });
1733         }else{
1734                 req.trace = noop;
1735         }
1736
1737         var def = function(
1738                 mid,              //(commonjs.moduleId, optional) list of modules to be loaded before running factory
1739                 dependencies, //(array of commonjs.moduleId, optional)
1740                 factory           //(any)
1741         ){
1742                 ///
1743                 // Advises the loader of a module factory. //Implements http://wiki.commonjs.org/wiki/Modules/AsynchronousDefinition.
1744                 ///
1745                 //note
1746                 // CommonJS factory scan courtesy of http://requirejs.org
1747
1748                 var arity = arguments.length,
1749                         defaultDeps = ["require", "exports", "module"],
1750                         // the predominate signature...
1751                         args = [0, mid, dependencies];
1752                 if(arity==1){
1753                         args = [0, (isFunction(mid) ? defaultDeps : []), mid];
1754                 }else if(arity==2 && isString(mid)){
1755                         args = [mid, (isFunction(dependencies) ? defaultDeps : []), dependencies];
1756                 }else if(arity==3){
1757                         args = [mid, dependencies, factory];
1758                 }
1759
1760                 if( 0  && args[1]===defaultDeps){
1761                         args[2].toString()
1762                                 .replace(/(\/\*([\s\S]*?)\*\/|\/\/(.*)$)/mg, "")
1763                                 .replace(/require\(["']([\w\!\-_\.\/]+)["']\)/g, function(match, dep){
1764                                 args[1].push(dep);
1765                         });
1766                 }
1767
1768                 req.trace("loader-define", args.slice(0, 2));
1769                 var targetModule = args[0] && getModule(args[0]),
1770                         module;
1771                 if(targetModule && !waiting[targetModule.mid]){
1772                         // given a mid that hasn't been requested; therefore, defined through means other than injecting
1773                         // consequent to a require() or define() application; examples include defining modules on-the-fly
1774                         // due to some code path or including a module in a script element. In any case,
1775                         // there is no callback waiting to finish processing and nothing to trigger the defQ and the
1776                         // dependencies are never requested; therefore, do it here.
1777                         injectDependencies(defineModule(targetModule, args[1], args[2]));
1778                 }else if(!has("ie-event-behavior") || ! 1  || injectingCachedModule){
1779                         // not IE path: anonymous module and therefore must have been injected; therefore, onLoad will fire immediately
1780                         // after script finishes being evaluated and the defQ can be run from that callback to detect the module id
1781                         defQ.push(args);
1782                 }else{
1783                         // IE path: possibly anonymous module and therefore injected; therefore, cannot depend on 1-to-1,
1784                         // in-order exec of onLoad with script eval (since it's IE) and must manually detect here
1785                         targetModule = targetModule || injectingModule;
1786                         if(!targetModule){
1787                                 for(mid in waiting){
1788                                         module = modules[mid];
1789                                         if(module && module.node && module.node.readyState === 'interactive'){
1790                                                 targetModule = module;
1791                                                 break;
1792                                         }
1793                                 }
1794                                 if( 0  && !targetModule){
1795                                         for(var i = 0; i<combosPending.length; i++){
1796                                                 targetModule = combosPending[i];
1797                                                 if(targetModule.node && targetModule.node.readyState === 'interactive'){
1798                                                         break;
1799                                                 }
1800                                                 targetModule= 0;
1801                                         }
1802                                 }
1803                         }
1804                         if( 0  && isArray(targetModule)){
1805                                 injectDependencies(defineModule(getModule(targetModule.shift()), args[1], args[2]));
1806                                 if(!targetModule.length){
1807                                         combosPending.splice(i, 1);
1808                                 }
1809                         }else if(targetModule){
1810                                 consumePendingCacheInsert(targetModule);
1811                                 injectDependencies(defineModule(targetModule, args[1], args[2]));
1812                         }else{
1813                                 signal(error, makeError("ieDefineFailed", args[0]));
1814                         }
1815                         checkComplete();
1816                 }
1817         };
1818         def.amd = {
1819                 vendor:"dojotoolkit.org"
1820         };
1821
1822         if( 0 ){
1823                 req.def = def;
1824         }
1825
1826         // allow config to override default implemention of named functions; this is useful for
1827         // non-browser environments, e.g., overriding injectUrl, getText, log, etc. in node.js, Rhino, etc.
1828         // also useful for testing and monkey patching loader
1829         mix(mix(req, defaultConfig.loaderPatch), userConfig.loaderPatch);
1830
1831         // now that req is fully initialized and won't change, we can hook it up to the error signal
1832         on(error, function(arg){
1833                 try{
1834                         console.error(arg);
1835                         if(arg instanceof Error){
1836                                 for(var p in arg){
1837                                         console.log(p + ":", arg[p]);
1838                                 }
1839                                 console.log(".");
1840                         }
1841                 }catch(e){}
1842         });
1843
1844         // always publish these
1845         mix(req, {
1846                 uid:uid,
1847                 cache:cache,
1848                 packs:packs
1849         });
1850
1851
1852         if( 0 ){
1853                 mix(req, {
1854                         // these may be interesting to look at when debugging
1855                         paths:paths,
1856                         aliases:aliases,
1857                         modules:modules,
1858                         legacyMode:legacyMode,
1859                         execQ:execQ,
1860                         defQ:defQ,
1861                         waiting:waiting,
1862
1863                         // these are used for testing
1864                         // TODO: move testing infrastructure to a different has feature
1865                         packs:packs,
1866                         mapProgs:mapProgs,
1867                         pathsMapProg:pathsMapProg,
1868                         listenerQueues:listenerQueues,
1869
1870                         // these are used by the builder (at least)
1871                         computeMapProg:computeMapProg,
1872                         runMapProg:runMapProg,
1873                         compactPath:compactPath,
1874                         getModuleInfo:getModuleInfo_
1875                 });
1876         }
1877
1878         // the loader can be defined exactly once; look for global define which is the symbol AMD loaders are
1879         // *required* to define (as opposed to require, which is optional)
1880         if(global.define){
1881                 if( 1 ){
1882                         signal(error, makeError("defineAlreadyDefined", 0));
1883                 }
1884                 return;
1885         }else{
1886                 global.define = def;
1887                 global.require = req;
1888                 if( 0 ){
1889                         require= req;
1890                 }
1891         }
1892
1893         if( 0  && req.combo && req.combo.plugins){
1894                 var plugins = req.combo.plugins,
1895                         pluginName;
1896                 for(pluginName in plugins){
1897                         mix(mix(getModule(pluginName), plugins[pluginName]), {isCombo:1, executed:"executed", load:1});
1898                 }
1899         }
1900
1901         if( 1 ){
1902                 forEach(delayedModuleConfig, function(c){ config(c); });
1903                 var bootDeps = dojoSniffConfig.deps ||  userConfig.deps || defaultConfig.deps,
1904                         bootCallback = dojoSniffConfig.callback || userConfig.callback || defaultConfig.callback;
1905                 req.boot = (bootDeps || bootCallback) ? [bootDeps || [], bootCallback] : 0;
1906         }
1907         if(! 1 ){
1908                 !req.async && req(["dojo"]);
1909                 req.boot && req.apply(null, req.boot);
1910         }
1911 })
1912 (this.dojoConfig || this.djConfig || this.require || {}, {
1913                 async:0,
1914                 hasCache:{
1915                                 'config-selectorEngine':"acme",
1916                                 'config-tlmSiblingOfDojo':1,
1917                                 'dojo-built':1,
1918                                 'dojo-loader':1,
1919                                 dom:1,
1920                                 'host-browser':1
1921                 },
1922                 packages:[
1923                                 {
1924                                          location:"../dijit",
1925                                          name:"dijit"
1926                                 },
1927                                 {
1928                                          location:".",
1929                                          name:"dojo"
1930                                 }
1931                 ]
1932 });require({cache:{
1933 'dojo/_base/fx':function(){
1934 define(["./kernel", "./config", /*===== "./declare", =====*/ "./lang", "../Evented", "./Color", "./connect", "./sniff", "../dom", "../dom-style"],
1935         function(dojo, config, /*===== declare, =====*/ lang, Evented, Color, connect, has, dom, style){
1936         // module:
1937         //              dojo/_base/fx
1938         // notes:
1939         //              Animation loosely package based on Dan Pupius' work, contributed under CLA; see
1940         //              http://pupius.co.uk/js/Toolkit.Drawing.js
1941
1942         var _mixin = lang.mixin;
1943
1944         // Module export
1945         var basefx = {
1946                 // summary:
1947                 //              This module defines the base dojo/_base/fx implementation.
1948         };
1949
1950         var _Line = basefx._Line = function(/*int*/ start, /*int*/ end){
1951                 // summary:
1952                 //              Object used to generate values from a start value to an end value
1953                 // start: int
1954                 //              Beginning value for range
1955                 // end: int
1956                 //              Ending value for range
1957                 this.start = start;
1958                 this.end = end;
1959         };
1960
1961         _Line.prototype.getValue = function(/*float*/ n){
1962                 // summary:
1963                 //              Returns the point on the line
1964                 // n:
1965                 //              a floating point number greater than 0 and less than 1
1966                 return ((this.end - this.start) * n) + this.start; // Decimal
1967         };
1968
1969         var Animation = basefx.Animation = function(args){
1970                 // summary:
1971                 //              A generic animation class that fires callbacks into its handlers
1972                 //              object at various states.
1973                 // description:
1974                 //              A generic animation class that fires callbacks into its handlers
1975                 //              object at various states. Nearly all dojo animation functions
1976                 //              return an instance of this method, usually without calling the
1977                 //              .play() method beforehand. Therefore, you will likely need to
1978                 //              call .play() on instances of `Animation` when one is
1979                 //              returned.
1980                 // args: Object
1981                 //              The 'magic argument', mixing all the properties into this
1982                 //              animation instance.
1983
1984                 _mixin(this, args);
1985                 if(lang.isArray(this.curve)){
1986                         this.curve = new _Line(this.curve[0], this.curve[1]);
1987                 }
1988
1989         };
1990         Animation.prototype = new Evented();
1991
1992         lang.extend(Animation, {
1993                 // duration: Integer
1994                 //              The time in milliseconds the animation will take to run
1995                 duration: 350,
1996
1997         /*=====
1998                 // curve: _Line|Array
1999                 //              A two element array of start and end values, or a `_Line` instance to be
2000                 //              used in the Animation.
2001                 curve: null,
2002
2003                 // easing: Function?
2004                 //              A Function to adjust the acceleration (or deceleration) of the progress
2005                 //              across a _Line
2006                 easing: null,
2007         =====*/
2008
2009                 // repeat: Integer?
2010                 //              The number of times to loop the animation
2011                 repeat: 0,
2012
2013                 // rate: Integer?
2014                 //              the time in milliseconds to wait before advancing to next frame
2015                 //              (used as a fps timer: 1000/rate = fps)
2016                 rate: 20 /* 50 fps */,
2017
2018         /*=====
2019                 // delay: Integer?
2020                 //              The time in milliseconds to wait before starting animation after it
2021                 //              has been .play()'ed
2022                 delay: null,
2023
2024                 // beforeBegin: Event?
2025                 //              Synthetic event fired before a Animation begins playing (synchronous)
2026                 beforeBegin: null,
2027
2028                 // onBegin: Event?
2029                 //              Synthetic event fired as a Animation begins playing (useful?)
2030                 onBegin: null,
2031
2032                 // onAnimate: Event?
2033                 //              Synthetic event fired at each interval of the Animation
2034                 onAnimate: null,
2035
2036                 // onEnd: Event?
2037                 //              Synthetic event fired after the final frame of the Animation
2038                 onEnd: null,
2039
2040                 // onPlay: Event?
2041                 //              Synthetic event fired any time the Animation is play()'ed
2042                 onPlay: null,
2043
2044                 // onPause: Event?
2045                 //              Synthetic event fired when the Animation is paused
2046                 onPause: null,
2047
2048                 // onStop: Event
2049                 //              Synthetic event fires when the Animation is stopped
2050                 onStop: null,
2051
2052         =====*/
2053
2054                 _percent: 0,
2055                 _startRepeatCount: 0,
2056
2057                 _getStep: function(){
2058                         var _p = this._percent,
2059                                 _e = this.easing
2060                         ;
2061                         return _e ? _e(_p) : _p;
2062                 },
2063                 _fire: function(/*Event*/ evt, /*Array?*/ args){
2064                         // summary:
2065                         //              Convenience function.  Fire event "evt" and pass it the
2066                         //              arguments specified in "args".
2067                         // description:
2068                         //              Convenience function.  Fire event "evt" and pass it the
2069                         //              arguments specified in "args".
2070                         //              Fires the callback in the scope of this Animation
2071                         //              instance.
2072                         // evt:
2073                         //              The event to fire.
2074                         // args:
2075                         //              The arguments to pass to the event.
2076                         var a = args||[];
2077                         if(this[evt]){
2078                                 if(config.debugAtAllCosts){
2079                                         this[evt].apply(this, a);
2080                                 }else{
2081                                         try{
2082                                                 this[evt].apply(this, a);
2083                                         }catch(e){
2084                                                 // squelch and log because we shouldn't allow exceptions in
2085                                                 // synthetic event handlers to cause the internal timer to run
2086                                                 // amuck, potentially pegging the CPU. I'm not a fan of this
2087                                                 // squelch, but hopefully logging will make it clear what's
2088                                                 // going on
2089                                                 console.error("exception in animation handler for:", evt);
2090                                                 console.error(e);
2091                                         }
2092                                 }
2093                         }
2094                         return this; // Animation
2095                 },
2096
2097                 play: function(/*int?*/ delay, /*Boolean?*/ gotoStart){
2098                         // summary:
2099                         //              Start the animation.
2100                         // delay:
2101                         //              How many milliseconds to delay before starting.
2102                         // gotoStart:
2103                         //              If true, starts the animation from the beginning; otherwise,
2104                         //              starts it from its current position.
2105                         // returns: Animation
2106                         //              The instance to allow chaining.
2107
2108                         var _t = this;
2109                         if(_t._delayTimer){ _t._clearTimer(); }
2110                         if(gotoStart){
2111                                 _t._stopTimer();
2112                                 _t._active = _t._paused = false;
2113                                 _t._percent = 0;
2114                         }else if(_t._active && !_t._paused){
2115                                 return _t;
2116                         }
2117
2118                         _t._fire("beforeBegin", [_t.node]);
2119
2120                         var de = delay || _t.delay,
2121                                 _p = lang.hitch(_t, "_play", gotoStart);
2122
2123                         if(de > 0){
2124                                 _t._delayTimer = setTimeout(_p, de);
2125                                 return _t;
2126                         }
2127                         _p();
2128                         return _t;      // Animation
2129                 },
2130
2131                 _play: function(gotoStart){
2132                         var _t = this;
2133                         if(_t._delayTimer){ _t._clearTimer(); }
2134                         _t._startTime = new Date().valueOf();
2135                         if(_t._paused){
2136                                 _t._startTime -= _t.duration * _t._percent;
2137                         }
2138
2139                         _t._active = true;
2140                         _t._paused = false;
2141                         var value = _t.curve.getValue(_t._getStep());
2142                         if(!_t._percent){
2143                                 if(!_t._startRepeatCount){
2144                                         _t._startRepeatCount = _t.repeat;
2145                                 }
2146                                 _t._fire("onBegin", [value]);
2147                         }
2148
2149                         _t._fire("onPlay", [value]);
2150
2151                         _t._cycle();
2152                         return _t; // Animation
2153                 },
2154
2155                 pause: function(){
2156                         // summary:
2157                         //              Pauses a running animation.
2158                         var _t = this;
2159                         if(_t._delayTimer){ _t._clearTimer(); }
2160                         _t._stopTimer();
2161                         if(!_t._active){ return _t; /*Animation*/ }
2162                         _t._paused = true;
2163                         _t._fire("onPause", [_t.curve.getValue(_t._getStep())]);
2164                         return _t; // Animation
2165                 },
2166
2167                 gotoPercent: function(/*Decimal*/ percent, /*Boolean?*/ andPlay){
2168                         // summary:
2169                         //              Sets the progress of the animation.
2170                         // percent:
2171                         //              A percentage in decimal notation (between and including 0.0 and 1.0).
2172                         // andPlay:
2173                         //              If true, play the animation after setting the progress.
2174                         var _t = this;
2175                         _t._stopTimer();
2176                         _t._active = _t._paused = true;
2177                         _t._percent = percent;
2178                         if(andPlay){ _t.play(); }
2179                         return _t; // Animation
2180                 },
2181
2182                 stop: function(/*boolean?*/ gotoEnd){
2183                         // summary:
2184                         //              Stops a running animation.
2185                         // gotoEnd:
2186                         //              If true, the animation will end.
2187                         var _t = this;
2188                         if(_t._delayTimer){ _t._clearTimer(); }
2189                         if(!_t._timer){ return _t; /* Animation */ }
2190                         _t._stopTimer();
2191                         if(gotoEnd){
2192                                 _t._percent = 1;
2193                         }
2194                         _t._fire("onStop", [_t.curve.getValue(_t._getStep())]);
2195                         _t._active = _t._paused = false;
2196                         return _t; // Animation
2197                 },
2198
2199                 status: function(){
2200                         // summary:
2201                         //              Returns a string token representation of the status of
2202                         //              the animation, one of: "paused", "playing", "stopped"
2203                         if(this._active){
2204                                 return this._paused ? "paused" : "playing"; // String
2205                         }
2206                         return "stopped"; // String
2207                 },
2208
2209                 _cycle: function(){
2210                         var _t = this;
2211                         if(_t._active){
2212                                 var curr = new Date().valueOf();
2213                                 // Allow durations of 0 (instant) by setting step to 1 - see #13798
2214                                 var step = _t.duration === 0 ? 1 : (curr - _t._startTime) / (_t.duration);
2215
2216                                 if(step >= 1){
2217                                         step = 1;
2218                                 }
2219                                 _t._percent = step;
2220
2221                                 // Perform easing
2222                                 if(_t.easing){
2223                                         step = _t.easing(step);
2224                                 }
2225
2226                                 _t._fire("onAnimate", [_t.curve.getValue(step)]);
2227
2228                                 if(_t._percent < 1){
2229                                         _t._startTimer();
2230                                 }else{
2231                                         _t._active = false;
2232
2233                                         if(_t.repeat > 0){
2234                                                 _t.repeat--;
2235                                                 _t.play(null, true);
2236                                         }else if(_t.repeat == -1){
2237                                                 _t.play(null, true);
2238                                         }else{
2239                                                 if(_t._startRepeatCount){
2240                                                         _t.repeat = _t._startRepeatCount;
2241                                                         _t._startRepeatCount = 0;
2242                                                 }
2243                                         }
2244                                         _t._percent = 0;
2245                                         _t._fire("onEnd", [_t.node]);
2246                                         !_t.repeat && _t._stopTimer();
2247                                 }
2248                         }
2249                         return _t; // Animation
2250                 },
2251
2252                 _clearTimer: function(){
2253                         // summary:
2254                         //              Clear the play delay timer
2255                         clearTimeout(this._delayTimer);
2256                         delete this._delayTimer;
2257                 }
2258
2259         });
2260
2261         // the local timer, stubbed into all Animation instances
2262         var ctr = 0,
2263                 timer = null,
2264                 runner = {
2265                         run: function(){}
2266                 };
2267
2268         lang.extend(Animation, {
2269
2270                 _startTimer: function(){
2271                         if(!this._timer){
2272                                 this._timer = connect.connect(runner, "run", this, "_cycle");
2273                                 ctr++;
2274                         }
2275                         if(!timer){
2276                                 timer = setInterval(lang.hitch(runner, "run"), this.rate);
2277                         }
2278                 },
2279
2280                 _stopTimer: function(){
2281                         if(this._timer){
2282                                 connect.disconnect(this._timer);
2283                                 this._timer = null;
2284                                 ctr--;
2285                         }
2286                         if(ctr <= 0){
2287                                 clearInterval(timer);
2288                                 timer = null;
2289                                 ctr = 0;
2290                         }
2291                 }
2292
2293         });
2294
2295         var _makeFadeable =
2296                 has("ie") ? function(node){
2297                         // only set the zoom if the "tickle" value would be the same as the
2298                         // default
2299                         var ns = node.style;
2300                         // don't set the width to auto if it didn't already cascade that way.
2301                         // We don't want to f anyones designs
2302                         if(!ns.width.length && style.get(node, "width") == "auto"){
2303                                 ns.width = "auto";
2304                         }
2305                 } :
2306                 function(){};
2307
2308         basefx._fade = function(/*Object*/ args){
2309                 // summary:
2310                 //              Returns an animation that will fade the node defined by
2311                 //              args.node from the start to end values passed (args.start
2312                 //              args.end) (end is mandatory, start is optional)
2313
2314                 args.node = dom.byId(args.node);
2315                 var fArgs = _mixin({ properties: {} }, args),
2316                         props = (fArgs.properties.opacity = {});
2317
2318                 props.start = !("start" in fArgs) ?
2319                         function(){
2320                                 return +style.get(fArgs.node, "opacity")||0;
2321                         } : fArgs.start;
2322                 props.end = fArgs.end;
2323
2324                 var anim = basefx.animateProperty(fArgs);
2325                 connect.connect(anim, "beforeBegin", lang.partial(_makeFadeable, fArgs.node));
2326
2327                 return anim; // Animation
2328         };
2329
2330         /*=====
2331         var __FadeArgs = declare(null, {
2332                 // node: DOMNode|String
2333                 //              The node referenced in the animation
2334                 // duration: Integer?
2335                 //              Duration of the animation in milliseconds.
2336                 // easing: Function?
2337                 //              An easing function.
2338         });
2339         =====*/
2340
2341         basefx.fadeIn = function(/*__FadeArgs*/ args){
2342                 // summary:
2343                 //              Returns an animation that will fade node defined in 'args' from
2344                 //              its current opacity to fully opaque.
2345                 return basefx._fade(_mixin({ end: 1 }, args)); // Animation
2346         };
2347
2348         basefx.fadeOut = function(/*__FadeArgs*/ args){
2349                 // summary:
2350                 //              Returns an animation that will fade node defined in 'args'
2351                 //              from its current opacity to fully transparent.
2352                 return basefx._fade(_mixin({ end: 0 }, args)); // Animation
2353         };
2354
2355         basefx._defaultEasing = function(/*Decimal?*/ n){
2356                 // summary:
2357                 //              The default easing function for Animation(s)
2358                 return 0.5 + ((Math.sin((n + 1.5) * Math.PI)) / 2);     // Decimal
2359         };
2360
2361         var PropLine = function(properties){
2362                 // PropLine is an internal class which is used to model the values of
2363                 // an a group of CSS properties across an animation lifecycle. In
2364                 // particular, the "getValue" function handles getting interpolated
2365                 // values between start and end for a particular CSS value.
2366                 this._properties = properties;
2367                 for(var p in properties){
2368                         var prop = properties[p];
2369                         if(prop.start instanceof Color){
2370                                 // create a reusable temp color object to keep intermediate results
2371                                 prop.tempColor = new Color();
2372                         }
2373                 }
2374         };
2375
2376         PropLine.prototype.getValue = function(r){
2377                 var ret = {};
2378                 for(var p in this._properties){
2379                         var prop = this._properties[p],
2380                                 start = prop.start;
2381                         if(start instanceof Color){
2382                                 ret[p] = Color.blendColors(start, prop.end, r, prop.tempColor).toCss();
2383                         }else if(!lang.isArray(start)){
2384                                 ret[p] = ((prop.end - start) * r) + start + (p != "opacity" ? prop.units || "px" : 0);
2385                         }
2386                 }
2387                 return ret;
2388         };
2389
2390         /*=====
2391         var __AnimArgs = declare(__FadeArgs, {
2392                 // properties: Object?
2393                 //              A hash map of style properties to Objects describing the transition,
2394                 //              such as the properties of _Line with an additional 'units' property
2395                 properties: {}
2396
2397                 //TODOC: add event callbacks
2398         });
2399         =====*/
2400
2401         basefx.animateProperty = function(/*__AnimArgs*/ args){
2402                 // summary:
2403                 //              Returns an animation that will transition the properties of
2404                 //              node defined in `args` depending how they are defined in
2405                 //              `args.properties`
2406                 //
2407                 // description:
2408                 //              Foundation of most `dojo/_base/fx`
2409                 //              animations. It takes an object of "properties" corresponding to
2410                 //              style properties, and animates them in parallel over a set
2411                 //              duration.
2412                 //
2413                 // example:
2414                 //              A simple animation that changes the width of the specified node.
2415                 //      |       basefx.animateProperty({
2416                 //      |               node: "nodeId",
2417                 //      |               properties: { width: 400 },
2418                 //      |       }).play();
2419                 //              Dojo figures out the start value for the width and converts the
2420                 //              integer specified for the width to the more expressive but
2421                 //              verbose form `{ width: { end: '400', units: 'px' } }` which you
2422                 //              can also specify directly. Defaults to 'px' if omitted.
2423                 //
2424                 // example:
2425                 //              Animate width, height, and padding over 2 seconds... the
2426                 //              pedantic way:
2427                 //      |       basefx.animateProperty({ node: node, duration:2000,
2428                 //      |               properties: {
2429                 //      |                       width: { start: '200', end: '400', units:"px" },
2430                 //      |                       height: { start:'200', end: '400', units:"px" },
2431                 //      |                       paddingTop: { start:'5', end:'50', units:"px" }
2432                 //      |               }
2433                 //      |       }).play();
2434                 //              Note 'paddingTop' is used over 'padding-top'. Multi-name CSS properties
2435                 //              are written using "mixed case", as the hyphen is illegal as an object key.
2436                 //
2437                 // example:
2438                 //              Plug in a different easing function and register a callback for
2439                 //              when the animation ends. Easing functions accept values between
2440                 //              zero and one and return a value on that basis. In this case, an
2441                 //              exponential-in curve.
2442                 //      |       basefx.animateProperty({
2443                 //      |               node: "nodeId",
2444                 //      |               // dojo figures out the start value
2445                 //      |               properties: { width: { end: 400 } },
2446                 //      |               easing: function(n){
2447                 //      |                       return (n==0) ? 0 : Math.pow(2, 10 * (n - 1));
2448                 //      |               },
2449                 //      |               onEnd: function(node){
2450                 //      |                       // called when the animation finishes. The animation
2451                 //      |                       // target is passed to this function
2452                 //      |               }
2453                 //      |       }).play(500); // delay playing half a second
2454                 //
2455                 // example:
2456                 //              Like all `Animation`s, animateProperty returns a handle to the
2457                 //              Animation instance, which fires the events common to Dojo FX. Use `aspect.after`
2458                 //              to access these events outside of the Animation definition:
2459                 //      |       var anim = basefx.animateProperty({
2460                 //      |               node:"someId",
2461                 //      |               properties:{
2462                 //      |                       width:400, height:500
2463                 //      |               }
2464                 //      |       });
2465                 //      |       aspect.after(anim, "onEnd", function(){
2466                 //      |               console.log("animation ended");
2467                 //      |       }, true);
2468                 //      |       // play the animation now:
2469                 //      |       anim.play();
2470                 //
2471                 // example:
2472                 //              Each property can be a function whose return value is substituted along.
2473                 //              Additionally, each measurement (eg: start, end) can be a function. The node
2474                 //              reference is passed directly to callbacks.
2475                 //      |       basefx.animateProperty({
2476                 //      |               node:"mine",
2477                 //      |               properties:{
2478                 //      |                       height:function(node){
2479                 //      |                               // shrink this node by 50%
2480                 //      |                               return domGeom.position(node).h / 2
2481                 //      |                       },
2482                 //      |                       width:{
2483                 //      |                               start:function(node){ return 100; },
2484                 //      |                               end:function(node){ return 200; }
2485                 //      |                       }
2486                 //      |               }
2487                 //      |       }).play();
2488                 //
2489
2490                 var n = args.node = dom.byId(args.node);
2491                 if(!args.easing){ args.easing = dojo._defaultEasing; }
2492
2493                 var anim = new Animation(args);
2494                 connect.connect(anim, "beforeBegin", anim, function(){
2495                         var pm = {};
2496                         for(var p in this.properties){
2497                                 // Make shallow copy of properties into pm because we overwrite
2498                                 // some values below. In particular if start/end are functions
2499                                 // we don't want to overwrite them or the functions won't be
2500                                 // called if the animation is reused.
2501                                 if(p == "width" || p == "height"){
2502                                         this.node.display = "block";
2503                                 }
2504                                 var prop = this.properties[p];
2505                                 if(lang.isFunction(prop)){
2506                                         prop = prop(n);
2507                                 }
2508                                 prop = pm[p] = _mixin({}, (lang.isObject(prop) ? prop: { end: prop }));
2509
2510                                 if(lang.isFunction(prop.start)){
2511                                         prop.start = prop.start(n);
2512                                 }
2513                                 if(lang.isFunction(prop.end)){
2514                                         prop.end = prop.end(n);
2515                                 }
2516                                 var isColor = (p.toLowerCase().indexOf("color") >= 0);
2517                                 function getStyle(node, p){
2518                                         // domStyle.get(node, "height") can return "auto" or "" on IE; this is more reliable:
2519                                         var v = { height: node.offsetHeight, width: node.offsetWidth }[p];
2520                                         if(v !== undefined){ return v; }
2521                                         v = style.get(node, p);
2522                                         return (p == "opacity") ? +v : (isColor ? v : parseFloat(v));
2523                                 }
2524                                 if(!("end" in prop)){
2525                                         prop.end = getStyle(n, p);
2526                                 }else if(!("start" in prop)){
2527                                         prop.start = getStyle(n, p);
2528                                 }
2529
2530                                 if(isColor){
2531                                         prop.start = new Color(prop.start);
2532                                         prop.end = new Color(prop.end);
2533                                 }else{
2534                                         prop.start = (p == "opacity") ? +prop.start : parseFloat(prop.start);
2535                                 }
2536                         }
2537                         this.curve = new PropLine(pm);
2538                 });
2539                 connect.connect(anim, "onAnimate", lang.hitch(style, "set", anim.node));
2540                 return anim; // Animation
2541         };
2542
2543         basefx.anim = function( /*DOMNode|String*/      node,
2544                                                         /*Object*/                      properties,
2545                                                         /*Integer?*/            duration,
2546                                                         /*Function?*/           easing,
2547                                                         /*Function?*/           onEnd,
2548                                                         /*Integer?*/            delay){
2549                 // summary:
2550                 //              A simpler interface to `animateProperty()`, also returns
2551                 //              an instance of `Animation` but begins the animation
2552                 //              immediately, unlike nearly every other Dojo animation API.
2553                 // description:
2554                 //              Simpler (but somewhat less powerful) version
2555                 //              of `animateProperty`.  It uses defaults for many basic properties
2556                 //              and allows for positional parameters to be used in place of the
2557                 //              packed "property bag" which is used for other Dojo animation
2558                 //              methods.
2559                 //
2560                 //              The `Animation` object returned will be already playing, so
2561                 //              calling play() on it again is (usually) a no-op.
2562                 // node:
2563                 //              a DOM node or the id of a node to animate CSS properties on
2564                 // duration:
2565                 //              The number of milliseconds over which the animation
2566                 //              should run. Defaults to the global animation default duration
2567                 //              (350ms).
2568                 // easing:
2569                 //              An easing function over which to calculate acceleration
2570                 //              and deceleration of the animation through its duration.
2571                 //              A default easing algorithm is provided, but you may
2572                 //              plug in any you wish. A large selection of easing algorithms
2573                 //              are available in `dojo/fx/easing`.
2574                 // onEnd:
2575                 //              A function to be called when the animation finishes
2576                 //              running.
2577                 // delay:
2578                 //              The number of milliseconds to delay beginning the
2579                 //              animation by. The default is 0.
2580                 // example:
2581                 //              Fade out a node
2582                 //      |       basefx.anim("id", { opacity: 0 });
2583                 // example:
2584                 //              Fade out a node over a full second
2585                 //      |       basefx.anim("id", { opacity: 0 }, 1000);
2586                 return basefx.animateProperty({ // Animation
2587                         node: node,
2588                         duration: duration || Animation.prototype.duration,
2589                         properties: properties,
2590                         easing: easing,
2591                         onEnd: onEnd
2592                 }).play(delay || 0);
2593         };
2594
2595
2596         if( 1 ){
2597                 _mixin(dojo, basefx);
2598                 // Alias to drop come 2.0:
2599                 dojo._Animation = Animation;
2600         }
2601
2602         return basefx;
2603 });
2604
2605 },
2606 'dojo/dom-form':function(){
2607 define(["./_base/lang", "./dom", "./io-query", "./json"], function(lang, dom, ioq, json){
2608         // module:
2609         //              dojo/dom-form
2610
2611     function setValue(/*Object*/ obj, /*String*/ name, /*String*/ value){
2612         // summary:
2613         //              For the named property in object, set the value. If a value
2614         //              already exists and it is a string, convert the value to be an
2615         //              array of values.
2616
2617         // Skip it if there is no value
2618         if(value === null){
2619             return;
2620         }
2621
2622         var val = obj[name];
2623         if(typeof val == "string"){ // inline'd type check
2624             obj[name] = [val, value];
2625         }else if(lang.isArray(val)){
2626             val.push(value);
2627         }else{
2628             obj[name] = value;
2629         }
2630     }
2631
2632         var exclude = "file|submit|image|reset|button";
2633
2634         var form = {
2635                 // summary:
2636                 //              This module defines form-processing functions.
2637
2638                 fieldToObject: function fieldToObject(/*DOMNode|String*/ inputNode){
2639                         // summary:
2640                         //              Serialize a form field to a JavaScript object.
2641                         // description:
2642                         //              Returns the value encoded in a form field as
2643                         //              as a string or an array of strings. Disabled form elements
2644                         //              and unchecked radio and checkboxes are skipped. Multi-select
2645                         //              elements are returned as an array of string values.
2646                         // inputNode: DOMNode|String
2647                         // returns: Object
2648
2649                         var ret = null;
2650                         inputNode = dom.byId(inputNode);
2651                         if(inputNode){
2652                                 var _in = inputNode.name, type = (inputNode.type || "").toLowerCase();
2653                                 if(_in && type && !inputNode.disabled){
2654                                         if(type == "radio" || type == "checkbox"){
2655                                                 if(inputNode.checked){
2656                                                         ret = inputNode.value;
2657                                                 }
2658                                         }else if(inputNode.multiple){
2659                                                 ret = [];
2660                                                 var nodes = [inputNode.firstChild];
2661                                                 while(nodes.length){
2662                                                         for(var node = nodes.pop(); node; node = node.nextSibling){
2663                                                                 if(node.nodeType == 1 && node.tagName.toLowerCase() == "option"){
2664                                                                         if(node.selected){
2665                                                                                 ret.push(node.value);
2666                                                                         }
2667                                                                 }else{
2668                                                                         if(node.nextSibling){
2669                                                                                 nodes.push(node.nextSibling);
2670                                                                         }
2671                                                                         if(node.firstChild){
2672                                                                                 nodes.push(node.firstChild);
2673                                                                         }
2674                                                                         break;
2675                                                                 }
2676                                                         }
2677                                                 }
2678                                         }else{
2679                                                 ret = inputNode.value;
2680                                         }
2681                                 }
2682                         }
2683                         return ret; // Object
2684                 },
2685
2686                 toObject: function formToObject(/*DOMNode|String*/ formNode){
2687                         // summary:
2688                         //              Serialize a form node to a JavaScript object.
2689                         // description:
2690                         //              Returns the values encoded in an HTML form as
2691                         //              string properties in an object which it then returns. Disabled form
2692                         //              elements, buttons, and other non-value form elements are skipped.
2693                         //              Multi-select elements are returned as an array of string values.
2694                         // formNode: DOMNode|String
2695                         // example:
2696                         //              This form:
2697                         //              |       <form id="test_form">
2698                         //              |               <input type="text" name="blah" value="blah">
2699                         //              |               <input type="text" name="no_value" value="blah" disabled>
2700                         //              |               <input type="button" name="no_value2" value="blah">
2701                         //              |               <select type="select" multiple name="multi" size="5">
2702                         //              |                       <option value="blah">blah</option>
2703                         //              |                       <option value="thud" selected>thud</option>
2704                         //              |                       <option value="thonk" selected>thonk</option>
2705                         //              |               </select>
2706                         //              |       </form>
2707                         //
2708                         //              yields this object structure as the result of a call to
2709                         //              formToObject():
2710                         //
2711                         //              |       {
2712                         //              |               blah: "blah",
2713                         //              |               multi: [
2714                         //              |                       "thud",
2715                         //              |                       "thonk"
2716                         //              |               ]
2717                         //              |       };
2718
2719                         var ret = {}, elems = dom.byId(formNode).elements;
2720                         for(var i = 0, l = elems.length; i < l; ++i){
2721                                 var item = elems[i], _in = item.name, type = (item.type || "").toLowerCase();
2722                                 if(_in && type && exclude.indexOf(type) < 0 && !item.disabled){
2723                                         setValue(ret, _in, form.fieldToObject(item));
2724                                         if(type == "image"){
2725                                                 ret[_in + ".x"] = ret[_in + ".y"] = ret[_in].x = ret[_in].y = 0;
2726                                         }
2727                                 }
2728                         }
2729                         return ret; // Object
2730                 },
2731
2732                 toQuery: function formToQuery(/*DOMNode|String*/ formNode){
2733                         // summary:
2734                         //              Returns a URL-encoded string representing the form passed as either a
2735                         //              node or string ID identifying the form to serialize
2736                         // formNode: DOMNode|String
2737                         // returns: String
2738
2739                         return ioq.objectToQuery(form.toObject(formNode)); // String
2740                 },
2741
2742                 toJson: function formToJson(/*DOMNode|String*/ formNode, /*Boolean?*/ prettyPrint){
2743                         // summary:
2744                         //              Create a serialized JSON string from a form node or string
2745                         //              ID identifying the form to serialize
2746                         // formNode: DOMNode|String
2747                         // prettyPrint: Boolean?
2748                         // returns: String
2749
2750                         return json.stringify(form.toObject(formNode), null, prettyPrint ? 4 : 0); // String
2751                 }
2752         };
2753
2754     return form;
2755 });
2756
2757 },
2758 'dojo/promise/tracer':function(){
2759 define([
2760         "../_base/lang",
2761         "./Promise",
2762         "../Evented"
2763 ], function(lang, Promise, Evented){
2764         "use strict";
2765
2766         // module:
2767         //              dojo/promise/tracer
2768
2769         /*=====
2770         return {
2771                 // summary:
2772                 //              Trace promise fulfillment.
2773                 // description:
2774                 //              Trace promise fulfillment. Calling `.trace()` or `.traceError()` on a
2775                 //              promise enables tracing. Will emit `resolved`, `rejected` or `progress`
2776                 //              events.
2777
2778                 on: function(type, listener){
2779                         // summary:
2780                         //              Subscribe to traces.
2781                         // description:
2782                         //              See `dojo/Evented#on()`.
2783                         // type: String
2784                         //              `resolved`, `rejected`, or `progress`
2785                         // listener: Function
2786                         //              The listener is passed the traced value and any arguments
2787                         //              that were used with the `.trace()` call.
2788                 }
2789         };
2790         =====*/
2791
2792         var evented = new Evented;
2793         var emit = evented.emit;
2794         evented.emit = null;
2795         // Emit events asynchronously since they should not change the promise state.
2796         function emitAsync(args){
2797                 setTimeout(function(){
2798                         emit.apply(evented, args);
2799                 }, 0);
2800         }
2801
2802         Promise.prototype.trace = function(){
2803                 // summary:
2804                 //              Trace the promise.
2805                 // description:
2806                 //              Tracing allows you to transparently log progress,
2807                 //              resolution and rejection of promises, without affecting the
2808                 //              promise itself. Any arguments passed to `trace()` are
2809                 //              emitted in trace events. See `dojo/promise/tracer` on how
2810                 //              to handle traces.
2811                 // returns: dojo/promise/Promise
2812                 //              The promise instance `trace()` is called on.
2813
2814                 var args = lang._toArray(arguments);
2815                 this.then(
2816                         function(value){ emitAsync(["resolved", value].concat(args)); },
2817                         function(error){ emitAsync(["rejected", error].concat(args)); },
2818                         function(update){ emitAsync(["progress", update].concat(args)); }
2819                 );
2820                 return this;
2821         };
2822
2823         Promise.prototype.traceRejected = function(){
2824                 // summary:
2825                 //              Trace rejection of the promise.
2826                 // description:
2827                 //              Tracing allows you to transparently log progress,
2828                 //              resolution and rejection of promises, without affecting the
2829                 //              promise itself. Any arguments passed to `trace()` are
2830                 //              emitted in trace events. See `dojo/promise/tracer` on how
2831                 //              to handle traces.
2832                 // returns: dojo/promise/Promise
2833                 //              The promise instance `traceRejected()` is called on.
2834
2835                 var args = lang._toArray(arguments);
2836                 this.otherwise(function(error){
2837                         emitAsync(["rejected", error].concat(args));
2838                 });
2839                 return this;
2840         };
2841
2842         return evented;
2843 });
2844
2845 },
2846 'dojo/errors/RequestError':function(){
2847 define(['./create'], function(create){
2848         // module:
2849         //              dojo/errors/RequestError
2850
2851         /*=====
2852          return function(){
2853                  // summary:
2854                  //             TODOC
2855          };
2856          =====*/
2857
2858         return create("RequestError", function(message, response){
2859                 this.response = response;
2860         });
2861 });
2862
2863 },
2864 'dojo/_base/html':function(){
2865 define("dojo/_base/html", ["./kernel", "../dom", "../dom-style", "../dom-attr", "../dom-prop", "../dom-class", "../dom-construct", "../dom-geometry"], function(dojo, dom, style, attr, prop, cls, ctr, geom){
2866         // module:
2867         //              dojo/dom
2868
2869         /*=====
2870         return {
2871                 // summary:
2872                 //              This module is a stub for the core dojo DOM API.
2873         };
2874         =====*/
2875
2876         // mix-in dom
2877         dojo.byId = dom.byId;
2878         dojo.isDescendant = dom.isDescendant;
2879         dojo.setSelectable = dom.setSelectable;
2880
2881         // mix-in dom-attr
2882         dojo.getAttr = attr.get;
2883         dojo.setAttr = attr.set;
2884         dojo.hasAttr = attr.has;
2885         dojo.removeAttr = attr.remove;
2886         dojo.getNodeProp = attr.getNodeProp;
2887
2888         dojo.attr = function(node, name, value){
2889                 // summary:
2890                 //              Gets or sets an attribute on an HTML element.
2891                 // description:
2892                 //              Handles normalized getting and setting of attributes on DOM
2893                 //              Nodes. If 2 arguments are passed, and a the second argument is a
2894                 //              string, acts as a getter.
2895                 //
2896                 //              If a third argument is passed, or if the second argument is a
2897                 //              map of attributes, acts as a setter.
2898                 //
2899                 //              When passing functions as values, note that they will not be
2900                 //              directly assigned to slots on the node, but rather the default
2901                 //              behavior will be removed and the new behavior will be added
2902                 //              using `dojo.connect()`, meaning that event handler properties
2903                 //              will be normalized and that some caveats with regards to
2904                 //              non-standard behaviors for onsubmit apply. Namely that you
2905                 //              should cancel form submission using `dojo.stopEvent()` on the
2906                 //              passed event object instead of returning a boolean value from
2907                 //              the handler itself.
2908                 // node: DOMNode|String
2909                 //              id or reference to the element to get or set the attribute on
2910                 // name: String|Object
2911                 //              the name of the attribute to get or set.
2912                 // value: String?
2913                 //              The value to set for the attribute
2914                 // returns:
2915                 //              when used as a getter, the value of the requested attribute
2916                 //              or null if that attribute does not have a specified or
2917                 //              default value;
2918                 //
2919                 //              when used as a setter, the DOM node
2920                 //
2921                 // example:
2922                 //      |       // get the current value of the "foo" attribute on a node
2923                 //      |       dojo.attr(dojo.byId("nodeId"), "foo");
2924                 //      |       // or we can just pass the id:
2925                 //      |       dojo.attr("nodeId", "foo");
2926                 //
2927                 // example:
2928                 //      |       // use attr() to set the tab index
2929                 //      |       dojo.attr("nodeId", "tabIndex", 3);
2930                 //      |
2931                 //
2932                 // example:
2933                 //      Set multiple values at once, including event handlers:
2934                 //      |       dojo.attr("formId", {
2935                 //      |               "foo": "bar",
2936                 //      |               "tabIndex": -1,
2937                 //      |               "method": "POST",
2938                 //      |               "onsubmit": function(e){
2939                 //      |                       // stop submitting the form. Note that the IE behavior
2940                 //      |                       // of returning true or false will have no effect here
2941                 //      |                       // since our handler is connect()ed to the built-in
2942                 //      |                       // onsubmit behavior and so we need to use
2943                 //      |                       // dojo.stopEvent() to ensure that the submission
2944                 //      |                       // doesn't proceed.
2945                 //      |                       dojo.stopEvent(e);
2946                 //      |
2947                 //      |                       // submit the form with Ajax
2948                 //      |                       dojo.xhrPost({ form: "formId" });
2949                 //      |               }
2950                 //      |       });
2951                 //
2952                 // example:
2953                 //      Style is s special case: Only set with an object hash of styles
2954                 //      |       dojo.attr("someNode",{
2955                 //      |               id:"bar",
2956                 //      |               style:{
2957                 //      |                       width:"200px", height:"100px", color:"#000"
2958                 //      |               }
2959                 //      |       });
2960                 //
2961                 // example:
2962                 //      Again, only set style as an object hash of styles:
2963                 //      |       var obj = { color:"#fff", backgroundColor:"#000" };
2964                 //      |       dojo.attr("someNode", "style", obj);
2965                 //      |
2966                 //      |       // though shorter to use `dojo.style()` in this case:
2967                 //      |       dojo.style("someNode", obj);
2968
2969                 if(arguments.length == 2){
2970                         return attr[typeof name == "string" ? "get" : "set"](node, name);
2971                 }
2972                 return attr.set(node, name, value);
2973         };
2974
2975         // mix-in dom-class
2976         dojo.hasClass = cls.contains;
2977         dojo.addClass = cls.add;
2978         dojo.removeClass = cls.remove;
2979         dojo.toggleClass = cls.toggle;
2980         dojo.replaceClass = cls.replace;
2981
2982         // mix-in dom-construct
2983         dojo._toDom = dojo.toDom = ctr.toDom;
2984         dojo.place = ctr.place;
2985         dojo.create = ctr.create;
2986         dojo.empty = function(node){ ctr.empty(node); };
2987         dojo._destroyElement = dojo.destroy = function(node){ ctr.destroy(node); };
2988
2989         // mix-in dom-geometry
2990         dojo._getPadExtents = dojo.getPadExtents = geom.getPadExtents;
2991         dojo._getBorderExtents = dojo.getBorderExtents = geom.getBorderExtents;
2992         dojo._getPadBorderExtents = dojo.getPadBorderExtents = geom.getPadBorderExtents;
2993         dojo._getMarginExtents = dojo.getMarginExtents = geom.getMarginExtents;
2994         dojo._getMarginSize = dojo.getMarginSize = geom.getMarginSize;
2995         dojo._getMarginBox = dojo.getMarginBox = geom.getMarginBox;
2996         dojo.setMarginBox = geom.setMarginBox;
2997         dojo._getContentBox = dojo.getContentBox = geom.getContentBox;
2998         dojo.setContentSize = geom.setContentSize;
2999         dojo._isBodyLtr = dojo.isBodyLtr = geom.isBodyLtr;
3000         dojo._docScroll = dojo.docScroll = geom.docScroll;
3001         dojo._getIeDocumentElementOffset = dojo.getIeDocumentElementOffset = geom.getIeDocumentElementOffset;
3002         dojo._fixIeBiDiScrollLeft = dojo.fixIeBiDiScrollLeft = geom.fixIeBiDiScrollLeft;
3003         dojo.position = geom.position;
3004
3005         dojo.marginBox = function marginBox(/*DomNode|String*/node, /*Object?*/box){
3006                 // summary:
3007                 //              Getter/setter for the margin-box of node.
3008                 // description:
3009                 //              Getter/setter for the margin-box of node.
3010                 //              Returns an object in the expected format of box (regardless
3011                 //              if box is passed). The object might look like:
3012                 //              `{ l: 50, t: 200, w: 300: h: 150 }`
3013                 //              for a node offset from its parent 50px to the left, 200px from
3014                 //              the top with a margin width of 300px and a margin-height of
3015                 //              150px.
3016                 // node:
3017                 //              id or reference to DOM Node to get/set box for
3018                 // box:
3019                 //              If passed, denotes that dojo.marginBox() should
3020                 //              update/set the margin box for node. Box is an object in the
3021                 //              above format. All properties are optional if passed.
3022                 // example:
3023                 //              Retrieve the margin box of a passed node
3024                 //      |       var box = dojo.marginBox("someNodeId");
3025                 //      |       console.dir(box);
3026                 //
3027                 // example:
3028                 //              Set a node's margin box to the size of another node
3029                 //      |       var box = dojo.marginBox("someNodeId");
3030                 //      |       dojo.marginBox("someOtherNode", box);
3031                 return box ? geom.setMarginBox(node, box) : geom.getMarginBox(node); // Object
3032         };
3033
3034         dojo.contentBox = function contentBox(/*DomNode|String*/node, /*Object?*/box){
3035                 // summary:
3036                 //              Getter/setter for the content-box of node.
3037                 // description:
3038                 //              Returns an object in the expected format of box (regardless if box is passed).
3039                 //              The object might look like:
3040                 //              `{ l: 50, t: 200, w: 300: h: 150 }`
3041                 //              for a node offset from its parent 50px to the left, 200px from
3042                 //              the top with a content width of 300px and a content-height of
3043                 //              150px. Note that the content box may have a much larger border
3044                 //              or margin box, depending on the box model currently in use and
3045                 //              CSS values set/inherited for node.
3046                 //              While the getter will return top and left values, the
3047                 //              setter only accepts setting the width and height.
3048                 // node:
3049                 //              id or reference to DOM Node to get/set box for
3050                 // box:
3051                 //              If passed, denotes that dojo.contentBox() should
3052                 //              update/set the content box for node. Box is an object in the
3053                 //              above format, but only w (width) and h (height) are supported.
3054                 //              All properties are optional if passed.
3055                 return box ? geom.setContentSize(node, box) : geom.getContentBox(node); // Object
3056         };
3057
3058         dojo.coords = function(/*DomNode|String*/node, /*Boolean?*/includeScroll){
3059                 // summary:
3060                 //              Deprecated: Use position() for border-box x/y/w/h
3061                 //              or marginBox() for margin-box w/h/l/t.
3062                 //
3063                 //              Returns an object that measures margin-box (w)idth/(h)eight
3064                 //              and absolute position x/y of the border-box. Also returned
3065                 //              is computed (l)eft and (t)op values in pixels from the
3066                 //              node's offsetParent as returned from marginBox().
3067                 //              Return value will be in the form:
3068                 //|                     { l: 50, t: 200, w: 300: h: 150, x: 100, y: 300 }
3069                 //              Does not act as a setter. If includeScroll is passed, the x and
3070                 //              y params are affected as one would expect in dojo.position().
3071                 dojo.deprecated("dojo.coords()", "Use dojo.position() or dojo.marginBox().");
3072                 node = dom.byId(node);
3073                 var s = style.getComputedStyle(node), mb = geom.getMarginBox(node, s);
3074                 var abs = geom.position(node, includeScroll);
3075                 mb.x = abs.x;
3076                 mb.y = abs.y;
3077                 return mb;      // Object
3078         };
3079
3080         // mix-in dom-prop
3081         dojo.getProp = prop.get;
3082         dojo.setProp = prop.set;
3083
3084         dojo.prop = function(/*DomNode|String*/node, /*String|Object*/name, /*String?*/value){
3085                 // summary:
3086                 //              Gets or sets a property on an HTML element.
3087                 // description:
3088                 //              Handles normalized getting and setting of properties on DOM
3089                 //              Nodes. If 2 arguments are passed, and a the second argument is a
3090                 //              string, acts as a getter.
3091                 //
3092                 //              If a third argument is passed, or if the second argument is a
3093                 //              map of attributes, acts as a setter.
3094                 //
3095                 //              When passing functions as values, note that they will not be
3096                 //              directly assigned to slots on the node, but rather the default
3097                 //              behavior will be removed and the new behavior will be added
3098                 //              using `dojo.connect()`, meaning that event handler properties
3099                 //              will be normalized and that some caveats with regards to
3100                 //              non-standard behaviors for onsubmit apply. Namely that you
3101                 //              should cancel form submission using `dojo.stopEvent()` on the
3102                 //              passed event object instead of returning a boolean value from
3103                 //              the handler itself.
3104                 // node:
3105                 //              id or reference to the element to get or set the property on
3106                 // name:
3107                 //              the name of the property to get or set.
3108                 // value:
3109                 //              The value to set for the property
3110                 // returns:
3111                 //              when used as a getter, the value of the requested property
3112                 //              or null if that attribute does not have a specified or
3113                 //              default value;
3114                 //
3115                 //              when used as a setter, the DOM node
3116                 //
3117                 // example:
3118                 //      |       // get the current value of the "foo" property on a node
3119                 //      |       dojo.prop(dojo.byId("nodeId"), "foo");
3120                 //      |       // or we can just pass the id:
3121                 //      |       dojo.prop("nodeId", "foo");
3122                 //
3123                 // example:
3124                 //      |       // use prop() to set the tab index
3125                 //      |       dojo.prop("nodeId", "tabIndex", 3);
3126                 //      |
3127                 //
3128                 // example:
3129                 //      Set multiple values at once, including event handlers:
3130                 //      |       dojo.prop("formId", {
3131                 //      |               "foo": "bar",
3132                 //      |               "tabIndex": -1,
3133                 //      |               "method": "POST",
3134                 //      |               "onsubmit": function(e){
3135                 //      |                       // stop submitting the form. Note that the IE behavior
3136                 //      |                       // of returning true or false will have no effect here
3137                 //      |                       // since our handler is connect()ed to the built-in
3138                 //      |                       // onsubmit behavior and so we need to use
3139                 //      |                       // dojo.stopEvent() to ensure that the submission
3140                 //      |                       // doesn't proceed.
3141                 //      |                       dojo.stopEvent(e);
3142                 //      |
3143                 //      |                       // submit the form with Ajax
3144                 //      |                       dojo.xhrPost({ form: "formId" });
3145                 //      |               }
3146                 //      |       });
3147                 //
3148                 // example:
3149                 //              Style is s special case: Only set with an object hash of styles
3150                 //      |       dojo.prop("someNode",{
3151                 //      |               id:"bar",
3152                 //      |               style:{
3153                 //      |                       width:"200px", height:"100px", color:"#000"
3154                 //      |               }
3155                 //      |       });
3156                 //
3157                 // example:
3158                 //              Again, only set style as an object hash of styles:
3159                 //      |       var obj = { color:"#fff", backgroundColor:"#000" };
3160                 //      |       dojo.prop("someNode", "style", obj);
3161                 //      |
3162                 //      |       // though shorter to use `dojo.style()` in this case:
3163                 //      |       dojo.style("someNode", obj);
3164
3165                 if(arguments.length == 2){
3166                         return prop[typeof name == "string" ? "get" : "set"](node, name);
3167                 }
3168                 // setter
3169                 return prop.set(node, name, value);
3170         };
3171
3172         // mix-in dom-style
3173         dojo.getStyle = style.get;
3174         dojo.setStyle = style.set;
3175         dojo.getComputedStyle = style.getComputedStyle;
3176         dojo.__toPixelValue = dojo.toPixelValue = style.toPixelValue;
3177
3178         dojo.style = function(node, name, value){
3179                 // summary:
3180                 //              Accesses styles on a node. If 2 arguments are
3181                 //              passed, acts as a getter. If 3 arguments are passed, acts
3182                 //              as a setter.
3183                 // description:
3184                 //              Getting the style value uses the computed style for the node, so the value
3185                 //              will be a calculated value, not just the immediate node.style value.
3186                 //              Also when getting values, use specific style names,
3187                 //              like "borderBottomWidth" instead of "border" since compound values like
3188                 //              "border" are not necessarily reflected as expected.
3189                 //              If you want to get node dimensions, use `dojo.marginBox()`,
3190                 //              `dojo.contentBox()` or `dojo.position()`.
3191                 // node: DOMNode|String
3192                 //              id or reference to node to get/set style for
3193                 // name: String|Object?
3194                 //              the style property to set in DOM-accessor format
3195                 //              ("borderWidth", not "border-width") or an object with key/value
3196                 //              pairs suitable for setting each property.
3197                 // value: String?
3198                 //              If passed, sets value on the node for style, handling
3199                 //              cross-browser concerns.  When setting a pixel value,
3200                 //              be sure to include "px" in the value. For instance, top: "200px".
3201                 //              Otherwise, in some cases, some browsers will not apply the style.
3202                 // returns:
3203                 //              when used as a getter, return the computed style of the node if passing in an ID or node,
3204                 //              or return the normalized, computed value for the property when passing in a node and a style property
3205                 // example:
3206                 //              Passing only an ID or node returns the computed style object of
3207                 //              the node:
3208                 //      |       dojo.style("thinger");
3209                 // example:
3210                 //              Passing a node and a style property returns the current
3211                 //              normalized, computed value for that property:
3212                 //      |       dojo.style("thinger", "opacity"); // 1 by default
3213                 //
3214                 // example:
3215                 //              Passing a node, a style property, and a value changes the
3216                 //              current display of the node and returns the new computed value
3217                 //      |       dojo.style("thinger", "opacity", 0.5); // == 0.5
3218                 //
3219                 // example:
3220                 //              Passing a node, an object-style style property sets each of the values in turn and returns the computed style object of the node:
3221                 //      |       dojo.style("thinger", {
3222                 //      |               "opacity": 0.5,
3223                 //      |               "border": "3px solid black",
3224                 //      |               "height": "300px"
3225                 //      |       });
3226                 //
3227                 // example:
3228                 //              When the CSS style property is hyphenated, the JavaScript property is camelCased.
3229                 //              font-size becomes fontSize, and so on.
3230                 //      |       dojo.style("thinger",{
3231                 //      |               fontSize:"14pt",
3232                 //      |               letterSpacing:"1.2em"
3233                 //      |       });
3234                 //
3235                 // example:
3236                 //              dojo/NodeList implements .style() using the same syntax, omitting the "node" parameter, calling
3237                 //              dojo.style() on every element of the list. See: `dojo/query` and `dojo/NodeList`
3238                 //      |       dojo.query(".someClassName").style("visibility","hidden");
3239                 //      |       // or
3240                 //      |       dojo.query("#baz > div").style({
3241                 //      |               opacity:0.75,
3242                 //      |               fontSize:"13pt"
3243                 //      |       });
3244
3245                 switch(arguments.length){
3246                         case 1:
3247                                 return style.get(node);
3248                         case 2:
3249                                 return style[typeof name == "string" ? "get" : "set"](node, name);
3250                 }
3251                 // setter
3252                 return style.set(node, name, value);
3253         };
3254
3255         return dojo;
3256 });
3257
3258 },
3259 'dojo/_base/kernel':function(){
3260 define(["../has", "./config", "require", "module"], function(has, config, require, module){
3261         // module:
3262         //              dojo/_base/kernel
3263
3264         // This module is the foundational module of the dojo boot sequence; it defines the dojo object.
3265
3266         var
3267                 // loop variables for this module
3268                 i, p,
3269
3270                 // create dojo, dijit, and dojox
3271                 // FIXME: in 2.0 remove dijit, dojox being created by dojo
3272                 dijit = {},
3273                 dojox = {},
3274                 dojo = {
3275                         // summary:
3276                         //              This module is the foundational module of the dojo boot sequence; it defines the dojo object.
3277
3278                         // notice dojo takes ownership of the value of the config module
3279                         config:config,
3280                         global:this,
3281                         dijit:dijit,
3282                         dojox:dojox
3283                 };
3284
3285
3286         // Configure the scope map. For a 100% AMD application, the scope map is not needed other than to provide
3287         // a _scopeName property for the dojo, dijit, and dojox root object so those packages can create
3288         // unique names in the global space.
3289         //
3290         // Built, legacy modules use the scope map to allow those modules to be expressed as if dojo, dijit, and dojox,
3291         // where global when in fact they are either global under different names or not global at all. In v1.6-, the
3292         // config variable "scopeMap" was used to map names as used within a module to global names. This has been
3293         // subsumed by the AMD map configuration variable which can relocate packages to different names. For backcompat,
3294         // only the "*" mapping is supported. See http://livedocs.dojotoolkit.org/developer/design/loader#legacy-cross-domain-mode for details.
3295         //
3296         // The following computations contort the packageMap for this dojo instance into a scopeMap.
3297         var scopeMap =
3298                         // a map from a name used in a legacy module to the (global variable name, object addressed by that name)
3299                         // always map dojo, dijit, and dojox
3300                         {
3301                                 dojo:["dojo", dojo],
3302                                 dijit:["dijit", dijit],
3303                                 dojox:["dojox", dojox]
3304                         },
3305
3306                 packageMap =
3307                         // the package map for this dojo instance; note, a foreign loader or no pacakgeMap results in the above default config
3308                         (require.map && require.map[module.id.match(/[^\/]+/)[0]]),
3309
3310                 item;
3311
3312
3313         // process all mapped top-level names for this instance of dojo
3314         for(p in packageMap){
3315                 if(scopeMap[p]){
3316                         // mapped dojo, dijit, or dojox
3317                         scopeMap[p][0] = packageMap[p];
3318                 }else{
3319                         // some other top-level name
3320                         scopeMap[p] = [packageMap[p], {}];
3321                 }
3322         }
3323
3324         // publish those names to _scopeName and, optionally, the global namespace
3325         for(p in scopeMap){
3326                 item = scopeMap[p];
3327                 item[1]._scopeName = item[0];
3328                 if(!config.noGlobals){
3329                         this[item[0]] = item[1];
3330                 }
3331         }
3332         dojo.scopeMap = scopeMap;
3333
3334         /*===== dojo.__docParserConfigureScopeMap(scopeMap); =====*/
3335
3336         // FIXME: dojo.baseUrl and dojo.config.baseUrl should be deprecated
3337         dojo.baseUrl = dojo.config.baseUrl = require.baseUrl;
3338         dojo.isAsync = ! 1  || require.async;
3339         dojo.locale = config.locale;
3340
3341         var rev = "$Rev: 30226 $".match(/\d+/);
3342         dojo.version = {
3343                 // summary:
3344                 //              Version number of the Dojo Toolkit
3345                 // description:
3346                 //              Hash about the version, including
3347                 //
3348                 //              - major: Integer: Major version. If total version is "1.2.0beta1", will be 1
3349                 //              - minor: Integer: Minor version. If total version is "1.2.0beta1", will be 2
3350                 //              - patch: Integer: Patch version. If total version is "1.2.0beta1", will be 0
3351                 //              - flag: String: Descriptor flag. If total version is "1.2.0beta1", will be "beta1"
3352                 //              - revision: Number: The SVN rev from which dojo was pulled
3353
3354                 major: 1, minor: 8, patch: 3, flag: "",
3355                 revision: rev ? +rev[0] : NaN,
3356                 toString: function(){
3357                         var v = dojo.version;
3358                         return v.major + "." + v.minor + "." + v.patch + v.flag + " (" + v.revision + ")";      // String
3359                 }
3360         };
3361
3362         // If  1  is truthy, then as a dojo module is defined it should push it's definitions
3363         // into the dojo object, and conversely. In 2.0, it will likely be unusual to augment another object
3364         // as a result of defining a module. This has feature gives a way to force 2.0 behavior as the code
3365         // is migrated. Absent specific advice otherwise, set extend-dojo to truthy.
3366          1 || has.add("extend-dojo", 1);
3367
3368
3369         (Function("d", "d.eval = function(){return d.global.eval ? d.global.eval(arguments[0]) : eval(arguments[0]);}"))(dojo);
3370         /*=====
3371         dojo.eval = function(scriptText){
3372                 // summary:
3373                 //              A legacy method created for use exclusively by internal Dojo methods. Do not use this method
3374                 //              directly unless you understand its possibly-different implications on the platforms your are targeting.
3375                 // description:
3376                 //              Makes an attempt to evaluate scriptText in the global scope. The function works correctly for browsers
3377                 //              that support indirect eval.
3378                 //
3379                 //              As usual, IE does not. On IE, the only way to implement global eval is to
3380                 //              use execScript. Unfortunately, execScript does not return a value and breaks some current usages of dojo.eval.
3381                 //              This implementation uses the technique of executing eval in the scope of a function that is a single scope
3382                 //              frame below the global scope; thereby coming close to the global scope. Note carefully that
3383                 //
3384                 //              dojo.eval("var pi = 3.14;");
3385                 //
3386                 //              will define global pi in non-IE environments, but define pi only in a temporary local scope for IE. If you want
3387                 //              to define a global variable using dojo.eval, write something like
3388                 //
3389                 //              dojo.eval("window.pi = 3.14;")
3390                 // scriptText:
3391                 //              The text to evaluation.
3392                 // returns:
3393                 //              The result of the evaluation. Often `undefined`
3394         };
3395         =====*/
3396
3397
3398         if( 0 ){
3399                 dojo.exit = function(exitcode){
3400                         quit(exitcode);
3401                 };
3402         }else{
3403                 dojo.exit = function(){
3404                 };
3405         }
3406
3407          1 || has.add("dojo-guarantee-console",
3408                 // ensure that console.log, console.warn, etc. are defined
3409                 1
3410         );
3411         if( 1 ){
3412                 typeof console != "undefined" || (console = {});
3413                 //      Be careful to leave 'log' always at the end
3414                 var cn = [
3415                         "assert", "count", "debug", "dir", "dirxml", "error", "group",
3416                         "groupEnd", "info", "profile", "profileEnd", "time", "timeEnd",
3417                         "trace", "warn", "log"
3418                 ];
3419                 var tn;
3420                 i = 0;
3421                 while((tn = cn[i++])){
3422                         if(!console[tn]){
3423                                 (function(){
3424                                         var tcn = tn + "";
3425                                         console[tcn] = ('log' in console) ? function(){
3426                                                 var a = Array.apply({}, arguments);
3427                                                 a.unshift(tcn + ":");
3428                                                 console["log"](a.join(" "));
3429                                         } : function(){};
3430                                         console[tcn]._fake = true;
3431                                 })();
3432                         }
3433                 }
3434         }
3435
3436         has.add("dojo-debug-messages",
3437                 // include dojo.deprecated/dojo.experimental implementations
3438                 !!config.isDebug
3439         );
3440         dojo.deprecated = dojo.experimental =  function(){};
3441         if(has("dojo-debug-messages")){
3442                 dojo.deprecated = function(/*String*/ behaviour, /*String?*/ extra, /*String?*/ removal){
3443                         // summary:
3444                         //              Log a debug message to indicate that a behavior has been
3445                         //              deprecated.
3446                         // behaviour: String
3447                         //              The API or behavior being deprecated. Usually in the form
3448                         //              of "myApp.someFunction()".
3449                         // extra: String?
3450                         //              Text to append to the message. Often provides advice on a
3451                         //              new function or facility to achieve the same goal during
3452                         //              the deprecation period.
3453                         // removal: String?
3454                         //              Text to indicate when in the future the behavior will be
3455                         //              removed. Usually a version number.
3456                         // example:
3457                         //      | dojo.deprecated("myApp.getTemp()", "use myApp.getLocaleTemp() instead", "1.0");
3458
3459                         var message = "DEPRECATED: " + behaviour;
3460                         if(extra){ message += " " + extra; }
3461                         if(removal){ message += " -- will be removed in version: " + removal; }
3462                         console.warn(message);
3463                 };
3464
3465                 dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
3466                         // summary:
3467                         //              Marks code as experimental.
3468                         // description:
3469                         //              This can be used to mark a function, file, or module as
3470                         //              experimental.    Experimental code is not ready to be used, and the
3471                         //              APIs are subject to change without notice.      Experimental code may be
3472                         //              completed deleted without going through the normal deprecation
3473                         //              process.
3474                         // moduleName: String
3475                         //              The name of a module, or the name of a module file or a specific
3476                         //              function
3477                         // extra: String?
3478                         //              some additional message for the user
3479                         // example:
3480                         //      | dojo.experimental("dojo.data.Result");
3481                         // example:
3482                         //      | dojo.experimental("dojo.weather.toKelvin()", "PENDING approval from NOAA");
3483
3484                         var message = "EXPERIMENTAL: " + moduleName + " -- APIs subject to change without notice.";
3485                         if(extra){ message += " " + extra; }
3486                         console.warn(message);
3487                 };
3488         }
3489
3490          1 || has.add("dojo-modulePaths",
3491                 // consume dojo.modulePaths processing
3492                 1
3493         );
3494         if( 1 ){
3495                 // notice that modulePaths won't be applied to any require's before the dojo/_base/kernel factory is run;
3496                 // this is the v1.6- behavior.
3497                 if(config.modulePaths){
3498                         dojo.deprecated("dojo.modulePaths", "use paths configuration");
3499                         var paths = {};
3500                         for(p in config.modulePaths){
3501                                 paths[p.replace(/\./g, "/")] = config.modulePaths[p];
3502                         }
3503                         require({paths:paths});
3504                 }
3505         }
3506
3507          1 || has.add("dojo-moduleUrl",
3508                 // include dojo.moduleUrl
3509                 1
3510         );
3511         if( 1 ){
3512                 dojo.moduleUrl = function(/*String*/module, /*String?*/url){
3513                         // summary:
3514                         //              Returns a URL relative to a module.
3515                         // example:
3516                         //      |       var pngPath = dojo.moduleUrl("acme","images/small.png");
3517                         //      |       console.dir(pngPath); // list the object properties
3518                         //      |       // create an image and set it's source to pngPath's value:
3519                         //      |       var img = document.createElement("img");
3520                         //      |       img.src = pngPath;
3521                         //      |       // add our image to the document
3522                         //      |       dojo.body().appendChild(img);
3523                         // example:
3524                         //              you may de-reference as far as you like down the package
3525                         //              hierarchy.  This is sometimes handy to avoid lenghty relative
3526                         //              urls or for building portable sub-packages. In this example,
3527                         //              the `acme.widget` and `acme.util` directories may be located
3528                         //              under different roots (see `dojo.registerModulePath`) but the
3529                         //              the modules which reference them can be unaware of their
3530                         //              relative locations on the filesystem:
3531                         //      |       // somewhere in a configuration block
3532                         //      |       dojo.registerModulePath("acme.widget", "../../acme/widget");
3533                         //      |       dojo.registerModulePath("acme.util", "../../util");
3534                         //      |
3535                         //      |       // ...
3536                         //      |
3537                         //      |       // code in a module using acme resources
3538                         //      |       var tmpltPath = dojo.moduleUrl("acme.widget","templates/template.html");
3539                         //      |       var dataPath = dojo.moduleUrl("acme.util","resources/data.json");
3540
3541                         dojo.deprecated("dojo.moduleUrl()", "use require.toUrl", "2.0");
3542
3543                         // require.toUrl requires a filetype; therefore, just append the suffix "/*.*" to guarantee a filetype, then
3544                         // remove the suffix from the result. This way clients can request a url w/out a filetype. This should be
3545                         // rare, but it maintains backcompat for the v1.x line (note: dojo.moduleUrl will be removed in v2.0).
3546                         // Notice * is an illegal filename so it won't conflict with any real path map that may exist the paths config.
3547                         var result = null;
3548                         if(module){
3549                                 result = require.toUrl(module.replace(/\./g, "/") + (url ? ("/" + url) : "") + "/*.*").replace(/\/\*\.\*/, "") + (url ? "" : "/");
3550                         }
3551                         return result;
3552                 };
3553         }
3554
3555         dojo._hasResource = {}; // for backward compatibility with layers built with 1.6 tooling
3556
3557         return dojo;
3558 });
3559
3560 },
3561 'dojo/io-query':function(){
3562 define(["./_base/lang"], function(lang){
3563
3564 // module:
3565 //              dojo/io-query
3566
3567 var backstop = {};
3568
3569 return {
3570 // summary:
3571 //              This module defines query string processing functions.
3572
3573         objectToQuery: function objectToQuery(/*Object*/ map){
3574                 // summary:
3575         //              takes a name/value mapping object and returns a string representing
3576         //              a URL-encoded version of that object.
3577         // example:
3578         //              this object:
3579         //
3580         //      |       {
3581         //      |               blah: "blah",
3582         //      |               multi: [
3583         //      |                       "thud",
3584         //      |                       "thonk"
3585         //      |               ]
3586         //      |       };
3587         //
3588         //              yields the following query string:
3589         //
3590         //      |       "blah=blah&multi=thud&multi=thonk"
3591
3592         // FIXME: need to implement encodeAscii!!
3593         var enc = encodeURIComponent, pairs = [];
3594         for(var name in map){
3595             var value = map[name];
3596             if(value != backstop[name]){
3597                 var assign = enc(name) + "=";
3598                 if(lang.isArray(value)){
3599                     for(var i = 0, l = value.length; i < l; ++i){
3600                         pairs.push(assign + enc(value[i]));
3601                     }
3602                 }else{
3603                     pairs.push(assign + enc(value));
3604                 }
3605             }
3606         }
3607         return pairs.join("&"); // String
3608     },
3609
3610         queryToObject: function queryToObject(/*String*/ str){
3611         // summary:
3612         //              Create an object representing a de-serialized query section of a
3613         //              URL. Query keys with multiple values are returned in an array.
3614         //
3615         // example:
3616         //              This string:
3617         //
3618         //      |               "foo=bar&foo=baz&thinger=%20spaces%20=blah&zonk=blarg&"
3619         //
3620         //              results in this object structure:
3621         //
3622         //      |               {
3623         //      |                       foo: [ "bar", "baz" ],
3624         //      |                       thinger: " spaces =blah",
3625         //      |                       zonk: "blarg"
3626         //      |               }
3627         //
3628         //              Note that spaces and other urlencoded entities are correctly
3629         //              handled.
3630
3631         // FIXME: should we grab the URL string if we're not passed one?
3632         var dec = decodeURIComponent, qp = str.split("&"), ret = {}, name, val;
3633         for(var i = 0, l = qp.length, item; i < l; ++i){
3634             item = qp[i];
3635             if(item.length){
3636                 var s = item.indexOf("=");
3637                 if(s < 0){
3638                     name = dec(item);
3639                     val = "";
3640                 }else{
3641                     name = dec(item.slice(0, s));
3642                     val  = dec(item.slice(s + 1));
3643                 }
3644                 if(typeof ret[name] == "string"){ // inline'd type check
3645                     ret[name] = [ret[name]];
3646                 }
3647
3648                 if(lang.isArray(ret[name])){
3649                     ret[name].push(val);
3650                 }else{
3651                     ret[name] = val;
3652                 }
3653             }
3654         }
3655         return ret; // Object
3656     }
3657 };
3658 });
3659 },
3660 'dojo/_base/Deferred':function(){
3661 define([
3662         "./kernel",
3663         "../Deferred",
3664         "../promise/Promise",
3665         "../errors/CancelError",
3666         "../has",
3667         "./lang",
3668         "../when"
3669 ], function(dojo, NewDeferred, Promise, CancelError, has, lang, when){
3670         // module:
3671         //              dojo/_base/Deferred
3672
3673         var mutator = function(){};
3674         var freeze = Object.freeze || function(){};
3675         // A deferred provides an API for creating and resolving a promise.
3676         var Deferred = dojo.Deferred = function(/*Function?*/ canceller){
3677                 // summary:
3678                 //              Deprecated.   This module defines the legacy dojo/_base/Deferred API.
3679                 //              New code should use dojo/Deferred instead.
3680                 // description:
3681                 //              The Deferred API is based on the concept of promises that provide a
3682                 //              generic interface into the eventual completion of an asynchronous action.
3683                 //              The motivation for promises fundamentally is about creating a
3684                 //              separation of concerns that allows one to achieve the same type of
3685                 //              call patterns and logical data flow in asynchronous code as can be
3686                 //              achieved in synchronous code. Promises allows one
3687                 //              to be able to call a function purely with arguments needed for
3688                 //              execution, without conflating the call with concerns of whether it is
3689                 //              sync or async. One shouldn't need to alter a call's arguments if the
3690                 //              implementation switches from sync to async (or vice versa). By having
3691                 //              async functions return promises, the concerns of making the call are
3692                 //              separated from the concerns of asynchronous interaction (which are
3693                 //              handled by the promise).
3694                 //
3695                 //              The Deferred is a type of promise that provides methods for fulfilling the
3696                 //              promise with a successful result or an error. The most important method for
3697                 //              working with Dojo's promises is the then() method, which follows the
3698                 //              CommonJS proposed promise API. An example of using a Dojo promise:
3699                 //
3700                 //              |       var resultingPromise = someAsyncOperation.then(function(result){
3701                 //              |               ... handle result ...
3702                 //              |       },
3703                 //              |       function(error){
3704                 //              |               ... handle error ...
3705                 //              |       });
3706                 //
3707                 //              The .then() call returns a new promise that represents the result of the
3708                 //              execution of the callback. The callbacks will never affect the original promises value.
3709                 //
3710                 //              The Deferred instances also provide the following functions for backwards compatibility:
3711                 //
3712                 //              - addCallback(handler)
3713                 //              - addErrback(handler)
3714                 //              - callback(result)
3715                 //              - errback(result)
3716                 //
3717                 //              Callbacks are allowed to return promises themselves, so
3718                 //              you can build complicated sequences of events with ease.
3719                 //
3720                 //              The creator of the Deferred may specify a canceller.  The canceller
3721                 //              is a function that will be called if Deferred.cancel is called
3722                 //              before the Deferred fires. You can use this to implement clean
3723                 //              aborting of an XMLHttpRequest, etc. Note that cancel will fire the
3724                 //              deferred with a CancelledError (unless your canceller returns
3725                 //              another kind of error), so the errbacks should be prepared to
3726                 //              handle that error for cancellable Deferreds.
3727                 // example:
3728                 //      |       var deferred = new Deferred();
3729                 //      |       setTimeout(function(){ deferred.callback({success: true}); }, 1000);
3730                 //      |       return deferred;
3731                 // example:
3732                 //              Deferred objects are often used when making code asynchronous. It
3733                 //              may be easiest to write functions in a synchronous manner and then
3734                 //              split code using a deferred to trigger a response to a long-lived
3735                 //              operation. For example, instead of register a callback function to
3736                 //              denote when a rendering operation completes, the function can
3737                 //              simply return a deferred:
3738                 //
3739                 //              |       // callback style:
3740                 //              |       function renderLotsOfData(data, callback){
3741                 //              |               var success = false
3742                 //              |               try{
3743                 //              |                       for(var x in data){
3744                 //              |                               renderDataitem(data[x]);
3745                 //              |                       }
3746                 //              |                       success = true;
3747                 //              |               }catch(e){ }
3748                 //              |               if(callback){
3749                 //              |                       callback(success);
3750                 //              |               }
3751                 //              |       }
3752                 //
3753                 //              |       // using callback style
3754                 //              |       renderLotsOfData(someDataObj, function(success){
3755                 //              |               // handles success or failure
3756                 //              |               if(!success){
3757                 //              |                       promptUserToRecover();
3758                 //              |               }
3759                 //              |       });
3760                 //              |       // NOTE: no way to add another callback here!!
3761                 // example:
3762                 //              Using a Deferred doesn't simplify the sending code any, but it
3763                 //              provides a standard interface for callers and senders alike,
3764                 //              providing both with a simple way to service multiple callbacks for
3765                 //              an operation and freeing both sides from worrying about details
3766                 //              such as "did this get called already?". With Deferreds, new
3767                 //              callbacks can be added at any time.
3768                 //
3769                 //              |       // Deferred style:
3770                 //              |       function renderLotsOfData(data){
3771                 //              |               var d = new Deferred();
3772                 //              |               try{
3773                 //              |                       for(var x in data){
3774                 //              |                               renderDataitem(data[x]);
3775                 //              |                       }
3776                 //              |                       d.callback(true);
3777                 //              |               }catch(e){
3778                 //              |                       d.errback(new Error("rendering failed"));
3779                 //              |               }
3780                 //              |               return d;
3781                 //              |       }
3782                 //
3783                 //              |       // using Deferred style
3784                 //              |       renderLotsOfData(someDataObj).then(null, function(){
3785                 //              |               promptUserToRecover();
3786                 //              |       });
3787                 //              |       // NOTE: addErrback and addCallback both return the Deferred
3788                 //              |       // again, so we could chain adding callbacks or save the
3789                 //              |       // deferred for later should we need to be notified again.
3790                 // example:
3791                 //              In this example, renderLotsOfData is synchronous and so both
3792                 //              versions are pretty artificial. Putting the data display on a
3793                 //              timeout helps show why Deferreds rock:
3794                 //
3795                 //              |       // Deferred style and async func
3796                 //              |       function renderLotsOfData(data){
3797                 //              |               var d = new Deferred();
3798                 //              |               setTimeout(function(){
3799                 //              |                       try{
3800                 //              |                               for(var x in data){
3801                 //              |                                       renderDataitem(data[x]);
3802                 //              |                               }
3803                 //              |                               d.callback(true);
3804                 //              |                       }catch(e){
3805                 //              |                               d.errback(new Error("rendering failed"));
3806                 //              |                       }
3807                 //              |               }, 100);
3808                 //              |               return d;
3809                 //              |       }
3810                 //
3811                 //              |       // using Deferred style
3812                 //              |       renderLotsOfData(someDataObj).then(null, function(){
3813                 //              |               promptUserToRecover();
3814                 //              |       });
3815                 //
3816                 //              Note that the caller doesn't have to change his code at all to
3817                 //              handle the asynchronous case.
3818
3819                 var result, finished, isError, head, nextListener;
3820                 var promise = (this.promise = new Promise());
3821
3822                 function complete(value){
3823                         if(finished){
3824                                 throw new Error("This deferred has already been resolved");
3825                         }
3826                         result = value;
3827                         finished = true;
3828                         notify();
3829                 }
3830                 function notify(){
3831                         var mutated;
3832                         while(!mutated && nextListener){
3833                                 var listener = nextListener;
3834                                 nextListener = nextListener.next;
3835                                 if((mutated = (listener.progress == mutator))){ // assignment and check
3836                                         finished = false;
3837                                 }
3838
3839                                 var func = (isError ? listener.error : listener.resolved);
3840                                 if(has("config-useDeferredInstrumentation")){
3841                                         if(isError && NewDeferred.instrumentRejected){
3842                                                 NewDeferred.instrumentRejected(result, !!func);
3843                                         }
3844                                 }
3845                                 if(func){
3846                                         try{
3847                                                 var newResult = func(result);
3848                                                 if (newResult && typeof newResult.then === "function"){
3849                                                         newResult.then(lang.hitch(listener.deferred, "resolve"), lang.hitch(listener.deferred, "reject"), lang.hitch(listener.deferred, "progress"));
3850                                                         continue;
3851                                                 }
3852                                                 var unchanged = mutated && newResult === undefined;
3853                                                 if(mutated && !unchanged){
3854                                                         isError = newResult instanceof Error;
3855                                                 }
3856                                                 listener.deferred[unchanged && isError ? "reject" : "resolve"](unchanged ? result : newResult);
3857                                         }catch(e){
3858                                                 listener.deferred.reject(e);
3859                                         }
3860                                 }else{
3861                                         if(isError){
3862                                                 listener.deferred.reject(result);
3863                                         }else{
3864                                                 listener.deferred.resolve(result);
3865                                         }
3866                                 }
3867                         }
3868                 }
3869                 // calling resolve will resolve the promise
3870                 this.resolve = this.callback = function(value){
3871                         // summary:
3872                         //              Fulfills the Deferred instance successfully with the provide value
3873                         this.fired = 0;
3874                         this.results = [value, null];
3875                         complete(value);
3876                 };
3877
3878
3879                 // calling error will indicate that the promise failed
3880                 this.reject = this.errback = function(error){
3881                         // summary:
3882                         //              Fulfills the Deferred instance as an error with the provided error
3883                         isError = true;
3884                         this.fired = 1;
3885                         if(has("config-useDeferredInstrumentation")){
3886                                 if(NewDeferred.instrumentRejected){
3887                                         NewDeferred.instrumentRejected(error, !!nextListener);
3888                                 }
3889                         }
3890                         complete(error);
3891                         this.results = [null, error];
3892                 };
3893                 // call progress to provide updates on the progress on the completion of the promise
3894                 this.progress = function(update){
3895                         // summary:
3896                         //              Send progress events to all listeners
3897                         var listener = nextListener;
3898                         while(listener){
3899                                 var progress = listener.progress;
3900                                 progress && progress(update);
3901                                 listener = listener.next;
3902                         }
3903                 };
3904                 this.addCallbacks = function(callback, errback){
3905                         // summary:
3906                         //              Adds callback and error callback for this deferred instance.
3907                         // callback: Function?
3908                         //              The callback attached to this deferred object.
3909                         // errback: Function?
3910                         //              The error callback attached to this deferred object.
3911                         // returns:
3912                         //              Returns this deferred object.
3913                         this.then(callback, errback, mutator);
3914                         return this;    // Deferred
3915                 };
3916                 // provide the implementation of the promise
3917                 promise.then = this.then = function(/*Function?*/resolvedCallback, /*Function?*/errorCallback, /*Function?*/progressCallback){
3918                         // summary:
3919                         //              Adds a fulfilledHandler, errorHandler, and progressHandler to be called for
3920                         //              completion of a promise. The fulfilledHandler is called when the promise
3921                         //              is fulfilled. The errorHandler is called when a promise fails. The
3922                         //              progressHandler is called for progress events. All arguments are optional
3923                         //              and non-function values are ignored. The progressHandler is not only an
3924                         //              optional argument, but progress events are purely optional. Promise
3925                         //              providers are not required to ever create progress events.
3926                         //
3927                         //              This function will return a new promise that is fulfilled when the given
3928                         //              fulfilledHandler or errorHandler callback is finished. This allows promise
3929                         //              operations to be chained together. The value returned from the callback
3930                         //              handler is the fulfillment value for the returned promise. If the callback
3931                         //              throws an error, the returned promise will be moved to failed state.
3932                         //
3933                         // returns:
3934                         //              Returns a new promise that represents the result of the
3935                         //              execution of the callback. The callbacks will never affect the original promises value.
3936                         // example:
3937                         //              An example of using a CommonJS compliant promise:
3938                         //              |       asyncComputeTheAnswerToEverything().
3939                         //              |               then(addTwo).
3940                         //              |               then(printResult, onError);
3941                         //              |       >44
3942                         //
3943                         var returnDeferred = progressCallback == mutator ? this : new Deferred(promise.cancel);
3944                         var listener = {
3945                                 resolved: resolvedCallback,
3946                                 error: errorCallback,
3947                                 progress: progressCallback,
3948                                 deferred: returnDeferred
3949                         };
3950                         if(nextListener){
3951                                 head = head.next = listener;
3952                         }
3953                         else{
3954                                 nextListener = head = listener;
3955                         }
3956                         if(finished){
3957                                 notify();
3958                         }
3959                         return returnDeferred.promise; // Promise
3960                 };
3961                 var deferred = this;
3962                 promise.cancel = this.cancel = function(){
3963                         // summary:
3964                         //              Cancels the asynchronous operation
3965                         if(!finished){
3966                                 var error = canceller && canceller(deferred);
3967                                 if(!finished){
3968                                         if (!(error instanceof Error)){
3969                                                 error = new CancelError(error);
3970                                         }
3971                                         error.log = false;
3972                                         deferred.reject(error);
3973                                 }
3974                         }
3975                 };
3976                 freeze(promise);
3977         };
3978         lang.extend(Deferred, {
3979                 addCallback: function(/*Function*/ callback){
3980                         // summary:
3981                         //              Adds successful callback for this deferred instance.
3982                         // returns:
3983                         //              Returns this deferred object.
3984                         return this.addCallbacks(lang.hitch.apply(dojo, arguments));    // Deferred
3985                 },
3986
3987                 addErrback: function(/*Function*/ errback){
3988                         // summary:
3989                         //              Adds error callback for this deferred instance.
3990                         // returns:
3991                         //              Returns this deferred object.
3992                         return this.addCallbacks(null, lang.hitch.apply(dojo, arguments));      // Deferred
3993                 },
3994
3995                 addBoth: function(/*Function*/ callback){
3996                         // summary:
3997                         //              Add handler as both successful callback and error callback for this deferred instance.
3998                         // returns:
3999                         //              Returns this deferred object.
4000                         var enclosed = lang.hitch.apply(dojo, arguments);
4001                         return this.addCallbacks(enclosed, enclosed);   // Deferred
4002                 },
4003                 fired: -1
4004         });
4005
4006         Deferred.when = dojo.when = when;
4007
4008         return Deferred;
4009 });
4010
4011 },
4012 'dojo/NodeList-dom':function(){
4013 define(["./_base/kernel", "./query", "./_base/array", "./_base/lang", "./dom-class", "./dom-construct", "./dom-geometry", "./dom-attr", "./dom-style"], function(dojo, query, array, lang, domCls, domCtr, domGeom, domAttr, domStyle){
4014
4015         // module:
4016         //              dojo/NodeList-dom.js
4017
4018         /*=====
4019          return function(){
4020                  // summary:
4021                  //             Adds DOM related methods to NodeList, and returns NodeList constructor.
4022          };
4023          =====*/
4024
4025         var magicGuard = function(a){
4026                 // summary:
4027                 //              the guard function for dojo.attr() and dojo.style()
4028                 return a.length == 1 && (typeof a[0] == "string"); // inline'd type check
4029         };
4030
4031         var orphan = function(node){
4032                 // summary:
4033                 //              function to orphan nodes
4034                 var p = node.parentNode;
4035                 if(p){
4036                         p.removeChild(node);
4037                 }
4038         };
4039         // FIXME: should we move orphan() to dojo.html?
4040
4041         var NodeList = query.NodeList,
4042                 awc = NodeList._adaptWithCondition,
4043                 aafe = NodeList._adaptAsForEach,
4044                 aam = NodeList._adaptAsMap;
4045
4046         function getSet(module){
4047                 return function(node, name, value){
4048                         if(arguments.length == 2){
4049                                 return module[typeof name == "string" ? "get" : "set"](node, name);
4050                         }
4051                         // setter
4052                         return module.set(node, name, value);
4053                 };
4054         }
4055
4056         lang.extend(NodeList, {
4057                 _normalize: function(/*String||Element||Object||NodeList*/content, /*DOMNode?*/refNode){
4058                         // summary:
4059                         //              normalizes data to an array of items to insert.
4060                         // description:
4061                         //              If content is an object, it can have special properties "template" and
4062                         //              "parse". If "template" is defined, then the template value is run through
4063                         //              dojo.string.substitute (if dojo/string.substitute() has been dojo.required elsewhere),
4064                         //              or if templateFunc is a function on the content, that function will be used to
4065                         //              transform the template into a final string to be used for for passing to dojo/dom-construct.toDom().
4066                         //              If content.parse is true, then it is remembered for later, for when the content
4067                         //              nodes are inserted into the DOM. At that point, the nodes will be parsed for widgets
4068                         //              (if dojo.parser has been dojo.required elsewhere).
4069
4070                         //Wanted to just use a DocumentFragment, but for the array/NodeList
4071                         //case that meant using cloneNode, but we may not want that.
4072                         //Cloning should only happen if the node operations span
4073                         //multiple refNodes. Also, need a real array, not a NodeList from the
4074                         //DOM since the node movements could change those NodeLists.
4075
4076                         var parse = content.parse === true;
4077
4078                         //Do we have an object that needs to be run through a template?
4079                         if(typeof content.template == "string"){
4080                                 var templateFunc = content.templateFunc || (dojo.string && dojo.string.substitute);
4081                                 content = templateFunc ? templateFunc(content.template, content) : content;
4082                         }
4083
4084                         var type = (typeof content);
4085                         if(type == "string" || type == "number"){
4086                                 content = domCtr.toDom(content, (refNode && refNode.ownerDocument));
4087                                 if(content.nodeType == 11){
4088                                         //DocumentFragment. It cannot handle cloneNode calls, so pull out the children.
4089                                         content = lang._toArray(content.childNodes);
4090                                 }else{
4091                                         content = [content];
4092                                 }
4093                         }else if(!lang.isArrayLike(content)){
4094                                 content = [content];
4095                         }else if(!lang.isArray(content)){
4096                                 //To get to this point, content is array-like, but
4097                                 //not an array, which likely means a DOM NodeList. Convert it now.
4098                                 content = lang._toArray(content);
4099                         }
4100
4101                         //Pass around the parse info
4102                         if(parse){
4103                                 content._runParse = true;
4104                         }
4105                         return content; //Array
4106                 },
4107
4108                 _cloneNode: function(/*DOMNode*/ node){
4109                         // summary:
4110                         //              private utility to clone a node. Not very interesting in the vanilla
4111                         //              dojo/NodeList case, but delegates could do interesting things like
4112                         //              clone event handlers if that is derivable from the node.
4113                         return node.cloneNode(true);
4114                 },
4115
4116                 _place: function(/*Array*/ary, /*DOMNode*/refNode, /*String*/position, /*Boolean*/useClone){
4117                         // summary:
4118                         //              private utility to handle placing an array of nodes relative to another node.
4119                         // description:
4120                         //              Allows for cloning the nodes in the array, and for
4121                         //              optionally parsing widgets, if ary._runParse is true.
4122
4123                         //Avoid a disallowed operation if trying to do an innerHTML on a non-element node.
4124                         if(refNode.nodeType != 1 && position == "only"){
4125                                 return;
4126                         }
4127                         var rNode = refNode, tempNode;
4128
4129                         //Always cycle backwards in case the array is really a
4130                         //DOM NodeList and the DOM operations take it out of the live collection.
4131                         var length = ary.length;
4132                         for(var i = length - 1; i >= 0; i--){
4133                                 var node = (useClone ? this._cloneNode(ary[i]) : ary[i]);
4134
4135                                 //If need widget parsing, use a temp node, instead of waiting after inserting into
4136                                 //real DOM because we need to start widget parsing at one node up from current node,
4137                                 //which could cause some already parsed widgets to be parsed again.
4138                                 if(ary._runParse && dojo.parser && dojo.parser.parse){
4139                                         if(!tempNode){
4140                                                 tempNode = rNode.ownerDocument.createElement("div");
4141                                         }
4142                                         tempNode.appendChild(node);
4143                                         dojo.parser.parse(tempNode);
4144                                         node = tempNode.firstChild;
4145                                         while(tempNode.firstChild){
4146                                                 tempNode.removeChild(tempNode.firstChild);
4147                                         }
4148                                 }
4149
4150                                 if(i == length - 1){
4151                                         domCtr.place(node, rNode, position);
4152                                 }else{
4153                                         rNode.parentNode.insertBefore(node, rNode);
4154                                 }
4155                                 rNode = node;
4156                         }
4157                 },
4158
4159
4160                 position: aam(domGeom.position),
4161                 /*=====
4162                 position: function(){
4163                         // summary:
4164                         //              Returns border-box objects (x/y/w/h) of all elements in a node list
4165                         //              as an Array (*not* a NodeList). Acts like `dojo.position`, though
4166                         //              assumes the node passed is each node in this list.
4167
4168                         return dojo.map(this, dojo.position); // Array
4169                 },
4170                 =====*/
4171
4172                 attr: awc(getSet(domAttr), magicGuard),
4173                 /*=====
4174                 attr: function(property, value){
4175                         // summary:
4176                         //              gets or sets the DOM attribute for every element in the
4177                         //              NodeList. See also `dojo.attr`
4178                         // property: String
4179                         //              the attribute to get/set
4180                         // value: String?
4181                         //              optional. The value to set the property to
4182                         // returns:
4183                         //              if no value is passed, the result is an array of attribute values
4184                         //              If a value is passed, the return is this NodeList
4185                         // example:
4186                         //              Make all nodes with a particular class focusable:
4187                         //      |       dojo.query(".focusable").attr("tabIndex", -1);
4188                         // example:
4189                         //              Disable a group of buttons:
4190                         //      |       dojo.query("button.group").attr("disabled", true);
4191                         // example:
4192                         //              innerHTML can be assigned or retrieved as well:
4193                         //      |       // get the innerHTML (as an array) for each list item
4194                         //      |       var ih = dojo.query("li.replaceable").attr("innerHTML");
4195                         return; // dojo/NodeList|Array
4196                 },
4197                 =====*/
4198
4199                 style: awc(getSet(domStyle), magicGuard),
4200                 /*=====
4201                 style: function(property, value){
4202                         // summary:
4203                         //              gets or sets the CSS property for every element in the NodeList
4204                         // property: String
4205                         //              the CSS property to get/set, in JavaScript notation
4206                         //              ("lineHieght" instead of "line-height")
4207                         // value: String?
4208                         //              optional. The value to set the property to
4209                         // returns:
4210                         //              if no value is passed, the result is an array of strings.
4211                         //              If a value is passed, the return is this NodeList
4212                         return; // dojo/NodeList
4213                         return; // Array
4214                 },
4215                 =====*/
4216
4217                 addClass: aafe(domCls.add),
4218                 /*=====
4219                 addClass: function(className){
4220                         // summary:
4221                         //              adds the specified class to every node in the list
4222                         // className: String|Array
4223                         //              A String class name to add, or several space-separated class names,
4224                         //              or an array of class names.
4225                         return; // dojo/NodeList
4226                 },
4227                 =====*/
4228
4229                 removeClass: aafe(domCls.remove),
4230                 /*=====
4231                 removeClass: function(className){
4232                         // summary:
4233                         //              removes the specified class from every node in the list
4234                         // className: String|Array?
4235                         //              An optional String class name to remove, or several space-separated
4236                         //              class names, or an array of class names. If omitted, all class names
4237                         //              will be deleted.
4238                         // returns:
4239                         //              this list
4240                         return; // dojo/NodeList
4241                 },
4242                 =====*/
4243
4244                 toggleClass: aafe(domCls.toggle),
4245                 /*=====
4246                 toggleClass: function(className, condition){
4247                         // summary:
4248                         //              Adds a class to node if not present, or removes if present.
4249                         //              Pass a boolean condition if you want to explicitly add or remove.
4250                         // condition: Boolean?
4251                         //              If passed, true means to add the class, false means to remove.
4252                         // className: String
4253                         //              the CSS class to add
4254                         return; // dojo/NodeList
4255                 },
4256                 =====*/
4257
4258                 replaceClass: aafe(domCls.replace),
4259                 /*=====
4260                 replaceClass: function(addClassStr, removeClassStr){
4261                         // summary:
4262                         //              Replaces one or more classes on a node if not present.
4263                         //              Operates more quickly than calling `removeClass()` and `addClass()`
4264                         // addClassStr: String|Array
4265                         //              A String class name to add, or several space-separated class names,
4266                         //              or an array of class names.
4267                         // removeClassStr: String|Array?
4268                         //              A String class name to remove, or several space-separated class names,
4269                         //              or an array of class names.
4270                         return; // dojo/NodeList
4271                  },
4272                  =====*/
4273
4274                 empty: aafe(domCtr.empty),
4275                 /*=====
4276                 empty: function(){
4277                         // summary:
4278                         //              clears all content from each node in the list. Effectively
4279                         //              equivalent to removing all child nodes from every item in
4280                         //              the list.
4281                         return this.forEach("item.innerHTML='';"); // dojo/NodeList
4282                         // FIXME: should we be checking for and/or disposing of widgets below these nodes?
4283                 },
4284                 =====*/
4285
4286                 removeAttr: aafe(domAttr.remove),
4287                 /*=====
4288                  removeAttr: function(name){
4289                         // summary:
4290                         //              Removes an attribute from each node in the list.
4291                         // name: String
4292                         //              the name of the attribute to remove
4293                         return;         // dojo/NodeList
4294                 },
4295                 =====*/
4296
4297                 marginBox: aam(domGeom.getMarginBox),
4298                 /*=====
4299                 marginBox: function(){
4300                         // summary:
4301                         //              Returns margin-box size of nodes
4302                         return; // dojo/NodeList
4303                  },
4304                  =====*/
4305
4306                 // FIXME: connectPublisher()? connectRunOnce()?
4307
4308                 /*
4309                 destroy: function(){
4310                         // summary:
4311                         //              destroys every item in the list.
4312                         this.forEach(d.destroy);
4313                         // FIXME: should we be checking for and/or disposing of widgets below these nodes?
4314                 },
4315                 */
4316
4317                 place: function(/*String||Node*/ queryOrNode, /*String*/ position){
4318                         // summary:
4319                         //              places elements of this node list relative to the first element matched
4320                         //              by queryOrNode. Returns the original NodeList. See: `dojo.place`
4321                         // queryOrNode:
4322                         //              may be a string representing any valid CSS3 selector or a DOM node.
4323                         //              In the selector case, only the first matching element will be used
4324                         //              for relative positioning.
4325                         // position:
4326                         //              can be one of:
4327                         //
4328                         //              -       "last" (default)
4329                         //              -       "first"
4330                         //              -       "before"
4331                         //              -       "after"
4332                         //              -       "only"
4333                         //              -       "replace"
4334                         //
4335                         //              or an offset in the childNodes property
4336                         var item = query(queryOrNode)[0];
4337                         return this.forEach(function(node){ domCtr.place(node, item, position); }); // dojo/NodeList
4338                 },
4339
4340                 orphan: function(/*String?*/ filter){
4341                         // summary:
4342                         //              removes elements in this list that match the filter
4343                         //              from their parents and returns them as a new NodeList.
4344                         // filter:
4345                         //              CSS selector like ".foo" or "div > span"
4346                         // returns:
4347                         //              NodeList containing the orphaned elements
4348                         return (filter ? query._filterResult(this, filter) : this).forEach(orphan); // dojo/NodeList
4349                 },
4350
4351                 adopt: function(/*String||Array||DomNode*/ queryOrListOrNode, /*String?*/ position){
4352                         // summary:
4353                         //              places any/all elements in queryOrListOrNode at a
4354                         //              position relative to the first element in this list.
4355                         //              Returns a dojo/NodeList of the adopted elements.
4356                         // queryOrListOrNode:
4357                         //              a DOM node or a query string or a query result.
4358                         //              Represents the nodes to be adopted relative to the
4359                         //              first element of this NodeList.
4360                         // position:
4361                         //              can be one of:
4362                         //
4363                         //              -       "last" (default)
4364                         //              -       "first"
4365                         //              -       "before"
4366                         //              -       "after"
4367                         //              -       "only"
4368                         //              -       "replace"
4369                         //
4370                         //              or an offset in the childNodes property
4371                         return query(queryOrListOrNode).place(this[0], position)._stash(this);  // dojo/NodeList
4372                 },
4373
4374                 // FIXME: do we need this?
4375                 query: function(/*String*/ queryStr){
4376                         // summary:
4377                         //              Returns a new list whose members match the passed query,
4378                         //              assuming elements of the current NodeList as the root for
4379                         //              each search.
4380                         // example:
4381                         //              assume a DOM created by this markup:
4382                         //      |       <div id="foo">
4383                         //      |               <p>
4384                         //      |                       bacon is tasty, <span>dontcha think?</span>
4385                         //      |               </p>
4386                         //      |       </div>
4387                         //      |       <div id="bar">
4388                         //      |               <p>great comedians may not be funny <span>in person</span></p>
4389                         //      |       </div>
4390                         //              If we are presented with the following definition for a NodeList:
4391                         //      |       var l = new NodeList(dojo.byId("foo"), dojo.byId("bar"));
4392                         //              it's possible to find all span elements under paragraphs
4393                         //              contained by these elements with this sub-query:
4394                         //      |       var spans = l.query("p span");
4395
4396                         // FIXME: probably slow
4397                         if(!queryStr){ return this; }
4398                         var ret = new NodeList;
4399                         this.map(function(node){
4400                                 // FIXME: why would we ever get undefined here?
4401                                 query(queryStr, node).forEach(function(subNode){
4402                                         if(subNode !== undefined){
4403                                                 ret.push(subNode);
4404                                         }
4405                                 });
4406                         });
4407                         return ret._stash(this);        // dojo/NodeList
4408                 },
4409
4410                 filter: function(/*String|Function*/ filter){
4411                         // summary:
4412                         //              "masks" the built-in javascript filter() method (supported
4413                         //              in Dojo via `dojo.filter`) to support passing a simple
4414                         //              string filter in addition to supporting filtering function
4415                         //              objects.
4416                         // filter:
4417                         //              If a string, a CSS rule like ".thinger" or "div > span".
4418                         // example:
4419                         //              "regular" JS filter syntax as exposed in dojo.filter:
4420                         //              |       dojo.query("*").filter(function(item){
4421                         //              |               // highlight every paragraph
4422                         //              |               return (item.nodeName == "p");
4423                         //              |       }).style("backgroundColor", "yellow");
4424                         // example:
4425                         //              the same filtering using a CSS selector
4426                         //              |       dojo.query("*").filter("p").styles("backgroundColor", "yellow");
4427
4428                         var a = arguments, items = this, start = 0;
4429                         if(typeof filter == "string"){ // inline'd type check
4430                                 items = query._filterResult(this, a[0]);
4431                                 if(a.length == 1){
4432                                         // if we only got a string query, pass back the filtered results
4433                                         return items._stash(this); // dojo/NodeList
4434                                 }
4435                                 // if we got a callback, run it over the filtered items
4436                                 start = 1;
4437                         }
4438                         return this._wrap(array.filter(items, a[start], a[start + 1]), this);   // dojo/NodeList
4439                 },
4440
4441                 /*
4442                 // FIXME: should this be "copyTo" and include parenting info?
4443                 clone: function(){
4444                         // summary:
4445                         //              creates node clones of each element of this list
4446                         //              and returns a new list containing the clones
4447                 },
4448                 */
4449
4450                 addContent: function(/*String||DomNode||Object||dojo/NodeList*/ content, /*String||Integer?*/ position){
4451                         // summary:
4452                         //              add a node, NodeList or some HTML as a string to every item in the
4453                         //              list.  Returns the original list.
4454                         // description:
4455                         //              a copy of the HTML content is added to each item in the
4456                         //              list, with an optional position argument. If no position
4457                         //              argument is provided, the content is appended to the end of
4458                         //              each item.
4459                         // content:
4460                         //              DOM node, HTML in string format, a NodeList or an Object. If a DOM node or
4461                         //              NodeList, the content will be cloned if the current NodeList has more than one
4462                         //              element. Only the DOM nodes are cloned, no event handlers. If it is an Object,
4463                         //              it should be an object with at "template" String property that has the HTML string
4464                         //              to insert. If dojo.string has already been dojo.required, then dojo.string.substitute
4465                         //              will be used on the "template" to generate the final HTML string. Other allowed
4466                         //              properties on the object are: "parse" if the HTML
4467                         //              string should be parsed for widgets (dojo.require("dojo.parser") to get that
4468                         //              option to work), and "templateFunc" if a template function besides dojo.string.substitute
4469                         //              should be used to transform the "template".
4470                         // position:
4471                         //              can be one of:
4472                         //
4473                         //              -       "last"||"end" (default)
4474                         //              -       "first||"start"
4475                         //              -       "before"
4476                         //              -       "after"
4477                         //              -       "replace" (replaces nodes in this NodeList with new content)
4478                         //              -       "only" (removes other children of the nodes so new content is the only child)
4479                         //
4480                         //              or an offset in the childNodes property
4481                         // example:
4482                         //              appends content to the end if the position is omitted
4483                         //      |       dojo.query("h3 > p").addContent("hey there!");
4484                         // example:
4485                         //              add something to the front of each element that has a
4486                         //              "thinger" property:
4487                         //      |       dojo.query("[thinger]").addContent("...", "first");
4488                         // example:
4489                         //              adds a header before each element of the list
4490                         //      |       dojo.query(".note").addContent("<h4>NOTE:</h4>", "before");
4491                         // example:
4492                         //              add a clone of a DOM node to the end of every element in
4493                         //              the list, removing it from its existing parent.
4494                         //      |       dojo.query(".note").addContent(dojo.byId("foo"));
4495                         // example:
4496                         //              Append nodes from a templatized string.
4497                         // |    dojo.require("dojo.string");
4498                         // |    dojo.query(".note").addContent({
4499                         // |            template: '<b>${id}: </b><span>${name}</span>',
4500                         // |            id: "user332",
4501                         // |            name: "Mr. Anderson"
4502                         // |    });
4503                         // example:
4504                         //              Append nodes from a templatized string that also has widgets parsed.
4505                         // |    dojo.require("dojo.string");
4506                         // |    dojo.require("dojo.parser");
4507                         // |    var notes = dojo.query(".note").addContent({
4508                         // |            template: '<button dojoType="dijit/form/Button">${text}</button>',
4509                         // |            parse: true,
4510                         // |            text: "Send"
4511                         // |    });
4512                         content = this._normalize(content, this[0]);
4513                         for(var i = 0, node; (node = this[i]); i++){
4514                                 this._place(content, node, position, i > 0);
4515                         }
4516                         return this; // dojo/NodeList
4517                 }
4518         });
4519
4520         return NodeList;
4521 });
4522
4523 },
4524 'dojo/query':function(){
4525 define(["./_base/kernel", "./has", "./dom", "./on", "./_base/array", "./_base/lang", "./selector/_loader", "./selector/_loader!default"],
4526         function(dojo, has, dom, on, array, lang, loader, defaultEngine){
4527
4528         "use strict";
4529
4530         has.add("array-extensible", function(){
4531                 // test to see if we can extend an array (not supported in old IE)
4532                 return lang.delegate([], {length: 1}).length == 1 && !has("bug-for-in-skips-shadowed");
4533         });
4534         
4535         var ap = Array.prototype, aps = ap.slice, apc = ap.concat, forEach = array.forEach;
4536
4537         var tnl = function(/*Array*/ a, /*dojo/NodeList?*/ parent, /*Function?*/ NodeListCtor){
4538                 // summary:
4539                 //              decorate an array to make it look like a `dojo/NodeList`.
4540                 // a:
4541                 //              Array of nodes to decorate.
4542                 // parent:
4543                 //              An optional parent NodeList that generated the current
4544                 //              list of nodes. Used to call _stash() so the parent NodeList
4545                 //              can be accessed via end() later.
4546                 // NodeListCtor:
4547                 //              An optional constructor function to use for any
4548                 //              new NodeList calls. This allows a certain chain of
4549                 //              NodeList calls to use a different object than dojo/NodeList.
4550                 var nodeList = new (NodeListCtor || this._NodeListCtor || nl)(a);
4551                 return parent ? nodeList._stash(parent) : nodeList;
4552         };
4553
4554         var loopBody = function(f, a, o){
4555                 a = [0].concat(aps.call(a, 0));
4556                 o = o || dojo.global;
4557                 return function(node){
4558                         a[0] = node;
4559                         return f.apply(o, a);
4560                 };
4561         };
4562
4563         // adapters
4564
4565         var adaptAsForEach = function(f, o){
4566                 // summary:
4567                 //              adapts a single node function to be used in the forEach-type
4568                 //              actions. The initial object is returned from the specialized
4569                 //              function.
4570                 // f: Function
4571                 //              a function to adapt
4572                 // o: Object?
4573                 //              an optional context for f
4574                 return function(){
4575                         this.forEach(loopBody(f, arguments, o));
4576                         return this;    // Object
4577                 };
4578         };
4579
4580         var adaptAsMap = function(f, o){
4581                 // summary:
4582                 //              adapts a single node function to be used in the map-type
4583                 //              actions. The return is a new array of values, as via `dojo.map`
4584                 // f: Function
4585                 //              a function to adapt
4586                 // o: Object?
4587                 //              an optional context for f
4588                 return function(){
4589                         return this.map(loopBody(f, arguments, o));
4590                 };
4591         };
4592
4593         var adaptAsFilter = function(f, o){
4594                 // summary:
4595                 //              adapts a single node function to be used in the filter-type actions
4596                 // f: Function
4597                 //              a function to adapt
4598                 // o: Object?
4599                 //              an optional context for f
4600                 return function(){
4601                         return this.filter(loopBody(f, arguments, o));
4602                 };
4603         };
4604
4605         var adaptWithCondition = function(f, g, o){
4606                 // summary:
4607                 //              adapts a single node function to be used in the map-type
4608                 //              actions, behaves like forEach() or map() depending on arguments
4609                 // f: Function
4610                 //              a function to adapt
4611                 // g: Function
4612                 //              a condition function, if true runs as map(), otherwise runs as forEach()
4613                 // o: Object?
4614                 //              an optional context for f and g
4615                 return function(){
4616                         var a = arguments, body = loopBody(f, a, o);
4617                         if(g.call(o || dojo.global, a)){
4618                                 return this.map(body);  // self
4619                         }
4620                         this.forEach(body);
4621                         return this;    // self
4622                 };
4623         };
4624
4625         var NodeList = function(array){
4626                 // summary:
4627                 //              Array-like object which adds syntactic
4628                 //              sugar for chaining, common iteration operations, animation, and
4629                 //              node manipulation. NodeLists are most often returned as the
4630                 //              result of dojo.query() calls.
4631                 // description:
4632                 //              NodeList instances provide many utilities that reflect
4633                 //              core Dojo APIs for Array iteration and manipulation, DOM
4634                 //              manipulation, and event handling. Instead of needing to dig up
4635                 //              functions in the dojo.* namespace, NodeLists generally make the
4636                 //              full power of Dojo available for DOM manipulation tasks in a
4637                 //              simple, chainable way.
4638                 // example:
4639                 //              create a node list from a node
4640                 //              |       new query.NodeList(dojo.byId("foo"));
4641                 // example:
4642                 //              get a NodeList from a CSS query and iterate on it
4643                 //              |       var l = dojo.query(".thinger");
4644                 //              |       l.forEach(function(node, index, nodeList){
4645                 //              |               console.log(index, node.innerHTML);
4646                 //              |       });
4647                 // example:
4648                 //              use native and Dojo-provided array methods to manipulate a
4649                 //              NodeList without needing to use dojo.* functions explicitly:
4650                 //              |       var l = dojo.query(".thinger");
4651                 //              |       // since NodeLists are real arrays, they have a length
4652                 //              |       // property that is both readable and writable and
4653                 //              |       // push/pop/shift/unshift methods
4654                 //              |       console.log(l.length);
4655                 //              |       l.push(dojo.create("span"));
4656                 //              |
4657                 //              |       // dojo's normalized array methods work too:
4658                 //              |       console.log( l.indexOf(dojo.byId("foo")) );
4659                 //              |       // ...including the special "function as string" shorthand
4660                 //              |       console.log( l.every("item.nodeType == 1") );
4661                 //              |
4662                 //              |       // NodeLists can be [..] indexed, or you can use the at()
4663                 //              |       // function to get specific items wrapped in a new NodeList:
4664                 //              |       var node = l[3]; // the 4th element
4665                 //              |       var newList = l.at(1, 3); // the 2nd and 4th elements
4666                 // example:
4667                 //              the style functions you expect are all there too:
4668                 //              |       // style() as a getter...
4669                 //              |       var borders = dojo.query(".thinger").style("border");
4670                 //              |       // ...and as a setter:
4671                 //              |       dojo.query(".thinger").style("border", "1px solid black");
4672                 //              |       // class manipulation
4673                 //              |       dojo.query("li:nth-child(even)").addClass("even");
4674                 //              |       // even getting the coordinates of all the items
4675                 //              |       var coords = dojo.query(".thinger").coords();
4676                 // example:
4677                 //              DOM manipulation functions from the dojo.* namespace area also available:
4678                 //              |       // remove all of the elements in the list from their
4679                 //              |       // parents (akin to "deleting" them from the document)
4680                 //              |       dojo.query(".thinger").orphan();
4681                 //              |       // place all elements in the list at the front of #foo
4682                 //              |       dojo.query(".thinger").place("foo", "first");
4683                 // example:
4684                 //              Event handling couldn't be easier. `dojo.connect` is mapped in,
4685                 //              and shortcut handlers are provided for most DOM events:
4686                 //              |       // like dojo.connect(), but with implicit scope
4687                 //              |       dojo.query("li").connect("onclick", console, "log");
4688                 //              |
4689                 //              |       // many common event handlers are already available directly:
4690                 //              |       dojo.query("li").onclick(console, "log");
4691                 //              |       var toggleHovered = dojo.hitch(dojo, "toggleClass", "hovered");
4692                 //              |       dojo.query("p")
4693                 //              |               .onmouseenter(toggleHovered)
4694                 //              |               .onmouseleave(toggleHovered);
4695                 // example:
4696                 //              chainability is a key advantage of NodeLists:
4697                 //              |       dojo.query(".thinger")
4698                 //              |               .onclick(function(e){ /* ... */ })
4699                 //              |               .at(1, 3, 8) // get a subset
4700                 //              |                       .style("padding", "5px")
4701                 //              |                       .forEach(console.log);
4702                 var isNew = this instanceof nl && has("array-extensible");
4703                 if(typeof array == "number"){
4704                         array = Array(array);
4705                 }
4706                 var nodeArray = (array && "length" in array) ? array : arguments;
4707                 if(isNew || !nodeArray.sort){
4708                         // make sure it's a real array before we pass it on to be wrapped 
4709                         var target = isNew ? this : [],
4710                                 l = target.length = nodeArray.length;
4711                         for(var i = 0; i < l; i++){
4712                                 target[i] = nodeArray[i];
4713                         }
4714                         if(isNew){
4715                                 // called with new operator, this means we are going to use this instance and push
4716                                 // the nodes on to it. This is usually much faster since the NodeList properties
4717                                 //      don't need to be copied (unless the list of nodes is extremely large).
4718                                 return target;
4719                         }
4720                         nodeArray = target;
4721                 }
4722                 // called without new operator, use a real array and copy prototype properties,
4723                 // this is slower and exists for back-compat. Should be removed in 2.0.
4724                 lang._mixin(nodeArray, nlp);
4725                 nodeArray._NodeListCtor = function(array){
4726                         // call without new operator to preserve back-compat behavior
4727                         return nl(array);
4728                 };
4729                 return nodeArray;
4730         };
4731         
4732         var nl = NodeList, nlp = nl.prototype = 
4733                 has("array-extensible") ? [] : {};// extend an array if it is extensible
4734
4735         // expose adapters and the wrapper as private functions
4736
4737         nl._wrap = nlp._wrap = tnl;
4738         nl._adaptAsMap = adaptAsMap;
4739         nl._adaptAsForEach = adaptAsForEach;
4740         nl._adaptAsFilter  = adaptAsFilter;
4741         nl._adaptWithCondition = adaptWithCondition;
4742
4743         // mass assignment
4744
4745         // add array redirectors
4746         forEach(["slice", "splice"], function(name){
4747                 var f = ap[name];
4748                 //Use a copy of the this array via this.slice() to allow .end() to work right in the splice case.
4749                 // CANNOT apply ._stash()/end() to splice since it currently modifies
4750                 // the existing this array -- it would break backward compatibility if we copy the array before
4751                 // the splice so that we can use .end(). So only doing the stash option to this._wrap for slice.
4752                 nlp[name] = function(){ return this._wrap(f.apply(this, arguments), name == "slice" ? this : null); };
4753         });
4754         // concat should be here but some browsers with native NodeList have problems with it
4755
4756         // add array.js redirectors
4757         forEach(["indexOf", "lastIndexOf", "every", "some"], function(name){
4758                 var f = array[name];
4759                 nlp[name] = function(){ return f.apply(dojo, [this].concat(aps.call(arguments, 0))); };
4760         });
4761
4762         lang.extend(NodeList, {
4763                 // copy the constructors
4764                 constructor: nl,
4765                 _NodeListCtor: nl,
4766                 toString: function(){
4767                         // Array.prototype.toString can't be applied to objects, so we use join
4768                         return this.join(",");
4769                 },
4770                 _stash: function(parent){
4771                         // summary:
4772                         //              private function to hold to a parent NodeList. end() to return the parent NodeList.
4773                         //
4774                         // example:
4775                         //              How to make a `dojo/NodeList` method that only returns the third node in
4776                         //              the dojo/NodeList but allows access to the original NodeList by using this._stash:
4777                         //      |       dojo.extend(NodeList, {
4778                         //      |               third: function(){
4779                         //      |                       var newNodeList = NodeList(this[2]);
4780                         //      |                       return newNodeList._stash(this);
4781                         //      |               }
4782                         //      |       });
4783                         //      |       // then see how _stash applies a sub-list, to be .end()'ed out of
4784                         //      |       dojo.query(".foo")
4785                         //      |               .third()
4786                         //      |                       .addClass("thirdFoo")
4787                         //      |               .end()
4788                         //      |               // access to the orig .foo list
4789                         //      |               .removeClass("foo")
4790                         //      |
4791                         //
4792                         this._parent = parent;
4793                         return this; // dojo/NodeList
4794                 },
4795
4796                 on: function(eventName, listener){
4797                         // summary:
4798                         //              Listen for events on the nodes in the NodeList. Basic usage is:
4799                         //              | query(".my-class").on("click", listener);
4800                         //              This supports event delegation by using selectors as the first argument with the event names as
4801                         //              pseudo selectors. For example:
4802                         //              | dojo.query("#my-list").on("li:click", listener);
4803                         //              This will listen for click events within `<li>` elements that are inside the `#my-list` element.
4804                         //              Because on supports CSS selector syntax, we can use comma-delimited events as well:
4805                         //              | dojo.query("#my-list").on("li button:mouseover, li:click", listener);
4806                         var handles = this.map(function(node){
4807                                 return on(node, eventName, listener); // TODO: apply to the NodeList so the same selector engine is used for matches
4808                         });
4809                         handles.remove = function(){
4810                                 for(var i = 0; i < handles.length; i++){
4811                                         handles[i].remove();
4812                                 }
4813                         };
4814                         return handles;
4815                 },
4816
4817                 end: function(){
4818                         // summary:
4819                         //              Ends use of the current `NodeList` by returning the previous NodeList
4820                         //              that generated the current NodeList.
4821                         // description:
4822                         //              Returns the `NodeList` that generated the current `NodeList`. If there
4823                         //              is no parent NodeList, an empty NodeList is returned.
4824                         // example:
4825                         //      |       dojo.query("a")
4826                         //      |               .filter(".disabled")
4827                         //      |                       // operate on the anchors that only have a disabled class
4828                         //      |                       .style("color", "grey")
4829                         //      |               .end()
4830                         //      |               // jump back to the list of anchors
4831                         //      |               .style(...)
4832                         //
4833                         if(this._parent){
4834                                 return this._parent;
4835                         }else{
4836                                 //Just return empty list.
4837                                 return new this._NodeListCtor(0);
4838                         }
4839                 },
4840
4841                 // http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array#Methods
4842
4843                 // FIXME: handle return values for #3244
4844                 //              http://trac.dojotoolkit.org/ticket/3244
4845
4846                 // FIXME:
4847                 //              need to wrap or implement:
4848                 //                      join (perhaps w/ innerHTML/outerHTML overload for toString() of items?)
4849                 //                      reduce
4850                 //                      reduceRight
4851
4852                 /*=====
4853                 slice: function(begin, end){
4854                         // summary:
4855                         //              Returns a new NodeList, maintaining this one in place
4856                         // description:
4857                         //              This method behaves exactly like the Array.slice method
4858                         //              with the caveat that it returns a dojo/NodeList and not a
4859                         //              raw Array. For more details, see Mozilla's [slice
4860                         //              documentation](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/slice)
4861                         // begin: Integer
4862                         //              Can be a positive or negative integer, with positive
4863                         //              integers noting the offset to begin at, and negative
4864                         //              integers denoting an offset from the end (i.e., to the left
4865                         //              of the end)
4866                         // end: Integer?
4867                         //              Optional parameter to describe what position relative to
4868                         //              the NodeList's zero index to end the slice at. Like begin,
4869                         //              can be positive or negative.
4870                         return this._wrap(a.slice.apply(this, arguments));
4871                 },
4872
4873                 splice: function(index, howmany, item){
4874                         // summary:
4875                         //              Returns a new NodeList, manipulating this NodeList based on
4876                         //              the arguments passed, potentially splicing in new elements
4877                         //              at an offset, optionally deleting elements
4878                         // description:
4879                         //              This method behaves exactly like the Array.splice method
4880                         //              with the caveat that it returns a dojo/NodeList and not a
4881                         //              raw Array. For more details, see Mozilla's [splice
4882                         //              documentation](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/splice)
4883                         //              For backwards compatibility, calling .end() on the spliced NodeList
4884                         //              does not return the original NodeList -- splice alters the NodeList in place.
4885                         // index: Integer
4886                         //              begin can be a positive or negative integer, with positive
4887                         //              integers noting the offset to begin at, and negative
4888                         //              integers denoting an offset from the end (i.e., to the left
4889                         //              of the end)
4890                         // howmany: Integer?
4891                         //              Optional parameter to describe what position relative to
4892                         //              the NodeList's zero index to end the slice at. Like begin,
4893                         //              can be positive or negative.
4894                         // item: Object...?
4895                         //              Any number of optional parameters may be passed in to be
4896                         //              spliced into the NodeList
4897                         return this._wrap(a.splice.apply(this, arguments));     // dojo/NodeList
4898                 },
4899
4900                 indexOf: function(value, fromIndex){
4901                         // summary:
4902                         //              see dojo.indexOf(). The primary difference is that the acted-on
4903                         //              array is implicitly this NodeList
4904                         // value: Object
4905                         //              The value to search for.
4906                         // fromIndex: Integer?
4907                         //              The location to start searching from. Optional. Defaults to 0.
4908                         // description:
4909                         //              For more details on the behavior of indexOf, see Mozilla's
4910                         //              [indexOf
4911                         //              docs](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf)
4912                         // returns:
4913                         //              Positive Integer or 0 for a match, -1 of not found.
4914                         return d.indexOf(this, value, fromIndex); // Integer
4915                 },
4916
4917                 lastIndexOf: function(value, fromIndex){
4918                         // summary:
4919                         //              see dojo.lastIndexOf(). The primary difference is that the
4920                         //              acted-on array is implicitly this NodeList
4921                         // description:
4922                         //              For more details on the behavior of lastIndexOf, see
4923                         //              Mozilla's [lastIndexOf
4924                         //              docs](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf)
4925                         // value: Object
4926                         //              The value to search for.
4927                         // fromIndex: Integer?
4928                         //              The location to start searching from. Optional. Defaults to 0.
4929                         // returns:
4930                         //              Positive Integer or 0 for a match, -1 of not found.
4931                         return d.lastIndexOf(this, value, fromIndex); // Integer
4932                 },
4933
4934                 every: function(callback, thisObject){
4935                         // summary:
4936                         //              see `dojo.every()` and the [Array.every
4937                         //              docs](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every).
4938                         //              Takes the same structure of arguments and returns as
4939                         //              dojo.every() with the caveat that the passed array is
4940                         //              implicitly this NodeList
4941                         // callback: Function
4942                         //              the callback
4943                         // thisObject: Object?
4944                         //              the context
4945                         return d.every(this, callback, thisObject); // Boolean
4946                 },
4947
4948                 some: function(callback, thisObject){
4949                         // summary:
4950                         //              Takes the same structure of arguments and returns as
4951                         //              `dojo.some()` with the caveat that the passed array is
4952                         //              implicitly this NodeList.  See `dojo.some()` and Mozilla's
4953                         //              [Array.some
4954                         //              documentation](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some).
4955                         // callback: Function
4956                         //              the callback
4957                         // thisObject: Object?
4958                         //              the context
4959                         return d.some(this, callback, thisObject); // Boolean
4960                 },
4961                 =====*/
4962
4963                 concat: function(item){
4964                         // summary:
4965                         //              Returns a new NodeList comprised of items in this NodeList
4966                         //              as well as items passed in as parameters
4967                         // description:
4968                         //              This method behaves exactly like the Array.concat method
4969                         //              with the caveat that it returns a `NodeList` and not a
4970                         //              raw Array. For more details, see the [Array.concat
4971                         //              docs](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/concat)
4972                         // item: Object?
4973                         //              Any number of optional parameters may be passed in to be
4974                         //              spliced into the NodeList
4975
4976                         //return this._wrap(apc.apply(this, arguments));
4977                         // the line above won't work for the native NodeList, or for Dojo NodeLists either :-(
4978
4979                         // implementation notes:
4980                         // Array.concat() doesn't recognize native NodeLists or Dojo NodeLists
4981                         // as arrays, and so does not inline them into a unioned array, but
4982                         // appends them as single entities. Both the original NodeList and the
4983                         // items passed in as parameters must be converted to raw Arrays
4984                         // and then the concatenation result may be re-_wrap()ed as a Dojo NodeList.
4985
4986                         var t = aps.call(this, 0),
4987                                 m = array.map(arguments, function(a){
4988                                         return aps.call(a, 0);
4989                                 });
4990                         return this._wrap(apc.apply(t, m), this);       // dojo/NodeList
4991                 },
4992
4993                 map: function(/*Function*/ func, /*Function?*/ obj){
4994                         // summary:
4995                         //              see dojo.map(). The primary difference is that the acted-on
4996                         //              array is implicitly this NodeList and the return is a
4997                         //              NodeList (a subclass of Array)
4998                         return this._wrap(array.map(this, func, obj), this); // dojo/NodeList
4999                 },
5000
5001                 forEach: function(callback, thisObj){
5002                         // summary:
5003                         //              see `dojo.forEach()`. The primary difference is that the acted-on
5004                         //              array is implicitly this NodeList. If you want the option to break out
5005                         //              of the forEach loop, use every() or some() instead.
5006                         forEach(this, callback, thisObj);
5007                         // non-standard return to allow easier chaining
5008                         return this; // dojo/NodeList
5009                 },
5010                 filter: function(/*String|Function*/ filter){
5011                         // summary:
5012                         //              "masks" the built-in javascript filter() method (supported
5013                         //              in Dojo via `dojo.filter`) to support passing a simple
5014                         //              string filter in addition to supporting filtering function
5015                         //              objects.
5016                         // filter:
5017                         //              If a string, a CSS rule like ".thinger" or "div > span".
5018                         // example:
5019                         //              "regular" JS filter syntax as exposed in dojo.filter:
5020                         //              |       dojo.query("*").filter(function(item){
5021                         //              |               // highlight every paragraph
5022                         //              |               return (item.nodeName == "p");
5023                         //              |       }).style("backgroundColor", "yellow");
5024                         // example:
5025                         //              the same filtering using a CSS selector
5026                         //              |       dojo.query("*").filter("p").styles("backgroundColor", "yellow");
5027
5028                         var a = arguments, items = this, start = 0;
5029                         if(typeof filter == "string"){ // inline'd type check
5030                                 items = query._filterResult(this, a[0]);
5031                                 if(a.length == 1){
5032                                         // if we only got a string query, pass back the filtered results
5033                                         return items._stash(this); // dojo/NodeList
5034                                 }
5035                                 // if we got a callback, run it over the filtered items
5036                                 start = 1;
5037                         }
5038                         return this._wrap(array.filter(items, a[start], a[start + 1]), this);   // dojo/NodeList
5039                 },
5040                 instantiate: function(/*String|Object*/ declaredClass, /*Object?*/ properties){
5041                         // summary:
5042                         //              Create a new instance of a specified class, using the
5043                         //              specified properties and each node in the NodeList as a
5044                         //              srcNodeRef.
5045                         // example:
5046                         //              Grabs all buttons in the page and converts them to dijit/form/Button's.
5047                         //      |       var buttons = query("button").instantiate(Button, {showLabel: true});
5048                         var c = lang.isFunction(declaredClass) ? declaredClass : lang.getObject(declaredClass);
5049                         properties = properties || {};
5050                         return this.forEach(function(node){
5051                                 new c(properties, node);
5052                         });     // dojo/NodeList
5053                 },
5054                 at: function(/*===== index =====*/){
5055                         // summary:
5056                         //              Returns a new NodeList comprised of items in this NodeList
5057                         //              at the given index or indices.
5058                         //
5059                         // index: Integer...
5060                         //              One or more 0-based indices of items in the current
5061                         //              NodeList. A negative index will start at the end of the
5062                         //              list and go backwards.
5063                         //
5064                         // example:
5065                         //      Shorten the list to the first, second, and third elements
5066                         //      |       query("a").at(0, 1, 2).forEach(fn);
5067                         //
5068                         // example:
5069                         //      Retrieve the first and last elements of a unordered list:
5070                         //      |       query("ul > li").at(0, -1).forEach(cb);
5071                         //
5072                         // example:
5073                         //      Do something for the first element only, but end() out back to
5074                         //      the original list and continue chaining:
5075                         //      |       query("a").at(0).onclick(fn).end().forEach(function(n){
5076                         //      |               console.log(n); // all anchors on the page.
5077                         //      |       })
5078
5079                         var t = new this._NodeListCtor(0);
5080                         forEach(arguments, function(i){
5081                                 if(i < 0){ i = this.length + i; }
5082                                 if(this[i]){ t.push(this[i]); }
5083                         }, this);
5084                         return t._stash(this); // dojo/NodeList
5085                 }
5086         });
5087
5088         function queryForEngine(engine, NodeList){
5089                 var query = function(/*String*/ query, /*String|DOMNode?*/ root){
5090                         // summary:
5091                         //              Returns nodes which match the given CSS selector, searching the
5092                         //              entire document by default but optionally taking a node to scope
5093                         //              the search by. Returns an instance of NodeList.
5094                         if(typeof root == "string"){
5095                                 root = dom.byId(root);
5096                                 if(!root){
5097                                         return new NodeList([]);
5098                                 }
5099                         }
5100                         var results = typeof query == "string" ? engine(query, root) : query ? query.orphan ? query : [query] : [];
5101                         if(results.orphan){
5102                                 // already wrapped
5103                                 return results;
5104                         }
5105                         return new NodeList(results);
5106                 };
5107                 query.matches = engine.match || function(node, selector, root){
5108                         // summary:
5109                         //              Test to see if a node matches a selector
5110                         return query.filter([node], selector, root).length > 0;
5111                 };
5112                 // the engine provides a filtering function, use it to for matching
5113                 query.filter = engine.filter || function(nodes, selector, root){
5114                         // summary:
5115                         //              Filters an array of nodes. Note that this does not guarantee to return a NodeList, just an array.
5116                         return query(selector, root).filter(function(node){
5117                                 return array.indexOf(nodes, node) > -1;
5118                         });
5119                 };
5120                 if(typeof engine != "function"){
5121                         var search = engine.search;
5122                         engine = function(selector, root){
5123                                 // Slick does it backwards (or everyone else does it backwards, probably the latter)
5124                                 return search(root || document, selector);
5125                         };
5126                 }
5127                 return query;
5128         }
5129         var query = queryForEngine(defaultEngine, NodeList);
5130         /*=====
5131         query = function(selector, context){
5132                 // summary:
5133                 //              This modules provides DOM querying functionality. The module export is a function
5134                 //              that can be used to query for DOM nodes by CSS selector and returns a NodeList
5135                 //              representing the matching nodes.
5136                 // selector: String
5137                 //              A CSS selector to search for.
5138                 // context: String|DomNode?
5139                 //              An optional context to limit the searching scope. Only nodes under `context` will be
5140                 //              scanned.
5141                 // example:
5142                 //              add an onclick handler to every submit button in the document
5143                 //              which causes the form to be sent via Ajax instead:
5144                 //      |       require(["dojo/query"], function(query){
5145                 //      |               query("input[type='submit']").on("click", function(e){
5146                 //      |                       dojo.stopEvent(e); // prevent sending the form
5147                 //      |                       var btn = e.target;
5148                 //      |                       dojo.xhrPost({
5149                 //      |                               form: btn.form,
5150                 //      |                               load: function(data){
5151                 //      |                                       // replace the form with the response
5152                 //      |                                       var div = dojo.doc.createElement("div");
5153                 //      |                                       dojo.place(div, btn.form, "after");
5154                 //      |                                       div.innerHTML = data;
5155                 //      |                                       dojo.style(btn.form, "display", "none");
5156                 //      |                               }
5157                 //      |                       });
5158                 //      |               });
5159                 // |    });
5160                 //
5161                 // description:
5162                 //              dojo/query is responsible for loading the appropriate query engine and wrapping
5163                 //              its results with a `NodeList`. You can use dojo/query with a specific selector engine
5164                 //              by using it as a plugin. For example, if you installed the sizzle package, you could
5165                 //              use it as the selector engine with:
5166                 //              |       require(["dojo/query!sizzle"], function(query){
5167                 //              |               query("div")...
5168                 //
5169                 //              The id after the ! can be a module id of the selector engine or one of the following values:
5170                 //
5171                 //              - acme: This is the default engine used by Dojo base, and will ensure that the full
5172                 //              Acme engine is always loaded.
5173                 //
5174                 //              - css2: If the browser has a native selector engine, this will be used, otherwise a
5175                 //              very minimal lightweight selector engine will be loaded that can do simple CSS2 selectors
5176                 //              (by #id, .class, tag, and [name=value] attributes, with standard child or descendant (>)
5177                 //              operators) and nothing more.
5178                 //
5179                 //              - css2.1: If the browser has a native selector engine, this will be used, otherwise the
5180                 //              full Acme engine will be loaded.
5181                 //
5182                 //              - css3: If the browser has a native selector engine with support for CSS3 pseudo
5183                 //              selectors (most modern browsers except IE8), this will be used, otherwise the
5184                 //              full Acme engine will be loaded.
5185                 //
5186                 //              - Or the module id of a selector engine can be used to explicitly choose the selector engine
5187                 //
5188                 //              For example, if you are using CSS3 pseudo selectors in module, you can specify that
5189                 //              you will need support them with:
5190                 //              |       require(["dojo/query!css3"], function(query){
5191                 //              |               query('#t > h3:nth-child(odd)')...
5192                 //
5193                 //              You can also choose the selector engine/load configuration by setting the query-selector:
5194                 //              For example:
5195                 //              |       <script data-dojo-config="query-selector:'css3'" src="dojo.js"></script>
5196                 //
5197                 return new NodeList(); // dojo/NodeList
5198          };
5199          =====*/
5200
5201         // the query that is returned from this module is slightly different than dojo.query,
5202         // because dojo.query has to maintain backwards compatibility with returning a
5203         // true array which has performance problems. The query returned from the module
5204         // does not use true arrays, but rather inherits from Array, making it much faster to
5205         // instantiate.
5206         dojo.query = queryForEngine(defaultEngine, function(array){
5207                 // call it without the new operator to invoke the back-compat behavior that returns a true array
5208                 return NodeList(array); // dojo/NodeList
5209         });
5210
5211         query.load = function(id, parentRequire, loaded){
5212                 // summary:
5213                 //              can be used as AMD plugin to conditionally load new query engine
5214                 // example:
5215                 //      |       require(["dojo/query!custom"], function(qsa){
5216                 //      |               // loaded selector/custom.js as engine
5217                 //      |               qsa("#foobar").forEach(...);
5218                 //      |       });
5219                 loader.load(id, parentRequire, function(engine){
5220                         loaded(queryForEngine(engine, NodeList));
5221                 });
5222         };
5223
5224         dojo._filterQueryResult = query._filterResult = function(nodes, selector, root){
5225                 return new NodeList(query.filter(nodes, selector, root));
5226         };
5227         dojo.NodeList = query.NodeList = NodeList;
5228         return query;
5229 });
5230
5231 },
5232 'dojo/has':function(){
5233 define(["require", "module"], function(require, module){
5234         // module:
5235         //              dojo/has
5236         // summary:
5237         //              Defines the has.js API and several feature tests used by dojo.
5238         // description:
5239         //              This module defines the has API as described by the project has.js with the following additional features:
5240         //
5241         //              - the has test cache is exposed at has.cache.
5242         //              - the method has.add includes a forth parameter that controls whether or not existing tests are replaced
5243         //              - the loader's has cache may be optionally copied into this module's has cahce.
5244         //
5245         //              This module adopted from https://github.com/phiggins42/has.js; thanks has.js team!
5246
5247         // try to pull the has implementation from the loader; both the dojo loader and bdLoad provide one
5248         // if using a foreign loader, then the has cache may be initialized via the config object for this module
5249         // WARNING: if a foreign loader defines require.has to be something other than the has.js API, then this implementation fail
5250         var has = require.has || function(){};
5251         if(! 1 ){
5252                 var
5253                         isBrowser =
5254                                 // the most fundamental decision: are we in the browser?
5255                                 typeof window != "undefined" &&
5256                                 typeof location != "undefined" &&
5257                                 typeof document != "undefined" &&
5258                                 window.location == location && window.document == document,
5259
5260                         // has API variables
5261                         global = this,
5262                         doc = isBrowser && document,
5263                         element = doc && doc.createElement("DiV"),
5264                         cache = (module.config && module.config()) || {};
5265
5266                 has = function(name){
5267                         // summary:
5268                         //              Return the current value of the named feature.
5269                         //
5270                         // name: String|Integer
5271                         //              The name (if a string) or identifier (if an integer) of the feature to test.
5272                         //
5273                         // description:
5274                         //              Returns the value of the feature named by name. The feature must have been
5275                         //              previously added to the cache by has.add.
5276
5277                         return typeof cache[name] == "function" ? (cache[name] = cache[name](global, doc, element)) : cache[name]; // Boolean
5278                 };
5279
5280                 has.cache = cache;
5281
5282                 has.add = function(name, test, now, force){
5283                         // summary:
5284                         //              Register a new feature test for some named feature.
5285                         // name: String|Integer
5286                         //              The name (if a string) or identifier (if an integer) of the feature to test.
5287                         // test: Function
5288                         //               A test function to register. If a function, queued for testing until actually
5289                         //               needed. The test function should return a boolean indicating
5290                         //              the presence of a feature or bug.
5291                         // now: Boolean?
5292                         //               Optional. Omit if `test` is not a function. Provides a way to immediately
5293                         //               run the test and cache the result.
5294                         // force: Boolean?
5295                         //              Optional. If the test already exists and force is truthy, then the existing
5296                         //              test will be replaced; otherwise, add does not replace an existing test (that
5297                         //              is, by default, the first test advice wins).
5298                         // example:
5299                         //              A redundant test, testFn with immediate execution:
5300                         //      |       has.add("javascript", function(){ return true; }, true);
5301                         //
5302                         // example:
5303                         //              Again with the redundantness. You can do this in your tests, but we should
5304                         //              not be doing this in any internal has.js tests
5305                         //      |       has.add("javascript", true);
5306                         //
5307                         // example:
5308                         //              Three things are passed to the testFunction. `global`, `document`, and a generic element
5309                         //              from which to work your test should the need arise.
5310                         //      |       has.add("bug-byid", function(g, d, el){
5311                         //      |               // g    == global, typically window, yadda yadda
5312                         //      |               // d    == document object
5313                         //      |               // el == the generic element. a `has` element.
5314                         //      |               return false; // fake test, byid-when-form-has-name-matching-an-id is slightly longer
5315                         //      |       });
5316
5317                         (typeof cache[name]=="undefined" || force) && (cache[name]= test);
5318                         return now && has(name);
5319                 };
5320
5321                 // since we're operating under a loader that doesn't provide a has API, we must explicitly initialize
5322                 // has as it would have otherwise been initialized by the dojo loader; use has.add to the builder
5323                 // can optimize these away iff desired
5324                  1 || has.add("host-browser", isBrowser);
5325                  1 || has.add("dom", isBrowser);
5326                  1 || has.add("dojo-dom-ready-api", 1);
5327                  1 || has.add("dojo-sniff", 1);
5328         }
5329
5330         if( 1 ){
5331                 // Common application level tests
5332                 has.add("dom-addeventlistener", !!document.addEventListener);
5333                 has.add("touch", "ontouchstart" in document);
5334                 // I don't know if any of these tests are really correct, just a rough guess
5335                 has.add("device-width", screen.availWidth || innerWidth);
5336
5337                 // Tests for DOMNode.attributes[] behavior:
5338                 //       - dom-attributes-explicit - attributes[] only lists explicitly user specified attributes
5339                 //       - dom-attributes-specified-flag (IE8) - need to check attr.specified flag to skip attributes user didn't specify
5340                 //       - Otherwise, in IE6-7. attributes[] will list hundreds of values, so need to do outerHTML to get attrs instead.
5341                 var form = document.createElement("form");
5342                 has.add("dom-attributes-explicit", form.attributes.length == 0); // W3C
5343                 has.add("dom-attributes-specified-flag", form.attributes.length > 0 && form.attributes.length < 40);    // IE8
5344         }
5345
5346         has.clearElement = function(element){
5347                 // summary:
5348                 //       Deletes the contents of the element passed to test functions.
5349                 element.innerHTML= "";
5350                 return element;
5351         };
5352
5353         has.normalize = function(id, toAbsMid){
5354                 // summary:
5355                 //       Resolves id into a module id based on possibly-nested tenary expression that branches on has feature test value(s).
5356                 //
5357                 // toAbsMid: Function
5358                 //       Resolves a relative module id into an absolute module id
5359                 var
5360                         tokens = id.match(/[\?:]|[^:\?]*/g), i = 0,
5361                         get = function(skip){
5362                                 var term = tokens[i++];
5363                                 if(term == ":"){
5364                                         // empty string module name, resolves to 0
5365                                         return 0;
5366                                 }else{
5367                                         // postfixed with a ? means it is a feature to branch on, the term is the name of the feature
5368                                         if(tokens[i++] == "?"){
5369                                                 if(!skip && has(term)){
5370                                                         // matched the feature, get the first value from the options
5371                                                         return get();
5372                                                 }else{
5373                                                         // did not match, get the second value, passing over the first
5374                                                         get(true);
5375                                                         return get(skip);
5376                                                 }
5377                                         }
5378                                         // a module
5379                                         return term || 0;
5380                                 }
5381                         };
5382                 id = get();
5383                 return id && toAbsMid(id);
5384         };
5385
5386         has.load = function(id, parentRequire, loaded){
5387                 // summary:
5388                 //              Conditional loading of AMD modules based on a has feature test value.
5389                 // id: String
5390                 //              Gives the resolved module id to load.
5391                 // parentRequire: Function
5392                 //              The loader require function with respect to the module that contained the plugin resource in it's
5393                 //              dependency list.
5394                 // loaded: Function
5395                 //       Callback to loader that consumes result of plugin demand.
5396
5397                 if(id){
5398                         parentRequire([id], loaded);
5399                 }else{
5400                         loaded();
5401                 }
5402         };
5403
5404         return has;
5405 });
5406
5407 },
5408 'dojo/_base/loader':function(){
5409 define(["./kernel", "../has", "require", "module", "./json", "./lang", "./array"], function(dojo, has, require, thisModule, json, lang, array) {
5410         // module:
5411         //              dojo/_base/loader
5412
5413         //              This module defines the v1.x synchronous loader API.
5414
5415         // signal the loader in sync mode...
5416         //>>pure-amd
5417
5418         if (! 1 ){
5419                 console.error("cannot load the Dojo v1.x loader with a foreign loader");
5420                 return 0;
5421         }
5422
5423          1 || has.add("dojo-fast-sync-require", 1);
5424
5425
5426         var makeErrorToken = function(id){
5427                         return {src:thisModule.id, id:id};
5428                 },
5429
5430                 slashName = function(name){
5431                         return name.replace(/\./g, "/");
5432                 },
5433
5434                 buildDetectRe = /\/\/>>built/,
5435
5436                 dojoRequireCallbacks = [],
5437                 dojoRequireModuleStack = [],
5438
5439                 dojoRequirePlugin = function(mid, require, loaded){
5440                         dojoRequireCallbacks.push(loaded);
5441                         array.forEach(mid.split(","), function(mid){
5442                                 var module = getModule(mid, require.module);
5443                                 dojoRequireModuleStack.push(module);
5444                                 injectModule(module);
5445                         });
5446                         checkDojoRequirePlugin();
5447                 },
5448
5449                 checkDojoRequirePlugin = ( 1  ?
5450                         // This version of checkDojoRequirePlugin makes the observation that all dojoRequireCallbacks can be released
5451                         // when all *non-dojo/require!, dojo/loadInit!* modules are either executed, not requested, or arrived. This is
5452                         // the case since there are no more modules the loader is waiting for, therefore, dojo/require! must have
5453                         // everything it needs on board.
5454                         //
5455                         // The potential weakness of this algorithm is that dojo/require will not execute callbacks until *all* dependency
5456                         // trees are ready. It is possible that some trees may be ready earlier than others, and this extra wait is non-optimal.
5457                         // Still, for big projects, this seems better than the original algorithm below that proved slow in some cases.
5458                         // Note, however, the original algorithm had the potential to execute partial trees,  but that potential was never enabled.
5459                         // There are also other optimization available with the original algorithm that have not been explored.
5460                         function(){
5461                                 var module, mid;
5462                                 for(mid in modules){
5463                                         module = modules[mid];
5464                                         if(module.noReqPluginCheck===undefined){
5465                                                 // tag the module as either a loadInit or require plugin or not for future reference
5466                                                 module.noReqPluginCheck = /loadInit\!/.test(mid) || /require\!/.test(mid) ? 1 : 0;
5467                                         }
5468                                         if(!module.executed && !module.noReqPluginCheck && module.injected==requested){
5469                                                 return;
5470                                         }
5471                                 }
5472
5473                                 guardCheckComplete(function(){
5474                                         var oldCallbacks = dojoRequireCallbacks;
5475                                         dojoRequireCallbacks = [];
5476                                         array.forEach(oldCallbacks, function(cb){cb(1);});
5477                                 });
5478                 } : (function(){
5479                         // Note: this is the original checkDojoRequirePlugin that is much slower than the algorithm above. However, we know it
5480                         // works, so we leave it here in case the algorithm above fails in some corner case.
5481                         //
5482                         // checkDojoRequirePlugin inspects all of the modules demanded by a dojo/require!<module-list> dependency
5483                         // to see if they have arrived. The loader does not release *any* of these modules to be instantiated
5484                         // until *all* of these modules are on board, thereby preventing the evaluation of a module with dojo.require's
5485                         // that reference modules that are not available.
5486                         //
5487                         // The algorithm works by traversing the dependency graphs (remember, there can be cycles so they are not trees)
5488                         // of each module in the dojoRequireModuleStack array (which contains the list of modules demanded by dojo/require!).
5489                         // The moment a single module is discovered that is missing, the algorithm gives up and indicates that not all
5490                         // modules are on board. dojo/loadInit! and dojo/require! are ignored because there dependencies are inserted
5491                         // directly in dojoRequireModuleStack. For example, if "your/module" module depends on "dojo/require!my/module", then
5492                         // *both* "dojo/require!my/module" and "my/module" will be in dojoRequireModuleStack. Obviously, if "my/module"
5493                         // is on board, then "dojo/require!my/module" is also satisfied, so the algorithm doesn't check for "dojo/require!my/module".
5494                         //
5495                         // Note: inserting a dojo/require!<some-module-list> dependency in the dojoRequireModuleStack achieves nothing
5496                         // with the current algorithm; however, having such modules present makes it possible to optimize the algorithm
5497                         //
5498                         // Note: prior versions of this algorithm had an optimization that signaled loaded on dojo/require! dependencies
5499                         // individually (rather than waiting for them all to be resolved). The implementation proved problematic with cycles
5500                         // and plugins. However, it is possible to reattach that strategy in the future.
5501
5502                         // a set from module-id to {undefined | 1 | 0}, where...
5503                         //       undefined => the module has not been inspected
5504                         //       0 => the module or at least one of its dependencies has not arrived
5505                         //       1 => the module is a loadInit! or require! plugin resource, or is currently being traversed (therefore, assume
5506                         //                OK until proven otherwise), or has been completely traversed and all dependencies have arrived
5507
5508                         var touched,
5509                         traverse = function(m){
5510                                 touched[m.mid] = 1;
5511                                 for(var t, module, deps = m.deps || [], i= 0; i<deps.length; i++){
5512                                         module = deps[i];
5513                                         if(!(t = touched[module.mid])){
5514                                                 if(t===0 || !traverse(module)){
5515                                                         touched[m.mid] = 0;
5516                                                         return false;
5517                                                 }
5518                                         }
5519                                 }
5520                                 return true;
5521                         };
5522
5523                         return function(){
5524                                 // initialize the touched hash with easy-to-compute values that help short circuit recursive algorithm;
5525                                 // recall loadInit/require plugin modules are dependencies of modules in dojoRequireModuleStack...
5526                                 // which would cause a circular dependency chain that would never be resolved if checked here
5527                                 // notice all dependencies of any particular loadInit/require plugin module will already
5528                                 // be checked since those are pushed into dojoRequireModuleStack explicitly by the
5529                                 // plugin...so if a particular loadInitPlugin module's dependencies are not really
5530                                 // on board, that *will* be detected elsewhere in the traversal.
5531                                 var module, mid;
5532                                 touched = {};
5533                                 for(mid in modules){
5534                                         module = modules[mid];
5535                                         if(module.executed || module.noReqPluginCheck){
5536                                                 touched[mid] = 1;
5537                                         }else{
5538                                                 if(module.noReqPluginCheck!==0){
5539                                                         // tag the module as either a loadInit or require plugin or not for future reference
5540                                                         module.noReqPluginCheck = /loadInit\!/.test(mid) || /require\!/.test(mid) ? 1 : 0;
5541                                                 }
5542                                                 if(module.noReqPluginCheck){
5543                                                         touched[mid] = 1;
5544                                                 }else if(module.injected!==arrived){
5545                                                         // not executed, has not arrived, and is not a loadInit or require plugin resource
5546                                                         touched[mid] = 0;
5547                                                 }// else, leave undefined and we'll traverse the dependencies
5548                                         }
5549                                 }
5550                                 for(var t, i = 0, end = dojoRequireModuleStack.length; i<end; i++){
5551                                         module = dojoRequireModuleStack[i];
5552                                         if(!(t = touched[module.mid])){
5553                                                 if(t===0 || !traverse(module)){
5554                                                         return;
5555                                                 }
5556                                         }
5557                                 }
5558                                 guardCheckComplete(function(){
5559                                         var oldCallbacks = dojoRequireCallbacks;
5560                                         dojoRequireCallbacks = [];
5561                                         array.forEach(oldCallbacks, function(cb){cb(1);});
5562                                 });
5563                         };
5564                 })()),
5565
5566                 dojoLoadInitPlugin = function(mid, require, loaded){
5567                         // mid names a module that defines a "dojo load init" bundle, an object with two properties:
5568                         //
5569                         //       * names: a vector of module ids that give top-level names to define in the lexical scope of def
5570                         //       * def: a function that contains some some legacy loader API applications
5571                         //
5572                         // The point of def is to possibly cause some modules to be loaded (but not executed) by dojo/require! where the module
5573                         // ids are possibly-determined at runtime. For example, here is dojox.gfx from v1.6 expressed as an AMD module using the dojo/loadInit
5574                         // and dojo/require plugins.
5575                         //
5576                         // // dojox/gfx:
5577                         //
5578                         //       define("*loadInit_12, {
5579                         //         names:["dojo", "dijit", "dojox"],
5580                         //         def: function(){
5581                         //               dojo.loadInit(function(){
5582                         //                 var gfx = lang.getObject("dojox.gfx", true);
5583                         //
5584                         //                 //
5585                         //                 // code required to set gfx properties ommitted...
5586                         //                 //
5587                         //
5588                         //                 // now use the calculations to include the runtime-dependent module
5589                         //                 dojo.require("dojox.gfx." + gfx.renderer);
5590                         //               });
5591                         //         }
5592                         //       });
5593                         //
5594                         //       define(["dojo", "dojo/loadInit!" + id].concat("dojo/require!dojox/gfx/matric,dojox/gfx/_base"), function(dojo){
5595                         //         // when this AMD factory function is executed, the following modules are guaranteed downloaded but not executed:
5596                         //         //   "dojox.gfx." + gfx.renderer
5597                         //         //   dojox.gfx.matrix
5598                         //         //   dojox.gfx._base
5599                         //         dojo.provide("dojo.gfx");
5600                         //         dojo.require("dojox.gfx.matrix");
5601                         //         dojo.require("dojox.gfx._base");
5602                         //         dojo.require("dojox.gfx." + gfx.renderer);
5603                         //         return lang.getObject("dojo.gfx");
5604                         //       });
5605                         //      })();
5606                         //
5607                         // The idea is to run the legacy loader API with global variables shadowed, which allows these variables to
5608                         // be relocated. For example, dojox and dojo could be relocated to different names by giving a map and the code above will
5609                         // execute properly (because the plugin below resolves the load init bundle.names module with respect to the module that demanded
5610                         // the plugin resource).
5611                         //
5612                         // Note that the relocation is specified in the runtime configuration; relocated names need not be set at build-time.
5613                         //
5614                         // Warning: this is not the best way to express dojox.gfx as and AMD module. In fact, the module has been properly converted in
5615                         // v1.7. However, this technique allows the builder to convert legacy modules into AMD modules and guarantee the codepath is the
5616                         // same in the converted AMD module.
5617                         require([mid], function(bundle){
5618                                 // notice how names is resolved with respect to the module that demanded the plugin resource
5619                                 require(bundle.names, function(){
5620                                         // bring the bundle names into scope
5621                                         for(var scopeText = "", args= [], i = 0; i<arguments.length; i++){
5622                                                 scopeText+= "var " + bundle.names[i] + "= arguments[" + i + "]; ";
5623                                                 args.push(arguments[i]);
5624                                         }
5625                                         eval(scopeText);
5626
5627                                         var callingModule = require.module,
5628                                                 // the list of modules that need to be downloaded but not executed before the callingModule can be executed
5629                                                 requireList = [],
5630
5631                                                 // the list of i18n bundles that are xdomain; undefined if none
5632                                                 i18nDeps,
5633
5634                                                 syncLoaderApi = {
5635                                                         provide:function(moduleName){
5636                                                                 // mark modules that arrive consequent to multiple provides in this module as arrived since they can't be injected
5637                                                                 moduleName = slashName(moduleName);
5638                                                                 var providedModule = getModule(moduleName, callingModule);
5639                                                                 if(providedModule!==callingModule){
5640                                                                         setArrived(providedModule);
5641                                                                 }
5642                                                         },
5643                                                         require:function(moduleName, omitModuleCheck){
5644                                                                 moduleName = slashName(moduleName);
5645                                                                 omitModuleCheck && (getModule(moduleName, callingModule).result = nonmodule);
5646                                                                 requireList.push(moduleName);
5647                                                         },
5648                                                         requireLocalization:function(moduleName, bundleName, locale){
5649                                                                 // since we're going to need dojo/i8n, add it to i18nDeps if not already there
5650                                                                 if(!i18nDeps){
5651                                                                         // don't have to map since that will occur when the dependency is resolved
5652                                                                         i18nDeps = ["dojo/i18n"];
5653                                                                 }
5654
5655                                                                 // figure out if the bundle is xdomain; if so, add it to the i18nDepsSet
5656                                                                 locale = (locale || dojo.locale).toLowerCase();
5657                                                                 moduleName = slashName(moduleName) + "/nls/" + (/root/i.test(locale) ? "" : locale + "/") + slashName(bundleName);
5658                                                                 if(getModule(moduleName, callingModule).isXd){
5659                                                                         // don't have to map since that will occur when the dependency is resolved
5660                                                                         i18nDeps.push("dojo/i18n!" + moduleName);
5661                                                                 }// else the bundle will be loaded synchronously when the module is evaluated
5662                                                         },
5663                                                         loadInit:function(f){
5664                                                                 f();
5665                                                         }
5666                                                 },
5667
5668                                                 hold = {},
5669                                                 p;
5670
5671                                         // hijack the correct dojo and apply bundle.def
5672                                         try{
5673                                                 for(p in syncLoaderApi){
5674                                                         hold[p] = dojo[p];
5675                                                         dojo[p] = syncLoaderApi[p];
5676                                                 }
5677                                                 bundle.def.apply(null, args);
5678                                         }catch(e){
5679                                                 signal("error", [makeErrorToken("failedDojoLoadInit"), e]);
5680                                         }finally{
5681                                                 for(p in syncLoaderApi){
5682                                                         dojo[p] = hold[p];
5683                                                 }
5684                                         }
5685
5686                                         if(i18nDeps){
5687                                                 requireList = requireList.concat(i18nDeps);
5688                                         }
5689
5690                                         if(requireList.length){
5691                                                 dojoRequirePlugin(requireList.join(","), require, loaded);
5692                                         }else{
5693                                                 loaded();
5694                                         }
5695                                 });
5696                         });
5697                 },
5698
5699                 extractApplication = function(
5700                         text,                     // the text to search
5701                         startSearch,      // the position in text to start looking for the closing paren
5702                         startApplication  // the position in text where the function application expression starts
5703                 ){
5704                         // find end of the call by finding the matching end paren
5705                         // Warning: as usual, this will fail in the presense of unmatched right parans contained in strings, regexs, or unremoved comments
5706                         var parenRe = /\(|\)/g,
5707                                 matchCount = 1,
5708                                 match;
5709                         parenRe.lastIndex = startSearch;
5710                         while((match = parenRe.exec(text))){
5711                                 if(match[0] == ")"){
5712                                         matchCount -= 1;
5713                                 }else{
5714                                         matchCount += 1;
5715                                 }
5716                                 if(matchCount == 0){
5717                                         break;
5718                                 }
5719                         }
5720
5721                         if(matchCount != 0){
5722                                 throw "unmatched paren around character " + parenRe.lastIndex + " in: " + text;
5723                         }
5724
5725                         //Put the master matching string in the results.
5726                         return [dojo.trim(text.substring(startApplication, parenRe.lastIndex))+";\n", parenRe.lastIndex];
5727                 },
5728
5729                 // the following regex is taken from 1.6. It is a very poor technique to remove comments and
5730                 // will fail in some cases; for example, consider the code...
5731                 //
5732                 //        var message = "Category-1 */* Category-2";
5733                 //
5734                 // The regex that follows will see a /* comment and trash the code accordingly. In fact, there are all
5735                 // kinds of cases like this with strings and regexs that will cause this design to fail miserably.
5736                 //
5737                 // Alternative regex designs exist that will result in less-likely failures, but will still fail in many cases.
5738                 // The only solution guaranteed 100% correct is to parse the code and that seems overkill for this
5739                 // backcompat/unbuilt-xdomain layer. In the end, since it's been this way for a while, we won't change it.
5740                 // See the opening paragraphs of Chapter 7 or ECME-262 which describes the lexical abiguity further.
5741                 removeCommentRe = /(\/\*([\s\S]*?)\*\/|\/\/(.*)$)/mg,
5742
5743                 syncLoaderApiRe = /(^|\s)dojo\.(loadInit|require|provide|requireLocalization|requireIf|requireAfterIf|platformRequire)\s*\(/mg,
5744
5745                 amdLoaderApiRe = /(^|\s)(require|define)\s*\(/m,
5746
5747                 extractLegacyApiApplications = function(text, noCommentText){
5748                         // scan the noCommentText for any legacy loader API applications. Copy such applications into result (this is
5749                         // used by the builder). Move dojo.loadInit applications to loadInitApplications string. Copy all other applications
5750                         // to otherApplications string. If no applications were found, return 0, signalling an AMD module. Otherwise, return
5751                         // loadInitApplications + otherApplications. Fixup text by replacing
5752                         //
5753                         //       dojo.loadInit(// etc...
5754                         //
5755                         // with
5756                         //
5757                         //       \n 0 && dojo.loadInit(// etc...
5758                         //
5759                         // Which results in the dojo.loadInit from *not* being applied. This design goes a long way towards protecting the
5760                         // code from an over-agressive removeCommentRe. However...
5761                         //
5762                         // WARNING: the removeCommentRe will cause an error if a detected comment removes all or part of a legacy-loader application
5763                         // that is not in a comment.
5764
5765                         var match, startSearch, startApplication, application,
5766                                 loadInitApplications = [],
5767                                 otherApplications = [],
5768                                 allApplications = [];
5769
5770                         // noCommentText may be provided by a build app with comments extracted by a better method than regex (hopefully)
5771                         noCommentText = noCommentText || text.replace(removeCommentRe, function(match){
5772                                 // remove iff the detected comment has text that looks like a sync loader API application; this helps by
5773                                 // removing as little as possible, minimizing the changes the janky regex will kill the module
5774                                 syncLoaderApiRe.lastIndex = amdLoaderApiRe.lastIndex = 0;
5775                                 return (syncLoaderApiRe.test(match) || amdLoaderApiRe.test(match)) ? "" : match;
5776                         });
5777
5778                         // find and extract all dojo.loadInit applications
5779                         while((match = syncLoaderApiRe.exec(noCommentText))){
5780                                 startSearch = syncLoaderApiRe.lastIndex;
5781                                 startApplication = startSearch  - match[0].length;
5782                                 application = extractApplication(noCommentText, startSearch, startApplication);
5783                                 if(match[2]=="loadInit"){
5784                                         loadInitApplications.push(application[0]);
5785                                 }else{
5786                                         otherApplications.push(application[0]);
5787                                 }
5788                                 syncLoaderApiRe.lastIndex = application[1];
5789                         }
5790                         allApplications = loadInitApplications.concat(otherApplications);
5791                         if(allApplications.length || !amdLoaderApiRe.test(noCommentText)){
5792                                 // either there were some legacy loader API applications or there were no AMD API applications
5793                                 return [text.replace(/(^|\s)dojo\.loadInit\s*\(/g, "\n0 && dojo.loadInit("), allApplications.join(""), allApplications];
5794                         }else{
5795                                 // legacy loader API *was not* detected and AMD API *was* detected; therefore, assume it's an AMD module
5796                                 return 0;
5797                         }
5798                 },
5799
5800                 transformToAmd = function(module, text){
5801                         // This is roughly the equivalent of dojo._xdCreateResource in 1.6-; however, it expresses a v1.6- dojo
5802                         // module in terms of AMD define instead of creating the dojo proprietary xdomain module expression.
5803                         // The module could have originated from several sources:
5804                         //
5805                         //       * amd require() a module, e.g., require(["my/module"])
5806                         //       * amd require() a nonmodule, e.g., require(["my/resource.js"')
5807                         //       * amd define() deps vector (always a module)
5808                         //       * dojo.require() a module, e.g. dojo.require("my.module")
5809                         //       * dojo.require() a nonmodule, e.g., dojo.require("my.module", true)
5810                         //       * dojo.requireIf/requireAfterIf/platformRequire a module
5811                         //
5812                         // The module is scanned for legacy loader API applications; if none are found, then assume the module is an
5813                         // AMD module and return 0. Otherwise, a synthetic dojo/loadInit plugin resource is created and the module text
5814                         // is rewritten as an AMD module with the single dependency of this synthetic resource. When the dojo/loadInit
5815                         // plugin loaded the synthetic resource, it will cause all dojo.loadInit's to be executed, find all dojo.require's
5816                         // (either directly consequent to dojo.require or indirectly consequent to dojo.require[After]If or
5817                         // dojo.platformRequire, and finally cause loading of all dojo.required modules with the dojo/require plugin. Thus,
5818                         // when the dojo/loadInit plugin reports it has been loaded, all modules required by the given module are guaranteed
5819                         // loaded (but not executed). This then allows the module to execute it's code path without interupts, thereby
5820                         // following the synchronous code path.
5821                         //
5822                         // Notice that this function behaves the same whether or not it happens to be in a mapped dojo/loader module.
5823
5824                         var extractResult, id, names = [], namesAsStrings = [];
5825                         if(buildDetectRe.test(text) || !(extractResult = extractLegacyApiApplications(text))){
5826                                 // buildDetectRe.test(text) => a built module, always AMD
5827                                 // extractResult==0 => no sync API
5828                                 return 0;
5829                         }
5830
5831                         // manufacture a synthetic module id that can never be a real mdule id (just like require does)
5832                         id = module.mid + "-*loadInit";
5833
5834                         // construct the dojo/loadInit names vector which causes any relocated names to be defined as lexical variables under their not-relocated name
5835                         // the dojo/loadInit plugin assumes the first name in names is "dojo"
5836
5837                         for(var p in getModule("dojo", module).result.scopeMap){
5838                                 names.push(p);
5839                                 namesAsStrings.push('"' + p + '"');
5840                         }
5841
5842                         // rewrite the module as a synthetic dojo/loadInit plugin resource + the module expressed as an AMD module that depends on this synthetic resource
5843                         // don't have to map dojo/init since that will occur when the dependency is resolved
5844                         return "// xdomain rewrite of " + module.mid + "\n" +
5845                                 "define('" + id + "',{\n" +
5846                                 "\tnames:" + dojo.toJson(names) + ",\n" +
5847                                 "\tdef:function(" + names.join(",") + "){" + extractResult[1] + "}" +
5848                                 "});\n\n" +
5849                                 "define(" + dojo.toJson(names.concat(["dojo/loadInit!"+id])) + ", function(" + names.join(",") + "){\n" + extractResult[0] + "});";
5850                 },
5851
5852                 loaderVars = require.initSyncLoader(dojoRequirePlugin, checkDojoRequirePlugin, transformToAmd),
5853
5854                 sync =
5855                         loaderVars.sync,
5856
5857                 requested =
5858                         loaderVars.requested,
5859
5860                 arrived =
5861                         loaderVars.arrived,
5862
5863                 nonmodule =
5864                         loaderVars.nonmodule,
5865
5866                 executing =
5867                         loaderVars.executing,
5868
5869                 executed =
5870                         loaderVars.executed,
5871
5872                 syncExecStack =
5873                         loaderVars.syncExecStack,
5874
5875                 modules =
5876                         loaderVars.modules,
5877
5878                 execQ =
5879                         loaderVars.execQ,
5880
5881                 getModule =
5882                         loaderVars.getModule,
5883
5884                 injectModule =
5885                         loaderVars.injectModule,
5886
5887                 setArrived =
5888                         loaderVars.setArrived,
5889
5890                 signal =
5891                         loaderVars.signal,
5892
5893                 finishExec =
5894                         loaderVars.finishExec,
5895
5896                 execModule =
5897                         loaderVars.execModule,
5898
5899                 getLegacyMode =
5900                         loaderVars.getLegacyMode,
5901
5902                 guardCheckComplete =
5903                         loaderVars.guardCheckComplete;
5904
5905         // there is exactly one dojoRequirePlugin among possibly-many dojo/_base/loader's (owing to mapping)
5906         dojoRequirePlugin = loaderVars.dojoRequirePlugin;
5907
5908         dojo.provide = function(mid){
5909                 var executingModule = syncExecStack[0],
5910                         module = lang.mixin(getModule(slashName(mid), require.module), {
5911                                 executed:executing,
5912                                 result:lang.getObject(mid, true)
5913                         });
5914                 setArrived(module);
5915                 if(executingModule){
5916                         (executingModule.provides || (executingModule.provides = [])).push(function(){
5917                                 module.result = lang.getObject(mid);
5918                                 delete module.provides;
5919                                 module.executed!==executed && finishExec(module);
5920                         });
5921                 }// else dojo.provide called not consequent to loading; therefore, give up trying to publish module value to loader namespace
5922                 return module.result;
5923         };
5924
5925         has.add("config-publishRequireResult", 1, 0, 0);
5926
5927         dojo.require = function(moduleName, omitModuleCheck) {
5928                 // summary:
5929                 //              loads a Javascript module from the appropriate URI
5930                 //
5931                 // moduleName: String
5932                 //              module name to load, using periods for separators,
5933                 //               e.g. "dojo.date.locale".  Module paths are de-referenced by dojo's
5934                 //              internal mapping of locations to names and are disambiguated by
5935                 //              longest prefix. See `dojo.registerModulePath()` for details on
5936                 //              registering new modules.
5937                 //
5938                 // omitModuleCheck: Boolean?
5939                 //              if `true`, omitModuleCheck skips the step of ensuring that the
5940                 //              loaded file actually defines the symbol it is referenced by.
5941                 //              For example if it called as `dojo.require("a.b.c")` and the
5942                 //              file located at `a/b/c.js` does not define an object `a.b.c`,
5943                 //              and exception will be throws whereas no exception is raised
5944                 //              when called as `dojo.require("a.b.c", true)`
5945                 //
5946                 // description:
5947                 //              Modules are loaded via dojo.require by using one of two loaders: the normal loader
5948                 //              and the xdomain loader. The xdomain loader is used when dojo was built with a
5949                 //              custom build that specified loader=xdomain and the module lives on a modulePath
5950                 //              that is a whole URL, with protocol and a domain. The versions of Dojo that are on
5951                 //              the Google and AOL CDNs use the xdomain loader.
5952                 //
5953                 //              If the module is loaded via the xdomain loader, it is an asynchronous load, since
5954                 //              the module is added via a dynamically created script tag. This
5955                 //              means that dojo.require() can return before the module has loaded. However, this
5956                 //              should only happen in the case where you do dojo.require calls in the top-level
5957                 //              HTML page, or if you purposely avoid the loader checking for dojo.require
5958                 //              dependencies in your module by using a syntax like dojo["require"] to load the module.
5959                 //
5960                 //              Sometimes it is useful to not have the loader detect the dojo.require calls in the
5961                 //              module so that you can dynamically load the modules as a result of an action on the
5962                 //              page, instead of right at module load time.
5963                 //
5964                 //              Also, for script blocks in an HTML page, the loader does not pre-process them, so
5965                 //              it does not know to download the modules before the dojo.require calls occur.
5966                 //
5967                 //              So, in those two cases, when you want on-the-fly module loading or for script blocks
5968                 //              in the HTML page, special care must be taken if the dojo.required code is loaded
5969                 //              asynchronously. To make sure you can execute code that depends on the dojo.required
5970                 //              modules, be sure to add the code that depends on the modules in a dojo.addOnLoad()
5971                 //              callback. dojo.addOnLoad waits for all outstanding modules to finish loading before
5972                 //              executing.
5973                 //
5974                 //              This type of syntax works with both xdomain and normal loaders, so it is good
5975                 //              practice to always use this idiom for on-the-fly code loading and in HTML script
5976                 //              blocks. If at some point you change loaders and where the code is loaded from,
5977                 //              it will all still work.
5978                 //
5979                 //              More on how dojo.require
5980                 //              `dojo.require("A.B")` first checks to see if symbol A.B is
5981                 //              defined. If it is, it is simply returned (nothing to do).
5982                 //
5983                 //              If it is not defined, it will look for `A/B.js` in the script root
5984                 //              directory.
5985                 //
5986                 //              `dojo.require` throws an exception if it cannot find a file
5987                 //              to load, or if the symbol `A.B` is not defined after loading.
5988                 //
5989                 //              It returns the object `A.B`, but note the caveats above about on-the-fly loading and
5990                 //              HTML script blocks when the xdomain loader is loading a module.
5991                 //
5992                 //              `dojo.require()` does nothing about importing symbols into
5993                 //              the current namespace.  It is presumed that the caller will
5994                 //              take care of that.
5995                 //
5996                 // example:
5997                 //              To use dojo.require in conjunction with dojo.ready:
5998                 //
5999                 //              |       dojo.require("foo");
6000                 //              |       dojo.require("bar");
6001                 //              |       dojo.addOnLoad(function(){
6002                 //              |               //you can now safely do something with foo and bar
6003                 //              |       });
6004                 //
6005                 // example:
6006                 //              For example, to import all symbols into a local block, you might write:
6007                 //
6008                 //              |       with (dojo.require("A.B")) {
6009                 //              |               ...
6010                 //              |       }
6011                 //
6012                 //              And to import just the leaf symbol to a local variable:
6013                 //
6014                 //              |       var B = dojo.require("A.B");
6015                 //              |       ...
6016                 //
6017                 // returns:
6018                 //              the required namespace object
6019                 function doRequire(mid, omitModuleCheck){
6020                         var module = getModule(slashName(mid), require.module);
6021                         if(syncExecStack.length && syncExecStack[0].finish){
6022                                 // switched to async loading in the middle of evaluating a legacy module; stop
6023                                 // applying dojo.require so the remaining dojo.requires are applied in order
6024                                 syncExecStack[0].finish.push(mid);
6025                                 return undefined;
6026                         }
6027
6028                         // recall module.executed has values {0, executing, executed}; therefore, truthy indicates executing or executed
6029                         if(module.executed){
6030                                 return module.result;
6031                         }
6032                         omitModuleCheck && (module.result = nonmodule);
6033
6034                         // rcg...why here and in two lines??
6035                         var currentMode = getLegacyMode();
6036
6037                         // recall, in sync mode to inject is to *eval* the module text
6038                         // if the module is a legacy module, this is the same as executing
6039                         // but if the module is an AMD module, this means defining, not executing
6040                         injectModule(module);
6041                         // the inject may have changed the mode
6042                         currentMode = getLegacyMode();
6043
6044                         // in sync mode to dojo.require is to execute
6045                         if(module.executed!==executed && module.injected===arrived){
6046                                 // the module was already here before injectModule was called probably finishing up a xdomain
6047                                 // load, but maybe a module given to the loader directly rather than having the loader retrieve it
6048
6049                                 loaderVars.guardCheckComplete(function(){
6050                                         execModule(module);
6051                                 });
6052                         }
6053                         if(module.executed){
6054                                 return module.result;
6055                         }
6056
6057                         if(currentMode==sync){
6058                                 // the only way to get here is in sync mode and dojo.required a module that
6059                                 //       * was loaded async in the injectModule application a few lines up
6060                                 //       * was an AMD module that had deps that are being loaded async and therefore couldn't execute
6061                                 if(module.cjs){
6062                                         // the module was an AMD module; unshift, not push, which causes the current traversal to be reattempted from the top
6063                                         execQ.unshift(module);
6064                                 }else{
6065                                         // the module was a legacy module
6066                                         syncExecStack.length && (syncExecStack[0].finish= [mid]);
6067                                 }
6068                         }else{
6069                                 // the loader wasn't in sync mode on entry; probably async mode; therefore, no expectation of getting
6070                                 // the module value synchronously; make sure it gets executed though
6071                                 execQ.push(module);
6072                         }
6073
6074                         return undefined;
6075                 }
6076
6077                 var result = doRequire(moduleName, omitModuleCheck);
6078                 if(has("config-publishRequireResult") && !lang.exists(moduleName) && result!==undefined){
6079                         lang.setObject(moduleName, result);
6080                 }
6081                 return result;
6082         };
6083
6084         dojo.loadInit = function(f) {
6085                 f();
6086         };
6087
6088         dojo.registerModulePath = function(/*String*/moduleName, /*String*/prefix){
6089                 // summary:
6090                 //              Maps a module name to a path
6091                 // description:
6092                 //              An unregistered module is given the default path of ../[module],
6093                 //              relative to Dojo root. For example, module acme is mapped to
6094                 //              ../acme.  If you want to use a different module name, use
6095                 //              dojo.registerModulePath.
6096                 // example:
6097                 //              If your dojo.js is located at this location in the web root:
6098                 //      |       /myapp/js/dojo/dojo/dojo.js
6099                 //              and your modules are located at:
6100                 //      |       /myapp/js/foo/bar.js
6101                 //      |       /myapp/js/foo/baz.js
6102                 //      |       /myapp/js/foo/thud/xyzzy.js
6103                 //              Your application can tell Dojo to locate the "foo" namespace by calling:
6104                 //      |       dojo.registerModulePath("foo", "../../foo");
6105                 //              At which point you can then use dojo.require() to load the
6106                 //              modules (assuming they provide() the same things which are
6107                 //              required). The full code might be:
6108                 //      |       <script type="text/javascript"
6109                 //      |               src="/myapp/js/dojo/dojo/dojo.js"></script>
6110                 //      |       <script type="text/javascript">
6111                 //      |               dojo.registerModulePath("foo", "../../foo");
6112                 //      |               dojo.require("foo.bar");
6113                 //      |               dojo.require("foo.baz");
6114                 //      |               dojo.require("foo.thud.xyzzy");
6115                 //      |       </script>
6116
6117                 var paths = {};
6118                 paths[moduleName.replace(/\./g, "/")] = prefix;
6119                 require({paths:paths});
6120         };
6121
6122         dojo.platformRequire = function(/*Object*/modMap){
6123                 // summary:
6124                 //              require one or more modules based on which host environment
6125                 //              Dojo is currently operating in
6126                 // description:
6127                 //              This method takes a "map" of arrays which one can use to
6128                 //              optionally load dojo modules. The map is indexed by the
6129                 //              possible dojo.name_ values, with two additional values:
6130                 //              "default" and "common". The items in the "default" array will
6131                 //              be loaded if none of the other items have been choosen based on
6132                 //              dojo.name_, set by your host environment. The items in the
6133                 //              "common" array will *always* be loaded, regardless of which
6134                 //              list is chosen.
6135                 // example:
6136                 //              |       dojo.platformRequire({
6137                 //              |               browser: [
6138                 //              |                       "foo.sample", // simple module
6139                 //              |                       "foo.test",
6140                 //              |                       ["foo.bar.baz", true] // skip object check in _loadModule (dojo.require)
6141                 //              |               ],
6142                 //              |               default: [ "foo.sample._base" ],
6143                 //              |               common: [ "important.module.common" ]
6144                 //              |       });
6145
6146                 var result = (modMap.common || []).concat(modMap[dojo._name] || modMap["default"] || []),
6147                         temp;
6148                 while(result.length){
6149                         if(lang.isArray(temp = result.shift())){
6150                                 dojo.require.apply(dojo, temp);
6151                         }else{
6152                                 dojo.require(temp);
6153                         }
6154                 }
6155         };
6156
6157         dojo.requireIf = dojo.requireAfterIf = function(/*Boolean*/ condition, /*String*/ moduleName, /*Boolean?*/omitModuleCheck){
6158                 // summary:
6159                 //              If the condition is true then call `dojo.require()` for the specified
6160                 //              resource
6161                 //
6162                 // example:
6163                 //      |       dojo.requireIf(dojo.isBrowser, "my.special.Module");
6164
6165                 if(condition){
6166                         dojo.require(moduleName, omitModuleCheck);
6167                 }
6168         };
6169
6170         dojo.requireLocalization = function(/*String*/moduleName, /*String*/bundleName, /*String?*/locale){
6171                 require(["../i18n"], function(i18n){
6172                         i18n.getLocalization(moduleName, bundleName, locale);
6173                 });
6174         };
6175
6176         return {
6177                 // summary:
6178                 //              This module defines the v1.x synchronous loader API.
6179
6180                 extractLegacyApiApplications:extractLegacyApiApplications,
6181                 require:dojoRequirePlugin,
6182                 loadInit:dojoLoadInitPlugin
6183         };
6184 });
6185
6186 },
6187 'dojo/json':function(){
6188 define(["./has"], function(has){
6189         "use strict";
6190         var hasJSON = typeof JSON != "undefined";
6191         has.add("json-parse", hasJSON); // all the parsers work fine
6192                 // Firefox 3.5/Gecko 1.9 fails to use replacer in stringify properly https://bugzilla.mozilla.org/show_bug.cgi?id=509184
6193         has.add("json-stringify", hasJSON && JSON.stringify({a:0}, function(k,v){return v||1;}) == '{"a":1}');
6194
6195         /*=====
6196         return {
6197                 // summary:
6198                 //              Functions to parse and serialize JSON
6199
6200                 parse: function(str, strict){
6201                         // summary:
6202                         //              Parses a [JSON](http://json.org) string to return a JavaScript object.
6203                         // description:
6204                         //              This function follows [native JSON API](https://developer.mozilla.org/en/JSON)
6205                         //              Throws for invalid JSON strings. This delegates to eval() if native JSON
6206                         //              support is not available. By default this will evaluate any valid JS expression.
6207                         //              With the strict parameter set to true, the parser will ensure that only
6208                         //              valid JSON strings are parsed (otherwise throwing an error). Without the strict
6209                         //              parameter, the content passed to this method must come
6210                         //              from a trusted source.
6211                         // str:
6212                         //              a string literal of a JSON item, for instance:
6213                         //              `'{ "foo": [ "bar", 1, { "baz": "thud" } ] }'`
6214                         // strict:
6215                         //              When set to true, this will ensure that only valid, secure JSON is ever parsed.
6216                         //              Make sure this is set to true for untrusted content. Note that on browsers/engines
6217                         //              without native JSON support, setting this to true will run slower.
6218                 },
6219                 stringify: function(value, replacer, spacer){
6220                         // summary:
6221                         //              Returns a [JSON](http://json.org) serialization of an object.
6222                         // description:
6223                         //              Returns a [JSON](http://json.org) serialization of an object.
6224                         //              This function follows [native JSON API](https://developer.mozilla.org/en/JSON)
6225                         //              Note that this doesn't check for infinite recursion, so don't do that!
6226                         // value:
6227                         //              A value to be serialized.
6228                         // replacer:
6229                         //              A replacer function that is called for each value and can return a replacement
6230                         // spacer:
6231                         //              A spacer string to be used for pretty printing of JSON
6232                         // example:
6233                         //              simple serialization of a trivial object
6234                         //      |       define(["dojo/json"], function(JSON){
6235                         //      |               var jsonStr = JSON.stringify({ howdy: "stranger!", isStrange: true });
6236                         //      |               doh.is('{"howdy":"stranger!","isStrange":true}', jsonStr);
6237                 }
6238         };
6239         =====*/
6240
6241         if(has("json-stringify")){
6242                 return JSON;
6243         }else{
6244                 var escapeString = function(/*String*/str){
6245                         // summary:
6246                         //              Adds escape sequences for non-visual characters, double quote and
6247                         //              backslash and surrounds with double quotes to form a valid string
6248                         //              literal.
6249                         return ('"' + str.replace(/(["\\])/g, '\\$1') + '"').
6250                                 replace(/[\f]/g, "\\f").replace(/[\b]/g, "\\b").replace(/[\n]/g, "\\n").
6251                                 replace(/[\t]/g, "\\t").replace(/[\r]/g, "\\r"); // string
6252                 };
6253                 return {
6254                         parse: has("json-parse") ? JSON.parse : function(str, strict){
6255                                 if(strict && !/^([\s\[\{]*(?:"(?:\\.|[^"])+"|-?\d[\d\.]*(?:[Ee][+-]?\d+)?|null|true|false|)[\s\]\}]*(?:,|:|$))+$/.test(str)){
6256                                         throw new SyntaxError("Invalid characters in JSON");
6257                                 }
6258                                 return eval('(' + str + ')');
6259                         },
6260                         stringify: function(value, replacer, spacer){
6261                                 var undef;
6262                                 if(typeof replacer == "string"){
6263                                         spacer = replacer;
6264                                         replacer = null;
6265                                 }
6266                                 function stringify(it, indent, key){
6267                                         if(replacer){
6268                                                 it = replacer(key, it);
6269                                         }
6270                                         var val, objtype = typeof it;
6271                                         if(objtype == "number"){
6272                                                 return isFinite(it) ? it + "" : "null";
6273                                         }
6274                                         if(objtype == "boolean"){
6275                                                 return it + "";
6276                                         }
6277                                         if(it === null){
6278                                                 return "null";
6279                                         }
6280                                         if(typeof it == "string"){
6281                                                 return escapeString(it);
6282                                         }
6283                                         if(objtype == "function" || objtype == "undefined"){
6284                                                 return undef; // undefined
6285                                         }
6286                                         // short-circuit for objects that support "json" serialization
6287                                         // if they return "self" then just pass-through...
6288                                         if(typeof it.toJSON == "function"){
6289                                                 return stringify(it.toJSON(key), indent, key);
6290                                         }
6291                                         if(it instanceof Date){
6292                                                 return '"{FullYear}-{Month+}-{Date}T{Hours}:{Minutes}:{Seconds}Z"'.replace(/\{(\w+)(\+)?\}/g, function(t, prop, plus){
6293                                                         var num = it["getUTC" + prop]() + (plus ? 1 : 0);
6294                                                         return num < 10 ? "0" + num : num;
6295                                                 });
6296                                         }
6297                                         if(it.valueOf() !== it){
6298                                                 // primitive wrapper, try again unwrapped:
6299                                                 return stringify(it.valueOf(), indent, key);
6300                                         }
6301                                         var nextIndent= spacer ? (indent + spacer) : "";
6302                                         /* we used to test for DOM nodes and throw, but FF serializes them as {}, so cross-browser consistency is probably not efficiently attainable */ 
6303                                 
6304                                         var sep = spacer ? " " : "";
6305                                         var newLine = spacer ? "\n" : "";
6306                                 
6307                                         // array
6308                                         if(it instanceof Array){
6309                                                 var itl = it.length, res = [];
6310                                                 for(key = 0; key < itl; key++){
6311                                                         var obj = it[key];
6312                                                         val = stringify(obj, nextIndent, key);
6313                                                         if(typeof val != "string"){
6314                                                                 val = "null";
6315                                                         }
6316                                                         res.push(newLine + nextIndent + val);
6317                                                 }
6318                                                 return "[" + res.join(",") + newLine + indent + "]";
6319                                         }
6320                                         // generic object code path
6321                                         var output = [];
6322                                         for(key in it){
6323                                                 var keyStr;
6324                                                 if(it.hasOwnProperty(key)){
6325                                                         if(typeof key == "number"){
6326                                                                 keyStr = '"' + key + '"';
6327                                                         }else if(typeof key == "string"){
6328                                                                 keyStr = escapeString(key);
6329                                                         }else{
6330                                                                 // skip non-string or number keys
6331                                                                 continue;
6332                                                         }
6333                                                         val = stringify(it[key], nextIndent, key);
6334                                                         if(typeof val != "string"){
6335                                                                 // skip non-serializable values
6336                                                                 continue;
6337                                                         }
6338                                                         // At this point, the most non-IE browsers don't get in this branch 
6339                                                         // (they have native JSON), so push is definitely the way to
6340                                                         output.push(newLine + nextIndent + keyStr + ":" + sep + val);
6341                                                 }
6342                                         }
6343                                         return "{" + output.join(",") + newLine + indent + "}"; // String
6344                                 }
6345                                 return stringify(value, "", "");
6346                         }
6347                 };
6348         }
6349 });
6350
6351 },
6352 'dojo/_base/declare':function(){
6353 define(["./kernel", "../has", "./lang"], function(dojo, has, lang){
6354         // module:
6355         //              dojo/_base/declare
6356
6357         var mix = lang.mixin, op = Object.prototype, opts = op.toString,
6358                 xtor = new Function, counter = 0, cname = "constructor";
6359
6360         function err(msg, cls){ throw new Error("declare" + (cls ? " " + cls : "") + ": " + msg); }
6361
6362         // C3 Method Resolution Order (see http://www.python.org/download/releases/2.3/mro/)
6363         function c3mro(bases, className){
6364                 var result = [], roots = [{cls: 0, refs: []}], nameMap = {}, clsCount = 1,
6365                         l = bases.length, i = 0, j, lin, base, top, proto, rec, name, refs;
6366
6367                 // build a list of bases naming them if needed
6368                 for(; i < l; ++i){
6369                         base = bases[i];
6370                         if(!base){
6371                                 err("mixin #" + i + " is unknown. Did you use dojo.require to pull it in?", className);
6372                         }else if(opts.call(base) != "[object Function]"){
6373                                 err("mixin #" + i + " is not a callable constructor.", className);
6374                         }
6375                         lin = base._meta ? base._meta.bases : [base];
6376                         top = 0;
6377                         // add bases to the name map
6378                         for(j = lin.length - 1; j >= 0; --j){
6379                                 proto = lin[j].prototype;
6380                                 if(!proto.hasOwnProperty("declaredClass")){
6381                                         proto.declaredClass = "uniqName_" + (counter++);
6382                                 }
6383                                 name = proto.declaredClass;
6384                                 if(!nameMap.hasOwnProperty(name)){
6385                                         nameMap[name] = {count: 0, refs: [], cls: lin[j]};
6386                                         ++clsCount;
6387                                 }
6388                                 rec = nameMap[name];
6389                                 if(top && top !== rec){
6390                                         rec.refs.push(top);
6391                                         ++top.count;
6392                                 }
6393                                 top = rec;
6394                         }
6395                         ++top.count;
6396                         roots[0].refs.push(top);
6397                 }
6398
6399                 // remove classes without external references recursively
6400                 while(roots.length){
6401                         top = roots.pop();
6402                         result.push(top.cls);
6403                         --clsCount;
6404                         // optimization: follow a single-linked chain
6405                         while(refs = top.refs, refs.length == 1){
6406                                 top = refs[0];
6407                                 if(!top || --top.count){
6408                                         // branch or end of chain => do not end to roots
6409                                         top = 0;
6410                                         break;
6411                                 }
6412                                 result.push(top.cls);
6413                                 --clsCount;
6414                         }
6415                         if(top){
6416                                 // branch
6417                                 for(i = 0, l = refs.length; i < l; ++i){
6418                                         top = refs[i];
6419                                         if(!--top.count){
6420                                                 roots.push(top);
6421                                         }
6422                                 }
6423                         }
6424                 }
6425                 if(clsCount){
6426                         err("can't build consistent linearization", className);
6427                 }
6428
6429                 // calculate the superclass offset
6430                 base = bases[0];
6431                 result[0] = base ?
6432                         base._meta && base === result[result.length - base._meta.bases.length] ?
6433                                 base._meta.bases.length : 1 : 0;
6434
6435                 return result;
6436         }
6437
6438         function inherited(args, a, f){
6439                 var name, chains, bases, caller, meta, base, proto, opf, pos,
6440                         cache = this._inherited = this._inherited || {};
6441
6442                 // crack arguments
6443                 if(typeof args == "string"){
6444                         name = args;
6445                         args = a;
6446                         a = f;
6447                 }
6448                 f = 0;
6449
6450                 caller = args.callee;
6451                 name = name || caller.nom;
6452                 if(!name){
6453                         err("can't deduce a name to call inherited()", this.declaredClass);
6454                 }
6455
6456                 meta = this.constructor._meta;
6457                 bases = meta.bases;
6458
6459                 pos = cache.p;
6460                 if(name != cname){
6461                         // method
6462                         if(cache.c !== caller){
6463                                 // cache bust
6464                                 pos = 0;
6465                                 base = bases[0];
6466                                 meta = base._meta;
6467                                 if(meta.hidden[name] !== caller){
6468                                         // error detection
6469                                         chains = meta.chains;
6470                                         if(chains && typeof chains[name] == "string"){
6471                                                 err("calling chained method with inherited: " + name, this.declaredClass);
6472                                         }
6473                                         // find caller
6474                                         do{
6475                                                 meta = base._meta;
6476                                                 proto = base.prototype;
6477                                                 if(meta && (proto[name] === caller && proto.hasOwnProperty(name) || meta.hidden[name] === caller)){
6478                                                         break;
6479                                                 }
6480                                         }while(base = bases[++pos]); // intentional assignment
6481                                         pos = base ? pos : -1;
6482                                 }
6483                         }
6484                         // find next
6485                         base = bases[++pos];
6486                         if(base){
6487                                 proto = base.prototype;
6488                                 if(base._meta && proto.hasOwnProperty(name)){
6489                                         f = proto[name];
6490                                 }else{
6491                                         opf = op[name];
6492                                         do{
6493                                                 proto = base.prototype;
6494                                                 f = proto[name];
6495                                                 if(f && (base._meta ? proto.hasOwnProperty(name) : f !== opf)){
6496                                                         break;
6497                                                 }
6498                                         }while(base = bases[++pos]); // intentional assignment
6499                                 }
6500                         }
6501                         f = base && f || op[name];
6502                 }else{
6503                         // constructor
6504                         if(cache.c !== caller){
6505                                 // cache bust
6506                                 pos = 0;
6507                                 meta = bases[0]._meta;
6508                                 if(meta && meta.ctor !== caller){
6509                                         // error detection
6510                                         chains = meta.chains;
6511                                         if(!chains || chains.constructor !== "manual"){
6512                                                 err("calling chained constructor with inherited", this.declaredClass);
6513                                         }
6514                                         // find caller
6515                                         while(base = bases[++pos]){ // intentional assignment
6516                                                 meta = base._meta;
6517                                                 if(meta && meta.ctor === caller){
6518                                                         break;
6519                                                 }
6520                                         }
6521                                         pos = base ? pos : -1;
6522                                 }
6523                         }
6524                         // find next
6525                         while(base = bases[++pos]){     // intentional assignment
6526                                 meta = base._meta;
6527                                 f = meta ? meta.ctor : base;
6528                                 if(f){
6529                                         break;
6530                                 }
6531                         }
6532                         f = base && f;
6533                 }
6534
6535                 // cache the found super method
6536                 cache.c = f;
6537                 cache.p = pos;
6538
6539                 // now we have the result
6540                 if(f){
6541                         return a === true ? f : f.apply(this, a || args);
6542                 }
6543                 // intentionally no return if a super method was not found
6544         }
6545
6546         function getInherited(name, args){
6547                 if(typeof name == "string"){
6548                         return this.__inherited(name, args, true);
6549                 }
6550                 return this.__inherited(name, true);
6551         }
6552
6553         function inherited__debug(args, a1, a2){
6554                 var f = this.getInherited(args, a1);
6555                 if(f){ return f.apply(this, a2 || a1 || args); }
6556                 // intentionally no return if a super method was not found
6557         }
6558
6559         var inheritedImpl = dojo.config.isDebug ? inherited__debug : inherited;
6560
6561         // emulation of "instanceof"
6562         function isInstanceOf(cls){
6563                 var bases = this.constructor._meta.bases;
6564                 for(var i = 0, l = bases.length; i < l; ++i){
6565                         if(bases[i] === cls){
6566                                 return true;
6567                         }
6568                 }
6569                 return this instanceof cls;
6570         }
6571
6572         function mixOwn(target, source){
6573                 // add props adding metadata for incoming functions skipping a constructor
6574                 for(var name in source){
6575                         if(name != cname && source.hasOwnProperty(name)){
6576                                 target[name] = source[name];
6577                         }
6578                 }
6579                 if(has("bug-for-in-skips-shadowed")){
6580                         for(var extraNames= lang._extraNames, i= extraNames.length; i;){
6581                                 name = extraNames[--i];
6582                                 if(name != cname && source.hasOwnProperty(name)){
6583                                           target[name] = source[name];
6584                                 }
6585                         }
6586                 }
6587         }
6588
6589         // implementation of safe mixin function
6590         function safeMixin(target, source){
6591                 // summary:
6592                 //              Mix in properties skipping a constructor and decorating functions
6593                 //              like it is done by declare().
6594                 // target: Object
6595                 //              Target object to accept new properties.
6596                 // source: Object
6597                 //              Source object for new properties.
6598                 // description:
6599                 //              This function is used to mix in properties like lang.mixin does,
6600                 //              but it skips a constructor property and decorates functions like
6601                 //              declare() does.
6602                 //
6603                 //              It is meant to be used with classes and objects produced with
6604                 //              declare. Functions mixed in with dojo.safeMixin can use
6605                 //              this.inherited() like normal methods.
6606                 //
6607                 //              This function is used to implement extend() method of a constructor
6608                 //              produced with declare().
6609                 //
6610                 // example:
6611                 //      |       var A = declare(null, {
6612                 //      |               m1: function(){
6613                 //      |                       console.log("A.m1");
6614                 //      |               },
6615                 //      |               m2: function(){
6616                 //      |                       console.log("A.m2");
6617                 //      |               }
6618                 //      |       });
6619                 //      |       var B = declare(A, {
6620                 //      |               m1: function(){
6621                 //      |                       this.inherited(arguments);
6622                 //      |                       console.log("B.m1");
6623                 //      |               }
6624                 //      |       });
6625                 //      |       B.extend({
6626                 //      |               m2: function(){
6627                 //      |                       this.inherited(arguments);
6628                 //      |                       console.log("B.m2");
6629                 //      |               }
6630                 //      |       });
6631                 //      |       var x = new B();
6632                 //      |       dojo.safeMixin(x, {
6633                 //      |               m1: function(){
6634                 //      |                       this.inherited(arguments);
6635                 //      |                       console.log("X.m1");
6636                 //      |               },
6637                 //      |               m2: function(){
6638                 //      |                       this.inherited(arguments);
6639                 //      |                       console.log("X.m2");
6640                 //      |               }
6641                 //      |       });
6642                 //      |       x.m2();
6643                 //      |       // prints:
6644                 //      |       // A.m1
6645                 //      |       // B.m1
6646                 //      |       // X.m1
6647
6648                 var name, t;
6649                 // add props adding metadata for incoming functions skipping a constructor
6650                 for(name in source){
6651                         t = source[name];
6652                         if((t !== op[name] || !(name in op)) && name != cname){
6653                                 if(opts.call(t) == "[object Function]"){
6654                                         // non-trivial function method => attach its name
6655                                         t.nom = name;
6656                                 }
6657                                 target[name] = t;
6658                         }
6659                 }
6660                 if(has("bug-for-in-skips-shadowed")){
6661                         for(var extraNames= lang._extraNames, i= extraNames.length; i;){
6662                                 name = extraNames[--i];
6663                                 t = source[name];
6664                                 if((t !== op[name] || !(name in op)) && name != cname){
6665                                         if(opts.call(t) == "[object Function]"){
6666                                                 // non-trivial function method => attach its name
6667                                                   t.nom = name;
6668                                         }
6669                                         target[name] = t;
6670                                 }
6671                         }
6672                 }
6673                 return target;
6674         }
6675
6676         function extend(source){
6677                 declare.safeMixin(this.prototype, source);
6678                 return this;
6679         }
6680
6681         function createSubclass(mixins){
6682                 return declare([this].concat(mixins));
6683         }
6684
6685         // chained constructor compatible with the legacy declare()
6686         function chainedConstructor(bases, ctorSpecial){
6687                 return function(){
6688                         var a = arguments, args = a, a0 = a[0], f, i, m,
6689                                 l = bases.length, preArgs;
6690
6691                         if(!(this instanceof a.callee)){
6692                                 // not called via new, so force it
6693                                 return applyNew(a);
6694                         }
6695
6696                         //this._inherited = {};
6697                         // perform the shaman's rituals of the original declare()
6698                         // 1) call two types of the preamble
6699                         if(ctorSpecial && (a0 && a0.preamble || this.preamble)){
6700                                 // full blown ritual
6701                                 preArgs = new Array(bases.length);
6702                                 // prepare parameters
6703                                 preArgs[0] = a;
6704                                 for(i = 0;;){
6705                                         // process the preamble of the 1st argument
6706                                         a0 = a[0];
6707                                         if(a0){
6708                                                 f = a0.preamble;
6709                                                 if(f){
6710                                                         a = f.apply(this, a) || a;
6711                                                 }
6712                                         }
6713                                         // process the preamble of this class
6714                                         f = bases[i].prototype;
6715                                         f = f.hasOwnProperty("preamble") && f.preamble;
6716                                         if(f){
6717                                                 a = f.apply(this, a) || a;
6718                                         }
6719                                         // one peculiarity of the preamble:
6720                                         // it is called if it is not needed,
6721                                         // e.g., there is no constructor to call
6722                                         // let's watch for the last constructor
6723                                         // (see ticket #9795)
6724                                         if(++i == l){
6725                                                 break;
6726                                         }
6727                                         preArgs[i] = a;
6728                                 }
6729                         }
6730                         // 2) call all non-trivial constructors using prepared arguments
6731                         for(i = l - 1; i >= 0; --i){
6732                                 f = bases[i];
6733                                 m = f._meta;
6734                                 f = m ? m.ctor : f;
6735                                 if(f){
6736                                         f.apply(this, preArgs ? preArgs[i] : a);
6737                                 }
6738                         }
6739                         // 3) continue the original ritual: call the postscript
6740                         f = this.postscript;
6741                         if(f){
6742                                 f.apply(this, args);
6743                         }
6744                 };
6745         }
6746
6747
6748         // chained constructor compatible with the legacy declare()
6749         function singleConstructor(ctor, ctorSpecial){
6750                 return function(){
6751                         var a = arguments, t = a, a0 = a[0], f;
6752
6753                         if(!(this instanceof a.callee)){
6754                                 // not called via new, so force it
6755                                 return applyNew(a);
6756                         }
6757
6758                         //this._inherited = {};
6759                         // perform the shaman's rituals of the original declare()
6760                         // 1) call two types of the preamble
6761                         if(ctorSpecial){
6762                                 // full blown ritual
6763                                 if(a0){
6764                                         // process the preamble of the 1st argument
6765                                         f = a0.preamble;
6766                                         if(f){
6767                                                 t = f.apply(this, t) || t;
6768                                         }
6769                                 }
6770                                 f = this.preamble;
6771                                 if(f){
6772                                         // process the preamble of this class
6773                                         f.apply(this, t);
6774                                         // one peculiarity of the preamble:
6775                                         // it is called even if it is not needed,
6776                                         // e.g., there is no constructor to call
6777                                         // let's watch for the last constructor
6778                                         // (see ticket #9795)
6779                                 }
6780                         }
6781                         // 2) call a constructor
6782                         if(ctor){
6783                                 ctor.apply(this, a);
6784                         }
6785                         // 3) continue the original ritual: call the postscript
6786                         f = this.postscript;
6787                         if(f){
6788                                 f.apply(this, a);
6789                         }
6790                 };
6791         }
6792
6793         // plain vanilla constructor (can use inherited() to call its base constructor)
6794         function simpleConstructor(bases){
6795                 return function(){
6796                         var a = arguments, i = 0, f, m;
6797
6798                         if(!(this instanceof a.callee)){
6799                                 // not called via new, so force it
6800                                 return applyNew(a);
6801                         }
6802
6803                         //this._inherited = {};
6804                         // perform the shaman's rituals of the original declare()
6805                         // 1) do not call the preamble
6806                         // 2) call the top constructor (it can use this.inherited())
6807                         for(; f = bases[i]; ++i){ // intentional assignment
6808                                 m = f._meta;
6809                                 f = m ? m.ctor : f;
6810                                 if(f){
6811                                         f.apply(this, a);
6812                                         break;
6813                                 }
6814                         }
6815                         // 3) call the postscript
6816                         f = this.postscript;
6817                         if(f){
6818                                 f.apply(this, a);
6819                         }
6820                 };
6821         }
6822
6823         function chain(name, bases, reversed){
6824                 return function(){
6825                         var b, m, f, i = 0, step = 1;
6826                         if(reversed){
6827                                 i = bases.length - 1;
6828                                 step = -1;
6829                         }
6830                         for(; b = bases[i]; i += step){ // intentional assignment
6831                                 m = b._meta;
6832                                 f = (m ? m.hidden : b.prototype)[name];
6833                                 if(f){
6834                                         f.apply(this, arguments);
6835                                 }
6836                         }
6837                 };
6838         }
6839
6840         // forceNew(ctor)
6841         // return a new object that inherits from ctor.prototype but
6842         // without actually running ctor on the object.
6843         function forceNew(ctor){
6844                 // create object with correct prototype using a do-nothing
6845                 // constructor
6846                 xtor.prototype = ctor.prototype;
6847                 var t = new xtor;
6848                 xtor.prototype = null;  // clean up
6849                 return t;
6850         }
6851
6852         // applyNew(args)
6853         // just like 'new ctor()' except that the constructor and its arguments come
6854         // from args, which must be an array or an arguments object
6855         function applyNew(args){
6856                 // create an object with ctor's prototype but without
6857                 // calling ctor on it.
6858                 var ctor = args.callee, t = forceNew(ctor);
6859                 // execute the real constructor on the new object
6860                 ctor.apply(t, args);
6861                 return t;
6862         }
6863
6864         function declare(className, superclass, props){
6865                 // summary:
6866                 //              Create a feature-rich constructor from compact notation.
6867                 // className: String?
6868                 //              The optional name of the constructor (loosely, a "class")
6869                 //              stored in the "declaredClass" property in the created prototype.
6870                 //              It will be used as a global name for a created constructor.
6871                 // superclass: Function|Function[]
6872                 //              May be null, a Function, or an Array of Functions. This argument
6873                 //              specifies a list of bases (the left-most one is the most deepest
6874                 //              base).
6875                 // props: Object
6876                 //              An object whose properties are copied to the created prototype.
6877                 //              Add an instance-initialization function by making it a property
6878                 //              named "constructor".
6879                 // returns: dojo/_base/declare.__DeclareCreatedObject
6880                 //              New constructor function.
6881                 // description:
6882                 //              Create a constructor using a compact notation for inheritance and
6883                 //              prototype extension.
6884                 //
6885                 //              Mixin ancestors provide a type of multiple inheritance.
6886                 //              Prototypes of mixin ancestors are copied to the new class:
6887                 //              changes to mixin prototypes will not affect classes to which
6888                 //              they have been mixed in.
6889                 //
6890                 //              Ancestors can be compound classes created by this version of
6891                 //              declare(). In complex cases all base classes are going to be
6892                 //              linearized according to C3 MRO algorithm
6893                 //              (see http://www.python.org/download/releases/2.3/mro/ for more
6894                 //              details).
6895                 //
6896                 //              "className" is cached in "declaredClass" property of the new class,
6897                 //              if it was supplied. The immediate super class will be cached in
6898                 //              "superclass" property of the new class.
6899                 //
6900                 //              Methods in "props" will be copied and modified: "nom" property
6901                 //              (the declared name of the method) will be added to all copied
6902                 //              functions to help identify them for the internal machinery. Be
6903                 //              very careful, while reusing methods: if you use the same
6904                 //              function under different names, it can produce errors in some
6905                 //              cases.
6906                 //
6907                 //              It is possible to use constructors created "manually" (without
6908                 //              declare()) as bases. They will be called as usual during the
6909                 //              creation of an instance, their methods will be chained, and even
6910                 //              called by "this.inherited()".
6911                 //
6912                 //              Special property "-chains-" governs how to chain methods. It is
6913                 //              a dictionary, which uses method names as keys, and hint strings
6914                 //              as values. If a hint string is "after", this method will be
6915                 //              called after methods of its base classes. If a hint string is
6916                 //              "before", this method will be called before methods of its base
6917                 //              classes.
6918                 //
6919                 //              If "constructor" is not mentioned in "-chains-" property, it will
6920                 //              be chained using the legacy mode: using "after" chaining,
6921                 //              calling preamble() method before each constructor, if available,
6922                 //              and calling postscript() after all constructors were executed.
6923                 //              If the hint is "after", it is chained as a regular method, but
6924                 //              postscript() will be called after the chain of constructors.
6925                 //              "constructor" cannot be chained "before", but it allows
6926                 //              a special hint string: "manual", which means that constructors
6927                 //              are not going to be chained in any way, and programmer will call
6928                 //              them manually using this.inherited(). In the latter case
6929                 //              postscript() will be called after the construction.
6930                 //
6931                 //              All chaining hints are "inherited" from base classes and
6932                 //              potentially can be overridden. Be very careful when overriding
6933                 //              hints! Make sure that all chained methods can work in a proposed
6934                 //              manner of chaining.
6935                 //
6936                 //              Once a method was chained, it is impossible to unchain it. The
6937                 //              only exception is "constructor". You don't need to define a
6938                 //              method in order to supply a chaining hint.
6939                 //
6940                 //              If a method is chained, it cannot use this.inherited() because
6941                 //              all other methods in the hierarchy will be called automatically.
6942                 //
6943                 //              Usually constructors and initializers of any kind are chained
6944                 //              using "after" and destructors of any kind are chained as
6945                 //              "before". Note that chaining assumes that chained methods do not
6946                 //              return any value: any returned value will be discarded.
6947                 //
6948                 // example:
6949                 //      |       declare("my.classes.bar", my.classes.foo, {
6950                 //      |               // properties to be added to the class prototype
6951                 //      |               someValue: 2,
6952                 //      |               // initialization function
6953                 //      |               constructor: function(){
6954                 //      |                       this.myComplicatedObject = new ReallyComplicatedObject();
6955                 //      |               },
6956                 //      |               // other functions
6957                 //      |               someMethod: function(){
6958                 //      |                       doStuff();
6959                 //      |               }
6960                 //      |       });
6961                 //
6962                 // example:
6963                 //      |       var MyBase = declare(null, {
6964                 //      |               // constructor, properties, and methods go here
6965                 //      |               // ...
6966                 //      |       });
6967                 //      |       var MyClass1 = declare(MyBase, {
6968                 //      |               // constructor, properties, and methods go here
6969                 //      |               // ...
6970                 //      |       });
6971                 //      |       var MyClass2 = declare(MyBase, {
6972                 //      |               // constructor, properties, and methods go here
6973                 //      |               // ...
6974                 //      |       });
6975                 //      |       var MyDiamond = declare([MyClass1, MyClass2], {
6976                 //      |               // constructor, properties, and methods go here
6977                 //      |               // ...
6978                 //      |       });
6979                 //
6980                 // example:
6981                 //      |       var F = function(){ console.log("raw constructor"); };
6982                 //      |       F.prototype.method = function(){
6983                 //      |               console.log("raw method");
6984                 //      |       };
6985                 //      |       var A = declare(F, {
6986                 //      |               constructor: function(){
6987                 //      |                       console.log("A.constructor");
6988                 //      |               },
6989                 //      |               method: function(){
6990                 //      |                       console.log("before calling F.method...");
6991                 //      |                       this.inherited(arguments);
6992                 //      |                       console.log("...back in A");
6993                 //      |               }
6994                 //      |       });
6995                 //      |       new A().method();
6996                 //      |       // will print:
6997                 //      |       // raw constructor
6998                 //      |       // A.constructor
6999                 //      |       // before calling F.method...
7000                 //      |       // raw method
7001                 //      |       // ...back in A
7002                 //
7003                 // example:
7004                 //      |       var A = declare(null, {
7005                 //      |               "-chains-": {
7006                 //      |                       destroy: "before"
7007                 //      |               }
7008                 //      |       });
7009                 //      |       var B = declare(A, {
7010                 //      |               constructor: function(){
7011                 //      |                       console.log("B.constructor");
7012                 //      |               },
7013                 //      |               destroy: function(){
7014                 //      |                       console.log("B.destroy");
7015                 //      |               }
7016                 //      |       });
7017                 //      |       var C = declare(B, {
7018                 //      |               constructor: function(){
7019                 //      |                       console.log("C.constructor");
7020                 //      |               },
7021                 //      |               destroy: function(){
7022                 //      |                       console.log("C.destroy");
7023                 //      |               }
7024                 //      |       });
7025                 //      |       new C().destroy();
7026                 //      |       // prints:
7027                 //      |       // B.constructor
7028                 //      |       // C.constructor
7029                 //      |       // C.destroy
7030                 //      |       // B.destroy
7031                 //
7032                 // example:
7033                 //      |       var A = declare(null, {
7034                 //      |               "-chains-": {
7035                 //      |                       constructor: "manual"
7036                 //      |               }
7037                 //      |       });
7038                 //      |       var B = declare(A, {
7039                 //      |               constructor: function(){
7040                 //      |                       // ...
7041                 //      |                       // call the base constructor with new parameters
7042                 //      |                       this.inherited(arguments, [1, 2, 3]);
7043                 //      |                       // ...
7044                 //      |               }
7045                 //      |       });
7046                 //
7047                 // example:
7048                 //      |       var A = declare(null, {
7049                 //      |               "-chains-": {
7050                 //      |                       m1: "before"
7051                 //      |               },
7052                 //      |               m1: function(){
7053                 //      |                       console.log("A.m1");
7054                 //      |               },
7055                 //      |               m2: function(){
7056                 //      |                       console.log("A.m2");
7057                 //      |               }
7058                 //      |       });
7059                 //      |       var B = declare(A, {
7060                 //      |               "-chains-": {
7061                 //      |                       m2: "after"
7062                 //      |               },
7063                 //      |               m1: function(){
7064                 //      |                       console.log("B.m1");
7065                 //      |               },
7066                 //      |               m2: function(){
7067                 //      |                       console.log("B.m2");
7068                 //      |               }
7069                 //      |       });
7070                 //      |       var x = new B();
7071                 //      |       x.m1();
7072                 //      |       // prints:
7073                 //      |       // B.m1
7074                 //      |       // A.m1
7075                 //      |       x.m2();
7076                 //      |       // prints:
7077                 //      |       // A.m2
7078                 //      |       // B.m2
7079
7080                 // crack parameters
7081                 if(typeof className != "string"){
7082                         props = superclass;
7083                         superclass = className;
7084                         className = "";
7085                 }
7086                 props = props || {};
7087
7088                 var proto, i, t, ctor, name, bases, chains, mixins = 1, parents = superclass;
7089
7090                 // build a prototype
7091                 if(opts.call(superclass) == "[object Array]"){
7092                         // C3 MRO
7093                         bases = c3mro(superclass, className);
7094                         t = bases[0];
7095                         mixins = bases.length - t;
7096                         superclass = bases[mixins];
7097                 }else{
7098                         bases = [0];
7099                         if(superclass){
7100                                 if(opts.call(superclass) == "[object Function]"){
7101                                         t = superclass._meta;
7102                                         bases = bases.concat(t ? t.bases : superclass);
7103                                 }else{
7104                                         err("base class is not a callable constructor.", className);
7105                                 }
7106                         }else if(superclass !== null){
7107                                 err("unknown base class. Did you use dojo.require to pull it in?", className);
7108                         }
7109                 }
7110                 if(superclass){
7111                         for(i = mixins - 1;; --i){
7112                                 proto = forceNew(superclass);
7113                                 if(!i){
7114                                         // stop if nothing to add (the last base)
7115                                         break;
7116                                 }
7117                                 // mix in properties
7118                                 t = bases[i];
7119                                 (t._meta ? mixOwn : mix)(proto, t.prototype);
7120                                 // chain in new constructor
7121                                 ctor = new Function;
7122                                 ctor.superclass = superclass;
7123                                 ctor.prototype = proto;
7124                                 superclass = proto.constructor = ctor;
7125                         }
7126                 }else{
7127                         proto = {};
7128                 }
7129                 // add all properties
7130                 declare.safeMixin(proto, props);
7131                 // add constructor
7132                 t = props.constructor;
7133                 if(t !== op.constructor){
7134                         t.nom = cname;
7135                         proto.constructor = t;
7136                 }
7137
7138                 // collect chains and flags
7139                 for(i = mixins - 1; i; --i){ // intentional assignment
7140                         t = bases[i]._meta;
7141                         if(t && t.chains){
7142                                 chains = mix(chains || {}, t.chains);
7143                         }
7144                 }
7145                 if(proto["-chains-"]){
7146                         chains = mix(chains || {}, proto["-chains-"]);
7147                 }
7148
7149                 // build ctor
7150                 t = !chains || !chains.hasOwnProperty(cname);
7151                 bases[0] = ctor = (chains && chains.constructor === "manual") ? simpleConstructor(bases) :
7152                         (bases.length == 1 ? singleConstructor(props.constructor, t) : chainedConstructor(bases, t));
7153
7154                 // add meta information to the constructor
7155                 ctor._meta  = {bases: bases, hidden: props, chains: chains,
7156                         parents: parents, ctor: props.constructor};
7157                 ctor.superclass = superclass && superclass.prototype;
7158                 ctor.extend = extend;
7159                 ctor.createSubclass = createSubclass;
7160                 ctor.prototype = proto;
7161                 proto.constructor = ctor;
7162
7163                 // add "standard" methods to the prototype
7164                 proto.getInherited = getInherited;
7165                 proto.isInstanceOf = isInstanceOf;
7166                 proto.inherited    = inheritedImpl;
7167                 proto.__inherited  = inherited;
7168
7169                 // add name if specified
7170                 if(className){
7171                         proto.declaredClass = className;
7172                         lang.setObject(className, ctor);
7173                 }
7174
7175                 // build chains and add them to the prototype
7176                 if(chains){
7177                         for(name in chains){
7178                                 if(proto[name] && typeof chains[name] == "string" && name != cname){
7179                                         t = proto[name] = chain(name, bases, chains[name] === "after");
7180                                         t.nom = name;
7181                                 }
7182                         }
7183                 }
7184                 // chained methods do not return values
7185                 // no need to chain "invisible" functions
7186
7187                 return ctor;    // Function
7188         }
7189
7190         /*=====
7191         declare.__DeclareCreatedObject = {
7192                 // summary:
7193                 //              dojo/_base/declare() returns a constructor `C`.   `new C()` returns an Object with the following
7194                 //              methods, in addition to the methods and properties specified via the arguments passed to declare().
7195
7196                 inherited: function(name, args, newArgs){
7197                         // summary:
7198                         //              Calls a super method.
7199                         // name: String?
7200                         //              The optional method name. Should be the same as the caller's
7201                         //              name. Usually "name" is specified in complex dynamic cases, when
7202                         //              the calling method was dynamically added, undecorated by
7203                         //              declare(), and it cannot be determined.
7204                         // args: Arguments
7205                         //              The caller supply this argument, which should be the original
7206                         //              "arguments".
7207                         // newArgs: Object?
7208                         //              If "true", the found function will be returned without
7209                         //              executing it.
7210                         //              If Array, it will be used to call a super method. Otherwise
7211                         //              "args" will be used.
7212                         // returns:
7213                         //              Whatever is returned by a super method, or a super method itself,
7214                         //              if "true" was specified as newArgs.
7215                         // description:
7216                         //              This method is used inside method of classes produced with
7217                         //              declare() to call a super method (next in the chain). It is
7218                         //              used for manually controlled chaining. Consider using the regular
7219                         //              chaining, because it is faster. Use "this.inherited()" only in
7220                         //              complex cases.
7221                         //
7222                         //              This method cannot me called from automatically chained
7223                         //              constructors including the case of a special (legacy)
7224                         //              constructor chaining. It cannot be called from chained methods.
7225                         //
7226                         //              If "this.inherited()" cannot find the next-in-chain method, it
7227                         //              does nothing and returns "undefined". The last method in chain
7228                         //              can be a default method implemented in Object, which will be
7229                         //              called last.
7230                         //
7231                         //              If "name" is specified, it is assumed that the method that
7232                         //              received "args" is the parent method for this call. It is looked
7233                         //              up in the chain list and if it is found the next-in-chain method
7234                         //              is called. If it is not found, the first-in-chain method is
7235                         //              called.
7236                         //
7237                         //              If "name" is not specified, it will be derived from the calling
7238                         //              method (using a methoid property "nom").
7239                         //
7240                         // example:
7241                         //      |       var B = declare(A, {
7242                         //      |               method1: function(a, b, c){
7243                         //      |                       this.inherited(arguments);
7244                         //      |               },
7245                         //      |               method2: function(a, b){
7246                         //      |                       return this.inherited(arguments, [a + b]);
7247                         //      |               }
7248                         //      |       });
7249                         //      |       // next method is not in the chain list because it is added
7250                         //      |       // manually after the class was created.
7251                         //      |       B.prototype.method3 = function(){
7252                         //      |               console.log("This is a dynamically-added method.");
7253                         //      |               this.inherited("method3", arguments);
7254                         //      |       };
7255                         // example:
7256                         //      |       var B = declare(A, {
7257                         //      |               method: function(a, b){
7258                         //      |                       var super = this.inherited(arguments, true);
7259                         //      |                       // ...
7260                         //      |                       if(!super){
7261                         //      |                               console.log("there is no super method");
7262                         //      |                               return 0;
7263                         //      |                       }
7264                         //      |                       return super.apply(this, arguments);
7265                         //      |               }
7266                         //      |       });
7267                         return  {};     // Object
7268                 },
7269
7270                 getInherited: function(name, args){
7271                         // summary:
7272                         //              Returns a super method.
7273                         // name: String?
7274                         //              The optional method name. Should be the same as the caller's
7275                         //              name. Usually "name" is specified in complex dynamic cases, when
7276                         //              the calling method was dynamically added, undecorated by
7277                         //              declare(), and it cannot be determined.
7278                         // args: Arguments
7279                         //              The caller supply this argument, which should be the original
7280                         //              "arguments".
7281                         // returns:
7282                         //              Returns a super method (Function) or "undefined".
7283                         // description:
7284                         //              This method is a convenience method for "this.inherited()".
7285                         //              It uses the same algorithm but instead of executing a super
7286                         //              method, it returns it, or "undefined" if not found.
7287                         //
7288                         // example:
7289                         //      |       var B = declare(A, {
7290                         //      |               method: function(a, b){
7291                         //      |                       var super = this.getInherited(arguments);
7292                         //      |                       // ...
7293                         //      |                       if(!super){
7294                         //      |                               console.log("there is no super method");
7295                         //      |                               return 0;
7296                         //      |                       }
7297                         //      |                       return super.apply(this, arguments);
7298                         //      |               }
7299                         //      |       });
7300                         return  {};     // Object
7301                 },
7302
7303                 isInstanceOf: function(cls){
7304                         // summary:
7305                         //              Checks the inheritance chain to see if it is inherited from this
7306                         //              class.
7307                         // cls: Function
7308                         //              Class constructor.
7309                         // returns:
7310                         //              "true", if this object is inherited from this class, "false"
7311                         //              otherwise.
7312                         // description:
7313                         //              This method is used with instances of classes produced with
7314                         //              declare() to determine of they support a certain interface or
7315                         //              not. It models "instanceof" operator.
7316                         //
7317                         // example:
7318                         //      |       var A = declare(null, {
7319                         //      |               // constructor, properties, and methods go here
7320                         //      |               // ...
7321                         //      |       });
7322                         //      |       var B = declare(null, {
7323                         //      |               // constructor, properties, and methods go here
7324                         //      |               // ...
7325                         //      |       });
7326                         //      |       var C = declare([A, B], {
7327                         //      |               // constructor, properties, and methods go here
7328                         //      |               // ...
7329                         //      |       });
7330                         //      |       var D = declare(A, {
7331                         //      |               // constructor, properties, and methods go here
7332                         //      |               // ...
7333                         //      |       });
7334                         //      |
7335                         //      |       var a = new A(), b = new B(), c = new C(), d = new D();
7336                         //      |
7337                         //      |       console.log(a.isInstanceOf(A)); // true
7338                         //      |       console.log(b.isInstanceOf(A)); // false
7339                         //      |       console.log(c.isInstanceOf(A)); // true
7340                         //      |       console.log(d.isInstanceOf(A)); // true
7341                         //      |
7342                         //      |       console.log(a.isInstanceOf(B)); // false
7343                         //      |       console.log(b.isInstanceOf(B)); // true
7344                         //      |       console.log(c.isInstanceOf(B)); // true
7345                         //      |       console.log(d.isInstanceOf(B)); // false
7346                         //      |
7347                         //      |       console.log(a.isInstanceOf(C)); // false
7348                         //      |       console.log(b.isInstanceOf(C)); // false
7349                         //      |       console.log(c.isInstanceOf(C)); // true
7350                         //      |       console.log(d.isInstanceOf(C)); // false
7351                         //      |
7352                         //      |       console.log(a.isInstanceOf(D)); // false
7353                         //      |       console.log(b.isInstanceOf(D)); // false
7354                         //      |       console.log(c.isInstanceOf(D)); // false
7355                         //      |       console.log(d.isInstanceOf(D)); // true
7356                         return  {};     // Object
7357                 },
7358
7359                 extend: function(source){
7360                         // summary:
7361                         //              Adds all properties and methods of source to constructor's
7362                         //              prototype, making them available to all instances created with
7363                         //              constructor. This method is specific to constructors created with
7364                         //              declare().
7365                         // source: Object
7366                         //              Source object which properties are going to be copied to the
7367                         //              constructor's prototype.
7368                         // description:
7369                         //              Adds source properties to the constructor's prototype. It can
7370                         //              override existing properties.
7371                         //
7372                         //              This method is similar to dojo.extend function, but it is specific
7373                         //              to constructors produced by declare(). It is implemented
7374                         //              using dojo.safeMixin, and it skips a constructor property,
7375                         //              and properly decorates copied functions.
7376                         //
7377                         // example:
7378                         //      |       var A = declare(null, {
7379                         //      |               m1: function(){},
7380                         //      |               s1: "Popokatepetl"
7381                         //      |       });
7382                         //      |       A.extend({
7383                         //      |               m1: function(){},
7384                         //      |               m2: function(){},
7385                         //      |               f1: true,
7386                         //      |               d1: 42
7387                         //      |       });
7388                 }
7389         };
7390         =====*/
7391
7392         // For back-compat, remove for 2.0
7393         dojo.safeMixin = declare.safeMixin = safeMixin;
7394         dojo.declare = declare;
7395
7396         return declare;
7397 });
7398
7399 },
7400 'dojo/dom':function(){
7401 define(["./sniff", "./_base/window"],
7402                 function(has, win){
7403         // module:
7404         //              dojo/dom
7405
7406         // FIXME: need to add unit tests for all the semi-public methods
7407
7408         if(has("ie") <= 7){
7409                 try{
7410                         document.execCommand("BackgroundImageCache", false, true);
7411                 }catch(e){
7412                         // sane browsers don't have cache "issues"
7413                 }
7414         }
7415
7416         // =============================
7417         // DOM Functions
7418         // =============================
7419
7420         // the result object
7421         var dom = {
7422                 // summary:
7423                 //              This module defines the core dojo DOM API.
7424         };
7425
7426         if(has("ie")){
7427                 dom.byId = function(id, doc){
7428                         if(typeof id != "string"){
7429                                 return id;
7430                         }
7431                         var _d = doc || win.doc, te = id && _d.getElementById(id);
7432                         // attributes.id.value is better than just id in case the
7433                         // user has a name=id inside a form
7434                         if(te && (te.attributes.id.value == id || te.id == id)){
7435                                 return te;
7436                         }else{
7437                                 var eles = _d.all[id];
7438                                 if(!eles || eles.nodeName){
7439                                         eles = [eles];
7440                                 }
7441                                 // if more than 1, choose first with the correct id
7442                                 var i = 0;
7443                                 while((te = eles[i++])){
7444                                         if((te.attributes && te.attributes.id && te.attributes.id.value == id) || te.id == id){
7445                                                 return te;
7446                                         }
7447                                 }
7448                         }
7449                 };
7450         }else{
7451                 dom.byId = function(id, doc){
7452                         // inline'd type check.
7453                         // be sure to return null per documentation, to match IE branch.
7454                         return ((typeof id == "string") ? (doc || win.doc).getElementById(id) : id) || null; // DOMNode
7455                 };
7456         }
7457         /*=====
7458          dom.byId = function(id, doc){
7459                  // summary:
7460                  //             Returns DOM node with matching `id` attribute or falsy value (ex: null or undefined)
7461                  //             if not found.  If `id` is a DomNode, this function is a no-op.
7462                  //
7463                  // id: String|DOMNode
7464                  //             A string to match an HTML id attribute or a reference to a DOM Node
7465                  //
7466                  // doc: Document?
7467                  //             Document to work in. Defaults to the current value of
7468                  //             dojo.doc.  Can be used to retrieve
7469                  //             node references from other documents.
7470                  //
7471                  // example:
7472                  //             Look up a node by ID:
7473                  //     |       var n = dojo.byId("foo");
7474                  //
7475                  // example:
7476                  //             Check if a node exists, and use it.
7477                  //     |       var n = dojo.byId("bar");
7478                  //     |       if(n){ doStuff() ... }
7479                  //
7480                  // example:
7481                  //             Allow string or DomNode references to be passed to a custom function:
7482                  //     |       var foo = function(nodeOrId){
7483                  //     |               nodeOrId = dojo.byId(nodeOrId);
7484                  //     |               // ... more stuff
7485                  //     |       }
7486          };
7487          =====*/
7488
7489         dom.isDescendant = function(/*DOMNode|String*/ node, /*DOMNode|String*/ ancestor){
7490                 // summary:
7491                 //              Returns true if node is a descendant of ancestor
7492                 // node: DOMNode|String
7493                 //              string id or node reference to test
7494                 // ancestor: DOMNode|String
7495                 //              string id or node reference of potential parent to test against
7496                 //
7497                 // example:
7498                 //              Test is node id="bar" is a descendant of node id="foo"
7499                 //      |       if(dojo.isDescendant("bar", "foo")){ ... }
7500
7501                 try{
7502                         node = dom.byId(node);
7503                         ancestor = dom.byId(ancestor);
7504                         while(node){
7505                                 if(node == ancestor){
7506                                         return true; // Boolean
7507                                 }
7508                                 node = node.parentNode;
7509                         }
7510                 }catch(e){ /* squelch, return false */ }
7511                 return false; // Boolean
7512         };
7513
7514
7515         // TODO: do we need setSelectable in the base?
7516
7517         // Add feature test for user-select CSS property
7518         // (currently known to work in all but IE < 10 and Opera)
7519         has.add("css-user-select", function(global, doc, element){
7520                 // Avoid exception when dom.js is loaded in non-browser environments
7521                 if(!element){ return false; }
7522                 
7523                 var style = element.style;
7524                 var prefixes = ["Khtml", "O", "ms", "Moz", "Webkit"],
7525                         i = prefixes.length,
7526                         name = "userSelect",
7527                         prefix;
7528
7529                 // Iterate prefixes from most to least likely
7530                 do{
7531                         if(typeof style[name] !== "undefined"){
7532                                 // Supported; return property name
7533                                 return name;
7534                         }
7535                 }while(i-- && (name = prefixes[i] + "UserSelect"));
7536
7537                 // Not supported if we didn't return before now
7538                 return false;
7539         });
7540
7541         /*=====
7542         dom.setSelectable = function(node, selectable){
7543                 // summary:
7544                 //              Enable or disable selection on a node
7545                 // node: DOMNode|String
7546                 //              id or reference to node
7547                 // selectable: Boolean
7548                 //              state to put the node in. false indicates unselectable, true
7549                 //              allows selection.
7550                 // example:
7551                 //              Make the node id="bar" unselectable
7552                 //      |       dojo.setSelectable("bar");
7553                 // example:
7554                 //              Make the node id="bar" selectable
7555                 //      |       dojo.setSelectable("bar", true);
7556         };
7557         =====*/
7558
7559         var cssUserSelect = has("css-user-select");
7560         dom.setSelectable = cssUserSelect ? function(node, selectable){
7561                 // css-user-select returns a (possibly vendor-prefixed) CSS property name
7562                 dom.byId(node).style[cssUserSelect] = selectable ? "" : "none";
7563         } : function(node, selectable){
7564                 node = dom.byId(node);
7565
7566                 // (IE < 10 / Opera) Fall back to setting/removing the
7567                 // unselectable attribute on the element and all its children
7568                 var nodes = node.getElementsByTagName("*"),
7569                         i = nodes.length;
7570
7571                 if(selectable){
7572                         node.removeAttribute("unselectable");
7573                         while(i--){
7574                                 nodes[i].removeAttribute("unselectable");
7575                         }
7576                 }else{
7577                         node.setAttribute("unselectable", "on");
7578                         while(i--){
7579                                 nodes[i].setAttribute("unselectable", "on");
7580                         }
7581                 }
7582         };
7583
7584         return dom;
7585 });
7586
7587 },
7588 'dojo/_base/browser':function(){
7589 if(require.has){
7590         require.has.add("config-selectorEngine", "acme");
7591 }
7592 define([
7593         "../ready",
7594         "./kernel",
7595         "./connect", // until we decide if connect is going back into non-browser environments
7596         "./unload",
7597         "./window",
7598         "./event",
7599         "./html",
7600         "./NodeList",
7601         "../query",
7602         "./xhr",
7603         "./fx"], function(dojo){
7604
7605         // module:
7606         //              dojo/_base/browser
7607
7608         /*=====
7609         return {
7610                 // summary:
7611                 //              This module causes the browser-only base modules to be loaded.
7612         };
7613         =====*/
7614
7615         return dojo;
7616 });
7617
7618 },
7619 'dojo/errors/RequestTimeoutError':function(){
7620 define("dojo/errors/RequestTimeoutError", ['./create', './RequestError'], function(create, RequestError){
7621         // module:
7622         //              dojo/errors/RequestTimeoutError
7623
7624         /*=====
7625          return function(){
7626                  // summary:
7627                  //             TODOC
7628          };
7629          =====*/
7630
7631         return create("RequestTimeoutError", null, RequestError, {
7632                 dojoType: "timeout"
7633         });
7634 });
7635
7636 },
7637 'dojo/dom-style':function(){
7638 define("dojo/dom-style", ["./sniff", "./dom"], function(has, dom){
7639         // module:
7640         //              dojo/dom-style
7641
7642         // =============================
7643         // Style Functions
7644         // =============================
7645
7646         // getComputedStyle drives most of the style code.
7647         // Wherever possible, reuse the returned object.
7648         //
7649         // API functions below that need to access computed styles accept an
7650         // optional computedStyle parameter.
7651         // If this parameter is omitted, the functions will call getComputedStyle themselves.
7652         // This way, calling code can access computedStyle once, and then pass the reference to
7653         // multiple API functions.
7654
7655         // Although we normally eschew argument validation at this
7656         // level, here we test argument 'node' for (duck)type,
7657         // by testing nodeType, ecause 'document' is the 'parentNode' of 'body'
7658         // it is frequently sent to this function even
7659         // though it is not Element.
7660         var getComputedStyle, style = {
7661                 // summary:
7662                 //              This module defines the core dojo DOM style API.
7663         };
7664         if(has("webkit")){
7665                 getComputedStyle = function(/*DomNode*/ node){
7666                         var s;
7667                         if(node.nodeType == 1){
7668                                 var dv = node.ownerDocument.defaultView;
7669                                 s = dv.getComputedStyle(node, null);
7670                                 if(!s && node.style){
7671                                         node.style.display = "";
7672                                         s = dv.getComputedStyle(node, null);
7673                                 }
7674                         }
7675                         return s || {};
7676                 };
7677         }else if(has("ie") && (has("ie") < 9 || has("quirks"))){
7678                 getComputedStyle = function(node){
7679                         // IE (as of 7) doesn't expose Element like sane browsers
7680                         // currentStyle can be null on IE8!
7681                         return node.nodeType == 1 /* ELEMENT_NODE*/ && node.currentStyle ? node.currentStyle : {};
7682                 };
7683         }else{
7684                 getComputedStyle = function(node){
7685                         return node.nodeType == 1 /* ELEMENT_NODE*/ ?
7686                                 node.ownerDocument.defaultView.getComputedStyle(node, null) : {};
7687                 };
7688         }
7689         style.getComputedStyle = getComputedStyle;
7690         /*=====
7691         style.getComputedStyle = function(node){
7692                 // summary:
7693                 //              Returns a "computed style" object.
7694                 //
7695                 // description:
7696                 //              Gets a "computed style" object which can be used to gather
7697                 //              information about the current state of the rendered node.
7698                 //
7699                 //              Note that this may behave differently on different browsers.
7700                 //              Values may have different formats and value encodings across
7701                 //              browsers.
7702                 //
7703                 //              Note also that this method is expensive.  Wherever possible,
7704                 //              reuse the returned object.
7705                 //
7706                 //              Use the dojo.style() method for more consistent (pixelized)
7707                 //              return values.
7708                 //
7709                 // node: DOMNode
7710                 //              A reference to a DOM node. Does NOT support taking an
7711                 //              ID string for speed reasons.
7712                 // example:
7713                 //      |       dojo.getComputedStyle(dojo.byId('foo')).borderWidth;
7714                 //
7715                 // example:
7716                 //              Reusing the returned object, avoiding multiple lookups:
7717                 //      |       var cs = dojo.getComputedStyle(dojo.byId("someNode"));
7718                 //      |       var w = cs.width, h = cs.height;
7719                 return; // CSS2Properties
7720         };
7721         =====*/
7722
7723         var toPixel;
7724         if(!has("ie")){
7725                 toPixel = function(element, value){
7726                         // style values can be floats, client code may want
7727                         // to round for integer pixels.
7728                         return parseFloat(value) || 0;
7729                 };
7730         }else{
7731                 toPixel = function(element, avalue){
7732                         if(!avalue){ return 0; }
7733                         // on IE7, medium is usually 4 pixels
7734                         if(avalue == "medium"){ return 4; }
7735                         // style values can be floats, client code may
7736                         // want to round this value for integer pixels.
7737                         if(avalue.slice && avalue.slice(-2) == 'px'){ return parseFloat(avalue); }
7738                         var s = element.style, rs = element.runtimeStyle, cs = element.currentStyle,
7739                                 sLeft = s.left, rsLeft = rs.left;
7740                         rs.left = cs.left;
7741                         try{
7742                                 // 'avalue' may be incompatible with style.left, which can cause IE to throw
7743                                 // this has been observed for border widths using "thin", "medium", "thick" constants
7744                                 // those particular constants could be trapped by a lookup
7745                                 // but perhaps there are more
7746                                 s.left = avalue;
7747                                 avalue = s.pixelLeft;
7748                         }catch(e){
7749                                 avalue = 0;
7750                         }
7751                         s.left = sLeft;
7752                         rs.left = rsLeft;
7753                         return avalue;
7754                 };
7755         }
7756         style.toPixelValue = toPixel;
7757         /*=====
7758         style.toPixelValue = function(node, value){
7759                 // summary:
7760                 //              converts style value to pixels on IE or return a numeric value.
7761                 // node: DOMNode
7762                 // value: String
7763                 // returns: Number
7764         };
7765         =====*/
7766
7767         // FIXME: there opacity quirks on FF that we haven't ported over. Hrm.
7768
7769         var astr = "DXImageTransform.Microsoft.Alpha";
7770         var af = function(n, f){
7771                 try{
7772                         return n.filters.item(astr);
7773                 }catch(e){
7774                         return f ? {} : null;
7775                 }
7776         };
7777
7778         var _getOpacity =
7779                 has("ie") < 9 || (has("ie") < 10 && has("quirks")) ? function(node){
7780                         try{
7781                                 return af(node).Opacity / 100; // Number
7782                         }catch(e){
7783                                 return 1; // Number
7784                         }
7785                 } :
7786                 function(node){
7787                         return getComputedStyle(node).opacity;
7788                 };
7789
7790         var _setOpacity =
7791                 has("ie") < 9 || (has("ie") < 10 && has("quirks")) ? function(/*DomNode*/ node, /*Number*/ opacity){
7792                         var ov = opacity * 100, opaque = opacity == 1;
7793                         node.style.zoom = opaque ? "" : 1;
7794
7795                         if(!af(node)){
7796                                 if(opaque){
7797                                         return opacity;
7798                                 }
7799                                 node.style.filter += " progid:" + astr + "(Opacity=" + ov + ")";
7800                         }else{
7801                                 af(node, 1).Opacity = ov;
7802                         }
7803
7804                         // on IE7 Alpha(Filter opacity=100) makes text look fuzzy so disable it altogether (bug #2661),
7805                         //but still update the opacity value so we can get a correct reading if it is read later.
7806                         af(node, 1).Enabled = !opaque;
7807
7808                         if(node.tagName.toLowerCase() == "tr"){
7809                                 for(var td = node.firstChild; td; td = td.nextSibling){
7810                                         if(td.tagName.toLowerCase() == "td"){
7811                                                 _setOpacity(td, opacity);
7812                                         }
7813                                 }
7814                         }
7815                         return opacity;
7816                 } :
7817                 function(node, opacity){
7818                         return node.style.opacity = opacity;
7819                 };
7820
7821         var _pixelNamesCache = {
7822                 left: true, top: true
7823         };
7824         var _pixelRegExp = /margin|padding|width|height|max|min|offset/; // |border
7825         function _toStyleValue(node, type, value){
7826                 //TODO: should we really be doing string case conversion here? Should we cache it? Need to profile!
7827                 type = type.toLowerCase();
7828                 if(has("ie")){
7829                         if(value == "auto"){
7830                                 if(type == "height"){ return node.offsetHeight; }
7831                                 if(type == "width"){ return node.offsetWidth; }
7832                         }
7833                         if(type == "fontweight"){
7834                                 switch(value){
7835                                         case 700: return "bold";
7836                                         case 400:
7837                                         default: return "normal";
7838                                 }
7839                         }
7840                 }
7841                 if(!(type in _pixelNamesCache)){
7842                         _pixelNamesCache[type] = _pixelRegExp.test(type);
7843                 }
7844                 return _pixelNamesCache[type] ? toPixel(node, value) : value;
7845         }
7846
7847         var _floatStyle = has("ie") ? "styleFloat" : "cssFloat",
7848                 _floatAliases = {"cssFloat": _floatStyle, "styleFloat": _floatStyle, "float": _floatStyle};
7849
7850         // public API
7851
7852         style.get = function getStyle(/*DOMNode|String*/ node, /*String?*/ name){
7853                 // summary:
7854                 //              Accesses styles on a node.
7855                 // description:
7856                 //              Getting the style value uses the computed style for the node, so the value
7857                 //              will be a calculated value, not just the immediate node.style value.
7858                 //              Also when getting values, use specific style names,
7859                 //              like "borderBottomWidth" instead of "border" since compound values like
7860                 //              "border" are not necessarily reflected as expected.
7861                 //              If you want to get node dimensions, use `dojo.marginBox()`,
7862                 //              `dojo.contentBox()` or `dojo.position()`.
7863                 // node: DOMNode|String
7864                 //              id or reference to node to get style for
7865                 // name: String?
7866                 //              the style property to get
7867                 // example:
7868                 //              Passing only an ID or node returns the computed style object of
7869                 //              the node:
7870                 //      |       dojo.getStyle("thinger");
7871                 // example:
7872                 //              Passing a node and a style property returns the current
7873                 //              normalized, computed value for that property:
7874                 //      |       dojo.getStyle("thinger", "opacity"); // 1 by default
7875
7876                 var n = dom.byId(node), l = arguments.length, op = (name == "opacity");
7877                 if(l == 2 && op){
7878                         return _getOpacity(n);
7879                 }
7880                 name = _floatAliases[name] || name;
7881                 var s = style.getComputedStyle(n);
7882                 return (l == 1) ? s : _toStyleValue(n, name, s[name] || n.style[name]); /* CSS2Properties||String||Number */
7883         };
7884
7885         style.set = function setStyle(/*DOMNode|String*/ node, /*String|Object*/ name, /*String?*/ value){
7886                 // summary:
7887                 //              Sets styles on a node.
7888                 // node: DOMNode|String
7889                 //              id or reference to node to set style for
7890                 // name: String|Object
7891                 //              the style property to set in DOM-accessor format
7892                 //              ("borderWidth", not "border-width") or an object with key/value
7893                 //              pairs suitable for setting each property.
7894                 // value: String?
7895                 //              If passed, sets value on the node for style, handling
7896                 //              cross-browser concerns.  When setting a pixel value,
7897                 //              be sure to include "px" in the value. For instance, top: "200px".
7898                 //              Otherwise, in some cases, some browsers will not apply the style.
7899                 //
7900                 // example:
7901                 //              Passing a node, a style property, and a value changes the
7902                 //              current display of the node and returns the new computed value
7903                 //      |       dojo.setStyle("thinger", "opacity", 0.5); // == 0.5
7904                 //
7905                 // example:
7906                 //              Passing a node, an object-style style property sets each of the values in turn and returns the computed style object of the node:
7907                 //      |       dojo.setStyle("thinger", {
7908                 //      |               "opacity": 0.5,
7909                 //      |               "border": "3px solid black",
7910                 //      |               "height": "300px"
7911                 //      |       });
7912                 //
7913                 // example:
7914                 //              When the CSS style property is hyphenated, the JavaScript property is camelCased.
7915                 //              font-size becomes fontSize, and so on.
7916                 //      |       dojo.setStyle("thinger",{
7917                 //      |               fontSize:"14pt",
7918                 //      |               letterSpacing:"1.2em"
7919                 //      |       });
7920                 //
7921                 // example:
7922                 //              dojo/NodeList implements .style() using the same syntax, omitting the "node" parameter, calling
7923                 //              dojo.style() on every element of the list. See: `dojo.query()` and `dojo/NodeList`
7924                 //      |       dojo.query(".someClassName").style("visibility","hidden");
7925                 //      |       // or
7926                 //      |       dojo.query("#baz > div").style({
7927                 //      |               opacity:0.75,
7928                 //      |               fontSize:"13pt"
7929                 //      |       });
7930
7931                 var n = dom.byId(node), l = arguments.length, op = (name == "opacity");
7932                 name = _floatAliases[name] || name;
7933                 if(l == 3){
7934                         return op ? _setOpacity(n, value) : n.style[name] = value; // Number
7935                 }
7936                 for(var x in name){
7937                         style.set(node, x, name[x]);
7938                 }
7939                 return style.getComputedStyle(n);
7940         };
7941
7942         return style;
7943 });
7944
7945 },
7946 'dojo/dom-geometry':function(){
7947 define(["./sniff", "./_base/window","./dom", "./dom-style"],
7948                 function(has, win, dom, style){
7949         // module:
7950         //              dojo/dom-geometry
7951
7952         // the result object
7953         var geom = {
7954                 // summary:
7955                 //              This module defines the core dojo DOM geometry API.
7956         };
7957
7958         // Box functions will assume this model.
7959         // On IE/Opera, BORDER_BOX will be set if the primary document is in quirks mode.
7960         // Can be set to change behavior of box setters.
7961
7962         // can be either:
7963         //      "border-box"
7964         //      "content-box" (default)
7965         geom.boxModel = "content-box";
7966
7967         // We punt per-node box mode testing completely.
7968         // If anybody cares, we can provide an additional (optional) unit
7969         // that overrides existing code to include per-node box sensitivity.
7970
7971         // Opera documentation claims that Opera 9 uses border-box in BackCompat mode.
7972         // but experiments (Opera 9.10.8679 on Windows Vista) indicate that it actually continues to use content-box.
7973         // IIRC, earlier versions of Opera did in fact use border-box.
7974         // Opera guys, this is really confusing. Opera being broken in quirks mode is not our fault.
7975
7976         if(has("ie") /*|| has("opera")*/){
7977                 // client code may have to adjust if compatMode varies across iframes
7978                 geom.boxModel = document.compatMode == "BackCompat" ? "border-box" : "content-box";
7979         }
7980
7981         geom.getPadExtents = function getPadExtents(/*DomNode*/ node, /*Object*/ computedStyle){
7982                 // summary:
7983                 //              Returns object with special values specifically useful for node
7984                 //              fitting.
7985                 // description:
7986                 //              Returns an object with `w`, `h`, `l`, `t` properties:
7987                 //      |               l/t/r/b = left/top/right/bottom padding (respectively)
7988                 //      |               w = the total of the left and right padding
7989                 //      |               h = the total of the top and bottom padding
7990                 //              If 'node' has position, l/t forms the origin for child nodes.
7991                 //              The w/h are used for calculating boxes.
7992                 //              Normally application code will not need to invoke this
7993                 //              directly, and will use the ...box... functions instead.
7994                 // node: DOMNode
7995                 // computedStyle: Object?
7996                 //              This parameter accepts computed styles object.
7997                 //              If this parameter is omitted, the functions will call
7998                 //              dojo.getComputedStyle to get one. It is a better way, calling
7999                 //              dojo.computedStyle once, and then pass the reference to this
8000                 //              computedStyle parameter. Wherever possible, reuse the returned
8001                 //              object of dojo/dom-style.getComputedStyle().
8002
8003                 node = dom.byId(node);
8004                 var s = computedStyle || style.getComputedStyle(node), px = style.toPixelValue,
8005                         l = px(node, s.paddingLeft), t = px(node, s.paddingTop), r = px(node, s.paddingRight), b = px(node, s.paddingBottom);
8006                 return {l: l, t: t, r: r, b: b, w: l + r, h: t + b};
8007         };
8008
8009         var none = "none";
8010
8011         geom.getBorderExtents = function getBorderExtents(/*DomNode*/ node, /*Object*/ computedStyle){
8012                 // summary:
8013                 //              returns an object with properties useful for noting the border
8014                 //              dimensions.
8015                 // description:
8016                 //              - l/t/r/b = the sum of left/top/right/bottom border (respectively)
8017                 //              - w = the sum of the left and right border
8018                 //              - h = the sum of the top and bottom border
8019                 //
8020                 //              The w/h are used for calculating boxes.
8021                 //              Normally application code will not need to invoke this
8022                 //              directly, and will use the ...box... functions instead.
8023                 // node: DOMNode
8024                 // computedStyle: Object?
8025                 //              This parameter accepts computed styles object.
8026                 //              If this parameter is omitted, the functions will call
8027                 //              dojo.getComputedStyle to get one. It is a better way, calling
8028                 //              dojo.computedStyle once, and then pass the reference to this
8029                 //              computedStyle parameter. Wherever possible, reuse the returned
8030                 //              object of dojo/dom-style.getComputedStyle().
8031
8032                 node = dom.byId(node);
8033                 var px = style.toPixelValue, s = computedStyle || style.getComputedStyle(node),
8034                         l = s.borderLeftStyle != none ? px(node, s.borderLeftWidth) : 0,
8035                         t = s.borderTopStyle != none ? px(node, s.borderTopWidth) : 0,
8036                         r = s.borderRightStyle != none ? px(node, s.borderRightWidth) : 0,
8037                         b = s.borderBottomStyle != none ? px(node, s.borderBottomWidth) : 0;
8038                 return {l: l, t: t, r: r, b: b, w: l + r, h: t + b};
8039         };
8040
8041         geom.getPadBorderExtents = function getPadBorderExtents(/*DomNode*/ node, /*Object*/ computedStyle){
8042                 // summary:
8043                 //              Returns object with properties useful for box fitting with
8044                 //              regards to padding.
8045                 // description:
8046                 //              - l/t/r/b = the sum of left/top/right/bottom padding and left/top/right/bottom border (respectively)
8047                 //              - w = the sum of the left and right padding and border
8048                 //              - h = the sum of the top and bottom padding and border
8049                 //
8050                 //              The w/h are used for calculating boxes.
8051                 //              Normally application code will not need to invoke this
8052                 //              directly, and will use the ...box... functions instead.
8053                 // node: DOMNode
8054                 // computedStyle: Object?
8055                 //              This parameter accepts computed styles object.
8056                 //              If this parameter is omitted, the functions will call
8057                 //              dojo.getComputedStyle to get one. It is a better way, calling
8058                 //              dojo.computedStyle once, and then pass the reference to this
8059                 //              computedStyle parameter. Wherever possible, reuse the returned
8060                 //              object of dojo/dom-style.getComputedStyle().
8061
8062                 node = dom.byId(node);
8063                 var s = computedStyle || style.getComputedStyle(node),
8064                         p = geom.getPadExtents(node, s),
8065                         b = geom.getBorderExtents(node, s);
8066                 return {
8067                         l: p.l + b.l,
8068                         t: p.t + b.t,
8069                         r: p.r + b.r,
8070                         b: p.b + b.b,
8071                         w: p.w + b.w,
8072                         h: p.h + b.h
8073                 };
8074         };
8075
8076         geom.getMarginExtents = function getMarginExtents(node, computedStyle){
8077                 // summary:
8078                 //              returns object with properties useful for box fitting with
8079                 //              regards to box margins (i.e., the outer-box).
8080                 //
8081                 //              - l/t = marginLeft, marginTop, respectively
8082                 //              - w = total width, margin inclusive
8083                 //              - h = total height, margin inclusive
8084                 //
8085                 //              The w/h are used for calculating boxes.
8086                 //              Normally application code will not need to invoke this
8087                 //              directly, and will use the ...box... functions instead.
8088                 // node: DOMNode
8089                 // computedStyle: Object?
8090                 //              This parameter accepts computed styles object.
8091                 //              If this parameter is omitted, the functions will call
8092                 //              dojo.getComputedStyle to get one. It is a better way, calling
8093                 //              dojo.computedStyle once, and then pass the reference to this
8094                 //              computedStyle parameter. Wherever possible, reuse the returned
8095                 //              object of dojo/dom-style.getComputedStyle().
8096
8097                 node = dom.byId(node);
8098                 var s = computedStyle || style.getComputedStyle(node), px = style.toPixelValue,
8099                         l = px(node, s.marginLeft), t = px(node, s.marginTop), r = px(node, s.marginRight), b = px(node, s.marginBottom);
8100                 return {l: l, t: t, r: r, b: b, w: l + r, h: t + b};
8101         };
8102
8103         // Box getters work in any box context because offsetWidth/clientWidth
8104         // are invariant wrt box context
8105         //
8106         // They do *not* work for display: inline objects that have padding styles
8107         // because the user agent ignores padding (it's bogus styling in any case)
8108         //
8109         // Be careful with IMGs because they are inline or block depending on
8110         // browser and browser mode.
8111
8112         // Although it would be easier to read, there are not separate versions of
8113         // _getMarginBox for each browser because:
8114         // 1. the branching is not expensive
8115         // 2. factoring the shared code wastes cycles (function call overhead)
8116         // 3. duplicating the shared code wastes bytes
8117
8118         geom.getMarginBox = function getMarginBox(/*DomNode*/ node, /*Object*/ computedStyle){
8119                 // summary:
8120                 //              returns an object that encodes the width, height, left and top
8121                 //              positions of the node's margin box.
8122                 // node: DOMNode
8123                 // computedStyle: Object?
8124                 //              This parameter accepts computed styles object.
8125                 //              If this parameter is omitted, the functions will call
8126                 //              dojo.getComputedStyle to get one. It is a better way, calling
8127                 //              dojo.computedStyle once, and then pass the reference to this
8128                 //              computedStyle parameter. Wherever possible, reuse the returned
8129                 //              object of dojo/dom-style.getComputedStyle().
8130
8131                 node = dom.byId(node);
8132                 var s = computedStyle || style.getComputedStyle(node), me = geom.getMarginExtents(node, s),
8133                         l = node.offsetLeft - me.l, t = node.offsetTop - me.t, p = node.parentNode, px = style.toPixelValue, pcs;
8134                 if(has("mozilla")){
8135                         // Mozilla:
8136                         // If offsetParent has a computed overflow != visible, the offsetLeft is decreased
8137                         // by the parent's border.
8138                         // We don't want to compute the parent's style, so instead we examine node's
8139                         // computed left/top which is more stable.
8140                         var sl = parseFloat(s.left), st = parseFloat(s.top);
8141                         if(!isNaN(sl) && !isNaN(st)){
8142                                 l = sl;
8143                                 t = st;
8144                         }else{
8145                                 // If child's computed left/top are not parseable as a number (e.g. "auto"), we
8146                                 // have no choice but to examine the parent's computed style.
8147                                 if(p && p.style){
8148                                         pcs = style.getComputedStyle(p);
8149                                         if(pcs.overflow != "visible"){
8150                                                 l += pcs.borderLeftStyle != none ? px(node, pcs.borderLeftWidth) : 0;
8151                                                 t += pcs.borderTopStyle != none ? px(node, pcs.borderTopWidth) : 0;
8152                                         }
8153                                 }
8154                         }
8155                 }else if(has("opera") || (has("ie") == 8 && !has("quirks"))){
8156                         // On Opera and IE 8, offsetLeft/Top includes the parent's border
8157                         if(p){
8158                                 pcs = style.getComputedStyle(p);
8159                                 l -= pcs.borderLeftStyle != none ? px(node, pcs.borderLeftWidth) : 0;
8160                                 t -= pcs.borderTopStyle != none ? px(node, pcs.borderTopWidth) : 0;
8161                         }
8162                 }
8163                 return {l: l, t: t, w: node.offsetWidth + me.w, h: node.offsetHeight + me.h};
8164         };
8165
8166         geom.getContentBox = function getContentBox(node, computedStyle){
8167                 // summary:
8168                 //              Returns an object that encodes the width, height, left and top
8169                 //              positions of the node's content box, irrespective of the
8170                 //              current box model.
8171                 // node: DOMNode
8172                 // computedStyle: Object?
8173                 //              This parameter accepts computed styles object.
8174                 //              If this parameter is omitted, the functions will call
8175                 //              dojo.getComputedStyle to get one. It is a better way, calling
8176                 //              dojo.computedStyle once, and then pass the reference to this
8177                 //              computedStyle parameter. Wherever possible, reuse the returned
8178                 //              object of dojo/dom-style.getComputedStyle().
8179
8180                 // clientWidth/Height are important since the automatically account for scrollbars
8181                 // fallback to offsetWidth/Height for special cases (see #3378)
8182                 node = dom.byId(node);
8183                 var s = computedStyle || style.getComputedStyle(node), w = node.clientWidth, h,
8184                         pe = geom.getPadExtents(node, s), be = geom.getBorderExtents(node, s);
8185                 if(!w){
8186                         w = node.offsetWidth;
8187                         h = node.offsetHeight;
8188                 }else{
8189                         h = node.clientHeight;
8190                         be.w = be.h = 0;
8191                 }
8192                 // On Opera, offsetLeft includes the parent's border
8193                 if(has("opera")){
8194                         pe.l += be.l;
8195                         pe.t += be.t;
8196                 }
8197                 return {l: pe.l, t: pe.t, w: w - pe.w - be.w, h: h - pe.h - be.h};
8198         };
8199
8200         // Box setters depend on box context because interpretation of width/height styles
8201         // vary wrt box context.
8202         //
8203         // The value of boxModel is used to determine box context.
8204         // boxModel can be set directly to change behavior.
8205         //
8206         // Beware of display: inline objects that have padding styles
8207         // because the user agent ignores padding (it's a bogus setup anyway)
8208         //
8209         // Be careful with IMGs because they are inline or block depending on
8210         // browser and browser mode.
8211         //
8212         // Elements other than DIV may have special quirks, like built-in
8213         // margins or padding, or values not detectable via computedStyle.
8214         // In particular, margins on TABLE do not seems to appear
8215         // at all in computedStyle on Mozilla.
8216
8217         function setBox(/*DomNode*/ node, /*Number?*/ l, /*Number?*/ t, /*Number?*/ w, /*Number?*/ h, /*String?*/ u){
8218                 // summary:
8219                 //              sets width/height/left/top in the current (native) box-model
8220                 //              dimensions. Uses the unit passed in u.
8221                 // node:
8222                 //              DOM Node reference. Id string not supported for performance
8223                 //              reasons.
8224                 // l:
8225                 //              left offset from parent.
8226                 // t:
8227                 //              top offset from parent.
8228                 // w:
8229                 //              width in current box model.
8230                 // h:
8231                 //              width in current box model.
8232                 // u:
8233                 //              unit measure to use for other measures. Defaults to "px".
8234                 u = u || "px";
8235                 var s = node.style;
8236                 if(!isNaN(l)){
8237                         s.left = l + u;
8238                 }
8239                 if(!isNaN(t)){
8240                         s.top = t + u;
8241                 }
8242                 if(w >= 0){
8243                         s.width = w + u;
8244                 }
8245                 if(h >= 0){
8246                         s.height = h + u;
8247                 }
8248         }
8249
8250         function isButtonTag(/*DomNode*/ node){
8251                 // summary:
8252                 //              True if the node is BUTTON or INPUT.type="button".
8253                 return node.tagName.toLowerCase() == "button" ||
8254                         node.tagName.toLowerCase() == "input" && (node.getAttribute("type") || "").toLowerCase() == "button"; // boolean
8255         }
8256
8257         function usesBorderBox(/*DomNode*/ node){
8258                 // summary:
8259                 //              True if the node uses border-box layout.
8260
8261                 // We could test the computed style of node to see if a particular box
8262                 // has been specified, but there are details and we choose not to bother.
8263
8264                 // TABLE and BUTTON (and INPUT type=button) are always border-box by default.
8265                 // If you have assigned a different box to either one via CSS then
8266                 // box functions will break.
8267
8268                 return geom.boxModel == "border-box" || node.tagName.toLowerCase() == "table" || isButtonTag(node); // boolean
8269         }
8270
8271         geom.setContentSize = function setContentSize(/*DomNode*/ node, /*Object*/ box, /*Object*/ computedStyle){
8272                 // summary:
8273                 //              Sets the size of the node's contents, irrespective of margins,
8274                 //              padding, or borders.
8275                 // node: DOMNode
8276                 // box: Object
8277                 //              hash with optional "w", and "h" properties for "width", and "height"
8278                 //              respectively. All specified properties should have numeric values in whole pixels.
8279                 // computedStyle: Object?
8280                 //              This parameter accepts computed styles object.
8281                 //              If this parameter is omitted, the functions will call
8282                 //              dojo.getComputedStyle to get one. It is a better way, calling
8283                 //              dojo.computedStyle once, and then pass the reference to this
8284                 //              computedStyle parameter. Wherever possible, reuse the returned
8285                 //              object of dojo/dom-style.getComputedStyle().
8286
8287                 node = dom.byId(node);
8288                 var w = box.w, h = box.h;
8289                 if(usesBorderBox(node)){
8290                         var pb = geom.getPadBorderExtents(node, computedStyle);
8291                         if(w >= 0){
8292                                 w += pb.w;
8293                         }
8294                         if(h >= 0){
8295                                 h += pb.h;
8296                         }
8297                 }
8298                 setBox(node, NaN, NaN, w, h);
8299         };
8300
8301         var nilExtents = {l: 0, t: 0, w: 0, h: 0};
8302
8303         geom.setMarginBox = function setMarginBox(/*DomNode*/ node, /*Object*/ box, /*Object*/ computedStyle){
8304                 // summary:
8305                 //              sets the size of the node's margin box and placement
8306                 //              (left/top), irrespective of box model. Think of it as a
8307                 //              passthrough to setBox that handles box-model vagaries for
8308                 //              you.
8309                 // node: DOMNode
8310                 // box: Object
8311                 //              hash with optional "l", "t", "w", and "h" properties for "left", "right", "width", and "height"
8312                 //              respectively. All specified properties should have numeric values in whole pixels.
8313                 // computedStyle: Object?
8314                 //              This parameter accepts computed styles object.
8315                 //              If this parameter is omitted, the functions will call
8316                 //              dojo.getComputedStyle to get one. It is a better way, calling
8317                 //              dojo.computedStyle once, and then pass the reference to this
8318                 //              computedStyle parameter. Wherever possible, reuse the returned
8319                 //              object of dojo/dom-style.getComputedStyle().
8320
8321                 node = dom.byId(node);
8322                 var s = computedStyle || style.getComputedStyle(node), w = box.w, h = box.h,
8323                 // Some elements have special padding, margin, and box-model settings.
8324                 // To use box functions you may need to set padding, margin explicitly.
8325                 // Controlling box-model is harder, in a pinch you might set dojo/dom-geometry.boxModel.
8326                         pb = usesBorderBox(node) ? nilExtents : geom.getPadBorderExtents(node, s),
8327                         mb = geom.getMarginExtents(node, s);
8328                 if(has("webkit")){
8329                         // on Safari (3.1.2), button nodes with no explicit size have a default margin
8330                         // setting an explicit size eliminates the margin.
8331                         // We have to swizzle the width to get correct margin reading.
8332                         if(isButtonTag(node)){
8333                                 var ns = node.style;
8334                                 if(w >= 0 && !ns.width){
8335                                         ns.width = "4px";
8336                                 }
8337                                 if(h >= 0 && !ns.height){
8338                                         ns.height = "4px";
8339                                 }
8340                         }
8341                 }
8342                 if(w >= 0){
8343                         w = Math.max(w - pb.w - mb.w, 0);
8344                 }
8345                 if(h >= 0){
8346                         h = Math.max(h - pb.h - mb.h, 0);
8347                 }
8348                 setBox(node, box.l, box.t, w, h);
8349         };
8350
8351         // =============================
8352         // Positioning
8353         // =============================
8354
8355         geom.isBodyLtr = function isBodyLtr(/*Document?*/ doc){
8356                 // summary:
8357                 //              Returns true if the current language is left-to-right, and false otherwise.
8358                 // doc: Document?
8359                 //              Optional document to query.   If unspecified, use win.doc.
8360                 // returns: Boolean
8361
8362                 doc = doc || win.doc;
8363                 return (win.body(doc).dir || doc.documentElement.dir || "ltr").toLowerCase() == "ltr"; // Boolean
8364         };
8365
8366         geom.docScroll = function docScroll(/*Document?*/ doc){
8367                 // summary:
8368                 //              Returns an object with {node, x, y} with corresponding offsets.
8369                 // doc: Document?
8370                 //              Optional document to query.   If unspecified, use win.doc.
8371                 // returns: Object
8372
8373                 doc = doc || win.doc;
8374                 var node = win.doc.parentWindow || win.doc.defaultView;   // use UI window, not dojo.global window.   TODO: use dojo/window::get() except for circular dependency problem
8375                 return "pageXOffset" in node ? {x: node.pageXOffset, y: node.pageYOffset } :
8376                         (node = has("quirks") ? win.body(doc) : doc.documentElement) &&
8377                                 {x: geom.fixIeBiDiScrollLeft(node.scrollLeft || 0, doc), y: node.scrollTop || 0 };
8378         };
8379
8380         if(has("ie")){
8381                 geom.getIeDocumentElementOffset = function getIeDocumentElementOffset(/*Document?*/ doc){
8382                         // summary:
8383                         //              returns the offset in x and y from the document body to the
8384                         //              visual edge of the page for IE
8385                         // doc: Document?
8386                         //              Optional document to query.   If unspecified, use win.doc.
8387                         // description:
8388                         //              The following values in IE contain an offset:
8389                         //      |               event.clientX
8390                         //      |               event.clientY
8391                         //      |               node.getBoundingClientRect().left
8392                         //      |               node.getBoundingClientRect().top
8393                         //              But other position related values do not contain this offset,
8394                         //              such as node.offsetLeft, node.offsetTop, node.style.left and
8395                         //              node.style.top. The offset is always (2, 2) in LTR direction.
8396                         //              When the body is in RTL direction, the offset counts the width
8397                         //              of left scroll bar's width.  This function computes the actual
8398                         //              offset.
8399
8400                         //NOTE: assumes we're being called in an IE browser
8401
8402                         doc = doc || win.doc;
8403                         var de = doc.documentElement; // only deal with HTML element here, position() handles body/quirks
8404
8405                         if(has("ie") < 8){
8406                                 var r = de.getBoundingClientRect(), // works well for IE6+
8407                                         l = r.left, t = r.top;
8408                                 if(has("ie") < 7){
8409                                         l += de.clientLeft;     // scrollbar size in strict/RTL, or,
8410                                         t += de.clientTop;      // HTML border size in strict
8411                                 }
8412                                 return {
8413                                         x: l < 0 ? 0 : l, // FRAME element border size can lead to inaccurate negative values
8414                                         y: t < 0 ? 0 : t
8415                                 };
8416                         }else{
8417                                 return {
8418                                         x: 0,
8419                                         y: 0
8420                                 };
8421                         }
8422                 };
8423         }
8424
8425         geom.fixIeBiDiScrollLeft = function fixIeBiDiScrollLeft(/*Integer*/ scrollLeft, /*Document?*/ doc){
8426                 // summary:
8427                 //              In RTL direction, scrollLeft should be a negative value, but IE
8428                 //              returns a positive one. All codes using documentElement.scrollLeft
8429                 //              must call this function to fix this error, otherwise the position
8430                 //              will offset to right when there is a horizontal scrollbar.
8431                 // scrollLeft: Number
8432                 // doc: Document?
8433                 //              Optional document to query.   If unspecified, use win.doc.
8434                 // returns: Number
8435
8436                 // In RTL direction, scrollLeft should be a negative value, but IE
8437                 // returns a positive one. All codes using documentElement.scrollLeft
8438                 // must call this function to fix this error, otherwise the position
8439                 // will offset to right when there is a horizontal scrollbar.
8440
8441                 doc = doc || win.doc;
8442                 var ie = has("ie");
8443                 if(ie && !geom.isBodyLtr(doc)){
8444                         var qk = has("quirks"),
8445                                 de = qk ? win.body(doc) : doc.documentElement,
8446                                 pwin = win.global;      // TODO: use winUtils.get(doc) after resolving circular dependency b/w dom-geometry.js and dojo/window.js
8447                         if(ie == 6 && !qk && pwin.frameElement && de.scrollHeight > de.clientHeight){
8448                                 scrollLeft += de.clientLeft; // workaround ie6+strict+rtl+iframe+vertical-scrollbar bug where clientWidth is too small by clientLeft pixels
8449                         }
8450                         return (ie < 8 || qk) ? (scrollLeft + de.clientWidth - de.scrollWidth) : -scrollLeft; // Integer
8451                 }
8452                 return scrollLeft; // Integer
8453         };
8454
8455         geom.position = function(/*DomNode*/ node, /*Boolean?*/ includeScroll){
8456                 // summary:
8457                 //              Gets the position and size of the passed element relative to
8458                 //              the viewport (if includeScroll==false), or relative to the
8459                 //              document root (if includeScroll==true).
8460                 //
8461                 // description:
8462                 //              Returns an object of the form:
8463                 //              `{ x: 100, y: 300, w: 20, h: 15 }`.
8464                 //              If includeScroll==true, the x and y values will include any
8465                 //              document offsets that may affect the position relative to the
8466                 //              viewport.
8467                 //              Uses the border-box model (inclusive of border and padding but
8468                 //              not margin).  Does not act as a setter.
8469                 // node: DOMNode|String
8470                 // includeScroll: Boolean?
8471                 // returns: Object
8472
8473                 node = dom.byId(node);
8474                 var     db = win.body(node.ownerDocument),
8475                         ret = node.getBoundingClientRect();
8476                 ret = {x: ret.left, y: ret.top, w: ret.right - ret.left, h: ret.bottom - ret.top};
8477
8478                 if(has("ie") < 9){
8479                         // On IE<9 there's a 2px offset that we need to adjust for, see dojo.getIeDocumentElementOffset()
8480                         var offset = geom.getIeDocumentElementOffset(node.ownerDocument);
8481
8482                         // fixes the position in IE, quirks mode
8483                         ret.x -= offset.x + (has("quirks") ? db.clientLeft + db.offsetLeft : 0);
8484                         ret.y -= offset.y + (has("quirks") ? db.clientTop + db.offsetTop : 0);
8485                 }
8486
8487                 // account for document scrolling
8488                 // if offsetParent is used, ret value already includes scroll position
8489                 // so we may have to actually remove that value if !includeScroll
8490                 if(includeScroll){
8491                         var scroll = geom.docScroll(node.ownerDocument);
8492                         ret.x += scroll.x;
8493                         ret.y += scroll.y;
8494                 }
8495
8496                 return ret; // Object
8497         };
8498
8499         // random "private" functions wildly used throughout the toolkit
8500
8501         geom.getMarginSize = function getMarginSize(/*DomNode*/ node, /*Object*/ computedStyle){
8502                 // summary:
8503                 //              returns an object that encodes the width and height of
8504                 //              the node's margin box
8505                 // node: DOMNode|String
8506                 // computedStyle: Object?
8507                 //              This parameter accepts computed styles object.
8508                 //              If this parameter is omitted, the functions will call
8509                 //              dojo.getComputedStyle to get one. It is a better way, calling
8510                 //              dojo.computedStyle once, and then pass the reference to this
8511                 //              computedStyle parameter. Wherever possible, reuse the returned
8512                 //              object of dojo/dom-style.getComputedStyle().
8513
8514                 node = dom.byId(node);
8515                 var me = geom.getMarginExtents(node, computedStyle || style.getComputedStyle(node));
8516                 var size = node.getBoundingClientRect();
8517                 return {
8518                         w: (size.right - size.left) + me.w,
8519                         h: (size.bottom - size.top) + me.h
8520                 };
8521         };
8522
8523         geom.normalizeEvent = function(event){
8524                 // summary:
8525                 //              Normalizes the geometry of a DOM event, normalizing the pageX, pageY,
8526                 //              offsetX, offsetY, layerX, and layerX properties
8527                 // event: Object
8528                 if(!("layerX" in event)){
8529                         event.layerX = event.offsetX;
8530                         event.layerY = event.offsetY;
8531                 }
8532                 if(!has("dom-addeventlistener")){
8533                         // old IE version
8534                         // FIXME: scroll position query is duped from dojo.html to
8535                         // avoid dependency on that entire module. Now that HTML is in
8536                         // Base, we should convert back to something similar there.
8537                         var se = event.target;
8538                         var doc = (se && se.ownerDocument) || document;
8539                         // DO NOT replace the following to use dojo.body(), in IE, document.documentElement should be used
8540                         // here rather than document.body
8541                         var docBody = has("quirks") ? doc.body : doc.documentElement;
8542                         var offset = geom.getIeDocumentElementOffset(doc);
8543                         event.pageX = event.clientX + geom.fixIeBiDiScrollLeft(docBody.scrollLeft || 0, doc) - offset.x;
8544                         event.pageY = event.clientY + (docBody.scrollTop || 0) - offset.y;
8545                 }
8546         };
8547
8548         // TODO: evaluate separate getters/setters for position and sizes?
8549
8550         return geom;
8551 });
8552
8553 },
8554 'dojo/dom-prop':function(){
8555 define(["exports", "./_base/kernel", "./sniff", "./_base/lang", "./dom", "./dom-style", "./dom-construct", "./_base/connect"],
8556                 function(exports, dojo, has, lang, dom, style, ctr, conn){
8557         // module:
8558         //              dojo/dom-prop
8559         // summary:
8560         //              This module defines the core dojo DOM properties API.
8561         //              Indirectly depends on dojo.empty() and dojo.toDom().
8562
8563         // TODOC: summary not showing up in output, see https://github.com/csnover/js-doc-parse/issues/42
8564
8565         // =============================
8566         // Element properties Functions
8567         // =============================
8568
8569         // helper to connect events
8570         var _evtHdlrMap = {}, _ctr = 0, _attrId = dojo._scopeName + "attrid";
8571
8572         exports.names = {
8573                 // properties renamed to avoid clashes with reserved words
8574                 "class": "className",
8575                 "for": "htmlFor",
8576                 // properties written as camelCase
8577                 tabindex: "tabIndex",
8578                 readonly: "readOnly",
8579                 colspan: "colSpan",
8580                 frameborder: "frameBorder",
8581                 rowspan: "rowSpan",
8582                 valuetype: "valueType"
8583         };
8584
8585         exports.get = function getProp(/*DOMNode|String*/ node, /*String*/ name){
8586                 // summary:
8587                 //              Gets a property on an HTML element.
8588                 // description:
8589                 //              Handles normalized getting of properties on DOM nodes.
8590                 //
8591                 // node: DOMNode|String
8592                 //              id or reference to the element to get the property on
8593                 // name: String
8594                 //              the name of the property to get.
8595                 // returns:
8596                 //              the value of the requested property or its default value
8597                 //
8598                 // example:
8599                 //      |       // get the current value of the "foo" property on a node
8600                 //      |       dojo.getProp(dojo.byId("nodeId"), "foo");
8601                 //      |       // or we can just pass the id:
8602                 //      |       dojo.getProp("nodeId", "foo");
8603
8604                 node = dom.byId(node);
8605                 var lc = name.toLowerCase(), propName = exports.names[lc] || name;
8606                 return node[propName];  // Anything
8607         };
8608
8609         exports.set = function setProp(/*DOMNode|String*/ node, /*String|Object*/ name, /*String?*/ value){
8610                 // summary:
8611                 //              Sets a property on an HTML element.
8612                 // description:
8613                 //              Handles normalized setting of properties on DOM nodes.
8614                 //
8615                 //              When passing functions as values, note that they will not be
8616                 //              directly assigned to slots on the node, but rather the default
8617                 //              behavior will be removed and the new behavior will be added
8618                 //              using `dojo.connect()`, meaning that event handler properties
8619                 //              will be normalized and that some caveats with regards to
8620                 //              non-standard behaviors for onsubmit apply. Namely that you
8621                 //              should cancel form submission using `dojo.stopEvent()` on the
8622                 //              passed event object instead of returning a boolean value from
8623                 //              the handler itself.
8624                 // node: DOMNode|String
8625                 //              id or reference to the element to set the property on
8626                 // name: String|Object
8627                 //              the name of the property to set, or a hash object to set
8628                 //              multiple properties at once.
8629                 // value: String?
8630                 //              The value to set for the property
8631                 // returns:
8632                 //              the DOM node
8633                 //
8634                 // example:
8635                 //      |       // use prop() to set the tab index
8636                 //      |       dojo.setProp("nodeId", "tabIndex", 3);
8637                 //      |
8638                 //
8639                 // example:
8640                 //      Set multiple values at once, including event handlers:
8641                 //      |       dojo.setProp("formId", {
8642                 //      |               "foo": "bar",
8643                 //      |               "tabIndex": -1,
8644                 //      |               "method": "POST",
8645                 //      |               "onsubmit": function(e){
8646                 //      |                       // stop submitting the form. Note that the IE behavior
8647                 //      |                       // of returning true or false will have no effect here
8648                 //      |                       // since our handler is connect()ed to the built-in
8649                 //      |                       // onsubmit behavior and so we need to use
8650                 //      |                       // dojo.stopEvent() to ensure that the submission
8651                 //      |                       // doesn't proceed.
8652                 //      |                       dojo.stopEvent(e);
8653                 //      |
8654                 //      |                       // submit the form with Ajax
8655                 //      |                       dojo.xhrPost({ form: "formId" });
8656                 //      |               }
8657                 //      |       });
8658                 //
8659                 // example:
8660                 //      Style is s special case: Only set with an object hash of styles
8661                 //      |       dojo.setProp("someNode",{
8662                 //      |               id:"bar",
8663                 //      |               style:{
8664                 //      |                       width:"200px", height:"100px", color:"#000"
8665                 //      |               }
8666                 //      |       });
8667                 //
8668                 // example:
8669                 //      Again, only set style as an object hash of styles:
8670                 //      |       var obj = { color:"#fff", backgroundColor:"#000" };
8671                 //      |       dojo.setProp("someNode", "style", obj);
8672                 //      |
8673                 //      |       // though shorter to use `dojo.style()` in this case:
8674                 //      |       dojo.style("someNode", obj);
8675
8676                 node = dom.byId(node);
8677                 var l = arguments.length;
8678                 if(l == 2 && typeof name != "string"){ // inline'd type check
8679                         // the object form of setter: the 2nd argument is a dictionary
8680                         for(var x in name){
8681                                 exports.set(node, x, name[x]);
8682                         }
8683                         return node; // DomNode
8684                 }
8685                 var lc = name.toLowerCase(), propName = exports.names[lc] || name;
8686                 if(propName == "style" && typeof value != "string"){ // inline'd type check
8687                         // special case: setting a style
8688                         style.set(node, value);
8689                         return node; // DomNode
8690                 }
8691                 if(propName == "innerHTML"){
8692                         // special case: assigning HTML
8693                         // the hash lists elements with read-only innerHTML on IE
8694                         if(has("ie") && node.tagName.toLowerCase() in {col: 1, colgroup: 1,
8695                                                 table: 1, tbody: 1, tfoot: 1, thead: 1, tr: 1, title: 1}){
8696                                 ctr.empty(node);
8697                                 node.appendChild(ctr.toDom(value, node.ownerDocument));
8698                         }else{
8699                                 node[propName] = value;
8700                         }
8701                         return node; // DomNode
8702                 }
8703                 if(lang.isFunction(value)){
8704                         // special case: assigning an event handler
8705                         // clobber if we can
8706                         var attrId = node[_attrId];
8707                         if(!attrId){
8708                                 attrId = _ctr++;
8709                                 node[_attrId] = attrId;
8710                         }
8711                         if(!_evtHdlrMap[attrId]){
8712                                 _evtHdlrMap[attrId] = {};
8713                         }
8714                         var h = _evtHdlrMap[attrId][propName];
8715                         if(h){
8716                                 //h.remove();
8717                                 conn.disconnect(h);
8718                         }else{
8719                                 try{
8720                                         delete node[propName];
8721                                 }catch(e){}
8722                         }
8723                         // ensure that event objects are normalized, etc.
8724                         if(value){
8725                                 //_evtHdlrMap[attrId][propName] = on(node, propName, value);
8726                                 _evtHdlrMap[attrId][propName] = conn.connect(node, propName, value);
8727                         }else{
8728                                 node[propName] = null;
8729                         }
8730                         return node; // DomNode
8731                 }
8732                 node[propName] = value;
8733                 return node;    // DomNode
8734         };
8735 });
8736
8737 },
8738 'dojo/when':function(){
8739 define([
8740         "./Deferred",
8741         "./promise/Promise"
8742 ], function(Deferred, Promise){
8743         "use strict";
8744
8745         // module:
8746         //              dojo/when
8747
8748         return function when(valueOrPromise, callback, errback, progback){
8749                 // summary:
8750                 //              Transparently applies callbacks to values and/or promises.
8751                 // description:
8752                 //              Accepts promises but also transparently handles non-promises. If no
8753                 //              callbacks are provided returns a promise, regardless of the initial
8754                 //              value. Foreign promises are converted.
8755                 //
8756                 //              If callbacks are provided and the initial value is not a promise,
8757                 //              the callback is executed immediately with no error handling. Returns
8758                 //              a promise if the initial value is a promise, or the result of the
8759                 //              callback otherwise.
8760                 // valueOrPromise:
8761                 //              Either a regular value or an object with a `then()` method that
8762                 //              follows the Promises/A specification.
8763                 // callback: Function?
8764                 //              Callback to be invoked when the promise is resolved, or a non-promise
8765                 //              is received.
8766                 // errback: Function?
8767                 //              Callback to be invoked when the promise is rejected.
8768                 // progback: Function?
8769                 //              Callback to be invoked when the promise emits a progress update.
8770                 // returns: dojo/promise/Promise
8771                 //              Promise, or if a callback is provided, the result of the callback.
8772
8773                 var receivedPromise = valueOrPromise && typeof valueOrPromise.then === "function";
8774                 var nativePromise = receivedPromise && valueOrPromise instanceof Promise;
8775
8776                 if(!receivedPromise){
8777                         if(callback){
8778                                 return callback(valueOrPromise);
8779                         }else{
8780                                 return new Deferred().resolve(valueOrPromise);
8781                         }
8782                 }else if(!nativePromise){
8783                         var deferred = new Deferred(valueOrPromise.cancel);
8784                         valueOrPromise.then(deferred.resolve, deferred.reject, deferred.progress);
8785                         valueOrPromise = deferred.promise;
8786                 }
8787
8788                 if(callback || errback || progback){
8789                         return valueOrPromise.then(callback, errback, progback);
8790                 }
8791                 return valueOrPromise;
8792         };
8793 });
8794
8795 },
8796 'dojo/dom-attr':function(){
8797 define(["exports", "./sniff", "./_base/lang", "./dom", "./dom-style", "./dom-prop"],
8798                 function(exports, has, lang, dom, style, prop){
8799         // module:
8800         //              dojo/dom-attr
8801         // summary:
8802         //              This module defines the core dojo DOM attributes API.
8803
8804         // TODOC: summary not showing up in output see https://github.com/csnover/js-doc-parse/issues/42
8805
8806         // =============================
8807         // Element attribute Functions
8808         // =============================
8809
8810         // This module will be obsolete soon. Use dojo/prop instead.
8811
8812         // dojo.attr() should conform to http://www.w3.org/TR/DOM-Level-2-Core/
8813
8814         // attribute-related functions (to be obsolete soon)
8815
8816         var forcePropNames = {
8817                         innerHTML:      1,
8818                         className:      1,
8819                         htmlFor:        has("ie"),
8820                         value:          1
8821                 },
8822                 attrNames = {
8823                         // original attribute names
8824                         classname: "class",
8825                         htmlfor: "for",
8826                         // for IE
8827                         tabindex: "tabIndex",
8828                         readonly: "readOnly"
8829                 };
8830
8831         function _hasAttr(node, name){
8832                 var attr = node.getAttributeNode && node.getAttributeNode(name);
8833                 return attr && attr.specified; // Boolean
8834         }
8835
8836         // There is a difference in the presence of certain properties and their default values
8837         // between browsers. For example, on IE "disabled" is present on all elements,
8838         // but it is value is "false"; "tabIndex" of <div> returns 0 by default on IE, yet other browsers
8839         // can return -1.
8840
8841         exports.has = function hasAttr(/*DOMNode|String*/ node, /*String*/ name){
8842                 // summary:
8843                 //              Returns true if the requested attribute is specified on the
8844                 //              given element, and false otherwise.
8845                 // node: DOMNode|String
8846                 //              id or reference to the element to check
8847                 // name: String
8848                 //              the name of the attribute
8849                 // returns: Boolean
8850                 //              true if the requested attribute is specified on the
8851                 //              given element, and false otherwise
8852
8853                 var lc = name.toLowerCase();
8854                 return forcePropNames[prop.names[lc] || name] || _hasAttr(dom.byId(node), attrNames[lc] || name);       // Boolean
8855         };
8856
8857         exports.get = function getAttr(/*DOMNode|String*/ node, /*String*/ name){
8858                 // summary:
8859                 //              Gets an attribute on an HTML element.
8860                 // description:
8861                 //              Handles normalized getting of attributes on DOM Nodes.
8862                 // node: DOMNode|String
8863                 //              id or reference to the element to get the attribute on
8864                 // name: String
8865                 //              the name of the attribute to get.
8866                 // returns:
8867                 //              the value of the requested attribute or null if that attribute does not have a specified or
8868                 //              default value;
8869                 //
8870                 // example:
8871                 //      |       // get the current value of the "foo" attribute on a node
8872                 //      |       dojo.getAttr(dojo.byId("nodeId"), "foo");
8873                 //      |       // or we can just pass the id:
8874                 //      |       dojo.getAttr("nodeId", "foo");
8875
8876                 node = dom.byId(node);
8877                 var lc = name.toLowerCase(),
8878                         propName = prop.names[lc] || name,
8879                         forceProp = forcePropNames[propName],
8880                         value = node[propName];         // should we access this attribute via a property or via getAttribute()?
8881
8882                 if(forceProp && typeof value != "undefined"){
8883                         // node's property
8884                         return value;   // Anything
8885                 }
8886                 if(propName != "href" && (typeof value == "boolean" || lang.isFunction(value))){
8887                         // node's property
8888                         return value;   // Anything
8889                 }
8890                 // node's attribute
8891                 // we need _hasAttr() here to guard against IE returning a default value
8892                 var attrName = attrNames[lc] || name;
8893                 return _hasAttr(node, attrName) ? node.getAttribute(attrName) : null; // Anything
8894         };
8895
8896         exports.set = function setAttr(/*DOMNode|String*/ node, /*String|Object*/ name, /*String?*/ value){
8897                 // summary:
8898                 //              Sets an attribute on an HTML element.
8899                 // description:
8900                 //              Handles normalized setting of attributes on DOM Nodes.
8901                 //
8902                 //              When passing functions as values, note that they will not be
8903                 //              directly assigned to slots on the node, but rather the default
8904                 //              behavior will be removed and the new behavior will be added
8905                 //              using `dojo.connect()`, meaning that event handler properties
8906                 //              will be normalized and that some caveats with regards to
8907                 //              non-standard behaviors for onsubmit apply. Namely that you
8908                 //              should cancel form submission using `dojo.stopEvent()` on the
8909                 //              passed event object instead of returning a boolean value from
8910                 //              the handler itself.
8911                 // node: DOMNode|String
8912                 //              id or reference to the element to set the attribute on
8913                 // name: String|Object
8914                 //              the name of the attribute to set, or a hash of key-value pairs to set.
8915                 // value: String?
8916                 //              the value to set for the attribute, if the name is a string.
8917                 // returns:
8918                 //              the DOM node
8919                 //
8920                 // example:
8921                 //      |       // use attr() to set the tab index
8922                 //      |       dojo.setAttr("nodeId", "tabIndex", 3);
8923                 //
8924                 // example:
8925                 //      Set multiple values at once, including event handlers:
8926                 //      |       dojo.setAttr("formId", {
8927                 //      |               "foo": "bar",
8928                 //      |               "tabIndex": -1,
8929                 //      |               "method": "POST",
8930                 //      |               "onsubmit": function(e){
8931                 //      |                       // stop submitting the form. Note that the IE behavior
8932                 //      |                       // of returning true or false will have no effect here
8933                 //      |                       // since our handler is connect()ed to the built-in
8934                 //      |                       // onsubmit behavior and so we need to use
8935                 //      |                       // dojo.stopEvent() to ensure that the submission
8936                 //      |                       // doesn't proceed.
8937                 //      |                       dojo.stopEvent(e);
8938                 //      |
8939                 //      |                       // submit the form with Ajax
8940                 //      |                       dojo.xhrPost({ form: "formId" });
8941                 //      |               }
8942                 //      |       });
8943                 //
8944                 // example:
8945                 //      Style is s special case: Only set with an object hash of styles
8946                 //      |       dojo.setAttr("someNode",{
8947                 //      |               id:"bar",
8948                 //      |               style:{
8949                 //      |                       width:"200px", height:"100px", color:"#000"
8950                 //      |               }
8951                 //      |       });
8952                 //
8953                 // example:
8954                 //      Again, only set style as an object hash of styles:
8955                 //      |       var obj = { color:"#fff", backgroundColor:"#000" };
8956                 //      |       dojo.setAttr("someNode", "style", obj);
8957                 //      |
8958                 //      |       // though shorter to use `dojo.style()` in this case:
8959                 //      |       dojo.setStyle("someNode", obj);
8960
8961                 node = dom.byId(node);
8962                 if(arguments.length == 2){ // inline'd type check
8963                         // the object form of setter: the 2nd argument is a dictionary
8964                         for(var x in name){
8965                                 exports.set(node, x, name[x]);
8966                         }
8967                         return node; // DomNode
8968                 }
8969                 var lc = name.toLowerCase(),
8970                         propName = prop.names[lc] || name,
8971                         forceProp = forcePropNames[propName];
8972                 if(propName == "style" && typeof value != "string"){ // inline'd type check
8973                         // special case: setting a style
8974                         style.set(node, value);
8975                         return node; // DomNode
8976                 }
8977                 if(forceProp || typeof value == "boolean" || lang.isFunction(value)){
8978                         return prop.set(node, name, value);
8979                 }
8980                 // node's attribute
8981                 node.setAttribute(attrNames[lc] || name, value);
8982                 return node; // DomNode
8983         };
8984
8985         exports.remove = function removeAttr(/*DOMNode|String*/ node, /*String*/ name){
8986                 // summary:
8987                 //              Removes an attribute from an HTML element.
8988                 // node: DOMNode|String
8989                 //              id or reference to the element to remove the attribute from
8990                 // name: String
8991                 //              the name of the attribute to remove
8992
8993                 dom.byId(node).removeAttribute(attrNames[name.toLowerCase()] || name);
8994         };
8995
8996         exports.getNodeProp = function getNodeProp(/*DomNode|String*/ node, /*String*/ name){
8997                 // summary:
8998                 //              Returns an effective value of a property or an attribute.
8999                 // node: DOMNode|String
9000                 //              id or reference to the element to remove the attribute from
9001                 // name: String
9002                 //              the name of the attribute
9003                 // returns:
9004                 //              the value of the attribute
9005
9006                 node = dom.byId(node);
9007                 var lc = name.toLowerCase(), propName = prop.names[lc] || name;
9008                 if((propName in node) && propName != "href"){
9009                         // node's property
9010                         return node[propName];  // Anything
9011                 }
9012                 // node's attribute
9013                 var attrName = attrNames[lc] || name;
9014                 return _hasAttr(node, attrName) ? node.getAttribute(attrName) : null; // Anything
9015         };
9016 });
9017
9018 },
9019 'dojo/dom-construct':function(){
9020 define(["exports", "./_base/kernel", "./sniff", "./_base/window", "./dom", "./dom-attr", "./on"],
9021                 function(exports, dojo, has, win, dom, attr, on){
9022         // module:
9023         //              dojo/dom-construct
9024         // summary:
9025         //              This module defines the core dojo DOM construction API.
9026
9027         // TODOC: summary not showing up in output, see https://github.com/csnover/js-doc-parse/issues/42
9028
9029         // support stuff for toDom()
9030         var tagWrap = {
9031                         option: ["select"],
9032                         tbody: ["table"],
9033                         thead: ["table"],
9034                         tfoot: ["table"],
9035                         tr: ["table", "tbody"],
9036                         td: ["table", "tbody", "tr"],
9037                         th: ["table", "thead", "tr"],
9038                         legend: ["fieldset"],
9039                         caption: ["table"],
9040                         colgroup: ["table"],
9041                         col: ["table", "colgroup"],
9042                         li: ["ul"]
9043                 },
9044                 reTag = /<\s*([\w\:]+)/,
9045                 masterNode = {}, masterNum = 0,
9046                 masterName = "__" + dojo._scopeName + "ToDomId";
9047
9048         // generate start/end tag strings to use
9049         // for the injection for each special tag wrap case.
9050         for(var param in tagWrap){
9051                 if(tagWrap.hasOwnProperty(param)){
9052                         var tw = tagWrap[param];
9053                         tw.pre = param == "option" ? '<select multiple="multiple">' : "<" + tw.join("><") + ">";
9054                         tw.post = "</" + tw.reverse().join("></") + ">";
9055                         // the last line is destructive: it reverses the array,
9056                         // but we don't care at this point
9057                 }
9058         }
9059
9060         function _insertBefore(/*DomNode*/ node, /*DomNode*/ ref){
9061                 var parent = ref.parentNode;
9062                 if(parent){
9063                         parent.insertBefore(node, ref);
9064                 }
9065         }
9066
9067         function _insertAfter(/*DomNode*/ node, /*DomNode*/ ref){
9068                 // summary:
9069                 //              Try to insert node after ref
9070                 var parent = ref.parentNode;
9071                 if(parent){
9072                         if(parent.lastChild == ref){
9073                                 parent.appendChild(node);
9074                         }else{
9075                                 parent.insertBefore(node, ref.nextSibling);
9076                         }
9077                 }
9078         }
9079
9080         exports.toDom = function toDom(frag, doc){
9081                 // summary:
9082                 //              instantiates an HTML fragment returning the corresponding DOM.
9083                 // frag: String
9084                 //              the HTML fragment
9085                 // doc: DocumentNode?
9086                 //              optional document to use when creating DOM nodes, defaults to
9087                 //              dojo.doc if not specified.
9088                 // returns:
9089                 //              Document fragment, unless it's a single node in which case it returns the node itself
9090                 // example:
9091                 //              Create a table row:
9092                 //      |       var tr = dojo.toDom("<tr><td>First!</td></tr>");
9093
9094                 doc = doc || win.doc;
9095                 var masterId = doc[masterName];
9096                 if(!masterId){
9097                         doc[masterName] = masterId = ++masterNum + "";
9098                         masterNode[masterId] = doc.createElement("div");
9099                 }
9100
9101                 // make sure the frag is a string.
9102                 frag += "";
9103
9104                 // find the starting tag, and get node wrapper
9105                 var match = frag.match(reTag),
9106                         tag = match ? match[1].toLowerCase() : "",
9107                         master = masterNode[masterId],
9108                         wrap, i, fc, df;
9109                 if(match && tagWrap[tag]){
9110                         wrap = tagWrap[tag];
9111                         master.innerHTML = wrap.pre + frag + wrap.post;
9112                         for(i = wrap.length; i; --i){
9113                                 master = master.firstChild;
9114                         }
9115                 }else{
9116                         master.innerHTML = frag;
9117                 }
9118
9119                 // one node shortcut => return the node itself
9120                 if(master.childNodes.length == 1){
9121                         return master.removeChild(master.firstChild); // DOMNode
9122                 }
9123
9124                 // return multiple nodes as a document fragment
9125                 df = doc.createDocumentFragment();
9126                 while((fc = master.firstChild)){ // intentional assignment
9127                         df.appendChild(fc);
9128                 }
9129                 return df; // DocumentFragment
9130         };
9131
9132         exports.place = function place(/*DOMNode|String*/ node, /*DOMNode|String*/ refNode, /*String|Number?*/ position){
9133                 // summary:
9134                 //              Attempt to insert node into the DOM, choosing from various positioning options.
9135                 //              Returns the first argument resolved to a DOM node.
9136                 // node: DOMNode|String
9137                 //              id or node reference, or HTML fragment starting with "<" to place relative to refNode
9138                 // refNode: DOMNode|String
9139                 //              id or node reference to use as basis for placement
9140                 // position: String|Number?
9141                 //              string noting the position of node relative to refNode or a
9142                 //              number indicating the location in the childNodes collection of refNode.
9143                 //              Accepted string values are:
9144                 //
9145                 //              - before
9146                 //              - after
9147                 //              - replace
9148                 //              - only
9149                 //              - first
9150                 //              - last
9151                 //
9152                 //              "first" and "last" indicate positions as children of refNode, "replace" replaces refNode,
9153                 //              "only" replaces all children.  position defaults to "last" if not specified
9154                 // returns: DOMNode
9155                 //              Returned values is the first argument resolved to a DOM node.
9156                 //
9157                 //              .place() is also a method of `dojo/NodeList`, allowing `dojo.query` node lookups.
9158                 // example:
9159                 //              Place a node by string id as the last child of another node by string id:
9160                 //      |       dojo.place("someNode", "anotherNode");
9161                 // example:
9162                 //              Place a node by string id before another node by string id
9163                 //      |       dojo.place("someNode", "anotherNode", "before");
9164                 // example:
9165                 //              Create a Node, and place it in the body element (last child):
9166                 //      |       dojo.place("<div></div>", dojo.body());
9167                 // example:
9168                 //              Put a new LI as the first child of a list by id:
9169                 //      |       dojo.place("<li></li>", "someUl", "first");
9170
9171                 refNode = dom.byId(refNode);
9172                 if(typeof node == "string"){ // inline'd type check
9173                         node = /^\s*</.test(node) ? exports.toDom(node, refNode.ownerDocument) : dom.byId(node);
9174                 }
9175                 if(typeof position == "number"){ // inline'd type check
9176                         var cn = refNode.childNodes;
9177                         if(!cn.length || cn.length <= position){
9178                                 refNode.appendChild(node);
9179                         }else{
9180                                 _insertBefore(node, cn[position < 0 ? 0 : position]);
9181                         }
9182                 }else{
9183                         switch(position){
9184                                 case "before":
9185                                         _insertBefore(node, refNode);
9186                                         break;
9187                                 case "after":
9188                                         _insertAfter(node, refNode);
9189                                         break;
9190                                 case "replace":
9191                                         refNode.parentNode.replaceChild(node, refNode);
9192                                         break;
9193                                 case "only":
9194                                         exports.empty(refNode);
9195                                         refNode.appendChild(node);
9196                                         break;
9197                                 case "first":
9198                                         if(refNode.firstChild){
9199                                                 _insertBefore(node, refNode.firstChild);
9200                                                 break;
9201                                         }
9202                                         // else fallthrough...
9203                                 default: // aka: last
9204                                         refNode.appendChild(node);
9205                         }
9206                 }
9207                 return node; // DomNode
9208         };
9209
9210         exports.create = function create(/*DOMNode|String*/ tag, /*Object*/ attrs, /*DOMNode|String?*/ refNode, /*String?*/ pos){
9211                 // summary:
9212                 //              Create an element, allowing for optional attribute decoration
9213                 //              and placement.
9214                 // description:
9215                 //              A DOM Element creation function. A shorthand method for creating a node or
9216                 //              a fragment, and allowing for a convenient optional attribute setting step,
9217                 //              as well as an optional DOM placement reference.
9218                 //
9219                 //              Attributes are set by passing the optional object through `dojo.setAttr`.
9220                 //              See `dojo.setAttr` for noted caveats and nuances, and API if applicable.
9221                 //
9222                 //              Placement is done via `dojo.place`, assuming the new node to be the action
9223                 //              node, passing along the optional reference node and position.
9224                 // tag: DOMNode|String
9225                 //              A string of the element to create (eg: "div", "a", "p", "li", "script", "br"),
9226                 //              or an existing DOM node to process.
9227                 // attrs: Object
9228                 //              An object-hash of attributes to set on the newly created node.
9229                 //              Can be null, if you don't want to set any attributes/styles.
9230                 //              See: `dojo.setAttr` for a description of available attributes.
9231                 // refNode: DOMNode|String?
9232                 //              Optional reference node. Used by `dojo.place` to place the newly created
9233                 //              node somewhere in the dom relative to refNode. Can be a DomNode reference
9234                 //              or String ID of a node.
9235                 // pos: String?
9236                 //              Optional positional reference. Defaults to "last" by way of `dojo.place`,
9237                 //              though can be set to "first","after","before","last", "replace" or "only"
9238                 //              to further control the placement of the new node relative to the refNode.
9239                 //              'refNode' is required if a 'pos' is specified.
9240                 // example:
9241                 //              Create a DIV:
9242                 //      |       var n = dojo.create("div");
9243                 //
9244                 // example:
9245                 //              Create a DIV with content:
9246                 //      |       var n = dojo.create("div", { innerHTML:"<p>hi</p>" });
9247                 //
9248                 // example:
9249                 //              Place a new DIV in the BODY, with no attributes set
9250                 //      |       var n = dojo.create("div", null, dojo.body());
9251                 //
9252                 // example:
9253                 //              Create an UL, and populate it with LI's. Place the list as the first-child of a
9254                 //              node with id="someId":
9255                 //      |       var ul = dojo.create("ul", null, "someId", "first");
9256                 //      |       var items = ["one", "two", "three", "four"];
9257                 //      |       dojo.forEach(items, function(data){
9258                 //      |               dojo.create("li", { innerHTML: data }, ul);
9259                 //      |       });
9260                 //
9261                 // example:
9262                 //              Create an anchor, with an href. Place in BODY:
9263                 //      |       dojo.create("a", { href:"foo.html", title:"Goto FOO!" }, dojo.body());
9264                 //
9265                 // example:
9266                 //              Create a `dojo/NodeList()` from a new element (for syntactic sugar):
9267                 //      |       dojo.query(dojo.create('div'))
9268                 //      |               .addClass("newDiv")
9269                 //      |               .onclick(function(e){ console.log('clicked', e.target) })
9270                 //      |               .place("#someNode"); // redundant, but cleaner.
9271
9272                 var doc = win.doc;
9273                 if(refNode){
9274                         refNode = dom.byId(refNode);
9275                         doc = refNode.ownerDocument;
9276                 }
9277                 if(typeof tag == "string"){ // inline'd type check
9278                         tag = doc.createElement(tag);
9279                 }
9280                 if(attrs){ attr.set(tag, attrs); }
9281                 if(refNode){ exports.place(tag, refNode, pos); }
9282                 return tag; // DomNode
9283         };
9284
9285         var _empty = has("ie") ?
9286                 function(/*DomNode*/ node){
9287                         try{
9288                                 node.innerHTML = ""; // really fast when it works
9289                         }catch(e){ // IE can generate Unknown Error
9290                                 for(var c; c = node.lastChild;){ // intentional assignment
9291                                         _destroy(c, node); // destroy is better than removeChild so TABLE elements are removed in proper order
9292                                 }
9293                         }
9294                 } :
9295                 function(/*DomNode*/ node){
9296                         node.innerHTML = "";
9297                 };
9298
9299         exports.empty = function empty(/*DOMNode|String*/ node){
9300                  // summary:
9301                  //             safely removes all children of the node.
9302                  // node: DOMNode|String
9303                  //             a reference to a DOM node or an id.
9304                  // example:
9305                  //             Destroy node's children byId:
9306                  //     |       dojo.empty("someId");
9307                  //
9308                  // example:
9309                  //             Destroy all nodes' children in a list by reference:
9310                  //     |       dojo.query(".someNode").forEach(dojo.empty);
9311
9312                 _empty(dom.byId(node));
9313         };
9314
9315
9316         function _destroy(/*DomNode*/ node, /*DomNode*/ parent){
9317                 if(node.firstChild){
9318                         _empty(node);
9319                 }
9320                 if(parent){
9321                         parent.removeChild(node);
9322                 }
9323         }
9324         exports.destroy = function destroy(/*DOMNode|String*/ node){
9325                 // summary:
9326                 //              Removes a node from its parent, clobbering it and all of its
9327                 //              children.
9328                 //
9329                 // description:
9330                 //              Removes a node from its parent, clobbering it and all of its
9331                 //              children. Function only works with DomNodes, and returns nothing.
9332                 //
9333                 // node: DOMNode|String
9334                 //              A String ID or DomNode reference of the element to be destroyed
9335                 //
9336                 // example:
9337                 //              Destroy a node byId:
9338                 //      |       dojo.destroy("someId");
9339                 //
9340                 // example:
9341                 //              Destroy all nodes in a list by reference:
9342                 //      |       dojo.query(".someNode").forEach(dojo.destroy);
9343
9344                 node = dom.byId(node);
9345                 if(!node){ return; }
9346                 _destroy(node, node.parentNode);
9347         };
9348 });
9349
9350 },
9351 'dojo/request/xhr':function(){
9352 define("dojo/request/xhr", [
9353         '../errors/RequestError',
9354         './watch',
9355         './handlers',
9356         './util',
9357         '../has'/*=====,
9358         '../request',
9359         '../_base/declare' =====*/
9360 ], function(RequestError, watch, handlers, util, has/*=====, request, declare =====*/){
9361         has.add('native-xhr', function(){
9362                 // if true, the environment has a native XHR implementation
9363                 return typeof XMLHttpRequest !== 'undefined';
9364         });
9365         has.add('dojo-force-activex-xhr', function(){
9366                 return has('activex') && !document.addEventListener && window.location.protocol === 'file:';
9367         });
9368
9369         has.add('native-xhr2', function(){
9370                 if(!has('native-xhr')){ return; }
9371                 var x = new XMLHttpRequest();
9372                 return typeof x['addEventListener'] !== 'undefined' &&
9373                         (typeof opera === 'undefined' || typeof x['upload'] !== 'undefined');
9374         });
9375
9376         has.add('native-formdata', function(){
9377                 // if true, the environment has a native FormData implementation
9378                 return typeof FormData === 'function';
9379         });
9380
9381         function handleResponse(response, error){
9382                 var _xhr = response.xhr;
9383                 response.status = response.xhr.status;
9384                 response.text = _xhr.responseText;
9385
9386                 if(response.options.handleAs === 'xml'){
9387                         response.data = _xhr.responseXML;
9388                 }
9389
9390                 if(!error){
9391                         try{
9392                                 handlers(response);
9393                         }catch(e){
9394                                 error = e;
9395                         }
9396                 }
9397
9398                 if(error){
9399                         this.reject(error);
9400                 }else if(util.checkStatus(_xhr.status)){
9401                         this.resolve(response);
9402                 }else{
9403                         error = new RequestError('Unable to load ' + response.url + ' status: ' + _xhr.status, response);
9404
9405                         this.reject(error);
9406                 }
9407         }
9408
9409         var isValid, isReady, addListeners, cancel;
9410         if(has('native-xhr2')){
9411                 // Any platform with XHR2 will only use the watch mechanism for timeout.
9412
9413                 isValid = function(response){
9414                         // summary:
9415                         //              Check to see if the request should be taken out of the watch queue
9416                         return !this.isFulfilled();
9417                 };
9418                 cancel = function(dfd, response){
9419                         // summary:
9420                         //              Canceler for deferred
9421                         response.xhr.abort();
9422                 };
9423                 addListeners = function(_xhr, dfd, response){
9424                         // summary:
9425                         //              Adds event listeners to the XMLHttpRequest object
9426                         function onLoad(evt){
9427                                 dfd.handleResponse(response);
9428                         }
9429                         function onError(evt){
9430                                 var _xhr = evt.target;
9431                                 var error = new RequestError('Unable to load ' + response.url + ' status: ' + _xhr.status, response); 
9432                                 dfd.handleResponse(response, error);
9433                         }
9434
9435                         function onProgress(evt){
9436                                 if(evt.lengthComputable){
9437                                         response.loaded = evt.loaded;
9438                                         response.total = evt.total;
9439                                         dfd.progress(response);
9440                                 }
9441                         }
9442
9443                         _xhr.addEventListener('load', onLoad, false);
9444                         _xhr.addEventListener('error', onError, false);
9445                         _xhr.addEventListener('progress', onProgress, false);
9446
9447                         return function(){
9448                                 _xhr.removeEventListener('load', onLoad, false);
9449                                 _xhr.removeEventListener('error', onError, false);
9450                                 _xhr.removeEventListener('progress', onProgress, false);
9451                         };
9452                 };
9453         }else{
9454                 isValid = function(response){
9455                         return response.xhr.readyState; //boolean
9456                 };
9457                 isReady = function(response){
9458                         return 4 === response.xhr.readyState; //boolean
9459                 };
9460                 cancel = function(dfd, response){
9461                         // summary:
9462                         //              canceller function for util.deferred call.
9463                         var xhr = response.xhr;
9464                         var _at = typeof xhr.abort;
9465                         if(_at === 'function' || _at === 'object' || _at === 'unknown'){
9466                                 xhr.abort();
9467                         }
9468                 };
9469         }
9470
9471         var undefined,
9472                 defaultOptions = {
9473                         data: null,
9474                         query: null,
9475                         sync: false,
9476                         method: 'GET',
9477                         headers: {
9478                                 'Content-Type': 'application/x-www-form-urlencoded'
9479                         }
9480                 };
9481         function xhr(url, options, returnDeferred){
9482                 var response = util.parseArgs(
9483                         url,
9484                         util.deepCreate(defaultOptions, options),
9485                         has('native-formdata') && options && options.data && options.data instanceof FormData
9486                 );
9487                 url = response.url;
9488                 options = response.options;
9489
9490                 var remover,
9491                         last = function(){
9492                                 remover && remover();
9493                         };
9494
9495                 //Make the Deferred object for this xhr request.
9496                 var dfd = util.deferred(
9497                         response,
9498                         cancel,
9499                         isValid,
9500                         isReady,
9501                         handleResponse,
9502                         last
9503                 );
9504                 var _xhr = response.xhr = xhr._create();
9505
9506                 if(!_xhr){
9507                         // If XHR factory somehow returns nothings,
9508                         // cancel the deferred.
9509                         dfd.cancel(new RequestError('XHR was not created'));
9510                         return returnDeferred ? dfd : dfd.promise;
9511                 }
9512
9513                 response.getHeader = function(headerName){
9514                         return this.xhr.getResponseHeader(headerName);
9515                 };
9516
9517                 if(addListeners){
9518                         remover = addListeners(_xhr, dfd, response);
9519                 }
9520
9521                 var data = options.data,
9522                         async = !options.sync,
9523                         method = options.method;
9524
9525                 try{
9526                         // IE6 won't let you call apply() on the native function.
9527                         _xhr.open(method, url, async, options.user || undefined, options.password || undefined);
9528
9529                         if(options.withCredentials){
9530                                 _xhr.withCredentials = options.withCredentials;
9531                         }
9532
9533                         var headers = options.headers,
9534                                 contentType;
9535                         if(headers){
9536                                 for(var hdr in headers){
9537                                         if(hdr.toLowerCase() === 'content-type'){
9538                                                 contentType = headers[hdr];
9539                                         }else if(headers[hdr]){
9540                                                 //Only add header if it has a value. This allows for instance, skipping
9541                                                 //insertion of X-Requested-With by specifying empty value.
9542                                                 _xhr.setRequestHeader(hdr, headers[hdr]);
9543                                         }
9544                                 }
9545                         }
9546
9547                         if(contentType && contentType !== false){
9548                                 _xhr.setRequestHeader('Content-Type', contentType);
9549                         }
9550                         if(!headers || !('X-Requested-With' in headers)){
9551                                 _xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
9552                         }
9553
9554                         if(util.notify){
9555                                 util.notify.emit('send', response, dfd.promise.cancel);
9556                         }
9557                         _xhr.send(data);
9558                 }catch(e){
9559                         dfd.reject(e);
9560                 }
9561
9562                 watch(dfd);
9563                 _xhr = null;
9564
9565                 return returnDeferred ? dfd : dfd.promise;
9566         }
9567
9568         /*=====
9569         xhr = function(url, options){
9570                 // summary:
9571                 //              Sends a request using XMLHttpRequest with the given URL and options.
9572                 // url: String
9573                 //              URL to request
9574                 // options: dojo/request/xhr.__Options?
9575                 //              Options for the request.
9576                 // returns: dojo/request.__Promise
9577         };
9578         xhr.__BaseOptions = declare(request.__BaseOptions, {
9579                 // sync: Boolean?
9580                 //              Whether to make a synchronous request or not. Default
9581                 //              is `false` (asynchronous).
9582                 // data: String|Object|FormData?
9583                 //              Data to transfer. This is ignored for GET and DELETE
9584                 //              requests.
9585                 // headers: Object?
9586                 //              Headers to use for the request.
9587                 // user: String?
9588                 //              Username to use during the request.
9589                 // password: String?
9590                 //              Password to use during the request.
9591                 // withCredentials: Boolean?
9592                 //              For cross-site requests, whether to send credentials
9593                 //              or not.
9594         });
9595         xhr.__MethodOptions = declare(null, {
9596                 // method: String?
9597                 //              The HTTP method to use to make the request. Must be
9598                 //              uppercase. Default is `"GET"`.
9599         });
9600         xhr.__Options = declare([xhr.__BaseOptions, xhr.__MethodOptions]);
9601
9602         xhr.get = function(url, options){
9603                 // summary:
9604                 //              Send an HTTP GET request using XMLHttpRequest with the given URL and options.
9605                 // url: String
9606                 //              URL to request
9607                 // options: dojo/request/xhr.__BaseOptions?
9608                 //              Options for the request.
9609                 // returns: dojo/request.__Promise
9610         };
9611         xhr.post = function(url, options){
9612                 // summary:
9613                 //              Send an HTTP POST request using XMLHttpRequest with the given URL and options.
9614                 // url: String
9615                 //              URL to request
9616                 // options: dojo/request/xhr.__BaseOptions?
9617                 //              Options for the request.
9618                 // returns: dojo/request.__Promise
9619         };
9620         xhr.put = function(url, options){
9621                 // summary:
9622                 //              Send an HTTP PUT request using XMLHttpRequest with the given URL and options.
9623                 // url: String
9624                 //              URL to request
9625                 // options: dojo/request/xhr.__BaseOptions?
9626                 //              Options for the request.
9627                 // returns: dojo/request.__Promise
9628         };
9629         xhr.del = function(url, options){
9630                 // summary:
9631                 //              Send an HTTP DELETE request using XMLHttpRequest with the given URL and options.
9632                 // url: String
9633                 //              URL to request
9634                 // options: dojo/request/xhr.__BaseOptions?
9635                 //              Options for the request.
9636                 // returns: dojo/request.__Promise
9637         };
9638         =====*/
9639         xhr._create = function(){
9640                 // summary:
9641                 //              does the work of portably generating a new XMLHTTPRequest object.
9642                 throw new Error('XMLHTTP not available');
9643         };
9644         if(has('native-xhr') && !has('dojo-force-activex-xhr')){
9645                 xhr._create = function(){
9646                         return new XMLHttpRequest();
9647                 };
9648         }else if(has('activex')){
9649                 try{
9650                         new ActiveXObject('Msxml2.XMLHTTP');
9651                         xhr._create = function(){
9652                                 return new ActiveXObject('Msxml2.XMLHTTP');
9653                         };
9654                 }catch(e){
9655                         try{
9656                                 new ActiveXObject('Microsoft.XMLHTTP');
9657                                 xhr._create = function(){
9658                                         return new ActiveXObject('Microsoft.XMLHTTP');
9659                                 };
9660                         }catch(e){}
9661                 }
9662         }
9663
9664         util.addCommonMethods(xhr);
9665
9666         return xhr;
9667 });
9668
9669 },
9670 'dojo/keys':function(){
9671 define("dojo/keys", ["./_base/kernel", "./sniff"], function(dojo, has){
9672
9673         // module:
9674         //              dojo/keys
9675
9676         return dojo.keys = {
9677                 // summary:
9678                 //              Definitions for common key values.  Client code should test keyCode against these named constants,
9679                 //              as the actual codes can vary by browser.
9680
9681                 BACKSPACE: 8,
9682                 TAB: 9,
9683                 CLEAR: 12,
9684                 ENTER: 13,
9685                 SHIFT: 16,
9686                 CTRL: 17,
9687                 ALT: 18,
9688                 META: has("webkit") ? 91 : 224,         // the apple key on macs
9689                 PAUSE: 19,
9690                 CAPS_LOCK: 20,
9691                 ESCAPE: 27,
9692                 SPACE: 32,
9693                 PAGE_UP: 33,
9694                 PAGE_DOWN: 34,
9695                 END: 35,
9696                 HOME: 36,
9697                 LEFT_ARROW: 37,
9698                 UP_ARROW: 38,
9699                 RIGHT_ARROW: 39,
9700                 DOWN_ARROW: 40,
9701                 INSERT: 45,
9702                 DELETE: 46,
9703                 HELP: 47,
9704                 LEFT_WINDOW: 91,
9705                 RIGHT_WINDOW: 92,
9706                 SELECT: 93,
9707                 NUMPAD_0: 96,
9708                 NUMPAD_1: 97,
9709                 NUMPAD_2: 98,
9710                 NUMPAD_3: 99,
9711                 NUMPAD_4: 100,
9712                 NUMPAD_5: 101,
9713                 NUMPAD_6: 102,
9714                 NUMPAD_7: 103,
9715                 NUMPAD_8: 104,
9716                 NUMPAD_9: 105,
9717                 NUMPAD_MULTIPLY: 106,
9718                 NUMPAD_PLUS: 107,
9719                 NUMPAD_ENTER: 108,
9720                 NUMPAD_MINUS: 109,
9721                 NUMPAD_PERIOD: 110,
9722                 NUMPAD_DIVIDE: 111,
9723                 F1: 112,
9724                 F2: 113,
9725                 F3: 114,
9726                 F4: 115,
9727                 F5: 116,
9728                 F6: 117,
9729                 F7: 118,
9730                 F8: 119,
9731                 F9: 120,
9732                 F10: 121,
9733                 F11: 122,
9734                 F12: 123,
9735                 F13: 124,
9736                 F14: 125,
9737                 F15: 126,
9738                 NUM_LOCK: 144,
9739                 SCROLL_LOCK: 145,
9740                 UP_DPAD: 175,
9741                 DOWN_DPAD: 176,
9742                 LEFT_DPAD: 177,
9743                 RIGHT_DPAD: 178,
9744                 // virtual key mapping
9745                 copyKey: has("mac") && !has("air") ? (has("safari") ? 91 : 224 ) : 17
9746         };
9747 });
9748
9749 },
9750 'dojo/domReady':function(){
9751 define(['./has'], function(has){
9752         var global = this,
9753                 doc = document,
9754                 readyStates = { 'loaded': 1, 'complete': 1 },
9755                 fixReadyState = typeof doc.readyState != "string",
9756                 ready = !!readyStates[doc.readyState];
9757
9758         // For FF <= 3.5
9759         if(fixReadyState){ doc.readyState = "loading"; }
9760
9761         if(!ready){
9762                 var readyQ = [], tests = [],
9763                         detectReady = function(evt){
9764                                 evt = evt || global.event;
9765                                 if(ready || (evt.type == "readystatechange" && !readyStates[doc.readyState])){ return; }
9766                                 ready = 1;
9767
9768                                 // For FF <= 3.5
9769                                 if(fixReadyState){ doc.readyState = "complete"; }
9770
9771                                 while(readyQ.length){
9772                                         (readyQ.shift())(doc);
9773                                 }
9774                         },
9775                         on = function(node, event){
9776                                 node.addEventListener(event, detectReady, false);
9777                                 readyQ.push(function(){ node.removeEventListener(event, detectReady, false); });
9778                         };
9779
9780                 if(!has("dom-addeventlistener")){
9781                         on = function(node, event){
9782                                 event = "on" + event;
9783                                 node.attachEvent(event, detectReady);
9784                                 readyQ.push(function(){ node.detachEvent(event, detectReady); });
9785                         };
9786
9787                         var div = doc.createElement("div");
9788                         try{
9789                                 if(div.doScroll && global.frameElement === null){
9790                                         // the doScroll test is only useful if we're in the top-most frame
9791                                         tests.push(function(){
9792                                                 // Derived with permission from Diego Perini's IEContentLoaded
9793                                                 // http://javascript.nwbox.com/IEContentLoaded/
9794                                                 try{
9795                                                         div.doScroll("left");
9796                                                         return 1;
9797                                                 }catch(e){}
9798                                         });
9799                                 }
9800                         }catch(e){}
9801                 }
9802
9803                 on(doc, "DOMContentLoaded");
9804                 on(global, "load");
9805
9806                 if("onreadystatechange" in doc){
9807                         on(doc, "readystatechange");
9808                 }else if(!fixReadyState){
9809                         // if the ready state property exists and there's
9810                         // no readystatechange event, poll for the state
9811                         // to change
9812                         tests.push(function(){
9813                                 return readyStates[doc.readyState];
9814                         });
9815                 }
9816
9817                 if(tests.length){
9818                         var poller = function(){
9819                                 if(ready){ return; }
9820                                 var i = tests.length;
9821                                 while(i--){
9822                                         if(tests[i]()){
9823                                                 detectReady("poller");
9824                                                 return;
9825                                         }
9826                                 }
9827                                 setTimeout(poller, 30);
9828                         };
9829                         poller();
9830                 }
9831         }
9832
9833         function domReady(callback){
9834                 // summary:
9835                 //              Plugin to delay require()/define() callback from firing until the DOM has finished loading.
9836                 if(ready){
9837                         callback(doc);
9838                 }else{
9839                         readyQ.push(callback);
9840                 }
9841         }
9842         domReady.load = function(id, req, load){
9843                 domReady(load);
9844         };
9845
9846         return domReady;
9847 });
9848
9849 },
9850 'dojo/_base/lang':function(){
9851 define("dojo/_base/lang", ["./kernel", "../has", "../sniff"], function(dojo, has){
9852         // module:
9853         //              dojo/_base/lang
9854
9855         has.add("bug-for-in-skips-shadowed", function(){
9856                 // if true, the for-in iterator skips object properties that exist in Object's prototype (IE 6 - ?)
9857                 for(var i in {toString: 1}){
9858                         return 0;
9859                 }
9860                 return 1;
9861         });
9862
9863         // Helper methods
9864         var _extraNames =
9865                         has("bug-for-in-skips-shadowed") ?
9866                                 "hasOwnProperty.valueOf.isPrototypeOf.propertyIsEnumerable.toLocaleString.toString.constructor".split(".") : [],
9867
9868                 _extraLen = _extraNames.length,
9869
9870                 getProp = function(/*Array*/parts, /*Boolean*/create, /*Object*/context){
9871                         var p, i = 0, dojoGlobal = dojo.global;
9872                         if(!context){
9873                                 if(!parts.length){
9874                                         return dojoGlobal;
9875                                 }else{
9876                                         p = parts[i++];
9877                                         try{
9878                                                 context = dojo.scopeMap[p] && dojo.scopeMap[p][1];
9879                                         }catch(e){}
9880                                         context = context || (p in dojoGlobal ? dojoGlobal[p] : (create ? dojoGlobal[p] = {} : undefined));
9881                                 }
9882                         }
9883                         while(context && (p = parts[i++])){
9884                                 context = (p in context ? context[p] : (create ? context[p] = {} : undefined));
9885                         }
9886                         return context; // mixed
9887                 },
9888
9889                 opts = Object.prototype.toString,
9890
9891                 efficient = function(obj, offset, startWith){
9892                         return (startWith||[]).concat(Array.prototype.slice.call(obj, offset||0));
9893                 },
9894
9895                 _pattern = /\{([^\}]+)\}/g;
9896
9897         // Module export
9898         var lang = {
9899                 // summary:
9900                 //              This module defines Javascript language extensions.
9901
9902                 // _extraNames: String[]
9903                 //              Lists property names that must be explicitly processed during for-in iteration
9904                 //              in environments that have has("bug-for-in-skips-shadowed") true.
9905                 _extraNames:_extraNames,
9906
9907                 _mixin: function(dest, source, copyFunc){
9908                         // summary:
9909                         //              Copies/adds all properties of source to dest; returns dest.
9910                         // dest: Object
9911                         //              The object to which to copy/add all properties contained in source.
9912                         // source: Object
9913                         //              The object from which to draw all properties to copy into dest.
9914                         // copyFunc: Function?
9915                         //              The process used to copy/add a property in source; defaults to the Javascript assignment operator.
9916                         // returns:
9917                         //              dest, as modified
9918                         // description:
9919                         //              All properties, including functions (sometimes termed "methods"), excluding any non-standard extensions
9920                         //              found in Object.prototype, are copied/added to dest. Copying/adding each particular property is
9921                         //              delegated to copyFunc (if any); copyFunc defaults to the Javascript assignment operator if not provided.
9922                         //              Notice that by default, _mixin executes a so-called "shallow copy" and aggregate types are copied/added by reference.
9923                         var name, s, i, empty = {};
9924                         for(name in source){
9925                                 // the (!(name in empty) || empty[name] !== s) condition avoids copying properties in "source"
9926                                 // inherited from Object.prototype.      For example, if dest has a custom toString() method,
9927                                 // don't overwrite it with the toString() method that source inherited from Object.prototype
9928                                 s = source[name];
9929                                 if(!(name in dest) || (dest[name] !== s && (!(name in empty) || empty[name] !== s))){
9930                                         dest[name] = copyFunc ? copyFunc(s) : s;
9931                                 }
9932                         }
9933
9934                         if(has("bug-for-in-skips-shadowed")){
9935                                 if(source){
9936                                         for(i = 0; i < _extraLen; ++i){
9937                                                 name = _extraNames[i];
9938                                                 s = source[name];
9939                                                 if(!(name in dest) || (dest[name] !== s && (!(name in empty) || empty[name] !== s))){
9940                                                         dest[name] = copyFunc ? copyFunc(s) : s;
9941                                                 }
9942                                         }
9943                                 }
9944                         }
9945
9946                         return dest; // Object
9947                 },
9948
9949                 mixin: function(dest, sources){
9950                         // summary:
9951                         //              Copies/adds all properties of one or more sources to dest; returns dest.
9952                         // dest: Object
9953                         //              The object to which to copy/add all properties contained in source. If dest is falsy, then
9954                         //              a new object is manufactured before copying/adding properties begins.
9955                         // sources: Object...
9956                         //              One of more objects from which to draw all properties to copy into dest. sources are processed
9957                         //              left-to-right and if more than one of these objects contain the same property name, the right-most
9958                         //              value "wins".
9959                         // returns: Object
9960                         //              dest, as modified
9961                         // description:
9962                         //              All properties, including functions (sometimes termed "methods"), excluding any non-standard extensions
9963                         //              found in Object.prototype, are copied/added from sources to dest. sources are processed left to right.
9964                         //              The Javascript assignment operator is used to copy/add each property; therefore, by default, mixin
9965                         //              executes a so-called "shallow copy" and aggregate types are copied/added by reference.
9966                         // example:
9967                         //              make a shallow copy of an object
9968                         //      |       var copy = lang.mixin({}, source);
9969                         // example:
9970                         //              many class constructors often take an object which specifies
9971                         //              values to be configured on the object. In this case, it is
9972                         //              often simplest to call `lang.mixin` on the `this` object:
9973                         //      |       declare("acme.Base", null, {
9974                         //      |               constructor: function(properties){
9975                         //      |                       // property configuration:
9976                         //      |                       lang.mixin(this, properties);
9977                         //      |
9978                         //      |                       console.log(this.quip);
9979                         //      |                       //      ...
9980                         //      |               },
9981                         //      |               quip: "I wasn't born yesterday, you know - I've seen movies.",
9982                         //      |               // ...
9983                         //      |       });
9984                         //      |
9985                         //      |       // create an instance of the class and configure it
9986                         //      |       var b = new acme.Base({quip: "That's what it does!" });
9987                         // example:
9988                         //              copy in properties from multiple objects
9989                         //      |       var flattened = lang.mixin(
9990                         //      |               {
9991                         //      |                       name: "Frylock",
9992                         //      |                       braces: true
9993                         //      |               },
9994                         //      |               {
9995                         //      |                       name: "Carl Brutanananadilewski"
9996                         //      |               }
9997                         //      |       );
9998                         //      |
9999                         //      |       // will print "Carl Brutanananadilewski"
10000                         //      |       console.log(flattened.name);
10001                         //      |       // will print "true"
10002                         //      |       console.log(flattened.braces);
10003
10004                         if(!dest){ dest = {}; }
10005                         for(var i = 1, l = arguments.length; i < l; i++){
10006                                 lang._mixin(dest, arguments[i]);
10007                         }
10008                         return dest; // Object
10009                 },
10010
10011                 setObject: function(name, value, context){
10012                         // summary:
10013                         //              Set a property from a dot-separated string, such as "A.B.C"
10014                         // description:
10015                         //              Useful for longer api chains where you have to test each object in
10016                         //              the chain, or when you have an object reference in string format.
10017                         //              Objects are created as needed along `path`. Returns the passed
10018                         //              value if setting is successful or `undefined` if not.
10019                         // name: String
10020                         //              Path to a property, in the form "A.B.C".
10021                         // value: anything
10022                         //              value or object to place at location given by name
10023                         // context: Object?
10024                         //              Optional. Object to use as root of path. Defaults to
10025                         //              `dojo.global`.
10026                         // example:
10027                         //              set the value of `foo.bar.baz`, regardless of whether
10028                         //              intermediate objects already exist:
10029                         //      | lang.setObject("foo.bar.baz", value);
10030                         // example:
10031                         //              without `lang.setObject`, we often see code like this:
10032                         //      | // ensure that intermediate objects are available
10033                         //      | if(!obj["parent"]){ obj.parent = {}; }
10034                         //      | if(!obj.parent["child"]){ obj.parent.child = {}; }
10035                         //      | // now we can safely set the property
10036                         //      | obj.parent.child.prop = "some value";
10037                         //              whereas with `lang.setObject`, we can shorten that to:
10038                         //      | lang.setObject("parent.child.prop", "some value", obj);
10039
10040                         var parts = name.split("."), p = parts.pop(), obj = getProp(parts, true, context);
10041                         return obj && p ? (obj[p] = value) : undefined; // Object
10042                 },
10043
10044                 getObject: function(name, create, context){
10045                         // summary:
10046                         //              Get a property from a dot-separated string, such as "A.B.C"
10047                         // description:
10048                         //              Useful for longer api chains where you have to test each object in
10049                         //              the chain, or when you have an object reference in string format.
10050                         // name: String
10051                         //              Path to an property, in the form "A.B.C".
10052                         // create: Boolean?
10053                         //              Optional. Defaults to `false`. If `true`, Objects will be
10054                         //              created at any point along the 'path' that is undefined.
10055                         // context: Object?
10056                         //              Optional. Object to use as root of path. Defaults to
10057                         //              'dojo.global'. Null may be passed.
10058                         return getProp(name.split("."), create, context); // Object
10059                 },
10060
10061                 exists: function(name, obj){
10062                         // summary:
10063                         //              determine if an object supports a given method
10064                         // description:
10065                         //              useful for longer api chains where you have to test each object in
10066                         //              the chain. Useful for object and method detection.
10067                         // name: String
10068                         //              Path to an object, in the form "A.B.C".
10069                         // obj: Object?
10070                         //              Object to use as root of path. Defaults to
10071                         //              'dojo.global'. Null may be passed.
10072                         // example:
10073                         //      | // define an object
10074                         //      | var foo = {
10075                         //      |               bar: { }
10076                         //      | };
10077                         //      |
10078                         //      | // search the global scope
10079                         //      | lang.exists("foo.bar"); // true
10080                         //      | lang.exists("foo.bar.baz"); // false
10081                         //      |
10082                         //      | // search from a particular scope
10083                         //      | lang.exists("bar", foo); // true
10084                         //      | lang.exists("bar.baz", foo); // false
10085                         return lang.getObject(name, false, obj) !== undefined; // Boolean
10086                 },
10087
10088                 // Crockford (ish) functions
10089
10090                 isString: function(it){
10091                         // summary:
10092                         //              Return true if it is a String
10093                         // it: anything
10094                         //              Item to test.
10095                         return (typeof it == "string" || it instanceof String); // Boolean
10096                 },
10097
10098                 isArray: function(it){
10099                         // summary:
10100                         //              Return true if it is an Array.
10101                         //              Does not work on Arrays created in other windows.
10102                         // it: anything
10103                         //              Item to test.
10104                         return it && (it instanceof Array || typeof it == "array"); // Boolean
10105                 },
10106
10107                 isFunction: function(it){
10108                         // summary:
10109                         //              Return true if it is a Function
10110                         // it: anything
10111                         //              Item to test.
10112                         return opts.call(it) === "[object Function]";
10113                 },
10114
10115                 isObject: function(it){
10116                         // summary:
10117                         //              Returns true if it is a JavaScript object (or an Array, a Function
10118                         //              or null)
10119                         // it: anything
10120                         //              Item to test.
10121                         return it !== undefined &&
10122                                 (it === null || typeof it == "object" || lang.isArray(it) || lang.isFunction(it)); // Boolean
10123                 },
10124
10125                 isArrayLike: function(it){
10126                         // summary:
10127                         //              similar to isArray() but more permissive
10128                         // it: anything
10129                         //              Item to test.
10130                         // returns:
10131                         //              If it walks like a duck and quacks like a duck, return `true`
10132                         // description:
10133                         //              Doesn't strongly test for "arrayness".  Instead, settles for "isn't
10134                         //              a string or number and has a length property". Arguments objects
10135                         //              and DOM collections will return true when passed to
10136                         //              isArrayLike(), but will return false when passed to
10137                         //              isArray().
10138                         return it && it !== undefined && // Boolean
10139                                 // keep out built-in constructors (Number, String, ...) which have length
10140                                 // properties
10141                                 !lang.isString(it) && !lang.isFunction(it) &&
10142                                 !(it.tagName && it.tagName.toLowerCase() == 'form') &&
10143                                 (lang.isArray(it) || isFinite(it.length));
10144                 },
10145
10146                 isAlien: function(it){
10147                         // summary:
10148                         //              Returns true if it is a built-in function or some other kind of
10149                         //              oddball that *should* report as a function but doesn't
10150                         return it && !lang.isFunction(it) && /\{\s*\[native code\]\s*\}/.test(String(it)); // Boolean
10151                 },
10152
10153                 extend: function(ctor, props){
10154                         // summary:
10155                         //              Adds all properties and methods of props to constructor's
10156                         //              prototype, making them available to all instances created with
10157                         //              constructor.
10158                         // ctor: Object
10159                         //              Target constructor to extend.
10160                         // props: Object
10161                         //              One or more objects to mix into ctor.prototype
10162                         for(var i=1, l=arguments.length; i<l; i++){
10163                                 lang._mixin(ctor.prototype, arguments[i]);
10164                         }
10165                         return ctor; // Object
10166                 },
10167
10168                 _hitchArgs: function(scope, method){
10169                         var pre = lang._toArray(arguments, 2);
10170                         var named = lang.isString(method);
10171                         return function(){
10172                                 // arrayify arguments
10173                                 var args = lang._toArray(arguments);
10174                                 // locate our method
10175                                 var f = named ? (scope||dojo.global)[method] : method;
10176                                 // invoke with collected args
10177                                 return f && f.apply(scope || this, pre.concat(args)); // mixed
10178                         }; // Function
10179                 },
10180
10181                 hitch: function(scope, method){
10182                         // summary:
10183                         //              Returns a function that will only ever execute in the a given scope.
10184                         //              This allows for easy use of object member functions
10185                         //              in callbacks and other places in which the "this" keyword may
10186                         //              otherwise not reference the expected scope.
10187                         //              Any number of default positional arguments may be passed as parameters
10188                         //              beyond "method".
10189                         //              Each of these values will be used to "placehold" (similar to curry)
10190                         //              for the hitched function.
10191                         // scope: Object
10192                         //              The scope to use when method executes. If method is a string,
10193                         //              scope is also the object containing method.
10194                         // method: Function|String...
10195                         //              A function to be hitched to scope, or the name of the method in
10196                         //              scope to be hitched.
10197                         // example:
10198                         //      |       lang.hitch(foo, "bar")();
10199                         //              runs foo.bar() in the scope of foo
10200                         // example:
10201                         //      |       lang.hitch(foo, myFunction);
10202                         //              returns a function that runs myFunction in the scope of foo
10203                         // example:
10204                         //              Expansion on the default positional arguments passed along from
10205                         //              hitch. Passed args are mixed first, additional args after.
10206                         //      |       var foo = { bar: function(a, b, c){ console.log(a, b, c); } };
10207                         //      |       var fn = lang.hitch(foo, "bar", 1, 2);
10208                         //      |       fn(3); // logs "1, 2, 3"
10209                         // example:
10210                         //      |       var foo = { bar: 2 };
10211                         //      |       lang.hitch(foo, function(){ this.bar = 10; })();
10212                         //              execute an anonymous function in scope of foo
10213                         if(arguments.length > 2){
10214                                 return lang._hitchArgs.apply(dojo, arguments); // Function
10215                         }
10216                         if(!method){
10217                                 method = scope;
10218                                 scope = null;
10219                         }
10220                         if(lang.isString(method)){
10221                                 scope = scope || dojo.global;
10222                                 if(!scope[method]){ throw(['lang.hitch: scope["', method, '"] is null (scope="', scope, '")'].join('')); }
10223                                 return function(){ return scope[method].apply(scope, arguments || []); }; // Function
10224                         }
10225                         return !scope ? method : function(){ return method.apply(scope, arguments || []); }; // Function
10226                 },
10227
10228                 delegate: (function(){
10229                         // boodman/crockford delegation w/ cornford optimization
10230                         function TMP(){}
10231                         return function(obj, props){
10232                                 TMP.prototype = obj;
10233                                 var tmp = new TMP();
10234                                 TMP.prototype = null;
10235                                 if(props){
10236                                         lang._mixin(tmp, props);
10237                                 }
10238                                 return tmp; // Object
10239                         };
10240                 })(),
10241                 /*=====
10242                 delegate: function(obj, props){
10243                         // summary:
10244                         //              Returns a new object which "looks" to obj for properties which it
10245                         //              does not have a value for. Optionally takes a bag of properties to
10246                         //              seed the returned object with initially.
10247                         // description:
10248                         //              This is a small implementation of the Boodman/Crockford delegation
10249                         //              pattern in JavaScript. An intermediate object constructor mediates
10250                         //              the prototype chain for the returned object, using it to delegate
10251                         //              down to obj for property lookup when object-local lookup fails.
10252                         //              This can be thought of similarly to ES4's "wrap", save that it does
10253                         //              not act on types but rather on pure objects.
10254                         // obj: Object
10255                         //              The object to delegate to for properties not found directly on the
10256                         //              return object or in props.
10257                         // props: Object...
10258                         //              an object containing properties to assign to the returned object
10259                         // returns:
10260                         //              an Object of anonymous type
10261                         // example:
10262                         //      |       var foo = { bar: "baz" };
10263                         //      |       var thinger = lang.delegate(foo, { thud: "xyzzy"});
10264                         //      |       thinger.bar == "baz"; // delegated to foo
10265                         //      |       foo.thud == undefined; // by definition
10266                         //      |       thinger.thud == "xyzzy"; // mixed in from props
10267                         //      |       foo.bar = "thonk";
10268                         //      |       thinger.bar == "thonk"; // still delegated to foo's bar
10269                 },
10270                 =====*/
10271
10272                 _toArray: has("ie") ?
10273                         (function(){
10274                                 function slow(obj, offset, startWith){
10275                                         var arr = startWith||[];
10276                                         for(var x = offset || 0; x < obj.length; x++){
10277                                                 arr.push(obj[x]);
10278                                         }
10279                                         return arr;
10280                                 }
10281                                 return function(obj){
10282                                         return ((obj.item) ? slow : efficient).apply(this, arguments);
10283                                 };
10284                         })() : efficient,
10285                 /*=====
10286                  _toArray: function(obj, offset, startWith){
10287                          // summary:
10288                          //             Converts an array-like object (i.e. arguments, DOMCollection) to an
10289                          //             array. Returns a new Array with the elements of obj.
10290                          // obj: Object
10291                          //             the object to "arrayify". We expect the object to have, at a
10292                          //             minimum, a length property which corresponds to integer-indexed
10293                          //             properties.
10294                          // offset: Number?
10295                          //             the location in obj to start iterating from. Defaults to 0.
10296                          //             Optional.
10297                          // startWith: Array?
10298                          //             An array to pack with the properties of obj. If provided,
10299                          //             properties in obj are appended at the end of startWith and
10300                          //             startWith is the returned array.
10301                  },
10302                  =====*/
10303
10304                 partial: function(/*Function|String*/ method /*, ...*/){
10305                         // summary:
10306                         //              similar to hitch() except that the scope object is left to be
10307                         //              whatever the execution context eventually becomes.
10308                         // description:
10309                         //              Calling lang.partial is the functional equivalent of calling:
10310                         //              |       lang.hitch(null, funcName, ...);
10311                         // method:
10312                         //              The function to "wrap"
10313                         var arr = [ null ];
10314                         return lang.hitch.apply(dojo, arr.concat(lang._toArray(arguments))); // Function
10315                 },
10316
10317                 clone: function(/*anything*/ src){
10318                         // summary:
10319                         //              Clones objects (including DOM nodes) and all children.
10320                         //              Warning: do not clone cyclic structures.
10321                         // src:
10322                         //              The object to clone
10323                         if(!src || typeof src != "object" || lang.isFunction(src)){
10324                                 // null, undefined, any non-object, or function
10325                                 return src;     // anything
10326                         }
10327                         if(src.nodeType && "cloneNode" in src){
10328                                 // DOM Node
10329                                 return src.cloneNode(true); // Node
10330                         }
10331                         if(src instanceof Date){
10332                                 // Date
10333                                 return new Date(src.getTime()); // Date
10334                         }
10335                         if(src instanceof RegExp){
10336                                 // RegExp
10337                                 return new RegExp(src);   // RegExp
10338                         }
10339                         var r, i, l;
10340                         if(lang.isArray(src)){
10341                                 // array
10342                                 r = [];
10343                                 for(i = 0, l = src.length; i < l; ++i){
10344                                         if(i in src){
10345                                                 r.push(lang.clone(src[i]));
10346                                         }
10347                                 }
10348                                 // we don't clone functions for performance reasons
10349                                 //              }else if(d.isFunction(src)){
10350                                 //                      // function
10351                                 //                      r = function(){ return src.apply(this, arguments); };
10352                         }else{
10353                                 // generic objects
10354                                 r = src.constructor ? new src.constructor() : {};
10355                         }
10356                         return lang._mixin(r, src, lang.clone);
10357                 },
10358
10359
10360                 trim: String.prototype.trim ?
10361                         function(str){ return str.trim(); } :
10362                         function(str){ return str.replace(/^\s\s*/, '').replace(/\s\s*$/, ''); },
10363                 /*=====
10364                  trim: function(str){
10365                          // summary:
10366                          //             Trims whitespace from both sides of the string
10367                          // str: String
10368                          //             String to be trimmed
10369                          // returns: String
10370                          //             Returns the trimmed string
10371                          // description:
10372                          //             This version of trim() was selected for inclusion into the base due
10373                          //             to its compact size and relatively good performance
10374                          //             (see [Steven Levithan's blog](http://blog.stevenlevithan.com/archives/faster-trim-javascript)
10375                          //             Uses String.prototype.trim instead, if available.
10376                          //             The fastest but longest version of this function is located at
10377                          //             lang.string.trim()
10378                  },
10379                  =====*/
10380
10381                 replace: function(tmpl, map, pattern){
10382                         // summary:
10383                         //              Performs parameterized substitutions on a string. Throws an
10384                         //              exception if any parameter is unmatched.
10385                         // tmpl: String
10386                         //              String to be used as a template.
10387                         // map: Object|Function
10388                         //              If an object, it is used as a dictionary to look up substitutions.
10389                         //              If a function, it is called for every substitution with following parameters:
10390                         //              a whole match, a name, an offset, and the whole template
10391                         //              string (see https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/String/replace
10392                         //              for more details).
10393                         // pattern: RegEx?
10394                         //              Optional regular expression objects that overrides the default pattern.
10395                         //              Must be global and match one item. The default is: /\{([^\}]+)\}/g,
10396                         //              which matches patterns like that: "{xxx}", where "xxx" is any sequence
10397                         //              of characters, which doesn't include "}".
10398                         // returns: String
10399                         //              Returns the substituted string.
10400                         // example:
10401                         //      |       // uses a dictionary for substitutions:
10402                         //      |       lang.replace("Hello, {name.first} {name.last} AKA {nick}!",
10403                         //      |               {
10404                         //      |                       nick: "Bob",
10405                         //      |                       name: {
10406                         //      |                               first:  "Robert",
10407                         //      |                               middle: "X",
10408                         //      |                               last:           "Cringely"
10409                         //      |                       }
10410                         //      |               });
10411                         //      |       // returns: Hello, Robert Cringely AKA Bob!
10412                         // example:
10413                         //      |       // uses an array for substitutions:
10414                         //      |       lang.replace("Hello, {0} {2}!",
10415                         //      |               ["Robert", "X", "Cringely"]);
10416                         //      |       // returns: Hello, Robert Cringely!
10417                         // example:
10418                         //      |       // uses a function for substitutions:
10419                         //      |       function sum(a){
10420                         //      |               var t = 0;
10421                         //      |               arrayforEach(a, function(x){ t += x; });
10422                         //      |               return t;
10423                         //      |       }
10424                         //      |       lang.replace(
10425                         //      |               "{count} payments averaging {avg} USD per payment.",
10426                         //      |               lang.hitch(
10427                         //      |                       { payments: [11, 16, 12] },
10428                         //      |                       function(_, key){
10429                         //      |                               switch(key){
10430                         //      |                                       case "count": return this.payments.length;
10431                         //      |                                       case "min":             return Math.min.apply(Math, this.payments);
10432                         //      |                                       case "max":             return Math.max.apply(Math, this.payments);
10433                         //      |                                       case "sum":             return sum(this.payments);
10434                         //      |                                       case "avg":             return sum(this.payments) / this.payments.length;
10435                         //      |                               }
10436                         //      |                       }
10437                         //      |               )
10438                         //      |       );
10439                         //      |       // prints: 3 payments averaging 13 USD per payment.
10440                         // example:
10441                         //      |       // uses an alternative PHP-like pattern for substitutions:
10442                         //      |       lang.replace("Hello, ${0} ${2}!",
10443                         //      |               ["Robert", "X", "Cringely"], /\$\{([^\}]+)\}/g);
10444                         //      |       // returns: Hello, Robert Cringely!
10445
10446                         return tmpl.replace(pattern || _pattern, lang.isFunction(map) ?
10447                                 map : function(_, k){ return lang.getObject(k, false, map); });
10448                 }
10449         };
10450
10451          1  && lang.mixin(dojo, lang);
10452
10453         return lang;
10454 });
10455
10456
10457 },
10458 'dojo/request/util':function(){
10459 define("dojo/request/util", [
10460         'exports',
10461         '../errors/RequestError',
10462         '../errors/CancelError',
10463         '../Deferred',
10464         '../io-query',
10465         '../_base/array',
10466         '../_base/lang'
10467 ], function(exports, RequestError, CancelError, Deferred, ioQuery, array, lang){
10468         exports.deepCopy = function deepCopy(target, source){
10469                 for(var name in source){
10470                         var tval = target[name],
10471                                 sval = source[name];
10472                         if(tval !== sval){
10473                                 if(tval && typeof tval === 'object' && sval && typeof sval === 'object'){
10474                                         exports.deepCopy(tval, sval);
10475                                 }else{
10476                                         target[name] = sval;
10477                                 }
10478                         }
10479                 }
10480                 return target;
10481         };
10482
10483         exports.deepCreate = function deepCreate(source, properties){
10484                 properties = properties || {};
10485                 var target = lang.delegate(source),
10486                         name, value;
10487
10488                 for(name in source){
10489                         value = source[name];
10490
10491                         if(value && typeof value === 'object'){
10492                                 target[name] = exports.deepCreate(value, properties[name]);
10493                         }
10494                 }
10495                 return exports.deepCopy(target, properties);
10496         };
10497
10498         var freeze = Object.freeze || function(obj){ return obj; };
10499         function okHandler(response){
10500                 return freeze(response);
10501         }
10502
10503         exports.deferred = function deferred(response, cancel, isValid, isReady, handleResponse, last){
10504                 var def = new Deferred(function(reason){
10505                         cancel && cancel(def, response);
10506
10507                         if(!reason || !(reason instanceof RequestError) && !(reason instanceof CancelError)){
10508                                 return new CancelError('Request canceled', response);
10509                         }
10510                         return reason;
10511                 });
10512
10513                 def.response = response;
10514                 def.isValid = isValid;
10515                 def.isReady = isReady;
10516                 def.handleResponse = handleResponse;
10517
10518                 function errHandler(error){
10519                         error.response = response;
10520                         throw error;
10521                 }
10522                 var responsePromise = def.then(okHandler).otherwise(errHandler);
10523
10524                 if(exports.notify){
10525                         responsePromise.then(
10526                                 lang.hitch(exports.notify, 'emit', 'load'),
10527                                 lang.hitch(exports.notify, 'emit', 'error')
10528                         );
10529                 }
10530
10531                 var dataPromise = responsePromise.then(function(response){
10532                                 return response.data || response.text;
10533                         });
10534
10535                 var promise = freeze(lang.delegate(dataPromise, {
10536                         response: responsePromise
10537                 }));
10538
10539
10540                 if(last){
10541                         def.then(function(response){
10542                                 last.call(def, response);
10543                         }, function(error){
10544                                 last.call(def, response, error);
10545                         });
10546                 }
10547
10548                 def.promise = promise;
10549                 def.then = promise.then;
10550
10551                 return def;
10552         };
10553
10554         exports.addCommonMethods = function addCommonMethods(provider, methods){
10555                 array.forEach(methods||['GET', 'POST', 'PUT', 'DELETE'], function(method){
10556                         provider[(method === 'DELETE' ? 'DEL' : method).toLowerCase()] = function(url, options){
10557                                 options = lang.delegate(options||{});
10558                                 options.method = method;
10559                                 return provider(url, options);
10560                         };
10561                 });
10562         };
10563
10564         exports.parseArgs = function parseArgs(url, options, skipData){
10565                 var data = options.data,
10566                         query = options.query;
10567                 
10568                 if(data && !skipData){
10569                         if(typeof data === 'object'){
10570                                 options.data = ioQuery.objectToQuery(data);
10571                         }
10572                 }
10573
10574                 if(query){
10575                         if(typeof query === 'object'){
10576                                 query = ioQuery.objectToQuery(query);
10577                         }
10578                         if(options.preventCache){
10579                                 query += (query ? '&' : '') + 'request.preventCache=' + (+(new Date));
10580                         }
10581                 }else if(options.preventCache){
10582                         query = 'request.preventCache=' + (+(new Date));
10583                 }
10584
10585                 if(url && query){
10586                         url += (~url.indexOf('?') ? '&' : '?') + query;
10587                 }
10588
10589                 return {
10590                         url: url,
10591                         options: options,
10592                         getHeader: function(headerName){ return null; }
10593                 };
10594         };
10595
10596         exports.checkStatus = function(stat){
10597                 stat = stat || 0;
10598                 return (stat >= 200 && stat < 300) || // allow any 2XX response code
10599                         stat === 304 ||                 // or, get it out of the cache
10600                         stat === 1223 ||                // or, Internet Explorer mangled the status code
10601                         !stat;                         // or, we're Titanium/browser chrome/chrome extension requesting a local file
10602         };
10603 });
10604
10605 },
10606 'dojo/Evented':function(){
10607 define("dojo/Evented", ["./aspect", "./on"], function(aspect, on){
10608         // module:
10609         //              dojo/Evented
10610
10611         "use strict";
10612         var after = aspect.after;
10613         function Evented(){
10614                 // summary:
10615                 //              A class that can be used as a mixin or base class,
10616                 //              to add on() and emit() methods to a class
10617                 //              for listening for events and emitting events:
10618                 //
10619                 //              |       define(["dojo/Evented"], function(Evented){
10620                 //              |               var EventedWidget = dojo.declare([Evented, dijit._Widget], {...});
10621                 //              |               widget = new EventedWidget();
10622                 //              |               widget.on("open", function(event){
10623                 //              |               ... do something with event
10624                 //              |        });
10625                 //              |
10626                 //              |       widget.emit("open", {name:"some event", ...});
10627         }
10628         Evented.prototype = {
10629                 on: function(type, listener){
10630                         return on.parse(this, type, listener, function(target, type){
10631                                 return after(target, 'on' + type, listener, true);
10632                         });
10633                 },
10634                 emit: function(type, event){
10635                         var args = [this];
10636                         args.push.apply(args, arguments);
10637                         return on.emit.apply(on, args);
10638                 }
10639         };
10640         return Evented;
10641 });
10642
10643 },
10644 'dojo/mouse':function(){
10645 define("dojo/mouse", ["./_base/kernel", "./on", "./has", "./dom", "./_base/window"], function(dojo, on, has, dom, win){
10646
10647         // module:
10648         //              dojo/mouse
10649
10650     has.add("dom-quirks", win.doc && win.doc.compatMode == "BackCompat");
10651         has.add("events-mouseenter", win.doc && "onmouseenter" in win.doc.createElement("div"));
10652         has.add("events-mousewheel", win.doc && 'onmousewheel' in win.doc);
10653
10654         var mouseButtons;
10655         if((has("dom-quirks") && has("ie")) || !has("dom-addeventlistener")){
10656                 mouseButtons = {
10657                         LEFT:   1,
10658                         MIDDLE: 4,
10659                         RIGHT:  2,
10660                         // helper functions
10661                         isButton: function(e, button){ return e.button & button; },
10662                         isLeft:   function(e){ return e.button & 1; },
10663                         isMiddle: function(e){ return e.button & 4; },
10664                         isRight:  function(e){ return e.button & 2; }
10665                 };
10666         }else{
10667                 mouseButtons = {
10668                         LEFT:   0,
10669                         MIDDLE: 1,
10670                         RIGHT:  2,
10671                         // helper functions
10672                         isButton: function(e, button){ return e.button == button; },
10673                         isLeft:   function(e){ return e.button == 0; },
10674                         isMiddle: function(e){ return e.button == 1; },
10675                         isRight:  function(e){ return e.button == 2; }
10676                 };
10677         }
10678         dojo.mouseButtons = mouseButtons;
10679
10680 /*=====
10681         dojo.mouseButtons = {
10682                 // LEFT: Number
10683                 //              Numeric value of the left mouse button for the platform.
10684                 LEFT:   0,
10685                 // MIDDLE: Number
10686                 //              Numeric value of the middle mouse button for the platform.
10687                 MIDDLE: 1,
10688                 // RIGHT: Number
10689                 //              Numeric value of the right mouse button for the platform.
10690                 RIGHT:  2,
10691
10692                 isButton: function(e, button){
10693                         // summary:
10694                         //              Checks an event object for a pressed button
10695                         // e: Event
10696                         //              Event object to examine
10697                         // button: Number
10698                         //              The button value (example: dojo.mouseButton.LEFT)
10699                         return e.button == button; // Boolean
10700                 },
10701                 isLeft: function(e){
10702                         // summary:
10703                         //              Checks an event object for the pressed left button
10704                         // e: Event
10705                         //              Event object to examine
10706                         return e.button == 0; // Boolean
10707                 },
10708                 isMiddle: function(e){
10709                         // summary:
10710                         //              Checks an event object for the pressed middle button
10711                         // e: Event
10712                         //              Event object to examine
10713                         return e.button == 1; // Boolean
10714                 },
10715                 isRight: function(e){
10716                         // summary:
10717                         //              Checks an event object for the pressed right button
10718                         // e: Event
10719                         //              Event object to examine
10720                         return e.button == 2; // Boolean
10721                 }
10722         };
10723 =====*/
10724
10725         function eventHandler(type, selectHandler){
10726                 // emulation of mouseenter/leave with mouseover/out using descendant checking
10727                 var handler = function(node, listener){
10728                         return on(node, type, function(evt){
10729                                 if(selectHandler){
10730                                         return selectHandler(evt, listener);
10731                                 }
10732                                 if(!dom.isDescendant(evt.relatedTarget, node)){
10733                                         return listener.call(this, evt);
10734                                 }
10735                         });
10736                 };
10737                 handler.bubble = function(select){
10738                         return eventHandler(type, function(evt, listener){
10739                                 // using a selector, use the select function to determine if the mouse moved inside the selector and was previously outside the selector
10740                                 var target = select(evt.target);
10741                                 var relatedTarget = evt.relatedTarget;
10742                                 if(target && (target != (relatedTarget && relatedTarget.nodeType == 1 && select(relatedTarget)))){
10743                                         return listener.call(target, evt);
10744                                 } 
10745                         });
10746                 };
10747                 return handler;
10748         }
10749         var wheel;
10750         if(has("events-mousewheel")){
10751                 wheel = 'mousewheel';
10752         }else{ //firefox
10753                 wheel = function(node, listener){
10754                         return on(node, 'DOMMouseScroll', function(evt){
10755                                 evt.wheelDelta = -evt.detail;
10756                                 listener.call(this, evt);
10757                         });
10758                 };
10759         }
10760         return {
10761                 // summary:
10762                 //              This module provide mouse event handling utility functions and exports
10763                 //              mouseenter and mouseleave event emulation.
10764                 // example:
10765                 //              To use these events, you register a mouseenter like this:
10766                 //              |       define(["dojo/on", dojo/mouse"], function(on, mouse){
10767                 //              |               on(targetNode, mouse.enter, function(event){
10768                 //              |                       dojo.addClass(targetNode, "highlighted");
10769                 //              |               });
10770                 //              |               on(targetNode, mouse.leave, function(event){
10771                 //              |                       dojo.removeClass(targetNode, "highlighted");
10772                 //              |               });
10773
10774                 _eventHandler: eventHandler,            // for dojo/touch
10775
10776                 // enter: Synthetic Event
10777                 //              This is an extension event for the mouseenter that IE provides, emulating the
10778                 //              behavior on other browsers.
10779                 enter: eventHandler("mouseover"),
10780
10781                 // leave: Synthetic Event
10782                 //              This is an extension event for the mouseleave that IE provides, emulating the
10783                 //              behavior on other browsers.
10784                 leave: eventHandler("mouseout"),
10785
10786                 // wheel: Normalized Mouse Wheel Event
10787                 //              This is an extension event for the mousewheel that non-Mozilla browsers provide,
10788                 //              emulating the behavior on Mozilla based browsers.
10789                 wheel: wheel,
10790
10791                 isLeft: mouseButtons.isLeft,
10792                 /*=====
10793                 isLeft: function(){
10794                         // summary:
10795                         //              Test an event object (from a mousedown event) to see if the left button was pressed.
10796                 },
10797                 =====*/
10798
10799                 isMiddle: mouseButtons.isMiddle,
10800                 /*=====
10801                  isMiddle: function(){
10802                          // summary:
10803                          //             Test an event object (from a mousedown event) to see if the middle button was pressed.
10804                  },
10805                  =====*/
10806
10807                 isRight: mouseButtons.isRight
10808                 /*=====
10809                  , isRight: function(){
10810                          // summary:
10811                          //             Test an event object (from a mousedown event) to see if the right button was pressed.
10812                  }
10813                  =====*/
10814         };
10815 });
10816
10817 },
10818 'dojo/topic':function(){
10819 define("dojo/topic", ["./Evented"], function(Evented){
10820
10821         // module:
10822         //              dojo/topic
10823
10824         var hub = new Evented;
10825         return {
10826                 // summary:
10827                 //              Pubsub hub.
10828                 // example:
10829                 //              |       topic.subscribe("some/topic", function(event){
10830                 //              |       ... do something with event
10831                 //              |       });
10832                 //              |       topic.publish("some/topic", {name:"some event", ...});
10833
10834                 publish: function(topic, event){
10835                         // summary:
10836                         //              Publishes a message to a topic on the pub/sub hub. All arguments after
10837                         //              the first will be passed to the subscribers, so any number of arguments
10838                         //              can be provided (not just event).
10839                         // topic: String
10840                         //              The name of the topic to publish to
10841                         // event: Object
10842                         //              An event to distribute to the topic listeners
10843                         return hub.emit.apply(hub, arguments);
10844                 },
10845
10846                 subscribe: function(topic, listener){
10847                         // summary:
10848                         //              Subscribes to a topic on the pub/sub hub
10849                         // topic: String
10850                         //              The topic to subscribe to
10851                         // listener: Function
10852                         //              A function to call when a message is published to the given topic
10853                         return hub.on.apply(hub, arguments);
10854                 }
10855         };
10856 });
10857
10858 },
10859 'dojo/_base/xhr':function(){
10860 define("dojo/_base/xhr", [
10861         "./kernel",
10862         "./sniff",
10863         "require",
10864         "../io-query",
10865         /*===== "./declare", =====*/
10866         "../dom",
10867         "../dom-form",
10868         "./Deferred",
10869         "./config",
10870         "./json",
10871         "./lang",
10872         "./array",
10873         "../on",
10874         "../aspect",
10875         "../request/watch",
10876         "../request/xhr",
10877         "../request/util"
10878 ], function(dojo, has, require, ioq, /*===== declare, =====*/ dom, domForm, Deferred, config, json, lang, array, on, aspect, watch, _xhr, util){
10879         // module:
10880         //              dojo/_base/xhr
10881
10882         /*=====
10883         dojo._xhrObj = function(){
10884                 // summary:
10885                 //              does the work of portably generating a new XMLHTTPRequest object.
10886         };
10887         =====*/
10888         dojo._xhrObj = _xhr._create;
10889
10890         var cfg = dojo.config;
10891
10892         // mix in io-query and dom-form
10893         dojo.objectToQuery = ioq.objectToQuery;
10894         dojo.queryToObject = ioq.queryToObject;
10895         dojo.fieldToObject = domForm.fieldToObject;
10896         dojo.formToObject = domForm.toObject;
10897         dojo.formToQuery = domForm.toQuery;
10898         dojo.formToJson = domForm.toJson;
10899
10900         // need to block async callbacks from snatching this thread as the result
10901         // of an async callback might call another sync XHR, this hangs khtml forever
10902         // must checked by watchInFlight()
10903
10904         dojo._blockAsync = false;
10905
10906         // MOW: remove dojo._contentHandlers alias in 2.0
10907         var handlers = dojo._contentHandlers = dojo.contentHandlers = {
10908                 // summary:
10909                 //              A map of available XHR transport handle types. Name matches the
10910                 //              `handleAs` attribute passed to XHR calls.
10911                 // description:
10912                 //              A map of available XHR transport handle types. Name matches the
10913                 //              `handleAs` attribute passed to XHR calls. Each contentHandler is
10914                 //              called, passing the xhr object for manipulation. The return value
10915                 //              from the contentHandler will be passed to the `load` or `handle`
10916                 //              functions defined in the original xhr call.
10917                 // example:
10918                 //              Creating a custom content-handler:
10919                 //      |       xhr.contentHandlers.makeCaps = function(xhr){
10920                 //      |               return xhr.responseText.toUpperCase();
10921                 //      |       }
10922                 //      |       // and later:
10923                 //      |       dojo.xhrGet({
10924                 //      |               url:"foo.txt",
10925                 //      |               handleAs:"makeCaps",
10926                 //      |               load: function(data){ /* data is a toUpper version of foo.txt */ }
10927                 //      |       });
10928
10929                 "text": function(xhr){
10930                         // summary:
10931                         //              A contentHandler which simply returns the plaintext response data
10932                         return xhr.responseText;
10933                 },
10934                 "json": function(xhr){
10935                         // summary:
10936                         //              A contentHandler which returns a JavaScript object created from the response data
10937                         return json.fromJson(xhr.responseText || null);
10938                 },
10939                 "json-comment-filtered": function(xhr){
10940                         // summary:
10941                         //              A contentHandler which expects comment-filtered JSON.
10942                         // description:
10943                         //              A contentHandler which expects comment-filtered JSON.
10944                         //              the json-comment-filtered option was implemented to prevent
10945                         //              "JavaScript Hijacking", but it is less secure than standard JSON. Use
10946                         //              standard JSON instead. JSON prefixing can be used to subvert hijacking.
10947                         //
10948                         //              Will throw a notice suggesting to use application/json mimetype, as
10949                         //              json-commenting can introduce security issues. To decrease the chances of hijacking,
10950                         //              use the standard `json` contentHandler, and prefix your "JSON" with: {}&&
10951                         //
10952                         //              use djConfig.useCommentedJson = true to turn off the notice
10953                         if(!config.useCommentedJson){
10954                                 console.warn("Consider using the standard mimetype:application/json."
10955                                         + " json-commenting can introduce security issues. To"
10956                                         + " decrease the chances of hijacking, use the standard the 'json' handler and"
10957                                         + " prefix your json with: {}&&\n"
10958                                         + "Use djConfig.useCommentedJson=true to turn off this message.");
10959                         }
10960
10961                         var value = xhr.responseText;
10962                         var cStartIdx = value.indexOf("\/*");
10963                         var cEndIdx = value.lastIndexOf("*\/");
10964                         if(cStartIdx == -1 || cEndIdx == -1){
10965                                 throw new Error("JSON was not comment filtered");
10966                         }
10967                         return json.fromJson(value.substring(cStartIdx+2, cEndIdx));
10968                 },
10969                 "javascript": function(xhr){
10970                         // summary:
10971                         //              A contentHandler which evaluates the response data, expecting it to be valid JavaScript
10972
10973                         // FIXME: try Moz and IE specific eval variants?
10974                         return dojo.eval(xhr.responseText);
10975                 },
10976                 "xml": function(xhr){
10977                         // summary:
10978                         //              A contentHandler returning an XML Document parsed from the response data
10979                         var result = xhr.responseXML;
10980
10981                         if(has("ie")){
10982                                 if((!result || !result.documentElement)){
10983                                         //WARNING: this branch used by the xml handling in dojo.io.iframe,
10984                                         //so be sure to test dojo.io.iframe if making changes below.
10985                                         var ms = function(n){ return "MSXML" + n + ".DOMDocument"; };
10986                                         var dp = ["Microsoft.XMLDOM", ms(6), ms(4), ms(3), ms(2)];
10987                                         array.some(dp, function(p){
10988                                                 try{
10989                                                         var dom = new ActiveXObject(p);
10990                                                         dom.async = false;
10991                                                         dom.loadXML(xhr.responseText);
10992                                                         result = dom;
10993                                                 }catch(e){ return false; }
10994                                                 return true;
10995                                         });
10996                                 }
10997                         }
10998                         return result; // DOMDocument
10999                 },
11000                 "json-comment-optional": function(xhr){
11001                         // summary:
11002                         //              A contentHandler which checks the presence of comment-filtered JSON and
11003                         //              alternates between the `json` and `json-comment-filtered` contentHandlers.
11004                         if(xhr.responseText && /^[^{\[]*\/\*/.test(xhr.responseText)){
11005                                 return handlers["json-comment-filtered"](xhr);
11006                         }else{
11007                                 return handlers["json"](xhr);
11008                         }
11009                 }
11010         };
11011
11012         /*=====
11013
11014         // kwargs function parameter definitions.   Assigning to dojo namespace rather than making them local variables
11015         // because they are used by dojo/io modules too
11016
11017         dojo.__IoArgs = declare(null, {
11018                 // url: String
11019                 //              URL to server endpoint.
11020                 // content: Object?
11021                 //              Contains properties with string values. These
11022                 //              properties will be serialized as name1=value2 and
11023                 //              passed in the request.
11024                 // timeout: Integer?
11025                 //              Milliseconds to wait for the response. If this time
11026                 //              passes, the then error callbacks are called.
11027                 // form: DOMNode?
11028                 //              DOM node for a form. Used to extract the form values
11029                 //              and send to the server.
11030                 // preventCache: Boolean?
11031                 //              Default is false. If true, then a
11032                 //              "dojo.preventCache" parameter is sent in the request
11033                 //              with a value that changes with each request
11034                 //              (timestamp). Useful only with GET-type requests.
11035                 // handleAs: String?
11036                 //              Acceptable values depend on the type of IO
11037                 //              transport (see specific IO calls for more information).
11038                 // rawBody: String?
11039                 //              Sets the raw body for an HTTP request. If this is used, then the content
11040                 //              property is ignored. This is mostly useful for HTTP methods that have
11041                 //              a body to their requests, like PUT or POST. This property can be used instead
11042                 //              of postData and putData for dojo/_base/xhr.rawXhrPost and dojo/_base/xhr.rawXhrPut respectively.
11043                 // ioPublish: Boolean?
11044                 //              Set this explicitly to false to prevent publishing of topics related to
11045                 //              IO operations. Otherwise, if djConfig.ioPublish is set to true, topics
11046                 //              will be published via dojo/topic.publish() for different phases of an IO operation.
11047                 //              See dojo/main.__IoPublish for a list of topics that are published.
11048
11049                 load: function(response, ioArgs){
11050                         // summary:
11051                         //              This function will be
11052                         //              called on a successful HTTP response code.
11053                         // ioArgs: dojo/main.__IoCallbackArgs
11054                         //              Provides additional information about the request.
11055                         // response: Object
11056                         //              The response in the format as defined with handleAs.
11057                 },
11058
11059                 error: function(response, ioArgs){
11060                         // summary:
11061                         //              This function will
11062                         //              be called when the request fails due to a network or server error, the url
11063                         //              is invalid, etc. It will also be called if the load or handle callback throws an
11064                         //              exception, unless djConfig.debugAtAllCosts is true.      This allows deployed applications
11065                         //              to continue to run even when a logic error happens in the callback, while making
11066                         //              it easier to troubleshoot while in debug mode.
11067                         // ioArgs: dojo/main.__IoCallbackArgs
11068                         //              Provides additional information about the request.
11069                         // response: Object
11070                         //              The response in the format as defined with handleAs.
11071                 },
11072
11073                 handle: function(loadOrError, response, ioArgs){
11074                         // summary:
11075                         //              This function will
11076                         //              be called at the end of every request, whether or not an error occurs.
11077                         // loadOrError: String
11078                         //              Provides a string that tells you whether this function
11079                         //              was called because of success (load) or failure (error).
11080                         // response: Object
11081                         //              The response in the format as defined with handleAs.
11082                         // ioArgs: dojo/main.__IoCallbackArgs
11083                         //              Provides additional information about the request.
11084                 }
11085         });
11086
11087         dojo.__IoCallbackArgs = declare(null, {
11088                 // args: Object
11089                 //              the original object argument to the IO call.
11090                 // xhr: XMLHttpRequest
11091                 //              For XMLHttpRequest calls only, the
11092                 //              XMLHttpRequest object that was used for the
11093                 //              request.
11094                 // url: String
11095                 //              The final URL used for the call. Many times it
11096                 //              will be different than the original args.url
11097                 //              value.
11098                 // query: String
11099                 //              For non-GET requests, the
11100                 //              name1=value1&name2=value2 parameters sent up in
11101                 //              the request.
11102                 // handleAs: String
11103                 //              The final indicator on how the response will be
11104                 //              handled.
11105                 // id: String
11106                 //              For dojo/io/script calls only, the internal
11107                 //              script ID used for the request.
11108                 // canDelete: Boolean
11109                 //              For dojo/io/script calls only, indicates
11110                 //              whether the script tag that represents the
11111                 //              request can be deleted after callbacks have
11112                 //              been called. Used internally to know when
11113                 //              cleanup can happen on JSONP-type requests.
11114                 // json: Object
11115                 //              For dojo/io/script calls only: holds the JSON
11116                 //              response for JSONP-type requests. Used
11117                 //              internally to hold on to the JSON responses.
11118                 //              You should not need to access it directly --
11119                 //              the same object should be passed to the success
11120                 //              callbacks directly.
11121         });
11122
11123         dojo.__IoPublish = declare(null, {
11124                 // summary:
11125                 //              This is a list of IO topics that can be published
11126                 //              if djConfig.ioPublish is set to true. IO topics can be
11127                 //              published for any Input/Output, network operation. So,
11128                 //              dojo.xhr, dojo.io.script and dojo.io.iframe can all
11129                 //              trigger these topics to be published.
11130                 // start: String
11131                 //              "/dojo/io/start" is sent when there are no outstanding IO
11132                 //              requests, and a new IO request is started. No arguments
11133                 //              are passed with this topic.
11134                 // send: String
11135                 //              "/dojo/io/send" is sent whenever a new IO request is started.
11136                 //              It passes the dojo.Deferred for the request with the topic.
11137                 // load: String
11138                 //              "/dojo/io/load" is sent whenever an IO request has loaded
11139                 //              successfully. It passes the response and the dojo.Deferred
11140                 //              for the request with the topic.
11141                 // error: String
11142                 //              "/dojo/io/error" is sent whenever an IO request has errored.
11143                 //              It passes the error and the dojo.Deferred
11144                 //              for the request with the topic.
11145                 // done: String
11146                 //              "/dojo/io/done" is sent whenever an IO request has completed,
11147                 //              either by loading or by erroring. It passes the error and
11148                 //              the dojo.Deferred for the request with the topic.
11149                 // stop: String
11150                 //              "/dojo/io/stop" is sent when all outstanding IO requests have
11151                 //              finished. No arguments are passed with this topic.
11152         });
11153         =====*/
11154
11155
11156         dojo._ioSetArgs = function(/*dojo/main.__IoArgs*/args,
11157                         /*Function*/canceller,
11158                         /*Function*/okHandler,
11159                         /*Function*/errHandler){
11160                 // summary:
11161                 //              sets up the Deferred and ioArgs property on the Deferred so it
11162                 //              can be used in an io call.
11163                 // args:
11164                 //              The args object passed into the public io call. Recognized properties on
11165                 //              the args object are:
11166                 // canceller:
11167                 //              The canceller function used for the Deferred object. The function
11168                 //              will receive one argument, the Deferred object that is related to the
11169                 //              canceller.
11170                 // okHandler:
11171                 //              The first OK callback to be registered with Deferred. It has the opportunity
11172                 //              to transform the OK response. It will receive one argument -- the Deferred
11173                 //              object returned from this function.
11174                 // errHandler:
11175                 //              The first error callback to be registered with Deferred. It has the opportunity
11176                 //              to do cleanup on an error. It will receive two arguments: error (the
11177                 //              Error object) and dfd, the Deferred object returned from this function.
11178
11179                 var ioArgs = {args: args, url: args.url};
11180
11181                 //Get values from form if requested.
11182                 var formObject = null;
11183                 if(args.form){
11184                         var form = dom.byId(args.form);
11185                         //IE requires going through getAttributeNode instead of just getAttribute in some form cases,
11186                         //so use it for all. See #2844
11187                         var actnNode = form.getAttributeNode("action");
11188                         ioArgs.url = ioArgs.url || (actnNode ? actnNode.value : null);
11189                         formObject = domForm.toObject(form);
11190                 }
11191
11192                 // set up the query params
11193                 var miArgs = [{}];
11194
11195                 if(formObject){
11196                         // potentially over-ride url-provided params w/ form values
11197                         miArgs.push(formObject);
11198                 }
11199                 if(args.content){
11200                         // stuff in content over-rides what's set by form
11201                         miArgs.push(args.content);
11202                 }
11203                 if(args.preventCache){
11204                         miArgs.push({"dojo.preventCache": new Date().valueOf()});
11205                 }
11206                 ioArgs.query = ioq.objectToQuery(lang.mixin.apply(null, miArgs));
11207
11208                 // .. and the real work of getting the deferred in order, etc.
11209                 ioArgs.handleAs = args.handleAs || "text";
11210                 var d = new Deferred(function(dfd){
11211                         dfd.canceled = true;
11212                         canceller && canceller(dfd);
11213
11214                         var err = dfd.ioArgs.error;
11215                         if(!err){
11216                                 err = new Error("request cancelled");
11217                                 err.dojoType="cancel";
11218                                 dfd.ioArgs.error = err;
11219                         }
11220                         return err;
11221                 });
11222                 d.addCallback(okHandler);
11223
11224                 //Support specifying load, error and handle callback functions from the args.
11225                 //For those callbacks, the "this" object will be the args object.
11226                 //The callbacks will get the deferred result value as the
11227                 //first argument and the ioArgs object as the second argument.
11228                 var ld = args.load;
11229                 if(ld && lang.isFunction(ld)){
11230                         d.addCallback(function(value){
11231                                 return ld.call(args, value, ioArgs);
11232                         });
11233                 }
11234                 var err = args.error;
11235                 if(err && lang.isFunction(err)){
11236                         d.addErrback(function(value){
11237                                 return err.call(args, value, ioArgs);
11238                         });
11239                 }
11240                 var handle = args.handle;
11241                 if(handle && lang.isFunction(handle)){
11242                         d.addBoth(function(value){
11243                                 return handle.call(args, value, ioArgs);
11244                         });
11245                 }
11246
11247                 // Attach error handler last (not including topic publishing)
11248                 // to catch any errors that may have been generated from load
11249                 // or handle functions.
11250                 d.addErrback(function(error){
11251                         return errHandler(error, d);
11252                 });
11253
11254                 //Plug in topic publishing, if dojo.publish is loaded.
11255                 if(cfg.ioPublish && dojo.publish && ioArgs.args.ioPublish !== false){
11256                         d.addCallbacks(
11257                                 function(res){
11258                                         dojo.publish("/dojo/io/load", [d, res]);
11259                                         return res;
11260                                 },
11261                                 function(res){
11262                                         dojo.publish("/dojo/io/error", [d, res]);
11263                                         return res;
11264                                 }
11265                         );
11266                         d.addBoth(function(res){
11267                                 dojo.publish("/dojo/io/done", [d, res]);
11268                                 return res;
11269                         });
11270                 }
11271
11272                 d.ioArgs = ioArgs;
11273
11274                 // FIXME: need to wire up the xhr object's abort method to something
11275                 // analogous in the Deferred
11276                 return d;
11277         };
11278
11279         var _deferredOk = function(/*Deferred*/dfd){
11280                 // summary:
11281                 //              okHandler function for dojo._ioSetArgs call.
11282
11283                 var ret = handlers[dfd.ioArgs.handleAs](dfd.ioArgs.xhr);
11284                 return ret === undefined ? null : ret;
11285         };
11286         var _deferError = function(/*Error*/error, /*Deferred*/dfd){
11287                 // summary:
11288                 //              errHandler function for dojo._ioSetArgs call.
11289
11290                 if(!dfd.ioArgs.args.failOk){
11291                         console.error(error);
11292                 }
11293                 return error;
11294         };
11295
11296         //Use a separate count for knowing if we are starting/stopping io calls.
11297         var _checkPubCount = function(dfd){
11298                 if(_pubCount <= 0){
11299                         _pubCount = 0;
11300                         if(cfg.ioPublish && dojo.publish && (!dfd || dfd && dfd.ioArgs.args.ioPublish !== false)){
11301                                 dojo.publish("/dojo/io/stop");
11302                         }
11303                 }
11304         };
11305
11306         var _pubCount = 0;
11307         aspect.after(watch, "_onAction", function(){
11308                 _pubCount -= 1;
11309         });
11310         aspect.after(watch, "_onInFlight", _checkPubCount);
11311
11312         dojo._ioCancelAll = watch.cancelAll;
11313         /*=====
11314         dojo._ioCancelAll = function(){
11315                 // summary:
11316                 //              Cancels all pending IO requests, regardless of IO type
11317                 //              (xhr, script, iframe).
11318         };
11319         =====*/
11320
11321         dojo._ioNotifyStart = function(/*Deferred*/dfd){
11322                 // summary:
11323                 //              If dojo.publish is available, publish topics
11324                 //              about the start of a request queue and/or the
11325                 //              the beginning of request.
11326                 //
11327                 //              Used by IO transports. An IO transport should
11328                 //              call this method before making the network connection.
11329                 if(cfg.ioPublish && dojo.publish && dfd.ioArgs.args.ioPublish !== false){
11330                         if(!_pubCount){
11331                                 dojo.publish("/dojo/io/start");
11332                         }
11333                         _pubCount += 1;
11334                         dojo.publish("/dojo/io/send", [dfd]);
11335                 }
11336         };
11337
11338         dojo._ioWatch = function(dfd, validCheck, ioCheck, resHandle){
11339                 // summary:
11340                 //              Watches the io request represented by dfd to see if it completes.
11341                 // dfd: Deferred
11342                 //              The Deferred object to watch.
11343                 // validCheck: Function
11344                 //              Function used to check if the IO request is still valid. Gets the dfd
11345                 //              object as its only argument.
11346                 // ioCheck: Function
11347                 //              Function used to check if basic IO call worked. Gets the dfd
11348                 //              object as its only argument.
11349                 // resHandle: Function
11350                 //              Function used to process response. Gets the dfd
11351                 //              object as its only argument.
11352
11353                 var args = dfd.ioArgs.options = dfd.ioArgs.args;
11354                 lang.mixin(dfd, {
11355                         response: dfd.ioArgs,
11356                         isValid: function(response){
11357                                 return validCheck(dfd);
11358                         },
11359                         isReady: function(response){
11360                                 return ioCheck(dfd);
11361                         },
11362                         handleResponse: function(response){
11363                                 return resHandle(dfd);
11364                         }
11365                 });
11366                 watch(dfd);
11367
11368                 _checkPubCount(dfd);
11369         };
11370
11371         var _defaultContentType = "application/x-www-form-urlencoded";
11372
11373         dojo._ioAddQueryToUrl = function(/*dojo.__IoCallbackArgs*/ioArgs){
11374                 // summary:
11375                 //              Adds query params discovered by the io deferred construction to the URL.
11376                 //              Only use this for operations which are fundamentally GET-type operations.
11377                 if(ioArgs.query.length){
11378                         ioArgs.url += (ioArgs.url.indexOf("?") == -1 ? "?" : "&") + ioArgs.query;
11379                         ioArgs.query = null;
11380                 }
11381         };
11382
11383         /*=====
11384         dojo.__XhrArgs = declare(dojo.__IoArgs, {
11385                 // summary:
11386                 //              In addition to the properties listed for the dojo._IoArgs type,
11387                 //              the following properties are allowed for dojo.xhr* methods.
11388                 // handleAs: String?
11389                 //              Acceptable values are: text (default), json, json-comment-optional,
11390                 //              json-comment-filtered, javascript, xml. See `dojo/_base/xhr.contentHandlers`
11391                 // sync: Boolean?
11392                 //              false is default. Indicates whether the request should
11393                 //              be a synchronous (blocking) request.
11394                 // headers: Object?
11395                 //              Additional HTTP headers to send in the request.
11396                 // failOk: Boolean?
11397                 //              false is default. Indicates whether a request should be
11398                 //              allowed to fail (and therefore no console error message in
11399                 //              the event of a failure)
11400                 // contentType: String|Boolean
11401                 //              "application/x-www-form-urlencoded" is default. Set to false to
11402                 //              prevent a Content-Type header from being sent, or to a string
11403                 //              to send a different Content-Type.
11404          });
11405         =====*/
11406
11407         dojo.xhr = function(/*String*/ method, /*dojo.__XhrArgs*/ args, /*Boolean?*/ hasBody){
11408                 // summary:
11409                 //              Deprecated.   Use dojo/request instead.
11410                 // description:
11411                 //              Sends an HTTP request with the given method.
11412                 //              See also dojo.xhrGet(), xhrPost(), xhrPut() and dojo.xhrDelete() for shortcuts
11413                 //              for those HTTP methods. There are also methods for "raw" PUT and POST methods
11414                 //              via dojo.rawXhrPut() and dojo.rawXhrPost() respectively.
11415                 // method:
11416                 //              HTTP method to be used, such as GET, POST, PUT, DELETE. Should be uppercase.
11417                 // hasBody:
11418                 //              If the request has an HTTP body, then pass true for hasBody.
11419
11420                 var rDfd;
11421                 //Make the Deferred object for this xhr request.
11422                 var dfd = dojo._ioSetArgs(args, function(dfd){
11423                         rDfd && rDfd.cancel();
11424                 }, _deferredOk, _deferError);
11425                 var ioArgs = dfd.ioArgs;
11426
11427                 //Allow for specifying the HTTP body completely.
11428                 if("postData" in args){
11429                         ioArgs.query = args.postData;
11430                 }else if("putData" in args){
11431                         ioArgs.query = args.putData;
11432                 }else if("rawBody" in args){
11433                         ioArgs.query = args.rawBody;
11434                 }else if((arguments.length > 2 && !hasBody) || "POST|PUT".indexOf(method.toUpperCase()) === -1){
11435                         //Check for hasBody being passed. If no hasBody,
11436                         //then only append query string if not a POST or PUT request.
11437                         dojo._ioAddQueryToUrl(ioArgs);
11438                 }
11439
11440                 var options = {
11441                         method: method,
11442                         handleAs: "text",
11443                         timeout: args.timeout,
11444                         withCredentials: args.withCredentials,
11445                         ioArgs: ioArgs
11446                 };
11447
11448                 if(typeof args.headers !== 'undefined'){
11449                         options.headers = args.headers;
11450                 }
11451                 if(typeof args.contentType !== 'undefined'){
11452                         if(!options.headers){
11453                                 options.headers = {};
11454                         }
11455                         options.headers['Content-Type'] = args.contentType;
11456                 }
11457                 if(typeof ioArgs.query !== 'undefined'){
11458                         options.data = ioArgs.query;
11459                 }
11460                 if(typeof args.sync !== 'undefined'){
11461                         options.sync = args.sync;
11462                 }
11463
11464                 dojo._ioNotifyStart(dfd);
11465                 try{
11466                         rDfd = _xhr(ioArgs.url, options, true);
11467                 }catch(e){
11468                         // If XHR creation fails, dojo/request/xhr throws
11469                         // When this happens, cancel the deferred
11470                         dfd.cancel();
11471                         return dfd;
11472                 }
11473
11474                 // sync ioArgs
11475                 dfd.ioArgs.xhr = rDfd.response.xhr;
11476
11477                 rDfd.then(function(){
11478                         dfd.resolve(dfd);
11479                 }).otherwise(function(error){
11480                         ioArgs.error = error;
11481                         if(error.response){
11482                                 error.status = error.response.status;
11483                                 error.responseText = error.response.text;
11484                                 error.xhr = error.response.xhr;
11485                         }
11486                         dfd.reject(error);
11487                 });
11488                 return dfd; // dojo/_base/Deferred
11489         };
11490
11491         dojo.xhrGet = function(/*dojo.__XhrArgs*/ args){
11492                 // summary:
11493                 //              Sends an HTTP GET request to the server.
11494                 return dojo.xhr("GET", args); // dojo/_base/Deferred
11495         };
11496
11497         dojo.rawXhrPost = dojo.xhrPost = function(/*dojo.__XhrArgs*/ args){
11498                 // summary:
11499                 //              Sends an HTTP POST request to the server. In addition to the properties
11500                 //              listed for the dojo.__XhrArgs type, the following property is allowed:
11501                 // postData:
11502                 //              String. Send raw data in the body of the POST request.
11503                 return dojo.xhr("POST", args, true); // dojo/_base/Deferred
11504         };
11505
11506         dojo.rawXhrPut = dojo.xhrPut = function(/*dojo.__XhrArgs*/ args){
11507                 // summary:
11508                 //              Sends an HTTP PUT request to the server. In addition to the properties
11509                 //              listed for the dojo.__XhrArgs type, the following property is allowed:
11510                 // putData:
11511                 //              String. Send raw data in the body of the PUT request.
11512                 return dojo.xhr("PUT", args, true); // dojo/_base/Deferred
11513         };
11514
11515         dojo.xhrDelete = function(/*dojo.__XhrArgs*/ args){
11516                 // summary:
11517                 //              Sends an HTTP DELETE request to the server.
11518                 return dojo.xhr("DELETE", args); // dojo/_base/Deferred
11519         };
11520
11521         /*
11522         dojo.wrapForm = function(formNode){
11523                 // summary:
11524                 //              A replacement for FormBind, but not implemented yet.
11525
11526                 // FIXME: need to think harder about what extensions to this we might
11527                 // want. What should we allow folks to do w/ this? What events to
11528                 // set/send?
11529                 throw new Error("dojo.wrapForm not yet implemented");
11530         }
11531         */
11532
11533         dojo._isDocumentOk = function(x){
11534                 return util.checkStatus(x.status);
11535         };
11536
11537         dojo._getText = function(url){
11538                 var result;
11539                 dojo.xhrGet({url:url, sync:true, load:function(text){
11540                         result = text;
11541                 }});
11542                 return result;
11543         };
11544
11545         // Add aliases for static functions to dojo.xhr since dojo.xhr is what's returned from this module
11546         lang.mixin(dojo.xhr, {
11547                 _xhrObj: dojo._xhrObj,
11548                 fieldToObject: domForm.fieldToObject,
11549                 formToObject: domForm.toObject,
11550                 objectToQuery: ioq.objectToQuery,
11551                 formToQuery: domForm.toQuery,
11552                 formToJson: domForm.toJson,
11553                 queryToObject: ioq.queryToObject,
11554                 contentHandlers: handlers,
11555                 _ioSetArgs: dojo._ioSetArgs,
11556                 _ioCancelAll: dojo._ioCancelAll,
11557                 _ioNotifyStart: dojo._ioNotifyStart,
11558                 _ioWatch: dojo._ioWatch,
11559                 _ioAddQueryToUrl: dojo._ioAddQueryToUrl,
11560                 _isDocumentOk: dojo._isDocumentOk,
11561                 _getText: dojo._getText,
11562                 get: dojo.xhrGet,
11563                 post: dojo.xhrPost,
11564                 put: dojo.xhrPut,
11565                 del: dojo.xhrDelete     // because "delete" is a reserved word
11566         });
11567
11568         return dojo.xhr;
11569 });
11570
11571 },
11572 'dojo/_base/unload':function(){
11573 define(["./kernel", "./lang", "../on"], function(dojo, lang, on){
11574
11575 // module:
11576 //              dojo/unload
11577
11578 var win = window;
11579
11580 var unload = {
11581         // summary:
11582         //              This module contains the document and window unload detection API.
11583
11584         addOnWindowUnload: function(/*Object|Function?*/ obj, /*String|Function?*/ functionName){
11585                 // summary:
11586                 //              registers a function to be triggered when window.onunload
11587                 //              fires.
11588                 // description:
11589                 //              The first time that addOnWindowUnload is called Dojo
11590                 //              will register a page listener to trigger your unload
11591                 //              handler with. Note that registering these handlers may
11592                 //              destroy "fastback" page caching in browsers that support
11593                 //              it. Be careful trying to modify the DOM or access
11594                 //              JavaScript properties during this phase of page unloading:
11595                 //              they may not always be available. Consider
11596                 //              addOnUnload() if you need to modify the DOM or do
11597                 //              heavy JavaScript work since it fires at the equivalent of
11598                 //              the page's "onbeforeunload" event.
11599                 // example:
11600                 //      |       unload.addOnWindowUnload(functionPointer)
11601                 //      |       unload.addOnWindowUnload(object, "functionName");
11602                 //      |       unload.addOnWindowUnload(object, function(){ /* ... */});
11603
11604                 if (!dojo.windowUnloaded){
11605                         on(win, "unload", (dojo.windowUnloaded = function(){
11606                                 // summary:
11607                                 //              signal fired by impending window destruction. You may use
11608                                 //              dojo.addOnWindowUnload() to register a listener for this
11609                                 //              event. NOTE: if you wish to dojo.connect() to this method
11610                                 //              to perform page/application cleanup, be aware that this
11611                                 //              event WILL NOT fire if no handler has been registered with
11612                                 //              addOnWindowUnload(). This behavior started in Dojo 1.3.
11613                                 //              Previous versions always triggered windowUnloaded(). See
11614                                 //              addOnWindowUnload for more info.
11615                         }));
11616                 }
11617                 on(win, "unload", lang.hitch(obj, functionName));
11618         },
11619
11620         addOnUnload: function(/*Object?|Function?*/ obj, /*String|Function?*/ functionName){
11621                 // summary:
11622                 //              registers a function to be triggered when the page unloads.
11623                 // description:
11624                 //              The first time that addOnUnload is called Dojo will
11625                 //              register a page listener to trigger your unload handler
11626                 //              with.
11627                 //
11628                 //              In a browser environment, the functions will be triggered
11629                 //              during the window.onbeforeunload event. Be careful of doing
11630                 //              too much work in an unload handler. onbeforeunload can be
11631                 //              triggered if a link to download a file is clicked, or if
11632                 //              the link is a javascript: link. In these cases, the
11633                 //              onbeforeunload event fires, but the document is not
11634                 //              actually destroyed. So be careful about doing destructive
11635                 //              operations in a dojo.addOnUnload callback.
11636                 //
11637                 //              Further note that calling dojo.addOnUnload will prevent
11638                 //              browsers from using a "fast back" cache to make page
11639                 //              loading via back button instantaneous.
11640                 // example:
11641                 //      |       dojo.addOnUnload(functionPointer)
11642                 //      |       dojo.addOnUnload(object, "functionName")
11643                 //      |       dojo.addOnUnload(object, function(){ /* ... */});
11644
11645                 on(win, "beforeunload", lang.hitch(obj, functionName));
11646         }
11647 };
11648
11649 dojo.addOnWindowUnload = unload.addOnWindowUnload;
11650 dojo.addOnUnload = unload.addOnUnload;
11651
11652 return unload;
11653
11654 });
11655
11656 },
11657 'dojo/Deferred':function(){
11658 define([
11659         "./has",
11660         "./_base/lang",
11661         "./errors/CancelError",
11662         "./promise/Promise",
11663         "./promise/instrumentation"
11664 ], function(has, lang, CancelError, Promise, instrumentation){
11665         "use strict";
11666
11667         // module:
11668         //              dojo/Deferred
11669
11670         var PROGRESS = 0,
11671                         RESOLVED = 1,
11672                         REJECTED = 2;
11673         var FULFILLED_ERROR_MESSAGE = "This deferred has already been fulfilled.";
11674
11675         var freezeObject = Object.freeze || function(){};
11676
11677         var signalWaiting = function(waiting, type, result, rejection, deferred){
11678                 if( 1 ){
11679                         if(type === REJECTED && Deferred.instrumentRejected && waiting.length === 0){
11680                                 Deferred.instrumentRejected(result, false, rejection, deferred);
11681                         }
11682                 }
11683
11684                 for(var i = 0; i < waiting.length; i++){
11685                         signalListener(waiting[i], type, result, rejection);
11686                 }
11687         };
11688
11689         var signalListener = function(listener, type, result, rejection){
11690                 var func = listener[type];
11691                 var deferred = listener.deferred;
11692                 if(func){
11693                         try{
11694                                 var newResult = func(result);
11695                                 if(type === PROGRESS){
11696                                         if(typeof newResult !== "undefined"){
11697                                                 signalDeferred(deferred, type, newResult);
11698                                         }
11699                                 }else{
11700                                         if(newResult && typeof newResult.then === "function"){
11701                                                 listener.cancel = newResult.cancel;
11702                                                 newResult.then(
11703                                                                 // Only make resolvers if they're actually going to be used
11704                                                                 makeDeferredSignaler(deferred, RESOLVED),
11705                                                                 makeDeferredSignaler(deferred, REJECTED),
11706                                                                 makeDeferredSignaler(deferred, PROGRESS));
11707                                                 return;
11708                                         }
11709                                         signalDeferred(deferred, RESOLVED, newResult);
11710                                 }
11711                         }catch(error){
11712                                 signalDeferred(deferred, REJECTED, error);
11713                         }
11714                 }else{
11715                         signalDeferred(deferred, type, result);
11716                 }
11717
11718                 if( 1 ){
11719                         if(type === REJECTED && Deferred.instrumentRejected){
11720                                 Deferred.instrumentRejected(result, !!func, rejection, deferred.promise);
11721                         }
11722                 }
11723         };
11724
11725         var makeDeferredSignaler = function(deferred, type){
11726                 return function(value){
11727                         signalDeferred(deferred, type, value);
11728                 };
11729         };
11730
11731         var signalDeferred = function(deferred, type, result){
11732                 if(!deferred.isCanceled()){
11733                         switch(type){
11734                                 case PROGRESS:
11735                                         deferred.progress(result);
11736                                         break;
11737                                 case RESOLVED:
11738                                         deferred.resolve(result);
11739                                         break;
11740                                 case REJECTED:
11741                                         deferred.reject(result);
11742                                         break;
11743                         }
11744                 }
11745         };
11746
11747         var Deferred = function(canceler){
11748                 // summary:
11749                 //              Creates a new deferred. This API is preferred over
11750                 //              `dojo/_base/Deferred`.
11751                 // description:
11752                 //              Creates a new deferred, as an abstraction over (primarily)
11753                 //              asynchronous operations. The deferred is the private interface
11754                 //              that should not be returned to calling code. That's what the
11755                 //              `promise` is for. See `dojo/promise/Promise`.
11756                 // canceler: Function?
11757                 //              Will be invoked if the deferred is canceled. The canceler
11758                 //              receives the reason the deferred was canceled as its argument.
11759                 //              The deferred is rejected with its return value, or a new
11760                 //              `dojo/errors/CancelError` instance.
11761
11762                 // promise: dojo/promise/Promise
11763                 //              The public promise object that clients can add callbacks to. 
11764                 var promise = this.promise = new Promise();
11765
11766                 var deferred = this;
11767                 var fulfilled, result, rejection;
11768                 var canceled = false;
11769                 var waiting = [];
11770
11771                 if( 1  && Error.captureStackTrace){
11772                         Error.captureStackTrace(deferred, Deferred);
11773                         Error.captureStackTrace(promise, Deferred);
11774                 }
11775
11776                 this.isResolved = promise.isResolved = function(){
11777                         // summary:
11778                         //              Checks whether the deferred has been resolved.
11779                         // returns: Boolean
11780
11781                         return fulfilled === RESOLVED;
11782                 };
11783
11784                 this.isRejected = promise.isRejected = function(){
11785                         // summary:
11786                         //              Checks whether the deferred has been rejected.
11787                         // returns: Boolean
11788
11789                         return fulfilled === REJECTED;
11790                 };
11791
11792                 this.isFulfilled = promise.isFulfilled = function(){
11793                         // summary:
11794                         //              Checks whether the deferred has been resolved or rejected.
11795                         // returns: Boolean
11796
11797                         return !!fulfilled;
11798                 };
11799
11800                 this.isCanceled = promise.isCanceled = function(){
11801                         // summary:
11802                         //              Checks whether the deferred has been canceled.
11803                         // returns: Boolean
11804
11805                         return canceled;
11806                 };
11807
11808                 this.progress = function(update, strict){
11809                         // summary:
11810                         //              Emit a progress update on the deferred.
11811                         // description:
11812                         //              Emit a progress update on the deferred. Progress updates
11813                         //              can be used to communicate updates about the asynchronous
11814                         //              operation before it has finished.
11815                         // update: any
11816                         //              The progress update. Passed to progbacks.
11817                         // strict: Boolean?
11818                         //              If strict, will throw an error if the deferred has already
11819                         //              been fulfilled and consequently no progress can be emitted.
11820                         // returns: dojo/promise/Promise
11821                         //              Returns the original promise for the deferred.
11822
11823                         if(!fulfilled){
11824                                 signalWaiting(waiting, PROGRESS, update, null, deferred);
11825                                 return promise;
11826                         }else if(strict === true){
11827                                 throw new Error(FULFILLED_ERROR_MESSAGE);
11828                         }else{
11829                                 return promise;
11830                         }
11831                 };
11832
11833                 this.resolve = function(value, strict){
11834                         // summary:
11835                         //              Resolve the deferred.
11836                         // description:
11837                         //              Resolve the deferred, putting it in a success state.
11838                         // value: any
11839                         //              The result of the deferred. Passed to callbacks.
11840                         // strict: Boolean?
11841                         //              If strict, will throw an error if the deferred has already
11842                         //              been fulfilled and consequently cannot be resolved.
11843                         // returns: dojo/promise/Promise
11844                         //              Returns the original promise for the deferred.
11845
11846                         if(!fulfilled){
11847                                 // Set fulfilled, store value. After signaling waiting listeners unset
11848                                 // waiting.
11849                                 signalWaiting(waiting, fulfilled = RESOLVED, result = value, null, deferred);
11850                                 waiting = null;
11851                                 return promise;
11852                         }else if(strict === true){
11853                                 throw new Error(FULFILLED_ERROR_MESSAGE);
11854                         }else{
11855                                 return promise;
11856                         }
11857                 };
11858
11859                 var reject = this.reject = function(error, strict){
11860                         // summary:
11861                         //              Reject the deferred.
11862                         // description:
11863                         //              Reject the deferred, putting it in an error state.
11864                         // error: any
11865                         //              The error result of the deferred. Passed to errbacks.
11866                         // strict: Boolean?
11867                         //              If strict, will throw an error if the deferred has already
11868                         //              been fulfilled and consequently cannot be rejected.
11869                         // returns: dojo/promise/Promise
11870                         //              Returns the original promise for the deferred.
11871
11872                         if(!fulfilled){
11873                                 if( 1  && Error.captureStackTrace){
11874                                         Error.captureStackTrace(rejection = {}, reject);
11875                                 }
11876                                 signalWaiting(waiting, fulfilled = REJECTED, result = error, rejection, deferred);
11877                                 waiting = null;
11878                                 return promise;
11879                         }else if(strict === true){
11880                                 throw new Error(FULFILLED_ERROR_MESSAGE);
11881                         }else{
11882                                 return promise;
11883                         }
11884                 };
11885
11886                 this.then = promise.then = function(callback, errback, progback){
11887                         // summary:
11888                         //              Add new callbacks to the deferred.
11889                         // description:
11890                         //              Add new callbacks to the deferred. Callbacks can be added
11891                         //              before or after the deferred is fulfilled.
11892                         // callback: Function?
11893                         //              Callback to be invoked when the promise is resolved.
11894                         //              Receives the resolution value.
11895                         // errback: Function?
11896                         //              Callback to be invoked when the promise is rejected.
11897                         //              Receives the rejection error.
11898                         // progback: Function?
11899                         //              Callback to be invoked when the promise emits a progress
11900                         //              update. Receives the progress update.
11901                         // returns: dojo/promise/Promise
11902                         //              Returns a new promise for the result of the callback(s).
11903                         //              This can be used for chaining many asynchronous operations.
11904
11905                         var listener = [progback, callback, errback];
11906                         // Ensure we cancel the promise we're waiting for, or if callback/errback
11907                         // have returned a promise, cancel that one.
11908                         listener.cancel = promise.cancel;
11909                         listener.deferred = new Deferred(function(reason){
11910                                 // Check whether cancel is really available, returned promises are not
11911                                 // required to expose `cancel`
11912                                 return listener.cancel && listener.cancel(reason);
11913                         });
11914                         if(fulfilled && !waiting){
11915                                 signalListener(listener, fulfilled, result, rejection);
11916                         }else{
11917                                 waiting.push(listener);
11918                         }
11919                         return listener.deferred.promise;
11920                 };
11921
11922                 this.cancel = promise.cancel = function(reason, strict){
11923                         // summary:
11924                         //              Inform the deferred it may cancel its asynchronous operation.
11925                         // description:
11926                         //              Inform the deferred it may cancel its asynchronous operation.
11927                         //              The deferred's (optional) canceler is invoked and the
11928                         //              deferred will be left in a rejected state. Can affect other
11929                         //              promises that originate with the same deferred.
11930                         // reason: any
11931                         //              A message that may be sent to the deferred's canceler,
11932                         //              explaining why it's being canceled.
11933                         // strict: Boolean?
11934                         //              If strict, will throw an error if the deferred has already
11935                         //              been fulfilled and consequently cannot be canceled.
11936                         // returns: any
11937                         //              Returns the rejection reason if the deferred was canceled
11938                         //              normally.
11939
11940                         if(!fulfilled){
11941                                 // Cancel can be called even after the deferred is fulfilled
11942                                 if(canceler){
11943                                         var returnedReason = canceler(reason);
11944                                         reason = typeof returnedReason === "undefined" ? reason : returnedReason;
11945                                 }
11946                                 canceled = true;
11947                                 if(!fulfilled){
11948                                         // Allow canceler to provide its own reason, but fall back to a CancelError
11949                                         if(typeof reason === "undefined"){
11950                                                 reason = new CancelError();
11951                                         }
11952                                         reject(reason);
11953                                         return reason;
11954                                 }else if(fulfilled === REJECTED && result === reason){
11955                                         return reason;
11956                                 }
11957                         }else if(strict === true){
11958                                 throw new Error(FULFILLED_ERROR_MESSAGE);
11959                         }
11960                 };
11961
11962                 freezeObject(promise);
11963         };
11964
11965         Deferred.prototype.toString = function(){
11966                 // returns: String
11967                 //              Returns `[object Deferred]`.
11968
11969                 return "[object Deferred]";
11970         };
11971
11972         if(instrumentation){
11973                 instrumentation(Deferred);
11974         }
11975
11976         return Deferred;
11977 });
11978
11979 },
11980 'dojo/_base/NodeList':function(){
11981 define("dojo/_base/NodeList", ["./kernel", "../query", "./array", "./html", "../NodeList-dom"], function(dojo, query, array){
11982         // module:
11983         //              dojo/_base/NodeList
11984
11985         /*=====
11986         return {
11987                 // summary:
11988                 //              This module extends dojo/NodeList with the legacy connect(), coords(),
11989                 //              blur(), focus(), change(), click(), error(), keydown(), keypress(),
11990                 //              keyup(), load(), mousedown(), mouseenter(), mouseleave(), mousemove(),
11991                 //              mouseout(), mouseover(), mouseup(), and submit() methods.
11992         };
11993         =====*/
11994  
11995         var NodeList = query.NodeList,
11996                 nlp = NodeList.prototype;
11997
11998         nlp.connect = NodeList._adaptAsForEach(function(){
11999                 // don't bind early to dojo.connect since we no longer explicitly depend on it
12000                 return dojo.connect.apply(this, arguments);
12001         });
12002         /*=====
12003         nlp.connect = function(methodName, objOrFunc, funcName){
12004                 // summary:
12005                 //              Attach event handlers to every item of the NodeList. Uses dojo.connect()
12006                 //              so event properties are normalized.
12007                 //
12008                 //              Application must manually require() "dojo/_base/connect" before using this method.
12009                 // methodName: String
12010                 //              the name of the method to attach to. For DOM events, this should be
12011                 //              the lower-case name of the event
12012                 // objOrFunc: Object|Function|String
12013                 //              if 2 arguments are passed (methodName, objOrFunc), objOrFunc should
12014                 //              reference a function or be the name of the function in the global
12015                 //              namespace to attach. If 3 arguments are provided
12016                 //              (methodName, objOrFunc, funcName), objOrFunc must be the scope to
12017                 //              locate the bound function in
12018                 // funcName: String?
12019                 //              optional. A string naming the function in objOrFunc to bind to the
12020                 //              event. May also be a function reference.
12021                 // example:
12022                 //              add an onclick handler to every button on the page
12023                 //              |       query("div:nth-child(odd)").connect("onclick", function(e){
12024                 //              |               console.log("clicked!");
12025                 //              |       });
12026                 // example:
12027                 //              attach foo.bar() to every odd div's onmouseover
12028                 //              |       query("div:nth-child(odd)").connect("onmouseover", foo, "bar");
12029
12030                 return null;    // NodeList
12031         };
12032         =====*/
12033
12034         nlp.coords = NodeList._adaptAsMap(dojo.coords);
12035         /*=====
12036         nlp.coords = function(){
12037                 // summary:
12038                 //              Deprecated: Use position() for border-box x/y/w/h
12039                 //              or marginBox() for margin-box w/h/l/t.
12040                 //              Returns the box objects of all elements in a node list as
12041                 //              an Array (*not* a NodeList). Acts like `domGeom.coords`, though assumes
12042                 //              the node passed is each node in this list.
12043
12044                 return []; // Array
12045         };
12046         =====*/
12047
12048         NodeList.events = [
12049                 // summary:
12050                 //              list of all DOM events used in NodeList
12051                 "blur", "focus", "change", "click", "error", "keydown", "keypress",
12052                 "keyup", "load", "mousedown", "mouseenter", "mouseleave", "mousemove",
12053                 "mouseout", "mouseover", "mouseup", "submit"
12054         ];
12055
12056         // FIXME: pseudo-doc the above automatically generated on-event functions
12057
12058         // syntactic sugar for DOM events
12059         array.forEach(NodeList.events, function(evt){
12060                         var _oe = "on" + evt;
12061                         nlp[_oe] = function(a, b){
12062                                 return this.connect(_oe, a, b);
12063                         };
12064                                 // FIXME: should these events trigger publishes?
12065                                 /*
12066                                 return (a ? this.connect(_oe, a, b) :
12067                                                         this.forEach(function(n){
12068                                                                 // FIXME:
12069                                                                 //              listeners get buried by
12070                                                                 //              addEventListener and can't be dug back
12071                                                                 //              out to be triggered externally.
12072                                                                 // see:
12073                                                                 //              http://developer.mozilla.org/en/docs/DOM:element
12074
12075                                                                 console.log(n, evt, _oe);
12076
12077                                                                 // FIXME: need synthetic event support!
12078                                                                 var _e = { target: n, faux: true, type: evt };
12079                                                                 // dojo._event_listener._synthesizeEvent({}, { target: n, faux: true, type: evt });
12080                                                                 try{ n[evt](_e); }catch(e){ console.log(e); }
12081                                                                 try{ n[_oe](_e); }catch(e){ console.log(e); }
12082                                                         })
12083                                 );
12084                                 */
12085                 }
12086         );
12087
12088         dojo.NodeList = NodeList;
12089         return NodeList;
12090 });
12091
12092 },
12093 'dojo/_base/Color':function(){
12094 define(["./kernel", "./lang", "./array", "./config"], function(dojo, lang, ArrayUtil, config){
12095
12096         var Color = dojo.Color = function(/*Array|String|Object*/ color){
12097                 // summary:
12098                 //              Takes a named string, hex string, array of rgb or rgba values,
12099                 //              an object with r, g, b, and a properties, or another `Color` object
12100                 //              and creates a new Color instance to work from.
12101                 //
12102                 // example:
12103                 //              Work with a Color instance:
12104                 //       | var c = new Color();
12105                 //       | c.setColor([0,0,0]); // black
12106                 //       | var hex = c.toHex(); // #000000
12107                 //
12108                 // example:
12109                 //              Work with a node's color:
12110                 //       | var color = dojo.style("someNode", "backgroundColor");
12111                 //       | var n = new Color(color);
12112                 //       | // adjust the color some
12113                 //       | n.r *= .5;
12114                 //       | console.log(n.toString()); // rgb(128, 255, 255);
12115                 if(color){ this.setColor(color); }
12116         };
12117
12118         // FIXME:
12119         // there's got to be a more space-efficient way to encode or discover
12120         // these!! Use hex?
12121         Color.named = {
12122                 // summary:
12123                 //              Dictionary list of all CSS named colors, by name. Values are 3-item arrays with corresponding RG and B values.
12124                 "black":  [0,0,0],
12125                 "silver": [192,192,192],
12126                 "gray":   [128,128,128],
12127                 "white":  [255,255,255],
12128                 "maroon": [128,0,0],
12129                 "red":    [255,0,0],
12130                 "purple": [128,0,128],
12131                 "fuchsia":[255,0,255],
12132                 "green":  [0,128,0],
12133                 "lime":   [0,255,0],
12134                 "olive":  [128,128,0],
12135                 "yellow": [255,255,0],
12136                 "navy":   [0,0,128],
12137                 "blue":   [0,0,255],
12138                 "teal":   [0,128,128],
12139                 "aqua":   [0,255,255],
12140                 "transparent": config.transparentColor || [0,0,0,0]
12141         };
12142
12143         lang.extend(Color, {
12144                 r: 255, g: 255, b: 255, a: 1,
12145                 _set: function(r, g, b, a){
12146                         var t = this; t.r = r; t.g = g; t.b = b; t.a = a;
12147                 },
12148                 setColor: function(/*Array|String|Object*/ color){
12149                         // summary:
12150                         //              Takes a named string, hex string, array of rgb or rgba values,
12151                         //              an object with r, g, b, and a properties, or another `Color` object
12152                         //              and sets this color instance to that value.
12153                         //
12154                         // example:
12155                         //      |       var c = new Color(); // no color
12156                         //      |       c.setColor("#ededed"); // greyish
12157                         if(lang.isString(color)){
12158                                 Color.fromString(color, this);
12159                         }else if(lang.isArray(color)){
12160                                 Color.fromArray(color, this);
12161                         }else{
12162                                 this._set(color.r, color.g, color.b, color.a);
12163                                 if(!(color instanceof Color)){ this.sanitize(); }
12164                         }
12165                         return this;    // Color
12166                 },
12167                 sanitize: function(){
12168                         // summary:
12169                         //              Ensures the object has correct attributes
12170                         // description:
12171                         //              the default implementation does nothing, include dojo.colors to
12172                         //              augment it with real checks
12173                         return this;    // Color
12174                 },
12175                 toRgb: function(){
12176                         // summary:
12177                         //              Returns 3 component array of rgb values
12178                         // example:
12179                         //      |       var c = new Color("#000000");
12180                         //      |       console.log(c.toRgb()); // [0,0,0]
12181                         var t = this;
12182                         return [t.r, t.g, t.b]; // Array
12183                 },
12184                 toRgba: function(){
12185                         // summary:
12186                         //              Returns a 4 component array of rgba values from the color
12187                         //              represented by this object.
12188                         var t = this;
12189                         return [t.r, t.g, t.b, t.a];    // Array
12190                 },
12191                 toHex: function(){
12192                         // summary:
12193                         //              Returns a CSS color string in hexadecimal representation
12194                         // example:
12195                         //      |       console.log(new Color([0,0,0]).toHex()); // #000000
12196                         var arr = ArrayUtil.map(["r", "g", "b"], function(x){
12197                                 var s = this[x].toString(16);
12198                                 return s.length < 2 ? "0" + s : s;
12199                         }, this);
12200                         return "#" + arr.join("");      // String
12201                 },
12202                 toCss: function(/*Boolean?*/ includeAlpha){
12203                         // summary:
12204                         //              Returns a css color string in rgb(a) representation
12205                         // example:
12206                         //      |       var c = new Color("#FFF").toCss();
12207                         //      |       console.log(c); // rgb('255','255','255')
12208                         var t = this, rgb = t.r + ", " + t.g + ", " + t.b;
12209                         return (includeAlpha ? "rgba(" + rgb + ", " + t.a : "rgb(" + rgb) + ")";        // String
12210                 },
12211                 toString: function(){
12212                         // summary:
12213                         //              Returns a visual representation of the color
12214                         return this.toCss(true); // String
12215                 }
12216         });
12217
12218         Color.blendColors = dojo.blendColors = function(
12219                 /*Color*/ start,
12220                 /*Color*/ end,
12221                 /*Number*/ weight,
12222                 /*Color?*/ obj
12223         ){
12224                 // summary:
12225                 //              Blend colors end and start with weight from 0 to 1, 0.5 being a 50/50 blend,
12226                 //              can reuse a previously allocated Color object for the result
12227                 var t = obj || new Color();
12228                 ArrayUtil.forEach(["r", "g", "b", "a"], function(x){
12229                         t[x] = start[x] + (end[x] - start[x]) * weight;
12230                         if(x != "a"){ t[x] = Math.round(t[x]); }
12231                 });
12232                 return t.sanitize();    // Color
12233         };
12234
12235         Color.fromRgb = dojo.colorFromRgb = function(/*String*/ color, /*Color?*/ obj){
12236                 // summary:
12237                 //              Returns a `Color` instance from a string of the form
12238                 //              "rgb(...)" or "rgba(...)". Optionally accepts a `Color`
12239                 //              object to update with the parsed value and return instead of
12240                 //              creating a new object.
12241                 // returns:
12242                 //              A Color object. If obj is passed, it will be the return value.
12243                 var m = color.toLowerCase().match(/^rgba?\(([\s\.,0-9]+)\)/);
12244                 return m && Color.fromArray(m[1].split(/\s*,\s*/), obj);        // Color
12245         };
12246
12247         Color.fromHex = dojo.colorFromHex = function(/*String*/ color, /*Color?*/ obj){
12248                 // summary:
12249                 //              Converts a hex string with a '#' prefix to a color object.
12250                 //              Supports 12-bit #rgb shorthand. Optionally accepts a
12251                 //              `Color` object to update with the parsed value.
12252                 //
12253                 // returns:
12254                 //              A Color object. If obj is passed, it will be the return value.
12255                 //
12256                 // example:
12257                 //       | var thing = dojo.colorFromHex("#ededed"); // grey, longhand
12258                 //
12259                 // example:
12260                 //      | var thing = dojo.colorFromHex("#000"); // black, shorthand
12261                 var t = obj || new Color(),
12262                         bits = (color.length == 4) ? 4 : 8,
12263                         mask = (1 << bits) - 1;
12264                 color = Number("0x" + color.substr(1));
12265                 if(isNaN(color)){
12266                         return null; // Color
12267                 }
12268                 ArrayUtil.forEach(["b", "g", "r"], function(x){
12269                         var c = color & mask;
12270                         color >>= bits;
12271                         t[x] = bits == 4 ? 17 * c : c;
12272                 });
12273                 t.a = 1;
12274                 return t;       // Color
12275         };
12276
12277         Color.fromArray = dojo.colorFromArray = function(/*Array*/ a, /*Color?*/ obj){
12278                 // summary:
12279                 //              Builds a `Color` from a 3 or 4 element array, mapping each
12280                 //              element in sequence to the rgb(a) values of the color.
12281                 // example:
12282                 //              | var myColor = dojo.colorFromArray([237,237,237,0.5]); // grey, 50% alpha
12283                 // returns:
12284                 //              A Color object. If obj is passed, it will be the return value.
12285                 var t = obj || new Color();
12286                 t._set(Number(a[0]), Number(a[1]), Number(a[2]), Number(a[3]));
12287                 if(isNaN(t.a)){ t.a = 1; }
12288                 return t.sanitize();    // Color
12289         };
12290
12291         Color.fromString = dojo.colorFromString = function(/*String*/ str, /*Color?*/ obj){
12292                 // summary:
12293                 //              Parses `str` for a color value. Accepts hex, rgb, and rgba
12294                 //              style color values.
12295                 // description:
12296                 //              Acceptable input values for str may include arrays of any form
12297                 //              accepted by dojo.colorFromArray, hex strings such as "#aaaaaa", or
12298                 //              rgb or rgba strings such as "rgb(133, 200, 16)" or "rgba(10, 10,
12299                 //              10, 50)"
12300                 // returns:
12301                 //              A Color object. If obj is passed, it will be the return value.
12302                 var a = Color.named[str];
12303                 return a && Color.fromArray(a, obj) || Color.fromRgb(str, obj) || Color.fromHex(str, obj);      // Color
12304         };
12305
12306         return Color;
12307 });
12308
12309 },
12310 'dojo/promise/instrumentation':function(){
12311 define([
12312         "./tracer",
12313         "../has",
12314         "../_base/lang",
12315         "../_base/array"
12316 ], function(tracer, has, lang, arrayUtil){
12317         function logError(error, rejection, deferred){
12318                 var stack = "";
12319                 if(error && error.stack){
12320                         stack += error.stack;
12321                 }
12322                 if(rejection && rejection.stack){
12323                         stack += "\n    ----------------------------------------\n    rejected" + rejection.stack.split("\n").slice(1).join("\n").replace(/^\s+/, " ");
12324                 }
12325                 if(deferred && deferred.stack){
12326                         stack += "\n    ----------------------------------------\n" + deferred.stack;
12327                 }
12328                 console.error(error, stack);
12329         }
12330
12331         function reportRejections(error, handled, rejection, deferred){
12332                 if(!handled){
12333                         logError(error, rejection, deferred);
12334                 }
12335         }
12336
12337         var errors = [];
12338         var activeTimeout = false;
12339         var unhandledWait = 1000;
12340         function trackUnhandledRejections(error, handled, rejection, deferred){
12341                 if(handled){
12342                         arrayUtil.some(errors, function(obj, ix){
12343                                 if(obj.error === error){
12344                                         errors.splice(ix, 1);
12345                                         return true;
12346                                 }
12347                         });
12348                 }else if(!arrayUtil.some(errors, function(obj){ return obj.error === error; })){
12349                         errors.push({
12350                                 error: error,
12351                                 rejection: rejection,
12352                                 deferred: deferred,
12353                                 timestamp: new Date().getTime()
12354                         });
12355                 }
12356
12357                 if(!activeTimeout){
12358                         activeTimeout = setTimeout(logRejected, unhandledWait);
12359                 }
12360         }
12361
12362         function logRejected(){
12363                 var now = new Date().getTime();
12364                 var reportBefore = now - unhandledWait;
12365                 errors = arrayUtil.filter(errors, function(obj){
12366                         if(obj.timestamp < reportBefore){
12367                                 logError(obj.error, obj.rejection, obj.deferred);
12368                                 return false;
12369                         }
12370                         return true;
12371                 });
12372
12373                 if(errors.length){
12374                         activeTimeout = setTimeout(logRejected, errors[0].timestamp + unhandledWait - now);
12375                 }else{
12376                         activeTimeout = false;
12377                 }
12378         }
12379
12380         return function(Deferred){
12381                 // summary:
12382                 //              Initialize instrumentation for the Deferred class.
12383                 // description:
12384                 //              Initialize instrumentation for the Deferred class.
12385                 //              Done automatically by `dojo/Deferred` if the
12386                 //              `deferredInstrumentation` and `useDeferredInstrumentation`
12387                 //              config options are set.
12388                 //
12389                 //              Sets up `dojo/promise/tracer` to log to the console.
12390                 //
12391                 //              Sets up instrumentation of rejected deferreds so unhandled
12392                 //              errors are logged to the console.
12393
12394                 var usage = has("config-useDeferredInstrumentation");
12395                 if(usage){
12396                         tracer.on("resolved", lang.hitch(console, "log", "resolved"));
12397                         tracer.on("rejected", lang.hitch(console, "log", "rejected"));
12398                         tracer.on("progress", lang.hitch(console, "log", "progress"));
12399
12400                         var args = [];
12401                         if(typeof usage === "string"){
12402                                 args = usage.split(",");
12403                                 usage = args.shift();
12404                         }
12405                         if(usage === "report-rejections"){
12406                                 Deferred.instrumentRejected = reportRejections;
12407                         }else if(usage === "report-unhandled-rejections" || usage === true || usage === 1){
12408                                 Deferred.instrumentRejected = trackUnhandledRejections;
12409                                 unhandledWait = parseInt(args[0], 10) || unhandledWait;
12410                         }else{
12411                                 throw new Error("Unsupported instrumentation usage <" + usage + ">");
12412                         }
12413                 }
12414         };
12415 });
12416
12417 },
12418 'dojo/selector/_loader':function(){
12419 define(["../has", "require"],
12420                 function(has, require){
12421
12422 "use strict";
12423 var testDiv = document.createElement("div");
12424 has.add("dom-qsa2.1", !!testDiv.querySelectorAll);
12425 has.add("dom-qsa3", function(){
12426                         // test to see if we have a reasonable native selector engine available
12427                         try{
12428                                 testDiv.innerHTML = "<p class='TEST'></p>"; // test kind of from sizzle
12429                                 // Safari can't handle uppercase or unicode characters when
12430                                 // in quirks mode, IE8 can't handle pseudos like :empty
12431                                 return testDiv.querySelectorAll(".TEST:empty").length == 1;
12432                         }catch(e){}
12433                 });
12434 var fullEngine;
12435 var acme = "./acme", lite = "./lite";
12436 return {
12437         // summary:
12438         //              This module handles loading the appropriate selector engine for the given browser
12439
12440         load: function(id, parentRequire, loaded, config){
12441                 var req = require;
12442                 // here we implement the default logic for choosing a selector engine
12443                 id = id == "default" ? has("config-selectorEngine") || "css3" : id;
12444                 id = id == "css2" || id == "lite" ? lite :
12445                                 id == "css2.1" ? has("dom-qsa2.1") ? lite : acme :
12446                                 id == "css3" ? has("dom-qsa3") ? lite : acme :
12447                                 id == "acme" ? acme : (req = parentRequire) && id;
12448                 if(id.charAt(id.length-1) == '?'){
12449                         id = id.substring(0,id.length - 1);
12450                         var optionalLoad = true;
12451                 }
12452                 // the query engine is optional, only load it if a native one is not available or existing one has not been loaded
12453                 if(optionalLoad && (has("dom-compliant-qsa") || fullEngine)){
12454                         return loaded(fullEngine);
12455                 }
12456                 // load the referenced selector engine
12457                 req([id], function(engine){
12458                         if(id != "./lite"){
12459                                 fullEngine = engine;
12460                         }
12461                         loaded(engine);
12462                 });
12463         }
12464 };
12465 });
12466
12467 },
12468 'dojo/promise/Promise':function(){
12469 define([
12470         "../_base/lang"
12471 ], function(lang){
12472         "use strict";
12473
12474         // module:
12475         //              dojo/promise/Promise
12476
12477         function throwAbstract(){
12478                 throw new TypeError("abstract");
12479         }
12480
12481         return lang.extend(function Promise(){
12482                 // summary:
12483                 //              The public interface to a deferred.
12484                 // description:
12485                 //              The public interface to a deferred. All promises in Dojo are
12486                 //              instances of this class.
12487         }, {
12488                 then: function(callback, errback, progback){
12489                         // summary:
12490                         //              Add new callbacks to the promise.
12491                         // description:
12492                         //              Add new callbacks to the deferred. Callbacks can be added
12493                         //              before or after the deferred is fulfilled.
12494                         // callback: Function?
12495                         //              Callback to be invoked when the promise is resolved.
12496                         //              Receives the resolution value.
12497                         // errback: Function?
12498                         //              Callback to be invoked when the promise is rejected.
12499                         //              Receives the rejection error.
12500                         // progback: Function?
12501                         //              Callback to be invoked when the promise emits a progress
12502                         //              update. Receives the progress update.
12503                         // returns: dojo/promise/Promise
12504                         //              Returns a new promise for the result of the callback(s).
12505                         //              This can be used for chaining many asynchronous operations.
12506
12507                         throwAbstract();
12508                 },
12509
12510                 cancel: function(reason, strict){
12511                         // summary:
12512                         //              Inform the deferred it may cancel its asynchronous operation.
12513                         // description:
12514                         //              Inform the deferred it may cancel its asynchronous operation.
12515                         //              The deferred's (optional) canceler is invoked and the
12516                         //              deferred will be left in a rejected state. Can affect other
12517                         //              promises that originate with the same deferred.
12518                         // reason: any
12519                         //              A message that may be sent to the deferred's canceler,
12520                         //              explaining why it's being canceled.
12521                         // strict: Boolean?
12522                         //              If strict, will throw an error if the deferred has already
12523                         //              been fulfilled and consequently cannot be canceled.
12524                         // returns: any
12525                         //              Returns the rejection reason if the deferred was canceled
12526                         //              normally.
12527
12528                         throwAbstract();
12529                 },
12530
12531                 isResolved: function(){
12532                         // summary:
12533                         //              Checks whether the promise has been resolved.
12534                         // returns: Boolean
12535
12536                         throwAbstract();
12537                 },
12538
12539                 isRejected: function(){
12540                         // summary:
12541                         //              Checks whether the promise has been rejected.
12542                         // returns: Boolean
12543
12544                         throwAbstract();
12545                 },
12546
12547                 isFulfilled: function(){
12548                         // summary:
12549                         //              Checks whether the promise has been resolved or rejected.
12550                         // returns: Boolean
12551
12552                         throwAbstract();
12553                 },
12554
12555                 isCanceled: function(){
12556                         // summary:
12557                         //              Checks whether the promise has been canceled.
12558                         // returns: Boolean
12559
12560                         throwAbstract();
12561                 },
12562
12563                 always: function(callbackOrErrback){
12564                         // summary:
12565                         //              Add a callback to be invoked when the promise is resolved
12566                         //              or rejected.
12567                         // callbackOrErrback: Function?
12568                         //              A function that is used both as a callback and errback.
12569                         // returns: dojo/promise/Promise
12570                         //              Returns a new promise for the result of the callback/errback.
12571
12572                         return this.then(callbackOrErrback, callbackOrErrback);
12573                 },
12574
12575                 otherwise: function(errback){
12576                         // summary:
12577                         //              Add new errbacks to the promise.
12578                         // errback: Function?
12579                         //              Callback to be invoked when the promise is rejected.
12580                         // returns: dojo/promise/Promise
12581                         //              Returns a new promise for the result of the errback.
12582
12583                         return this.then(null, errback);
12584                 },
12585
12586                 trace: function(){
12587                         return this;
12588                 },
12589
12590                 traceRejected: function(){
12591                         return this;
12592                 },
12593
12594                 toString: function(){
12595                         // returns: string
12596                         //              Returns `[object Promise]`.
12597
12598                         return "[object Promise]";
12599                 }
12600         });
12601 });
12602
12603 },
12604 'dojo/request/watch':function(){
12605 define([
12606         './util',
12607         '../errors/RequestTimeoutError',
12608         '../errors/CancelError',
12609         '../_base/array',
12610         '../_base/window',
12611         '../has!host-browser?dom-addeventlistener?:../on:'
12612 ], function(util, RequestTimeoutError, CancelError, array, win, on){
12613         // avoid setting a timer per request. It degrades performance on IE
12614         // something fierece if we don't use unified loops.
12615         var _inFlightIntvl = null,
12616                 _inFlight = [];
12617
12618         function watchInFlight(){
12619                 // summary:
12620                 //              internal method that checks each inflight XMLHttpRequest to see
12621                 //              if it has completed or if the timeout situation applies.
12622
12623                 var now = +(new Date);
12624
12625                 // we need manual loop because we often modify _inFlight (and therefore 'i') while iterating
12626                 for(var i = 0, dfd; i < _inFlight.length && (dfd = _inFlight[i]); i++){
12627                         var response = dfd.response,
12628                                 options = response.options;
12629                         if((dfd.isCanceled && dfd.isCanceled()) || (dfd.isValid && !dfd.isValid(response))){
12630                                 _inFlight.splice(i--, 1);
12631                                 watch._onAction && watch._onAction();
12632                         }else if(dfd.isReady && dfd.isReady(response)){
12633                                 _inFlight.splice(i--, 1);
12634                                 dfd.handleResponse(response);
12635                                 watch._onAction && watch._onAction();
12636                         }else if(dfd.startTime){
12637                                 // did we timeout?
12638                                 if(dfd.startTime + (options.timeout || 0) < now){
12639                                         _inFlight.splice(i--, 1);
12640                                         // Cancel the request so the io module can do appropriate cleanup.
12641                                         dfd.cancel(new RequestTimeoutError('Timeout exceeded', response));
12642                                         watch._onAction && watch._onAction();
12643                                 }
12644                         }
12645                 }
12646
12647                 watch._onInFlight && watch._onInFlight(dfd);
12648
12649                 if(!_inFlight.length){
12650                         clearInterval(_inFlightIntvl);
12651                         _inFlightIntvl = null;
12652                 }
12653         }
12654
12655         function watch(dfd){
12656                 // summary:
12657                 //              Watches the io request represented by dfd to see if it completes.
12658                 // dfd: Deferred
12659                 //              The Deferred object to watch.
12660                 // response: Object
12661                 //              The object used as the value of the request promise.
12662                 // validCheck: Function
12663                 //              Function used to check if the IO request is still valid. Gets the dfd
12664                 //              object as its only argument.
12665                 // ioCheck: Function
12666                 //              Function used to check if basic IO call worked. Gets the dfd
12667                 //              object as its only argument.
12668                 // resHandle: Function
12669                 //              Function used to process response. Gets the dfd
12670                 //              object as its only argument.
12671                 if(dfd.response.options.timeout){
12672                         dfd.startTime = +(new Date);
12673                 }
12674
12675                 if(dfd.isFulfilled()){
12676                         // bail out if the deferred is already fulfilled
12677                         return;
12678                 }
12679
12680                 _inFlight.push(dfd);
12681                 if(!_inFlightIntvl){
12682                         _inFlightIntvl = setInterval(watchInFlight, 50);
12683                 }
12684
12685                 // handle sync requests separately from async:
12686                 // http://bugs.dojotoolkit.org/ticket/8467
12687                 if(dfd.response.options.sync){
12688                         watchInFlight();
12689                 }
12690         }
12691
12692         watch.cancelAll = function cancelAll(){
12693                 // summary:
12694                 //              Cancels all pending IO requests, regardless of IO type
12695                 try{
12696                         array.forEach(_inFlight, function(dfd){
12697                                 try{
12698                                         dfd.cancel(new CancelError('All requests canceled.'));
12699                                 }catch(e){}
12700                         });
12701                 }catch(e){}
12702         };
12703
12704         if(win && on && win.doc.attachEvent){
12705                 // Automatically call cancel all io calls on unload in IE
12706                 // http://bugs.dojotoolkit.org/ticket/2357
12707                 on(win.global, 'unload', function(){
12708                         watch.cancelAll();
12709                 });
12710         }
12711
12712         return watch;
12713 });
12714
12715 },
12716 'dojo/on':function(){
12717 define(["./has!dom-addeventlistener?:./aspect", "./_base/kernel", "./has"], function(aspect, dojo, has){
12718
12719         "use strict";
12720         if( 1 ){ // check to make sure we are in a browser, this module should work anywhere
12721                 var major = window.ScriptEngineMajorVersion;
12722                 has.add("jscript", major && (major() + ScriptEngineMinorVersion() / 10));
12723                 has.add("event-orientationchange", has("touch") && !has("android")); // TODO: how do we detect this?
12724                 has.add("event-stopimmediatepropagation", window.Event && !!window.Event.prototype && !!window.Event.prototype.stopImmediatePropagation);
12725         }
12726         var on = function(target, type, listener, dontFix){
12727                 // summary:
12728                 //              A function that provides core event listening functionality. With this function
12729                 //              you can provide a target, event type, and listener to be notified of
12730                 //              future matching events that are fired.
12731                 // target: Element|Object
12732                 //              This is the target object or DOM element that to receive events from
12733                 // type: String|Function
12734                 //              This is the name of the event to listen for or an extension event type.
12735                 // listener: Function
12736                 //              This is the function that should be called when the event fires.
12737                 // returns: Object
12738                 //              An object with a remove() method that can be used to stop listening for this
12739                 //              event.
12740                 // description:
12741                 //              To listen for "click" events on a button node, we can do:
12742                 //              |       define(["dojo/on"], function(listen){
12743                 //              |               on(button, "click", clickHandler);
12744                 //              |               ...
12745                 //              Evented JavaScript objects can also have their own events.
12746                 //              |       var obj = new Evented;
12747                 //              |       on(obj, "foo", fooHandler);
12748                 //              And then we could publish a "foo" event:
12749                 //              |       on.emit(obj, "foo", {key: "value"});
12750                 //              We can use extension events as well. For example, you could listen for a tap gesture:
12751                 //              |       define(["dojo/on", "dojo/gesture/tap", function(listen, tap){
12752                 //              |               on(button, tap, tapHandler);
12753                 //              |               ...
12754                 //              which would trigger fooHandler. Note that for a simple object this is equivalent to calling:
12755                 //              |       obj.onfoo({key:"value"});
12756                 //              If you use on.emit on a DOM node, it will use native event dispatching when possible.
12757
12758                 if(typeof target.on == "function" && typeof type != "function"){
12759                         // delegate to the target's on() method, so it can handle it's own listening if it wants
12760                         return target.on(type, listener);
12761                 }
12762                 // delegate to main listener code
12763                 return on.parse(target, type, listener, addListener, dontFix, this);
12764         };
12765         on.pausable =  function(target, type, listener, dontFix){
12766                 // summary:
12767                 //              This function acts the same as on(), but with pausable functionality. The
12768                 //              returned signal object has pause() and resume() functions. Calling the
12769                 //              pause() method will cause the listener to not be called for future events. Calling the
12770                 //              resume() method will cause the listener to again be called for future events.
12771                 var paused;
12772                 var signal = on(target, type, function(){
12773                         if(!paused){
12774                                 return listener.apply(this, arguments);
12775                         }
12776                 }, dontFix);
12777                 signal.pause = function(){
12778                         paused = true;
12779                 };
12780                 signal.resume = function(){
12781                         paused = false;
12782                 };
12783                 return signal;
12784         };
12785         on.once = function(target, type, listener, dontFix){
12786                 // summary:
12787                 //              This function acts the same as on(), but will only call the listener once. The 
12788                 //              listener will be called for the first
12789                 //              event that takes place and then listener will automatically be removed.
12790                 var signal = on(target, type, function(){
12791                         // remove this listener
12792                         signal.remove();
12793                         // proceed to call the listener
12794                         return listener.apply(this, arguments);
12795                 });
12796                 return signal;
12797         };
12798         on.parse = function(target, type, listener, addListener, dontFix, matchesTarget){
12799                 if(type.call){
12800                         // event handler function
12801                         // on(node, touch.press, touchListener);
12802                         return type.call(matchesTarget, target, listener);
12803                 }
12804
12805                 if(type.indexOf(",") > -1){
12806                         // we allow comma delimited event names, so you can register for multiple events at once
12807                         var events = type.split(/\s*,\s*/);
12808                         var handles = [];
12809                         var i = 0;
12810                         var eventName;
12811                         while(eventName = events[i++]){
12812                                 handles.push(addListener(target, eventName, listener, dontFix, matchesTarget));
12813                         }
12814                         handles.remove = function(){
12815                                 for(var i = 0; i < handles.length; i++){
12816                                         handles[i].remove();
12817                                 }
12818                         };
12819                         return handles;
12820                 }
12821                 return addListener(target, type, listener, dontFix, matchesTarget);
12822         };
12823         var touchEvents = /^touch/;
12824         function addListener(target, type, listener, dontFix, matchesTarget){
12825                 // event delegation:
12826                 var selector = type.match(/(.*):(.*)/);
12827                 // if we have a selector:event, the last one is interpreted as an event, and we use event delegation
12828                 if(selector){
12829                         type = selector[2];
12830                         selector = selector[1];
12831                         // create the extension event for selectors and directly call it
12832                         return on.selector(selector, type).call(matchesTarget, target, listener);
12833                 }
12834                 // test to see if it a touch event right now, so we don't have to do it every time it fires
12835                 if(has("touch")){
12836                         if(touchEvents.test(type)){
12837                                 // touch event, fix it
12838                                 listener = fixTouchListener(listener);
12839                         }
12840                         if(!has("event-orientationchange") && (type == "orientationchange")){
12841                                 //"orientationchange" not supported <= Android 2.1, 
12842                                 //but works through "resize" on window
12843                                 type = "resize"; 
12844                                 target = window;
12845                                 listener = fixTouchListener(listener);
12846                         } 
12847                 }
12848                 if(addStopImmediate){
12849                         // add stopImmediatePropagation if it doesn't exist
12850                         listener = addStopImmediate(listener);
12851                 }
12852                 // normal path, the target is |this|
12853                 if(target.addEventListener){
12854                         // the target has addEventListener, which should be used if available (might or might not be a node, non-nodes can implement this method as well)
12855                         // check for capture conversions
12856                         var capture = type in captures,
12857                                 adjustedType = capture ? captures[type] : type;
12858                         target.addEventListener(adjustedType, listener, capture);
12859                         // create and return the signal
12860                         return {
12861                                 remove: function(){
12862                                         target.removeEventListener(adjustedType, listener, capture);
12863                                 }
12864                         };
12865                 }
12866                 type = "on" + type;
12867                 if(fixAttach && target.attachEvent){
12868                         return fixAttach(target, type, listener);
12869                 }
12870                 throw new Error("Target must be an event emitter");
12871         }
12872
12873         on.selector = function(selector, eventType, children){
12874                 // summary:
12875                 //              Creates a new extension event with event delegation. This is based on
12876                 //              the provided event type (can be extension event) that
12877                 //              only calls the listener when the CSS selector matches the target of the event.
12878                 //
12879                 //              The application must require() an appropriate level of dojo/query to handle the selector.
12880                 // selector:
12881                 //              The CSS selector to use for filter events and determine the |this| of the event listener.
12882                 // eventType:
12883                 //              The event to listen for
12884                 // children:
12885                 //              Indicates if children elements of the selector should be allowed. This defaults to 
12886                 //              true
12887                 // example:
12888                 // |    require(["dojo/on", "dojo/mouse", "dojo/query!css2"], function(listen, mouse){
12889                 // |            on(node, on.selector(".my-class", mouse.enter), handlerForMyHover);
12890                 return function(target, listener){
12891                         // if the selector is function, use it to select the node, otherwise use the matches method
12892                         var matchesTarget = typeof selector == "function" ? {matches: selector} : this,
12893                                 bubble = eventType.bubble;
12894                         function select(eventTarget){
12895                                 // see if we have a valid matchesTarget or default to dojo.query
12896                                 matchesTarget = matchesTarget && matchesTarget.matches ? matchesTarget : dojo.query;
12897                                 // there is a selector, so make sure it matches
12898                                 while(!matchesTarget.matches(eventTarget, selector, target)){
12899                                         if(eventTarget == target || children === false || !(eventTarget = eventTarget.parentNode) || eventTarget.nodeType != 1){ // intentional assignment
12900                                                 return;
12901                                         }
12902                                 }
12903                                 return eventTarget;
12904                         }
12905                         if(bubble){
12906                                 // the event type doesn't naturally bubble, but has a bubbling form, use that, and give it the selector so it can perform the select itself
12907                                 return on(target, bubble(select), listener);
12908                         }
12909                         // standard event delegation
12910                         return on(target, eventType, function(event){
12911                                 // call select to see if we match
12912                                 var eventTarget = select(event.target);
12913                                 // if it matches we call the listener
12914                                 return eventTarget && listener.call(eventTarget, event);
12915                         });
12916                 };
12917         };
12918
12919         function syntheticPreventDefault(){
12920                 this.cancelable = false;
12921         }
12922         function syntheticStopPropagation(){
12923                 this.bubbles = false;
12924         }
12925         var slice = [].slice,
12926                 syntheticDispatch = on.emit = function(target, type, event){
12927                 // summary:
12928                 //              Fires an event on the target object.
12929                 // target:
12930                 //              The target object to fire the event on. This can be a DOM element or a plain 
12931                 //              JS object. If the target is a DOM element, native event emiting mechanisms
12932                 //              are used when possible.
12933                 // type:
12934                 //              The event type name. You can emulate standard native events like "click" and 
12935                 //              "mouseover" or create custom events like "open" or "finish".
12936                 // event:
12937                 //              An object that provides the properties for the event. See https://developer.mozilla.org/en/DOM/event.initEvent 
12938                 //              for some of the properties. These properties are copied to the event object.
12939                 //              Of particular importance are the cancelable and bubbles properties. The
12940                 //              cancelable property indicates whether or not the event has a default action
12941                 //              that can be cancelled. The event is cancelled by calling preventDefault() on
12942                 //              the event object. The bubbles property indicates whether or not the
12943                 //              event will bubble up the DOM tree. If bubbles is true, the event will be called
12944                 //              on the target and then each parent successively until the top of the tree
12945                 //              is reached or stopPropagation() is called. Both bubbles and cancelable 
12946                 //              default to false.
12947                 // returns:
12948                 //              If the event is cancelable and the event is not cancelled,
12949                 //              emit will return true. If the event is cancelable and the event is cancelled,
12950                 //              emit will return false.
12951                 // details:
12952                 //              Note that this is designed to emit events for listeners registered through
12953                 //              dojo/on. It should actually work with any event listener except those
12954                 //              added through IE's attachEvent (IE8 and below's non-W3C event emiting
12955                 //              doesn't support custom event types). It should work with all events registered
12956                 //              through dojo/on. Also note that the emit method does do any default
12957                 //              action, it only returns a value to indicate if the default action should take
12958                 //              place. For example, emiting a keypress event would not cause a character
12959                 //              to appear in a textbox.
12960                 // example:
12961                 //              To fire our own click event
12962                 //      |       on.emit(dojo.byId("button"), "click", {
12963                 //      |               cancelable: true,
12964                 //      |               bubbles: true,
12965                 //      |               screenX: 33,
12966                 //      |               screenY: 44
12967                 //      |       });
12968                 //              We can also fire our own custom events:
12969                 //      |       on.emit(dojo.byId("slider"), "slide", {
12970                 //      |               cancelable: true,
12971                 //      |               bubbles: true,
12972                 //      |               direction: "left-to-right"
12973                 //      |       });
12974                 var args = slice.call(arguments, 2);
12975                 var method = "on" + type;
12976                 if("parentNode" in target){
12977                         // node (or node-like), create event controller methods
12978                         var newEvent = args[0] = {};
12979                         for(var i in event){
12980                                 newEvent[i] = event[i];
12981                         }
12982                         newEvent.preventDefault = syntheticPreventDefault;
12983                         newEvent.stopPropagation = syntheticStopPropagation;
12984                         newEvent.target = target;
12985                         newEvent.type = type;
12986                         event = newEvent;
12987                 }
12988                 do{
12989                         // call any node which has a handler (note that ideally we would try/catch to simulate normal event propagation but that causes too much pain for debugging)
12990                         target[method] && target[method].apply(target, args);
12991                         // and then continue up the parent node chain if it is still bubbling (if started as bubbles and stopPropagation hasn't been called)
12992                 }while(event && event.bubbles && (target = target.parentNode));
12993                 return event && event.cancelable && event; // if it is still true (was cancelable and was cancelled), return the event to indicate default action should happen
12994         };
12995         var captures = {};
12996         if(!has("event-stopimmediatepropagation")){
12997                 var stopImmediatePropagation =function(){
12998                         this.immediatelyStopped = true;
12999                         this.modified = true; // mark it as modified so the event will be cached in IE
13000                 };
13001                 var addStopImmediate = function(listener){
13002                         return function(event){
13003                                 if(!event.immediatelyStopped){// check to make sure it hasn't been stopped immediately
13004                                         event.stopImmediatePropagation = stopImmediatePropagation;
13005                                         return listener.apply(this, arguments);
13006                                 }
13007                         };
13008                 }
13009         } 
13010         if(has("dom-addeventlistener")){
13011                 // normalize focusin and focusout
13012                 captures = {
13013                         focusin: "focus",
13014                         focusout: "blur"
13015                 };
13016
13017                 // emiter that works with native event handling
13018                 on.emit = function(target, type, event){
13019                         if(target.dispatchEvent && document.createEvent){
13020                                 // use the native event emiting mechanism if it is available on the target object
13021                                 // create a generic event                               
13022                                 // we could create branch into the different types of event constructors, but 
13023                                 // that would be a lot of extra code, with little benefit that I can see, seems 
13024                                 // best to use the generic constructor and copy properties over, making it 
13025                                 // easy to have events look like the ones created with specific initializers
13026                                 var nativeEvent = target.ownerDocument.createEvent("HTMLEvents");
13027                                 nativeEvent.initEvent(type, !!event.bubbles, !!event.cancelable);
13028                                 // and copy all our properties over
13029                                 for(var i in event){
13030                                         var value = event[i];
13031                                         if(!(i in nativeEvent)){
13032                                                 nativeEvent[i] = event[i];
13033                                         }
13034                                 }
13035                                 return target.dispatchEvent(nativeEvent) && nativeEvent;
13036                         }
13037                         return syntheticDispatch.apply(on, arguments); // emit for a non-node
13038                 };
13039         }else{
13040                 // no addEventListener, basically old IE event normalization
13041                 on._fixEvent = function(evt, sender){
13042                         // summary:
13043                         //              normalizes properties on the event object including event
13044                         //              bubbling methods, keystroke normalization, and x/y positions
13045                         // evt:
13046                         //              native event object
13047                         // sender:
13048                         //              node to treat as "currentTarget"
13049                         if(!evt){
13050                                 var w = sender && (sender.ownerDocument || sender.document || sender).parentWindow || window;
13051                                 evt = w.event;
13052                         }
13053                         if(!evt){return evt;}
13054                         if(lastEvent && evt.type == lastEvent.type){
13055                                 // should be same event, reuse event object (so it can be augmented)
13056                                 evt = lastEvent;
13057                         }
13058                         if(!evt.target){ // check to see if it has been fixed yet
13059                                 evt.target = evt.srcElement;
13060                                 evt.currentTarget = (sender || evt.srcElement);
13061                                 if(evt.type == "mouseover"){
13062                                         evt.relatedTarget = evt.fromElement;
13063                                 }
13064                                 if(evt.type == "mouseout"){
13065                                         evt.relatedTarget = evt.toElement;
13066                                 }
13067                                 if(!evt.stopPropagation){
13068                                         evt.stopPropagation = stopPropagation;
13069                                         evt.preventDefault = preventDefault;
13070                                 }
13071                                 switch(evt.type){
13072                                         case "keypress":
13073                                                 var c = ("charCode" in evt ? evt.charCode : evt.keyCode);
13074                                                 if (c==10){
13075                                                         // CTRL-ENTER is CTRL-ASCII(10) on IE, but CTRL-ENTER on Mozilla
13076                                                         c=0;
13077                                                         evt.keyCode = 13;
13078                                                 }else if(c==13||c==27){
13079                                                         c=0; // Mozilla considers ENTER and ESC non-printable
13080                                                 }else if(c==3){
13081                                                         c=99; // Mozilla maps CTRL-BREAK to CTRL-c
13082                                                 }
13083                                                 // Mozilla sets keyCode to 0 when there is a charCode
13084                                                 // but that stops the event on IE.
13085                                                 evt.charCode = c;
13086                                                 _setKeyChar(evt);
13087                                                 break;
13088                                 }
13089                         }
13090                         return evt;
13091                 };
13092                 var lastEvent, IESignal = function(handle){
13093                         this.handle = handle;
13094                 };
13095                 IESignal.prototype.remove = function(){
13096                         delete _dojoIEListeners_[this.handle];
13097                 };
13098                 var fixListener = function(listener){
13099                         // this is a minimal function for closing on the previous listener with as few as variables as possible
13100                         return function(evt){
13101                                 evt = on._fixEvent(evt, this);
13102                                 var result = listener.call(this, evt);
13103                                 if(evt.modified){
13104                                         // cache the last event and reuse it if we can
13105                                         if(!lastEvent){
13106                                                 setTimeout(function(){
13107                                                         lastEvent = null;
13108                                                 });
13109                                         }
13110                                         lastEvent = evt;
13111                                 }
13112                                 return result;
13113                         };
13114                 };
13115                 var fixAttach = function(target, type, listener){
13116                         listener = fixListener(listener);
13117                         if(((target.ownerDocument ? target.ownerDocument.parentWindow : target.parentWindow || target.window || window) != top || 
13118                                                 has("jscript") < 5.8) && 
13119                                         !has("config-_allow_leaks")){
13120                                 // IE will leak memory on certain handlers in frames (IE8 and earlier) and in unattached DOM nodes for JScript 5.7 and below.
13121                                 // Here we use global redirection to solve the memory leaks
13122                                 if(typeof _dojoIEListeners_ == "undefined"){
13123                                         _dojoIEListeners_ = [];
13124                                 }
13125                                 var emiter = target[type];
13126                                 if(!emiter || !emiter.listeners){
13127                                         var oldListener = emiter;
13128                                         emiter = Function('event', 'var callee = arguments.callee; for(var i = 0; i<callee.listeners.length; i++){var listener = _dojoIEListeners_[callee.listeners[i]]; if(listener){listener.call(this,event);}}');
13129                                         emiter.listeners = [];
13130                                         target[type] = emiter;
13131                                         emiter.global = this;
13132                                         if(oldListener){
13133                                                 emiter.listeners.push(_dojoIEListeners_.push(oldListener) - 1);
13134                                         }
13135                                 }
13136                                 var handle;
13137                                 emiter.listeners.push(handle = (emiter.global._dojoIEListeners_.push(listener) - 1));
13138                                 return new IESignal(handle);
13139                         }
13140                         return aspect.after(target, type, listener, true);
13141                 };
13142
13143                 var _setKeyChar = function(evt){
13144                         evt.keyChar = evt.charCode ? String.fromCharCode(evt.charCode) : '';
13145                         evt.charOrCode = evt.keyChar || evt.keyCode;
13146                 };
13147                 // Called in Event scope
13148                 var stopPropagation = function(){
13149                         this.cancelBubble = true;
13150                 };
13151                 var preventDefault = on._preventDefault = function(){
13152                         // Setting keyCode to 0 is the only way to prevent certain keypresses (namely
13153                         // ctrl-combinations that correspond to menu accelerator keys).
13154                         // Otoh, it prevents upstream listeners from getting this information
13155                         // Try to split the difference here by clobbering keyCode only for ctrl
13156                         // combinations. If you still need to access the key upstream, bubbledKeyCode is
13157                         // provided as a workaround.
13158                         this.bubbledKeyCode = this.keyCode;
13159                         if(this.ctrlKey){
13160                                 try{
13161                                         // squelch errors when keyCode is read-only
13162                                         // (e.g. if keyCode is ctrl or shift)
13163                                         this.keyCode = 0;
13164                                 }catch(e){
13165                                 }
13166                         }
13167                         this.defaultPrevented = true;
13168                         this.returnValue = false;
13169                 };
13170         }
13171         if(has("touch")){ 
13172                 var Event = function(){};
13173                 var windowOrientation = window.orientation; 
13174                 var fixTouchListener = function(listener){ 
13175                         return function(originalEvent){ 
13176                                 //Event normalization(for ontouchxxx and resize): 
13177                                 //1.incorrect e.pageX|pageY in iOS 
13178                                 //2.there are no "e.rotation", "e.scale" and "onorientationchange" in Andriod
13179                                 //3.More TBD e.g. force | screenX | screenX | clientX | clientY | radiusX | radiusY
13180
13181                                 // see if it has already been corrected
13182                                 var event = originalEvent.corrected;
13183                                 if(!event){
13184                                         var type = originalEvent.type;
13185                                         try{
13186                                                 delete originalEvent.type; // on some JS engines (android), deleting properties make them mutable
13187                                         }catch(e){} 
13188                                         if(originalEvent.type){
13189                                                 // deleting properties doesn't work (older iOS), have to use delegation
13190                                                 Event.prototype = originalEvent;
13191                                                 var event = new Event;
13192                                                 // have to delegate methods to make them work
13193                                                 event.preventDefault = function(){
13194                                                         originalEvent.preventDefault();
13195                                                 };
13196                                                 event.stopPropagation = function(){
13197                                                         originalEvent.stopPropagation();
13198                                                 };
13199                                         }else{
13200                                                 // deletion worked, use property as is
13201                                                 event = originalEvent;
13202                                                 event.type = type;
13203                                         }
13204                                         originalEvent.corrected = event;
13205                                         if(type == 'resize'){
13206                                                 if(windowOrientation == window.orientation){ 
13207                                                         return null;//double tap causes an unexpected 'resize' in Andriod 
13208                                                 } 
13209                                                 windowOrientation = window.orientation;
13210                                                 event.type = "orientationchange"; 
13211                                                 return listener.call(this, event);
13212                                         }
13213                                         // We use the original event and augment, rather than doing an expensive mixin operation
13214                                         if(!("rotation" in event)){ // test to see if it has rotation
13215                                                 event.rotation = 0; 
13216                                                 event.scale = 1;
13217                                         }
13218                                         //use event.changedTouches[0].pageX|pageY|screenX|screenY|clientX|clientY|target
13219                                         var firstChangeTouch = event.changedTouches[0];
13220                                         for(var i in firstChangeTouch){ // use for-in, we don't need to have dependency on dojo/_base/lang here
13221                                                 delete event[i]; // delete it first to make it mutable
13222                                                 event[i] = firstChangeTouch[i];
13223                                         }
13224                                 }
13225                                 return listener.call(this, event); 
13226                         }; 
13227                 }; 
13228         }
13229         return on;
13230 });
13231
13232 },
13233 'dojo/_base/sniff':function(){
13234 define(["./kernel", "./lang", "../sniff"], function(dojo, lang, has){
13235         // module:
13236         //              dojo/_base/sniff
13237
13238         /*=====
13239         return {
13240                 // summary:
13241                 //              Deprecated.   New code should use dojo/sniff.
13242                 //              This module populates the dojo browser version sniffing properties like dojo.isIE.
13243         };
13244         =====*/
13245
13246         if(! 1 ){
13247                 return has;
13248         }
13249
13250         // no idea what this is for, or if it's used
13251         dojo._name = "browser";
13252
13253         lang.mixin(dojo, {
13254                 // isBrowser: Boolean
13255                 //              True if the client is a web-browser
13256                 isBrowser: true,
13257
13258                 // isFF: Number|undefined
13259                 //              Version as a Number if client is FireFox. undefined otherwise. Corresponds to
13260                 //              major detected FireFox version (1.5, 2, 3, etc.)
13261                 isFF: has("ff"),
13262
13263                 // isIE: Number|undefined
13264                 //              Version as a Number if client is MSIE(PC). undefined otherwise. Corresponds to
13265                 //              major detected IE version (6, 7, 8, etc.)
13266                 isIE: has("ie"),
13267
13268                 // isKhtml: Number|undefined
13269                 //              Version as a Number if client is a KHTML browser. undefined otherwise. Corresponds to major
13270                 //              detected version.
13271                 isKhtml: has("khtml"),
13272
13273                 // isWebKit: Number|undefined
13274                 //              Version as a Number if client is a WebKit-derived browser (Konqueror,
13275                 //              Safari, Chrome, etc.). undefined otherwise.
13276                 isWebKit: has("webkit"),
13277
13278                 // isMozilla: Number|undefined
13279                 //              Version as a Number if client is a Mozilla-based browser (Firefox,
13280                 //              SeaMonkey). undefined otherwise. Corresponds to major detected version.
13281                 isMozilla: has("mozilla"),
13282                 // isMoz: Number|undefined
13283                 //              Version as a Number if client is a Mozilla-based browser (Firefox,
13284                 //              SeaMonkey). undefined otherwise. Corresponds to major detected version.
13285                 isMoz: has("mozilla"),
13286
13287                 // isOpera: Number|undefined
13288                 //              Version as a Number if client is Opera. undefined otherwise. Corresponds to
13289                 //              major detected version.
13290                 isOpera: has("opera"),
13291
13292                 // isSafari: Number|undefined
13293                 //              Version as a Number if client is Safari or iPhone. undefined otherwise.
13294                 isSafari: has("safari"),
13295
13296                 // isChrome: Number|undefined
13297                 //              Version as a Number if client is Chrome browser. undefined otherwise.
13298                 isChrome: has("chrome"),
13299
13300                 // isMac: Boolean
13301                 //              True if the client runs on Mac
13302                 isMac: has("mac"),
13303
13304                 // isIos: Boolean
13305                 //              True if client is iPhone, iPod, or iPad
13306                 isIos: has("ios"),
13307
13308                 // isAndroid: Number|undefined
13309                 //              Version as a Number if client is android browser. undefined otherwise.
13310                 isAndroid: has("android"),
13311
13312                 // isWii: Boolean
13313                 //              True if client is Wii
13314                 isWii: has("wii"),
13315
13316                 // isQuirks: Boolean
13317                 //              Page is in quirks mode.
13318                 isQuirks: has("quirks"),
13319
13320                 // isAir: Boolean
13321                 //              True if client is Adobe Air
13322                 isAir: has("air")
13323         });
13324
13325
13326         dojo.locale = dojo.locale || (has("ie") ? navigator.userLanguage : navigator.language).toLowerCase();
13327
13328         return has;
13329 });
13330
13331 },
13332 'dojo/errors/create':function(){
13333 define(["../_base/lang"], function(lang){
13334         return function(name, ctor, base, props){
13335                 base = base || Error;
13336
13337                 var ErrorCtor = function(message){
13338                         if(base === Error){
13339                                 if(Error.captureStackTrace){
13340                                         Error.captureStackTrace(this, ErrorCtor);
13341                                 }
13342
13343                                 // Error.call() operates on the returned error
13344                                 // object rather than operating on |this|
13345                                 var err = Error.call(this, message),
13346                                         prop;
13347
13348                                 // Copy own properties from err to |this|
13349                                 for(prop in err){
13350                                         if(err.hasOwnProperty(prop)){
13351                                                 this[prop] = err[prop];
13352                                         }
13353                                 }
13354
13355                                 // messsage is non-enumerable in ES5
13356                                 this.message = message;
13357                                 // stack is non-enumerable in at least Firefox
13358                                 this.stack = err.stack;
13359                         }else{
13360                                 base.apply(this, arguments);
13361                         }
13362                         if(ctor){
13363                                 ctor.apply(this, arguments);
13364                         }
13365                 };
13366
13367                 ErrorCtor.prototype = lang.delegate(base.prototype, props);
13368                 ErrorCtor.prototype.name = name;
13369                 ErrorCtor.prototype.constructor = ErrorCtor;
13370
13371                 return ErrorCtor;
13372         };
13373 });
13374
13375 },
13376 'dojo/_base/array':function(){
13377 define(["./kernel", "../has", "./lang"], function(dojo, has, lang){
13378         // module:
13379         //              dojo/_base/array
13380
13381         // our old simple function builder stuff
13382         var cache = {}, u;
13383
13384         function buildFn(fn){
13385                 return cache[fn] = new Function("item", "index", "array", fn); // Function
13386         }
13387         // magic snippet: if(typeof fn == "string") fn = cache[fn] || buildFn(fn);
13388
13389         // every & some
13390
13391         function everyOrSome(some){
13392                 var every = !some;
13393                 return function(a, fn, o){
13394                         var i = 0, l = a && a.length || 0, result;
13395                         if(l && typeof a == "string") a = a.split("");
13396                         if(typeof fn == "string") fn = cache[fn] || buildFn(fn);
13397                         if(o){
13398                                 for(; i < l; ++i){
13399                                         result = !fn.call(o, a[i], i, a);
13400                                         if(some ^ result){
13401                                                 return !result;
13402                                         }
13403                                 }
13404                         }else{
13405                                 for(; i < l; ++i){
13406                                         result = !fn(a[i], i, a);
13407                                         if(some ^ result){
13408                                                 return !result;
13409                                         }
13410                                 }
13411                         }
13412                         return every; // Boolean
13413                 };
13414         }
13415
13416         // indexOf, lastIndexOf
13417
13418         function index(up){
13419                 var delta = 1, lOver = 0, uOver = 0;
13420                 if(!up){
13421                         delta = lOver = uOver = -1;
13422                 }
13423                 return function(a, x, from, last){
13424                         if(last && delta > 0){
13425                                 // TODO: why do we use a non-standard signature? why do we need "last"?
13426                                 return array.lastIndexOf(a, x, from);
13427                         }
13428                         var l = a && a.length || 0, end = up ? l + uOver : lOver, i;
13429                         if(from === u){
13430                                 i = up ? lOver : l + uOver;
13431                         }else{
13432                                 if(from < 0){
13433                                         i = l + from;
13434                                         if(i < 0){
13435                                                 i = lOver;
13436                                         }
13437                                 }else{
13438                                         i = from >= l ? l + uOver : from;
13439                                 }
13440                         }
13441                         if(l && typeof a == "string") a = a.split("");
13442                         for(; i != end; i += delta){
13443                                 if(a[i] == x){
13444                                         return i; // Number
13445                                 }
13446                         }
13447                         return -1; // Number
13448                 };
13449         }
13450
13451         var array = {
13452                 // summary:
13453                 //              The Javascript v1.6 array extensions.
13454
13455                 every: everyOrSome(false),
13456                 /*=====
13457                  every: function(arr, callback, thisObject){
13458                          // summary:
13459                          //             Determines whether or not every item in arr satisfies the
13460                          //             condition implemented by callback.
13461                          // arr: Array|String
13462                          //             the array to iterate on. If a string, operates on individual characters.
13463                          // callback: Function|String
13464                          //             a function is invoked with three arguments: item, index,
13465                          //             and array and returns true if the condition is met.
13466                          // thisObject: Object?
13467                          //             may be used to scope the call to callback
13468                          // returns: Boolean
13469                          // description:
13470                          //             This function corresponds to the JavaScript 1.6 Array.every() method, with one difference: when
13471                          //             run over sparse arrays, this implementation passes the "holes" in the sparse array to
13472                          //             the callback function with a value of undefined. JavaScript 1.6's every skips the holes in the sparse array.
13473                          //             For more details, see:
13474                          //             https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/every
13475                          // example:
13476                          //     |       // returns false
13477                          //     |       array.every([1, 2, 3, 4], function(item){ return item>1; });
13478                          // example:
13479                          //     |       // returns true
13480                          //     |       array.every([1, 2, 3, 4], function(item){ return item>0; });
13481                  },
13482                  =====*/
13483
13484                 some: everyOrSome(true),
13485                 /*=====
13486                 some: function(arr, callback, thisObject){
13487                         // summary:
13488                         //              Determines whether or not any item in arr satisfies the
13489                         //              condition implemented by callback.
13490                         // arr: Array|String
13491                         //              the array to iterate over. If a string, operates on individual characters.
13492                         // callback: Function|String
13493                         //              a function is invoked with three arguments: item, index,
13494                         //              and array and returns true if the condition is met.
13495                         // thisObject: Object?
13496                         //              may be used to scope the call to callback
13497                         // returns: Boolean
13498                         // description:
13499                         //              This function corresponds to the JavaScript 1.6 Array.some() method, with one difference: when
13500                         //              run over sparse arrays, this implementation passes the "holes" in the sparse array to
13501                         //              the callback function with a value of undefined. JavaScript 1.6's some skips the holes in the sparse array.
13502                         //              For more details, see:
13503                         //              https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/some
13504                         // example:
13505                         //      | // is true
13506                         //      | array.some([1, 2, 3, 4], function(item){ return item>1; });
13507                         // example:
13508                         //      | // is false
13509                         //      | array.some([1, 2, 3, 4], function(item){ return item<1; });
13510                 },
13511                 =====*/
13512
13513                 indexOf: index(true),
13514                 /*=====
13515                 indexOf: function(arr, value, fromIndex, findLast){
13516                         // summary:
13517                         //              locates the first index of the provided value in the
13518                         //              passed array. If the value is not found, -1 is returned.
13519                         // description:
13520                         //              This method corresponds to the JavaScript 1.6 Array.indexOf method, with one difference: when
13521                         //              run over sparse arrays, the Dojo function invokes the callback for every index whereas JavaScript
13522                         //              1.6's indexOf skips the holes in the sparse array.
13523                         //              For details on this method, see:
13524                         //              https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/indexOf
13525                         // arr: Array
13526                         // value: Object
13527                         // fromIndex: Integer?
13528                         // findLast: Boolean?
13529                         // returns: Number
13530                 },
13531                 =====*/
13532
13533                 lastIndexOf: index(false),
13534                 /*=====
13535                 lastIndexOf: function(arr, value, fromIndex){
13536                         // summary:
13537                         //              locates the last index of the provided value in the passed
13538                         //              array. If the value is not found, -1 is returned.
13539                         // description:
13540                         //              This method corresponds to the JavaScript 1.6 Array.lastIndexOf method, with one difference: when
13541                         //              run over sparse arrays, the Dojo function invokes the callback for every index whereas JavaScript
13542                         //              1.6's lastIndexOf skips the holes in the sparse array.
13543                         //              For details on this method, see:
13544                         //              https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/lastIndexOf
13545                         // arr: Array,
13546                         // value: Object,
13547                         // fromIndex: Integer?
13548                         // returns: Number
13549                 },
13550                 =====*/
13551
13552                 forEach: function(arr, callback, thisObject){
13553                         // summary:
13554                         //              for every item in arr, callback is invoked. Return values are ignored.
13555                         //              If you want to break out of the loop, consider using array.every() or array.some().
13556                         //              forEach does not allow breaking out of the loop over the items in arr.
13557                         // arr:
13558                         //              the array to iterate over. If a string, operates on individual characters.
13559                         // callback:
13560                         //              a function is invoked with three arguments: item, index, and array
13561                         // thisObject:
13562                         //              may be used to scope the call to callback
13563                         // description:
13564                         //              This function corresponds to the JavaScript 1.6 Array.forEach() method, with one difference: when
13565                         //              run over sparse arrays, this implementation passes the "holes" in the sparse array to
13566                         //              the callback function with a value of undefined. JavaScript 1.6's forEach skips the holes in the sparse array.
13567                         //              For more details, see:
13568                         //              https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/forEach
13569                         // example:
13570                         //      | // log out all members of the array:
13571                         //      | array.forEach(
13572                         //      |               [ "thinger", "blah", "howdy", 10 ],
13573                         //      |               function(item){
13574                         //      |                       console.log(item);
13575                         //      |               }
13576                         //      | );
13577                         // example:
13578                         //      | // log out the members and their indexes
13579                         //      | array.forEach(
13580                         //      |               [ "thinger", "blah", "howdy", 10 ],
13581                         //      |               function(item, idx, arr){
13582                         //      |                       console.log(item, "at index:", idx);
13583                         //      |               }
13584                         //      | );
13585                         // example:
13586                         //      | // use a scoped object member as the callback
13587                         //      |
13588                         //      | var obj = {
13589                         //      |               prefix: "logged via obj.callback:",
13590                         //      |               callback: function(item){
13591                         //      |                       console.log(this.prefix, item);
13592                         //      |               }
13593                         //      | };
13594                         //      |
13595                         //      | // specifying the scope function executes the callback in that scope
13596                         //      | array.forEach(
13597                         //      |               [ "thinger", "blah", "howdy", 10 ],
13598                         //      |               obj.callback,
13599                         //      |               obj
13600                         //      | );
13601                         //      |
13602                         //      | // alternately, we can accomplish the same thing with lang.hitch()
13603                         //      | array.forEach(
13604                         //      |               [ "thinger", "blah", "howdy", 10 ],
13605                         //      |               lang.hitch(obj, "callback")
13606                         //      | );
13607                         // arr: Array|String
13608                         // callback: Function|String
13609                         // thisObject: Object?
13610
13611                         var i = 0, l = arr && arr.length || 0;
13612                         if(l && typeof arr == "string") arr = arr.split("");
13613                         if(typeof callback == "string") callback = cache[callback] || buildFn(callback);
13614                         if(thisObject){
13615                                 for(; i < l; ++i){
13616                                         callback.call(thisObject, arr[i], i, arr);
13617                                 }
13618                         }else{
13619                                 for(; i < l; ++i){
13620                                         callback(arr[i], i, arr);
13621                                 }
13622                         }
13623                 },
13624
13625                 map: function(arr, callback, thisObject, Ctr){
13626                         // summary:
13627                         //              applies callback to each element of arr and returns
13628                         //              an Array with the results
13629                         // arr: Array|String
13630                         //              the array to iterate on. If a string, operates on
13631                         //              individual characters.
13632                         // callback: Function|String
13633                         //              a function is invoked with three arguments, (item, index,
13634                         //              array),  and returns a value
13635                         // thisObject: Object?
13636                         //              may be used to scope the call to callback
13637                         // returns: Array
13638                         // description:
13639                         //              This function corresponds to the JavaScript 1.6 Array.map() method, with one difference: when
13640                         //              run over sparse arrays, this implementation passes the "holes" in the sparse array to
13641                         //              the callback function with a value of undefined. JavaScript 1.6's map skips the holes in the sparse array.
13642                         //              For more details, see:
13643                         //              https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map
13644                         // example:
13645                         //      | // returns [2, 3, 4, 5]
13646                         //      | array.map([1, 2, 3, 4], function(item){ return item+1 });
13647
13648                         // TODO: why do we have a non-standard signature here? do we need "Ctr"?
13649                         var i = 0, l = arr && arr.length || 0, out = new (Ctr || Array)(l);
13650                         if(l && typeof arr == "string") arr = arr.split("");
13651                         if(typeof callback == "string") callback = cache[callback] || buildFn(callback);
13652                         if(thisObject){
13653                                 for(; i < l; ++i){
13654                                         out[i] = callback.call(thisObject, arr[i], i, arr);
13655                                 }
13656                         }else{
13657                                 for(; i < l; ++i){
13658                                         out[i] = callback(arr[i], i, arr);
13659                                 }
13660                         }
13661                         return out; // Array
13662                 },
13663
13664                 filter: function(arr, callback, thisObject){
13665                         // summary:
13666                         //              Returns a new Array with those items from arr that match the
13667                         //              condition implemented by callback.
13668                         // arr: Array
13669                         //              the array to iterate over.
13670                         // callback: Function|String
13671                         //              a function that is invoked with three arguments (item,
13672                         //              index, array). The return of this function is expected to
13673                         //              be a boolean which determines whether the passed-in item
13674                         //              will be included in the returned array.
13675                         // thisObject: Object?
13676                         //              may be used to scope the call to callback
13677                         // returns: Array
13678                         // description:
13679                         //              This function corresponds to the JavaScript 1.6 Array.filter() method, with one difference: when
13680                         //              run over sparse arrays, this implementation passes the "holes" in the sparse array to
13681                         //              the callback function with a value of undefined. JavaScript 1.6's filter skips the holes in the sparse array.
13682                         //              For more details, see:
13683                         //              https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter
13684                         // example:
13685                         //      | // returns [2, 3, 4]
13686                         //      | array.filter([1, 2, 3, 4], function(item){ return item>1; });
13687
13688                         // TODO: do we need "Ctr" here like in map()?
13689                         var i = 0, l = arr && arr.length || 0, out = [], value;
13690                         if(l && typeof arr == "string") arr = arr.split("");
13691                         if(typeof callback == "string") callback = cache[callback] || buildFn(callback);
13692                         if(thisObject){
13693                                 for(; i < l; ++i){
13694                                         value = arr[i];
13695                                         if(callback.call(thisObject, value, i, arr)){
13696                                                 out.push(value);
13697                                         }
13698                                 }
13699                         }else{
13700                                 for(; i < l; ++i){
13701                                         value = arr[i];
13702                                         if(callback(value, i, arr)){
13703                                                 out.push(value);
13704                                         }
13705                                 }
13706                         }
13707                         return out; // Array
13708                 },
13709
13710                 clearCache: function(){
13711                         cache = {};
13712                 }
13713         };
13714
13715
13716          1  && lang.mixin(dojo, array);
13717
13718         return array;
13719 });
13720
13721 },
13722 'dojo/_base/json':function(){
13723 define(["./kernel", "../json"], function(dojo, json){
13724
13725 // module:
13726 //              dojo/_base/json
13727
13728 /*=====
13729 return {
13730         // summary:
13731         //              This module defines the dojo JSON API.
13732 };
13733 =====*/
13734
13735 dojo.fromJson = function(/*String*/ js){
13736         // summary:
13737         //              Parses a JavaScript expression and returns a JavaScript value.
13738         // description:
13739         //              Throws for invalid JavaScript expressions. It does not use a strict JSON parser. It
13740         //              always delegates to eval(). The content passed to this method must therefore come
13741         //              from a trusted source.
13742         //              It is recommend that you use dojo/json's parse function for an
13743         //              implementation uses the (faster) native JSON parse when available.
13744         // js:
13745         //              a string literal of a JavaScript expression, for instance:
13746         //              `'{ "foo": [ "bar", 1, { "baz": "thud" } ] }'`
13747
13748         return eval("(" + js + ")"); // Object
13749 };
13750
13751 /*=====
13752 dojo._escapeString = function(){
13753         // summary:
13754         //              Adds escape sequences for non-visual characters, double quote and
13755         //              backslash and surrounds with double quotes to form a valid string
13756         //              literal.
13757 };
13758 =====*/
13759 dojo._escapeString = json.stringify; // just delegate to json.stringify
13760
13761 dojo.toJsonIndentStr = "\t";
13762 dojo.toJson = function(/*Object*/ it, /*Boolean?*/ prettyPrint){
13763         // summary:
13764         //              Returns a [JSON](http://json.org) serialization of an object.
13765         // description:
13766         //              Returns a [JSON](http://json.org) serialization of an object.
13767         //              Note that this doesn't check for infinite recursion, so don't do that!
13768         //              It is recommend that you use dojo/json's stringify function for an lighter
13769         //              and faster implementation that matches the native JSON API and uses the
13770         //              native JSON serializer when available.
13771         // it:
13772         //              an object to be serialized. Objects may define their own
13773         //              serialization via a special "__json__" or "json" function
13774         //              property. If a specialized serializer has been defined, it will
13775         //              be used as a fallback.
13776         //              Note that in 1.6, toJson would serialize undefined, but this no longer supported
13777         //              since it is not supported by native JSON serializer.
13778         // prettyPrint:
13779         //              if true, we indent objects and arrays to make the output prettier.
13780         //              The variable `dojo.toJsonIndentStr` is used as the indent string --
13781         //              to use something other than the default (tab), change that variable
13782         //              before calling dojo.toJson().
13783         //              Note that if native JSON support is available, it will be used for serialization,
13784         //              and native implementations vary on the exact spacing used in pretty printing.
13785         // returns:
13786         //              A JSON string serialization of the passed-in object.
13787         // example:
13788         //              simple serialization of a trivial object
13789         //              |       var jsonStr = dojo.toJson({ howdy: "stranger!", isStrange: true });
13790         //              |       doh.is('{"howdy":"stranger!","isStrange":true}', jsonStr);
13791         // example:
13792         //              a custom serializer for an objects of a particular class:
13793         //              |       dojo.declare("Furby", null, {
13794         //              |               furbies: "are strange",
13795         //              |               furbyCount: 10,
13796         //              |               __json__: function(){
13797         //              |               },
13798         //              |       });
13799
13800         // use dojo/json
13801         return json.stringify(it, function(key, value){
13802                 if(value){
13803                         var tf = value.__json__||value.json;
13804                         if(typeof tf == "function"){
13805                                 return tf.call(value);
13806                         }
13807                 }
13808                 return value;
13809         }, prettyPrint && dojo.toJsonIndentStr);        // String
13810 };
13811
13812 return dojo;
13813 });
13814
13815 },
13816 'dojo/_base/window':function(){
13817 define("dojo/_base/window", ["./kernel", "./lang", "../sniff"], function(dojo, lang, has){
13818 // module:
13819 //              dojo/_base/window
13820
13821 var ret = {
13822         // summary:
13823         //              API to save/set/restore the global/document scope.
13824
13825         global: dojo.global,
13826         /*=====
13827          global: {
13828                  // summary:
13829                  //             Alias for the current window. 'global' can be modified
13830                  //             for temporary context shifting. See also withGlobal().
13831                  // description:
13832                  //             Use this rather than referring to 'window' to ensure your code runs
13833                  //             correctly in managed contexts.
13834          },
13835          =====*/
13836
13837         doc: this["document"] || null,
13838         /*=====
13839         doc: {
13840                 // summary:
13841                 //              Alias for the current document. 'doc' can be modified
13842                 //              for temporary context shifting. See also withDoc().
13843                 // description:
13844                 //              Use this rather than referring to 'window.document' to ensure your code runs
13845                 //              correctly in managed contexts.
13846                 // example:
13847                 //      |       n.appendChild(dojo.doc.createElement('div'));
13848         },
13849         =====*/
13850
13851         body: function(/*Document?*/ doc){
13852                 // summary:
13853                 //              Return the body element of the specified document or of dojo/_base/window::doc.
13854                 // example:
13855                 //      |       win.body().appendChild(dojo.doc.createElement('div'));
13856
13857                 // Note: document.body is not defined for a strict xhtml document
13858                 // Would like to memoize this, but dojo.doc can change vi dojo.withDoc().
13859                 doc = doc || dojo.doc;
13860                 return doc.body || doc.getElementsByTagName("body")[0]; // Node
13861         },
13862
13863         setContext: function(/*Object*/ globalObject, /*DocumentElement*/ globalDocument){
13864                 // summary:
13865                 //              changes the behavior of many core Dojo functions that deal with
13866                 //              namespace and DOM lookup, changing them to work in a new global
13867                 //              context (e.g., an iframe). The varibles dojo.global and dojo.doc
13868                 //              are modified as a result of calling this function and the result of
13869                 //              `dojo.body()` likewise differs.
13870                 dojo.global = ret.global = globalObject;
13871                 dojo.doc = ret.doc = globalDocument;
13872         },
13873
13874         withGlobal: function(   /*Object*/ globalObject,
13875                                                         /*Function*/ callback,
13876                                                         /*Object?*/ thisObject,
13877                                                         /*Array?*/ cbArguments){
13878                 // summary:
13879                 //              Invoke callback with globalObject as dojo.global and
13880                 //              globalObject.document as dojo.doc.
13881                 // description:
13882                 //              Invoke callback with globalObject as dojo.global and
13883                 //              globalObject.document as dojo.doc. If provided, globalObject
13884                 //              will be executed in the context of object thisObject
13885                 //              When callback() returns or throws an error, the dojo.global
13886                 //              and dojo.doc will be restored to its previous state.
13887
13888                 var oldGlob = dojo.global;
13889                 try{
13890                         dojo.global = ret.global = globalObject;
13891                         return ret.withDoc.call(null, globalObject.document, callback, thisObject, cbArguments);
13892                 }finally{
13893                         dojo.global = ret.global = oldGlob;
13894                 }
13895         },
13896
13897         withDoc: function(      /*DocumentElement*/ documentObject,
13898                                                 /*Function*/ callback,
13899                                                 /*Object?*/ thisObject,
13900                                                 /*Array?*/ cbArguments){
13901                 // summary:
13902                 //              Invoke callback with documentObject as dojo/_base/window::doc.
13903                 // description:
13904                 //              Invoke callback with documentObject as dojo/_base/window::doc. If provided,
13905                 //              callback will be executed in the context of object thisObject
13906                 //              When callback() returns or throws an error, the dojo/_base/window::doc will
13907                 //              be restored to its previous state.
13908
13909                 var oldDoc = ret.doc,
13910                         oldQ = has("quirks"),
13911                         oldIE = has("ie"), isIE, mode, pwin;
13912
13913                 try{
13914                         dojo.doc = ret.doc = documentObject;
13915                         // update dojo.isQuirks and the value of the has feature "quirks".
13916                         // remove setting dojo.isQuirks and dojo.isIE for 2.0
13917                         dojo.isQuirks = has.add("quirks", dojo.doc.compatMode == "BackCompat", true, true); // no need to check for QuirksMode which was Opera 7 only
13918
13919                         if(has("ie")){
13920                                 if((pwin = documentObject.parentWindow) && pwin.navigator){
13921                                         // re-run IE detection logic and update dojo.isIE / has("ie")
13922                                         // (the only time parentWindow/navigator wouldn't exist is if we were not
13923                                         // passed an actual legitimate document object)
13924                                         isIE = parseFloat(pwin.navigator.appVersion.split("MSIE ")[1]) || undefined;
13925                                         mode = documentObject.documentMode;
13926                                         if(mode && mode != 5 && Math.floor(isIE) != mode){
13927                                                 isIE = mode;
13928                                         }
13929                                         dojo.isIE = has.add("ie", isIE, true, true);
13930                                 }
13931                         }
13932
13933                         if(thisObject && typeof callback == "string"){
13934                                 callback = thisObject[callback];
13935                         }
13936
13937                         return callback.apply(thisObject, cbArguments || []);
13938                 }finally{
13939                         dojo.doc = ret.doc = oldDoc;
13940                         dojo.isQuirks = has.add("quirks", oldQ, true, true);
13941                         dojo.isIE = has.add("ie", oldIE, true, true);
13942                 }
13943         }
13944 };
13945
13946  1  && lang.mixin(dojo, ret);
13947
13948 return ret;
13949
13950 });
13951
13952 },
13953 'dojo/dom-class':function(){
13954 define(["./_base/lang", "./_base/array", "./dom"], function(lang, array, dom){
13955         // module:
13956         //              dojo/dom-class
13957
13958         var className = "className";
13959
13960         /* Part I of classList-based implementation is preserved here for posterity
13961         var classList = "classList";
13962         has.add("dom-classList", function(){
13963                 return classList in document.createElement("p");
13964         });
13965         */
13966
13967         // =============================
13968         // (CSS) Class Functions
13969         // =============================
13970
13971         var cls, // exports object
13972                 spaces = /\s+/, a1 = [""];
13973
13974         function str2array(s){
13975                 if(typeof s == "string" || s instanceof String){
13976                         if(s && !spaces.test(s)){
13977                                 a1[0] = s;
13978                                 return a1;
13979                         }
13980                         var a = s.split(spaces);
13981                         if(a.length && !a[0]){
13982                                 a.shift();
13983                         }
13984                         if(a.length && !a[a.length - 1]){
13985                                 a.pop();
13986                         }
13987                         return a;
13988                 }
13989                 // assumed to be an array
13990                 if(!s){
13991                         return [];
13992                 }
13993                 return array.filter(s, function(x){ return x; });
13994         }
13995
13996         /* Part II of classList-based implementation is preserved here for posterity
13997         if(has("dom-classList")){
13998                 // new classList version
13999                 cls = {
14000                         contains: function containsClass(node, classStr){
14001                                 var clslst = classStr && dom.byId(node)[classList];
14002                                 return clslst && clslst.contains(classStr); // Boolean
14003                         },
14004
14005                         add: function addClass(node, classStr){
14006                                 node = dom.byId(node);
14007                                 classStr = str2array(classStr);
14008                                 for(var i = 0, len = classStr.length; i < len; ++i){
14009                                         node[classList].add(classStr[i]);
14010                                 }
14011                         },
14012
14013                         remove: function removeClass(node, classStr){
14014                                 node = dom.byId(node);
14015                                 if(classStr === undefined){
14016                                         node[className] = "";
14017                                 }else{
14018                                         classStr = str2array(classStr);
14019                                         for(var i = 0, len = classStr.length; i < len; ++i){
14020                                                 node[classList].remove(classStr[i]);
14021                                         }
14022                                 }
14023                         },
14024
14025                         replace: function replaceClass(node, addClassStr, removeClassStr){
14026                                 node = dom.byId(node);
14027                                 if(removeClassStr === undefined){
14028                                         node[className] = "";
14029                                 }else{
14030                                         removeClassStr = str2array(removeClassStr);
14031                                         for(var i = 0, len = removeClassStr.length; i < len; ++i){
14032                                                 node[classList].remove(removeClassStr[i]);
14033                                         }
14034                                 }
14035                                 addClassStr = str2array(addClassStr);
14036                                 for(i = 0, len = addClassStr.length; i < len; ++i){
14037                                         node[classList].add(addClassStr[i]);
14038                                 }
14039                         },
14040
14041                         toggle: function toggleClass(node, classStr, condition){
14042                                 node = dom.byId(node);
14043                                 if(condition === undefined){
14044                                         classStr = str2array(classStr);
14045                                         for(var i = 0, len = classStr.length; i < len; ++i){
14046                                                 node[classList].toggle(classStr[i]);
14047                                         }
14048                                 }else{
14049                                         cls[condition ? "add" : "remove"](node, classStr);
14050                                 }
14051                                 return condition;   // Boolean
14052                         }
14053                 }
14054         }
14055         */
14056
14057         // regular DOM version
14058         var fakeNode = {};  // for effective replacement
14059         cls = {
14060                 // summary:
14061                 //              This module defines the core dojo DOM class API.
14062
14063                 contains: function containsClass(/*DomNode|String*/ node, /*String*/ classStr){
14064                         // summary:
14065                         //              Returns whether or not the specified classes are a portion of the
14066                         //              class list currently applied to the node.
14067                         // node: String|DOMNode
14068                         //              String ID or DomNode reference to check the class for.
14069                         // classStr: String
14070                         //              A string class name to look for.
14071                         // example:
14072                         //              Do something if a node with id="someNode" has class="aSillyClassName" present
14073                         //      |       if(dojo.hasClass("someNode","aSillyClassName")){ ... }
14074
14075                         return ((" " + dom.byId(node)[className] + " ").indexOf(" " + classStr + " ") >= 0); // Boolean
14076                 },
14077
14078                 add: function addClass(/*DomNode|String*/ node, /*String|Array*/ classStr){
14079                         // summary:
14080                         //              Adds the specified classes to the end of the class list on the
14081                         //              passed node. Will not re-apply duplicate classes.
14082                         //
14083                         // node: String|DOMNode
14084                         //              String ID or DomNode reference to add a class string too
14085                         //
14086                         // classStr: String|Array
14087                         //              A String class name to add, or several space-separated class names,
14088                         //              or an array of class names.
14089                         //
14090                         // example:
14091                         //              Add a class to some node:
14092                         //      |       require(["dojo/dom-class"], function(domClass){
14093                         //      |               domClass.add("someNode", "anewClass");
14094                         //      |       });
14095                         //
14096                         // example:
14097                         //              Add two classes at once:
14098                         //      |       require(["dojo/dom-class"], function(domClass){
14099                         //      |               domClass.add("someNode", "firstClass secondClass");
14100                         //      |       });
14101                         //
14102                         // example:
14103                         //              Add two classes at once (using array):
14104                         //      |       require(["dojo/dom-class"], function(domClass){
14105                         //      |               domClass.add("someNode", ["firstClass", "secondClass"]);
14106                         //      |       });
14107                         //
14108                         // example:
14109                         //              Available in `dojo/NodeList` for multiple additions
14110                         //      |       require(["dojo/query"], function(query){
14111                         //      |               query("ul > li").addClass("firstLevel");
14112                         //      |       });
14113
14114                         node = dom.byId(node);
14115                         classStr = str2array(classStr);
14116                         var cls = node[className], oldLen;
14117                         cls = cls ? " " + cls + " " : " ";
14118                         oldLen = cls.length;
14119                         for(var i = 0, len = classStr.length, c; i < len; ++i){
14120                                 c = classStr[i];
14121                                 if(c && cls.indexOf(" " + c + " ") < 0){
14122                                         cls += c + " ";
14123                                 }
14124                         }
14125                         if(oldLen < cls.length){
14126                                 node[className] = cls.substr(1, cls.length - 2);
14127                         }
14128                 },
14129
14130                 remove: function removeClass(/*DomNode|String*/ node, /*String|Array?*/ classStr){
14131                         // summary:
14132                         //              Removes the specified classes from node. No `contains()`
14133                         //              check is required.
14134                         //
14135                         // node: String|DOMNode
14136                         //              String ID or DomNode reference to remove the class from.
14137                         //
14138                         // classStr: String|Array
14139                         //              An optional String class name to remove, or several space-separated
14140                         //              class names, or an array of class names. If omitted, all class names
14141                         //              will be deleted.
14142                         //
14143                         // example:
14144                         //              Remove a class from some node:
14145                         //      |       require(["dojo/dom-class"], function(domClass){
14146                         //      |               domClass.remove("someNode", "firstClass");
14147                         //      |       });
14148                         //
14149                         // example:
14150                         //              Remove two classes from some node:
14151                         //      |       require(["dojo/dom-class"], function(domClass){
14152                         //      |               domClass.remove("someNode", "firstClass secondClass");
14153                         //      |       });
14154                         //
14155                         // example:
14156                         //              Remove two classes from some node (using array):
14157                         //      |       require(["dojo/dom-class"], function(domClass){
14158                         //      |               domClass.remove("someNode", ["firstClass", "secondClass"]);
14159                         //      |       });
14160                         //
14161                         // example:
14162                         //              Remove all classes from some node:
14163                         //      |       require(["dojo/dom-class"], function(domClass){
14164                         //      |               domClass.remove("someNode");
14165                         //      |       });
14166                         //
14167                         // example:
14168                         //              Available in `dojo/NodeList` for multiple removal
14169                         //      |       require(["dojo/query"], function(query){
14170                         //      |               query("ul > li").removeClass("foo");
14171                         //      |       });
14172
14173                         node = dom.byId(node);
14174                         var cls;
14175                         if(classStr !== undefined){
14176                                 classStr = str2array(classStr);
14177                                 cls = " " + node[className] + " ";
14178                                 for(var i = 0, len = classStr.length; i < len; ++i){
14179                                         cls = cls.replace(" " + classStr[i] + " ", " ");
14180                                 }
14181                                 cls = lang.trim(cls);
14182                         }else{
14183                                 cls = "";
14184                         }
14185                         if(node[className] != cls){ node[className] = cls; }
14186                 },
14187
14188                 replace: function replaceClass(/*DomNode|String*/ node, /*String|Array*/ addClassStr, /*String|Array?*/ removeClassStr){
14189                         // summary:
14190                         //              Replaces one or more classes on a node if not present.
14191                         //              Operates more quickly than calling dojo.removeClass and dojo.addClass
14192                         //
14193                         // node: String|DOMNode
14194                         //              String ID or DomNode reference to remove the class from.
14195                         //
14196                         // addClassStr: String|Array
14197                         //              A String class name to add, or several space-separated class names,
14198                         //              or an array of class names.
14199                         //
14200                         // removeClassStr: String|Array?
14201                         //              A String class name to remove, or several space-separated class names,
14202                         //              or an array of class names.
14203                         //
14204                         // example:
14205                         //      |       require(["dojo/dom-class"], function(domClass){
14206                         //      |               domClass.replace("someNode", "add1 add2", "remove1 remove2");
14207                         //      |       });
14208                         //
14209                         // example:
14210                         //      Replace all classes with addMe
14211                         //      |       require(["dojo/dom-class"], function(domClass){
14212                         //      |               domClass.replace("someNode", "addMe");
14213                         //      |       });
14214                         //
14215                         // example:
14216                         //      Available in `dojo/NodeList` for multiple toggles
14217                         //      |       require(["dojo/query"], function(query){
14218                         //      |               query(".findMe").replaceClass("addMe", "removeMe");
14219                         //      |       });
14220
14221                         node = dom.byId(node);
14222                         fakeNode[className] = node[className];
14223                         cls.remove(fakeNode, removeClassStr);
14224                         cls.add(fakeNode, addClassStr);
14225                         if(node[className] !== fakeNode[className]){
14226                                 node[className] = fakeNode[className];
14227                         }
14228                 },
14229
14230                 toggle: function toggleClass(/*DomNode|String*/ node, /*String|Array*/ classStr, /*Boolean?*/ condition){
14231                         // summary:
14232                         //              Adds a class to node if not present, or removes if present.
14233                         //              Pass a boolean condition if you want to explicitly add or remove.
14234                         //              Returns the condition that was specified directly or indirectly.
14235                         //
14236                         // node: String|DOMNode
14237                         //              String ID or DomNode reference to toggle a class string
14238                         //
14239                         // classStr: String|Array
14240                         //              A String class name to toggle, or several space-separated class names,
14241                         //              or an array of class names.
14242                         //
14243                         // condition:
14244                         //              If passed, true means to add the class, false means to remove.
14245                         //              Otherwise dojo.hasClass(node, classStr) is used to detect the class presence.
14246                         //
14247                         // example:
14248                         //      |       require(["dojo/dom-class"], function(domClass){
14249                         //      |               domClass.toggle("someNode", "hovered");
14250                         //      |       });
14251                         //
14252                         // example:
14253                         //              Forcefully add a class
14254                         //      |       require(["dojo/dom-class"], function(domClass){
14255                         //      |               domClass.toggle("someNode", "hovered", true);
14256                         //      |       });
14257                         //
14258                         // example:
14259                         //              Available in `dojo/NodeList` for multiple toggles
14260                         //      |       require(["dojo/query"], function(query){
14261                         //      |               query(".toggleMe").toggleClass("toggleMe");
14262                         //      |       });
14263
14264                         node = dom.byId(node);
14265                         if(condition === undefined){
14266                                 classStr = str2array(classStr);
14267                                 for(var i = 0, len = classStr.length, c; i < len; ++i){
14268                                         c = classStr[i];
14269                                         cls[cls.contains(node, c) ? "remove" : "add"](node, c);
14270                                 }
14271                         }else{
14272                                 cls[condition ? "add" : "remove"](node, classStr);
14273                         }
14274                         return condition;   // Boolean
14275                 }
14276         };
14277
14278         return cls;
14279 });
14280
14281 },
14282 'dojo/_base/config':function(){
14283 define(["../has", "require"], function(has, require){
14284         // module:
14285         //              dojo/_base/config
14286
14287 /*=====
14288 return {
14289         // summary:
14290         //              This module defines the user configuration during bootstrap.
14291         // description:
14292         //              By defining user configuration as a module value, an entire configuration can be specified in a build,
14293         //              thereby eliminating the need for sniffing and or explicitly setting in the global variable dojoConfig.
14294         //              Also, when multiple instances of dojo exist in a single application, each will necessarily be located
14295         //              at an unique absolute module identifier as given by the package configuration. Implementing configuration
14296         //              as a module allows for specifying unique, per-instance configurations.
14297         // example:
14298         //              Create a second instance of dojo with a different, instance-unique configuration (assume the loader and
14299         //              dojo.js are already loaded).
14300         //              |       // specify a configuration that creates a new instance of dojo at the absolute module identifier "myDojo"
14301         //              |       require({
14302         //              |               packages:[{
14303         //              |                       name:"myDojo",
14304         //              |                       location:".", //assume baseUrl points to dojo.js
14305         //              |               }]
14306         //              |       });
14307         //              |
14308         //              |       // specify a configuration for the myDojo instance
14309         //              |       define("myDojo/config", {
14310         //              |               // normal configuration variables go here, e.g.,
14311         //              |               locale:"fr-ca"
14312         //              |       });
14313         //              |
14314         //              |       // load and use the new instance of dojo
14315         //              |       require(["myDojo"], function(dojo){
14316         //              |               // dojo is the new instance of dojo
14317         //              |               // use as required
14318         //              |       });
14319
14320         // isDebug: Boolean
14321         //              Defaults to `false`. If set to `true`, ensures that Dojo provides
14322         //              extended debugging feedback via Firebug. If Firebug is not available
14323         //              on your platform, setting `isDebug` to `true` will force Dojo to
14324         //              pull in (and display) the version of Firebug Lite which is
14325         //              integrated into the Dojo distribution, thereby always providing a
14326         //              debugging/logging console when `isDebug` is enabled. Note that
14327         //              Firebug's `console.*` methods are ALWAYS defined by Dojo. If
14328         //              `isDebug` is false and you are on a platform without Firebug, these
14329         //              methods will be defined as no-ops.
14330         isDebug: false,
14331
14332         // locale: String
14333         //              The locale to assume for loading localized resources in this page,
14334         //              specified according to [RFC 3066](http://www.ietf.org/rfc/rfc3066.txt).
14335         //              Must be specified entirely in lowercase, e.g. `en-us` and `zh-cn`.
14336         //              See the documentation for `dojo.i18n` and `dojo.requireLocalization`
14337         //              for details on loading localized resources. If no locale is specified,
14338         //              Dojo assumes the locale of the user agent, according to `navigator.userLanguage`
14339         //              or `navigator.language` properties.
14340         locale: undefined,
14341
14342         // extraLocale: Array
14343         //              No default value. Specifies additional locales whose
14344         //              resources should also be loaded alongside the default locale when
14345         //              calls to `dojo.requireLocalization()` are processed.
14346         extraLocale: undefined,
14347
14348         // baseUrl: String
14349         //              The directory in which `dojo.js` is located. Under normal
14350         //              conditions, Dojo auto-detects the correct location from which it
14351         //              was loaded. You may need to manually configure `baseUrl` in cases
14352         //              where you have renamed `dojo.js` or in which `<base>` tags confuse
14353         //              some browsers (e.g. IE 6). The variable `dojo.baseUrl` is assigned
14354         //              either the value of `djConfig.baseUrl` if one is provided or the
14355         //              auto-detected root if not. Other modules are located relative to
14356         //              this path. The path should end in a slash.
14357         baseUrl: undefined,
14358
14359         // modulePaths: [deprecated] Object
14360         //              A map of module names to paths relative to `dojo.baseUrl`. The
14361         //              key/value pairs correspond directly to the arguments which
14362         //              `dojo.registerModulePath` accepts. Specifying
14363         //              `djConfig.modulePaths = { "foo": "../../bar" }` is the equivalent
14364         //              of calling `dojo.registerModulePath("foo", "../../bar");`. Multiple
14365         //              modules may be configured via `djConfig.modulePaths`.
14366         modulePaths: {},
14367
14368         // addOnLoad: Function|Array
14369         //              Adds a callback via dojo/ready. Useful when Dojo is added after
14370         //              the page loads and djConfig.afterOnLoad is true. Supports the same
14371         //              arguments as dojo/ready. When using a function reference, use
14372         //              `djConfig.addOnLoad = function(){};`. For object with function name use
14373         //              `djConfig.addOnLoad = [myObject, "functionName"];` and for object with
14374         //              function reference use
14375         //              `djConfig.addOnLoad = [myObject, function(){}];`
14376         addOnLoad: null,
14377
14378         // parseOnLoad: Boolean
14379         //              Run the parser after the page is loaded
14380         parseOnLoad: false,
14381
14382         // require: String[]
14383         //              An array of module names to be loaded immediately after dojo.js has been included
14384         //              in a page.
14385         require: [],
14386
14387         // defaultDuration: Number
14388         //              Default duration, in milliseconds, for wipe and fade animations within dijits.
14389         //              Assigned to dijit.defaultDuration.
14390         defaultDuration: 200,
14391
14392         // dojoBlankHtmlUrl: String
14393         //              Used by some modules to configure an empty iframe. Used by dojo/io/iframe and
14394         //              dojo/back, and dijit/popup support in IE where an iframe is needed to make sure native
14395         //              controls do not bleed through the popups. Normally this configuration variable
14396         //              does not need to be set, except when using cross-domain/CDN Dojo builds.
14397         //              Save dojo/resources/blank.html to your domain and set `djConfig.dojoBlankHtmlUrl`
14398         //              to the path on your domain your copy of blank.html.
14399         dojoBlankHtmlUrl: undefined,
14400
14401         // ioPublish: Boolean?
14402         //              Set this to true to enable publishing of topics for the different phases of
14403         //              IO operations. Publishing is done via dojo/topic.publish(). See dojo/main.__IoPublish for a list
14404         //              of topics that are published.
14405         ioPublish: false,
14406
14407         // useCustomLogger: Anything?
14408         //              If set to a value that evaluates to true such as a string or array and
14409         //              isDebug is true and Firebug is not available or running, then it bypasses
14410         //              the creation of Firebug Lite allowing you to define your own console object.
14411         useCustomLogger: undefined,
14412
14413         // transparentColor: Array
14414         //              Array containing the r, g, b components used as transparent color in dojo.Color;
14415         //              if undefined, [255,255,255] (white) will be used.
14416         transparentColor: undefined,
14417         
14418         // deps: Function|Array
14419         //              Defines dependencies to be used before the loader has been loaded.
14420         //              When provided, they cause the loader to execute require(deps, callback) 
14421         //              once it has finished loading. Should be used with callback.
14422         deps: undefined,
14423         
14424         // callback: Function|Array
14425         //              Defines a callback to be used when dependencies are defined before 
14426         //              the loader has been loaded. When provided, they cause the loader to 
14427         //              execute require(deps, callback) once it has finished loading. 
14428         //              Should be used with deps.
14429         callback: undefined,
14430         
14431         // deferredInstrumentation: Boolean
14432         //              Whether deferred instrumentation should be loaded or included
14433         //              in builds.
14434         deferredInstrumentation: true,
14435
14436         // useDeferredInstrumentation: Boolean|String
14437         //              Whether the deferred instrumentation should be used.
14438         //
14439         //              * `"report-rejections"`: report each rejection as it occurs.
14440         //              * `true` or `1` or `"report-unhandled-rejections"`: wait 1 second
14441         //                      in an attempt to detect unhandled rejections.
14442         useDeferredInstrumentation: "report-unhandled-rejections"
14443 };
14444 =====*/
14445
14446         var result = {};
14447         if( 1 ){
14448                 // must be the dojo loader; take a shallow copy of require.rawConfig
14449                 var src = require.rawConfig, p;
14450                 for(p in src){
14451                         result[p] = src[p];
14452                 }
14453         }else{
14454                 var adviseHas = function(featureSet, prefix, booting){
14455                         for(p in featureSet){
14456                                 p!="has" && has.add(prefix + p, featureSet[p], 0, booting);
14457                         }
14458                 };
14459                 result =  1  ?
14460                         // must be a built version of the dojo loader; all config stuffed in require.rawConfig
14461                         require.rawConfig :
14462                         // a foreign loader
14463                         this.dojoConfig || this.djConfig || {};
14464                 adviseHas(result, "config", 1);
14465                 adviseHas(result.has, "", 1);
14466         }
14467         return result;
14468 });
14469
14470
14471 },
14472 'dojo/_base/event':function(){
14473 define("dojo/_base/event", ["./kernel", "../on", "../has", "../dom-geometry"], function(dojo, on, has, dom){
14474         // module:
14475         //              dojo/_base/event
14476
14477         if(on._fixEvent){
14478                 var fixEvent = on._fixEvent;
14479                 on._fixEvent = function(evt, se){
14480                         // add some additional normalization for back-compat, this isn't in on.js because it is somewhat more expensive
14481                         evt = fixEvent(evt, se);
14482                         if(evt){
14483                                 dom.normalizeEvent(evt);
14484                         }
14485                         return evt;
14486                 };              
14487         }
14488         
14489         var ret = {
14490                 // summary:
14491                 //              This module defines dojo DOM event API.   Usually you should use dojo/on, and evt.stopPropagation() +
14492                 //              evt.preventDefault(), rather than this module.
14493
14494                 fix: function(/*Event*/ evt, /*DOMNode*/ sender){
14495                         // summary:
14496                         //              normalizes properties on the event object including event
14497                         //              bubbling methods, keystroke normalization, and x/y positions
14498                         // evt: Event
14499                         //              native event object
14500                         // sender: DOMNode
14501                         //              node to treat as "currentTarget"
14502                         if(on._fixEvent){
14503                                 return on._fixEvent(evt, sender);
14504                         }
14505                         return evt;     // Event
14506                 },
14507         
14508                 stop: function(/*Event*/ evt){
14509                         // summary:
14510                         //              prevents propagation and clobbers the default action of the
14511                         //              passed event
14512                         // evt: Event
14513                         //              The event object. If omitted, window.event is used on IE.
14514                         if(has("dom-addeventlistener") || (evt && evt.preventDefault)){
14515                                 evt.preventDefault();
14516                                 evt.stopPropagation();
14517                         }else{
14518                                 evt = evt || window.event;
14519                                 evt.cancelBubble = true;
14520                                 on._preventDefault.call(evt);
14521                         }
14522                 }
14523         };
14524
14525         if( 1 ){
14526                 dojo.fixEvent = ret.fix;
14527                 dojo.stopEvent = ret.stop;
14528         }
14529
14530         return ret;
14531 });
14532
14533 },
14534 'dojo/main':function(){
14535 define([
14536         "./_base/kernel",       // kernel.isAsync
14537         "./has",
14538         "require",
14539         "./sniff",
14540         "./_base/lang",
14541         "./_base/array",
14542         "./_base/config",
14543         "./ready",
14544         "./_base/declare",
14545         "./_base/connect",
14546         "./_base/Deferred",
14547         "./_base/json",
14548         "./_base/Color",
14549         "./has!dojo-firebug?./_firebug/firebug",
14550         "./_base/browser",
14551         "./_base/loader"
14552 ], function(kernel, has, require, sniff, lang, array, config, ready){
14553         // module:
14554         //              dojo/main
14555         // summary:
14556         //              This is the package main module for the dojo package; it loads dojo base appropriate for the execution environment.
14557
14558         // the preferred way to load the dojo firebug console is by setting has("dojo-firebug") true in dojoConfig
14559         // the isDebug config switch is for backcompat and will work fine in sync loading mode; it works in
14560         // async mode too, but there's no guarantee when the module is loaded; therefore, if you need a firebug
14561         // console guaranteed at a particular spot in an app, either set config.has["dojo-firebug"] true before
14562         // loading dojo.js or explicitly include dojo/_firebug/firebug in a dependency list.
14563         if(config.isDebug){
14564                 require(["./_firebug/firebug"]);
14565         }
14566
14567         // dojoConfig.require is deprecated; use the loader configuration property deps
14568          1 || has.add("dojo-config-require", 1);
14569         if( 1 ){
14570                 var deps= config.require;
14571                 if(deps){
14572                         // config.require may be dot notation
14573                         deps= array.map(lang.isArray(deps) ? deps : [deps], function(item){ return item.replace(/\./g, "/"); });
14574                         if(kernel.isAsync){
14575                                 require(deps);
14576                         }else{
14577                                 // this is a bit janky; in 1.6- dojo is defined before these requires are applied; but in 1.7+
14578                                 // dojo isn't defined until returning from this module; this is only a problem in sync mode
14579                                 // since we're in sync mode, we know we've got our loader with its priority ready queue
14580                                 ready(1, function(){require(deps);});
14581                         }
14582                 }
14583         }
14584
14585         return kernel;
14586 });
14587
14588 },
14589 'dojo/sniff':function(){
14590 define(["./has"], function(has){
14591         // module:
14592         //              dojo/sniff
14593
14594         /*=====
14595         return function(){
14596                 // summary:
14597                 //              This module sets has() flags based on the current browser.
14598                 //              It returns the has() function.
14599         };
14600         =====*/
14601
14602         if( 1 ){
14603                 var n = navigator,
14604                         dua = n.userAgent,
14605                         dav = n.appVersion,
14606                         tv = parseFloat(dav);
14607
14608                 has.add("air", dua.indexOf("AdobeAIR") >= 0),
14609                 has.add("khtml", dav.indexOf("Konqueror") >= 0 ? tv : undefined);
14610                 has.add("webkit", parseFloat(dua.split("WebKit/")[1]) || undefined);
14611                 has.add("chrome", parseFloat(dua.split("Chrome/")[1]) || undefined);
14612                 has.add("safari", dav.indexOf("Safari")>=0 && !has("chrome") ? parseFloat(dav.split("Version/")[1]) : undefined);
14613                 has.add("mac", dav.indexOf("Macintosh") >= 0);
14614                 has.add("quirks", document.compatMode == "BackCompat");
14615                 has.add("ios", /iPhone|iPod|iPad/.test(dua));
14616                 has.add("android", parseFloat(dua.split("Android ")[1]) || undefined);
14617
14618                 if(!has("webkit")){
14619                         // Opera
14620                         if(dua.indexOf("Opera") >= 0){
14621                                 // see http://dev.opera.com/articles/view/opera-ua-string-changes and http://www.useragentstring.com/pages/Opera/
14622                                 // 9.8 has both styles; <9.8, 9.9 only old style
14623                                 has.add("opera", tv >= 9.8 ? parseFloat(dua.split("Version/")[1]) || tv : tv);
14624                         }
14625
14626                         // Mozilla and firefox
14627                         if(dua.indexOf("Gecko") >= 0 && !has("khtml") && !has("webkit")){
14628                                 has.add("mozilla", tv);
14629                         }
14630                         if(has("mozilla")){
14631                                 //We really need to get away from this. Consider a sane isGecko approach for the future.
14632                                 has.add("ff", parseFloat(dua.split("Firefox/")[1] || dua.split("Minefield/")[1]) || undefined);
14633                         }
14634
14635                         // IE
14636                         if(document.all && !has("opera")){
14637                                 var isIE = parseFloat(dav.split("MSIE ")[1]) || undefined;
14638
14639                                 //In cases where the page has an HTTP header or META tag with
14640                                 //X-UA-Compatible, then it is in emulation mode.
14641                                 //Make sure isIE reflects the desired version.
14642                                 //document.documentMode of 5 means quirks mode.
14643                                 //Only switch the value if documentMode's major version
14644                                 //is different from isIE's major version.
14645                                 var mode = document.documentMode;
14646                                 if(mode && mode != 5 && Math.floor(isIE) != mode){
14647                                         isIE = mode;
14648                                 }
14649
14650                                 has.add("ie", isIE);
14651                         }
14652
14653                         // Wii
14654                         has.add("wii", typeof opera != "undefined" && opera.wiiremote);
14655                 }
14656         }
14657
14658         return has;
14659 });
14660
14661 },
14662 'dojo/request/handlers':function(){
14663 define([
14664         '../json',
14665         '../_base/kernel',
14666         '../_base/array',
14667         '../has'
14668 ], function(JSON, kernel, array, has){
14669         has.add('activex', typeof ActiveXObject !== 'undefined');
14670
14671         var handleXML;
14672         if(has('activex')){
14673                 // GUIDs obtained from http://msdn.microsoft.com/en-us/library/ms757837(VS.85).aspx
14674                 var dp = [
14675                         'Msxml2.DOMDocument.6.0',
14676                         'Msxml2.DOMDocument.4.0',
14677                         'MSXML2.DOMDocument.3.0',
14678                         'MSXML.DOMDocument' // 2.0
14679                 ];
14680
14681                 handleXML = function(response){
14682                         var result = response.data;
14683
14684                         if(!result || !result.documentElement){
14685                                 var text = response.text;
14686                                 array.some(dp, function(p){
14687                                         try{
14688                                                 var dom = new ActiveXObject(p);
14689                                                 dom.async = false;
14690                                                 dom.loadXML(text);
14691                                                 result = dom;
14692                                         }catch(e){ return false; }
14693                                         return true;
14694                                 });
14695                         }
14696
14697                         return result;
14698                 };
14699         }
14700
14701         var handlers = {
14702                 'javascript': function(response){
14703                         return kernel.eval(response.text || '');
14704                 },
14705                 'json': function(response){
14706                         return JSON.parse(response.text || null);
14707                 },
14708                 'xml': handleXML
14709         };
14710
14711         function handle(response){
14712                 var handler = handlers[response.options.handleAs];
14713
14714                 response.data = handler ? handler(response) : (response.data || response.text);
14715
14716                 return response;
14717         }
14718
14719         handle.register = function(name, handler){
14720                 handlers[name] = handler;
14721         };
14722
14723         return handle;
14724 });
14725
14726 },
14727 'dojo/ready':function(){
14728 define("dojo/ready", ["./_base/kernel", "./has", "require", "./domReady", "./_base/lang"], function(dojo, has, require, domReady, lang){
14729         // module:
14730         //              dojo/ready
14731         // note:
14732         //              This module should be unnecessary in dojo 2.0
14733
14734         var
14735                 // truthy if DOMContentLoaded or better (e.g., window.onload fired) has been achieved
14736                 isDomReady = 0,
14737
14738                 // a function to call to cause onLoad to be called when all requested modules have been loaded
14739                 requestCompleteSignal,
14740
14741                 // The queue of functions waiting to execute as soon as dojo.ready conditions satisfied
14742                 loadQ = [],
14743
14744                 // prevent recursion in onLoad
14745                 onLoadRecursiveGuard = 0,
14746
14747                 handleDomReady = function(){
14748                         isDomReady = 1;
14749                         dojo._postLoad = dojo.config.afterOnLoad = true;
14750                         if(loadQ.length){
14751                                 requestCompleteSignal(onLoad);
14752                         }
14753                 },
14754
14755                 // run the next function queued with dojo.ready
14756                 onLoad = function(){
14757                         if(isDomReady && !onLoadRecursiveGuard && loadQ.length){
14758                                 //guard against recursions into this function
14759                                 onLoadRecursiveGuard = 1;
14760                                 var f = loadQ.shift();
14761                                         try{
14762                                                 f();
14763                                         }
14764                                                 // FIXME: signal the error via require.on
14765                                         finally{
14766                                                 onLoadRecursiveGuard = 0;
14767                                         }
14768                                 onLoadRecursiveGuard = 0;
14769                                 if(loadQ.length){
14770                                         requestCompleteSignal(onLoad);
14771                                 }
14772                         }
14773                 };
14774
14775         require.on("idle", onLoad);
14776         requestCompleteSignal = function(){
14777                 if(require.idle()){
14778                         onLoad();
14779                 } // else do nothing, onLoad will be called with the next idle signal
14780         };
14781
14782         var ready = dojo.ready = dojo.addOnLoad = function(priority, context, callback){
14783                 // summary:
14784                 //              Add a function to execute on DOM content loaded and all requested modules have arrived and been evaluated.
14785                 //              In most cases, the `domReady` plug-in should suffice and this method should not be needed.
14786                 // priority: Integer?
14787                 //              The order in which to exec this callback relative to other callbacks, defaults to 1000
14788                 // context: Object?|Function
14789                 //              The context in which to run execute callback, or a callback if not using context
14790                 // callback: Function?
14791                 //              The function to execute.
14792                 //
14793                 // example:
14794                 //      Simple DOM and Modules ready syntax
14795                 //      |       require(["dojo/ready"], function(ready){
14796                 //      |               ready(function(){ alert("Dom ready!"); });
14797                 //      |       });
14798                 //
14799                 // example:
14800                 //      Using a priority
14801                 //      |       require(["dojo/ready"], function(ready){
14802                 //      |               ready(2, function(){ alert("low priority ready!"); })
14803                 //      |       });
14804                 //
14805                 // example:
14806                 //      Using context
14807                 //      |       require(["dojo/ready"], function(ready){
14808                 //      |               ready(foo, function(){
14809                 //      |                       // in here, this == foo
14810                 //      |               });
14811                 //      |       });
14812                 //
14813                 // example:
14814                 //      Using dojo/hitch style args:
14815                 //      |       require(["dojo/ready"], function(ready){
14816                 //      |               var foo = { dojoReady: function(){ console.warn(this, "dojo dom and modules ready."); } };
14817                 //      |               ready(foo, "dojoReady");
14818                 //      |       });
14819
14820                 var hitchArgs = lang._toArray(arguments);
14821                 if(typeof priority != "number"){
14822                         callback = context;
14823                         context = priority;
14824                         priority = 1000;
14825                 }else{
14826                         hitchArgs.shift();
14827                 }
14828                 callback = callback ?
14829                         lang.hitch.apply(dojo, hitchArgs) :
14830                         function(){
14831                                 context();
14832                         };
14833                 callback.priority = priority;
14834                 for(var i = 0; i < loadQ.length && priority >= loadQ[i].priority; i++){}
14835                 loadQ.splice(i, 0, callback);
14836                 requestCompleteSignal();
14837         };
14838
14839          1 || has.add("dojo-config-addOnLoad", 1);
14840         if( 1 ){
14841                 var dca = dojo.config.addOnLoad;
14842                 if(dca){
14843                         ready[(lang.isArray(dca) ? "apply" : "call")](dojo, dca);
14844                 }
14845         }
14846
14847         if( 1  && dojo.config.parseOnLoad && !dojo.isAsync){
14848                 ready(99, function(){
14849                         if(!dojo.parser){
14850                                 dojo.deprecated("Add explicit require(['dojo/parser']);", "", "2.0");
14851                                 require(["dojo/parser"]);
14852                         }
14853                 });
14854         }
14855
14856         if( 1 ){
14857                 domReady(handleDomReady);
14858         }else{
14859                 handleDomReady();
14860         }
14861
14862         return ready;
14863 });
14864
14865 },
14866 'dojo/aspect':function(){
14867 define("dojo/aspect", [], function(){
14868
14869         // module:
14870         //              dojo/aspect
14871
14872         "use strict";
14873         var undefined, nextId = 0;
14874         function advise(dispatcher, type, advice, receiveArguments){
14875                 var previous = dispatcher[type];
14876                 var around = type == "around";
14877                 var signal;
14878                 if(around){
14879                         var advised = advice(function(){
14880                                 return previous.advice(this, arguments);
14881                         });
14882                         signal = {
14883                                 remove: function(){
14884                                         signal.cancelled = true;
14885                                 },
14886                                 advice: function(target, args){
14887                                         return signal.cancelled ?
14888                                                 previous.advice(target, args) : // cancelled, skip to next one
14889                                                 advised.apply(target, args);    // called the advised function
14890                                 }
14891                         };
14892                 }else{
14893                         // create the remove handler
14894                         signal = {
14895                                 remove: function(){
14896                                         var previous = signal.previous;
14897                                         var next = signal.next;
14898                                         if(!next && !previous){
14899                                                 delete dispatcher[type];
14900                                         }else{
14901                                                 if(previous){
14902                                                         previous.next = next;
14903                                                 }else{
14904                                                         dispatcher[type] = next;
14905                                                 }
14906                                                 if(next){
14907                                                         next.previous = previous;
14908                                                 }
14909                                         }
14910                                 },
14911                                 id: nextId++,
14912                                 advice: advice,
14913                                 receiveArguments: receiveArguments
14914                         };
14915                 }
14916                 if(previous && !around){
14917                         if(type == "after"){
14918                                 // add the listener to the end of the list
14919                                 // note that we had to change this loop a little bit to workaround a bizarre IE10 JIT bug 
14920                                 while(previous.next && (previous = previous.next)){}
14921                                 previous.next = signal;
14922                                 signal.previous = previous;
14923                         }else if(type == "before"){
14924                                 // add to beginning
14925                                 dispatcher[type] = signal;
14926                                 signal.next = previous;
14927                                 previous.previous = signal;
14928                         }
14929                 }else{
14930                         // around or first one just replaces
14931                         dispatcher[type] = signal;
14932                 }
14933                 return signal;
14934         }
14935         function aspect(type){
14936                 return function(target, methodName, advice, receiveArguments){
14937                         var existing = target[methodName], dispatcher;
14938                         if(!existing || existing.target != target){
14939                                 // no dispatcher in place
14940                                 target[methodName] = dispatcher = function(){
14941                                         var executionId = nextId;
14942                                         // before advice
14943                                         var args = arguments;
14944                                         var before = dispatcher.before;
14945                                         while(before){
14946                                                 args = before.advice.apply(this, args) || args;
14947                                                 before = before.next;
14948                                         }
14949                                         // around advice
14950                                         if(dispatcher.around){
14951                                                 var results = dispatcher.around.advice(this, args);
14952                                         }
14953                                         // after advice
14954                                         var after = dispatcher.after;
14955                                         while(after && after.id < executionId){
14956                                                 if(after.receiveArguments){
14957                                                         var newResults = after.advice.apply(this, args);
14958                                                         // change the return value only if a new value was returned
14959                                                         results = newResults === undefined ? results : newResults;
14960                                                 }else{
14961                                                         results = after.advice.call(this, results, args);
14962                                                 }
14963                                                 after = after.next;
14964                                         }
14965                                         return results;
14966                                 };
14967                                 if(existing){
14968                                         dispatcher.around = {advice: function(target, args){
14969                                                 return existing.apply(target, args);
14970                                         }};
14971                                 }
14972                                 dispatcher.target = target;
14973                         }
14974                         var results = advise((dispatcher || existing), type, advice, receiveArguments);
14975                         advice = null;
14976                         return results;
14977                 };
14978         }
14979
14980         // TODOC: after/before/around return object
14981
14982         var after = aspect("after");
14983         /*=====
14984         after = function(target, methodName, advice, receiveArguments){
14985                 // summary:
14986                 //              The "after" export of the aspect module is a function that can be used to attach
14987                 //              "after" advice to a method. This function will be executed after the original method
14988                 //              is executed. By default the function will be called with a single argument, the return
14989                 //              value of the original method, or the the return value of the last executed advice (if a previous one exists).
14990                 //              The fourth (optional) argument can be set to true to so the function receives the original
14991                 //              arguments (from when the original method was called) rather than the return value.
14992                 //              If there are multiple "after" advisors, they are executed in the order they were registered.
14993                 // target: Object
14994                 //              This is the target object
14995                 // methodName: String
14996                 //              This is the name of the method to attach to.
14997                 // advice: Function
14998                 //              This is function to be called after the original method
14999                 // receiveArguments: Boolean?
15000                 //              If this is set to true, the advice function receives the original arguments (from when the original mehtod
15001                 //              was called) rather than the return value of the original/previous method.
15002                 // returns:
15003                 //              A signal object that can be used to cancel the advice. If remove() is called on this signal object, it will
15004                 //              stop the advice function from being executed.
15005         };
15006         =====*/
15007
15008         var before = aspect("before");
15009         /*=====
15010         before = function(target, methodName, advice){
15011                 // summary:
15012                 //              The "before" export of the aspect module is a function that can be used to attach
15013                 //              "before" advice to a method. This function will be executed before the original method
15014                 //              is executed. This function will be called with the arguments used to call the method.
15015                 //              This function may optionally return an array as the new arguments to use to call
15016                 //              the original method (or the previous, next-to-execute before advice, if one exists).
15017                 //              If the before method doesn't return anything (returns undefined) the original arguments
15018                 //              will be preserved.
15019                 //              If there are multiple "before" advisors, they are executed in the reverse order they were registered.
15020                 // target: Object
15021                 //              This is the target object
15022                 // methodName: String
15023                 //              This is the name of the method to attach to.
15024                 // advice: Function
15025                 //              This is function to be called before the original method
15026         };
15027         =====*/
15028
15029         var around = aspect("around");
15030         /*=====
15031          around = function(target, methodName, advice){
15032                 // summary:
15033                 //              The "around" export of the aspect module is a function that can be used to attach
15034                 //              "around" advice to a method. The advisor function is immediately executed when
15035                 //              the around() is called, is passed a single argument that is a function that can be
15036                 //              called to continue execution of the original method (or the next around advisor).
15037                 //              The advisor function should return a function, and this function will be called whenever
15038                 //              the method is called. It will be called with the arguments used to call the method.
15039                 //              Whatever this function returns will be returned as the result of the method call (unless after advise changes it).
15040                 // example:
15041                 //              If there are multiple "around" advisors, the most recent one is executed first,
15042                 //              which can then delegate to the next one and so on. For example:
15043                 //              |       around(obj, "foo", function(originalFoo){
15044                 //              |               return function(){
15045                 //              |                       var start = new Date().getTime();
15046                 //              |                       var results = originalFoo.apply(this, arguments); // call the original
15047                 //              |                       var end = new Date().getTime();
15048                 //              |                       console.log("foo execution took " + (end - start) + " ms");
15049                 //              |                       return results;
15050                 //              |               };
15051                 //              |       });
15052                 // target: Object
15053                 //              This is the target object
15054                 // methodName: String
15055                 //              This is the name of the method to attach to.
15056                 // advice: Function
15057                 //              This is function to be called around the original method
15058         };
15059         =====*/
15060
15061         return {
15062                 // summary:
15063                 //              provides aspect oriented programming functionality, allowing for
15064                 //              one to add before, around, or after advice on existing methods.
15065                 // example:
15066                 //      |       define(["dojo/aspect"], function(aspect){
15067                 //      |               var signal = aspect.after(targetObject, "methodName", function(someArgument){
15068                 //      |                       this will be called when targetObject.methodName() is called, after the original function is called
15069                 //      |               });
15070                 //
15071                 // example:
15072                 //      The returned signal object can be used to cancel the advice.
15073                 //      |       signal.remove(); // this will stop the advice from being executed anymore
15074                 //      |       aspect.before(targetObject, "methodName", function(someArgument){
15075                 //      |               // this will be called when targetObject.methodName() is called, before the original function is called
15076                 //      |        });
15077
15078                 before: before,
15079                 around: around,
15080                 after: after
15081         };
15082 });
15083
15084 },
15085 'dojo/_base/connect':function(){
15086 define(["./kernel", "../on", "../topic", "../aspect", "./event", "../mouse", "./sniff", "./lang", "../keys"], function(dojo, on, hub, aspect, eventModule, mouse, has, lang){
15087 // module:
15088 //              dojo/_base/connect
15089
15090 has.add("events-keypress-typed", function(){ // keypresses should only occur a printable character is hit
15091         var testKeyEvent = {charCode: 0};
15092         try{
15093                 testKeyEvent = document.createEvent("KeyboardEvent");
15094                 (testKeyEvent.initKeyboardEvent || testKeyEvent.initKeyEvent).call(testKeyEvent, "keypress", true, true, null, false, false, false, false, 9, 3);
15095         }catch(e){}
15096         return testKeyEvent.charCode == 0 && !has("opera");
15097 });
15098
15099 function connect_(obj, event, context, method, dontFix){
15100         method = lang.hitch(context, method);
15101         if(!obj || !(obj.addEventListener || obj.attachEvent)){
15102                 // it is a not a DOM node and we are using the dojo.connect style of treating a
15103                 // method like an event, must go right to aspect
15104                 return aspect.after(obj || dojo.global, event, method, true);
15105         }
15106         if(typeof event == "string" && event.substring(0, 2) == "on"){
15107                 event = event.substring(2);
15108         }
15109         if(!obj){
15110                 obj = dojo.global;
15111         }
15112         if(!dontFix){
15113                 switch(event){
15114                         // dojo.connect has special handling for these event types
15115                         case "keypress":
15116                                 event = keypress;
15117                                 break;
15118                         case "mouseenter":
15119                                 event = mouse.enter;
15120                                 break;
15121                         case "mouseleave":
15122                                 event = mouse.leave;
15123                                 break;
15124                 }
15125         }
15126         return on(obj, event, method, dontFix);
15127 }
15128
15129 var _punctMap = {
15130         106:42,
15131         111:47,
15132         186:59,
15133         187:43,
15134         188:44,
15135         189:45,
15136         190:46,
15137         191:47,
15138         192:96,
15139         219:91,
15140         220:92,
15141         221:93,
15142         222:39,
15143         229:113
15144 };
15145 var evtCopyKey = has("mac") ? "metaKey" : "ctrlKey";
15146
15147
15148 var _synthesizeEvent = function(evt, props){
15149         var faux = lang.mixin({}, evt, props);
15150         setKeyChar(faux);
15151         // FIXME: would prefer to use lang.hitch: lang.hitch(evt, evt.preventDefault);
15152         // but it throws an error when preventDefault is invoked on Safari
15153         // does Event.preventDefault not support "apply" on Safari?
15154         faux.preventDefault = function(){ evt.preventDefault(); };
15155         faux.stopPropagation = function(){ evt.stopPropagation(); };
15156         return faux;
15157 };
15158 function setKeyChar(evt){
15159         evt.keyChar = evt.charCode ? String.fromCharCode(evt.charCode) : '';
15160         evt.charOrCode = evt.keyChar || evt.keyCode;
15161 }
15162 var keypress;
15163 if(has("events-keypress-typed")){
15164         // this emulates Firefox's keypress behavior where every keydown can correspond to a keypress
15165         var _trySetKeyCode = function(e, code){
15166                 try{
15167                         // squelch errors when keyCode is read-only
15168                         // (e.g. if keyCode is ctrl or shift)
15169                         return (e.keyCode = code);
15170                 }catch(e){
15171                         return 0;
15172                 }
15173         };
15174         keypress = function(object, listener){
15175                 var keydownSignal = on(object, "keydown", function(evt){
15176                         // munge key/charCode
15177                         var k=evt.keyCode;
15178                         // These are Windows Virtual Key Codes
15179                         // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/WinUI/WindowsUserInterface/UserInput/VirtualKeyCodes.asp
15180                         var unprintable = (k!=13) && k!=32 && (k!=27||!has("ie")) && (k<48||k>90) && (k<96||k>111) && (k<186||k>192) && (k<219||k>222) && k!=229;
15181                         // synthesize keypress for most unprintables and CTRL-keys
15182                         if(unprintable||evt.ctrlKey){
15183                                 var c = unprintable ? 0 : k;
15184                                 if(evt.ctrlKey){
15185                                         if(k==3 || k==13){
15186                                                 return listener.call(evt.currentTarget, evt); // IE will post CTRL-BREAK, CTRL-ENTER as keypress natively
15187                                         }else if(c>95 && c<106){
15188                                                 c -= 48; // map CTRL-[numpad 0-9] to ASCII
15189                                         }else if((!evt.shiftKey)&&(c>=65&&c<=90)){
15190                                                 c += 32; // map CTRL-[A-Z] to lowercase
15191                                         }else{
15192                                                 c = _punctMap[c] || c; // map other problematic CTRL combinations to ASCII
15193                                         }
15194                                 }
15195                                 // simulate a keypress event
15196                                 var faux = _synthesizeEvent(evt, {type: 'keypress', faux: true, charCode: c});
15197                                 listener.call(evt.currentTarget, faux);
15198                                 if(has("ie")){
15199                                         _trySetKeyCode(evt, faux.keyCode);
15200                                 }
15201                         }
15202                 });
15203                 var keypressSignal = on(object, "keypress", function(evt){
15204                         var c = evt.charCode;
15205                         c = c>=32 ? c : 0;
15206                         evt = _synthesizeEvent(evt, {charCode: c, faux: true});
15207                         return listener.call(this, evt);
15208                 });
15209                 return {
15210                         remove: function(){
15211                                 keydownSignal.remove();
15212                                 keypressSignal.remove();
15213                         }
15214                 };
15215         };
15216 }else{
15217         if(has("opera")){
15218                 keypress = function(object, listener){
15219                         return on(object, "keypress", function(evt){
15220                                 var c = evt.which;
15221                                 if(c==3){
15222                                         c=99; // Mozilla maps CTRL-BREAK to CTRL-c
15223                                 }
15224                                 // can't trap some keys at all, like INSERT and DELETE
15225                                 // there is no differentiating info between DELETE and ".", or INSERT and "-"
15226                                 c = c<32 && !evt.shiftKey ? 0 : c;
15227                                 if(evt.ctrlKey && !evt.shiftKey && c>=65 && c<=90){
15228                                         // lowercase CTRL-[A-Z] keys
15229                                         c += 32;
15230                                 }
15231                                 return listener.call(this, _synthesizeEvent(evt, { charCode: c }));
15232                         });
15233                 };
15234         }else{
15235                 keypress = function(object, listener){
15236                         return on(object, "keypress", function(evt){
15237                                 setKeyChar(evt);
15238                                 return listener.call(this, evt);
15239                         });
15240                 };
15241         }
15242 }
15243
15244 var connect = {
15245         // summary:
15246         //              This module defines the dojo.connect API.
15247         //              This modules also provides keyboard event handling helpers.
15248         //              This module exports an extension event for emulating Firefox's keypress handling.
15249         //              However, this extension event exists primarily for backwards compatibility and
15250         //              is not recommended. WebKit and IE uses an alternate keypress handling (only
15251         //              firing for printable characters, to distinguish from keydown events), and most
15252         //              consider the WebKit/IE behavior more desirable.
15253
15254         _keypress:keypress,
15255
15256         connect:function(obj, event, context, method, dontFix){
15257                 // summary:
15258                 //              `dojo.connect` is a deprecated event handling and delegation method in
15259                 //              Dojo. It allows one function to "listen in" on the execution of
15260                 //              any other, triggering the second whenever the first is called. Many
15261                 //              listeners may be attached to a function, and source functions may
15262                 //              be either regular function calls or DOM events.
15263                 //
15264                 // description:
15265                 //              Connects listeners to actions, so that after event fires, a
15266                 //              listener is called with the same arguments passed to the original
15267                 //              function.
15268                 //
15269                 //              Since `dojo.connect` allows the source of events to be either a
15270                 //              "regular" JavaScript function or a DOM event, it provides a uniform
15271                 //              interface for listening to all the types of events that an
15272                 //              application is likely to deal with though a single, unified
15273                 //              interface. DOM programmers may want to think of it as
15274                 //              "addEventListener for everything and anything".
15275                 //
15276                 //              When setting up a connection, the `event` parameter must be a
15277                 //              string that is the name of the method/event to be listened for. If
15278                 //              `obj` is null, `kernel.global` is assumed, meaning that connections
15279                 //              to global methods are supported but also that you may inadvertently
15280                 //              connect to a global by passing an incorrect object name or invalid
15281                 //              reference.
15282                 //
15283                 //              `dojo.connect` generally is forgiving. If you pass the name of a
15284                 //              function or method that does not yet exist on `obj`, connect will
15285                 //              not fail, but will instead set up a stub method. Similarly, null
15286                 //              arguments may simply be omitted such that fewer than 4 arguments
15287                 //              may be required to set up a connection See the examples for details.
15288                 //
15289                 //              The return value is a handle that is needed to
15290                 //              remove this connection with `dojo.disconnect`.
15291                 //
15292                 // obj: Object?
15293                 //              The source object for the event function.
15294                 //              Defaults to `kernel.global` if null.
15295                 //              If obj is a DOM node, the connection is delegated
15296                 //              to the DOM event manager (unless dontFix is true).
15297                 //
15298                 // event: String
15299                 //              String name of the event function in obj.
15300                 //              I.e. identifies a property `obj[event]`.
15301                 //
15302                 // context: Object|null
15303                 //              The object that method will receive as "this".
15304                 //
15305                 //              If context is null and method is a function, then method
15306                 //              inherits the context of event.
15307                 //
15308                 //              If method is a string then context must be the source
15309                 //              object object for method (context[method]). If context is null,
15310                 //              kernel.global is used.
15311                 //
15312                 // method: String|Function
15313                 //              A function reference, or name of a function in context.
15314                 //              The function identified by method fires after event does.
15315                 //              method receives the same arguments as the event.
15316                 //              See context argument comments for information on method's scope.
15317                 //
15318                 // dontFix: Boolean?
15319                 //              If obj is a DOM node, set dontFix to true to prevent delegation
15320                 //              of this connection to the DOM event manager.
15321                 //
15322                 // example:
15323                 //              When obj.onchange(), do ui.update():
15324                 //      |       dojo.connect(obj, "onchange", ui, "update");
15325                 //      |       dojo.connect(obj, "onchange", ui, ui.update); // same
15326                 //
15327                 // example:
15328                 //              Using return value for disconnect:
15329                 //      |       var link = dojo.connect(obj, "onchange", ui, "update");
15330                 //      |       ...
15331                 //      |       dojo.disconnect(link);
15332                 //
15333                 // example:
15334                 //              When onglobalevent executes, watcher.handler is invoked:
15335                 //      |       dojo.connect(null, "onglobalevent", watcher, "handler");
15336                 //
15337                 // example:
15338                 //              When ob.onCustomEvent executes, customEventHandler is invoked:
15339                 //      |       dojo.connect(ob, "onCustomEvent", null, "customEventHandler");
15340                 //      |       dojo.connect(ob, "onCustomEvent", "customEventHandler"); // same
15341                 //
15342                 // example:
15343                 //              When ob.onCustomEvent executes, customEventHandler is invoked
15344                 //              with the same scope (this):
15345                 //      |       dojo.connect(ob, "onCustomEvent", null, customEventHandler);
15346                 //      |       dojo.connect(ob, "onCustomEvent", customEventHandler); // same
15347                 //
15348                 // example:
15349                 //              When globalEvent executes, globalHandler is invoked
15350                 //              with the same scope (this):
15351                 //      |       dojo.connect(null, "globalEvent", null, globalHandler);
15352                 //      |       dojo.connect("globalEvent", globalHandler); // same
15353
15354                 // normalize arguments
15355                 var a=arguments, args=[], i=0;
15356                 // if a[0] is a String, obj was omitted
15357                 args.push(typeof a[0] == "string" ? null : a[i++], a[i++]);
15358                 // if the arg-after-next is a String or Function, context was NOT omitted
15359                 var a1 = a[i+1];
15360                 args.push(typeof a1 == "string" || typeof a1 == "function" ? a[i++] : null, a[i++]);
15361                 // absorb any additional arguments
15362                 for(var l=a.length; i<l; i++){  args.push(a[i]); }
15363                 return connect_.apply(this, args);
15364         },
15365
15366         disconnect:function(handle){
15367                 // summary:
15368                 //              Remove a link created by dojo.connect.
15369                 // description:
15370                 //              Removes the connection between event and the method referenced by handle.
15371                 // handle: Handle
15372                 //              the return value of the dojo.connect call that created the connection.
15373
15374                 if(handle){
15375                         handle.remove();
15376                 }
15377         },
15378
15379         subscribe:function(topic, context, method){
15380                 // summary:
15381                 //              Attach a listener to a named topic. The listener function is invoked whenever the
15382                 //              named topic is published (see: dojo.publish).
15383                 //              Returns a handle which is needed to unsubscribe this listener.
15384                 // topic: String
15385                 //              The topic to which to subscribe.
15386                 // context: Object?
15387                 //              Scope in which method will be invoked, or null for default scope.
15388                 // method: String|Function
15389                 //              The name of a function in context, or a function reference. This is the function that
15390                 //              is invoked when topic is published.
15391                 // example:
15392                 //      |       dojo.subscribe("alerts", null, function(caption, message){ alert(caption + "\n" + message); });
15393                 //      |       dojo.publish("alerts", [ "read this", "hello world" ]);
15394                 return hub.subscribe(topic, lang.hitch(context, method));
15395         },
15396
15397         publish:function(topic, args){
15398                 // summary:
15399                 //              Invoke all listener method subscribed to topic.
15400                 // topic: String
15401                 //              The name of the topic to publish.
15402                 // args: Array?
15403                 //              An array of arguments. The arguments will be applied
15404                 //              to each topic subscriber (as first class parameters, via apply).
15405                 // example:
15406                 //      |       dojo.subscribe("alerts", null, function(caption, message){ alert(caption + "\n" + message); };
15407                 //      |       dojo.publish("alerts", [ "read this", "hello world" ]);
15408                 return hub.publish.apply(hub, [topic].concat(args));
15409         },
15410
15411         connectPublisher:function(topic, obj, event){
15412                 // summary:
15413                 //              Ensure that every time obj.event() is called, a message is published
15414                 //              on the topic. Returns a handle which can be passed to
15415                 //              dojo.disconnect() to disable subsequent automatic publication on
15416                 //              the topic.
15417                 // topic: String
15418                 //              The name of the topic to publish.
15419                 // obj: Object?
15420                 //              The source object for the event function. Defaults to kernel.global
15421                 //              if null.
15422                 // event: String
15423                 //              The name of the event function in obj.
15424                 //              I.e. identifies a property obj[event].
15425                 // example:
15426                 //      |       dojo.connectPublisher("/ajax/start", dojo, "xhrGet");
15427                 var pf = function(){ connect.publish(topic, arguments); };
15428                 return event ? connect.connect(obj, event, pf) : connect.connect(obj, pf); //Handle
15429         },
15430
15431         isCopyKey: function(e){
15432                 // summary:
15433                 //              Checks an event for the copy key (meta on Mac, and ctrl anywhere else)
15434                 // e: Event
15435                 //              Event object to examine
15436                 return e[evtCopyKey];   // Boolean
15437         }
15438 };
15439
15440 connect.unsubscribe = connect.disconnect;
15441 /*=====
15442  connect.unsubscribe = function(handle){
15443          // summary:
15444          //             Remove a topic listener.
15445          // handle: Handle
15446          //             The handle returned from a call to subscribe.
15447          // example:
15448          //     |       var alerter = dojo.subscribe("alerts", null, function(caption, message){ alert(caption + "\n" + message); };
15449          //     |       ...
15450          //     |       dojo.unsubscribe(alerter);
15451  };
15452  =====*/
15453
15454  1  && lang.mixin(dojo, connect);
15455 return connect;
15456
15457 });
15458
15459
15460
15461 },
15462 'dojo/errors/CancelError':function(){
15463 define(["./create"], function(create){
15464         // module:
15465         //              dojo/errors/CancelError
15466
15467         /*=====
15468         return function(){
15469                 // summary:
15470                 //              Default error if a promise is canceled without a reason.
15471         };
15472         =====*/
15473
15474         return create("CancelError", null, null, { dojoType: "cancel" });
15475 });
15476
15477 }}});
15478 (function(){
15479         // must use this.require to make this work in node.js
15480         var require = this.require;
15481         // consume the cached dojo layer
15482         require({cache:{}});
15483         !require.async && require(["dojo"]);
15484         require.boot && require.apply(null, require.boot);
15485 })();