--- /dev/null
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+/*
+ This is an optimized version of Dojo, built for deployment and not for
+ development. To get sources and documentation, please visit:
+
+ http://dojotoolkit.org
+*/
+
+;(function(){
+
+ /*
+ dojo, dijit, and dojox must always be the first three, and in that order.
+ djConfig.scopeMap = [
+ ["dojo", "fojo"],
+ ["dijit", "fijit"],
+ ["dojox", "fojox"]
+
+ ]
+ */
+
+ /**Build will replace this comment with a scoped djConfig **/
+
+ //The null below can be relaced by a build-time value used instead of djConfig.scopeMap.
+ var sMap = null;
+
+ //See if new scopes need to be defined.
+ if((sMap || (typeof djConfig != "undefined" && djConfig.scopeMap)) && (typeof window != "undefined")){
+ var scopeDef = "", scopePrefix = "", scopeSuffix = "", scopeMap = {}, scopeMapRev = {};
+ sMap = sMap || djConfig.scopeMap;
+ for(var i = 0; i < sMap.length; i++){
+ //Make local variables, then global variables that use the locals.
+ var newScope = sMap[i];
+ scopeDef += "var " + newScope[0] + " = {}; " + newScope[1] + " = " + newScope[0] + ";" + newScope[1] + "._scopeName = '" + newScope[1] + "';";
+ scopePrefix += (i == 0 ? "" : ",") + newScope[0];
+ scopeSuffix += (i == 0 ? "" : ",") + newScope[1];
+ scopeMap[newScope[0]] = newScope[1];
+ scopeMapRev[newScope[1]] = newScope[0];
+ }
+
+ eval(scopeDef + "dojo._scopeArgs = [" + scopeSuffix + "];");
+
+ dojo._scopePrefixArgs = scopePrefix;
+ dojo._scopePrefix = "(function(" + scopePrefix + "){";
+ dojo._scopeSuffix = "})(" + scopeSuffix + ")";
+ dojo._scopeMap = scopeMap;
+ dojo._scopeMapRev = scopeMapRev;
+ }
+
+/*=====
+// note:
+// 'djConfig' does not exist under 'dojo.*' so that it can be set before the
+// 'dojo' variable exists.
+// note:
+// Setting any of these variables *after* the library has loaded does
+// nothing at all.
+
+djConfig = {
+ // summary:
+ // Application code can set the global 'djConfig' prior to loading
+ // the library to override certain global settings for how dojo works.
+ //
+ // isDebug: Boolean
+ // Defaults to `false`. If set to `true`, ensures that Dojo provides
+ // extended debugging feedback via Firebug. If Firebug is not available
+ // on your platform, setting `isDebug` to `true` will force Dojo to
+ // pull in (and display) the version of Firebug Lite which is
+ // integrated into the Dojo distribution, thereby always providing a
+ // debugging/logging console when `isDebug` is enabled. Note that
+ // Firebug's `console.*` methods are ALWAYS defined by Dojo. If
+ // `isDebug` is false and you are on a platform without Firebug, these
+ // methods will be defined as no-ops.
+ isDebug: false,
+ // debugAtAllCosts: Boolean
+ // Defaults to `false`. If set to `true`, this triggers an alternate
+ // mode of the package system in which dependencies are detected and
+ // only then are resources evaluated in dependency order via
+ // `<script>` tag inclusion. This may double-request resources and
+ // cause problems with scripts which expect `dojo.require()` to
+ // preform synchronously. `debugAtAllCosts` can be an invaluable
+ // debugging aid, but when using it, ensure that all code which
+ // depends on Dojo modules is wrapped in `dojo.addOnLoad()` handlers.
+ // Due to the somewhat unpredictable side-effects of using
+ // `debugAtAllCosts`, it is strongly recommended that you enable this
+ // flag as a last resort. `debugAtAllCosts` has no effect when loading
+ // resources across domains. For usage information, see the
+ // [Dojo Book](http://dojotoolkit.org/book/book-dojo/part-4-meta-dojo-making-your-dojo-code-run-faster-and-better/debugging-facilities/deb)
+ debugAtAllCosts: false,
+ // locale: String
+ // The locale to assume for loading localized resources in this page,
+ // specified according to [RFC 3066](http://www.ietf.org/rfc/rfc3066.txt).
+ // Must be specified entirely in lowercase, e.g. `en-us` and `zh-cn`.
+ // See the documentation for `dojo.i18n` and `dojo.requireLocalization`
+ // for details on loading localized resources. If no locale is specified,
+ // Dojo assumes the locale of the user agent, according to `navigator.userLanguage`
+ // or `navigator.language` properties.
+ locale: undefined,
+ // extraLocale: Array
+ // No default value. Specifies additional locales whose
+ // resources should also be loaded alongside the default locale when
+ // calls to `dojo.requireLocalization()` are processed.
+ extraLocale: undefined,
+ // baseUrl: String
+ // The directory in which `dojo.js` is located. Under normal
+ // conditions, Dojo auto-detects the correct location from which it
+ // was loaded. You may need to manually configure `baseUrl` in cases
+ // where you have renamed `dojo.js` or in which `<base>` tags confuse
+ // some browsers (e.g. IE 6). The variable `dojo.baseUrl` is assigned
+ // either the value of `djConfig.baseUrl` if one is provided or the
+ // auto-detected root if not. Other modules are located relative to
+ // this path. The path should end in a slash.
+ baseUrl: undefined,
+ // modulePaths: Object
+ // A map of module names to paths relative to `dojo.baseUrl`. The
+ // key/value pairs correspond directly to the arguments which
+ // `dojo.registerModulePath` accepts. Specifiying
+ // `djConfig.modulePaths = { "foo": "../../bar" }` is the equivalent
+ // of calling `dojo.registerModulePath("foo", "../../bar");`. Multiple
+ // modules may be configured via `djConfig.modulePaths`.
+ modulePaths: {},
+ // afterOnLoad: Boolean
+ // Indicates Dojo was added to the page after the page load. In this case
+ // Dojo will not wait for the page DOMContentLoad/load events and fire
+ // its dojo.addOnLoad callbacks after making sure all outstanding
+ // dojo.required modules have loaded. Only works with a built dojo.js,
+ // it does not work the dojo.js directly from source control.
+ afterOnLoad: false,
+ // addOnLoad: Function or Array
+ // Adds a callback via dojo.addOnLoad. Useful when Dojo is added after
+ // the page loads and djConfig.afterOnLoad is true. Supports the same
+ // arguments as dojo.addOnLoad. When using a function reference, use
+ // `djConfig.addOnLoad = function(){};`. For object with function name use
+ // `djConfig.addOnLoad = [myObject, "functionName"];` and for object with
+ // function reference use
+ // `djConfig.addOnLoad = [myObject, function(){}];`
+ addOnLoad: null,
+ // require: Array
+ // An array of module names to be loaded immediately after dojo.js has been included
+ // in a page.
+ require: [],
+ // defaultDuration: Array
+ // Default duration, in milliseconds, for wipe and fade animations within dijits.
+ // Assigned to dijit.defaultDuration.
+ defaultDuration: 200,
+ // dojoBlankHtmlUrl: String
+ // Used by some modules to configure an empty iframe. Used by dojo.io.iframe and
+ // dojo.back, and dijit popup support in IE where an iframe is needed to make sure native
+ // controls do not bleed through the popups. Normally this configuration variable
+ // does not need to be set, except when using cross-domain/CDN Dojo builds.
+ // Save dojo/resources/blank.html to your domain and set `djConfig.dojoBlankHtmlUrl`
+ // to the path on your domain your copy of blank.html.
+ dojoBlankHtmlUrl: undefined,
+ // ioPublish: Boolean?
+ // Set this to true to enable publishing of topics for the different phases of
+ // IO operations. Publishing is done via dojo.publish. See dojo.__IoPublish for a list
+ // of topics that are published.
+ ioPublish: false,
+ // useCustomLogger: Anything?
+ // If set to a value that evaluates to true such as a string or array and
+ // isDebug is true and Firebug is not available or running, then it bypasses
+ // the creation of Firebug Lite allowing you to define your own console object.
+ useCustomLogger: undefined,
+ // transparentColor: Array
+ // Array containing the r, g, b components used as transparent color in dojo.Color;
+ // if undefined, [255,255,255] (white) will be used.
+ transparentColor: undefined,
+ // skipIeDomLoaded: Boolean
+ // For IE only, skip the DOMContentLoaded hack used. Sometimes it can cause an Operation
+ // Aborted error if the rest of the page triggers script defers before the DOM is ready.
+ // If this is config value is set to true, then dojo.addOnLoad callbacks will not be
+ // triggered until the page load event, which is after images and iframes load. If you
+ // want to trigger the callbacks sooner, you can put a script block in the bottom of
+ // your HTML that calls dojo._loadInit();. If you are using multiversion support, change
+ // "dojo." to the appropriate scope name for dojo.
+ skipIeDomLoaded: false
+}
+=====*/
+
+(function(){
+ // firebug stubs
+
+ if(typeof this["loadFirebugConsole"] == "function"){
+ // for Firebug 1.2
+ this["loadFirebugConsole"]();
+ }else{
+ this.console = this.console || {};
+
+ // Be careful to leave 'log' always at the end
+ var cn = [
+ "assert", "count", "debug", "dir", "dirxml", "error", "group",
+ "groupEnd", "info", "profile", "profileEnd", "time", "timeEnd",
+ "trace", "warn", "log"
+ ];
+ var i = 0, tn;
+ while((tn=cn[i++])){
+ if(!console[tn]){
+ (function(){
+ var tcn = tn+"";
+ console[tcn] = ('log' in console) ? function(){
+ var a = Array.apply({}, arguments);
+ a.unshift(tcn+":");
+ console["log"](a.join(" "));
+ } : function(){}
+ console[tcn]._fake = true;
+ })();
+ }
+ }
+ }
+
+ //TODOC: HOW TO DOC THIS?
+ // dojo is the root variable of (almost all) our public symbols -- make sure it is defined.
+ if(typeof dojo == "undefined"){
+ dojo = {
+ _scopeName: "dojo",
+ _scopePrefix: "",
+ _scopePrefixArgs: "",
+ _scopeSuffix: "",
+ _scopeMap: {},
+ _scopeMapRev: {}
+ };
+ }
+
+ var d = dojo;
+
+ //Need placeholders for dijit and dojox for scoping code.
+ if(typeof dijit == "undefined"){
+ dijit = {_scopeName: "dijit"};
+ }
+ if(typeof dojox == "undefined"){
+ dojox = {_scopeName: "dojox"};
+ }
+
+ if(!d._scopeArgs){
+ d._scopeArgs = [dojo, dijit, dojox];
+ }
+
+/*=====
+dojo.global = {
+ // summary:
+ // Alias for the global scope
+ // (e.g. the window object in a browser).
+ // description:
+ // Refer to 'dojo.global' rather than referring to window to ensure your
+ // code runs correctly in contexts other than web browsers (e.g. Rhino on a server).
+}
+=====*/
+ d.global = this;
+
+ d.config =/*===== djConfig = =====*/{
+ isDebug: false,
+ debugAtAllCosts: false
+ };
+
+ // FIXME: 2.0, drop djConfig support. Use dojoConfig exclusively for global config.
+ var cfg = typeof djConfig != "undefined" ? djConfig :
+ typeof dojoConfig != "undefined" ? dojoConfig : null;
+
+ if(cfg){
+ for(var c in cfg){
+ d.config[c] = cfg[c];
+ }
+ }
+
+/*=====
+ // Override locale setting, if specified
+ dojo.locale = {
+ // summary: the locale as defined by Dojo (read-only)
+ };
+=====*/
+ dojo.locale = d.config.locale;
+
+ var rev = "$Rev: 24595 $".match(/\d+/);
+
+/*=====
+ dojo.version = function(){
+ // summary:
+ // Version number of the Dojo Toolkit
+ // major: Integer
+ // Major version. If total version is "1.2.0beta1", will be 1
+ // minor: Integer
+ // Minor version. If total version is "1.2.0beta1", will be 2
+ // patch: Integer
+ // Patch version. If total version is "1.2.0beta1", will be 0
+ // flag: String
+ // Descriptor flag. If total version is "1.2.0beta1", will be "beta1"
+ // revision: Number
+ // The SVN rev from which dojo was pulled
+ this.major = 0;
+ this.minor = 0;
+ this.patch = 0;
+ this.flag = "";
+ this.revision = 0;
+ }
+=====*/
+ dojo.version = {
+ major: 1, minor: 6, patch: 1, flag: "",
+ revision: rev ? +rev[0] : NaN,
+ toString: function(){
+ with(d.version){
+ return major + "." + minor + "." + patch + flag + " (" + revision + ")"; // String
+ }
+ }
+ }
+
+ // Register with the OpenAjax hub
+ if(typeof OpenAjax != "undefined"){
+ OpenAjax.hub.registerLibrary(dojo._scopeName, "http://dojotoolkit.org", d.version.toString());
+ }
+
+ var extraNames, extraLen, empty = {};
+ for(var i in {toString: 1}){ extraNames = []; break; }
+ dojo._extraNames = extraNames = extraNames || ["hasOwnProperty", "valueOf", "isPrototypeOf",
+ "propertyIsEnumerable", "toLocaleString", "toString", "constructor"];
+ extraLen = extraNames.length;
+
+ dojo._mixin = function(/*Object*/ target, /*Object*/ source){
+ // summary:
+ // Adds all properties and methods of source to target. This addition
+ // is "prototype extension safe", so that instances of objects
+ // will not pass along prototype defaults.
+ var name, s, i;
+ for(name in source){
+ // the "tobj" condition avoid copying properties in "source"
+ // inherited from Object.prototype. For example, if target has a custom
+ // toString() method, don't overwrite it with the toString() method
+ // that source inherited from Object.prototype
+ s = source[name];
+ if(!(name in target) || (target[name] !== s && (!(name in empty) || empty[name] !== s))){
+ target[name] = s;
+ }
+ }
+ // IE doesn't recognize some custom functions in for..in
+ if(extraLen && source){
+ for(i = 0; i < extraLen; ++i){
+ name = extraNames[i];
+ s = source[name];
+ if(!(name in target) || (target[name] !== s && (!(name in empty) || empty[name] !== s))){
+ target[name] = s;
+ }
+ }
+ }
+ return target; // Object
+ }
+
+ dojo.mixin = function(/*Object*/obj, /*Object...*/props){
+ // summary:
+ // Adds all properties and methods of props to obj and returns the
+ // (now modified) obj.
+ // description:
+ // `dojo.mixin` can mix multiple source objects into a
+ // destination object which is then returned. Unlike regular
+ // `for...in` iteration, `dojo.mixin` is also smart about avoiding
+ // extensions which other toolkits may unwisely add to the root
+ // object prototype
+ // obj:
+ // The object to mix properties into. Also the return value.
+ // props:
+ // One or more objects whose values are successively copied into
+ // obj. If more than one of these objects contain the same value,
+ // the one specified last in the function call will "win".
+ // example:
+ // make a shallow copy of an object
+ // | var copy = dojo.mixin({}, source);
+ // example:
+ // many class constructors often take an object which specifies
+ // values to be configured on the object. In this case, it is
+ // often simplest to call `dojo.mixin` on the `this` object:
+ // | dojo.declare("acme.Base", null, {
+ // | constructor: function(properties){
+ // | // property configuration:
+ // | dojo.mixin(this, properties);
+ // |
+ // | console.log(this.quip);
+ // | // ...
+ // | },
+ // | quip: "I wasn't born yesterday, you know - I've seen movies.",
+ // | // ...
+ // | });
+ // |
+ // | // create an instance of the class and configure it
+ // | var b = new acme.Base({quip: "That's what it does!" });
+ // example:
+ // copy in properties from multiple objects
+ // | var flattened = dojo.mixin(
+ // | {
+ // | name: "Frylock",
+ // | braces: true
+ // | },
+ // | {
+ // | name: "Carl Brutanananadilewski"
+ // | }
+ // | );
+ // |
+ // | // will print "Carl Brutanananadilewski"
+ // | console.log(flattened.name);
+ // | // will print "true"
+ // | console.log(flattened.braces);
+ if(!obj){ obj = {}; }
+ for(var i=1, l=arguments.length; i<l; i++){
+ d._mixin(obj, arguments[i]);
+ }
+ return obj; // Object
+ }
+
+ dojo._getProp = function(/*Array*/parts, /*Boolean*/create, /*Object*/context){
+ var obj=context || d.global;
+ for(var i=0, p; obj && (p=parts[i]); i++){
+ if(i == 0 && d._scopeMap[p]){
+ p = d._scopeMap[p];
+ }
+ obj = (p in obj ? obj[p] : (create ? obj[p]={} : undefined));
+ }
+ return obj; // mixed
+ }
+
+ dojo.setObject = function(/*String*/name, /*Object*/value, /*Object?*/context){
+ // summary:
+ // Set a property from a dot-separated string, such as "A.B.C"
+ // description:
+ // Useful for longer api chains where you have to test each object in
+ // the chain, or when you have an object reference in string format.
+ // Objects are created as needed along `path`. Returns the passed
+ // value if setting is successful or `undefined` if not.
+ // name:
+ // Path to a property, in the form "A.B.C".
+ // context:
+ // Optional. Object to use as root of path. Defaults to
+ // `dojo.global`.
+ // example:
+ // set the value of `foo.bar.baz`, regardless of whether
+ // intermediate objects already exist:
+ // | dojo.setObject("foo.bar.baz", value);
+ // example:
+ // without `dojo.setObject`, we often see code like this:
+ // | // ensure that intermediate objects are available
+ // | if(!obj["parent"]){ obj.parent = {}; }
+ // | if(!obj.parent["child"]){ obj.parent.child= {}; }
+ // | // now we can safely set the property
+ // | obj.parent.child.prop = "some value";
+ // wheras with `dojo.setObject`, we can shorten that to:
+ // | dojo.setObject("parent.child.prop", "some value", obj);
+ var parts=name.split("."), p=parts.pop(), obj=d._getProp(parts, true, context);
+ return obj && p ? (obj[p]=value) : undefined; // Object
+ }
+
+ dojo.getObject = function(/*String*/name, /*Boolean?*/create, /*Object?*/context){
+ // summary:
+ // Get a property from a dot-separated string, such as "A.B.C"
+ // description:
+ // Useful for longer api chains where you have to test each object in
+ // the chain, or when you have an object reference in string format.
+ // name:
+ // Path to an property, in the form "A.B.C".
+ // create:
+ // Optional. Defaults to `false`. If `true`, Objects will be
+ // created at any point along the 'path' that is undefined.
+ // context:
+ // Optional. Object to use as root of path. Defaults to
+ // 'dojo.global'. Null may be passed.
+ return d._getProp(name.split("."), create, context); // Object
+ }
+
+ dojo.exists = function(/*String*/name, /*Object?*/obj){
+ // summary:
+ // determine if an object supports a given method
+ // description:
+ // useful for longer api chains where you have to test each object in
+ // the chain. Useful for object and method detection.
+ // name:
+ // Path to an object, in the form "A.B.C".
+ // obj:
+ // Object to use as root of path. Defaults to
+ // 'dojo.global'. Null may be passed.
+ // example:
+ // | // define an object
+ // | var foo = {
+ // | bar: { }
+ // | };
+ // |
+ // | // search the global scope
+ // | dojo.exists("foo.bar"); // true
+ // | dojo.exists("foo.bar.baz"); // false
+ // |
+ // | // search from a particular scope
+ // | dojo.exists("bar", foo); // true
+ // | dojo.exists("bar.baz", foo); // false
+ return d.getObject(name, false, obj) !== undefined; // Boolean
+ }
+
+ dojo["eval"] = function(/*String*/ scriptFragment){
+ // summary:
+ // A legacy method created for use exclusively by internal Dojo methods. Do not use
+ // this method directly, the behavior of this eval will differ from the normal
+ // browser eval.
+ // description:
+ // Placed in a separate function to minimize size of trapped
+ // exceptions. Calling eval() directly from some other scope may
+ // complicate tracebacks on some platforms.
+ // returns:
+ // The result of the evaluation. Often `undefined`
+ return d.global.eval ? d.global.eval(scriptFragment) : eval(scriptFragment); // Object
+ }
+
+ /*=====
+ dojo.deprecated = function(behaviour, extra, removal){
+ // summary:
+ // Log a debug message to indicate that a behavior has been
+ // deprecated.
+ // behaviour: String
+ // The API or behavior being deprecated. Usually in the form
+ // of "myApp.someFunction()".
+ // extra: String?
+ // Text to append to the message. Often provides advice on a
+ // new function or facility to achieve the same goal during
+ // the deprecation period.
+ // removal: String?
+ // Text to indicate when in the future the behavior will be
+ // removed. Usually a version number.
+ // example:
+ // | dojo.deprecated("myApp.getTemp()", "use myApp.getLocaleTemp() instead", "1.0");
+ }
+
+ dojo.experimental = function(moduleName, extra){
+ // summary: Marks code as experimental.
+ // description:
+ // This can be used to mark a function, file, or module as
+ // experimental. Experimental code is not ready to be used, and the
+ // APIs are subject to change without notice. Experimental code may be
+ // completed deleted without going through the normal deprecation
+ // process.
+ // moduleName: String
+ // The name of a module, or the name of a module file or a specific
+ // function
+ // extra: String?
+ // some additional message for the user
+ // example:
+ // | dojo.experimental("dojo.data.Result");
+ // example:
+ // | dojo.experimental("dojo.weather.toKelvin()", "PENDING approval from NOAA");
+ }
+ =====*/
+
+ //Real functions declared in dojo._firebug.firebug.
+ d.deprecated = d.experimental = function(){};
+
+})();
+// vim:ai:ts=4:noet
+
+/*
+ * loader.js - A bootstrap module. Runs before the hostenv_*.js file. Contains
+ * all of the package loading methods.
+ */
+(function(){
+ var d = dojo, currentModule;
+
+ d.mixin(d, {
+ _loadedModules: {},
+ _inFlightCount: 0,
+ _hasResource: {},
+
+ _modulePrefixes: {
+ dojo: { name: "dojo", value: "." },
+ // dojox: { name: "dojox", value: "../dojox" },
+ // dijit: { name: "dijit", value: "../dijit" },
+ doh: { name: "doh", value: "../util/doh" },
+ tests: { name: "tests", value: "tests" }
+ },
+
+ _moduleHasPrefix: function(/*String*/module){
+ // summary: checks to see if module has been established
+ var mp = d._modulePrefixes;
+ return !!(mp[module] && mp[module].value); // Boolean
+ },
+
+ _getModulePrefix: function(/*String*/module){
+ // summary: gets the prefix associated with module
+ var mp = d._modulePrefixes;
+ if(d._moduleHasPrefix(module)){
+ return mp[module].value; // String
+ }
+ return module; // String
+ },
+
+ _loadedUrls: [],
+
+ //WARNING:
+ // This variable is referenced by packages outside of bootstrap:
+ // FloatingPane.js and undo/browser.js
+ _postLoad: false,
+
+ //Egad! Lots of test files push on this directly instead of using dojo.addOnLoad.
+ _loaders: [],
+ _unloaders: [],
+ _loadNotifying: false
+ });
+
+
+ dojo._loadPath = function(/*String*/relpath, /*String?*/module, /*Function?*/cb){
+ // summary:
+ // Load a Javascript module given a relative path
+ //
+ // description:
+ // Loads and interprets the script located at relpath, which is
+ // relative to the script root directory. If the script is found but
+ // its interpretation causes a runtime exception, that exception is
+ // not caught by us, so the caller will see it. We return a true
+ // value if and only if the script is found.
+ //
+ // relpath:
+ // A relative path to a script (no leading '/', and typically ending
+ // in '.js').
+ // module:
+ // A module whose existance to check for after loading a path. Can be
+ // used to determine success or failure of the load.
+ // cb:
+ // a callback function to pass the result of evaluating the script
+
+ var uri = ((relpath.charAt(0) == '/' || relpath.match(/^\w+:/)) ? "" : d.baseUrl) + relpath;
+ try{
+ currentModule = module;
+ return !module ? d._loadUri(uri, cb) : d._loadUriAndCheck(uri, module, cb); // Boolean
+ }catch(e){
+ console.error(e);
+ return false; // Boolean
+ }finally{
+ currentModule = null;
+ }
+ }
+
+ dojo._loadUri = function(/*String*/uri, /*Function?*/cb){
+ // summary:
+ // Loads JavaScript from a URI
+ // description:
+ // Reads the contents of the URI, and evaluates the contents. This is
+ // used to load modules as well as resource bundles. Returns true if
+ // it succeeded. Returns false if the URI reading failed. Throws if
+ // the evaluation throws.
+ // uri: a uri which points at the script to be loaded
+ // cb:
+ // a callback function to process the result of evaluating the script
+ // as an expression, typically used by the resource bundle loader to
+ // load JSON-style resources
+
+ if(d._loadedUrls[uri]){
+ return true; // Boolean
+ }
+ d._inFlightCount++; // block addOnLoad calls that arrive while we're busy downloading
+ var contents = d._getText(uri, true);
+ if(contents){ // not 404, et al
+ d._loadedUrls[uri] = true;
+ d._loadedUrls.push(uri);
+ if(cb){
+ //conditional to support script-inject i18n bundle format
+ contents = /^define\(/.test(contents) ? contents : '('+contents+')';
+ }else{
+ //Only do the scoping if no callback. If a callback is specified,
+ //it is most likely the i18n bundle stuff.
+ contents = d._scopePrefix + contents + d._scopeSuffix;
+ }
+ if(!d.isIE){ contents += "\r\n//@ sourceURL=" + uri; } // debugging assist for Firebug
+ var value = d["eval"](contents);
+ if(cb){ cb(value); }
+ }
+ // Check to see if we need to call _callLoaded() due to an addOnLoad() that arrived while we were busy downloading
+ if(--d._inFlightCount == 0 && d._postLoad && d._loaders.length){
+ // We shouldn't be allowed to get here but Firefox allows an event
+ // (mouse, keybd, async xhrGet) to interrupt a synchronous xhrGet.
+ // If the current script block contains multiple require() statements, then after each
+ // require() returns, inFlightCount == 0, but we want to hold the _callLoaded() until
+ // all require()s are done since the out-of-sequence addOnLoad() presumably needs them all.
+ // setTimeout allows the next require() to start (if needed), and then we check this again.
+ setTimeout(function(){
+ // If inFlightCount > 0, then multiple require()s are running sequentially and
+ // the next require() started after setTimeout() was executed but before we got here.
+ if(d._inFlightCount == 0){
+ d._callLoaded();
+ }
+ }, 0);
+ }
+ return !!contents; // Boolean: contents? true : false
+ }
+
+ // FIXME: probably need to add logging to this method
+ dojo._loadUriAndCheck = function(/*String*/uri, /*String*/moduleName, /*Function?*/cb){
+ // summary: calls loadUri then findModule and returns true if both succeed
+ var ok = false;
+ try{
+ ok = d._loadUri(uri, cb);
+ }catch(e){
+ console.error("failed loading " + uri + " with error: " + e);
+ }
+ return !!(ok && d._loadedModules[moduleName]); // Boolean
+ }
+
+ dojo.loaded = function(){
+ // summary:
+ // signal fired when initial environment and package loading is
+ // complete. You should use dojo.addOnLoad() instead of doing a
+ // direct dojo.connect() to this method in order to handle
+ // initialization tasks that require the environment to be
+ // initialized. In a browser host, declarative widgets will
+ // be constructed when this function finishes runing.
+ d._loadNotifying = true;
+ d._postLoad = true;
+ var mll = d._loaders;
+
+ //Clear listeners so new ones can be added
+ //For other xdomain package loads after the initial load.
+ d._loaders = [];
+
+ for(var x = 0; x < mll.length; x++){
+ mll[x]();
+ }
+
+ d._loadNotifying = false;
+
+ //Make sure nothing else got added to the onload queue
+ //after this first run. If something did, and we are not waiting for any
+ //more inflight resources, run again.
+ if(d._postLoad && d._inFlightCount == 0 && mll.length){
+ d._callLoaded();
+ }
+ }
+
+ dojo.unloaded = function(){
+ // summary:
+ // signal fired by impending environment destruction. You should use
+ // dojo.addOnUnload() instead of doing a direct dojo.connect() to this
+ // method to perform page/application cleanup methods. See
+ // dojo.addOnUnload for more info.
+ var mll = d._unloaders;
+ while(mll.length){
+ (mll.pop())();
+ }
+ }
+
+ d._onto = function(arr, obj, fn){
+ if(!fn){
+ arr.push(obj);
+ }else if(fn){
+ var func = (typeof fn == "string") ? obj[fn] : fn;
+ arr.push(function(){ func.call(obj); });
+ }
+ }
+
+ dojo.ready = dojo.addOnLoad = function(/*Object*/obj, /*String|Function?*/functionName){
+ // summary:
+ // Registers a function to be triggered after the DOM and dojo.require() calls
+ // have finished loading.
+ //
+ // description:
+ // Registers a function to be triggered after the DOM has finished
+ // loading and `dojo.require` modules have loaded. Widgets declared in markup
+ // have been instantiated if `djConfig.parseOnLoad` is true when this fires.
+ //
+ // Images and CSS files may or may not have finished downloading when
+ // the specified function is called. (Note that widgets' CSS and HTML
+ // code is guaranteed to be downloaded before said widgets are
+ // instantiated, though including css resouces BEFORE any script elements
+ // is highly recommended).
+ //
+ // example:
+ // Register an anonymous function to run when everything is ready
+ // | dojo.addOnLoad(function(){ doStuff(); });
+ //
+ // example:
+ // Register a function to run when everything is ready by pointer:
+ // | var init = function(){ doStuff(); }
+ // | dojo.addOnLoad(init);
+ //
+ // example:
+ // Register a function to run scoped to `object`, either by name or anonymously:
+ // | dojo.addOnLoad(object, "functionName");
+ // | dojo.addOnLoad(object, function(){ doStuff(); });
+
+ d._onto(d._loaders, obj, functionName);
+
+ //Added for xdomain loading. dojo.addOnLoad is used to
+ //indicate callbacks after doing some dojo.require() statements.
+ //In the xdomain case, if all the requires are loaded (after initial
+ //page load), then immediately call any listeners.
+ if(d._postLoad && d._inFlightCount == 0 && !d._loadNotifying){
+ d._callLoaded();
+ }
+ }
+
+ //Support calling dojo.addOnLoad via djConfig.addOnLoad. Support all the
+ //call permutations of dojo.addOnLoad. Mainly useful when dojo is added
+ //to the page after the page has loaded.
+ var dca = d.config.addOnLoad;
+ if(dca){
+ d.addOnLoad[(dca instanceof Array ? "apply" : "call")](d, dca);
+ }
+
+ dojo._modulesLoaded = function(){
+ if(d._postLoad){ return; }
+ if(d._inFlightCount > 0){
+ console.warn("files still in flight!");
+ return;
+ }
+ d._callLoaded();
+ }
+
+ dojo._callLoaded = function(){
+
+ // The "object" check is for IE, and the other opera check fixes an
+ // issue in Opera where it could not find the body element in some
+ // widget test cases. For 0.9, maybe route all browsers through the
+ // setTimeout (need protection still for non-browser environments
+ // though). This might also help the issue with FF 2.0 and freezing
+ // issues where we try to do sync xhr while background css images are
+ // being loaded (trac #2572)? Consider for 0.9.
+ if(typeof setTimeout == "object" || (d.config.useXDomain && d.isOpera)){
+ setTimeout(
+ d.isAIR ? function(){ d.loaded(); } : d._scopeName + ".loaded();",
+ 0);
+ }else{
+ d.loaded();
+ }
+ }
+
+ dojo._getModuleSymbols = function(/*String*/modulename){
+ // summary:
+ // Converts a module name in dotted JS notation to an array
+ // representing the path in the source tree
+ var syms = modulename.split(".");
+ for(var i = syms.length; i>0; i--){
+ var parentModule = syms.slice(0, i).join(".");
+ if(i == 1 && !d._moduleHasPrefix(parentModule)){
+ // Support default module directory (sibling of dojo) for top-level modules
+ syms[0] = "../" + syms[0];
+ }else{
+ var parentModulePath = d._getModulePrefix(parentModule);
+ if(parentModulePath != parentModule){
+ syms.splice(0, i, parentModulePath);
+ break;
+ }
+ }
+ }
+ return syms; // Array
+ }
+
+ dojo._global_omit_module_check = false;
+
+ dojo.loadInit = function(/*Function*/init){
+ // summary:
+ // Executes a function that needs to be executed for the loader's dojo.requireIf
+ // resolutions to work. This is needed mostly for the xdomain loader case where
+ // a function needs to be executed to set up the possible values for a dojo.requireIf
+ // call.
+ // init:
+ // a function reference. Executed immediately.
+ // description: This function is mainly a marker for the xdomain loader to know parts of
+ // code that needs be executed outside the function wrappper that is placed around modules.
+ // The init function could be executed more than once, and it should make no assumptions
+ // on what is loaded, or what modules are available. Only the functionality in Dojo Base
+ // is allowed to be used. Avoid using this method. For a valid use case,
+ // see the source for dojox.gfx.
+ init();
+ }
+
+ dojo._loadModule = dojo.require = function(/*String*/moduleName, /*Boolean?*/omitModuleCheck){
+ // summary:
+ // loads a Javascript module from the appropriate URI
+ //
+ // moduleName: String
+ // module name to load, using periods for separators,
+ // e.g. "dojo.date.locale". Module paths are de-referenced by dojo's
+ // internal mapping of locations to names and are disambiguated by
+ // longest prefix. See `dojo.registerModulePath()` for details on
+ // registering new modules.
+ //
+ // omitModuleCheck: Boolean?
+ // if `true`, omitModuleCheck skips the step of ensuring that the
+ // loaded file actually defines the symbol it is referenced by.
+ // For example if it called as `dojo.require("a.b.c")` and the
+ // file located at `a/b/c.js` does not define an object `a.b.c`,
+ // and exception will be throws whereas no exception is raised
+ // when called as `dojo.require("a.b.c", true)`
+ //
+ // description:
+ // Modules are loaded via dojo.require by using one of two loaders: the normal loader
+ // and the xdomain loader. The xdomain loader is used when dojo was built with a
+ // custom build that specified loader=xdomain and the module lives on a modulePath
+ // that is a whole URL, with protocol and a domain. The versions of Dojo that are on
+ // the Google and AOL CDNs use the xdomain loader.
+ //
+ // If the module is loaded via the xdomain loader, it is an asynchronous load, since
+ // the module is added via a dynamically created script tag. This
+ // means that dojo.require() can return before the module has loaded. However, this
+ // should only happen in the case where you do dojo.require calls in the top-level
+ // HTML page, or if you purposely avoid the loader checking for dojo.require
+ // dependencies in your module by using a syntax like dojo["require"] to load the module.
+ //
+ // Sometimes it is useful to not have the loader detect the dojo.require calls in the
+ // module so that you can dynamically load the modules as a result of an action on the
+ // page, instead of right at module load time.
+ //
+ // Also, for script blocks in an HTML page, the loader does not pre-process them, so
+ // it does not know to download the modules before the dojo.require calls occur.
+ //
+ // So, in those two cases, when you want on-the-fly module loading or for script blocks
+ // in the HTML page, special care must be taken if the dojo.required code is loaded
+ // asynchronously. To make sure you can execute code that depends on the dojo.required
+ // modules, be sure to add the code that depends on the modules in a dojo.addOnLoad()
+ // callback. dojo.addOnLoad waits for all outstanding modules to finish loading before
+ // executing.
+ //
+ // This type of syntax works with both xdomain and normal loaders, so it is good
+ // practice to always use this idiom for on-the-fly code loading and in HTML script
+ // blocks. If at some point you change loaders and where the code is loaded from,
+ // it will all still work.
+ //
+ // More on how dojo.require
+ // `dojo.require("A.B")` first checks to see if symbol A.B is
+ // defined. If it is, it is simply returned (nothing to do).
+ //
+ // If it is not defined, it will look for `A/B.js` in the script root
+ // directory.
+ //
+ // `dojo.require` throws an exception if it cannot find a file
+ // to load, or if the symbol `A.B` is not defined after loading.
+ //
+ // It returns the object `A.B`, but note the caveats above about on-the-fly loading and
+ // HTML script blocks when the xdomain loader is loading a module.
+ //
+ // `dojo.require()` does nothing about importing symbols into
+ // the current namespace. It is presumed that the caller will
+ // take care of that.
+ //
+ // example:
+ // To use dojo.require in conjunction with dojo.ready:
+ //
+ // | dojo.require("foo");
+ // | dojo.require("bar");
+ // | dojo.addOnLoad(function(){
+ // | //you can now safely do something with foo and bar
+ // | });
+ //
+ // example:
+ // For example, to import all symbols into a local block, you might write:
+ //
+ // | with (dojo.require("A.B")) {
+ // | ...
+ // | }
+ //
+ // And to import just the leaf symbol to a local variable:
+ //
+ // | var B = dojo.require("A.B");
+ // | ...
+ //
+ // returns:
+ // the required namespace object
+ omitModuleCheck = d._global_omit_module_check || omitModuleCheck;
+
+ //Check if it is already loaded.
+ var module = d._loadedModules[moduleName];
+ if(module){
+ return module;
+ }
+
+ // convert periods to slashes
+ var relpath = d._getModuleSymbols(moduleName).join("/") + '.js';
+ var modArg = !omitModuleCheck ? moduleName : null;
+ var ok = d._loadPath(relpath, modArg);
+ if(!ok && !omitModuleCheck){
+ throw new Error("Could not load '" + moduleName + "'; last tried '" + relpath + "'");
+ }
+
+ // check that the symbol was defined
+ // Don't bother if we're doing xdomain (asynchronous) loading.
+ if(!omitModuleCheck && !d._isXDomain){
+ // pass in false so we can give better error
+ module = d._loadedModules[moduleName];
+ if(!module){
+ throw new Error("symbol '" + moduleName + "' is not defined after loading '" + relpath + "'");
+ }
+ }
+
+ return module;
+ }
+
+ dojo.provide = function(/*String*/ resourceName){
+ // summary:
+ // Register a resource with the package system. Works in conjunction with `dojo.require`
+ //
+ // description:
+ // Each javascript source file is called a resource. When a
+ // resource is loaded by the browser, `dojo.provide()` registers
+ // that it has been loaded.
+ //
+ // Each javascript source file must have at least one
+ // `dojo.provide()` call at the top of the file, corresponding to
+ // the file name. For example, `js/dojo/foo.js` must have
+ // `dojo.provide("dojo.foo");` before any calls to
+ // `dojo.require()` are made.
+ //
+ // For backwards compatibility reasons, in addition to registering
+ // the resource, `dojo.provide()` also ensures that the javascript
+ // object for the module exists. For example,
+ // `dojo.provide("dojox.data.FlickrStore")`, in addition to
+ // registering that `FlickrStore.js` is a resource for the
+ // `dojox.data` module, will ensure that the `dojox.data`
+ // javascript object exists, so that calls like
+ // `dojo.data.foo = function(){ ... }` don't fail.
+ //
+ // In the case of a build where multiple javascript source files
+ // are combined into one bigger file (similar to a .lib or .jar
+ // file), that file may contain multiple dojo.provide() calls, to
+ // note that it includes multiple resources.
+ //
+ // resourceName: String
+ // A dot-sperated string identifying a resource.
+ //
+ // example:
+ // Safely create a `my` object, and make dojo.require("my.CustomModule") work
+ // | dojo.provide("my.CustomModule");
+
+ //Make sure we have a string.
+ resourceName = resourceName + "";
+ return (d._loadedModules[resourceName] = d.getObject(resourceName, true)); // Object
+ }
+
+ //Start of old bootstrap2:
+
+ dojo.platformRequire = function(/*Object*/modMap){
+ // summary:
+ // require one or more modules based on which host environment
+ // Dojo is currently operating in
+ // description:
+ // This method takes a "map" of arrays which one can use to
+ // optionally load dojo modules. The map is indexed by the
+ // possible dojo.name_ values, with two additional values:
+ // "default" and "common". The items in the "default" array will
+ // be loaded if none of the other items have been choosen based on
+ // dojo.name_, set by your host environment. The items in the
+ // "common" array will *always* be loaded, regardless of which
+ // list is chosen.
+ // example:
+ // | dojo.platformRequire({
+ // | browser: [
+ // | "foo.sample", // simple module
+ // | "foo.test",
+ // | ["foo.bar.baz", true] // skip object check in _loadModule (dojo.require)
+ // | ],
+ // | default: [ "foo.sample._base" ],
+ // | common: [ "important.module.common" ]
+ // | });
+
+ var common = modMap.common || [];
+ var result = common.concat(modMap[d._name] || modMap["default"] || []);
+
+ for(var x=0; x<result.length; x++){
+ var curr = result[x];
+ if(curr.constructor == Array){
+ d._loadModule.apply(d, curr);
+ }else{
+ d._loadModule(curr);
+ }
+ }
+ }
+
+ dojo.requireIf = function(/*Boolean*/ condition, /*String*/ resourceName){
+ // summary:
+ // If the condition is true then call `dojo.require()` for the specified
+ // resource
+ //
+ // example:
+ // | dojo.requireIf(dojo.isBrowser, "my.special.Module");
+
+ if(condition === true){
+ // FIXME: why do we support chained require()'s here? does the build system?
+ var args = [];
+ for(var i = 1; i < arguments.length; i++){
+ args.push(arguments[i]);
+ }
+ d.require.apply(d, args);
+ }
+ }
+
+ dojo.requireAfterIf = d.requireIf;
+
+ dojo.registerModulePath = function(/*String*/module, /*String*/prefix){
+ // summary:
+ // Maps a module name to a path
+ // description:
+ // An unregistered module is given the default path of ../[module],
+ // relative to Dojo root. For example, module acme is mapped to
+ // ../acme. If you want to use a different module name, use
+ // dojo.registerModulePath.
+ // example:
+ // If your dojo.js is located at this location in the web root:
+ // | /myapp/js/dojo/dojo/dojo.js
+ // and your modules are located at:
+ // | /myapp/js/foo/bar.js
+ // | /myapp/js/foo/baz.js
+ // | /myapp/js/foo/thud/xyzzy.js
+ // Your application can tell Dojo to locate the "foo" namespace by calling:
+ // | dojo.registerModulePath("foo", "../../foo");
+ // At which point you can then use dojo.require() to load the
+ // modules (assuming they provide() the same things which are
+ // required). The full code might be:
+ // | <script type="text/javascript"
+ // | src="/myapp/js/dojo/dojo/dojo.js"></script>
+ // | <script type="text/javascript">
+ // | dojo.registerModulePath("foo", "../../foo");
+ // | dojo.require("foo.bar");
+ // | dojo.require("foo.baz");
+ // | dojo.require("foo.thud.xyzzy");
+ // | </script>
+ d._modulePrefixes[module] = { name: module, value: prefix };
+ };
+
+ dojo.requireLocalization = function(/*String*/moduleName, /*String*/bundleName, /*String?*/locale, /*String?*/availableFlatLocales){
+ // summary:
+ // Declares translated resources and loads them if necessary, in the
+ // same style as dojo.require. Contents of the resource bundle are
+ // typically strings, but may be any name/value pair, represented in
+ // JSON format. See also `dojo.i18n.getLocalization`.
+ //
+ // description:
+ // Load translated resource bundles provided underneath the "nls"
+ // directory within a package. Translated resources may be located in
+ // different packages throughout the source tree.
+ //
+ // Each directory is named for a locale as specified by RFC 3066,
+ // (http://www.ietf.org/rfc/rfc3066.txt), normalized in lowercase.
+ // Note that the two bundles in the example do not define all the
+ // same variants. For a given locale, bundles will be loaded for
+ // that locale and all more general locales above it, including a
+ // fallback at the root directory. For example, a declaration for
+ // the "de-at" locale will first load `nls/de-at/bundleone.js`,
+ // then `nls/de/bundleone.js` and finally `nls/bundleone.js`. The
+ // data will be flattened into a single Object so that lookups
+ // will follow this cascading pattern. An optional build step can
+ // preload the bundles to avoid data redundancy and the multiple
+ // network hits normally required to load these resources.
+ //
+ // moduleName:
+ // name of the package containing the "nls" directory in which the
+ // bundle is found
+ //
+ // bundleName:
+ // bundle name, i.e. the filename without the '.js' suffix. Using "nls" as a
+ // a bundle name is not supported, since "nls" is the name of the folder
+ // that holds bundles. Using "nls" as the bundle name will cause problems
+ // with the custom build.
+ //
+ // locale:
+ // the locale to load (optional) By default, the browser's user
+ // locale as defined by dojo.locale
+ //
+ // availableFlatLocales:
+ // A comma-separated list of the available, flattened locales for this
+ // bundle. This argument should only be set by the build process.
+ //
+ // example:
+ // A particular widget may define one or more resource bundles,
+ // structured in a program as follows, where moduleName is
+ // mycode.mywidget and bundleNames available include bundleone and
+ // bundletwo:
+ // | ...
+ // | mycode/
+ // | mywidget/
+ // | nls/
+ // | bundleone.js (the fallback translation, English in this example)
+ // | bundletwo.js (also a fallback translation)
+ // | de/
+ // | bundleone.js
+ // | bundletwo.js
+ // | de-at/
+ // | bundleone.js
+ // | en/
+ // | (empty; use the fallback translation)
+ // | en-us/
+ // | bundleone.js
+ // | en-gb/
+ // | bundleone.js
+ // | es/
+ // | bundleone.js
+ // | bundletwo.js
+ // | ...etc
+ // | ...
+ //
+
+ d.require("dojo.i18n");
+ d.i18n._requireLocalization.apply(d.hostenv, arguments);
+ };
+
+
+ var ore = new RegExp("^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?$"),
+ ire = new RegExp("^((([^\\[:]+):)?([^@]+)@)?(\\[([^\\]]+)\\]|([^\\[:]*))(:([0-9]+))?$");
+
+ dojo._Url = function(/*dojo._Url|String...*/){
+ // summary:
+ // Constructor to create an object representing a URL.
+ // It is marked as private, since we might consider removing
+ // or simplifying it.
+ // description:
+ // Each argument is evaluated in order relative to the next until
+ // a canonical uri is produced. To get an absolute Uri relative to
+ // the current document use:
+ // new dojo._Url(document.baseURI, url)
+
+ var n = null,
+ _a = arguments,
+ uri = [_a[0]];
+ // resolve uri components relative to each other
+ for(var i = 1; i<_a.length; i++){
+ if(!_a[i]){ continue; }
+
+ // Safari doesn't support this.constructor so we have to be explicit
+ // FIXME: Tracked (and fixed) in Webkit bug 3537.
+ // http://bugs.webkit.org/show_bug.cgi?id=3537
+ var relobj = new d._Url(_a[i]+""),
+ uriobj = new d._Url(uri[0]+"");
+
+ if(
+ relobj.path == "" &&
+ !relobj.scheme &&
+ !relobj.authority &&
+ !relobj.query
+ ){
+ if(relobj.fragment != n){
+ uriobj.fragment = relobj.fragment;
+ }
+ relobj = uriobj;
+ }else if(!relobj.scheme){
+ relobj.scheme = uriobj.scheme;
+
+ if(!relobj.authority){
+ relobj.authority = uriobj.authority;
+
+ if(relobj.path.charAt(0) != "/"){
+ var path = uriobj.path.substring(0,
+ uriobj.path.lastIndexOf("/") + 1) + relobj.path;
+
+ var segs = path.split("/");
+ for(var j = 0; j < segs.length; j++){
+ if(segs[j] == "."){
+ // flatten "./" references
+ if(j == segs.length - 1){
+ segs[j] = "";
+ }else{
+ segs.splice(j, 1);
+ j--;
+ }
+ }else if(j > 0 && !(j == 1 && segs[0] == "") &&
+ segs[j] == ".." && segs[j-1] != ".."){
+ // flatten "../" references
+ if(j == (segs.length - 1)){
+ segs.splice(j, 1);
+ segs[j - 1] = "";
+ }else{
+ segs.splice(j - 1, 2);
+ j -= 2;
+ }
+ }
+ }
+ relobj.path = segs.join("/");
+ }
+ }
+ }
+
+ uri = [];
+ if(relobj.scheme){
+ uri.push(relobj.scheme, ":");
+ }
+ if(relobj.authority){
+ uri.push("//", relobj.authority);
+ }
+ uri.push(relobj.path);
+ if(relobj.query){
+ uri.push("?", relobj.query);
+ }
+ if(relobj.fragment){
+ uri.push("#", relobj.fragment);
+ }
+ }
+
+ this.uri = uri.join("");
+
+ // break the uri into its main components
+ var r = this.uri.match(ore);
+
+ this.scheme = r[2] || (r[1] ? "" : n);
+ this.authority = r[4] || (r[3] ? "" : n);
+ this.path = r[5]; // can never be undefined
+ this.query = r[7] || (r[6] ? "" : n);
+ this.fragment = r[9] || (r[8] ? "" : n);
+
+ if(this.authority != n){
+ // server based naming authority
+ r = this.authority.match(ire);
+
+ this.user = r[3] || n;
+ this.password = r[4] || n;
+ this.host = r[6] || r[7]; // ipv6 || ipv4
+ this.port = r[9] || n;
+ }
+ }
+
+ dojo._Url.prototype.toString = function(){ return this.uri; };
+
+ dojo.moduleUrl = function(/*String*/module, /*dojo._Url||String*/url){
+ // summary:
+ // Returns a `dojo._Url` object relative to a module.
+ // example:
+ // | var pngPath = dojo.moduleUrl("acme","images/small.png");
+ // | console.dir(pngPath); // list the object properties
+ // | // create an image and set it's source to pngPath's value:
+ // | var img = document.createElement("img");
+ // | // NOTE: we assign the string representation of the url object
+ // | img.src = pngPath.toString();
+ // | // add our image to the document
+ // | dojo.body().appendChild(img);
+ // example:
+ // you may de-reference as far as you like down the package
+ // hierarchy. This is sometimes handy to avoid lenghty relative
+ // urls or for building portable sub-packages. In this example,
+ // the `acme.widget` and `acme.util` directories may be located
+ // under different roots (see `dojo.registerModulePath`) but the
+ // the modules which reference them can be unaware of their
+ // relative locations on the filesystem:
+ // | // somewhere in a configuration block
+ // | dojo.registerModulePath("acme.widget", "../../acme/widget");
+ // | dojo.registerModulePath("acme.util", "../../util");
+ // |
+ // | // ...
+ // |
+ // | // code in a module using acme resources
+ // | var tmpltPath = dojo.moduleUrl("acme.widget","templates/template.html");
+ // | var dataPath = dojo.moduleUrl("acme.util","resources/data.json");
+
+ var loc = d._getModuleSymbols(module).join('/');
+ if(!loc){ return null; }
+ if(loc.lastIndexOf("/") != loc.length-1){
+ loc += "/";
+ }
+
+ //If the path is an absolute path (starts with a / or is on another
+ //domain/xdomain) then don't add the baseUrl.
+ var colonIndex = loc.indexOf(":");
+ if(loc.charAt(0) != "/" && (colonIndex == -1 || colonIndex > loc.indexOf("/"))){
+ loc = d.baseUrl + loc;
+ }
+
+ return new d._Url(loc, url); // dojo._Url
+ };
+
+
+
+})();
+
+/*=====
+dojo.isBrowser = {
+ // example:
+ // | if(dojo.isBrowser){ ... }
+};
+
+dojo.isFF = {
+ // example:
+ // | if(dojo.isFF > 1){ ... }
+};
+
+dojo.isIE = {
+ // example:
+ // | if(dojo.isIE > 6){
+ // | // we are IE7
+ // | }
+};
+
+dojo.isSafari = {
+ // example:
+ // | if(dojo.isSafari){ ... }
+ // example:
+ // Detect iPhone:
+ // | if(dojo.isSafari && navigator.userAgent.indexOf("iPhone") != -1){
+ // | // we are iPhone. Note, iPod touch reports "iPod" above and fails this test.
+ // | }
+};
+
+dojo = {
+ // isBrowser: Boolean
+ // True if the client is a web-browser
+ isBrowser: true,
+ // isFF: Number | undefined
+ // Version as a Number if client is FireFox. undefined otherwise. Corresponds to
+ // major detected FireFox version (1.5, 2, 3, etc.)
+ isFF: 2,
+ // isIE: Number | undefined
+ // Version as a Number if client is MSIE(PC). undefined otherwise. Corresponds to
+ // major detected IE version (6, 7, 8, etc.)
+ isIE: 6,
+ // isKhtml: Number | undefined
+ // Version as a Number if client is a KHTML browser. undefined otherwise. Corresponds to major
+ // detected version.
+ isKhtml: 0,
+ // isWebKit: Number | undefined
+ // Version as a Number if client is a WebKit-derived browser (Konqueror,
+ // Safari, Chrome, etc.). undefined otherwise.
+ isWebKit: 0,
+ // isMozilla: Number | undefined
+ // Version as a Number if client is a Mozilla-based browser (Firefox,
+ // SeaMonkey). undefined otherwise. Corresponds to major detected version.
+ isMozilla: 0,
+ // isOpera: Number | undefined
+ // Version as a Number if client is Opera. undefined otherwise. Corresponds to
+ // major detected version.
+ isOpera: 0,
+ // isSafari: Number | undefined
+ // Version as a Number if client is Safari or iPhone. undefined otherwise.
+ isSafari: 0,
+ // isChrome: Number | undefined
+ // Version as a Number if client is Chrome browser. undefined otherwise.
+ isChrome: 0
+ // isMac: Boolean
+ // True if the client runs on Mac
+}
+=====*/
+if(typeof window != 'undefined'){
+ dojo.isBrowser = true;
+ dojo._name = "browser";
+
+
+ // attempt to figure out the path to dojo if it isn't set in the config
+ (function(){
+ var d = dojo;
+
+ // this is a scope protection closure. We set browser versions and grab
+ // the URL we were loaded from here.
+
+ // grab the node we were loaded from
+ if(document && document.getElementsByTagName){
+ var scripts = document.getElementsByTagName("script");
+ var rePkg = /dojo(\.xd)?\.js(\W|$)/i;
+ for(var i = 0; i < scripts.length; i++){
+ var src = scripts[i].getAttribute("src");
+ if(!src){ continue; }
+ var m = src.match(rePkg);
+ if(m){
+ // find out where we came from
+ if(!d.config.baseUrl){
+ d.config.baseUrl = src.substring(0, m.index);
+ }
+ // and find out if we need to modify our behavior
+ var cfg = (scripts[i].getAttribute("djConfig") || scripts[i].getAttribute("data-dojo-config"));
+ if(cfg){
+ var cfgo = eval("({ "+cfg+" })");
+ for(var x in cfgo){
+ dojo.config[x] = cfgo[x];
+ }
+ }
+ break; // "first Dojo wins"
+ }
+ }
+ }
+ d.baseUrl = d.config.baseUrl;
+
+ // fill in the rendering support information in dojo.render.*
+ var n = navigator;
+ var dua = n.userAgent,
+ dav = n.appVersion,
+ tv = parseFloat(dav);
+
+ if(dua.indexOf("Opera") >= 0){ d.isOpera = tv; }
+ if(dua.indexOf("AdobeAIR") >= 0){ d.isAIR = 1; }
+ d.isKhtml = (dav.indexOf("Konqueror") >= 0) ? tv : 0;
+ d.isWebKit = parseFloat(dua.split("WebKit/")[1]) || undefined;
+ d.isChrome = parseFloat(dua.split("Chrome/")[1]) || undefined;
+ d.isMac = dav.indexOf("Macintosh") >= 0;
+
+ // safari detection derived from:
+ // http://developer.apple.com/internet/safari/faq.html#anchor2
+ // http://developer.apple.com/internet/safari/uamatrix.html
+ var index = Math.max(dav.indexOf("WebKit"), dav.indexOf("Safari"), 0);
+ if(index && !dojo.isChrome){
+ // try to grab the explicit Safari version first. If we don't get
+ // one, look for less than 419.3 as the indication that we're on something
+ // "Safari 2-ish".
+ d.isSafari = parseFloat(dav.split("Version/")[1]);
+ if(!d.isSafari || parseFloat(dav.substr(index + 7)) <= 419.3){
+ d.isSafari = 2;
+ }
+ }
+
+ if(dua.indexOf("Gecko") >= 0 && !d.isKhtml && !d.isWebKit){ d.isMozilla = d.isMoz = tv; }
+ if(d.isMoz){
+ //We really need to get away from this. Consider a sane isGecko approach for the future.
+ d.isFF = parseFloat(dua.split("Firefox/")[1] || dua.split("Minefield/")[1]) || undefined;
+ }
+ if(document.all && !d.isOpera){
+ d.isIE = parseFloat(dav.split("MSIE ")[1]) || undefined;
+ //In cases where the page has an HTTP header or META tag with
+ //X-UA-Compatible, then it is in emulation mode.
+ //Make sure isIE reflects the desired version.
+ //document.documentMode of 5 means quirks mode.
+ //Only switch the value if documentMode's major version
+ //is different from isIE's major version.
+ var mode = document.documentMode;
+ if(mode && mode != 5 && Math.floor(d.isIE) != mode){
+ d.isIE = mode;
+ }
+ }
+
+ //Workaround to get local file loads of dojo to work on IE 7
+ //by forcing to not use native xhr.
+ if(dojo.isIE && window.location.protocol === "file:"){
+ dojo.config.ieForceActiveXXhr=true;
+ }
+
+ d.isQuirks = document.compatMode == "BackCompat";
+
+ // TODO: is the HTML LANG attribute relevant?
+ d.locale = dojo.config.locale || (d.isIE ? n.userLanguage : n.language).toLowerCase();
+
+ // These are in order of decreasing likelihood; this will change in time.
+ d._XMLHTTP_PROGIDS = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'];
+
+ d._xhrObj = function(){
+ // summary:
+ // does the work of portably generating a new XMLHTTPRequest object.
+ var http, last_e;
+ if(!dojo.isIE || !dojo.config.ieForceActiveXXhr){
+ try{ http = new XMLHttpRequest(); }catch(e){}
+ }
+ if(!http){
+ for(var i=0; i<3; ++i){
+ var progid = d._XMLHTTP_PROGIDS[i];
+ try{
+ http = new ActiveXObject(progid);
+ }catch(e){
+ last_e = e;
+ }
+
+ if(http){
+ d._XMLHTTP_PROGIDS = [progid]; // so faster next time
+ break;
+ }
+ }
+ }
+
+ if(!http){
+ throw new Error("XMLHTTP not available: "+last_e);
+ }
+
+ return http; // XMLHTTPRequest instance
+ }
+
+ d._isDocumentOk = function(http){
+ var stat = http.status || 0,
+ lp = location.protocol;
+ return (stat >= 200 && stat < 300) || // Boolean
+ stat == 304 || // allow any 2XX response code
+ stat == 1223 || // get it out of the cache
+ // Internet Explorer mangled the status code
+ // Internet Explorer mangled the status code OR we're Titanium/browser chrome/chrome extension requesting a local file
+ (!stat && (lp == "file:" || lp == "chrome:" || lp == "chrome-extension:" || lp == "app:"));
+ }
+
+ //See if base tag is in use.
+ //This is to fix http://trac.dojotoolkit.org/ticket/3973,
+ //but really, we need to find out how to get rid of the dojo._Url reference
+ //below and still have DOH work with the dojo.i18n test following some other
+ //test that uses the test frame to load a document (trac #2757).
+ //Opera still has problems, but perhaps a larger issue of base tag support
+ //with XHR requests (hasBase is true, but the request is still made to document
+ //path, not base path).
+ var owloc = window.location+"";
+ var base = document.getElementsByTagName("base");
+ var hasBase = (base && base.length > 0);
+
+ d._getText = function(/*URI*/ uri, /*Boolean*/ fail_ok){
+ // summary: Read the contents of the specified uri and return those contents.
+ // uri:
+ // A relative or absolute uri. If absolute, it still must be in
+ // the same "domain" as we are.
+ // fail_ok:
+ // Default false. If fail_ok and loading fails, return null
+ // instead of throwing.
+ // returns: The response text. null is returned when there is a
+ // failure and failure is okay (an exception otherwise)
+
+ // NOTE: must be declared before scope switches ie. this._xhrObj()
+ var http = d._xhrObj();
+
+ if(!hasBase && dojo._Url){
+ uri = (new dojo._Url(owloc, uri)).toString();
+ }
+
+ if(d.config.cacheBust){
+ //Make sure we have a string before string methods are used on uri
+ uri += "";
+ uri += (uri.indexOf("?") == -1 ? "?" : "&") + String(d.config.cacheBust).replace(/\W+/g,"");
+ }
+
+ http.open('GET', uri, false);
+ try{
+ http.send(null);
+ if(!d._isDocumentOk(http)){
+ var err = Error("Unable to load "+uri+" status:"+ http.status);
+ err.status = http.status;
+ err.responseText = http.responseText;
+ throw err;
+ }
+ }catch(e){
+ if(fail_ok){ return null; } // null
+ // rethrow the exception
+ throw e;
+ }
+ return http.responseText; // String
+ }
+
+
+ var _w = window;
+ var _handleNodeEvent = function(/*String*/evtName, /*Function*/fp){
+ // summary:
+ // non-destructively adds the specified function to the node's
+ // evtName handler.
+ // evtName: should be in the form "onclick" for "onclick" handlers.
+ // Make sure you pass in the "on" part.
+ var _a = _w.attachEvent || _w.addEventListener;
+ evtName = _w.attachEvent ? evtName : evtName.substring(2);
+ _a(evtName, function(){
+ fp.apply(_w, arguments);
+ }, false);
+ };
+
+
+ d._windowUnloaders = [];
+
+ d.windowUnloaded = function(){
+ // summary:
+ // signal fired by impending window destruction. You may use
+ // dojo.addOnWindowUnload() to register a listener for this
+ // event. NOTE: if you wish to dojo.connect() to this method
+ // to perform page/application cleanup, be aware that this
+ // event WILL NOT fire if no handler has been registered with
+ // dojo.addOnWindowUnload. This behavior started in Dojo 1.3.
+ // Previous versions always triggered dojo.windowUnloaded. See
+ // dojo.addOnWindowUnload for more info.
+ var mll = d._windowUnloaders;
+ while(mll.length){
+ (mll.pop())();
+ }
+ d = null;
+ };
+
+ var _onWindowUnloadAttached = 0;
+ d.addOnWindowUnload = function(/*Object?|Function?*/obj, /*String|Function?*/functionName){
+ // summary:
+ // registers a function to be triggered when window.onunload
+ // fires.
+ // description:
+ // The first time that addOnWindowUnload is called Dojo
+ // will register a page listener to trigger your unload
+ // handler with. Note that registering these handlers may
+ // destory "fastback" page caching in browsers that support
+ // it. Be careful trying to modify the DOM or access
+ // JavaScript properties during this phase of page unloading:
+ // they may not always be available. Consider
+ // dojo.addOnUnload() if you need to modify the DOM or do
+ // heavy JavaScript work since it fires at the eqivalent of
+ // the page's "onbeforeunload" event.
+ // example:
+ // | dojo.addOnWindowUnload(functionPointer)
+ // | dojo.addOnWindowUnload(object, "functionName");
+ // | dojo.addOnWindowUnload(object, function(){ /* ... */});
+
+ d._onto(d._windowUnloaders, obj, functionName);
+ if(!_onWindowUnloadAttached){
+ _onWindowUnloadAttached = 1;
+ _handleNodeEvent("onunload", d.windowUnloaded);
+ }
+ };
+
+ var _onUnloadAttached = 0;
+ d.addOnUnload = function(/*Object?|Function?*/obj, /*String|Function?*/functionName){
+ // summary:
+ // registers a function to be triggered when the page unloads.
+ // description:
+ // The first time that addOnUnload is called Dojo will
+ // register a page listener to trigger your unload handler
+ // with.
+ //
+ // In a browser enviroment, the functions will be triggered
+ // during the window.onbeforeunload event. Be careful of doing
+ // too much work in an unload handler. onbeforeunload can be
+ // triggered if a link to download a file is clicked, or if
+ // the link is a javascript: link. In these cases, the
+ // onbeforeunload event fires, but the document is not
+ // actually destroyed. So be careful about doing destructive
+ // operations in a dojo.addOnUnload callback.
+ //
+ // Further note that calling dojo.addOnUnload will prevent
+ // browsers from using a "fast back" cache to make page
+ // loading via back button instantaneous.
+ // example:
+ // | dojo.addOnUnload(functionPointer)
+ // | dojo.addOnUnload(object, "functionName")
+ // | dojo.addOnUnload(object, function(){ /* ... */});
+
+ d._onto(d._unloaders, obj, functionName);
+ if(!_onUnloadAttached){
+ _onUnloadAttached = 1;
+ _handleNodeEvent("onbeforeunload", dojo.unloaded);
+ }
+ };
+
+ })();
+
+ //START DOMContentLoaded
+ dojo._initFired = false;
+ dojo._loadInit = function(e){
+ if(dojo._scrollIntervalId){
+ clearInterval(dojo._scrollIntervalId);
+ dojo._scrollIntervalId = 0;
+ }
+
+ if(!dojo._initFired){
+ dojo._initFired = true;
+
+ //Help out IE to avoid memory leak.
+ if(!dojo.config.afterOnLoad && window.detachEvent){
+ window.detachEvent("onload", dojo._loadInit);
+ }
+
+ if(dojo._inFlightCount == 0){
+ dojo._modulesLoaded();
+ }
+ }
+ }
+
+ if(!dojo.config.afterOnLoad){
+ if(document.addEventListener){
+ //Standards. Hooray! Assumption here that if standards based,
+ //it knows about DOMContentLoaded. It is OK if it does not, the fall through
+ //to window onload should be good enough.
+ document.addEventListener("DOMContentLoaded", dojo._loadInit, false);
+ window.addEventListener("load", dojo._loadInit, false);
+ }else if(window.attachEvent){
+ window.attachEvent("onload", dojo._loadInit);
+
+ //DOMContentLoaded approximation. Diego Perini found this MSDN article
+ //that indicates doScroll is available after DOM ready, so do a setTimeout
+ //to check when it is available.
+ //http://msdn.microsoft.com/en-us/library/ms531426.aspx
+ if(!dojo.config.skipIeDomLoaded && self === self.top){
+ dojo._scrollIntervalId = setInterval(function (){
+ try{
+ //When dojo is loaded into an iframe in an IE HTML Application
+ //(HTA), such as in a selenium test, javascript in the iframe
+ //can't see anything outside of it, so self===self.top is true,
+ //but the iframe is not the top window and doScroll will be
+ //available before document.body is set. Test document.body
+ //before trying the doScroll trick
+ if(document.body){
+ document.documentElement.doScroll("left");
+ dojo._loadInit();
+ }
+ }catch (e){}
+ }, 30);
+ }
+ }
+ }
+
+ if(dojo.isIE){
+ try{
+ (function(){
+ document.namespaces.add("v", "urn:schemas-microsoft-com:vml");
+ var vmlElems = ["*", "group", "roundrect", "oval", "shape", "rect", "imagedata", "path", "textpath", "text"],
+ i = 0, l = 1, s = document.createStyleSheet();
+ if(dojo.isIE >= 8){
+ i = 1;
+ l = vmlElems.length;
+ }
+ for(; i < l; ++i){
+ s.addRule("v\\:" + vmlElems[i], "behavior:url(#default#VML); display:inline-block");
+ }
+ })();
+ }catch(e){}
+ }
+ //END DOMContentLoaded
+
+
+ /*
+ OpenAjax.subscribe("OpenAjax", "onload", function(){
+ if(dojo._inFlightCount == 0){
+ dojo._modulesLoaded();
+ }
+ });
+
+ OpenAjax.subscribe("OpenAjax", "onunload", function(){
+ dojo.unloaded();
+ });
+ */
+} //if (typeof window != 'undefined')
+
+//Register any module paths set up in djConfig. Need to do this
+//in the hostenvs since hostenv_browser can read djConfig from a
+//script tag's attribute.
+(function(){
+ var mp = dojo.config["modulePaths"];
+ if(mp){
+ for(var param in mp){
+ dojo.registerModulePath(param, mp[param]);
+ }
+ }
+})();
+
+//Load debug code if necessary.
+if(dojo.config.isDebug){
+ dojo.require("dojo._firebug.firebug");
+}
+
+if(dojo.config.debugAtAllCosts){
+ // this breaks the new AMD based module loader. The XDomain won't be necessary
+ // anyway if you switch to the asynchronous loader
+ //dojo.config.useXDomain = true;
+ //dojo.require("dojo._base._loader.loader_xd");
+ dojo.require("dojo._base._loader.loader_debug");
+ dojo.require("dojo.i18n");
+}
+
+
+if(!dojo._hasResource["dojo._base.lang"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo._base.lang"] = true;
+dojo.provide("dojo._base.lang");
+
+
+(function(){
+ var d = dojo, opts = Object.prototype.toString;
+
+ // Crockford (ish) functions
+
+ dojo.isString = function(/*anything*/ it){
+ // summary:
+ // Return true if it is a String
+ return (typeof it == "string" || it instanceof String); // Boolean
+ };
+
+ dojo.isArray = function(/*anything*/ it){
+ // summary:
+ // Return true if it is an Array.
+ // Does not work on Arrays created in other windows.
+ return it && (it instanceof Array || typeof it == "array"); // Boolean
+ };
+
+ dojo.isFunction = function(/*anything*/ it){
+ // summary:
+ // Return true if it is a Function
+ return opts.call(it) === "[object Function]";
+ };
+
+ dojo.isObject = function(/*anything*/ it){
+ // summary:
+ // Returns true if it is a JavaScript object (or an Array, a Function
+ // or null)
+ return it !== undefined &&
+ (it === null || typeof it == "object" || d.isArray(it) || d.isFunction(it)); // Boolean
+ };
+
+ dojo.isArrayLike = function(/*anything*/ it){
+ // summary:
+ // similar to dojo.isArray() but more permissive
+ // description:
+ // Doesn't strongly test for "arrayness". Instead, settles for "isn't
+ // a string or number and has a length property". Arguments objects
+ // and DOM collections will return true when passed to
+ // dojo.isArrayLike(), but will return false when passed to
+ // dojo.isArray().
+ // returns:
+ // If it walks like a duck and quacks like a duck, return `true`
+ return it && it !== undefined && // Boolean
+ // keep out built-in constructors (Number, String, ...) which have length
+ // properties
+ !d.isString(it) && !d.isFunction(it) &&
+ !(it.tagName && it.tagName.toLowerCase() == 'form') &&
+ (d.isArray(it) || isFinite(it.length));
+ };
+
+ dojo.isAlien = function(/*anything*/ it){
+ // summary:
+ // Returns true if it is a built-in function or some other kind of
+ // oddball that *should* report as a function but doesn't
+ return it && !d.isFunction(it) && /\{\s*\[native code\]\s*\}/.test(String(it)); // Boolean
+ };
+
+ dojo.extend = function(/*Object*/ constructor, /*Object...*/ props){
+ // summary:
+ // Adds all properties and methods of props to constructor's
+ // prototype, making them available to all instances created with
+ // constructor.
+ for(var i=1, l=arguments.length; i<l; i++){
+ d._mixin(constructor.prototype, arguments[i]);
+ }
+ return constructor; // Object
+ };
+
+ dojo._hitchArgs = function(scope, method /*,...*/){
+ var pre = d._toArray(arguments, 2);
+ var named = d.isString(method);
+ return function(){
+ // arrayify arguments
+ var args = d._toArray(arguments);
+ // locate our method
+ var f = named ? (scope||d.global)[method] : method;
+ // invoke with collected args
+ return f && f.apply(scope || this, pre.concat(args)); // mixed
+ }; // Function
+ };
+
+ dojo.hitch = function(/*Object*/scope, /*Function|String*/method /*,...*/){
+ // summary:
+ // Returns a function that will only ever execute in the a given scope.
+ // This allows for easy use of object member functions
+ // in callbacks and other places in which the "this" keyword may
+ // otherwise not reference the expected scope.
+ // Any number of default positional arguments may be passed as parameters
+ // beyond "method".
+ // Each of these values will be used to "placehold" (similar to curry)
+ // for the hitched function.
+ // scope:
+ // The scope to use when method executes. If method is a string,
+ // scope is also the object containing method.
+ // method:
+ // A function to be hitched to scope, or the name of the method in
+ // scope to be hitched.
+ // example:
+ // | dojo.hitch(foo, "bar")();
+ // runs foo.bar() in the scope of foo
+ // example:
+ // | dojo.hitch(foo, myFunction);
+ // returns a function that runs myFunction in the scope of foo
+ // example:
+ // Expansion on the default positional arguments passed along from
+ // hitch. Passed args are mixed first, additional args after.
+ // | var foo = { bar: function(a, b, c){ console.log(a, b, c); } };
+ // | var fn = dojo.hitch(foo, "bar", 1, 2);
+ // | fn(3); // logs "1, 2, 3"
+ // example:
+ // | var foo = { bar: 2 };
+ // | dojo.hitch(foo, function(){ this.bar = 10; })();
+ // execute an anonymous function in scope of foo
+
+ if(arguments.length > 2){
+ return d._hitchArgs.apply(d, arguments); // Function
+ }
+ if(!method){
+ method = scope;
+ scope = null;
+ }
+ if(d.isString(method)){
+ scope = scope || d.global;
+ if(!scope[method]){ throw(['dojo.hitch: scope["', method, '"] is null (scope="', scope, '")'].join('')); }
+ return function(){ return scope[method].apply(scope, arguments || []); }; // Function
+ }
+ return !scope ? method : function(){ return method.apply(scope, arguments || []); }; // Function
+ };
+
+ /*=====
+ dojo.delegate = function(obj, props){
+ // summary:
+ // Returns a new object which "looks" to obj for properties which it
+ // does not have a value for. Optionally takes a bag of properties to
+ // seed the returned object with initially.
+ // description:
+ // This is a small implementaton of the Boodman/Crockford delegation
+ // pattern in JavaScript. An intermediate object constructor mediates
+ // the prototype chain for the returned object, using it to delegate
+ // down to obj for property lookup when object-local lookup fails.
+ // This can be thought of similarly to ES4's "wrap", save that it does
+ // not act on types but rather on pure objects.
+ // obj:
+ // The object to delegate to for properties not found directly on the
+ // return object or in props.
+ // props:
+ // an object containing properties to assign to the returned object
+ // returns:
+ // an Object of anonymous type
+ // example:
+ // | var foo = { bar: "baz" };
+ // | var thinger = dojo.delegate(foo, { thud: "xyzzy"});
+ // | thinger.bar == "baz"; // delegated to foo
+ // | foo.thud == undefined; // by definition
+ // | thinger.thud == "xyzzy"; // mixed in from props
+ // | foo.bar = "thonk";
+ // | thinger.bar == "thonk"; // still delegated to foo's bar
+ }
+ =====*/
+
+ dojo.delegate = dojo._delegate = (function(){
+ // boodman/crockford delegation w/ cornford optimization
+ function TMP(){}
+ return function(obj, props){
+ TMP.prototype = obj;
+ var tmp = new TMP();
+ TMP.prototype = null;
+ if(props){
+ d._mixin(tmp, props);
+ }
+ return tmp; // Object
+ };
+ })();
+
+ /*=====
+ dojo._toArray = function(obj, offset, startWith){
+ // summary:
+ // Converts an array-like object (i.e. arguments, DOMCollection) to an
+ // array. Returns a new Array with the elements of obj.
+ // obj: Object
+ // the object to "arrayify". We expect the object to have, at a
+ // minimum, a length property which corresponds to integer-indexed
+ // properties.
+ // offset: Number?
+ // the location in obj to start iterating from. Defaults to 0.
+ // Optional.
+ // startWith: Array?
+ // An array to pack with the properties of obj. If provided,
+ // properties in obj are appended at the end of startWith and
+ // startWith is the returned array.
+ }
+ =====*/
+
+ var efficient = function(obj, offset, startWith){
+ return (startWith||[]).concat(Array.prototype.slice.call(obj, offset||0));
+ };
+
+ var slow = function(obj, offset, startWith){
+ var arr = startWith||[];
+ for(var x = offset || 0; x < obj.length; x++){
+ arr.push(obj[x]);
+ }
+ return arr;
+ };
+
+ dojo._toArray =
+ d.isIE ? function(obj){
+ return ((obj.item) ? slow : efficient).apply(this, arguments);
+ } :
+ efficient;
+
+ dojo.partial = function(/*Function|String*/method /*, ...*/){
+ // summary:
+ // similar to hitch() except that the scope object is left to be
+ // whatever the execution context eventually becomes.
+ // description:
+ // Calling dojo.partial is the functional equivalent of calling:
+ // | dojo.hitch(null, funcName, ...);
+ var arr = [ null ];
+ return d.hitch.apply(d, arr.concat(d._toArray(arguments))); // Function
+ };
+
+ var extraNames = d._extraNames, extraLen = extraNames.length, empty = {};
+
+ dojo.clone = function(/*anything*/ o){
+ // summary:
+ // Clones objects (including DOM nodes) and all children.
+ // Warning: do not clone cyclic structures.
+ if(!o || typeof o != "object" || d.isFunction(o)){
+ // null, undefined, any non-object, or function
+ return o; // anything
+ }
+ if(o.nodeType && "cloneNode" in o){
+ // DOM Node
+ return o.cloneNode(true); // Node
+ }
+ if(o instanceof Date){
+ // Date
+ return new Date(o.getTime()); // Date
+ }
+ if(o instanceof RegExp){
+ // RegExp
+ return new RegExp(o); // RegExp
+ }
+ var r, i, l, s, name;
+ if(d.isArray(o)){
+ // array
+ r = [];
+ for(i = 0, l = o.length; i < l; ++i){
+ if(i in o){
+ r.push(d.clone(o[i]));
+ }
+ }
+// we don't clone functions for performance reasons
+// }else if(d.isFunction(o)){
+// // function
+// r = function(){ return o.apply(this, arguments); };
+ }else{
+ // generic objects
+ r = o.constructor ? new o.constructor() : {};
+ }
+ for(name in o){
+ // the "tobj" condition avoid copying properties in "source"
+ // inherited from Object.prototype. For example, if target has a custom
+ // toString() method, don't overwrite it with the toString() method
+ // that source inherited from Object.prototype
+ s = o[name];
+ if(!(name in r) || (r[name] !== s && (!(name in empty) || empty[name] !== s))){
+ r[name] = d.clone(s);
+ }
+ }
+ // IE doesn't recognize some custom functions in for..in
+ if(extraLen){
+ for(i = 0; i < extraLen; ++i){
+ name = extraNames[i];
+ s = o[name];
+ if(!(name in r) || (r[name] !== s && (!(name in empty) || empty[name] !== s))){
+ r[name] = s; // functions only, we don't clone them
+ }
+ }
+ }
+ return r; // Object
+ };
+
+ /*=====
+ dojo.trim = function(str){
+ // summary:
+ // Trims whitespace from both sides of the string
+ // str: String
+ // String to be trimmed
+ // returns: String
+ // Returns the trimmed string
+ // description:
+ // This version of trim() was selected for inclusion into the base due
+ // to its compact size and relatively good performance
+ // (see [Steven Levithan's blog](http://blog.stevenlevithan.com/archives/faster-trim-javascript)
+ // Uses String.prototype.trim instead, if available.
+ // The fastest but longest version of this function is located at
+ // dojo.string.trim()
+ return ""; // String
+ }
+ =====*/
+
+ dojo.trim = String.prototype.trim ?
+ function(str){ return str.trim(); } :
+ function(str){ return str.replace(/^\s\s*/, '').replace(/\s\s*$/, ''); };
+
+ /*=====
+ dojo.replace = function(tmpl, map, pattern){
+ // summary:
+ // Performs parameterized substitutions on a string. Throws an
+ // exception if any parameter is unmatched.
+ // tmpl: String
+ // String to be used as a template.
+ // map: Object|Function
+ // If an object, it is used as a dictionary to look up substitutions.
+ // If a function, it is called for every substitution with following
+ // parameters: a whole match, a name, an offset, and the whole template
+ // string (see https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/String/replace
+ // for more details).
+ // pattern: RegEx?
+ // Optional regular expression objects that overrides the default pattern.
+ // Must be global and match one item. The default is: /\{([^\}]+)\}/g,
+ // which matches patterns like that: "{xxx}", where "xxx" is any sequence
+ // of characters, which doesn't include "}".
+ // returns: String
+ // Returns the substituted string.
+ // example:
+ // | // uses a dictionary for substitutions:
+ // | dojo.replace("Hello, {name.first} {name.last} AKA {nick}!",
+ // | {
+ // | nick: "Bob",
+ // | name: {
+ // | first: "Robert",
+ // | middle: "X",
+ // | last: "Cringely"
+ // | }
+ // | });
+ // | // returns: Hello, Robert Cringely AKA Bob!
+ // example:
+ // | // uses an array for substitutions:
+ // | dojo.replace("Hello, {0} {2}!",
+ // | ["Robert", "X", "Cringely"]);
+ // | // returns: Hello, Robert Cringely!
+ // example:
+ // | // uses a function for substitutions:
+ // | function sum(a){
+ // | var t = 0;
+ // | dojo.forEach(a, function(x){ t += x; });
+ // | return t;
+ // | }
+ // | dojo.replace(
+ // | "{count} payments averaging {avg} USD per payment.",
+ // | dojo.hitch(
+ // | { payments: [11, 16, 12] },
+ // | function(_, key){
+ // | switch(key){
+ // | case "count": return this.payments.length;
+ // | case "min": return Math.min.apply(Math, this.payments);
+ // | case "max": return Math.max.apply(Math, this.payments);
+ // | case "sum": return sum(this.payments);
+ // | case "avg": return sum(this.payments) / this.payments.length;
+ // | }
+ // | }
+ // | )
+ // | );
+ // | // prints: 3 payments averaging 13 USD per payment.
+ // example:
+ // | // uses an alternative PHP-like pattern for substitutions:
+ // | dojo.replace("Hello, ${0} ${2}!",
+ // | ["Robert", "X", "Cringely"], /\$\{([^\}]+)\}/g);
+ // | // returns: Hello, Robert Cringely!
+ return ""; // String
+ }
+ =====*/
+
+ var _pattern = /\{([^\}]+)\}/g;
+ dojo.replace = function(tmpl, map, pattern){
+ return tmpl.replace(pattern || _pattern, d.isFunction(map) ?
+ map : function(_, k){ return d.getObject(k, false, map); });
+ };
+})();
+
+}
+
+if(!dojo._hasResource["dojo._base.array"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo._base.array"] = true;
+dojo.provide("dojo._base.array");
+
+
+
+(function(){
+ var _getParts = function(arr, obj, cb){
+ return [
+ (typeof arr == "string") ? arr.split("") : arr,
+ obj || dojo.global,
+ // FIXME: cache the anonymous functions we create here?
+ (typeof cb == "string") ? new Function("item", "index", "array", cb) : cb
+ ];
+ };
+
+ var everyOrSome = function(/*Boolean*/every, /*Array|String*/arr, /*Function|String*/callback, /*Object?*/thisObject){
+ var _p = _getParts(arr, thisObject, callback); arr = _p[0];
+ for(var i=0,l=arr.length; i<l; ++i){
+ var result = !!_p[2].call(_p[1], arr[i], i, arr);
+ if(every ^ result){
+ return result; // Boolean
+ }
+ }
+ return every; // Boolean
+ };
+
+ dojo.mixin(dojo, {
+ indexOf: function( /*Array*/ array,
+ /*Object*/ value,
+ /*Integer?*/ fromIndex,
+ /*Boolean?*/ findLast){
+ // summary:
+ // locates the first index of the provided value in the
+ // passed array. If the value is not found, -1 is returned.
+ // description:
+ // This method corresponds to the JavaScript 1.6 Array.indexOf method, with one difference: when
+ // run over sparse arrays, the Dojo function invokes the callback for every index whereas JavaScript
+ // 1.6's indexOf skips the holes in the sparse array.
+ // For details on this method, see:
+ // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/indexOf
+
+ var step = 1, end = array.length || 0, i = 0;
+ if(findLast){
+ i = end - 1;
+ step = end = -1;
+ }
+ if(fromIndex != undefined){ i = fromIndex; }
+ if((findLast && i > end) || i < end){
+ for(; i != end; i += step){
+ if(array[i] == value){ return i; }
+ }
+ }
+ return -1; // Number
+ },
+
+ lastIndexOf: function(/*Array*/array, /*Object*/value, /*Integer?*/fromIndex){
+ // summary:
+ // locates the last index of the provided value in the passed
+ // array. If the value is not found, -1 is returned.
+ // description:
+ // This method corresponds to the JavaScript 1.6 Array.lastIndexOf method, with one difference: when
+ // run over sparse arrays, the Dojo function invokes the callback for every index whereas JavaScript
+ // 1.6's lastIndexOf skips the holes in the sparse array.
+ // For details on this method, see:
+ // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/lastIndexOf
+ return dojo.indexOf(array, value, fromIndex, true); // Number
+ },
+
+ forEach: function(/*Array|String*/arr, /*Function|String*/callback, /*Object?*/thisObject){
+ // summary:
+ // for every item in arr, callback is invoked. Return values are ignored.
+ // If you want to break out of the loop, consider using dojo.every() or dojo.some().
+ // forEach does not allow breaking out of the loop over the items in arr.
+ // arr:
+ // the array to iterate over. If a string, operates on individual characters.
+ // callback:
+ // a function is invoked with three arguments: item, index, and array
+ // thisObject:
+ // may be used to scope the call to callback
+ // description:
+ // This function corresponds to the JavaScript 1.6 Array.forEach() method, with one difference: when
+ // run over sparse arrays, this implemenation passes the "holes" in the sparse array to
+ // the callback function with a value of undefined. JavaScript 1.6's forEach skips the holes in the sparse array.
+ // For more details, see:
+ // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/forEach
+ // example:
+ // | // log out all members of the array:
+ // | dojo.forEach(
+ // | [ "thinger", "blah", "howdy", 10 ],
+ // | function(item){
+ // | console.log(item);
+ // | }
+ // | );
+ // example:
+ // | // log out the members and their indexes
+ // | dojo.forEach(
+ // | [ "thinger", "blah", "howdy", 10 ],
+ // | function(item, idx, arr){
+ // | console.log(item, "at index:", idx);
+ // | }
+ // | );
+ // example:
+ // | // use a scoped object member as the callback
+ // |
+ // | var obj = {
+ // | prefix: "logged via obj.callback:",
+ // | callback: function(item){
+ // | console.log(this.prefix, item);
+ // | }
+ // | };
+ // |
+ // | // specifying the scope function executes the callback in that scope
+ // | dojo.forEach(
+ // | [ "thinger", "blah", "howdy", 10 ],
+ // | obj.callback,
+ // | obj
+ // | );
+ // |
+ // | // alternately, we can accomplish the same thing with dojo.hitch()
+ // | dojo.forEach(
+ // | [ "thinger", "blah", "howdy", 10 ],
+ // | dojo.hitch(obj, "callback")
+ // | );
+
+ // match the behavior of the built-in forEach WRT empty arrs
+ if(!arr || !arr.length){ return; }
+
+ // FIXME: there are several ways of handilng thisObject. Is
+ // dojo.global always the default context?
+ var _p = _getParts(arr, thisObject, callback); arr = _p[0];
+ for(var i=0,l=arr.length; i<l; ++i){
+ _p[2].call(_p[1], arr[i], i, arr);
+ }
+ },
+
+ every: function(/*Array|String*/arr, /*Function|String*/callback, /*Object?*/thisObject){
+ // summary:
+ // Determines whether or not every item in arr satisfies the
+ // condition implemented by callback.
+ // arr:
+ // the array to iterate on. If a string, operates on individual characters.
+ // callback:
+ // a function is invoked with three arguments: item, index,
+ // and array and returns true if the condition is met.
+ // thisObject:
+ // may be used to scope the call to callback
+ // description:
+ // This function corresponds to the JavaScript 1.6 Array.every() method, with one difference: when
+ // run over sparse arrays, this implemenation passes the "holes" in the sparse array to
+ // the callback function with a value of undefined. JavaScript 1.6's every skips the holes in the sparse array.
+ // For more details, see:
+ // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/every
+ // example:
+ // | // returns false
+ // | dojo.every([1, 2, 3, 4], function(item){ return item>1; });
+ // example:
+ // | // returns true
+ // | dojo.every([1, 2, 3, 4], function(item){ return item>0; });
+ return everyOrSome(true, arr, callback, thisObject); // Boolean
+ },
+
+ some: function(/*Array|String*/arr, /*Function|String*/callback, /*Object?*/thisObject){
+ // summary:
+ // Determines whether or not any item in arr satisfies the
+ // condition implemented by callback.
+ // arr:
+ // the array to iterate over. If a string, operates on individual characters.
+ // callback:
+ // a function is invoked with three arguments: item, index,
+ // and array and returns true if the condition is met.
+ // thisObject:
+ // may be used to scope the call to callback
+ // description:
+ // This function corresponds to the JavaScript 1.6 Array.some() method, with one difference: when
+ // run over sparse arrays, this implemenation passes the "holes" in the sparse array to
+ // the callback function with a value of undefined. JavaScript 1.6's some skips the holes in the sparse array.
+ // For more details, see:
+ // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/some
+ // example:
+ // | // is true
+ // | dojo.some([1, 2, 3, 4], function(item){ return item>1; });
+ // example:
+ // | // is false
+ // | dojo.some([1, 2, 3, 4], function(item){ return item<1; });
+ return everyOrSome(false, arr, callback, thisObject); // Boolean
+ },
+
+ map: function(/*Array|String*/arr, /*Function|String*/callback, /*Function?*/thisObject){
+ // summary:
+ // applies callback to each element of arr and returns
+ // an Array with the results
+ // arr:
+ // the array to iterate on. If a string, operates on
+ // individual characters.
+ // callback:
+ // a function is invoked with three arguments, (item, index,
+ // array), and returns a value
+ // thisObject:
+ // may be used to scope the call to callback
+ // description:
+ // This function corresponds to the JavaScript 1.6 Array.map() method, with one difference: when
+ // run over sparse arrays, this implemenation passes the "holes" in the sparse array to
+ // the callback function with a value of undefined. JavaScript 1.6's map skips the holes in the sparse array.
+ // For more details, see:
+ // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map
+ // example:
+ // | // returns [2, 3, 4, 5]
+ // | dojo.map([1, 2, 3, 4], function(item){ return item+1 });
+
+ var _p = _getParts(arr, thisObject, callback); arr = _p[0];
+ var outArr = (arguments[3] ? (new arguments[3]()) : []);
+ for(var i=0,l=arr.length; i<l; ++i){
+ outArr.push(_p[2].call(_p[1], arr[i], i, arr));
+ }
+ return outArr; // Array
+ },
+
+ filter: function(/*Array*/arr, /*Function|String*/callback, /*Object?*/thisObject){
+ // summary:
+ // Returns a new Array with those items from arr that match the
+ // condition implemented by callback.
+ // arr:
+ // the array to iterate over.
+ // callback:
+ // a function that is invoked with three arguments (item,
+ // index, array). The return of this function is expected to
+ // be a boolean which determines whether the passed-in item
+ // will be included in the returned array.
+ // thisObject:
+ // may be used to scope the call to callback
+ // description:
+ // This function corresponds to the JavaScript 1.6 Array.filter() method, with one difference: when
+ // run over sparse arrays, this implemenation passes the "holes" in the sparse array to
+ // the callback function with a value of undefined. JavaScript 1.6's filter skips the holes in the sparse array.
+ // For more details, see:
+ // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter
+ // example:
+ // | // returns [2, 3, 4]
+ // | dojo.filter([1, 2, 3, 4], function(item){ return item>1; });
+
+ var _p = _getParts(arr, thisObject, callback); arr = _p[0];
+ var outArr = [];
+ for(var i=0,l=arr.length; i<l; ++i){
+ if(_p[2].call(_p[1], arr[i], i, arr)){
+ outArr.push(arr[i]);
+ }
+ }
+ return outArr; // Array
+ }
+ });
+})();
+/*
+*/
+
+}
+
+if(!dojo._hasResource["dojo._base.declare"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo._base.declare"] = true;
+dojo.provide("dojo._base.declare");
+
+
+
+
+(function(){
+ var d = dojo, mix = d._mixin, op = Object.prototype, opts = op.toString,
+ xtor = new Function, counter = 0, cname = "constructor";
+
+ function err(msg, cls){ throw new Error("declare" + (cls ? " " + cls : "") + ": " + msg); }
+
+ // C3 Method Resolution Order (see http://www.python.org/download/releases/2.3/mro/)
+ function c3mro(bases, className){
+ var result = [], roots = [{cls: 0, refs: []}], nameMap = {}, clsCount = 1,
+ l = bases.length, i = 0, j, lin, base, top, proto, rec, name, refs;
+
+ // build a list of bases naming them if needed
+ for(; i < l; ++i){
+ base = bases[i];
+ if(!base){
+ err("mixin #" + i + " is unknown. Did you use dojo.require to pull it in?", className);
+ }else if(opts.call(base) != "[object Function]"){
+ err("mixin #" + i + " is not a callable constructor.", className);
+ }
+ lin = base._meta ? base._meta.bases : [base];
+ top = 0;
+ // add bases to the name map
+ for(j = lin.length - 1; j >= 0; --j){
+ proto = lin[j].prototype;
+ if(!proto.hasOwnProperty("declaredClass")){
+ proto.declaredClass = "uniqName_" + (counter++);
+ }
+ name = proto.declaredClass;
+ if(!nameMap.hasOwnProperty(name)){
+ nameMap[name] = {count: 0, refs: [], cls: lin[j]};
+ ++clsCount;
+ }
+ rec = nameMap[name];
+ if(top && top !== rec){
+ rec.refs.push(top);
+ ++top.count;
+ }
+ top = rec;
+ }
+ ++top.count;
+ roots[0].refs.push(top);
+ }
+
+ // remove classes without external references recursively
+ while(roots.length){
+ top = roots.pop();
+ result.push(top.cls);
+ --clsCount;
+ // optimization: follow a single-linked chain
+ while(refs = top.refs, refs.length == 1){
+ top = refs[0];
+ if(!top || --top.count){
+ // branch or end of chain => do not end to roots
+ top = 0;
+ break;
+ }
+ result.push(top.cls);
+ --clsCount;
+ }
+ if(top){
+ // branch
+ for(i = 0, l = refs.length; i < l; ++i){
+ top = refs[i];
+ if(!--top.count){
+ roots.push(top);
+ }
+ }
+ }
+ }
+ if(clsCount){
+ err("can't build consistent linearization", className);
+ }
+
+ // calculate the superclass offset
+ base = bases[0];
+ result[0] = base ?
+ base._meta && base === result[result.length - base._meta.bases.length] ?
+ base._meta.bases.length : 1 : 0;
+
+ return result;
+ }
+
+ function inherited(args, a, f){
+ var name, chains, bases, caller, meta, base, proto, opf, pos,
+ cache = this._inherited = this._inherited || {};
+
+ // crack arguments
+ if(typeof args == "string"){
+ name = args;
+ args = a;
+ a = f;
+ }
+ f = 0;
+
+ caller = args.callee;
+ name = name || caller.nom;
+ if(!name){
+ err("can't deduce a name to call inherited()", this.declaredClass);
+ }
+
+ meta = this.constructor._meta;
+ bases = meta.bases;
+
+ pos = cache.p;
+ if(name != cname){
+ // method
+ if(cache.c !== caller){
+ // cache bust
+ pos = 0;
+ base = bases[0];
+ meta = base._meta;
+ if(meta.hidden[name] !== caller){
+ // error detection
+ chains = meta.chains;
+ if(chains && typeof chains[name] == "string"){
+ err("calling chained method with inherited: " + name, this.declaredClass);
+ }
+ // find caller
+ do{
+ meta = base._meta;
+ proto = base.prototype;
+ if(meta && (proto[name] === caller && proto.hasOwnProperty(name) || meta.hidden[name] === caller)){
+ break;
+ }
+ }while(base = bases[++pos]); // intentional assignment
+ pos = base ? pos : -1;
+ }
+ }
+ // find next
+ base = bases[++pos];
+ if(base){
+ proto = base.prototype;
+ if(base._meta && proto.hasOwnProperty(name)){
+ f = proto[name];
+ }else{
+ opf = op[name];
+ do{
+ proto = base.prototype;
+ f = proto[name];
+ if(f && (base._meta ? proto.hasOwnProperty(name) : f !== opf)){
+ break;
+ }
+ }while(base = bases[++pos]); // intentional assignment
+ }
+ }
+ f = base && f || op[name];
+ }else{
+ // constructor
+ if(cache.c !== caller){
+ // cache bust
+ pos = 0;
+ meta = bases[0]._meta;
+ if(meta && meta.ctor !== caller){
+ // error detection
+ chains = meta.chains;
+ if(!chains || chains.constructor !== "manual"){
+ err("calling chained constructor with inherited", this.declaredClass);
+ }
+ // find caller
+ while(base = bases[++pos]){ // intentional assignment
+ meta = base._meta;
+ if(meta && meta.ctor === caller){
+ break;
+ }
+ }
+ pos = base ? pos : -1;
+ }
+ }
+ // find next
+ while(base = bases[++pos]){ // intentional assignment
+ meta = base._meta;
+ f = meta ? meta.ctor : base;
+ if(f){
+ break;
+ }
+ }
+ f = base && f;
+ }
+
+ // cache the found super method
+ cache.c = f;
+ cache.p = pos;
+
+ // now we have the result
+ if(f){
+ return a === true ? f : f.apply(this, a || args);
+ }
+ // intentionally if a super method was not found
+ }
+
+ function getInherited(name, args){
+ if(typeof name == "string"){
+ return this.inherited(name, args, true);
+ }
+ return this.inherited(name, true);
+ }
+
+ // emulation of "instanceof"
+ function isInstanceOf(cls){
+ var bases = this.constructor._meta.bases;
+ for(var i = 0, l = bases.length; i < l; ++i){
+ if(bases[i] === cls){
+ return true;
+ }
+ }
+ return this instanceof cls;
+ }
+
+ function mixOwn(target, source){
+ var name, i = 0, l = d._extraNames.length;
+ // add props adding metadata for incoming functions skipping a constructor
+ for(name in source){
+ if(name != cname && source.hasOwnProperty(name)){
+ target[name] = source[name];
+ }
+ }
+ // process unenumerable methods on IE
+ for(; i < l; ++i){
+ name = d._extraNames[i];
+ if(name != cname && source.hasOwnProperty(name)){
+ target[name] = source[name];
+ }
+ }
+ }
+
+ // implementation of safe mixin function
+ function safeMixin(target, source){
+ var name, t, i = 0, l = d._extraNames.length;
+ // add props adding metadata for incoming functions skipping a constructor
+ for(name in source){
+ t = source[name];
+ if((t !== op[name] || !(name in op)) && name != cname){
+ if(opts.call(t) == "[object Function]"){
+ // non-trivial function method => attach its name
+ t.nom = name;
+ }
+ target[name] = t;
+ }
+ }
+ // process unenumerable methods on IE
+ for(; i < l; ++i){
+ name = d._extraNames[i];
+ t = source[name];
+ if((t !== op[name] || !(name in op)) && name != cname){
+ if(opts.call(t) == "[object Function]"){
+ // non-trivial function method => attach its name
+ t.nom = name;
+ }
+ target[name] = t;
+ }
+ }
+ return target;
+ }
+
+ function extend(source){
+ safeMixin(this.prototype, source);
+ return this;
+ }
+
+ // chained constructor compatible with the legacy dojo.declare()
+ function chainedConstructor(bases, ctorSpecial){
+ return function(){
+ var a = arguments, args = a, a0 = a[0], f, i, m,
+ l = bases.length, preArgs;
+
+ if(!(this instanceof a.callee)){
+ // not called via new, so force it
+ return applyNew(a);
+ }
+
+ //this._inherited = {};
+ // perform the shaman's rituals of the original dojo.declare()
+ // 1) call two types of the preamble
+ if(ctorSpecial && (a0 && a0.preamble || this.preamble)){
+ // full blown ritual
+ preArgs = new Array(bases.length);
+ // prepare parameters
+ preArgs[0] = a;
+ for(i = 0;;){
+ // process the preamble of the 1st argument
+ a0 = a[0];
+ if(a0){
+ f = a0.preamble;
+ if(f){
+ a = f.apply(this, a) || a;
+ }
+ }
+ // process the preamble of this class
+ f = bases[i].prototype;
+ f = f.hasOwnProperty("preamble") && f.preamble;
+ if(f){
+ a = f.apply(this, a) || a;
+ }
+ // one peculiarity of the preamble:
+ // it is called if it is not needed,
+ // e.g., there is no constructor to call
+ // let's watch for the last constructor
+ // (see ticket #9795)
+ if(++i == l){
+ break;
+ }
+ preArgs[i] = a;
+ }
+ }
+ // 2) call all non-trivial constructors using prepared arguments
+ for(i = l - 1; i >= 0; --i){
+ f = bases[i];
+ m = f._meta;
+ f = m ? m.ctor : f;
+ if(f){
+ f.apply(this, preArgs ? preArgs[i] : a);
+ }
+ }
+ // 3) continue the original ritual: call the postscript
+ f = this.postscript;
+ if(f){
+ f.apply(this, args);
+ }
+ };
+ }
+
+
+ // chained constructor compatible with the legacy dojo.declare()
+ function singleConstructor(ctor, ctorSpecial){
+ return function(){
+ var a = arguments, t = a, a0 = a[0], f;
+
+ if(!(this instanceof a.callee)){
+ // not called via new, so force it
+ return applyNew(a);
+ }
+
+ //this._inherited = {};
+ // perform the shaman's rituals of the original dojo.declare()
+ // 1) call two types of the preamble
+ if(ctorSpecial){
+ // full blown ritual
+ if(a0){
+ // process the preamble of the 1st argument
+ f = a0.preamble;
+ if(f){
+ t = f.apply(this, t) || t;
+ }
+ }
+ f = this.preamble;
+ if(f){
+ // process the preamble of this class
+ f.apply(this, t);
+ // one peculiarity of the preamble:
+ // it is called even if it is not needed,
+ // e.g., there is no constructor to call
+ // let's watch for the last constructor
+ // (see ticket #9795)
+ }
+ }
+ // 2) call a constructor
+ if(ctor){
+ ctor.apply(this, a);
+ }
+ // 3) continue the original ritual: call the postscript
+ f = this.postscript;
+ if(f){
+ f.apply(this, a);
+ }
+ };
+ }
+
+ // plain vanilla constructor (can use inherited() to call its base constructor)
+ function simpleConstructor(bases){
+ return function(){
+ var a = arguments, i = 0, f, m;
+
+ if(!(this instanceof a.callee)){
+ // not called via new, so force it
+ return applyNew(a);
+ }
+
+ //this._inherited = {};
+ // perform the shaman's rituals of the original dojo.declare()
+ // 1) do not call the preamble
+ // 2) call the top constructor (it can use this.inherited())
+ for(; f = bases[i]; ++i){ // intentional assignment
+ m = f._meta;
+ f = m ? m.ctor : f;
+ if(f){
+ f.apply(this, a);
+ break;
+ }
+ }
+ // 3) call the postscript
+ f = this.postscript;
+ if(f){
+ f.apply(this, a);
+ }
+ };
+ }
+
+ function chain(name, bases, reversed){
+ return function(){
+ var b, m, f, i = 0, step = 1;
+ if(reversed){
+ i = bases.length - 1;
+ step = -1;
+ }
+ for(; b = bases[i]; i += step){ // intentional assignment
+ m = b._meta;
+ f = (m ? m.hidden : b.prototype)[name];
+ if(f){
+ f.apply(this, arguments);
+ }
+ }
+ };
+ }
+
+ // forceNew(ctor)
+ // return a new object that inherits from ctor.prototype but
+ // without actually running ctor on the object.
+ function forceNew(ctor){
+ // create object with correct prototype using a do-nothing
+ // constructor
+ xtor.prototype = ctor.prototype;
+ var t = new xtor;
+ xtor.prototype = null; // clean up
+ return t;
+ }
+
+ // applyNew(args)
+ // just like 'new ctor()' except that the constructor and its arguments come
+ // from args, which must be an array or an arguments object
+ function applyNew(args){
+ // create an object with ctor's prototype but without
+ // calling ctor on it.
+ var ctor = args.callee, t = forceNew(ctor);
+ // execute the real constructor on the new object
+ ctor.apply(t, args);
+ return t;
+ }
+
+ d.declare = function(className, superclass, props){
+ // crack parameters
+ if(typeof className != "string"){
+ props = superclass;
+ superclass = className;
+ className = "";
+ }
+ props = props || {};
+
+ var proto, i, t, ctor, name, bases, chains, mixins = 1, parents = superclass;
+
+ // build a prototype
+ if(opts.call(superclass) == "[object Array]"){
+ // C3 MRO
+ bases = c3mro(superclass, className);
+ t = bases[0];
+ mixins = bases.length - t;
+ superclass = bases[mixins];
+ }else{
+ bases = [0];
+ if(superclass){
+ if(opts.call(superclass) == "[object Function]"){
+ t = superclass._meta;
+ bases = bases.concat(t ? t.bases : superclass);
+ }else{
+ err("base class is not a callable constructor.", className);
+ }
+ }else if(superclass !== null){
+ err("unknown base class. Did you use dojo.require to pull it in?", className);
+ }
+ }
+ if(superclass){
+ for(i = mixins - 1;; --i){
+ proto = forceNew(superclass);
+ if(!i){
+ // stop if nothing to add (the last base)
+ break;
+ }
+ // mix in properties
+ t = bases[i];
+ (t._meta ? mixOwn : mix)(proto, t.prototype);
+ // chain in new constructor
+ ctor = new Function;
+ ctor.superclass = superclass;
+ ctor.prototype = proto;
+ superclass = proto.constructor = ctor;
+ }
+ }else{
+ proto = {};
+ }
+ // add all properties
+ safeMixin(proto, props);
+ // add constructor
+ t = props.constructor;
+ if(t !== op.constructor){
+ t.nom = cname;
+ proto.constructor = t;
+ }
+
+ // collect chains and flags
+ for(i = mixins - 1; i; --i){ // intentional assignment
+ t = bases[i]._meta;
+ if(t && t.chains){
+ chains = mix(chains || {}, t.chains);
+ }
+ }
+ if(proto["-chains-"]){
+ chains = mix(chains || {}, proto["-chains-"]);
+ }
+
+ // build ctor
+ t = !chains || !chains.hasOwnProperty(cname);
+ bases[0] = ctor = (chains && chains.constructor === "manual") ? simpleConstructor(bases) :
+ (bases.length == 1 ? singleConstructor(props.constructor, t) : chainedConstructor(bases, t));
+
+ // add meta information to the constructor
+ ctor._meta = {bases: bases, hidden: props, chains: chains,
+ parents: parents, ctor: props.constructor};
+ ctor.superclass = superclass && superclass.prototype;
+ ctor.extend = extend;
+ ctor.prototype = proto;
+ proto.constructor = ctor;
+
+ // add "standard" methods to the prototype
+ proto.getInherited = getInherited;
+ proto.inherited = inherited;
+ proto.isInstanceOf = isInstanceOf;
+
+ // add name if specified
+ if(className){
+ proto.declaredClass = className;
+ d.setObject(className, ctor);
+ }
+
+ // build chains and add them to the prototype
+ if(chains){
+ for(name in chains){
+ if(proto[name] && typeof chains[name] == "string" && name != cname){
+ t = proto[name] = chain(name, bases, chains[name] === "after");
+ t.nom = name;
+ }
+ }
+ }
+ // chained methods do not return values
+ // no need to chain "invisible" functions
+
+ return ctor; // Function
+ };
+
+ d.safeMixin = safeMixin;
+
+ /*=====
+ dojo.declare = function(className, superclass, props){
+ // summary:
+ // Create a feature-rich constructor from compact notation.
+ // className: String?:
+ // The optional name of the constructor (loosely, a "class")
+ // stored in the "declaredClass" property in the created prototype.
+ // It will be used as a global name for a created constructor.
+ // superclass: Function|Function[]:
+ // May be null, a Function, or an Array of Functions. This argument
+ // specifies a list of bases (the left-most one is the most deepest
+ // base).
+ // props: Object:
+ // An object whose properties are copied to the created prototype.
+ // Add an instance-initialization function by making it a property
+ // named "constructor".
+ // returns:
+ // New constructor function.
+ // description:
+ // Create a constructor using a compact notation for inheritance and
+ // prototype extension.
+ //
+ // Mixin ancestors provide a type of multiple inheritance.
+ // Prototypes of mixin ancestors are copied to the new class:
+ // changes to mixin prototypes will not affect classes to which
+ // they have been mixed in.
+ //
+ // Ancestors can be compound classes created by this version of
+ // dojo.declare. In complex cases all base classes are going to be
+ // linearized according to C3 MRO algorithm
+ // (see http://www.python.org/download/releases/2.3/mro/ for more
+ // details).
+ //
+ // "className" is cached in "declaredClass" property of the new class,
+ // if it was supplied. The immediate super class will be cached in
+ // "superclass" property of the new class.
+ //
+ // Methods in "props" will be copied and modified: "nom" property
+ // (the declared name of the method) will be added to all copied
+ // functions to help identify them for the internal machinery. Be
+ // very careful, while reusing methods: if you use the same
+ // function under different names, it can produce errors in some
+ // cases.
+ //
+ // It is possible to use constructors created "manually" (without
+ // dojo.declare) as bases. They will be called as usual during the
+ // creation of an instance, their methods will be chained, and even
+ // called by "this.inherited()".
+ //
+ // Special property "-chains-" governs how to chain methods. It is
+ // a dictionary, which uses method names as keys, and hint strings
+ // as values. If a hint string is "after", this method will be
+ // called after methods of its base classes. If a hint string is
+ // "before", this method will be called before methods of its base
+ // classes.
+ //
+ // If "constructor" is not mentioned in "-chains-" property, it will
+ // be chained using the legacy mode: using "after" chaining,
+ // calling preamble() method before each constructor, if available,
+ // and calling postscript() after all constructors were executed.
+ // If the hint is "after", it is chained as a regular method, but
+ // postscript() will be called after the chain of constructors.
+ // "constructor" cannot be chained "before", but it allows
+ // a special hint string: "manual", which means that constructors
+ // are not going to be chained in any way, and programmer will call
+ // them manually using this.inherited(). In the latter case
+ // postscript() will be called after the construction.
+ //
+ // All chaining hints are "inherited" from base classes and
+ // potentially can be overridden. Be very careful when overriding
+ // hints! Make sure that all chained methods can work in a proposed
+ // manner of chaining.
+ //
+ // Once a method was chained, it is impossible to unchain it. The
+ // only exception is "constructor". You don't need to define a
+ // method in order to supply a chaining hint.
+ //
+ // If a method is chained, it cannot use this.inherited() because
+ // all other methods in the hierarchy will be called automatically.
+ //
+ // Usually constructors and initializers of any kind are chained
+ // using "after" and destructors of any kind are chained as
+ // "before". Note that chaining assumes that chained methods do not
+ // return any value: any returned value will be discarded.
+ //
+ // example:
+ // | dojo.declare("my.classes.bar", my.classes.foo, {
+ // | // properties to be added to the class prototype
+ // | someValue: 2,
+ // | // initialization function
+ // | constructor: function(){
+ // | this.myComplicatedObject = new ReallyComplicatedObject();
+ // | },
+ // | // other functions
+ // | someMethod: function(){
+ // | doStuff();
+ // | }
+ // | });
+ //
+ // example:
+ // | var MyBase = dojo.declare(null, {
+ // | // constructor, properties, and methods go here
+ // | // ...
+ // | });
+ // | var MyClass1 = dojo.declare(MyBase, {
+ // | // constructor, properties, and methods go here
+ // | // ...
+ // | });
+ // | var MyClass2 = dojo.declare(MyBase, {
+ // | // constructor, properties, and methods go here
+ // | // ...
+ // | });
+ // | var MyDiamond = dojo.declare([MyClass1, MyClass2], {
+ // | // constructor, properties, and methods go here
+ // | // ...
+ // | });
+ //
+ // example:
+ // | var F = function(){ console.log("raw constructor"); };
+ // | F.prototype.method = function(){
+ // | console.log("raw method");
+ // | };
+ // | var A = dojo.declare(F, {
+ // | constructor: function(){
+ // | console.log("A.constructor");
+ // | },
+ // | method: function(){
+ // | console.log("before calling F.method...");
+ // | this.inherited(arguments);
+ // | console.log("...back in A");
+ // | }
+ // | });
+ // | new A().method();
+ // | // will print:
+ // | // raw constructor
+ // | // A.constructor
+ // | // before calling F.method...
+ // | // raw method
+ // | // ...back in A
+ //
+ // example:
+ // | var A = dojo.declare(null, {
+ // | "-chains-": {
+ // | destroy: "before"
+ // | }
+ // | });
+ // | var B = dojo.declare(A, {
+ // | constructor: function(){
+ // | console.log("B.constructor");
+ // | },
+ // | destroy: function(){
+ // | console.log("B.destroy");
+ // | }
+ // | });
+ // | var C = dojo.declare(B, {
+ // | constructor: function(){
+ // | console.log("C.constructor");
+ // | },
+ // | destroy: function(){
+ // | console.log("C.destroy");
+ // | }
+ // | });
+ // | new C().destroy();
+ // | // prints:
+ // | // B.constructor
+ // | // C.constructor
+ // | // C.destroy
+ // | // B.destroy
+ //
+ // example:
+ // | var A = dojo.declare(null, {
+ // | "-chains-": {
+ // | constructor: "manual"
+ // | }
+ // | });
+ // | var B = dojo.declare(A, {
+ // | constructor: function(){
+ // | // ...
+ // | // call the base constructor with new parameters
+ // | this.inherited(arguments, [1, 2, 3]);
+ // | // ...
+ // | }
+ // | });
+ //
+ // example:
+ // | var A = dojo.declare(null, {
+ // | "-chains-": {
+ // | m1: "before"
+ // | },
+ // | m1: function(){
+ // | console.log("A.m1");
+ // | },
+ // | m2: function(){
+ // | console.log("A.m2");
+ // | }
+ // | });
+ // | var B = dojo.declare(A, {
+ // | "-chains-": {
+ // | m2: "after"
+ // | },
+ // | m1: function(){
+ // | console.log("B.m1");
+ // | },
+ // | m2: function(){
+ // | console.log("B.m2");
+ // | }
+ // | });
+ // | var x = new B();
+ // | x.m1();
+ // | // prints:
+ // | // B.m1
+ // | // A.m1
+ // | x.m2();
+ // | // prints:
+ // | // A.m2
+ // | // B.m2
+ return new Function(); // Function
+ };
+ =====*/
+
+ /*=====
+ dojo.safeMixin = function(target, source){
+ // summary:
+ // Mix in properties skipping a constructor and decorating functions
+ // like it is done by dojo.declare.
+ // target: Object
+ // Target object to accept new properties.
+ // source: Object
+ // Source object for new properties.
+ // description:
+ // This function is used to mix in properties like dojo._mixin does,
+ // but it skips a constructor property and decorates functions like
+ // dojo.declare does.
+ //
+ // It is meant to be used with classes and objects produced with
+ // dojo.declare. Functions mixed in with dojo.safeMixin can use
+ // this.inherited() like normal methods.
+ //
+ // This function is used to implement extend() method of a constructor
+ // produced with dojo.declare().
+ //
+ // example:
+ // | var A = dojo.declare(null, {
+ // | m1: function(){
+ // | console.log("A.m1");
+ // | },
+ // | m2: function(){
+ // | console.log("A.m2");
+ // | }
+ // | });
+ // | var B = dojo.declare(A, {
+ // | m1: function(){
+ // | this.inherited(arguments);
+ // | console.log("B.m1");
+ // | }
+ // | });
+ // | B.extend({
+ // | m2: function(){
+ // | this.inherited(arguments);
+ // | console.log("B.m2");
+ // | }
+ // | });
+ // | var x = new B();
+ // | dojo.safeMixin(x, {
+ // | m1: function(){
+ // | this.inherited(arguments);
+ // | console.log("X.m1");
+ // | },
+ // | m2: function(){
+ // | this.inherited(arguments);
+ // | console.log("X.m2");
+ // | }
+ // | });
+ // | x.m2();
+ // | // prints:
+ // | // A.m1
+ // | // B.m1
+ // | // X.m1
+ };
+ =====*/
+
+ /*=====
+ Object.inherited = function(name, args, newArgs){
+ // summary:
+ // Calls a super method.
+ // name: String?
+ // The optional method name. Should be the same as the caller's
+ // name. Usually "name" is specified in complex dynamic cases, when
+ // the calling method was dynamically added, undecorated by
+ // dojo.declare, and it cannot be determined.
+ // args: Arguments
+ // The caller supply this argument, which should be the original
+ // "arguments".
+ // newArgs: Object?
+ // If "true", the found function will be returned without
+ // executing it.
+ // If Array, it will be used to call a super method. Otherwise
+ // "args" will be used.
+ // returns:
+ // Whatever is returned by a super method, or a super method itself,
+ // if "true" was specified as newArgs.
+ // description:
+ // This method is used inside method of classes produced with
+ // dojo.declare to call a super method (next in the chain). It is
+ // used for manually controlled chaining. Consider using the regular
+ // chaining, because it is faster. Use "this.inherited()" only in
+ // complex cases.
+ //
+ // This method cannot me called from automatically chained
+ // constructors including the case of a special (legacy)
+ // constructor chaining. It cannot be called from chained methods.
+ //
+ // If "this.inherited()" cannot find the next-in-chain method, it
+ // does nothing and returns "undefined". The last method in chain
+ // can be a default method implemented in Object, which will be
+ // called last.
+ //
+ // If "name" is specified, it is assumed that the method that
+ // received "args" is the parent method for this call. It is looked
+ // up in the chain list and if it is found the next-in-chain method
+ // is called. If it is not found, the first-in-chain method is
+ // called.
+ //
+ // If "name" is not specified, it will be derived from the calling
+ // method (using a methoid property "nom").
+ //
+ // example:
+ // | var B = dojo.declare(A, {
+ // | method1: function(a, b, c){
+ // | this.inherited(arguments);
+ // | },
+ // | method2: function(a, b){
+ // | return this.inherited(arguments, [a + b]);
+ // | }
+ // | });
+ // | // next method is not in the chain list because it is added
+ // | // manually after the class was created.
+ // | B.prototype.method3 = function(){
+ // | console.log("This is a dynamically-added method.");
+ // | this.inherited("method3", arguments);
+ // | };
+ // example:
+ // | var B = dojo.declare(A, {
+ // | method: function(a, b){
+ // | var super = this.inherited(arguments, true);
+ // | // ...
+ // | if(!super){
+ // | console.log("there is no super method");
+ // | return 0;
+ // | }
+ // | return super.apply(this, arguments);
+ // | }
+ // | });
+ return {}; // Object
+ }
+ =====*/
+
+ /*=====
+ Object.getInherited = function(name, args){
+ // summary:
+ // Returns a super method.
+ // name: String?
+ // The optional method name. Should be the same as the caller's
+ // name. Usually "name" is specified in complex dynamic cases, when
+ // the calling method was dynamically added, undecorated by
+ // dojo.declare, and it cannot be determined.
+ // args: Arguments
+ // The caller supply this argument, which should be the original
+ // "arguments".
+ // returns:
+ // Returns a super method (Function) or "undefined".
+ // description:
+ // This method is a convenience method for "this.inherited()".
+ // It uses the same algorithm but instead of executing a super
+ // method, it returns it, or "undefined" if not found.
+ //
+ // example:
+ // | var B = dojo.declare(A, {
+ // | method: function(a, b){
+ // | var super = this.getInherited(arguments);
+ // | // ...
+ // | if(!super){
+ // | console.log("there is no super method");
+ // | return 0;
+ // | }
+ // | return super.apply(this, arguments);
+ // | }
+ // | });
+ return {}; // Object
+ }
+ =====*/
+
+ /*=====
+ Object.isInstanceOf = function(cls){
+ // summary:
+ // Checks the inheritance chain to see if it is inherited from this
+ // class.
+ // cls: Function
+ // Class constructor.
+ // returns:
+ // "true", if this object is inherited from this class, "false"
+ // otherwise.
+ // description:
+ // This method is used with instances of classes produced with
+ // dojo.declare to determine of they support a certain interface or
+ // not. It models "instanceof" operator.
+ //
+ // example:
+ // | var A = dojo.declare(null, {
+ // | // constructor, properties, and methods go here
+ // | // ...
+ // | });
+ // | var B = dojo.declare(null, {
+ // | // constructor, properties, and methods go here
+ // | // ...
+ // | });
+ // | var C = dojo.declare([A, B], {
+ // | // constructor, properties, and methods go here
+ // | // ...
+ // | });
+ // | var D = dojo.declare(A, {
+ // | // constructor, properties, and methods go here
+ // | // ...
+ // | });
+ // |
+ // | var a = new A(), b = new B(), c = new C(), d = new D();
+ // |
+ // | console.log(a.isInstanceOf(A)); // true
+ // | console.log(b.isInstanceOf(A)); // false
+ // | console.log(c.isInstanceOf(A)); // true
+ // | console.log(d.isInstanceOf(A)); // true
+ // |
+ // | console.log(a.isInstanceOf(B)); // false
+ // | console.log(b.isInstanceOf(B)); // true
+ // | console.log(c.isInstanceOf(B)); // true
+ // | console.log(d.isInstanceOf(B)); // false
+ // |
+ // | console.log(a.isInstanceOf(C)); // false
+ // | console.log(b.isInstanceOf(C)); // false
+ // | console.log(c.isInstanceOf(C)); // true
+ // | console.log(d.isInstanceOf(C)); // false
+ // |
+ // | console.log(a.isInstanceOf(D)); // false
+ // | console.log(b.isInstanceOf(D)); // false
+ // | console.log(c.isInstanceOf(D)); // false
+ // | console.log(d.isInstanceOf(D)); // true
+ return {}; // Object
+ }
+ =====*/
+
+ /*=====
+ Object.extend = function(source){
+ // summary:
+ // Adds all properties and methods of source to constructor's
+ // prototype, making them available to all instances created with
+ // constructor. This method is specific to constructors created with
+ // dojo.declare.
+ // source: Object
+ // Source object which properties are going to be copied to the
+ // constructor's prototype.
+ // description:
+ // Adds source properties to the constructor's prototype. It can
+ // override existing properties.
+ //
+ // This method is similar to dojo.extend function, but it is specific
+ // to constructors produced by dojo.declare. It is implemented
+ // using dojo.safeMixin, and it skips a constructor property,
+ // and properly decorates copied functions.
+ //
+ // example:
+ // | var A = dojo.declare(null, {
+ // | m1: function(){},
+ // | s1: "Popokatepetl"
+ // | });
+ // | A.extend({
+ // | m1: function(){},
+ // | m2: function(){},
+ // | f1: true,
+ // | d1: 42
+ // | });
+ };
+ =====*/
+})();
+
+}
+
+if(!dojo._hasResource["dojo._base.connect"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo._base.connect"] = true;
+dojo.provide("dojo._base.connect");
+
+
+
+// this file courtesy of the TurboAjax Group, licensed under a Dojo CLA
+
+// low-level delegation machinery
+dojo._listener = {
+ // create a dispatcher function
+ getDispatcher: function(){
+ // following comments pulled out-of-line to prevent cloning them
+ // in the returned function.
+ // - indices (i) that are really in the array of listeners (ls) will
+ // not be in Array.prototype. This is the 'sparse array' trick
+ // that keeps us safe from libs that take liberties with built-in
+ // objects
+ // - listener is invoked with current scope (this)
+ return function(){
+ var ap = Array.prototype, c = arguments.callee, ls = c._listeners, t = c.target,
+ // return value comes from original target function
+ r = t && t.apply(this, arguments),
+ // make local copy of listener array so it is immutable during processing
+ i, lls = [].concat(ls)
+ ;
+
+ // invoke listeners after target function
+ for(i in lls){
+ if(!(i in ap)){
+ lls[i].apply(this, arguments);
+ }
+ }
+ // return value comes from original target function
+ return r;
+ };
+ },
+ // add a listener to an object
+ add: function(/*Object*/ source, /*String*/ method, /*Function*/ listener){
+ // Whenever 'method' is invoked, 'listener' will have the same scope.
+ // Trying to supporting a context object for the listener led to
+ // complexity.
+ // Non trivial to provide 'once' functionality here
+ // because listener could be the result of a dojo.hitch call,
+ // in which case two references to the same hitch target would not
+ // be equivalent.
+ source = source || dojo.global;
+ // The source method is either null, a dispatcher, or some other function
+ var f = source[method];
+ // Ensure a dispatcher
+ if(!f || !f._listeners){
+ var d = dojo._listener.getDispatcher();
+ // original target function is special
+ d.target = f;
+ // dispatcher holds a list of listeners
+ d._listeners = [];
+ // redirect source to dispatcher
+ f = source[method] = d;
+ }
+ // The contract is that a handle is returned that can
+ // identify this listener for disconnect.
+ //
+ // The type of the handle is private. Here is it implemented as Integer.
+ // DOM event code has this same contract but handle is Function
+ // in non-IE browsers.
+ //
+ // We could have separate lists of before and after listeners.
+ return f._listeners.push(listener); /*Handle*/
+ },
+ // remove a listener from an object
+ remove: function(/*Object*/ source, /*String*/ method, /*Handle*/ handle){
+ var f = (source || dojo.global)[method];
+ // remember that handle is the index+1 (0 is not a valid handle)
+ if(f && f._listeners && handle--){
+ delete f._listeners[handle];
+ }
+ }
+};
+
+// Multiple delegation for arbitrary methods.
+
+// This unit knows nothing about DOM, but we include DOM aware documentation
+// and dontFix argument here to help the autodocs. Actual DOM aware code is in
+// event.js.
+
+dojo.connect = function(/*Object|null*/ obj,
+ /*String*/ event,
+ /*Object|null*/ context,
+ /*String|Function*/ method,
+ /*Boolean?*/ dontFix){
+ // summary:
+ // `dojo.connect` is the core event handling and delegation method in
+ // Dojo. It allows one function to "listen in" on the execution of
+ // any other, triggering the second whenever the first is called. Many
+ // listeners may be attached to a function, and source functions may
+ // be either regular function calls or DOM events.
+ //
+ // description:
+ // Connects listeners to actions, so that after event fires, a
+ // listener is called with the same arguments passed to the original
+ // function.
+ //
+ // Since `dojo.connect` allows the source of events to be either a
+ // "regular" JavaScript function or a DOM event, it provides a uniform
+ // interface for listening to all the types of events that an
+ // application is likely to deal with though a single, unified
+ // interface. DOM programmers may want to think of it as
+ // "addEventListener for everything and anything".
+ //
+ // When setting up a connection, the `event` parameter must be a
+ // string that is the name of the method/event to be listened for. If
+ // `obj` is null, `dojo.global` is assumed, meaning that connections
+ // to global methods are supported but also that you may inadvertently
+ // connect to a global by passing an incorrect object name or invalid
+ // reference.
+ //
+ // `dojo.connect` generally is forgiving. If you pass the name of a
+ // function or method that does not yet exist on `obj`, connect will
+ // not fail, but will instead set up a stub method. Similarly, null
+ // arguments may simply be omitted such that fewer than 4 arguments
+ // may be required to set up a connection See the examples for details.
+ //
+ // The return value is a handle that is needed to
+ // remove this connection with `dojo.disconnect`.
+ //
+ // obj:
+ // The source object for the event function.
+ // Defaults to `dojo.global` if null.
+ // If obj is a DOM node, the connection is delegated
+ // to the DOM event manager (unless dontFix is true).
+ //
+ // event:
+ // String name of the event function in obj.
+ // I.e. identifies a property `obj[event]`.
+ //
+ // context:
+ // The object that method will receive as "this".
+ //
+ // If context is null and method is a function, then method
+ // inherits the context of event.
+ //
+ // If method is a string then context must be the source
+ // object object for method (context[method]). If context is null,
+ // dojo.global is used.
+ //
+ // method:
+ // A function reference, or name of a function in context.
+ // The function identified by method fires after event does.
+ // method receives the same arguments as the event.
+ // See context argument comments for information on method's scope.
+ //
+ // dontFix:
+ // If obj is a DOM node, set dontFix to true to prevent delegation
+ // of this connection to the DOM event manager.
+ //
+ // example:
+ // When obj.onchange(), do ui.update():
+ // | dojo.connect(obj, "onchange", ui, "update");
+ // | dojo.connect(obj, "onchange", ui, ui.update); // same
+ //
+ // example:
+ // Using return value for disconnect:
+ // | var link = dojo.connect(obj, "onchange", ui, "update");
+ // | ...
+ // | dojo.disconnect(link);
+ //
+ // example:
+ // When onglobalevent executes, watcher.handler is invoked:
+ // | dojo.connect(null, "onglobalevent", watcher, "handler");
+ //
+ // example:
+ // When ob.onCustomEvent executes, customEventHandler is invoked:
+ // | dojo.connect(ob, "onCustomEvent", null, "customEventHandler");
+ // | dojo.connect(ob, "onCustomEvent", "customEventHandler"); // same
+ //
+ // example:
+ // When ob.onCustomEvent executes, customEventHandler is invoked
+ // with the same scope (this):
+ // | dojo.connect(ob, "onCustomEvent", null, customEventHandler);
+ // | dojo.connect(ob, "onCustomEvent", customEventHandler); // same
+ //
+ // example:
+ // When globalEvent executes, globalHandler is invoked
+ // with the same scope (this):
+ // | dojo.connect(null, "globalEvent", null, globalHandler);
+ // | dojo.connect("globalEvent", globalHandler); // same
+
+ // normalize arguments
+ var a=arguments, args=[], i=0;
+ // if a[0] is a String, obj was omitted
+ args.push(dojo.isString(a[0]) ? null : a[i++], a[i++]);
+ // if the arg-after-next is a String or Function, context was NOT omitted
+ var a1 = a[i+1];
+ args.push(dojo.isString(a1)||dojo.isFunction(a1) ? a[i++] : null, a[i++]);
+ // absorb any additional arguments
+ for(var l=a.length; i<l; i++){ args.push(a[i]); }
+ // do the actual work
+ return dojo._connect.apply(this, args); /*Handle*/
+}
+
+// used by non-browser hostenvs. always overriden by event.js
+dojo._connect = function(obj, event, context, method){
+ var l=dojo._listener, h=l.add(obj, event, dojo.hitch(context, method));
+ return [obj, event, h, l]; // Handle
+};
+
+dojo.disconnect = function(/*Handle*/ handle){
+ // summary:
+ // Remove a link created by dojo.connect.
+ // description:
+ // Removes the connection between event and the method referenced by handle.
+ // handle:
+ // the return value of the dojo.connect call that created the connection.
+ if(handle && handle[0] !== undefined){
+ dojo._disconnect.apply(this, handle);
+ // let's not keep this reference
+ delete handle[0];
+ }
+};
+
+dojo._disconnect = function(obj, event, handle, listener){
+ listener.remove(obj, event, handle);
+};
+
+// topic publish/subscribe
+
+dojo._topics = {};
+
+dojo.subscribe = function(/*String*/ topic, /*Object|null*/ context, /*String|Function*/ method){
+ // summary:
+ // Attach a listener to a named topic. The listener function is invoked whenever the
+ // named topic is published (see: dojo.publish).
+ // Returns a handle which is needed to unsubscribe this listener.
+ // context:
+ // Scope in which method will be invoked, or null for default scope.
+ // method:
+ // The name of a function in context, or a function reference. This is the function that
+ // is invoked when topic is published.
+ // example:
+ // | dojo.subscribe("alerts", null, function(caption, message){ alert(caption + "\n" + message); });
+ // | dojo.publish("alerts", [ "read this", "hello world" ]);
+
+ // support for 2 argument invocation (omitting context) depends on hitch
+ return [topic, dojo._listener.add(dojo._topics, topic, dojo.hitch(context, method))]; /*Handle*/
+};
+
+dojo.unsubscribe = function(/*Handle*/ handle){
+ // summary:
+ // Remove a topic listener.
+ // handle:
+ // The handle returned from a call to subscribe.
+ // example:
+ // | var alerter = dojo.subscribe("alerts", null, function(caption, message){ alert(caption + "\n" + message); };
+ // | ...
+ // | dojo.unsubscribe(alerter);
+ if(handle){
+ dojo._listener.remove(dojo._topics, handle[0], handle[1]);
+ }
+};
+
+dojo.publish = function(/*String*/ topic, /*Array*/ args){
+ // summary:
+ // Invoke all listener method subscribed to topic.
+ // topic:
+ // The name of the topic to publish.
+ // args:
+ // An array of arguments. The arguments will be applied
+ // to each topic subscriber (as first class parameters, via apply).
+ // example:
+ // | dojo.subscribe("alerts", null, function(caption, message){ alert(caption + "\n" + message); };
+ // | dojo.publish("alerts", [ "read this", "hello world" ]);
+
+ // Note that args is an array, which is more efficient vs variable length
+ // argument list. Ideally, var args would be implemented via Array
+ // throughout the APIs.
+ var f = dojo._topics[topic];
+ if(f){
+ f.apply(this, args||[]);
+ }
+};
+
+dojo.connectPublisher = function( /*String*/ topic,
+ /*Object|null*/ obj,
+ /*String*/ event){
+ // summary:
+ // Ensure that every time obj.event() is called, a message is published
+ // on the topic. Returns a handle which can be passed to
+ // dojo.disconnect() to disable subsequent automatic publication on
+ // the topic.
+ // topic:
+ // The name of the topic to publish.
+ // obj:
+ // The source object for the event function. Defaults to dojo.global
+ // if null.
+ // event:
+ // The name of the event function in obj.
+ // I.e. identifies a property obj[event].
+ // example:
+ // | dojo.connectPublisher("/ajax/start", dojo, "xhrGet");
+ var pf = function(){ dojo.publish(topic, arguments); }
+ return event ? dojo.connect(obj, event, pf) : dojo.connect(obj, pf); //Handle
+};
+
+}
+
+if(!dojo._hasResource["dojo._base.Deferred"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo._base.Deferred"] = true;
+dojo.provide("dojo._base.Deferred");
+
+
+
+(function(){
+ var mutator = function(){};
+ var freeze = Object.freeze || function(){};
+ // A deferred provides an API for creating and resolving a promise.
+ dojo.Deferred = function(/*Function?*/canceller){
+ // summary:
+ // Deferreds provide a generic means for encapsulating an asynchronous
+ // operation and notifying users of the completion and result of the operation.
+ // description:
+ // The dojo.Deferred API is based on the concept of promises that provide a
+ // generic interface into the eventual completion of an asynchronous action.
+ // The motivation for promises fundamentally is about creating a
+ // separation of concerns that allows one to achieve the same type of
+ // call patterns and logical data flow in asynchronous code as can be
+ // achieved in synchronous code. Promises allows one
+ // to be able to call a function purely with arguments needed for
+ // execution, without conflating the call with concerns of whether it is
+ // sync or async. One shouldn't need to alter a call's arguments if the
+ // implementation switches from sync to async (or vice versa). By having
+ // async functions return promises, the concerns of making the call are
+ // separated from the concerns of asynchronous interaction (which are
+ // handled by the promise).
+ //
+ // The dojo.Deferred is a type of promise that provides methods for fulfilling the
+ // promise with a successful result or an error. The most important method for
+ // working with Dojo's promises is the then() method, which follows the
+ // CommonJS proposed promise API. An example of using a Dojo promise:
+ //
+ // | var resultingPromise = someAsyncOperation.then(function(result){
+ // | ... handle result ...
+ // | },
+ // | function(error){
+ // | ... handle error ...
+ // | });
+ //
+ // The .then() call returns a new promise that represents the result of the
+ // execution of the callback. The callbacks will never affect the original promises value.
+ //
+ // The dojo.Deferred instances also provide the following functions for backwards compatibility:
+ //
+ // * addCallback(handler)
+ // * addErrback(handler)
+ // * callback(result)
+ // * errback(result)
+ //
+ // Callbacks are allowed to return promises themselves, so
+ // you can build complicated sequences of events with ease.
+ //
+ // The creator of the Deferred may specify a canceller. The canceller
+ // is a function that will be called if Deferred.cancel is called
+ // before the Deferred fires. You can use this to implement clean
+ // aborting of an XMLHttpRequest, etc. Note that cancel will fire the
+ // deferred with a CancelledError (unless your canceller returns
+ // another kind of error), so the errbacks should be prepared to
+ // handle that error for cancellable Deferreds.
+ // example:
+ // | var deferred = new dojo.Deferred();
+ // | setTimeout(function(){ deferred.callback({success: true}); }, 1000);
+ // | return deferred;
+ // example:
+ // Deferred objects are often used when making code asynchronous. It
+ // may be easiest to write functions in a synchronous manner and then
+ // split code using a deferred to trigger a response to a long-lived
+ // operation. For example, instead of register a callback function to
+ // denote when a rendering operation completes, the function can
+ // simply return a deferred:
+ //
+ // | // callback style:
+ // | function renderLotsOfData(data, callback){
+ // | var success = false
+ // | try{
+ // | for(var x in data){
+ // | renderDataitem(data[x]);
+ // | }
+ // | success = true;
+ // | }catch(e){ }
+ // | if(callback){
+ // | callback(success);
+ // | }
+ // | }
+ //
+ // | // using callback style
+ // | renderLotsOfData(someDataObj, function(success){
+ // | // handles success or failure
+ // | if(!success){
+ // | promptUserToRecover();
+ // | }
+ // | });
+ // | // NOTE: no way to add another callback here!!
+ // example:
+ // Using a Deferred doesn't simplify the sending code any, but it
+ // provides a standard interface for callers and senders alike,
+ // providing both with a simple way to service multiple callbacks for
+ // an operation and freeing both sides from worrying about details
+ // such as "did this get called already?". With Deferreds, new
+ // callbacks can be added at any time.
+ //
+ // | // Deferred style:
+ // | function renderLotsOfData(data){
+ // | var d = new dojo.Deferred();
+ // | try{
+ // | for(var x in data){
+ // | renderDataitem(data[x]);
+ // | }
+ // | d.callback(true);
+ // | }catch(e){
+ // | d.errback(new Error("rendering failed"));
+ // | }
+ // | return d;
+ // | }
+ //
+ // | // using Deferred style
+ // | renderLotsOfData(someDataObj).then(null, function(){
+ // | promptUserToRecover();
+ // | });
+ // | // NOTE: addErrback and addCallback both return the Deferred
+ // | // again, so we could chain adding callbacks or save the
+ // | // deferred for later should we need to be notified again.
+ // example:
+ // In this example, renderLotsOfData is synchronous and so both
+ // versions are pretty artificial. Putting the data display on a
+ // timeout helps show why Deferreds rock:
+ //
+ // | // Deferred style and async func
+ // | function renderLotsOfData(data){
+ // | var d = new dojo.Deferred();
+ // | setTimeout(function(){
+ // | try{
+ // | for(var x in data){
+ // | renderDataitem(data[x]);
+ // | }
+ // | d.callback(true);
+ // | }catch(e){
+ // | d.errback(new Error("rendering failed"));
+ // | }
+ // | }, 100);
+ // | return d;
+ // | }
+ //
+ // | // using Deferred style
+ // | renderLotsOfData(someDataObj).then(null, function(){
+ // | promptUserToRecover();
+ // | });
+ //
+ // Note that the caller doesn't have to change his code at all to
+ // handle the asynchronous case.
+ var result, finished, isError, head, nextListener;
+ var promise = (this.promise = {});
+
+ function complete(value){
+ if(finished){
+ throw new Error("This deferred has already been resolved");
+ }
+ result = value;
+ finished = true;
+ notify();
+ }
+ function notify(){
+ var mutated;
+ while(!mutated && nextListener){
+ var listener = nextListener;
+ nextListener = nextListener.next;
+ if((mutated = (listener.progress == mutator))){ // assignment and check
+ finished = false;
+ }
+ var func = (isError ? listener.error : listener.resolved);
+ if (func) {
+ try {
+ var newResult = func(result);
+ if (newResult && typeof newResult.then === "function") {
+ newResult.then(dojo.hitch(listener.deferred, "resolve"), dojo.hitch(listener.deferred, "reject"));
+ continue;
+ }
+ var unchanged = mutated && newResult === undefined;
+ if(mutated && !unchanged){
+ isError = newResult instanceof Error;
+ }
+ listener.deferred[unchanged && isError ? "reject" : "resolve"](unchanged ? result : newResult);
+ }
+ catch (e) {
+ listener.deferred.reject(e);
+ }
+ }else {
+ if(isError){
+ listener.deferred.reject(result);
+ }else{
+ listener.deferred.resolve(result);
+ }
+ }
+ }
+ }
+ // calling resolve will resolve the promise
+ this.resolve = this.callback = function(value){
+ // summary:
+ // Fulfills the Deferred instance successfully with the provide value
+ this.fired = 0;
+ this.results = [value, null];
+ complete(value);
+ };
+
+
+ // calling error will indicate that the promise failed
+ this.reject = this.errback = function(error){
+ // summary:
+ // Fulfills the Deferred instance as an error with the provided error
+ isError = true;
+ this.fired = 1;
+ complete(error);
+ this.results = [null, error];
+ if(!error || error.log !== false){
+ (dojo.config.deferredOnError || function(x){ console.error(x); })(error);
+ }
+ };
+ // call progress to provide updates on the progress on the completion of the promise
+ this.progress = function(update){
+ // summary
+ // Send progress events to all listeners
+ var listener = nextListener;
+ while(listener){
+ var progress = listener.progress;
+ progress && progress(update);
+ listener = listener.next;
+ }
+ };
+ this.addCallbacks = function(/*Function?*/callback, /*Function?*/errback){
+ this.then(callback, errback, mutator);
+ return this;
+ };
+ // provide the implementation of the promise
+ this.then = promise.then = function(/*Function?*/resolvedCallback, /*Function?*/errorCallback, /*Function?*/progressCallback){
+ // summary:
+ // Adds a fulfilledHandler, errorHandler, and progressHandler to be called for
+ // completion of a promise. The fulfilledHandler is called when the promise
+ // is fulfilled. The errorHandler is called when a promise fails. The
+ // progressHandler is called for progress events. All arguments are optional
+ // and non-function values are ignored. The progressHandler is not only an
+ // optional argument, but progress events are purely optional. Promise
+ // providers are not required to ever create progress events.
+ //
+ // This function will return a new promise that is fulfilled when the given
+ // fulfilledHandler or errorHandler callback is finished. This allows promise
+ // operations to be chained together. The value returned from the callback
+ // handler is the fulfillment value for the returned promise. If the callback
+ // throws an error, the returned promise will be moved to failed state.
+ //
+ // example:
+ // An example of using a CommonJS compliant promise:
+ // | asyncComputeTheAnswerToEverything().
+ // | then(addTwo).
+ // | then(printResult, onError);
+ // | >44
+ //
+ var returnDeferred = progressCallback == mutator ? this : new dojo.Deferred(promise.cancel);
+ var listener = {
+ resolved: resolvedCallback,
+ error: errorCallback,
+ progress: progressCallback,
+ deferred: returnDeferred
+ };
+ if(nextListener){
+ head = head.next = listener;
+ }
+ else{
+ nextListener = head = listener;
+ }
+ if(finished){
+ notify();
+ }
+ return returnDeferred.promise;
+ };
+ var deferred = this;
+ this.cancel = promise.cancel = function () {
+ // summary:
+ // Cancels the asynchronous operation
+ if(!finished){
+ var error = canceller && canceller(deferred);
+ if(!finished){
+ if (!(error instanceof Error)) {
+ error = new Error(error);
+ }
+ error.log = false;
+ deferred.reject(error);
+ }
+ }
+ };
+ freeze(promise);
+ };
+ dojo.extend(dojo.Deferred, {
+ addCallback: function (/*Function*/callback) {
+ return this.addCallbacks(dojo.hitch.apply(dojo, arguments));
+ },
+
+ addErrback: function (/*Function*/errback) {
+ return this.addCallbacks(null, dojo.hitch.apply(dojo, arguments));
+ },
+
+ addBoth: function (/*Function*/callback) {
+ var enclosed = dojo.hitch.apply(dojo, arguments);
+ return this.addCallbacks(enclosed, enclosed);
+ },
+ fired: -1
+ });
+})();
+dojo.when = function(promiseOrValue, /*Function?*/callback, /*Function?*/errback, /*Function?*/progressHandler){
+ // summary:
+ // This provides normalization between normal synchronous values and
+ // asynchronous promises, so you can interact with them in a common way
+ // example:
+ // | function printFirstAndList(items){
+ // | dojo.when(findFirst(items), console.log);
+ // | dojo.when(findLast(items), console.log);
+ // | }
+ // | function findFirst(items){
+ // | return dojo.when(items, function(items){
+ // | return items[0];
+ // | });
+ // | }
+ // | function findLast(items){
+ // | return dojo.when(items, function(items){
+ // | return items[items.length];
+ // | });
+ // | }
+ // And now all three of his functions can be used sync or async.
+ // | printFirstAndLast([1,2,3,4]) will work just as well as
+ // | printFirstAndLast(dojo.xhrGet(...));
+
+ if(promiseOrValue && typeof promiseOrValue.then === "function"){
+ return promiseOrValue.then(callback, errback, progressHandler);
+ }
+ return callback(promiseOrValue);
+};
+
+}
+
+if(!dojo._hasResource["dojo._base.json"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo._base.json"] = true;
+dojo.provide("dojo._base.json");
+
+
+dojo.fromJson = function(/*String*/ json){
+ // summary:
+ // Parses a [JSON](http://json.org) string to return a JavaScript object.
+ // description:
+ // Throws for invalid JSON strings, but it does not use a strict JSON parser. It
+ // delegates to eval(). The content passed to this method must therefore come
+ // from a trusted source.
+ // json:
+ // a string literal of a JSON item, for instance:
+ // `'{ "foo": [ "bar", 1, { "baz": "thud" } ] }'`
+
+ return eval("(" + json + ")"); // Object
+};
+
+dojo._escapeString = function(/*String*/str){
+ //summary:
+ // Adds escape sequences for non-visual characters, double quote and
+ // backslash and surrounds with double quotes to form a valid string
+ // literal.
+ return ('"' + str.replace(/(["\\])/g, '\\$1') + '"').
+ replace(/[\f]/g, "\\f").replace(/[\b]/g, "\\b").replace(/[\n]/g, "\\n").
+ replace(/[\t]/g, "\\t").replace(/[\r]/g, "\\r"); // string
+};
+
+dojo.toJsonIndentStr = "\t";
+dojo.toJson = function(/*Object*/ it, /*Boolean?*/ prettyPrint, /*String?*/ _indentStr){
+ // summary:
+ // Returns a [JSON](http://json.org) serialization of an object.
+ // description:
+ // Returns a [JSON](http://json.org) serialization of an object.
+ // Note that this doesn't check for infinite recursion, so don't do that!
+ // it:
+ // an object to be serialized. Objects may define their own
+ // serialization via a special "__json__" or "json" function
+ // property. If a specialized serializer has been defined, it will
+ // be used as a fallback.
+ // prettyPrint:
+ // if true, we indent objects and arrays to make the output prettier.
+ // The variable `dojo.toJsonIndentStr` is used as the indent string --
+ // to use something other than the default (tab), change that variable
+ // before calling dojo.toJson().
+ // _indentStr:
+ // private variable for recursive calls when pretty printing, do not use.
+ // &nb