diff --git a/docz/docs/02-getting-started/01-installation/04-amd.md b/docz/docs/02-getting-started/01-installation/04-amd.md index dc83a4d..2400dee 100644 --- a/docz/docs/02-getting-started/01-installation/04-amd.md +++ b/docz/docs/02-getting-started/01-installation/04-amd.md @@ -17,7 +17,7 @@ Each standalone release script is available at .

https://cdn.sheetjs.com/xlsx-{current}/package/dist/xlsx.full.min.js is the URL for {current}

-:::note +:::note pass When referencing by file name, AMD loaders typically omit the file extension. @@ -63,7 +63,7 @@ sap.ui.define([ }) ``` -:::warning +:::warning pass **Copy and pasting code does not work** for SheetJS scripts as they contain Unicode characters that may be mangled. The standalone script should be @@ -73,7 +73,7 @@ downloaded and manually uploaded to the project. ## RequireJS -:::caution +:::caution pass The standalone script must be aliased to the path `xlsx`. @@ -100,11 +100,11 @@ require(['xlsx'], function(XLSX) { ## Dojo Toolkit Dojo has changed module loading strategies over the years. These examples were -tested with Dojo `1.10.4` and are not guaranteed to work with other versions. +tested with Dojo `1.17.3`. They are not guaranteed to work with other versions. Live demos are included in ["Dojo Toolkit"](/docs/demos/frontend/legacy#dojo-toolkit) -:::caution +:::caution pass The standalone scripts add `window.XLSX`, so it is recommended to use `_XLSX` in the function arguments and access the library with `XLSX` in the callback: @@ -127,7 +127,7 @@ When `async` is set to `false` or `0`, the scripts can be directly referenced in `require` calls. {`\ - + - + - + ``` -Pages should use `ContentRenderer` to reference the data: +Pages should use `ContentRenderer` to reference the data. The `data` variable +from the script setup will be shaped like the return value from the transformer. +`data.body` is an array of objects that holds the worksheet name and data. -```html title="Page" - +```html title="Template section of .vue VueJS page" + ``` ### Nuxt Content 2 Demo -:::caution +:::caution pass -When the demo was last tested, parts of the Nuxt dependency tree did not support +For some older versions, parts of the Nuxt dependency tree did not support NodeJS version 20. If the `yarn install` step fails with a message like ``` @@ -434,47 +579,14 @@ The server is listening on that URL. Open the link in a web browser. curl -L -o content/pres.xlsx https://sheetjs.com/pres.xlsx ``` -4) Create the transformer. +4) Create the transformer. Two files must be saved at the root of the project: -Two files must be written at the root of the project: +- [`sheetformer.ts`](https://docs.sheetjs.com/nuxt/3/sheetformer.ts) (raw transformer module) +- [`sheetmodule.ts`](https://docs.sheetjs.com/nuxt/3/sheetmodule.ts) (Nuxt configuration module) -- `sheetformer.ts` (the raw transformer module): - -```ts title="sheetformer.ts" -// @ts-ignore -import { defineTransformer } from "@nuxt/content/transformers/utils"; -import { read, utils } from "xlsx"; -import { readFileSync } from "node:fs"; -import { resolve } from 'node:path'; - -export default defineTransformer({ - name: 'sheetformer', - extensions: ['.xlsx'], - parse (_id: string, rawContent: string) { - const wb = read(readFileSync(resolve("./content/" + _id.slice(8)))); - const body = wb.SheetNames.map(name => ({ name, data: utils.sheet_to_json(wb.Sheets[name])})); - return { _id, body }; - } -}); -``` - -- `sheetmodule.ts` (the Nuxt configuration module): - -```ts title="sheetmodule.ts" -import { resolve } from 'path' -import { defineNuxtModule } from '@nuxt/kit' - -export default defineNuxtModule({ - setup (_options, nuxt) { - nuxt.options.nitro.externals = nuxt.options.nitro.externals || {} - nuxt.options.nitro.externals.inline = nuxt.options.nitro.externals.inline || [] - nuxt.options.nitro.externals.inline.push(resolve('./sheetmodule')) - // @ts-ignore - nuxt.hook('content:context', (contentContext) => { - contentContext.transformers.push(resolve('./sheetformer.ts')) - }) - } -}) +```bash +curl -O https://docs.sheetjs.com/nuxt/3/sheetformer.ts +curl -O https://docs.sheetjs.com/nuxt/3/sheetmodule.ts ``` After creating the source files, the module must be added to `nuxt.config.ts`: @@ -490,7 +602,7 @@ export default defineNuxtConfig({ '@nuxt/content' ], content: {} -}) +}); ``` Restart the dev server by exiting the process (Control+C) and running: @@ -520,25 +632,11 @@ Loading `http://localhost:3000/pres` should show some JSON data: }, ``` -5) Create a page. Save the following content to `pages/pres.vue`: +5) Download [`pres.vue`](pathname:///nuxt/3/pres.vue) and save to `pages`: -```html title="pages/pres.vue" - - +```bash +curl -o pages/pres.vue https://docs.sheetjs.com/nuxt/3/pres.vue ``` - Restart the dev server by exiting the process (Control+C) and running: ```bash @@ -568,3 +666,12 @@ npx -y http-server .output/public Accessing `http://localhost:8080/pres` will show the page contents. Verifying the static nature is trivial: make another change in Excel and save. The page will not change. + +[^1]: See [`readFile` in "Reading Files"](/docs/api/parse-options) +[^2]: See [`sheet_to_json` in "Utilities"](/docs/api/utilities/array#array-output) +[^3]: See [`extendParser`](https://content.nuxtjs.org/v1/getting-started/configuration#extendparser) in the NuxtJS documentation. +[^4]: See ["Array of Objects" in the VueJS demo](/docs/demos/frontend/vue#array-of-objects) +[^5]: See [`resolve`](https://nodejs.org/api/path.html#pathresolvepaths) in the NodeJS `node:path` documentation +[^6]: See [`readFileSync`](https://nodejs.org/api/fs.html#fsreadfilesyncpath-options) in the NodeJS `node:fs` documentation +[^7]: See [`read` in "Reading Files"](/docs/api/parse-options) +[^8]: See [`sheet_to_json` in "Utilities"](/docs/api/utilities/array#array-output) diff --git a/docz/docs/08-api/05-write-options.md b/docz/docs/08-api/05-write-options.md index 2305567..e2205b3 100644 --- a/docz/docs/08-api/05-write-options.md +++ b/docz/docs/08-api/05-write-options.md @@ -177,7 +177,7 @@ XLSX.writeFile(wb, "textport.numbers", {numbers: XLSX_ZAHL_PAYLOAD, compression: After installing the package: {`\ -npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} +bun i https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} The scripts will be available at `xlsx/dist/xlsx.zahl` (CommonJS) and @@ -226,33 +226,33 @@ XLSX.writeFile(wb, "textport.numbers", {numbers: XLSX_ZAHL_PAYLOAD, compression: For broad compatibility with third-party tools, this library supports many output formats. The specific file type is controlled with `bookType` option: -| `bookType` | file ext | container | sheets | Description | -| :--------- | -------: | :-------: | :----- |:------------------------------- | -| `xlsx` | `.xlsx` | ZIP | multi | Excel 2007+ XML Format | -| `xlsm` | `.xlsm` | ZIP | multi | Excel 2007+ Macro XML Format | -| `xlsb` | `.xlsb` | ZIP | multi | Excel 2007+ Binary Format | -| `biff8` | `.xls` | CFB | multi | Excel 97-2004 Workbook Format | -| `biff5` | `.xls` | CFB | multi | Excel 5.0/95 Workbook Format | -| `biff4` | `.xls` | none | single | Excel 4.0 Worksheet Format | -| `biff3` | `.xls` | none | single | Excel 3.0 Worksheet Format | -| `biff2` | `.xls` | none | single | Excel 2.0 Worksheet Format | -| `xlml` | `.xls` | none | multi | Excel 2003-2004 (SpreadsheetML) | -| `numbers` |`.numbers`| ZIP | single | Numbers 3.0+ Spreadsheet | -| `ods` | `.ods` | ZIP | multi | OpenDocument Spreadsheet | -| `fods` | `.fods` | none | multi | Flat OpenDocument Spreadsheet | -| `wk3` | `.wk3` | none | multi | Lotus Workbook (WK3) | -| `csv` | `.csv` | none | single | Comma Separated Values | -| `txt` | `.txt` | none | single | UTF-16 Unicode Text (TXT) | -| `sylk` | `.sylk` | none | single | Symbolic Link (SYLK) | -| `html` | `.html` | none | single | HTML Document | -| `dif` | `.dif` | none | single | Data Interchange Format (DIF) | -| `dbf` | `.dbf` | none | single | dBASE II + VFP Extensions (DBF) | -| `wk1` | `.wk1` | none | single | Lotus Worksheet (WK1) | -| `rtf` | `.rtf` | none | single | Rich Text Format (RTF) | -| `prn` | `.prn` | none | single | Lotus Formatted Text | -| `eth` | `.eth` | none | single | Ethercalc Record Format (ETH) | +| `bookType` | extension | sheets | Description | +|:-----------|:-----------|:-------|:--------------------------------| +| `xlsx` | `.xlsx` | multi | Excel 2007+ XML Format | +| `xlsm` | `.xlsm` | multi | Excel 2007+ Macro XML Format | +| `xlsb` | `.xlsb` | multi | Excel 2007+ Binary Format | +| `biff8` | `.xls` | multi | Excel 97-2004 Workbook Format | +| `biff5` | `.xls` | multi | Excel 5.0/95 Workbook Format | +| `biff4` | `.xls` | single | Excel 4.0 Worksheet Format | +| `biff3` | `.xls` | single | Excel 3.0 Worksheet Format | +| `biff2` | `.xls` | single | Excel 2.0 Worksheet Format | +| `xlml` | `.xls` | multi | Excel 2003-2004 (SpreadsheetML) | +| `numbers` | `.numbers` | multi | Numbers 3.0+ Spreadsheet | +| `ods` | `.ods` | multi | OpenDocument Spreadsheet | +| `fods` | `.fods` | multi | Flat OpenDocument Spreadsheet | +| `wk3` | `.wk3` | multi | Lotus Workbook (WK3) | +| `csv` | `.csv` | single | Comma Separated Values | +| `txt` | `.txt` | single | UTF-16 Unicode Text (TXT) | +| `sylk` | `.sylk` | single | Symbolic Link (SYLK) | +| `html` | `.html` | single | HTML Document | +| `dif` | `.dif` | single | Data Interchange Format (DIF) | +| `dbf` | `.dbf` | single | dBASE II + VFP Extensions (DBF) | +| `wk1` | `.wk1` | single | Lotus Worksheet (WK1) | +| `rtf` | `.rtf` | single | Rich Text Format (RTF) | +| `prn` | `.prn` | single | Lotus Formatted Text | +| `eth` | `.eth` | single | Ethercalc Record Format (ETH) | -- `compression` only applies to formats with ZIP containers. +- `compression` applies to ZIP-based formats (XLSX, XLSM, XLSB, NUMBERS, ODS) - Formats that only support a single sheet require a `sheet` option specifying the worksheet. If the string is empty, the first worksheet is used. - `writeFile` will automatically guess the output file format based on the file diff --git a/docz/static/dojo/dojo.js b/docz/static/dojo/dojo.js new file mode 100644 index 0000000..9ea3d48 --- /dev/null +++ b/docz/static/dojo/dojo.js @@ -0,0 +1,18979 @@ +/* + Copyright (c) 2004-2016, The JS 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( + userConfig, + defaultConfig +){ + // summary: + // This is the "source loader" and is the entry point for Dojo during development. You may also load Dojo with + // any AMD-compliant loader via the package main module dojo/main. + // description: + // This is the "source loader" for Dojo. It provides an AMD-compliant loader that can be configured + // to operate in either synchronous or asynchronous modes. After the loader is defined, dojo is loaded + // IAW the package main module dojo/main. In the event you wish to use a foreign loader, you may load dojo as a package + // via the package main module dojo/main and this loader is not required; see dojo/package.json for details. + // + // In order to keep compatibility with the v1.x line, this loader includes additional machinery that enables + // the dojo.provide, dojo.require et al API. This machinery is loaded by default, but may be dynamically removed + // via the has.js API and statically removed via the build system. + // + // This loader includes sniffing machinery to determine the environment; the following environments are supported: + // + // - browser + // - node.js + // - rhino + // + // This is the so-called "source loader". As such, it includes many optional features that may be discarded by + // building a customized version with the build system. + + // Design and Implementation Notes + // + // This is a dojo-specific adaption of bdLoad, donated to the dojo foundation by Altoviso LLC. + // + // This function defines an AMD-compliant (http://wiki.commonjs.org/wiki/Modules/AsynchronousDefinition) + // loader that can be configured to operate in either synchronous or asynchronous modes. + // + // Since this machinery implements a loader, it does not have the luxury of using a load system and/or + // leveraging a utility library. This results in an unpleasantly long file; here is a road map of the contents: + // + // 1. Small library for use implementing the loader. + // 2. Define the has.js API; this is used throughout the loader to bracket features. + // 3. Define the node.js and rhino sniffs and sniff. + // 4. Define the loader's data. + // 5. Define the configuration machinery. + // 6. Define the script element sniffing machinery and sniff for configuration data. + // 7. Configure the loader IAW the provided user, default, and sniffing data. + // 8. Define the global require function. + // 9. Define the module resolution machinery. + // 10. Define the module and plugin module definition machinery + // 11. Define the script injection machinery. + // 12. Define the window load detection. + // 13. Define the logging API. + // 14. Define the tracing API. + // 16. Define the AMD define function. + // 17. Define the dojo v1.x provide/require machinery--so called "legacy" modes. + // 18. Publish global variables. + // + // Language and Acronyms and Idioms + // + // moduleId: a CJS module identifier, (used for public APIs) + // mid: moduleId (used internally) + // packageId: a package identifier (used for public APIs) + // pid: packageId (used internally); the implied system or default package has pid==="" + // pack: package is used internally to reference a package object (since javascript has reserved words including "package") + // prid: plugin resource identifier + // The integer constant 1 is used in place of true and 0 in place of false. + // + // The "foreign-loader" has condition is defined if another loader is being used (e.g. webpack) and this code is only + // needed for resolving module identifiers based on the config. In this case, only the functions require.toUrl and + // require.toAbsMid are supported. The require and define functions are not supported. + + // define global + var globalObject = (function(){ + if (typeof global !== 'undefined' && typeof global !== 'function') { + // global spec defines a reference to the global object called 'global' + // https://github.com/tc39/proposal-global + // `global` is also defined in NodeJS + return global; + } + else if (typeof window !== 'undefined') { + // window is defined in browsers + return window; + } + else if (typeof self !== 'undefined') { + // self is defined in WebWorkers + return self; + } + return this; + })(); + + // define a minimal library to help build the loader + var noop = function(){ + }, + + isEmpty = function(it){ + for(var p in it){ + return 0; + } + return 1; + }, + + toString = {}.toString, + + isFunction = function(it){ + return toString.call(it) == "[object Function]"; + }, + + isString = function(it){ + return toString.call(it) == "[object String]"; + }, + + isArray = function(it){ + return toString.call(it) == "[object Array]"; + }, + + forEach = function(vector, callback){ + if(vector){ + for(var i = 0; i < vector.length;){ + callback(vector[i++]); + } + } + }, + + mix = function(dest, src){ + for(var p in src){ + dest[p] = src[p]; + } + return dest; + }, + + makeError = function(error, info){ + return mix(new Error(error), {src:"dojoLoader", info:info}); + }, + + uidSeed = 1, + + uid = function(){ + // Returns a unique identifier (within the lifetime of the document) of the form /_d+/. + return "_" + uidSeed++; + }, + + // FIXME: how to doc window.require() api + + // this will be the global require function; define it immediately so we can start hanging things off of it + req = function( + config, //(object, optional) hash of configuration properties + dependencies, //(array of commonjs.moduleId, optional) list of modules to be loaded before applying callback + callback //(function, optional) lambda expression to apply to module values implied by dependencies + ){ + return contextRequire(config, dependencies, callback, 0, req); + }, + + // the loader uses the has.js API to control feature inclusion/exclusion; define then use throughout + global = globalObject, + + doc = global.document, + + element = doc && doc.createElement("DiV"), + + has = req.has = function(name){ + return isFunction(hasCache[name]) ? (hasCache[name] = hasCache[name](global, doc, element)) : hasCache[name]; + }, + + hasCache = has.cache = defaultConfig.hasCache; + + if (isFunction(userConfig)) { + userConfig = userConfig(globalObject); + } + + has.add = function(name, test, now, force){ + (hasCache[name]===undefined || force) && (hasCache[name] = test); + return now && has(name); + }; + + 0 && has.add("host-node", userConfig.has && "host-node" in userConfig.has ? + userConfig.has["host-node"] : + (typeof process == "object" && process.versions && process.versions.node && process.versions.v8)); + if( 0 ){ + // fixup the default config for node.js environment + require("./_base/configNode.js").config(defaultConfig); + // remember node's require (with respect to baseUrl==dojo's root) + defaultConfig.loaderPatch.nodeRequire = require; + } + + 0 && has.add("host-rhino", userConfig.has && "host-rhino" in userConfig.has ? + userConfig.has["host-rhino"] : + (typeof load == "function" && (typeof Packages == "function" || typeof Packages == "object"))); + if( 0 ){ + // owing to rhino's lame feature that hides the source of the script, give the user a way to specify the baseUrl... + for(var baseUrl = userConfig.baseUrl || ".", arg, rhinoArgs = this.arguments, i = 0; i < rhinoArgs.length;){ + arg = (rhinoArgs[i++] + "").split("="); + if(arg[0] == "baseUrl"){ + baseUrl = arg[1]; + break; + } + } + load(baseUrl + "/_base/configRhino.js"); + rhinoDojoConfig(defaultConfig, baseUrl, rhinoArgs); + } + + has.add("host-webworker", ((typeof WorkerGlobalScope !== 'undefined') && (self instanceof WorkerGlobalScope))); + if(has("host-webworker")){ + mix(defaultConfig.hasCache, { + "host-browser": 0, + "dom": 0, + "dojo-dom-ready-api": 0, + "dojo-sniff": 0, + "dojo-inject-api": 1, + "host-webworker": 1, + "dojo-guarantee-console": 0 // console is immutable in FF30+, see https://bugs.dojotoolkit.org/ticket/18100 + }); + + defaultConfig.loaderPatch = { + injectUrl: function(url, callback){ + // TODO: + // This is not async, nor can it be in Webworkers. It could be made better by passing + // the entire require array into importScripts at. This way the scripts are loaded in + // async mode; even if the callbacks are ran in sync. It is not a major issue as webworkers + // tend to be long running where initial startup is not a major factor. + + try{ + importScripts(url); + callback(); + }catch(e){ + console.info("failed to load resource (" + url + ")"); + console.error(e); + } + } + }; + } + + // userConfig has tests override defaultConfig has tests; do this after the environment detection because + // the environment detection usually sets some has feature values in the hasCache. + for(var p in userConfig.has){ + has.add(p, userConfig.has[p], 0, 1); + } + + // + // define the loader data + // + + // the loader will use these like symbols if the loader has the traceApi; otherwise + // define magic numbers so that modules can be provided as part of defaultConfig + var requested = 1, + arrived = 2, + nonmodule = 3, + executing = 4, + executed = 5; + + if( 0 ){ + // these make debugging nice; but using strings for symbols is a gross rookie error; don't do it for production code + requested = "requested"; + arrived = "arrived"; + nonmodule = "not-a-module"; + executing = "executing"; + executed = "executed"; + } + + var legacyMode = 0, + sync = "sync", + xd = "xd", + syncExecStack = [], + dojoRequirePlugin = 0, + checkDojoRequirePlugin = noop, + transformToAmd = noop, + getXhr; + if( 1 ){ + req.isXdUrl = noop; + + req.initSyncLoader = function(dojoRequirePlugin_, checkDojoRequirePlugin_, transformToAmd_){ + // the first dojo/_base/loader loaded gets to define these variables; they are designed to work + // in the presence of zero to many mapped dojo/_base/loaders + if(!dojoRequirePlugin){ + dojoRequirePlugin = dojoRequirePlugin_; + checkDojoRequirePlugin = checkDojoRequirePlugin_; + transformToAmd = transformToAmd_; + } + + return { + sync:sync, + requested:requested, + arrived:arrived, + nonmodule:nonmodule, + executing:executing, + executed:executed, + syncExecStack:syncExecStack, + modules:modules, + execQ:execQ, + getModule:getModule, + injectModule:injectModule, + setArrived:setArrived, + signal:signal, + finishExec:finishExec, + execModule:execModule, + dojoRequirePlugin:dojoRequirePlugin, + getLegacyMode:function(){return legacyMode;}, + guardCheckComplete:guardCheckComplete + }; + }; + + if( 1 || has("host-webworker")){ + // in legacy sync mode, the loader needs a minimal XHR library + + var locationProtocol = location.protocol, + locationHost = location.host; + req.isXdUrl = function(url){ + if(/^\./.test(url)){ + // begins with a dot is always relative to page URL; therefore not xdomain + return false; + } + if(/^\/\//.test(url)){ + // for v1.6- backcompat, url starting with // indicates xdomain + return true; + } + // get protocol and host + // \/+ takes care of the typical file protocol that looks like file:///drive/path/to/file + // locationHost is falsy if file protocol => if locationProtocol matches and is "file:", || will return false + var match = url.match(/^([^\/\:]+\:)\/+([^\/]+)/); + return match && (match[1] != locationProtocol || (locationHost && match[2] != locationHost)); + }; + + + // note: to get the file:// protocol to work in FF, you must set security.fileuri.strict_origin_policy to false in about:config + 1 || has.add("dojo-xhr-factory", 1); + has.add("dojo-force-activex-xhr", 1 && !doc.addEventListener && window.location.protocol == "file:"); + has.add("native-xhr", typeof XMLHttpRequest != "undefined"); + if(has("native-xhr") && !has("dojo-force-activex-xhr")){ + getXhr = function(){ + return new XMLHttpRequest(); + }; + }else{ + // if in the browser an old IE; find an xhr + for(var XMLHTTP_PROGIDS = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'], progid, i = 0; i < 3;){ + try{ + progid = XMLHTTP_PROGIDS[i++]; + if(new ActiveXObject(progid)){ + // this progid works; therefore, use it from now on + break; + } + }catch(e){ + // squelch; we're just trying to find a good ActiveX progid + // if they all fail, then progid ends up as the last attempt and that will signal the error + // the first time the client actually tries to exec an xhr + } + } + getXhr = function(){ + return new ActiveXObject(progid); + }; + } + req.getXhr = getXhr; + + has.add("dojo-gettext-api", 1); + req.getText = function(url, async, onLoad){ + var xhr = getXhr(); + xhr.open('GET', fixupUrl(url), false); + xhr.send(null); + if(xhr.status == 200 || (!location.host && !xhr.status)){ + if(onLoad){ + onLoad(xhr.responseText, async); + } + }else{ + throw makeError("xhrFailed", xhr.status); + } + return xhr.responseText; + }; + } + }else{ + req.async = 1; + } + + // + // loader eval + // + var eval_ = has("csp-restrictions") ? + // noop eval if there are csp restrictions + function(){} : + // use the function constructor so our eval is scoped close to (but not in) in the global space with minimal pollution + new Function('return eval(arguments[0]);'); + + req.eval = + function(text, hint){ + return eval_(text + "\r\n//# sourceURL=" + hint); + }; + + // + // loader micro events API + // + var listenerQueues = {}, + error = "error", + signal = req.signal = function(type, args){ + var queue = listenerQueues[type]; + // notice we run a copy of the queue; this allows listeners to add/remove + // other listeners without affecting this particular signal + forEach(queue && queue.slice(0), function(listener){ + listener.apply(null, isArray(args) ? args : [args]); + }); + }, + on = req.on = function(type, listener){ + // notice a queue is not created until a client actually connects + var queue = listenerQueues[type] || (listenerQueues[type] = []); + queue.push(listener); + return { + remove:function(){ + for(var i = 0; i (alias, actual) + = [], + + paths + // CommonJS paths + = {}, + + pathsMapProg + // list of (from-path, to-path, regex, length) derived from paths; + // a "program" to apply paths; see computeMapProg + = [], + + packs + // a map from packageId to package configuration object; see fixupPackageInfo + = {}, + + map = req.map + // AMD map config variable; dojo/_base/kernel needs req.map to figure out the scope map + = {}, + + mapProgs + // vector of quads as described by computeMapProg; map-key is AMD map key, map-value is AMD map value + = [], + + modules + // A hash:(mid) --> (module-object) the module namespace + // + // pid: the package identifier to which the module belongs (e.g., "dojo"); "" indicates the system or default package + // mid: the fully-resolved (i.e., mappings have been applied) module identifier without the package identifier (e.g., "dojo/io/script") + // url: the URL from which the module was retrieved + // pack: the package object of the package to which the module belongs + // executed: 0 => not executed; executing => in the process of traversing deps and running factory; executed => factory has been executed + // deps: the dependency vector for this module (vector of modules objects) + // def: the factory for this module + // result: the result of the running the factory for this module + // injected: (0 | requested | arrived) the status of the module; nonmodule means the resource did not call define + // load: plugin load function; applicable only for plugins + // + // Modules go through several phases in creation: + // + // 1. Requested: some other module's definition or a require application contained the requested module in + // its dependency vector or executing code explicitly demands a module via req.require. + // + // 2. Injected: a script element has been appended to the insert-point element demanding the resource implied by the URL + // + // 3. Loaded: the resource injected in [2] has been evaluated. + // + // 4. Defined: the resource contained a define statement that advised the loader about the module. Notice that some + // resources may just contain a bundle of code and never formally define a module via define + // + // 5. Evaluated: the module was defined via define and the loader has evaluated the factory and computed a result. + = {}, + + cacheBust + // query string to append to module URLs to bust browser cache + = "", + + cache + // hash:(mid | url)-->(function | string) + // + // A cache of resources. The resources arrive via a config.cache object, which is a hash from either mid --> function or + // url --> string. The url key is distinguished from the mid key by always containing the prefix "url:". url keys as provided + // by config.cache always have a string value that represents the contents of the resource at the given url. mid keys as provided + // by configl.cache always have a function value that causes the same code to execute as if the module was script injected. + // + // Both kinds of key-value pairs are entered into cache via the function consumePendingCache, which may relocate keys as given + // by any mappings *iff* the config.cache was received as part of a module resource request. + // + // Further, for mid keys, the implied url is computed and the value is entered into that key as well. This allows mapped modules + // to retrieve cached items that may have arrived consequent to another namespace. + // + = {}, + + urlKeyPrefix + // the prefix to prepend to a URL key in the cache. + = "url:", + + pendingCacheInsert + // hash:(mid)-->(function) + // + // Gives a set of cache modules pending entry into cache. When cached modules are published to the loader, they are + // entered into pendingCacheInsert; modules are then pressed into cache upon (1) AMD define or (2) upon receiving another + // independent set of cached modules. (1) is the usual case, and this case allows normalizing mids given in the pending + // cache for the local configuration, possibly relocating modules. + = {}, + + dojoSniffConfig + // map of configuration variables + // give the data-dojo-config as sniffed from the document (if any) + = {}, + + insertPointSibling + // the nodes used to locate where scripts are injected into the document + = 0; + + if( 1 ){ + if (!has("foreign-loader")) { + var consumePendingCacheInsert = function(referenceModule, clear){ + clear = clear !== false; + var p, item, match, now, m; + for(p in pendingCacheInsert){ + item = pendingCacheInsert[p]; + match = p.match(/^url\:(.+)/); + if(match){ + cache[urlKeyPrefix + toUrl(match[1], referenceModule)] = item; + }else if(p=="*now"){ + now = item; + }else if(p!="*noref"){ + m = getModuleInfo(p, referenceModule, true); + cache[m.mid] = cache[urlKeyPrefix + m.url] = item; + } + } + if(now){ + now(createRequire(referenceModule)); + } + if(clear){ + pendingCacheInsert = {}; + } + }; + } + var escapeString = function(s){ + return s.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, function(c){ return "\\" + c; }); + }, + + computeMapProg = function(map, dest){ + // This routine takes a map as represented by a JavaScript object and initializes dest, a vector of + // quads of (map-key, map-value, refex-for-map-key, length-of-map-key), sorted decreasing by length- + // of-map-key. The regex looks for the map-key followed by either "/" or end-of-string at the beginning + // of a the search source. Notice the map-value is irrelevant to the algorithm + dest.splice(0, dest.length); + for(var p in map){ + dest.push([ + p, + map[p], + new RegExp("^" + escapeString(p) + "(\/|$)"), + p.length]); + } + dest.sort(function(lhs, rhs){ return rhs[3] - lhs[3]; }); + return dest; + }, + + computeAliases = function(config, dest){ + forEach(config, function(pair){ + // take a fixed-up copy... + dest.push([isString(pair[0]) ? new RegExp("^" + escapeString(pair[0]) + "$") : pair[0], pair[1]]); + }); + }, + + + fixupPackageInfo = function(packageInfo){ + // calculate the precise (name, location, main, mappings) for a package + var name = packageInfo.name; + if(!name){ + // packageInfo must be a string that gives the name + name = packageInfo; + packageInfo = {name:name}; + } + packageInfo = mix({main:"main"}, packageInfo); + packageInfo.location = packageInfo.location ? packageInfo.location : name; + + // packageMap is deprecated in favor of AMD map + if(packageInfo.packageMap){ + map[name] = packageInfo.packageMap; + } + + if(!packageInfo.main.indexOf("./")){ + packageInfo.main = packageInfo.main.substring(2); + } + + // now that we've got a fully-resolved package object, push it into the configuration + packs[name] = packageInfo; + }, + + delayedModuleConfig + // module config cannot be consumed until the loader is completely initialized; therefore, all + // module config detected during booting is memorized and applied at the end of loader initialization + // TODO: this is a bit of a kludge; all config should be moved to end of loader initialization, but + // we'll delay this chore and do it with a final loader 1.x cleanup after the 2.x loader prototyping is complete + = [], + + + config = function(config, booting, referenceModule){ + for(var p in config){ + if(p=="waitSeconds"){ + req.waitms = (config[p] || 0) * 1000; + } + if(p=="cacheBust"){ + cacheBust = config[p] ? (isString(config[p]) ? config[p] : (new Date()).getTime() + "") : ""; + } + if(p=="baseUrl" || p=="combo"){ + req[p] = config[p]; + } + if( 1 && p=="async"){ + // falsy or "sync" => legacy sync loader + // "xd" => sync but loading xdomain tree and therefore loading asynchronously (not configurable, set automatically by the loader) + // "legacyAsync" => permanently in "xd" by choice + // "debugAtAllCosts" => trying to load everything via script injection (not implemented) + // otherwise, must be truthy => AMD + // legacyMode: sync | legacyAsync | xd | false + var mode = config[p]; + req.legacyMode = legacyMode = (isString(mode) && /sync|legacyAsync/.test(mode) ? mode : (!mode ? sync : false)); + req.async = !legacyMode; + } + if(config[p]!==hasCache){ + // accumulate raw config info for client apps which can use this to pass their own config + req.rawConfig[p] = config[p]; + p!="has" && has.add("config-"+p, config[p], 0, booting); + } + } + + // make sure baseUrl exists + if(!req.baseUrl){ + req.baseUrl = "./"; + } + // make sure baseUrl ends with a slash + if(!/\/$/.test(req.baseUrl)){ + req.baseUrl += "/"; + } + + // now do the special work for has, packages, packagePaths, paths, aliases, and cache + + for(p in config.has){ + has.add(p, config.has[p], 0, booting); + } + + // for each package found in any packages config item, augment the packs map owned by the loader + forEach(config.packages, fixupPackageInfo); + + // for each packagePath found in any packagePaths config item, augment the packageConfig + // packagePaths is deprecated; remove in 2.0 + for(var baseUrl in config.packagePaths){ + forEach(config.packagePaths[baseUrl], function(packageInfo){ + var location = baseUrl + "/" + packageInfo; + if(isString(packageInfo)){ + packageInfo = {name:packageInfo}; + } + packageInfo.location = location; + fixupPackageInfo(packageInfo); + }); + } + + // notice that computeMapProg treats the dest as a reference; therefore, if/when that variable + // is published (see dojo-publish-privates), the published variable will always hold a valid value. + + // this must come after all package processing since package processing may mutate map + computeMapProg(mix(map, config.map), mapProgs); + forEach(mapProgs, function(item){ + item[1] = computeMapProg(item[1], []); + if(item[0]=="*"){ + mapProgs.star = item; + } + }); + + // push in any paths and recompute the internal pathmap + computeMapProg(mix(paths, config.paths), pathsMapProg); + + // aliases + computeAliases(config.aliases, aliases); + + if (!has("foreign-loader")) { + if(booting){ + delayedModuleConfig.push({config:config.config}); + }else{ + for(p in config.config){ + var module = getModule(p, referenceModule); + module.config = mix(module.config || {}, config.config[p]); + } + } + + // push in any new cache values + if(config.cache){ + consumePendingCacheInsert(); + pendingCacheInsert = config.cache; + //inject now all depencies so cache is available for mapped module + consumePendingCacheInsert(0, !!config.cache["*noref"]); + } + } + signal("config", [config, req.rawConfig]); + }; + + // + // execute the various sniffs; userConfig can override and value + // + + if(has("dojo-cdn") || 1 ){ + // the sniff regex looks for a src attribute ending in dojo.js, optionally preceded with a path. + // match[3] returns the path to dojo.js (if any) without the trailing slash. This is used for the + // dojo location on CDN deployments and baseUrl when either/both of these are not provided + // explicitly in the config data; this is the 1.6- behavior. + + var scripts = doc.getElementsByTagName("script"), + i = 0, + script, dojoDir, src, match; + while(i < scripts.length){ + script = scripts[i++]; + if((src = script.getAttribute("src")) && (match = src.match(/(((.*)\/)|^)dojo\.js(\W|$)/i))){ + // sniff dojoDir and baseUrl + dojoDir = match[3] || ""; + defaultConfig.baseUrl = defaultConfig.baseUrl || dojoDir; + + // remember an insertPointSibling + insertPointSibling = script; + } + + // sniff configuration on attribute in script element + if((src = (script.getAttribute("data-dojo-config") || script.getAttribute("djConfig")))){ + dojoSniffConfig = req.eval("({ " + src + " })", "data-dojo-config"); + + // remember an insertPointSibling + insertPointSibling = script; + } + + // sniff requirejs attribute + if( 0 ){ + if((src = script.getAttribute("data-main"))){ + dojoSniffConfig.deps = dojoSniffConfig.deps || [src]; + } + } + } + } + + if( 0 ){ + // pass down doh.testConfig from parent as if it were a data-dojo-config + try{ + if(window.parent != window && window.parent.require){ + var doh = window.parent.require("doh"); + doh && mix(dojoSniffConfig, doh.testConfig); + } + }catch(e){} + } + + // configure the loader; let the user override defaults + req.rawConfig = {}; + config(defaultConfig, 1); + + // do this before setting userConfig/sniffConfig to allow userConfig/sniff overrides + if(has("dojo-cdn")){ + packs.dojo.location = dojoDir; + if(dojoDir){ + dojoDir += "/"; + } + packs.dijit.location = dojoDir + "../dijit/"; + packs.dojox.location = dojoDir + "../dojox/"; + } + + config(userConfig, 1); + config(dojoSniffConfig, 1); + + }else{ + // no config API, assume defaultConfig has everything the loader needs...for the entire lifetime of the application + paths = defaultConfig.paths; + pathsMapProg = defaultConfig.pathsMapProg; + packs = defaultConfig.packs; + aliases = defaultConfig.aliases; + mapProgs = defaultConfig.mapProgs; + modules = defaultConfig.modules; + cache = defaultConfig.cache; + cacheBust = defaultConfig.cacheBust; + + // remember the default config for other processes (e.g., dojo/config) + req.rawConfig = defaultConfig; + } + + + if (!has("foreign-loader")) { + if( 0 ){ + req.combo = req.combo || {add:noop}; + var comboPending = 0, + combosPending = [], + comboPendingTimer = null; + } + + + // build the loader machinery iaw configuration, including has feature tests + var injectDependencies = function(module){ + // checkComplete!=0 holds the idle signal; we're not idle if we're injecting dependencies + guardCheckComplete(function(){ + forEach(module.deps, injectModule); + if( 0 && comboPending && !comboPendingTimer){ + comboPendingTimer = setTimeout(function() { + comboPending = 0; + comboPendingTimer = null; + req.combo.done(function(mids, url) { + var onLoadCallback= function(){ + // defQ is a vector of module definitions 1-to-1, onto mids + runDefQ(0, mids); + checkComplete(); + }; + combosPending.push(mids); + injectingModule = mids; + req.injectUrl(url, onLoadCallback, mids); + injectingModule = 0; + }, req); + }, 0); + } + }); + }, + + contextRequire = function(a1, a2, a3, referenceModule, contextRequire){ + var module, syntheticMid; + if(isString(a1)){ + // signature is (moduleId) + module = getModule(a1, referenceModule, true); + if(module && module.executed){ + return module.result; + } + throw makeError("undefinedModule", a1); + } + if(!isArray(a1)){ + // a1 is a configuration + config(a1, 0, referenceModule); + + // juggle args; (a2, a3) may be (dependencies, callback) + a1 = a2; + a2 = a3; + } + if(isArray(a1)){ + // signature is (requestList [,callback]) + if(!a1.length){ + a2 && a2(); + }else{ + syntheticMid = "require*" + uid(); + + // resolve the request list with respect to the reference module + for(var mid, deps = [], i = 0; i < a1.length;){ + mid = a1[i++]; + deps.push(getModule(mid, referenceModule)); + } + + // construct a synthetic module to control execution of the requestList, and, optionally, callback + module = mix(makeModuleInfo("", syntheticMid, 0, ""), { + injected: arrived, + deps: deps, + def: a2 || noop, + require: referenceModule ? referenceModule.require : req, + gc: 1 //garbage collect + }); + modules[module.mid] = module; + + // checkComplete!=0 holds the idle signal; we're not idle if we're injecting dependencies + injectDependencies(module); + + // try to immediately execute + // if already traversing a factory tree, then strict causes circular dependency to abort the execution; maybe + // it's possible to execute this require later after the current traversal completes and avoid the circular dependency. + // ...but *always* insist on immediate in synch mode + var strict = checkCompleteGuard && legacyMode!=sync; + guardCheckComplete(function(){ + execModule(module, strict); + }); + if(!module.executed){ + // some deps weren't on board or circular dependency detected and strict; therefore, push into the execQ + execQ.push(module); + } + checkComplete(); + } + } + return contextRequire; + }, + + createRequire = function(module){ + if(!module){ + return req; + } + var result = module.require; + if(!result){ + result = function(a1, a2, a3){ + return contextRequire(a1, a2, a3, module, result); + }; + module.require = mix(result, req); + result.module = module; + result.toUrl = function(name){ + return toUrl(name, module); + }; + result.toAbsMid = function(mid){ + return toAbsMid(mid, module); + }; + if( 0 ){ + result.undef = function(mid){ + req.undef(mid, module); + }; + } + if( 1 ){ + result.syncLoadNls = function(mid){ + var nlsModuleInfo = getModuleInfo(mid, module), + nlsModule = modules[nlsModuleInfo.mid]; + if(!nlsModule || !nlsModule.executed){ + cached = cache[nlsModuleInfo.mid] || cache[urlKeyPrefix + nlsModuleInfo.url]; + if(cached){ + evalModuleText(cached); + nlsModule = modules[nlsModuleInfo.mid]; + } + } + return nlsModule && nlsModule.executed && nlsModule.result; + }; + } + + } + return result; + }, + + execQ = + // The list of modules that need to be evaluated. + [], + + defQ = + // The queue of define arguments sent to loader. + [], + + waiting = + // The set of modules upon which the loader is waiting for definition to arrive + {}, + + setRequested = function(module){ + module.injected = requested; + waiting[module.mid] = 1; + if(module.url){ + waiting[module.url] = module.pack || 1; + } + startTimer(); + }, + + setArrived = function(module){ + module.injected = arrived; + delete waiting[module.mid]; + if(module.url){ + delete waiting[module.url]; + } + if(isEmpty(waiting)){ + clearTimer(); + 1 && legacyMode==xd && (legacyMode = sync); + } + }, + + execComplete = req.idle = + // says the loader has completed (or not) its work + function(){ + return !defQ.length && isEmpty(waiting) && !execQ.length && !checkCompleteGuard; + }; + } + + var runMapProg = function(targetMid, map){ + // search for targetMid in map; return the map item if found; falsy otherwise + if(map){ + for(var i = 0; i < map.length; i++){ + if(map[i][2].test(targetMid)){ + return map[i]; + } + } + } + return 0; + }, + + compactPath = function(path){ + var result = [], + segment, lastSegment; + path = path.replace(/\\/g, '/').split('/'); + while(path.length){ + segment = path.shift(); + if(segment==".." && result.length && lastSegment!=".."){ + result.pop(); + lastSegment = result[result.length - 1]; + }else if(segment!="."){ + result.push(lastSegment= segment); + } // else ignore "." + } + return result.join("/"); + }, + + makeModuleInfo = function(pid, mid, pack, url){ + if( 1 ){ + var xd= req.isXdUrl(url); + return {pid:pid, mid:mid, pack:pack, url:url, executed:0, def:0, isXd:xd, isAmd:!!(xd || (packs[pid] && packs[pid].isAmd))}; + }else{ + return {pid:pid, mid:mid, pack:pack, url:url, executed:0, def:0}; + } + }, + + getModuleInfo_ = function(mid, referenceModule, packs, modules, baseUrl, mapProgs, pathsMapProg, aliases, alwaysCreate, fromPendingCache){ + // arguments are passed instead of using lexical variables so that this function my be used independent of the loader (e.g., the builder) + // alwaysCreate is useful in this case so that getModuleInfo never returns references to real modules owned by the loader + var pid, pack, midInPackage, mapItem, url, result, isRelative, requestedMid; + requestedMid = mid; + isRelative = /^\./.test(mid); + if(/(^\/)|(\:)|(\.js$)/.test(mid) || (isRelative && !referenceModule)){ + // absolute path or protocol of .js filetype, or relative path but no reference module and therefore relative to page + // whatever it is, it's not a module but just a URL of some sort + // note: pid===0 indicates the routine is returning an unmodified mid + + return makeModuleInfo(0, mid, 0, mid); + }else{ + // relative module ids are relative to the referenceModule; get rid of any dots + mid = compactPath(isRelative ? (referenceModule.mid + "/../" + mid) : mid); + if(/^\./.test(mid)){ + throw makeError("irrationalPath", mid); + } + // at this point, mid is an absolute mid + + // map the mid + if(!fromPendingCache && !isRelative && mapProgs.star){ + mapItem = runMapProg(mid, mapProgs.star[1]); + } + if(!mapItem && referenceModule){ + mapItem = runMapProg(referenceModule.mid, mapProgs); + mapItem = mapItem && runMapProg(mid, mapItem[1]); + } + + if(mapItem){ + mid = mapItem[1] + mid.substring(mapItem[3]); + } + + match = mid.match(/^([^\/]+)(\/(.+))?$/); + pid = match ? match[1] : ""; + if((pack = packs[pid])){ + mid = pid + "/" + (midInPackage = (match[3] || pack.main)); + }else{ + pid = ""; + } + + // search aliases + var candidateLength = 0, + candidate = 0; + forEach(aliases, function(pair){ + var match = mid.match(pair[0]); + if(match && match.length>candidateLength){ + candidate = isFunction(pair[1]) ? mid.replace(pair[0], pair[1]) : pair[1]; + } + }); + if(candidate){ + return getModuleInfo_(candidate, 0, packs, modules, baseUrl, mapProgs, pathsMapProg, aliases, alwaysCreate); + } + + result = modules[mid]; + if(result){ + return alwaysCreate ? makeModuleInfo(result.pid, result.mid, result.pack, result.url) : modules[mid]; + } + } + // get here iff the sought-after module does not yet exist; therefore, we need to compute the URL given the + // fully resolved (i.e., all relative indicators and package mapping resolved) module id + + // note: pid!==0 indicates the routine is returning a url that has .js appended unmodified mid + mapItem = runMapProg(mid, pathsMapProg); + if(mapItem){ + url = mapItem[1] + mid.substring(mapItem[3]); + }else if(pid){ + url = (pack.location.slice(-1) === '/' ? pack.location.slice(0, -1) : pack.location) + "/" + midInPackage; + }else if(has("config-tlmSiblingOfDojo")){ + url = "../" + mid; + }else{ + url = mid; + } + // if result is not absolute, add baseUrl + if(!(/(^\/)|(\:)/.test(url))){ + url = baseUrl + url; + } + url += ".js"; + return makeModuleInfo(pid, mid, pack, compactPath(url)); + }, + + getModuleInfo = function(mid, referenceModule, fromPendingCache){ + return getModuleInfo_(mid, referenceModule, packs, modules, req.baseUrl, mapProgs, pathsMapProg, aliases, undefined, fromPendingCache); + }; + + if (!has("foreign-loader")) { + var resolvePluginResourceId = function(plugin, prid, referenceModule){ + return plugin.normalize ? plugin.normalize(prid, function(mid){return toAbsMid(mid, referenceModule);}) : toAbsMid(prid, referenceModule); + }, + + dynamicPluginUidGenerator = 0, + + getModule = function(mid, referenceModule, immediate){ + // compute and optionally construct (if necessary) the module implied by the mid with respect to referenceModule + var match, plugin, prid, result; + match = mid.match(/^(.+?)\!(.*)$/); + if(match){ + // name was ! + plugin = getModule(match[1], referenceModule, immediate); + + if( 1 && legacyMode == sync && !plugin.executed){ + injectModule(plugin); + if(plugin.injected===arrived && !plugin.executed){ + guardCheckComplete(function(){ + execModule(plugin); + }); + } + if(plugin.executed){ + promoteModuleToPlugin(plugin); + }else{ + // we are in xdomain mode for some reason + execQ.unshift(plugin); + } + } + + + + if(plugin.executed === executed && !plugin.load){ + // executed the module not knowing it was a plugin + promoteModuleToPlugin(plugin); + } + + // if the plugin has not been loaded, then can't resolve the prid and must assume this plugin is dynamic until we find out otherwise + if(plugin.load){ + prid = resolvePluginResourceId(plugin, match[2], referenceModule); + mid = (plugin.mid + "!" + (plugin.dynamic ? ++dynamicPluginUidGenerator + "!" : "") + prid); + }else{ + prid = match[2]; + mid = plugin.mid + "!" + (++dynamicPluginUidGenerator) + "!waitingForPlugin"; + } + result = {plugin:plugin, mid:mid, req:createRequire(referenceModule), prid:prid}; + }else{ + result = getModuleInfo(mid, referenceModule); + } + return modules[result.mid] || (!immediate && (modules[result.mid] = result)); + }; + } + + var toAbsMid = req.toAbsMid = function(mid, referenceModule){ + return getModuleInfo(mid, referenceModule).mid; + }, + + toUrl = req.toUrl = function(name, referenceModule){ + var moduleInfo = getModuleInfo(name+"/x", referenceModule), + url= moduleInfo.url; + return fixupUrl(moduleInfo.pid===0 ? + // if pid===0, then name had a protocol or absolute path; either way, toUrl is the identify function in such cases + name : + // "/x.js" since getModuleInfo automatically appends ".js" and we appended "/x" to make name look like a module id + url.substring(0, url.length-5) + ); + }; + + if (!has("foreign-loader")) { + var nonModuleProps = { + injected: arrived, + executed: executed, + def: nonmodule, + result: nonmodule + }, + + makeCjs = function(mid){ + return modules[mid] = mix({mid:mid}, nonModuleProps); + }, + + cjsRequireModule = makeCjs("require"), + cjsExportsModule = makeCjs("exports"), + cjsModuleModule = makeCjs("module"), + + runFactory = function(module, args){ + req.trace("loader-run-factory", [module.mid]); + var factory = module.def, + result; + 1 && syncExecStack.unshift(module); + if(has("config-dojo-loader-catches")){ + try{ + result= isFunction(factory) ? factory.apply(null, args) : factory; + }catch(e){ + signal(error, module.result = makeError("factoryThrew", [module, e])); + } + }else{ + result= isFunction(factory) ? factory.apply(null, args) : factory; + } + module.result = result===undefined && module.cjs ? module.cjs.exports : result; + 1 && syncExecStack.shift(module); + }, + + abortExec = {}, + + defOrder = 0, + + promoteModuleToPlugin = function(pluginModule){ + var plugin = pluginModule.result; + pluginModule.dynamic = plugin.dynamic; + pluginModule.normalize = plugin.normalize; + pluginModule.load = plugin.load; + return pluginModule; + }, + + resolvePluginLoadQ = function(plugin){ + // plugins is a newly executed module that has a loadQ waiting to run + + // step 1: traverse the loadQ and fixup the mid and prid; remember the map from original mid to new mid + // recall the original mid was created before the plugin was on board and therefore it was impossible to + // compute the final mid; accordingly, prid may or may not change, but the mid will definitely change + var map = {}; + forEach(plugin.loadQ, function(pseudoPluginResource){ + // manufacture and insert the real module in modules + var prid = resolvePluginResourceId(plugin, pseudoPluginResource.prid, pseudoPluginResource.req.module), + mid = plugin.dynamic ? pseudoPluginResource.mid.replace(/waitingForPlugin$/, prid) : (plugin.mid + "!" + prid), + pluginResource = mix(mix({}, pseudoPluginResource), {mid:mid, prid:prid, injected:0}); + if(!modules[mid] || !modules[mid].injected /*for require.undef*/){ + // create a new (the real) plugin resource and inject it normally now that the plugin is on board + injectPlugin(modules[mid] = pluginResource); + } // else this was a duplicate request for the same (plugin, rid) for a nondynamic plugin + + // pluginResource is really just a placeholder with the wrong mid (because we couldn't calculate it until the plugin was on board) + // mark is as arrived and delete it from modules; the real module was requested above + map[pseudoPluginResource.mid] = modules[mid]; + setArrived(pseudoPluginResource); + delete modules[pseudoPluginResource.mid]; + }); + plugin.loadQ = 0; + + // step2: replace all references to any placeholder modules with real modules + var substituteModules = function(module){ + for(var replacement, deps = module.deps || [], i = 0; i")]); + return (!module.def || strict) ? abortExec : (module.cjs && module.cjs.exports); + } + // at this point the module is either not executed or fully executed + + + if(!module.executed){ + if(!module.def){ + return abortExec; + } + var mid = module.mid, + deps = module.deps || [], + arg, argResult, + args = [], + i = 0; + + if( 0 ){ + circleTrace.push(mid); + req.trace("loader-exec-module", ["exec", circleTrace.length, mid]); + } + + // for circular dependencies, assume the first module encountered was executed OK + // modules that circularly depend on a module that has not run its factory will get + // the pre-made cjs.exports===module.result. They can take a reference to this object and/or + // add properties to it. When the module finally runs its factory, the factory can + // read/write/replace this object. Notice that so long as the object isn't replaced, any + // reference taken earlier while walking the deps list is still valid. + module.executed = executing; + while((arg = deps[i++])){ + argResult = ((arg === cjsRequireModule) ? createRequire(module) : + ((arg === cjsExportsModule) ? module.cjs.exports : + ((arg === cjsModuleModule) ? module.cjs : + execModule(arg, strict)))); + if(argResult === abortExec){ + module.executed = 0; + req.trace("loader-exec-module", ["abort", mid]); + 0 && circleTrace.pop(); + return abortExec; + } + args.push(argResult); + } + runFactory(module, args); + finishExec(module); + 0 && circleTrace.pop(); + } + // at this point the module is guaranteed fully executed + + return module.result; + }, + + + checkCompleteGuard = 0, + + guardCheckComplete = function(proc){ + try{ + checkCompleteGuard++; + proc(); + }catch(e){ + // https://bugs.dojotoolkit.org/ticket/16617 + throw e; + }finally{ + checkCompleteGuard--; + } + if(execComplete()){ + signal("idle", []); + } + }, + + checkComplete = function(){ + // keep going through the execQ as long as at least one factory is executed + // plugins, recursion, cached modules all make for many execution path possibilities + if(checkCompleteGuard){ + return; + } + guardCheckComplete(function(){ + checkDojoRequirePlugin(); + for(var currentDefOrder, module, i = 0; i < execQ.length;){ + currentDefOrder = defOrder; + module = execQ[i]; + execModule(module); + if(currentDefOrder!=defOrder){ + // defOrder was bumped one or more times indicating something was executed (note, this indicates + // the execQ was modified, maybe a lot (for example a later module causes an earlier module to execute) + checkDojoRequirePlugin(); + i = 0; + }else{ + // nothing happened; check the next module in the exec queue + i++; + } + } + }); + }; + } + + var fixupUrl= typeof userConfig.fixupUrl == "function" ? userConfig.fixupUrl : function(url){ + url += ""; // make sure url is a Javascript string (some paths may be a Java string) + return url + (cacheBust ? ((/\?/.test(url) ? "&" : "?") + cacheBust) : ""); + }; + + + + if( 0 ){ + req.undef = function(moduleId, referenceModule){ + // In order to reload a module, it must be undefined (this routine) and then re-requested. + // This is useful for testing frameworks (at least). + var module = getModule(moduleId, referenceModule); + setArrived(module); + mix(module, {def:0, executed:0, injected:0, node:0, load:0}); + }; + } + + if( 1 ){ + if(has("dojo-loader-eval-hint-url")===undefined){ + has.add("dojo-loader-eval-hint-url", 1); + } + + var injectPlugin = function( + module + ){ + // injects the plugin module given by module; may have to inject the plugin itself + var plugin = module.plugin; + + if(plugin.executed === executed && !plugin.load){ + // executed the module not knowing it was a plugin + promoteModuleToPlugin(plugin); + } + + var onLoad = function(def){ + module.result = def; + setArrived(module); + finishExec(module); + checkComplete(); + }; + + if(plugin.load){ + plugin.load(module.prid, module.req, onLoad); + }else if(plugin.loadQ){ + plugin.loadQ.push(module); + }else{ + // the unshift instead of push is important: we don't want plugins to execute as + // dependencies of some other module because this may cause circles when the plugin + // loadQ is run; also, generally, we want plugins to run early since they may load + // several other modules and therefore can potentially unblock many modules + plugin.loadQ = [module]; + execQ.unshift(plugin); + injectModule(plugin); + } + }, + + // for IE, injecting a module may result in a recursive execution if the module is in the cache + + cached = 0, + + injectingModule = 0, + + injectingCachedModule = 0, + + evalModuleText = function(text, module){ + // see def() for the injectingCachedModule bracket; it simply causes a short, safe circuit + if(has("config-stripStrict")){ + text = text.replace(/(["'])use strict\1/g, ''); + } + injectingCachedModule = 1; + if(has("config-dojo-loader-catches")){ + try{ + if(text===cached){ + cached.call(null); + }else{ + req.eval(text, has("dojo-loader-eval-hint-url") ? module.url : module.mid); + } + }catch(e){ + signal(error, makeError("evalModuleThrew", module)); + } + }else{ + if(text===cached){ + cached.call(null); + }else{ + req.eval(text, has("dojo-loader-eval-hint-url") ? module.url : module.mid); + } + } + injectingCachedModule = 0; + }, + + injectModule = function(module){ + // Inject the module. In the browser environment, this means appending a script element into + // the document; in other environments, it means loading a file. + // + // If in synchronous mode, then get the module synchronously if it's not xdomainLoading. + + var mid = module.mid, + url = module.url; + if(module.executed || module.injected || waiting[mid] || (module.url && ((module.pack && waiting[module.url]===module.pack) || waiting[module.url]==1))){ + return; + } + setRequested(module); + + if( 0 ){ + var viaCombo = 0; + if(module.plugin && module.plugin.isCombo){ + // a combo plugin; therefore, must be handled by combo service + // the prid should have already been converted to a URL (if required by the plugin) during + // the normalize process; in any event, there is no way for the loader to know how to + // to the conversion; therefore the third argument is zero + req.combo.add(module.plugin.mid, module.prid, 0, req); + viaCombo = 1; + }else if(!module.plugin){ + viaCombo = req.combo.add(0, module.mid, module.url, req); + } + if(viaCombo){ + comboPending= 1; + return; + } + } + + if(module.plugin){ + injectPlugin(module); + return; + } // else a normal module (not a plugin) + + + var onLoadCallback = function(){ + runDefQ(module); + if(module.injected !== arrived){ + // the script that contained the module arrived and has been executed yet + // nothing was added to the defQ (so it wasn't an AMD module) and the module + // wasn't marked as arrived by dojo.provide (so it wasn't a v1.6- module); + // therefore, it must not have been a module; adjust state accordingly + if(has("dojo-enforceDefine")){ + signal(error, makeError("noDefine", module)); + return; + } + setArrived(module); + mix(module, nonModuleProps); + req.trace("loader-define-nonmodule", [module.url]); + } + + if( 1 && legacyMode){ + // must call checkComplete even in for sync loader because we may be in xdomainLoading mode; + // but, if xd loading, then don't call checkComplete until out of the current sync traversal + // in order to preserve order of execution of the dojo.required modules + !syncExecStack.length && checkComplete(); + }else{ + checkComplete(); + } + }; + cached = cache[mid] || cache[urlKeyPrefix + module.url]; + if(cached){ + req.trace("loader-inject", ["cache", module.mid, url]); + evalModuleText(cached, module); + onLoadCallback(); + return; + } + if( 1 && legacyMode){ + if(module.isXd){ + // switch to async mode temporarily; if current legacyMode!=sync, then is must be one of {legacyAsync, xd, false} + legacyMode==sync && (legacyMode = xd); + // fall through and load via script injection + }else if(module.isAmd && legacyMode!=sync){ + // fall through and load via script injection + }else{ + // mode may be sync, xd/legacyAsync, or async; module may be AMD or legacy; but module is always located on the same domain + var xhrCallback = function(text){ + if(legacyMode==sync){ + // the top of syncExecStack gives the current synchronously executing module; the loader needs + // to know this if it has to switch to async loading in the middle of evaluating a legacy module + // this happens when a modules dojo.require's a module that must be loaded async because it's xdomain + // (using unshift/shift because there is no back() methods for Javascript arrays) + syncExecStack.unshift(module); + evalModuleText(text, module); + syncExecStack.shift(); + + // maybe the module was an AMD module + runDefQ(module); + + // legacy modules never get to defineModule() => cjs and injected never set; also evaluation implies executing + if(!module.cjs){ + setArrived(module); + finishExec(module); + } + + if(module.finish){ + // while synchronously evaluating this module, dojo.require was applied referencing a module + // that had to be loaded async; therefore, the loader stopped answering all dojo.require + // requests so they could be answered completely in the correct sequence; module.finish gives + // the list of dojo.requires that must be re-applied once all target modules are available; + // make a synthetic module to execute the dojo.require's in the correct order + + // compute a guaranteed-unique mid for the synthetic finish module; remember the finish vector; remove it from the reference module + // TODO: can we just leave the module.finish...what's it hurting? + var finishMid = mid + "*finish", + finish = module.finish; + delete module.finish; + + def(finishMid, ["dojo", ("dojo/require!" + finish.join(",")).replace(/\./g, "/")], function(dojo){ + forEach(finish, function(mid){ dojo.require(mid); }); + }); + // unshift, not push, which causes the current traversal to be reattempted from the top + execQ.unshift(getModule(finishMid)); + } + onLoadCallback(); + }else{ + text = transformToAmd(module, text); + if(text){ + evalModuleText(text, module); + onLoadCallback(); + }else{ + // if transformToAmd returned falsy, then the module was already AMD and it can be script-injected + // do so to improve debugability(even though it means another download...which probably won't happen with a good browser cache) + injectingModule = module; + req.injectUrl(fixupUrl(url), onLoadCallback, module); + injectingModule = 0; + } + } + }; + + req.trace("loader-inject", ["xhr", module.mid, url, legacyMode!=sync]); + if(has("config-dojo-loader-catches")){ + try{ + req.getText(url, legacyMode!=sync, xhrCallback); + }catch(e){ + signal(error, makeError("xhrInjectFailed", [module, e])); + } + }else{ + req.getText(url, legacyMode!=sync, xhrCallback); + } + return; + } + } // else async mode or fell through in xdomain loading mode; either way, load by script injection + req.trace("loader-inject", ["script", module.mid, url]); + injectingModule = module; + req.injectUrl(fixupUrl(url), onLoadCallback, module); + injectingModule = 0; + }, + + defineModule = function(module, deps, def){ + req.trace("loader-define-module", [module.mid, deps]); + + if( 0 && module.plugin && module.plugin.isCombo){ + // the module is a plugin resource loaded by the combo service + // note: check for module.plugin should be enough since normal plugin resources should + // not follow this path; module.plugin.isCombo is future-proofing belt and suspenders + module.result = isFunction(def) ? def() : def; + setArrived(module); + finishExec(module); + return module; + } + + var mid = module.mid; + if(module.injected === arrived){ + signal(error, makeError("multipleDefine", module)); + return module; + } + mix(module, { + deps: deps, + def: def, + cjs: { + id: module.mid, + uri: module.url, + exports: (module.result = {}), + setExports: function(exports){ + module.cjs.exports = exports; + }, + config:function(){ + return module.config; + } + } + }); + + // resolve deps with respect to this module + for(var i = 0; deps[i]; i++){ + deps[i] = getModule(deps[i], module); + } + + if( 1 && legacyMode && !waiting[mid]){ + // the module showed up without being asked for; it was probably in a + // | + + var paths = {}; + paths[moduleName.replace(/\./g, "/")] = prefix; + require({paths:paths}); + }; + + 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 chosen 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 result = (modMap.common || []).concat(modMap[dojo._name] || modMap["default"] || []), + temp; + while(result.length){ + if(lang.isArray(temp = result.shift())){ + dojo.require.apply(dojo, temp); + }else{ + dojo.require(temp); + } + } + }; + + dojo.requireIf = dojo.requireAfterIf = function(/*Boolean*/ condition, /*String*/ moduleName, /*Boolean?*/omitModuleCheck){ + // summary: + // If the condition is true then call `dojo.require()` for the specified + // resource + // + // example: + // | dojo.requireIf(dojo.isBrowser, "my.special.Module"); + + if(condition){ + dojo.require(moduleName, omitModuleCheck); + } + }; + + dojo.requireLocalization = function(/*String*/moduleName, /*String*/bundleName, /*String?*/locale){ + require(["../i18n"], function(i18n){ + i18n.getLocalization(moduleName, bundleName, locale); + }); + }; + + return { + // summary: + // This module defines the v1.x synchronous loader API. + + extractLegacyApiApplications:extractLegacyApiApplications, + require:dojoRequirePlugin, + loadInit:dojoLoadInitPlugin + }; +}); + +}, +'dojo/_base/kernel':function(){ +define(["../global", "../has", "./config", "require", "module"], function(global, has, config, require, module){ + // module: + // dojo/_base/kernel + + // This module is the foundational module of the dojo boot sequence; it defines the dojo object. + + var + // loop variables for this module + i, p, + + // create dojo, dijit, and dojox + // FIXME: in 2.0 remove dijit, dojox being created by dojo + dijit = {}, + dojox = {}, + dojo = { + // summary: + // This module is the foundational module of the dojo boot sequence; it defines the dojo object. + + // notice dojo takes ownership of the value of the config module + config:config, + global:global, + dijit:dijit, + dojox:dojox + }; + + + // Configure the scope map. For a 100% AMD application, the scope map is not needed other than to provide + // a _scopeName property for the dojo, dijit, and dojox root object so those packages can create + // unique names in the global space. + // + // Built, legacy modules use the scope map to allow those modules to be expressed as if dojo, dijit, and dojox, + // where global when in fact they are either global under different names or not global at all. In v1.6-, the + // config variable "scopeMap" was used to map names as used within a module to global names. This has been + // subsumed by the AMD map configuration variable which can relocate packages to different names. For backcompat, + // only the "*" mapping is supported. See http://livedocs.dojotoolkit.org/developer/design/loader#legacy-cross-domain-mode for details. + // + // The following computations contort the packageMap for this dojo instance into a scopeMap. + var scopeMap = + // a map from a name used in a legacy module to the (global variable name, object addressed by that name) + // always map dojo, dijit, and dojox + { + dojo:["dojo", dojo], + dijit:["dijit", dijit], + dojox:["dojox", dojox] + }, + + packageMap = + // the package map for this dojo instance; note, a foreign loader or no pacakgeMap results in the above default config + (require.map && require.map[module.id.match(/[^\/]+/)[0]]), + + item; + + + // process all mapped top-level names for this instance of dojo + for(p in packageMap){ + if(scopeMap[p]){ + // mapped dojo, dijit, or dojox + scopeMap[p][0] = packageMap[p]; + }else{ + // some other top-level name + scopeMap[p] = [packageMap[p], {}]; + } + } + + // publish those names to _scopeName and, optionally, the global namespace + for(p in scopeMap){ + item = scopeMap[p]; + item[1]._scopeName = item[0]; + if(!config.noGlobals){ + global[item[0]] = item[1]; + } + } + dojo.scopeMap = scopeMap; + + /*===== dojo.__docParserConfigureScopeMap(scopeMap); =====*/ + + // FIXME: dojo.baseUrl and dojo.config.baseUrl should be deprecated + dojo.baseUrl = dojo.config.baseUrl = require.baseUrl; + dojo.isAsync = ! 1 || require.async; + dojo.locale = config.locale; + + var rev = "$Rev:$".match(/[0-9a-f]{7,}/); + dojo.version = { + // summary: + // Version number of the Dojo Toolkit + // description: + // Hash about the version, including + // + // - 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 Git rev from which dojo was pulled + + major: 1, minor: 17, patch: 3, flag: "", + revision: rev ? rev[0] : NaN, + toString: function(){ + var v = dojo.version; + return v.major + "." + v.minor + "." + v.patch + v.flag + " (" + v.revision + ")"; // String + } + }; + + // If 1 is truthy, then as a dojo module is defined it should push it's definitions + // into the dojo object, and conversely. In 2.0, it will likely be unusual to augment another object + // as a result of defining a module. This has feature gives a way to force 2.0 behavior as the code + // is migrated. Absent specific advice otherwise, set extend-dojo to truthy. + 1 || has.add("extend-dojo", 1); + + if(!has("csp-restrictions")){ + (Function("d", "d.eval = function(){return d.global.eval ? d.global.eval(arguments[0]) : eval(arguments[0]);}"))(dojo); + } + /*===== + dojo.eval = function(scriptText){ + // summary: + // A legacy method created for use exclusively by internal Dojo methods. Do not use this method + // directly unless you understand its possibly-different implications on the platforms your are targeting. + // description: + // Makes an attempt to evaluate scriptText in the global scope. The function works correctly for browsers + // that support indirect eval. + // + // As usual, IE does not. On IE, the only way to implement global eval is to + // use execScript. Unfortunately, execScript does not return a value and breaks some current usages of dojo.eval. + // This implementation uses the technique of executing eval in the scope of a function that is a single scope + // frame below the global scope; thereby coming close to the global scope. Note carefully that + // + // dojo.eval("var pi = 3.14;"); + // + // will define global pi in non-IE environments, but define pi only in a temporary local scope for IE. If you want + // to define a global variable using dojo.eval, write something like + // + // dojo.eval("window.pi = 3.14;") + // scriptText: + // The text to evaluation. + // returns: + // The result of the evaluation. Often `undefined` + }; + =====*/ + + + if( 0 ){ + dojo.exit = function(exitcode){ + quit(exitcode); + }; + }else{ + dojo.exit = function(){ + }; + } + + if(!has("host-webworker")){ + // console is immutable in FF30+, https://bugs.dojotoolkit.org/ticket/18100 + 1 || has.add("dojo-guarantee-console", + // ensure that console.log, console.warn, etc. are defined + 1 + ); + } + + if( 1 ){ + // IE 9 bug: https://bugs.dojotoolkit.org/ticket/18197 + has.add("console-as-object", function () { + return Function.prototype.bind && console && typeof console.log === "object"; + }); + + typeof console != "undefined" || (console = {}); // intentional assignment + // 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 tn; + i = 0; + while((tn = cn[i++])){ + if(!console[tn]){ + (function(){ + var tcn = tn + ""; + console[tcn] = ('log' in console) ? function(){ + var a = Array.prototype.slice.call(arguments); + a.unshift(tcn + ":"); + console["log"](a.join(" ")); + } : function(){}; + console[tcn]._fake = true; + })(); + }else if(has("console-as-object")){ + console[tn] = Function.prototype.bind.call(console[tn], console); + } + } + } + + has.add("dojo-debug-messages", + // include dojo.deprecated/dojo.experimental implementations + !!config.isDebug + ); + dojo.deprecated = dojo.experimental = function(){}; + if(has("dojo-debug-messages")){ + dojo.deprecated = function(/*String*/ behaviour, /*String?*/ extra, /*String?*/ 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"); + + var message = "DEPRECATED: " + behaviour; + if(extra){ message += " " + extra; } + if(removal){ message += " -- will be removed in version: " + removal; } + console.warn(message); + }; + + dojo.experimental = function(/* String */ moduleName, /* String? */ 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"); + + var message = "EXPERIMENTAL: " + moduleName + " -- APIs subject to change without notice."; + if(extra){ message += " " + extra; } + console.warn(message); + }; + } + + 1 || has.add("dojo-modulePaths", + // consume dojo.modulePaths processing + 1 + ); + if( 1 ){ + // notice that modulePaths won't be applied to any require's before the dojo/_base/kernel factory is run; + // this is the v1.6- behavior. + if(config.modulePaths){ + dojo.deprecated("dojo.modulePaths", "use paths configuration"); + var paths = {}; + for(p in config.modulePaths){ + paths[p.replace(/\./g, "/")] = config.modulePaths[p]; + } + require({paths:paths}); + } + } + + 1 || has.add("dojo-moduleUrl", + // include dojo.moduleUrl + 1 + ); + if( 1 ){ + dojo.moduleUrl = function(/*String*/module, /*String?*/url){ + // summary: + // Returns a URL 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"); + // | img.src = pngPath; + // | // 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 lengthy 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"); + + dojo.deprecated("dojo.moduleUrl()", "use require.toUrl", "2.0"); + + // require.toUrl requires a filetype; therefore, just append the suffix "/*.*" to guarantee a filetype, then + // remove the suffix from the result. This way clients can request a url w/out a filetype. This should be + // rare, but it maintains backcompat for the v1.x line (note: dojo.moduleUrl will be removed in v2.0). + // Notice * is an illegal filename so it won't conflict with any real path map that may exist the paths config. + var result = null; + if(module){ + result = require.toUrl(module.replace(/\./g, "/") + (url ? ("/" + url) : "") + "/*.*").replace(/\/\*\.\*/, "") + (url ? "" : "/"); + } + return result; + }; + } + + dojo._hasResource = {}; // for backward compatibility with layers built with 1.6 tooling + + return dojo; +}); + +}, +'dojo/global':function(){ +define(function(){ + if (typeof global !== 'undefined' && typeof global !== 'function') { + // global spec defines a reference to the global object called 'global' + // https://github.com/tc39/proposal-global + // `global` is also defined in NodeJS + return global; + } + else if (typeof window !== 'undefined') { + // window is defined in browsers + return window; + } + else if (typeof self !== 'undefined') { + // self is defined in WebWorkers + return self; + } + return this; +}); + +}, +'dojo/has':function(){ +define(["./global", "require", "module"], function(global, require, module){ + // module: + // dojo/has + // summary: + // Defines the has.js API and several feature tests used by dojo. + // description: + // This module defines the has API as described by the project has.js with the following additional features: + // + // - the has test cache is exposed at has.cache. + // - the method has.add includes a forth parameter that controls whether or not existing tests are replaced + // - the loader's has cache may be optionally copied into this module's has cahce. + // + // This module adopted from https://github.com/phiggins42/has.js; thanks has.js team! + + // try to pull the has implementation from the loader; both the dojo loader and bdLoad provide one + // if using a foreign loader, then the has cache may be initialized via the config object for this module + // WARNING: if a foreign loader defines require.has to be something other than the has.js API, then this implementation fail + var has = require.has || function(){}; + if(! 1 ){ + var + isBrowser = + // the most fundamental decision: are we in the browser? + typeof window != "undefined" && + typeof location != "undefined" && + typeof document != "undefined" && + window.location == location && window.document == document, + + // has API variables + doc = isBrowser && document, + element = doc && doc.createElement("DiV"), + cache = (module.config && module.config()) || {}; + + has = function(name){ + // summary: + // Return the current value of the named feature. + // + // name: String|Integer + // The name (if a string) or identifier (if an integer) of the feature to test. + // + // description: + // Returns the value of the feature named by name. The feature must have been + // previously added to the cache by has.add. + + return typeof cache[name] == "function" ? (cache[name] = cache[name](global, doc, element)) : cache[name]; // Boolean + }; + + has.cache = cache; + + has.add = function(name, test, now, force){ + // summary: + // Register a new feature test for some named feature. + // name: String|Integer + // The name (if a string) or identifier (if an integer) of the feature to test. + // test: Function + // A test function to register. If a function, queued for testing until actually + // needed. The test function should return a boolean indicating + // the presence of a feature or bug. + // now: Boolean? + // Optional. Omit if `test` is not a function. Provides a way to immediately + // run the test and cache the result. + // force: Boolean? + // Optional. If the test already exists and force is truthy, then the existing + // test will be replaced; otherwise, add does not replace an existing test (that + // is, by default, the first test advice wins). + // example: + // A redundant test, testFn with immediate execution: + // | has.add("javascript", function(){ return true; }, true); + // + // example: + // Again with the redundantness. You can do this in your tests, but we should + // not be doing this in any internal has.js tests + // | has.add("javascript", true); + // + // example: + // Three things are passed to the testFunction. `global`, `document`, and a generic element + // from which to work your test should the need arise. + // | has.add("bug-byid", function(g, d, el){ + // | // g == global, typically window, yadda yadda + // | // d == document object + // | // el == the generic element. a `has` element. + // | return false; // fake test, byid-when-form-has-name-matching-an-id is slightly longer + // | }); + + (typeof cache[name]=="undefined" || force) && (cache[name]= test); + return now && has(name); + }; + + // since we're operating under a loader that doesn't provide a has API, we must explicitly initialize + // has as it would have otherwise been initialized by the dojo loader; use has.add to the builder + // can optimize these away iff desired + 1 || has.add("host-browser", isBrowser); + 0 && has.add("host-node", (typeof process == "object" && process.versions && process.versions.node && process.versions.v8)); + 0 && has.add("host-rhino", (typeof load == "function" && (typeof Packages == "function" || typeof Packages == "object"))); + 1 || has.add("dom", isBrowser); + 1 || has.add("dojo-dom-ready-api", 1); + 1 || has.add("dojo-sniff", 1); + } + + if( 1 ){ + // Common application level tests + has.add("dom-addeventlistener", !!document.addEventListener); + + // Do the device and browser have touch capability? + has.add("touch", "ontouchstart" in document + || ("onpointerdown" in document && navigator.maxTouchPoints > 0) + || window.navigator.msMaxTouchPoints); + + // Touch events support + has.add("touch-events", "ontouchstart" in document); + + // Test if pointer events are supported and enabled, with either standard names ("pointerdown" etc.) or + // IE specific names ("MSPointerDown" etc.). Tests are designed to work on embedded C# WebBrowser Controls + // in addition to IE, Edge, and future versions of Firefox and Chrome. + // Note that on IE11, has("pointer-events") and has("MSPointer") are both true. + has.add("pointer-events", "pointerEnabled" in window.navigator ? + window.navigator.pointerEnabled : "PointerEvent" in window); + has.add("MSPointer", window.navigator.msPointerEnabled); + // The "pointermove"" event is only continuously emitted in a touch environment if + // the target node's "touch-action"" CSS property is set to "none" + // https://www.w3.org/TR/pointerevents/#the-touch-action-css-property + has.add("touch-action", has("touch") && has("pointer-events")); + + // I don't know if any of these tests are really correct, just a rough guess + has.add("device-width", screen.availWidth || innerWidth); + + // Tests for DOMNode.attributes[] behavior: + // - dom-attributes-explicit - attributes[] only lists explicitly user specified attributes + // - dom-attributes-specified-flag (IE8) - need to check attr.specified flag to skip attributes user didn't specify + // - Otherwise, in IE6-7. attributes[] will list hundreds of values, so need to do outerHTML to get attrs instead. + var form = document.createElement("form"); + has.add("dom-attributes-explicit", form.attributes.length == 0); // W3C + has.add("dom-attributes-specified-flag", form.attributes.length > 0 && form.attributes.length < 40); // IE8 + } + + has.clearElement = function(element){ + // summary: + // Deletes the contents of the element passed to test functions. + element.innerHTML= ""; + return element; + }; + + has.normalize = function(id, toAbsMid){ + // summary: + // Resolves id into a module id based on possibly-nested tenary expression that branches on has feature test value(s). + // + // toAbsMid: Function + // Resolves a relative module id into an absolute module id + var + tokens = id.match(/[\?:]|[^:\?]*/g), i = 0, + get = function(skip){ + var term = tokens[i++]; + if(term == ":"){ + // empty string module name, resolves to 0 + return 0; + }else{ + // postfixed with a ? means it is a feature to branch on, the term is the name of the feature + if(tokens[i++] == "?"){ + if(!skip && has(term)){ + // matched the feature, get the first value from the options + return get(); + }else{ + // did not match, get the second value, passing over the first + get(true); + return get(skip); + } + } + // a module + return term || 0; + } + }; + id = get(); + return id && toAbsMid(id); + }; + + has.load = function(id, parentRequire, loaded){ + // summary: + // Conditional loading of AMD modules based on a has feature test value. + // id: String + // Gives the resolved module id to load. + // parentRequire: Function + // The loader require function with respect to the module that contained the plugin resource in it's + // dependency list. + // loaded: Function + // Callback to loader that consumes result of plugin demand. + + if(id){ + parentRequire([id], loaded); + }else{ + loaded(); + } + }; + + return has; +}); + +}, +'dojo/_base/config':function(){ +define(["../global", "../has", "require"], function(global, has, require){ + // module: + // dojo/_base/config + +/*===== +return { + // summary: + // This module defines the user configuration during bootstrap. + // description: + // By defining user configuration as a module value, an entire configuration can be specified in a build, + // thereby eliminating the need for sniffing and or explicitly setting in the global variable dojoConfig. + // Also, when multiple instances of dojo exist in a single application, each will necessarily be located + // at an unique absolute module identifier as given by the package configuration. Implementing configuration + // as a module allows for specifying unique, per-instance configurations. + // example: + // Create a second instance of dojo with a different, instance-unique configuration (assume the loader and + // dojo.js are already loaded). + // | // specify a configuration that creates a new instance of dojo at the absolute module identifier "myDojo" + // | require({ + // | packages:[{ + // | name:"myDojo", + // | location:".", //assume baseUrl points to dojo.js + // | }] + // | }); + // | + // | // specify a configuration for the myDojo instance + // | define("myDojo/config", { + // | // normal configuration variables go here, e.g., + // | locale:"fr-ca" + // | }); + // | + // | // load and use the new instance of dojo + // | require(["myDojo"], function(dojo){ + // | // dojo is the new instance of dojo + // | // use as required + // | }); + + // isDebug: Boolean + // Defaults to `false`. If set to `true`, ensures that Dojo provides + // extended debugging feedback to the console. + isDebug: 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 `` 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: [deprecated] 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. Specifying + // `djConfig.modulePaths = { "foo": "../../bar" }` is the equivalent + // of calling `dojo.registerModulePath("foo", "../../bar");`. Multiple + // modules may be configured via `djConfig.modulePaths`. + modulePaths: {}, + + // addOnLoad: Function|Array + // Adds a callback via dojo/ready. Useful when Dojo is added after + // the page loads and djConfig.afterOnLoad is true. Supports the same + // arguments as dojo/ready. 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, + + // parseOnLoad: Boolean + // Run the parser after the page is loaded + parseOnLoad: false, + + // require: String[] + // An array of module names to be loaded immediately after dojo.js has been included + // in a page. + require: [], + + // defaultDuration: Number + // 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/topic.publish(). See dojo/main.__IoPublish for a list + // of topics that are published. + ioPublish: false, + + // 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, + + // deps: Function|Array + // Defines dependencies to be used before the loader has been loaded. + // When provided, they cause the loader to execute require(deps, callback) + // once it has finished loading. Should be used with callback. + deps: undefined, + + // callback: Function|Array + // Defines a callback to be used when dependencies are defined before + // the loader has been loaded. When provided, they cause the loader to + // execute require(deps, callback) once it has finished loading. + // Should be used with deps. + callback: undefined, + + // deferredInstrumentation: Boolean + // Whether deferred instrumentation should be loaded or included + // in builds. + deferredInstrumentation: true, + + // useDeferredInstrumentation: Boolean|String + // Whether the deferred instrumentation should be used. + // + // * `"report-rejections"`: report each rejection as it occurs. + // * `true` or `1` or `"report-unhandled-rejections"`: wait 1 second + // in an attempt to detect unhandled rejections. + useDeferredInstrumentation: "report-unhandled-rejections" +}; +=====*/ + + var result = {}; + if( 1 ){ + // must be the dojo loader; take a shallow copy of require.rawConfig + var src = require.rawConfig, p; + for(p in src){ + result[p] = src[p]; + } + }else{ + var adviseHas = function(featureSet, prefix, booting){ + for(p in featureSet){ + p!="has" && has.add(prefix + p, featureSet[p], 0, booting); + } + }; + result = 1 ? + // must be a built version of the dojo loader; all config stuffed in require.rawConfig + require.rawConfig : + // a foreign loader + global.dojoConfig || global.djConfig || {}; + adviseHas(result, "config", 1); + adviseHas(result.has, "", 1); + } + + if(!result.locale && typeof navigator != "undefined"){ + // Default locale for browsers (ensure it's read from user-settings not download locale). + var language = (navigator.languages && navigator.languages.length) ? navigator.languages[0] : + (navigator.language || navigator.userLanguage); + if(language){ + result.locale = language.toLowerCase(); + } + } + + return result; +}); + + +}, +'dojo/json':function(){ +define(["./has"], function(has){ + "use strict"; + var hasJSON = typeof JSON != "undefined"; + has.add("json-parse", hasJSON); // all the parsers work fine + // Firefox 3.5/Gecko 1.9 fails to use replacer in stringify properly https://bugzilla.mozilla.org/show_bug.cgi?id=509184 + has.add("json-stringify", hasJSON && JSON.stringify({a:0}, function(k,v){return v||1;}) == '{"a":1}'); + + /*===== + return { + // summary: + // Functions to parse and serialize JSON + + parse: function(str, strict){ + // summary: + // Parses a [JSON](http://json.org) string to return a JavaScript object. + // description: + // This function follows [native JSON API](https://developer.mozilla.org/en/JSON) + // Throws for invalid JSON strings. This delegates to eval() if native JSON + // support is not available. By default this will evaluate any valid JS expression. + // With the strict parameter set to true, the parser will ensure that only + // valid JSON strings are parsed (otherwise throwing an error). Without the strict + // parameter, the content passed to this method must come + // from a trusted source. + // str: + // a string literal of a JSON item, for instance: + // `'{ "foo": [ "bar", 1, { "baz": "thud" } ] }'` + // strict: + // When set to true, this will ensure that only valid, secure JSON is ever parsed. + // Make sure this is set to true for untrusted content. Note that on browsers/engines + // without native JSON support, setting this to true will run slower. + }, + stringify: function(value, replacer, spacer){ + // summary: + // Returns a [JSON](http://json.org) serialization of an object. + // description: + // Returns a [JSON](http://json.org) serialization of an object. + // This function follows [native JSON API](https://developer.mozilla.org/en/JSON) + // Note that this doesn't check for infinite recursion, so don't do that! + // value: + // A value to be serialized. + // replacer: + // A replacer function that is called for each value and can return a replacement + // spacer: + // A spacer string to be used for pretty printing of JSON + // example: + // simple serialization of a trivial object + // | define(["dojo/json"], function(JSON){ + // | var jsonStr = JSON.stringify({ howdy: "stranger!", isStrange: true }); + // | doh.is('{"howdy":"stranger!","isStrange":true}', jsonStr); + } + }; + =====*/ + + if(has("json-stringify")){ + return JSON; + }else{ + var 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 + }; + return { + parse: has("json-parse") ? JSON.parse : function(str, strict){ + if(strict && !/^([\s\[\{]*(?:"(?:\\.|[^"])*"|-?\d[\d\.]*(?:[Ee][+-]?\d+)?|null|true|false|)[\s\]\}]*(?:,|:|$))+$/.test(str)){ + throw new SyntaxError("Invalid characters in JSON"); + } + return eval('(' + str + ')'); + }, + stringify: function(value, replacer, spacer){ + var undef; + if(typeof replacer == "string"){ + spacer = replacer; + replacer = null; + } + function stringify(it, indent, key){ + if(replacer){ + it = replacer(key, it); + } + var val, objtype = typeof it; + if(objtype == "number"){ + return isFinite(it) ? it + "" : "null"; + } + if(objtype == "boolean"){ + return it + ""; + } + if(it === null){ + return "null"; + } + if(typeof it == "string"){ + return escapeString(it); + } + if(objtype == "function" || objtype == "undefined"){ + return undef; // undefined + } + // short-circuit for objects that support "json" serialization + // if they return "self" then just pass-through... + if(typeof it.toJSON == "function"){ + return stringify(it.toJSON(key), indent, key); + } + if(it instanceof Date){ + return '"{FullYear}-{Month+}-{Date}T{Hours}:{Minutes}:{Seconds}Z"'.replace(/\{(\w+)(\+)?\}/g, function(t, prop, plus){ + var num = it["getUTC" + prop]() + (plus ? 1 : 0); + return num < 10 ? "0" + num : num; + }); + } + if(it.valueOf() !== it){ + // primitive wrapper, try again unwrapped: + return stringify(it.valueOf(), indent, key); + } + var nextIndent= spacer ? (indent + spacer) : ""; + /* we used to test for DOM nodes and throw, but FF serializes them as {}, so cross-browser consistency is probably not efficiently attainable */ + + var sep = spacer ? " " : ""; + var newLine = spacer ? "\n" : ""; + + // array + if(it instanceof Array){ + var itl = it.length, res = []; + for(key = 0; key < itl; key++){ + var obj = it[key]; + val = stringify(obj, nextIndent, key); + if(typeof val != "string"){ + val = "null"; + } + res.push(newLine + nextIndent + val); + } + return "[" + res.join(",") + newLine + indent + "]"; + } + // generic object code path + var output = []; + for(key in it){ + var keyStr; + if(it.hasOwnProperty(key)){ + if(typeof key == "number"){ + keyStr = '"' + key + '"'; + }else if(typeof key == "string"){ + keyStr = escapeString(key); + }else{ + // skip non-string or number keys + continue; + } + val = stringify(it[key], nextIndent, key); + if(typeof val != "string"){ + // skip non-serializable values + continue; + } + // At this point, the most non-IE browsers don't get in this branch + // (they have native JSON), so push is definitely the way to + output.push(newLine + nextIndent + keyStr + ":" + sep + val); + } + } + return "{" + output.join(",") + newLine + indent + "}"; // String + } + return stringify(value, "", ""); + } + }; + } +}); + +}, +'dojo/_base/lang':function(){ +define(["./kernel", "../has", "../sniff"], function(dojo, has){ + // module: + // dojo/_base/lang + + has.add("bug-for-in-skips-shadowed", function(){ + // if true, the for-in iterator skips object properties that exist in Object's prototype (IE 6 - ?) + for(var i in {toString: 1}){ + return 0; + } + return 1; + }); + + // Helper methods + var _extraNames = + has("bug-for-in-skips-shadowed") ? + "hasOwnProperty.valueOf.isPrototypeOf.propertyIsEnumerable.toLocaleString.toString.constructor".split(".") : [], + + _extraLen = _extraNames.length, + + getProp = function(/*Array*/parts, /*Boolean*/create, /*Object*/context){ + if(!context){ + if(parts[0] && dojo.scopeMap[parts[0]]) { + // Voodoo code from the old days where "dojo" or "dijit" maps to some special object + // rather than just window.dojo + context = dojo.scopeMap[parts.shift()][1]; + }else{ + context = dojo.global; + } + } + + try{ + for(var i = 0; i < parts.length; i++){ + var p = parts[i]; + // Fix for prototype pollution CVE-2021-23450 + if (p === '__proto__' || p === 'constructor') { + return; + } + if(!(p in context)){ + if(create){ + context[p] = {}; + }else{ + return; // return undefined + } + } + context = context[p]; + } + return context; // mixed + }catch(e){ + // "p in context" throws an exception when context is a number, boolean, etc. rather than an object, + // so in that corner case just return undefined (by having no return statement) + } + }, + + opts = Object.prototype.toString, + + efficient = function(obj, offset, startWith){ + return (startWith||[]).concat(Array.prototype.slice.call(obj, offset||0)); + }, + + _pattern = /\{([^\}]+)\}/g; + + // Module export + var lang = { + // summary: + // This module defines Javascript language extensions. + + // _extraNames: String[] + // Lists property names that must be explicitly processed during for-in iteration + // in environments that have has("bug-for-in-skips-shadowed") true. + _extraNames:_extraNames, + + _mixin: function(dest, source, copyFunc){ + // summary: + // Copies/adds all properties of source to dest; returns dest. + // dest: Object + // The object to which to copy/add all properties contained in source. + // source: Object + // The object from which to draw all properties to copy into dest. + // copyFunc: Function? + // The process used to copy/add a property in source; defaults to the Javascript assignment operator. + // returns: + // dest, as modified + // description: + // All properties, including functions (sometimes termed "methods"), excluding any non-standard extensions + // found in Object.prototype, are copied/added to dest. Copying/adding each particular property is + // delegated to copyFunc (if any); copyFunc defaults to the Javascript assignment operator if not provided. + // Notice that by default, _mixin executes a so-called "shallow copy" and aggregate types are copied/added by reference. + var name, s, i, empty = {}; + for(name in source){ + // the (!(name in empty) || empty[name] !== s) condition avoids copying properties in "source" + // inherited from Object.prototype. For example, if dest 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 dest) || (dest[name] !== s && (!(name in empty) || empty[name] !== s))){ + dest[name] = copyFunc ? copyFunc(s) : s; + } + } + + if(has("bug-for-in-skips-shadowed")){ + if(source){ + for(i = 0; i < _extraLen; ++i){ + name = _extraNames[i]; + s = source[name]; + if(!(name in dest) || (dest[name] !== s && (!(name in empty) || empty[name] !== s))){ + dest[name] = copyFunc ? copyFunc(s) : s; + } + } + } + } + + return dest; // Object + }, + + mixin: function(dest, sources){ + // summary: + // Copies/adds all properties of one or more sources to dest; returns dest. + // dest: Object + // The object to which to copy/add all properties contained in source. If dest is falsy, then + // a new object is manufactured before copying/adding properties begins. + // sources: Object... + // One of more objects from which to draw all properties to copy into dest. sources are processed + // left-to-right and if more than one of these objects contain the same property name, the right-most + // value "wins". + // returns: Object + // dest, as modified + // description: + // All properties, including functions (sometimes termed "methods"), excluding any non-standard extensions + // found in Object.prototype, are copied/added from sources to dest. sources are processed left to right. + // The Javascript assignment operator is used to copy/add each property; therefore, by default, mixin + // executes a so-called "shallow copy" and aggregate types are copied/added by reference. + // example: + // make a shallow copy of an object + // | var copy = lang.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 `lang.mixin` on the `this` object: + // | declare("acme.Base", null, { + // | constructor: function(properties){ + // | // property configuration: + // | lang.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 = lang.mixin( + // | { + // | name: "Frylock", + // | braces: true + // | }, + // | { + // | name: "Carl Brutanananadilewski" + // | } + // | ); + // | + // | // will print "Carl Brutanananadilewski" + // | console.log(flattened.name); + // | // will print "true" + // | console.log(flattened.braces); + + if(!dest){ dest = {}; } + for(var i = 1, l = arguments.length; i < l; i++){ + lang._mixin(dest, arguments[i]); + } + return dest; // Object + }, + + setObject: function(name, value, 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: String + // Path to a property, in the form "A.B.C". + // value: anything + // value or object to place at location given by name + // context: Object? + // 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: + // | lang.setObject("foo.bar.baz", value); + // example: + // without `lang.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"; + // whereas with `lang.setObject`, we can shorten that to: + // | lang.setObject("parent.child.prop", "some value", obj); + + var parts = name.split("."), p = parts.pop(), obj = getProp(parts, true, context); + return obj && p ? (obj[p] = value) : undefined; // Object + }, + + getObject: function(name, create, 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: String + // Path to an property, in the form "A.B.C". + // create: Boolean? + // Optional. Defaults to `false`. If `true`, Objects will be + // created at any point along the 'path' that is undefined. + // context: Object? + // Optional. Object to use as root of path. Defaults to + // 'dojo.global'. Null may be passed. + return !name ? context : getProp(name.split("."), create, context); // Object + }, + + exists: function(name, 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: String + // Path to an object, in the form "A.B.C". + // obj: Object? + // 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 + // | lang.exists("foo.bar"); // true + // | lang.exists("foo.bar.baz"); // false + // | + // | // search from a particular scope + // | lang.exists("bar", foo); // true + // | lang.exists("bar.baz", foo); // false + return lang.getObject(name, false, obj) !== undefined; // Boolean + }, + + // Crockford (ish) functions + + isString: function(it){ + // summary: + // Return true if it is a String + // it: anything + // Item to test. + return (typeof it == "string" || it instanceof String); // Boolean + }, + + isArray: Array.isArray || function(it){ + // summary: + // Return true if it is an Array. + // it: anything + // Item to test. + return opts.call(it) == "[object Array]"; // Boolean + }, + + isFunction: function(it){ + // summary: + // Return true if it is a Function + // it: anything + // Item to test. + return opts.call(it) === "[object Function]"; + }, + + isObject: function(it){ + // summary: + // Returns true if it is a JavaScript object (or an Array, a Function + // or null) + // it: anything + // Item to test. + return it !== undefined && + (it === null || typeof it == "object" || lang.isArray(it) || lang.isFunction(it)); // Boolean + }, + + isArrayLike: function(it){ + // summary: + // similar to isArray() but more permissive + // it: anything + // Item to test. + // returns: + // If it walks like a duck and quacks like a duck, return `true` + // 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 + // isArrayLike(), but will return false when passed to + // isArray(). + return !!it && // Boolean + // keep out built-in constructors (Number, String, ...) which have length + // properties + !lang.isString(it) && !lang.isFunction(it) && + !(it.tagName && it.tagName.toLowerCase() == 'form') && + (lang.isArray(it) || isFinite(it.length)); + }, + + isAlien: function(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 && !lang.isFunction(it) && /\{\s*\[native code\]\s*\}/.test(String(it)); // Boolean + }, + + extend: function(ctor, props){ + // summary: + // Adds all properties and methods of props to constructor's + // prototype, making them available to all instances created with + // constructor. + // ctor: Object + // Target constructor to extend. + // props: Object + // One or more objects to mix into ctor.prototype + for(var i=1, l=arguments.length; i 2){ + return lang._hitchArgs.apply(dojo, arguments); // Function + } + if(!method){ + method = scope; + scope = null; + } + if(lang.isString(method)){ + scope = scope || dojo.global; + if(!scope[method]){ throw(['lang.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 + }, + + 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){ + lang._mixin(tmp, props); + } + return tmp; // Object + }; + })(), + /*===== + 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 implementation 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: Object + // The object to delegate to for properties not found directly on the + // return object or in props. + // props: Object... + // an object containing properties to assign to the returned object + // returns: + // an Object of anonymous type + // example: + // | var foo = { bar: "baz" }; + // | var thinger = lang.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 + }, + =====*/ + + _toArray: has("ie") ? + (function(){ + function slow(obj, offset, startWith){ + var arr = startWith||[]; + for(var x = offset || 0; x < obj.length; x++){ + arr.push(obj[x]); + } + return arr; + } + return function(obj){ + return ((obj.item) ? slow : efficient).apply(this, arguments); + }; + })() : efficient, + /*===== + _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. + }, + =====*/ + + 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 lang.partial is the functional equivalent of calling: + // | lang.hitch(null, funcName, ...); + // method: + // The function to "wrap" + var arr = [ null ]; + return lang.hitch.apply(dojo, arr.concat(lang._toArray(arguments))); // Function + }, + + clone: function(/*anything*/ src){ + // summary: + // Clones objects (including DOM nodes) and all children. + // Warning: do not clone cyclic structures. + // src: + // The object to clone + if(!src || typeof src != "object" || lang.isFunction(src)){ + // null, undefined, any non-object, or function + return src; // anything + } + if(src.nodeType && "cloneNode" in src){ + // DOM Node + return src.cloneNode(true); // Node + } + if(src instanceof Date){ + // Date + return new Date(src.getTime()); // Date + } + if(src instanceof RegExp){ + // RegExp + return new RegExp(src); // RegExp + } + var r, i, l; + if(lang.isArray(src)){ + // array + r = []; + for(i = 0, l = src.length; i < l; ++i){ + if(i in src){ + r[i] = lang.clone(src[i]); + } + } + // we don't clone functions for performance reasons + // }else if(d.isFunction(src)){ + // // function + // r = function(){ return src.apply(this, arguments); }; + }else{ + // generic objects + r = src.constructor ? new src.constructor() : {}; + } + return lang._mixin(r, src, lang.clone); + }, + + + trim: String.prototype.trim ? + function(str){ return str.trim(); } : + function(str){ return str.replace(/^\s\s*/, '').replace(/\s\s*$/, ''); }, + /*===== + 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 + // lang.string.trim() + }, + =====*/ + + 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: + // | lang.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: + // | lang.replace("Hello, {0} {2}!", + // | ["Robert", "X", "Cringely"]); + // | // returns: Hello, Robert Cringely! + // example: + // | // uses a function for substitutions: + // | function sum(a){ + // | var t = 0; + // | arrayforEach(a, function(x){ t += x; }); + // | return t; + // | } + // | lang.replace( + // | "{count} payments averaging {avg} USD per payment.", + // | lang.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: + // | lang.replace("Hello, ${0} ${2}!", + // | ["Robert", "X", "Cringely"], /\$\{([^\}]+)\}/g); + // | // returns: Hello, Robert Cringely! + + return tmpl.replace(pattern || _pattern, lang.isFunction(map) ? + map : function(_, k){ return lang.getObject(k, false, map); }); + } + }; + + 1 && lang.mixin(dojo, lang); + + return lang; +}); + +}, +'dojo/sniff':function(){ +define(["./has"], function(has){ + // module: + // dojo/sniff + + /*===== + return function(){ + // summary: + // This module sets has() flags based on the current browser. + // It returns the has() function. + }; + =====*/ + + if( 1 ){ + var n = navigator, + dua = n.userAgent, + dav = n.appVersion, + tv = parseFloat(dav); + has.add("air", dua.indexOf("AdobeAIR") >= 0); + has.add("wp", parseFloat(dua.split("Windows Phone")[1]) || undefined); + has.add("msapp", parseFloat(dua.split("MSAppHost/")[1]) || undefined); + has.add("khtml", dav.indexOf("Konqueror") >= 0 ? tv : undefined); + has.add("edge", parseFloat(dua.split("Edge/")[1]) || undefined); + has.add("opr", parseFloat(dua.split("OPR/")[1]) || undefined); + // NOTE: https://dev.opera.com/blog/opera-user-agent-strings-opera-15-and-beyond/ + has.add("webkit", !has("wp") // NOTE: necessary since Windows Phone 8.1 Update 1, see #18540 + && !has("edge") && parseFloat(dua.split("WebKit/")[1]) || undefined); + has.add("chrome", !has("edge") && !has("opr") + && parseFloat(dua.split("Chrome/")[1]) || undefined); + has.add("android", !has("wp") // NOTE: necessary since Windows Phone 8.1 Update 1, see #18528 + && parseFloat(dua.split("Android ")[1]) || undefined); + has.add("safari", dav.indexOf("Safari") >= 0 + && !has("wp") // NOTE: necessary since Windows Phone 8.1 Update 1, see #18540 + && !has("chrome") && !has("android") && !has("edge") && !has("opr") ? + parseFloat(dav.split("Version/")[1]) : undefined); + has.add("mac", dav.indexOf("Macintosh") >= 0); + has.add("quirks", document.compatMode == "BackCompat"); + if(!has("wp") // NOTE: necessary since Windows Phone 8.1 Update 1, see #18528 + && dua.match(/(iPhone|iPod|iPad)/)){ + var p = RegExp.$1.replace(/P/, "p"); + var v = dua.match(/OS ([\d_]+)/) ? RegExp.$1 : "1"; + var os = parseFloat(v.replace(/_/, ".").replace(/_/g, "")); + has.add(p, os); // "iphone", "ipad" or "ipod" + has.add("ios", os); + } + has.add("bb", (dua.indexOf("BlackBerry") >= 0 || dua.indexOf("BB10") >= 0) && parseFloat(dua.split("Version/")[1]) || undefined); + has.add("trident", parseFloat(dav.split("Trident/")[1]) || undefined); + + has.add("svg", typeof SVGAngle !== "undefined"); + + if(!has("webkit")){ + // Opera + if(dua.indexOf("Opera") >= 0){ + // see http://dev.opera.com/articles/view/opera-ua-string-changes and http://www.useragentstring.com/pages/Opera/ + // 9.8 has both styles; <9.8, 9.9 only old style + has.add("opera", tv >= 9.8 ? parseFloat(dua.split("Version/")[1]) || tv : tv); + } + + // Mozilla and firefox + if(dua.indexOf("Gecko") >= 0 && !has("wp") // NOTE: necessary since Windows Phone 8.1 Update 1 + && !has("khtml") && !has("trident") && !has("edge")){ + has.add("mozilla", tv); + } + if(has("mozilla")){ + //We really need to get away from this. Consider a sane isGecko approach for the future. + has.add("ff", parseFloat(dua.split("Firefox/")[1] || dua.split("Minefield/")[1]) || undefined); + } + + // IE + if(document.all && !has("opera")){ + var 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(isIE) != mode){ + isIE = mode; + } + + has.add("ie", isIE); + } + + // Wii + has.add("wii", typeof opera != "undefined" && opera.wiiremote); + } + } + + return has; +}); + +}, +'dojo/_base/array':function(){ +define(["./kernel", "../has", "./lang"], function(dojo, has, lang){ + // module: + // dojo/_base/array + + // our old simple function builder stuff + var cache = {}, u; + + var buildFn; + if(!has("csp-restrictions")){ + buildFn = function (fn){ + return cache[fn] = new Function("item", "index", "array", fn); // Function + }; + } + + // magic snippet: if(typeof fn == "string") fn = cache[fn] || buildFn(fn); + + // every & some + + function everyOrSome(some){ + var every = !some; + return function(a, fn, o){ + var i = 0, l = a && a.length || 0, result; + if(l && typeof a == "string") a = a.split(""); + if(typeof fn == "string"){ + if(has("csp-restrictions")){ + throw new TypeError("callback must be a function"); + } + else{ + fn = cache[fn] || buildFn(fn); + } + } + if(o){ + for(; i < l; ++i){ + result = !fn.call(o, a[i], i, a); + if(some ^ result){ + return !result; + } + } + }else{ + for(; i < l; ++i){ + result = !fn(a[i], i, a); + if(some ^ result){ + return !result; + } + } + } + return every; // Boolean + }; + } + + // indexOf, lastIndexOf + + function index(up){ + var delta = 1, lOver = 0, uOver = 0; + if(!up){ + delta = lOver = uOver = -1; + } + return function(a, x, from, last){ + if(last && delta > 0){ + // TODO: why do we use a non-standard signature? why do we need "last"? + return array.lastIndexOf(a, x, from); + } + var l = a && a.length || 0, end = up ? l + uOver : lOver, i; + if(from === u){ + i = up ? lOver : l + uOver; + }else{ + if(from < 0){ + i = l + from; + if(i < 0){ + i = lOver; + } + }else{ + i = from >= l ? l + uOver : from; + } + } + if(l && typeof a == "string") a = a.split(""); + for(; i != end; i += delta){ + if(a[i] == x){ + return i; // Number + } + } + return -1; // Number + }; + } + + var array = { + // summary: + // The Javascript v1.6 array extensions. + + every: everyOrSome(false), + /*===== + every: function(arr, callback, thisObject){ + // summary: + // Determines whether or not every item in arr satisfies the + // condition implemented by callback. + // arr: Array|String + // the array to iterate on. If a string, operates on individual characters. + // callback: Function|String + // a function is invoked with three arguments: item, index, + // and array and returns true if the condition is met. + // thisObject: Object? + // may be used to scope the call to callback + // returns: Boolean + // description: + // This function corresponds to the JavaScript 1.6 Array.every() method, with one difference: when + // run over sparse arrays, this implementation 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 + // | array.every([1, 2, 3, 4], function(item){ return item>1; }); + // example: + // | // returns true + // | array.every([1, 2, 3, 4], function(item){ return item>0; }); + }, + =====*/ + + some: everyOrSome(true), + /*===== + some: function(arr, callback, thisObject){ + // summary: + // Determines whether or not any item in arr satisfies the + // condition implemented by callback. + // arr: Array|String + // the array to iterate over. If a string, operates on individual characters. + // callback: Function|String + // a function is invoked with three arguments: item, index, + // and array and returns true if the condition is met. + // thisObject: Object? + // may be used to scope the call to callback + // returns: Boolean + // description: + // This function corresponds to the JavaScript 1.6 Array.some() method, with one difference: when + // run over sparse arrays, this implementation 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 + // | array.some([1, 2, 3, 4], function(item){ return item>1; }); + // example: + // | // is false + // | array.some([1, 2, 3, 4], function(item){ return item<1; }); + }, + =====*/ + + indexOf: index(true), + /*===== + indexOf: function(arr, value, fromIndex, 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 two differences: + // + // 1. 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. + // 2. uses equality (==) rather than strict equality (===) + // + // For details on this method, see: + // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/indexOf + // arr: Array + // value: Object + // fromIndex: Integer? + // findLast: Boolean? + // Makes indexOf() work like lastIndexOf(). Used internally; not meant for external usage. + // returns: Number + }, + =====*/ + + lastIndexOf: index(false), + /*===== + lastIndexOf: function(arr, value, 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 two differences: + // + // 1. when run over sparse arrays, the Dojo function invokes the callback for every index + // whereas JavaScript 1.6's lasIndexOf skips the holes in the sparse array. + // 2. uses equality (==) rather than strict equality (===) + // + // For details on this method, see: + // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/lastIndexOf + // arr: Array, + // value: Object, + // fromIndex: Integer? + // returns: Number + }, + =====*/ + + forEach: function(arr, callback, 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 array.every() or array.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 implementation 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: + // | array.forEach( + // | [ "thinger", "blah", "howdy", 10 ], + // | function(item){ + // | console.log(item); + // | } + // | ); + // example: + // | // log out the members and their indexes + // | array.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 + // | array.forEach( + // | [ "thinger", "blah", "howdy", 10 ], + // | obj.callback, + // | obj + // | ); + // | + // | // alternately, we can accomplish the same thing with lang.hitch() + // | array.forEach( + // | [ "thinger", "blah", "howdy", 10 ], + // | lang.hitch(obj, "callback") + // | ); + // arr: Array|String + // callback: Function|String + // thisObject: Object? + + var i = 0, l = arr && arr.length || 0; + if(l && typeof arr == "string") arr = arr.split(""); + if(typeof callback == "string"){ + if(has("csp-restrictions")){ + throw new TypeError("callback must be a function"); + } + else{ + callback = cache[callback] || buildFn(callback); + } + } + if(thisObject){ + for(; i < l; ++i){ + callback.call(thisObject, arr[i], i, arr); + } + }else{ + for(; i < l; ++i){ + callback(arr[i], i, arr); + } + } + }, + + map: function(arr, callback, thisObject, Ctr){ + // summary: + // applies callback to each element of arr and returns + // an Array with the results + // arr: Array|String + // the array to iterate on. If a string, operates on + // individual characters. + // callback: Function|String + // a function is invoked with three arguments, (item, index, + // array), and returns a value + // thisObject: Object? + // may be used to scope the call to callback + // returns: Array + // description: + // This function corresponds to the JavaScript 1.6 Array.map() method, with one difference: when + // run over sparse arrays, this implementation 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] + // | array.map([1, 2, 3, 4], function(item){ return item+1 }); + + // TODO: why do we have a non-standard signature here? do we need "Ctr"? + var i = 0, l = arr && arr.length || 0, out = new (Ctr || Array)(l); + if(l && typeof arr == "string") arr = arr.split(""); + if(typeof callback == "string"){ + if(has("csp-restrictions")){ + throw new TypeError("callback must be a function"); + } + else{ + callback = cache[callback] || buildFn(callback); + } + } + if(thisObject){ + for(; i < l; ++i){ + out[i] = callback.call(thisObject, arr[i], i, arr); + } + }else{ + for(; i < l; ++i){ + out[i] = callback(arr[i], i, arr); + } + } + return out; // Array + }, + + filter: function(arr, callback, thisObject){ + // summary: + // Returns a new Array with those items from arr that match the + // condition implemented by callback. + // arr: Array + // the array to iterate over. + // callback: Function|String + // 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: Object? + // may be used to scope the call to callback + // returns: Array + // description: + // This function corresponds to the JavaScript 1.6 Array.filter() method, with one difference: when + // run over sparse arrays, this implementation 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] + // | array.filter([1, 2, 3, 4], function(item){ return item>1; }); + + // TODO: do we need "Ctr" here like in map()? + var i = 0, l = arr && arr.length || 0, out = [], value; + if(l && typeof arr == "string") arr = arr.split(""); + if(typeof callback == "string"){ + if(has("csp-restrictions")){ + throw new TypeError("callback must be a function"); + } + else{ + callback = cache[callback] || buildFn(callback); + } + } + if(thisObject){ + for(; i < l; ++i){ + value = arr[i]; + if(callback.call(thisObject, value, i, arr)){ + out.push(value); + } + } + }else{ + for(; i < l; ++i){ + value = arr[i]; + if(callback(value, i, arr)){ + out.push(value); + } + } + } + return out; // Array + }, + + clearCache: function(){ + cache = {}; + } + }; + + + 1 && lang.mixin(dojo, array); + + return array; +}); + +}, +'dojo/text':function(){ +define(["./_base/kernel", "require", "./has", "./request"], function(dojo, require, has, request){ + // module: + // dojo/text + + var getText; + if( 1 ){ + getText= function(url, sync, load){ + request(url, {sync:!!sync, headers: { 'X-Requested-With': null } }).then(load); + }; + }else{ + // Path for node.js and rhino, to load from local file system. + // TODO: use node.js native methods rather than depending on a require.getText() method to exist. + if(require.getText){ + getText= require.getText; + }else{ + console.error("dojo/text plugin failed to load because loader does not support getText"); + } + } + + var + theCache = {}, + + strip= function(text){ + //Strips declarations so that external SVG and XML + //documents can be added to a document without worry. Also, if the string + //is an HTML document, only the part inside the body tag is returned. + if(text){ + text= text.replace(/^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im, ""); + var matches= text.match(/]*>\s*([\s\S]+)\s*<\/body>/im); + if(matches){ + text= matches[1]; + } + }else{ + text = ""; + } + return text; + }, + + notFound = {}, + + pending = {}; + + dojo.cache = function(/*String||Object*/module, /*String*/url, /*String||Object?*/value){ + // summary: + // A getter and setter for storing the string content associated with the + // module and url arguments. + // description: + // If module is a string that contains slashes, then it is interpretted as a fully + // resolved path (typically a result returned by require.toUrl), and url should not be + // provided. This is the preferred signature. If module is a string that does not + // contain slashes, then url must also be provided and module and url are used to + // call `dojo.moduleUrl()` to generate a module URL. This signature is deprecated. + // If value is specified, the cache value for the moduleUrl will be set to + // that value. Otherwise, dojo.cache will fetch the moduleUrl and store it + // in its internal cache and return that cached value for the URL. To clear + // a cache value pass null for value. Since XMLHttpRequest (XHR) is used to fetch the + // the URL contents, only modules on the same domain of the page can use this capability. + // The build system can inline the cache values though, to allow for xdomain hosting. + // module: String||Object + // If a String with slashes, a fully resolved path; if a String without slashes, the + // module name to use for the base part of the URL, similar to module argument + // to `dojo.moduleUrl`. If an Object, something that has a .toString() method that + // generates a valid path for the cache item. For example, a dojo._Url object. + // url: String + // The rest of the path to append to the path derived from the module argument. If + // module is an object, then this second argument should be the "value" argument instead. + // value: String||Object? + // If a String, the value to use in the cache for the module/url combination. + // If an Object, it can have two properties: value and sanitize. The value property + // should be the value to use in the cache, and sanitize can be set to true or false, + // to indicate if XML declarations should be removed from the value and if the HTML + // inside a body tag in the value should be extracted as the real value. The value argument + // or the value property on the value argument are usually only used by the build system + // as it inlines cache content. + // example: + // To ask dojo.cache to fetch content and store it in the cache (the dojo["cache"] style + // of call is used to avoid an issue with the build system erroneously trying to intern + // this example. To get the build system to intern your dojo.cache calls, use the + // "dojo.cache" style of call): + // | //If template.html contains "

Hello

" that will be + // | //the value for the text variable. + // | //Note: This is pre-AMD, deprecated syntax + // | var text = dojo["cache"]("my.module", "template.html"); + // example: + // To ask dojo.cache to fetch content and store it in the cache, and sanitize the input + // (the dojo["cache"] style of call is used to avoid an issue with the build system + // erroneously trying to intern this example. To get the build system to intern your + // dojo.cache calls, use the "dojo.cache" style of call): + // | //If template.html contains "

Hello

", the + // | //text variable will contain just "

Hello

". + // | //Note: This is pre-AMD, deprecated syntax + // | var text = dojo["cache"]("my.module", "template.html", {sanitize: true}); + // example: + // Same example as previous, but demonstrates how an object can be passed in as + // the first argument, then the value argument can then be the second argument. + // | //If template.html contains "

Hello

", the + // | //text variable will contain just "

Hello

". + // | //Note: This is pre-AMD, deprecated syntax + // | var text = dojo["cache"](new dojo._Url("my/module/template.html"), {sanitize: true}); + + // * (string string [value]) => (module, url, value) + // * (object [value]) => (module, value), url defaults to "" + // + // * if module is an object, then it must be convertable to a string + // * (module, url) module + (url ? ("/" + url) : "") must be a legal argument to require.toUrl + // * value may be a string or an object; if an object then may have the properties "value" and/or "sanitize" + var key; + if(typeof module=="string"){ + if(/\//.test(module)){ + // module is a version 1.7+ resolved path + key = module; + value = url; + }else{ + // module is a version 1.6- argument to dojo.moduleUrl + key = require.toUrl(module.replace(/\./g, "/") + (url ? ("/" + url) : "")); + } + }else{ + key = module + ""; + value = url; + } + var + val = (value != undefined && typeof value != "string") ? value.value : value, + sanitize = value && value.sanitize; + + if(typeof val == "string"){ + //We have a string, set cache value + theCache[key] = val; + return sanitize ? strip(val) : val; + }else if(val === null){ + //Remove cached value + delete theCache[key]; + return null; + }else{ + //Allow cache values to be empty strings. If key property does + //not exist, fetch it. + if(!(key in theCache)){ + getText(key, true, function(text){ + theCache[key]= text; + }); + } + return sanitize ? strip(theCache[key]) : theCache[key]; + } + }; + + return { + // summary: + // This module implements the dojo/text! plugin and the dojo.cache API. + // description: + // We choose to include our own plugin to leverage functionality already contained in dojo + // and thereby reduce the size of the plugin compared to various foreign loader implementations. + // Also, this allows foreign AMD loaders to be used without their plugins. + // + // CAUTION: this module is designed to optionally function synchronously to support the dojo v1.x synchronous + // loader. This feature is outside the scope of the CommonJS plugins specification. + + // the dojo/text caches it's own resources because of dojo.cache + dynamic: true, + + normalize: function(id, toAbsMid){ + // id is something like (path may be relative): + // + // "path/to/text.html" + // "path/to/text.html!strip" + var parts= id.split("!"), + url= parts[0]; + return (/^\./.test(url) ? toAbsMid(url) : url) + (parts[1] ? "!" + parts[1] : ""); + }, + + load: function(id, require, load){ + // id: String + // Path to the resource. + // require: Function + // Object that include the function toUrl with given id returns a valid URL from which to load the text. + // load: Function + // Callback function which will be called, when the loading finished. + + // id is something like (path is always absolute): + // + // "path/to/text.html" + // "path/to/text.html!strip" + var + parts= id.split("!"), + stripFlag= parts.length>1, + absMid= parts[0], + url = require.toUrl(parts[0]), + requireCacheUrl = "url:" + url, + text = notFound, + finish = function(text){ + load(stripFlag ? strip(text) : text); + }; + if(absMid in theCache){ + text = theCache[absMid]; + }else if(require.cache && requireCacheUrl in require.cache){ + text = require.cache[requireCacheUrl]; + }else if(url in theCache){ + text = theCache[url]; + } + if(text===notFound){ + if(pending[url]){ + pending[url].push(finish); + }else{ + var pendingList = pending[url] = [finish]; + getText(url, !require.async, function(text){ + theCache[absMid]= theCache[url]= text; + for(var i = 0; i/nls/*` and + // therefore never looks like a relative + return /^\./.test(id) ? toAbsMid(id) : id; + }, + + getLocalesToLoad = function(targetLocale){ + var list = config.extraLocale || []; + list = lang.isArray(list) ? list : [list]; + list.push(targetLocale); + return list; + }, + + load = function(id, require, load){ + // summary: + // id is in one of the following formats + // + // 1. /nls/ + // => load the bundle, localized to config.locale; load all bundles localized to + // config.extraLocale (if any); return the loaded bundle localized to config.locale. + // + // 2. /nls// + // => load then return the bundle localized to + // + // 3. *preload*/nls/* + // => for config.locale and all config.extraLocale, load all bundles found + // in the best-matching bundle rollup. A value of 1 is returned, which + // is meaningless other than to say the plugin is executing the requested + // preloads + // + // In cases 1 and 2, is always normalized to an absolute module id upon entry; see + // normalize. In case 3, it is assumed to be absolute; this is arranged by the builder. + // + // To load a bundle means to insert the bundle into the plugin's cache and publish the bundle + // value to the loader. Given , , and a particular , the cache key + // + // /nls// + // + // will hold the value. Similarly, then plugin will publish this value to the loader by + // + // define("/nls//", ); + // + // Given this algorithm, other machinery can provide fast load paths be preplacing + // values in the plugin's cache, which is public. When a load is demanded the + // cache is inspected before starting any loading. Explicitly placing values in the plugin + // cache is an advanced/experimental feature that should not be needed; use at your own risk. + // + // For the normal AMD algorithm, the root bundle is loaded first, which instructs the + // plugin what additional localized bundles are required for a particular locale. These + // additional locales are loaded and a mix of the root and each progressively-specific + // locale is returned. For example: + // + // 1. The client demands "dojo/i18n!some/path/nls/someBundle + // + // 2. The loader demands load(some/path/nls/someBundle) + // + // 3. This plugin require's "some/path/nls/someBundle", which is the root bundle. + // + // 4. Assuming config.locale is "ab-cd-ef" and the root bundle indicates that localizations + // are available for "ab" and "ab-cd-ef" (note the missing "ab-cd", then the plugin + // requires "some/path/nls/ab/someBundle" and "some/path/nls/ab-cd-ef/someBundle" + // + // 5. Upon receiving all required bundles, the plugin constructs the value of the bundle + // ab-cd-ef as... + // + // mixin(mixin(mixin({}, require("some/path/nls/someBundle"), + // require("some/path/nls/ab/someBundle")), + // require("some/path/nls/ab-cd-ef/someBundle")); + // + // This value is inserted into the cache and published to the loader at the + // key/module-id some/path/nls/someBundle/ab-cd-ef. + // + // The special preload signature (case 3) instructs the plugin to stop servicing all normal requests + // (further preload requests will be serviced) until all ongoing preloading has completed. + // + // The preload signature instructs the plugin that a special rollup module is available that contains + // one or more flattened, localized bundles. The JSON array of available locales indicates which locales + // are available. Here is an example: + // + // *preload*some/path/nls/someModule*["root", "ab", "ab-cd-ef"] + // + // This indicates the following rollup modules are available: + // + // some/path/nls/someModule_ROOT + // some/path/nls/someModule_ab + // some/path/nls/someModule_ab-cd-ef + // + // Each of these modules is a normal AMD module that contains one or more flattened bundles in a hash. + // For example, assume someModule contained the bundles some/bundle/path/someBundle and + // some/bundle/path/someOtherBundle, then some/path/nls/someModule_ab would be expressed as follows: + // + // define({ + // some/bundle/path/someBundle:, + // some/bundle/path/someOtherBundle:, + // }); + // + // E.g., given this design, preloading for locale=="ab" can execute the following algorithm: + // + // require(["some/path/nls/someModule_ab"], function(rollup){ + // for(var p in rollup){ + // var id = p + "/ab", + // cache[id] = rollup[p]; + // define(id, rollup[p]); + // } + // }); + // + // Similarly, if "ab-cd" is requested, the algorithm can determine that "ab" is the best available and + // load accordingly. + // + // The builder will write such rollups for every layer if a non-empty localeList profile property is + // provided. Further, the builder will include the following cache entry in the cache associated with + // any layer. + // + // "*now":function(r){r(['dojo/i18n!*preload*/nls/*']);} + // + // The *now special cache module instructs the loader to apply the provided function to context-require + // with respect to the particular layer being defined. This causes the plugin to hold all normal service + // requests until all preloading is complete. + // + // Notice that this algorithm is rarely better than the standard AMD load algorithm. Consider the normal case + // where the target locale has a single segment and a layer depends on a single bundle: + // + // Without Preloads: + // + // 1. Layer loads root bundle. + // 2. bundle is demanded; plugin loads single localized bundle. + // + // With Preloads: + // + // 1. Layer causes preloading of target bundle. + // 2. bundle is demanded; service is delayed until preloading complete; bundle is returned. + // + // In each case a single transaction is required to load the target bundle. In cases where multiple bundles + // are required and/or the locale has multiple segments, preloads still requires a single transaction whereas + // the normal path requires an additional transaction for each additional bundle/locale-segment. However all + // of these additional transactions can be done concurrently. Owing to this analysis, the entire preloading + // algorithm can be discard during a build by setting the has feature dojo-preload-i18n-Api to false. + + var match = nlsRe.exec(id), + bundlePath = match[1] + "/", + bundleName = match[5] || match[4], + bundlePathAndName = bundlePath + bundleName, + localeSpecified = (match[5] && match[4]), + targetLocale = localeSpecified || dojo.locale || "", + loadTarget = bundlePathAndName + "/" + targetLocale, + loadList = localeSpecified ? [targetLocale] : getLocalesToLoad(targetLocale), + remaining = loadList.length, + finish = function(){ + if(!--remaining){ + load(lang.delegate(cache[loadTarget])); + } + }, + split = id.split("*"), + preloadDemand = split[1] == "preload"; + + if(has("dojo-preload-i18n-Api")){ + if(preloadDemand){ + if(!cache[id]){ + // use cache[id] to prevent multiple preloads of the same preload; this shouldn't happen, but + // who knows what over-aggressive human optimizers may attempt + cache[id] = 1; + preloadL10n(split[2], json.parse(split[3]), 1, require); + } + // don't stall the loader! + load(1); + } + if(preloadDemand || (waitForPreloads(id, require, load) && !cache[loadTarget])){ + return; + } + } + else if (preloadDemand) { + // If a build is created with nls resources and 'dojo-preload-i18n-Api' has not been set to false, + // the built file will include a preload in the cache (which looks about like so:) + // '*now':function(r){r(['dojo/i18n!*preload*dojo/nls/dojo*["ar","ca","cs","da","de","el","en-gb","en-us","es-es","fi-fi","fr-fr","he-il","hu","it-it","ja-jp","ko-kr","nl-nl","nb","pl","pt-br","pt-pt","ru","sk","sl","sv","th","tr","zh-tw","zh-cn","ROOT"]']);} + // If the consumer of the build sets 'dojo-preload-i18n-Api' to false in the Dojo config, the cached + // preload will not be parsed and will result in an attempt to call 'require' passing it the unparsed + // preload, which is not a valid module id. + // In this case we should skip this request. + load(1); + + return; + } + + array.forEach(loadList, function(locale){ + var target = bundlePathAndName + "/" + locale; + if(has("dojo-preload-i18n-Api")){ + checkForLegacyModules(target); + } + if(!cache[target]){ + doLoad(require, bundlePathAndName, bundlePath, bundleName, locale, finish); + }else{ + finish(); + } + }); + }; + + if(has("dojo-preload-i18n-Api") || 1 ){ + var normalizeLocale = thisModule.normalizeLocale = function(locale){ + var result = locale ? locale.toLowerCase() : dojo.locale; + return result == "root" ? "ROOT" : result; + }, + + isXd = function(mid, contextRequire){ + return ( 1 && 1 ) ? + contextRequire.isXdUrl(require.toUrl(mid + ".js")) : + true; + }, + + preloading = 0, + + preloadWaitQueue = [], + + preloadL10n = thisModule._preloadLocalizations = function(/*String*/bundlePrefix, /*Array*/localesGenerated, /*boolean?*/ guaranteedAmdFormat, /*function?*/ contextRequire){ + // summary: + // Load available flattened resource bundles associated with a particular module for dojo/locale and all dojo/config.extraLocale (if any) + // description: + // Only called by built layer files. The entire locale hierarchy is loaded. For example, + // if locale=="ab-cd", then ROOT, "ab", and "ab-cd" are loaded. This is different than v1.6- + // in that the v1.6- would only load ab-cd...which was *always* flattened. + // + // If guaranteedAmdFormat is true, then the module can be loaded with require thereby circumventing the detection algorithm + // and the extra possible extra transaction. + + // If this function is called from legacy code, then guaranteedAmdFormat and contextRequire will be undefined. Since the function + // needs a require in order to resolve module ids, fall back to the context-require associated with this dojo/i18n module, which + // itself may have been mapped. + contextRequire = contextRequire || require; + + function doRequire(mid, callback){ + if(isXd(mid, contextRequire) || guaranteedAmdFormat){ + contextRequire([mid], callback); + }else{ + syncRequire([mid], callback, contextRequire); + } + } + + function forEachLocale(locale, func){ + // given locale= "ab-cd-ef", calls func on "ab-cd-ef", "ab-cd", "ab", "ROOT"; stops calling the first time func returns truthy + var parts = locale.split("-"); + while(parts.length){ + if(func(parts.join("-"))){ + return; + } + parts.pop(); + } + func("ROOT"); + } + + function preloadingAddLock(){ + preloading++; + } + + function preloadingRelLock(){ + --preloading; + while(!preloading && preloadWaitQueue.length){ + load.apply(null, preloadWaitQueue.shift()); + } + } + + function cacheId(path, name, loc, require){ + // path is assumed to have a trailing "/" + return require.toAbsMid(path + name + "/" + loc) + } + + function preload(locale){ + locale = normalizeLocale(locale); + forEachLocale(locale, function(loc){ + if(array.indexOf(localesGenerated, loc) >= 0){ + var mid = bundlePrefix.replace(/\./g, "/") + "_" + loc; + preloadingAddLock(); + doRequire(mid, function(rollup){ + for(var p in rollup){ + var bundle = rollup[p], + match = p.match(/(.+)\/([^\/]+)$/), + bundleName, bundlePath; + + // If there is no match, the bundle is not a regular bundle from an AMD layer. + if (!match){continue;} + + bundleName = match[2]; + bundlePath = match[1] + "/"; + + // backcompat + if(!bundle._localized){continue;} + + var localized; + if(loc === "ROOT"){ + var root = localized = bundle._localized; + delete bundle._localized; + root.root = bundle; + cache[require.toAbsMid(p)] = root; + }else{ + localized = bundle._localized; + cache[cacheId(bundlePath, bundleName, loc, require)] = bundle; + } + + if(loc !== locale){ + // capture some locale variables + var improveBundle = function improveBundle(bundlePath, bundleName, bundle, localized){ + // locale was not flattened and we've fallen back to a less-specific locale that was flattened + // for example, we had a flattened 'fr', a 'fr-ca' is available for at least this bundle, and + // locale==='fr-ca'; therefore, we must improve the bundle as retrieved from the rollup by + // manually loading the fr-ca version of the bundle and mixing this into the already-retrieved 'fr' + // version of the bundle. + // + // Remember, different bundles may have different sets of locales available. + // + // we are really falling back on the regular algorithm here, but--hopefully--starting with most + // of the required bundles already on board as given by the rollup and we need to "manually" load + // only one locale from a few bundles...or even better...we won't find anything better to load. + // This algorithm ensures there is nothing better to load even when we can only load a less-specific rollup. + // + // note: this feature is only available in async mode + + // inspect the loaded bundle that came from the rollup to see if something better is available + // for any bundle in a rollup, more-specific available locales are given at localized. + var requiredBundles = [], + cacheIds = []; + forEachLocale(locale, function(loc){ + if(localized[loc]){ + requiredBundles.push(require.toAbsMid(bundlePath + loc + "/" + bundleName)); + cacheIds.push(cacheId(bundlePath, bundleName, loc, require)); + } + }); + + if(requiredBundles.length){ + preloadingAddLock(); + contextRequire(requiredBundles, function(){ + // requiredBundles was constructed by forEachLocale so it contains locales from + // less specific to most specific. + // the loop starts with the most specific locale, the last one. + for(var i = requiredBundles.length - 1; i >= 0 ; i--){ + bundle = lang.mixin(lang.clone(bundle), arguments[i]); + cache[cacheIds[i]] = bundle; + } + // this is the best possible (maybe a perfect match, maybe not), accept it + cache[cacheId(bundlePath, bundleName, locale, require)] = lang.clone(bundle); + preloadingRelLock(); + }); + }else{ + // this is the best possible (definitely not a perfect match), accept it + cache[cacheId(bundlePath, bundleName, locale, require)] = bundle; + } + }; + improveBundle(bundlePath, bundleName, bundle, localized); + } + } + preloadingRelLock(); + }); + return true; + } + return false; + }); + } + + preload(); + array.forEach(dojo.config.extraLocale, preload); + }, + + waitForPreloads = function(id, require, load){ + if(preloading){ + preloadWaitQueue.push([id, require, load]); + } + return preloading; + }, + + checkForLegacyModules = function() + {}; + } + + if( 1 ){ + // this code path assumes the dojo loader and won't work with a standard AMD loader + var amdValue = {}, + l10nCache = {}, + evalBundle, + + syncRequire = function(deps, callback, require){ + var results = []; + array.forEach(deps, function(mid){ + var url = require.toUrl(mid + ".js"); + + function load(text){ + if (!evalBundle) { + // use the function ctor to keep the minifiers away (also come close to global scope, but this is secondary) + evalBundle = new Function( + "__bundle", // the bundle to evalutate + "__checkForLegacyModules", // a function that checks if __bundle defined __mid in the global space + "__mid", // the mid that __bundle is intended to define + "__amdValue", + + // returns one of: + // 1 => the bundle was an AMD bundle + // a legacy bundle object that is the value of __mid + // instance of Error => could not figure out how to evaluate bundle + + // used to detect when __bundle calls define + "var define = function(mid, factory){define.called = 1; __amdValue.result = factory || mid;}," + + " require = function(){define.called = 1;};" + + + "try{" + + "define.called = 0;" + + "eval(__bundle);" + + "if(define.called==1)" + // bundle called define; therefore signal it's an AMD bundle + + "return __amdValue;" + + + "if((__checkForLegacyModules = __checkForLegacyModules(__mid)))" + // bundle was probably a v1.6- built NLS flattened NLS bundle that defined __mid in the global space + + "return __checkForLegacyModules;" + + + "}catch(e){}" + // evaulating the bundle was *neither* an AMD *nor* a legacy flattened bundle + // either way, re-eval *after* surrounding with parentheses + + + "try{" + + "return eval('('+__bundle+')');" + + "}catch(e){" + + "return e;" + + "}" + ); + } + var result = evalBundle(text, checkForLegacyModules, mid, amdValue); + if(result===amdValue){ + // the bundle was an AMD module; re-inject it through the normal AMD path + // we gotta do this since it could be an anonymous module and simply evaluating + // the text here won't provide the loader with the context to know what + // module is being defined()'d. With browser caching, this should be free; further + // this entire code path can be circumvented by using the AMD format to begin with + results.push(cache[url] = amdValue.result); + }else{ + if(result instanceof Error){ + console.error("failed to evaluate i18n bundle; url=" + url, result); + result = {}; + } + // nls// indicates not the root. + results.push(cache[url] = (/nls\/[^\/]+\/[^\/]+$/.test(url) ? result : {root:result, _v1x:1})); + } + } + + if(cache[url]){ + results.push(cache[url]); + }else{ + var bundle = require.syncLoadNls(mid); + // need to check for legacy module here because there might be a legacy module for a + // less specific locale (which was not looked up during the first checkForLegacyModules + // call in load()). + // Also need to reverse the locale and the module name in the mid because syncRequire + // deps parameters uses the AMD style package/nls/locale/module while legacy code uses + // package/nls/module/locale. + if(!bundle){ + bundle = checkForLegacyModules(mid.replace(/nls\/([^\/]*)\/([^\/]*)$/, "nls/$2/$1")); + } + if(bundle){ + results.push(bundle); + }else{ + if(!xhr){ + try{ + require.getText(url, true, load); + }catch(e){ + results.push(cache[url] = {}); + } + }else{ + xhr.get({ + url:url, + sync:true, + load:load, + error:function(){ + results.push(cache[url] = {}); + } + }); + } + } + } + }); + callback && callback.apply(null, results); + }; + + checkForLegacyModules = function(target){ + // legacy code may have already loaded [e.g] the raw bundle x/y/z at x.y.z; when true, push into the cache + for(var result, names = target.split("/"), object = dojo.global[names[0]], i = 1; object && i 2 && !hasBody) || "POST|PUT".indexOf(method.toUpperCase()) === -1){ + //Check for hasBody being passed. If no hasBody, + //then only append query string if not a POST or PUT request. + dojo._ioAddQueryToUrl(ioArgs); + } + + var options = { + method: method, + handleAs: "text", + timeout: args.timeout, + withCredentials: args.withCredentials, + ioArgs: ioArgs + }; + + if(typeof args.headers !== 'undefined'){ + options.headers = args.headers; + } + if(typeof args.contentType !== 'undefined'){ + if(!options.headers){ + options.headers = {}; + } + options.headers['Content-Type'] = args.contentType; + } + if(typeof ioArgs.query !== 'undefined'){ + options.data = ioArgs.query; + } + if(typeof args.sync !== 'undefined'){ + options.sync = args.sync; + } + + dojo._ioNotifyStart(dfd); + try{ + rDfd = _xhr(ioArgs.url, options, true); + }catch(e){ + // If XHR creation fails, dojo/request/xhr throws + // When this happens, cancel the deferred + dfd.cancel(); + return dfd; + } + + // sync ioArgs + dfd.ioArgs.xhr = rDfd.response.xhr; + + rDfd.then(function(){ + dfd.resolve(dfd); + }).otherwise(function(error){ + ioArgs.error = error; + if(error.response){ + error.status = error.response.status; + error.responseText = error.response.text; + error.xhr = error.response.xhr; + } + dfd.reject(error); + }); + return dfd; // dojo/_base/Deferred + }; + + dojo.xhrGet = function(/*dojo.__XhrArgs*/ args){ + // summary: + // Sends an HTTP GET request to the server. + return dojo.xhr("GET", args); // dojo/_base/Deferred + }; + + dojo.rawXhrPost = dojo.xhrPost = function(/*dojo.__XhrArgs*/ args){ + // summary: + // Sends an HTTP POST request to the server. In addition to the properties + // listed for the dojo.__XhrArgs type, the following property is allowed: + // postData: + // String. Send raw data in the body of the POST request. + return dojo.xhr("POST", args, true); // dojo/_base/Deferred + }; + + dojo.rawXhrPut = dojo.xhrPut = function(/*dojo.__XhrArgs*/ args){ + // summary: + // Sends an HTTP PUT request to the server. In addition to the properties + // listed for the dojo.__XhrArgs type, the following property is allowed: + // putData: + // String. Send raw data in the body of the PUT request. + return dojo.xhr("PUT", args, true); // dojo/_base/Deferred + }; + + dojo.xhrDelete = function(/*dojo.__XhrArgs*/ args){ + // summary: + // Sends an HTTP DELETE request to the server. + return dojo.xhr("DELETE", args); // dojo/_base/Deferred + }; + + /* + dojo.wrapForm = function(formNode){ + // summary: + // A replacement for FormBind, but not implemented yet. + + // FIXME: need to think harder about what extensions to this we might + // want. What should we allow folks to do w/ this? What events to + // set/send? + throw new Error("dojo.wrapForm not yet implemented"); + } + */ + + dojo._isDocumentOk = function(x){ + return util.checkStatus(x.status); + }; + + dojo._getText = function(url){ + var result; + dojo.xhrGet({url:url, sync:true, load:function(text){ + result = text; + }}); + return result; + }; + + // Add aliases for static functions to dojo.xhr since dojo.xhr is what's returned from this module + lang.mixin(dojo.xhr, { + _xhrObj: dojo._xhrObj, + fieldToObject: domForm.fieldToObject, + formToObject: domForm.toObject, + objectToQuery: ioq.objectToQuery, + formToQuery: domForm.toQuery, + formToJson: domForm.toJson, + queryToObject: ioq.queryToObject, + contentHandlers: handlers, + _ioSetArgs: dojo._ioSetArgs, + _ioCancelAll: dojo._ioCancelAll, + _ioNotifyStart: dojo._ioNotifyStart, + _ioWatch: dojo._ioWatch, + _ioAddQueryToUrl: dojo._ioAddQueryToUrl, + _isDocumentOk: dojo._isDocumentOk, + _getText: dojo._getText, + get: dojo.xhrGet, + post: dojo.xhrPost, + put: dojo.xhrPut, + del: dojo.xhrDelete // because "delete" is a reserved word + }); + + return dojo.xhr; +}); + +}, +'dojo/_base/sniff':function(){ +define(["./kernel", "./lang", "../sniff"], function(dojo, lang, has){ + // module: + // dojo/_base/sniff + + /*===== + return { + // summary: + // Deprecated. New code should use dojo/sniff. + // This module populates the dojo browser version sniffing properties like dojo.isIE. + }; + =====*/ + + if(! 1 ){ + return has; + } + + // no idea what this is for, or if it's used + dojo._name = "browser"; + + lang.mixin(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: has("ff"), + + // 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: has("ie"), + + // isKhtml: Number|undefined + // Version as a Number if client is a KHTML browser. undefined otherwise. Corresponds to major + // detected version. + isKhtml: has("khtml"), + + // isWebKit: Number|undefined + // Version as a Number if client is a WebKit-derived browser (Konqueror, + // Safari, Chrome, etc.). undefined otherwise. + isWebKit: has("webkit"), + + // isMozilla: Number|undefined + // Version as a Number if client is a Mozilla-based browser (Firefox, + // SeaMonkey). undefined otherwise. Corresponds to major detected version. + isMozilla: has("mozilla"), + // isMoz: Number|undefined + // Version as a Number if client is a Mozilla-based browser (Firefox, + // SeaMonkey). undefined otherwise. Corresponds to major detected version. + isMoz: has("mozilla"), + + // isOpera: Number|undefined + // Version as a Number if client is Opera. undefined otherwise. Corresponds to + // major detected version. + isOpera: has("opera"), + + // isSafari: Number|undefined + // Version as a Number if client is Safari or iPhone. undefined otherwise. + isSafari: has("safari"), + + // isChrome: Number|undefined + // Version as a Number if client is Chrome browser. undefined otherwise. + isChrome: has("chrome"), + + // isMac: Boolean + // True if the client runs on Mac + isMac: has("mac"), + + // isIos: Number|undefined + // Version as a Number if client is iPhone, iPod, or iPad. undefined otherwise. + isIos: has("ios"), + + // isAndroid: Number|undefined + // Version as a Number if client is android browser. undefined otherwise. + isAndroid: has("android"), + + // isWii: Boolean + // True if client is Wii + isWii: has("wii"), + + // isQuirks: Boolean + // Page is in quirks mode. + isQuirks: has("quirks"), + + // isAir: Boolean + // True if client is Adobe Air + isAir: has("air") + }); + + return has; +}); + +}, +'dojo/io-query':function(){ +define(["./_base/lang"], function(lang){ + + // module: + // dojo/io-query + + var backstop = {}; + + return { + // summary: + // This module defines query string processing functions. + + objectToQuery: function objectToQuery(/*Object*/ map){ + // summary: + // takes a name/value mapping object and returns a string representing + // a URL-encoded version of that object. + // example: + // this object: + // + // | { + // | blah: "blah", + // | multi: [ + // | "thud", + // | "thonk" + // | ] + // | }; + // + // yields the following query string: + // + // | "blah=blah&multi=thud&multi=thonk" + + // FIXME: need to implement encodeAscii!! + var enc = encodeURIComponent, pairs = []; + for(var name in map){ + var value = map[name]; + if(value != backstop[name]){ + var assign = enc(name) + "="; + if(lang.isArray(value)){ + for(var i = 0, l = value.length; i < l; ++i){ + pairs.push(assign + enc(value[i])); + } + }else{ + pairs.push(assign + enc(value)); + } + } + } + return pairs.join("&"); // String + }, + + queryToObject: function queryToObject(/*String*/ str){ + // summary: + // Create an object representing a de-serialized query section of a + // URL. Query keys with multiple values are returned in an array. + // + // example: + // This string: + // + // | "foo=bar&foo=baz&thinger=%20spaces%20=blah&zonk=blarg&" + // + // results in this object structure: + // + // | { + // | foo: [ "bar", "baz" ], + // | thinger: " spaces =blah", + // | zonk: "blarg" + // | } + // + // Note that spaces and other urlencoded entities are correctly + // handled. + + var dec = decodeURIComponent, qp = str.split("&"), ret = {}, name, val; + for(var i = 0, l = qp.length, item; i < l; ++i){ + item = qp[i]; + if(item.length){ + var s = item.indexOf("="); + if(s < 0){ + name = dec(item); + val = ""; + }else{ + name = dec(item.slice(0, s)); + val = dec(item.slice(s + 1)); + } + if(typeof ret[name] == "string"){ // inline'd type check + ret[name] = [ret[name]]; + } + + if(lang.isArray(ret[name])){ + ret[name].push(val); + }else{ + ret[name] = val; + } + } + } + return ret; // Object + } + }; +}); +}, +'dojo/dom':function(){ +define(["./sniff", "./_base/window", "./_base/kernel"], + function(has, win, kernel){ + // module: + // dojo/dom + + // FIXME: need to add unit tests for all the semi-public methods + + if(has("ie") <= 7){ + try{ + document.execCommand("BackgroundImageCache", false, true); + }catch(e){ + // sane browsers don't have cache "issues" + } + } + + // ============================= + // DOM Functions + // ============================= + + // the result object + var dom = { + // summary: + // This module defines the core dojo DOM API. + }; + + if(has("ie")){ + dom.byId = function(id, doc){ + if(typeof id != "string"){ + return id || null; + } + var _d = doc || win.doc, te = id && _d.getElementById(id); + // attributes.id.value is better than just id in case the + // user has a name=id inside a form + if(te && (te.attributes.id.value == id || te.id == id)){ + return te; + }else{ + var eles = _d.all[id]; + if(!eles || eles.nodeName){ + eles = [eles]; + } + // if more than 1, choose first with the correct id + var i = 0; + while((te = eles[i++])){ + if((te.attributes && te.attributes.id && te.attributes.id.value == id) || te.id == id){ + return te; + } + } + } + return null; + }; + }else{ + dom.byId = function(id, doc){ + // inline'd type check. + // be sure to return null per documentation, to match IE branch. + return ((typeof id == "string") ? (doc || win.doc).getElementById(id) : id) || null; // DOMNode + }; + } + /*===== + dom.byId = function(id, doc){ + // summary: + // Returns DOM node with matching `id` attribute or falsy value (ex: null or undefined) + // if not found. If `id` is a DomNode, this function is a no-op. + // + // id: String|DOMNode + // A string to match an HTML id attribute or a reference to a DOM Node + // + // doc: Document? + // Document to work in. Defaults to the current value of + // dojo/_base/window.doc. Can be used to retrieve + // node references from other documents. + // + // example: + // Look up a node by ID: + // | require(["dojo/dom"], function(dom){ + // | var n = dom.byId("foo"); + // | }); + // + // example: + // Check if a node exists, and use it. + // | require(["dojo/dom"], function(dom){ + // | var n = dom.byId("bar"); + // | if(n){ doStuff() ... } + // | }); + // + // example: + // Allow string or DomNode references to be passed to a custom function: + // | require(["dojo/dom"], function(dom){ + // | var foo = function(nodeOrId){ + // | nodeOrId = dom.byId(nodeOrId); + // | // ... more stuff + // | } + // | }); + }; + =====*/ + + // Test for DOMNode.contains() method, available everywhere except FF8- + // and IE8-, where it's available in general, but not on document itself, + // and also problems when either ancestor or node are text nodes. + + var doc = kernel.global["document"] || null; + has.add("dom-contains", !!(doc && doc.contains)); + dom.isDescendant = has("dom-contains") ? + // FF9+, IE9+, webkit, opera, iOS, Android, Edge, etc. + function(/*DOMNode|String*/ node, /*DOMNode|String*/ ancestor){ + return !!( (ancestor = dom.byId(ancestor)) && ancestor.contains(dom.byId(node)) ); + } : + function(/*DOMNode|String*/ node, /*DOMNode|String*/ ancestor){ + // summary: + // Returns true if node is a descendant of ancestor + // node: DOMNode|String + // string id or node reference to test + // ancestor: DOMNode|String + // string id or node reference of potential parent to test against + // + // example: + // Test is node id="bar" is a descendant of node id="foo" + // | require(["dojo/dom"], function(dom){ + // | if(dom.isDescendant("bar", "foo")){ ... } + // | }); + + try{ + node = dom.byId(node); + ancestor = dom.byId(ancestor); + while(node){ + if(node == ancestor){ + return true; // Boolean + } + node = node.parentNode; + } + }catch(e){ /* squelch, return false */ } + return false; // Boolean + }; + + // TODO: do we need setSelectable in the base? + + // Add feature test for user-select CSS property + // (currently known to work in all but IE < 10 and Opera) + // TODO: The user-select CSS property as of May 2014 is no longer part of + // any CSS specification. In IE, -ms-user-select does not do the same thing + // as the unselectable attribute on elements; namely, dijit Editor buttons + // do not properly prevent the content of the editable content frame from + // unblurring. As a result, the -ms- prefixed version is omitted here. + has.add("css-user-select", function(global, doc, element){ + // Avoid exception when dom.js is loaded in non-browser environments + if(!element){ return false; } + + var style = element.style; + var prefixes = ["Khtml", "O", "Moz", "Webkit"], + i = prefixes.length, + name = "userSelect", + prefix; + + // Iterate prefixes from most to least likely + do{ + if(typeof style[name] !== "undefined"){ + // Supported; return property name + return name; + } + }while(i-- && (name = prefixes[i] + "UserSelect")); + + // Not supported if we didn't return before now + return false; + }); + + /*===== + dom.setSelectable = function(node, selectable){ + // summary: + // Enable or disable selection on a node + // node: DOMNode|String + // id or reference to node + // selectable: Boolean + // state to put the node in. false indicates unselectable, true + // allows selection. + // example: + // Make the node id="bar" unselectable + // | require(["dojo/dom"], function(dom){ + // | dom.setSelectable("bar"); + // | }); + // example: + // Make the node id="bar" selectable + // | require(["dojo/dom"], function(dom){ + // | dom.setSelectable("bar", true); + // | }); + }; + =====*/ + + var cssUserSelect = has("css-user-select"); + dom.setSelectable = cssUserSelect ? function(node, selectable){ + // css-user-select returns a (possibly vendor-prefixed) CSS property name + dom.byId(node).style[cssUserSelect] = selectable ? "" : "none"; + } : function(node, selectable){ + node = dom.byId(node); + + // (IE < 10 / Opera) Fall back to setting/removing the + // unselectable attribute on the element and all its children + var nodes = node.getElementsByTagName("*"), + i = nodes.length; + + if(selectable){ + node.removeAttribute("unselectable"); + while(i--){ + nodes[i].removeAttribute("unselectable"); + } + }else{ + node.setAttribute("unselectable", "on"); + while(i--){ + nodes[i].setAttribute("unselectable", "on"); + } + } + }; + + return dom; +}); + +}, +'dojo/_base/window':function(){ +define(["./kernel", "./lang", "../sniff"], function(dojo, lang, has){ +// module: +// dojo/_base/window + +var ret = { + // summary: + // API to save/set/restore the global/document scope. + + global: dojo.global, + /*===== + global: { + // summary: + // Alias for the current window. 'global' can be modified + // for temporary context shifting. See also withGlobal(). + // description: + // Use this rather than referring to 'window' to ensure your code runs + // correctly in managed contexts. + }, + =====*/ + + doc: dojo.global["document"] || null, + /*===== + doc: { + // summary: + // Alias for the current document. 'doc' can be modified + // for temporary context shifting. See also withDoc(). + // description: + // Use this rather than referring to 'window.document' to ensure your code runs + // correctly in managed contexts. + // example: + // | n.appendChild(dojo.doc.createElement('div')); + }, + =====*/ + + body: function(/*Document?*/ doc){ + // summary: + // Return the body element of the specified document or of dojo/_base/window::doc. + // example: + // | win.body().appendChild(dojo.doc.createElement('div')); + + // Note: document.body is not defined for a strict xhtml document + // Would like to memoize this, but dojo.doc can change vi dojo.withDoc(). + doc = doc || dojo.doc; + return doc.body || doc.getElementsByTagName("body")[0]; // Node + }, + + setContext: function(/*Object*/ globalObject, /*DocumentElement*/ globalDocument){ + // summary: + // changes the behavior of many core Dojo functions that deal with + // namespace and DOM lookup, changing them to work in a new global + // context (e.g., an iframe). The varibles dojo.global and dojo.doc + // are modified as a result of calling this function and the result of + // `dojo.body()` likewise differs. + dojo.global = ret.global = globalObject; + dojo.doc = ret.doc = globalDocument; + }, + + withGlobal: function( /*Object*/ globalObject, + /*Function*/ callback, + /*Object?*/ thisObject, + /*Array?*/ cbArguments){ + // summary: + // Invoke callback with globalObject as dojo.global and + // globalObject.document as dojo.doc. + // description: + // Invoke callback with globalObject as dojo.global and + // globalObject.document as dojo.doc. If provided, globalObject + // will be executed in the context of object thisObject + // When callback() returns or throws an error, the dojo.global + // and dojo.doc will be restored to its previous state. + + var oldGlob = dojo.global; + try{ + dojo.global = ret.global = globalObject; + return ret.withDoc.call(null, globalObject.document, callback, thisObject, cbArguments); + }finally{ + dojo.global = ret.global = oldGlob; + } + }, + + withDoc: function( /*DocumentElement*/ documentObject, + /*Function*/ callback, + /*Object?*/ thisObject, + /*Array?*/ cbArguments){ + // summary: + // Invoke callback with documentObject as dojo/_base/window::doc. + // description: + // Invoke callback with documentObject as dojo/_base/window::doc. If provided, + // callback will be executed in the context of object thisObject + // When callback() returns or throws an error, the dojo/_base/window::doc will + // be restored to its previous state. + + var oldDoc = ret.doc, + oldQ = has("quirks"), + oldIE = has("ie"), isIE, mode, pwin; + + try{ + dojo.doc = ret.doc = documentObject; + // update dojo.isQuirks and the value of the has feature "quirks". + // remove setting dojo.isQuirks and dojo.isIE for 2.0 + dojo.isQuirks = has.add("quirks", dojo.doc.compatMode == "BackCompat", true, true); // no need to check for QuirksMode which was Opera 7 only + + if(has("ie")){ + if((pwin = documentObject.parentWindow) && pwin.navigator){ + // re-run IE detection logic and update dojo.isIE / has("ie") + // (the only time parentWindow/navigator wouldn't exist is if we were not + // passed an actual legitimate document object) + isIE = parseFloat(pwin.navigator.appVersion.split("MSIE ")[1]) || undefined; + mode = documentObject.documentMode; + if(mode && mode != 5 && Math.floor(isIE) != mode){ + isIE = mode; + } + dojo.isIE = has.add("ie", isIE, true, true); + } + } + + if(thisObject && typeof callback == "string"){ + callback = thisObject[callback]; + } + + return callback.apply(thisObject, cbArguments || []); + }finally{ + dojo.doc = ret.doc = oldDoc; + dojo.isQuirks = has.add("quirks", oldQ, true, true); + dojo.isIE = has.add("ie", oldIE, true, true); + } + } +}; + + 1 && lang.mixin(dojo, ret); + +return ret; + +}); + +}, +'dojo/dom-form':function(){ +define(["./_base/lang", "./dom", "./io-query", "./json"], function(lang, dom, ioq, json){ + // module: + // dojo/dom-form + + function setValue(/*Object*/ obj, /*String*/ name, /*String*/ value){ + // summary: + // For the named property in object, set the value. If a value + // already exists and it is a string, convert the value to be an + // array of values. + + // Skip it if there is no value + if(value === null){ + return; + } + + var val = obj[name]; + if(typeof val == "string"){ // inline'd type check + obj[name] = [val, value]; + }else if(lang.isArray(val)){ + val.push(value); + }else{ + obj[name] = value; + } + } + + var exclude = "file|submit|image|reset|button"; + + var form = { + // summary: + // This module defines form-processing functions. + + fieldToObject: function fieldToObject(/*DOMNode|String*/ inputNode){ + // summary: + // Serialize a form field to a JavaScript object. + // description: + // Returns the value encoded in a form field as + // as a string or an array of strings. Disabled form elements + // and unchecked radio and checkboxes are skipped. Multi-select + // elements are returned as an array of string values. + // inputNode: DOMNode|String + // returns: Object + + var ret = null; + inputNode = dom.byId(inputNode); + if(inputNode){ + var _in = inputNode.name, type = (inputNode.type || "").toLowerCase(); + if(_in && type && !inputNode.disabled){ + if(type == "radio" || type == "checkbox"){ + if(inputNode.checked){ + ret = inputNode.value; + } + }else if(inputNode.multiple){ + ret = []; + var nodes = [inputNode.firstChild]; + while(nodes.length){ + for(var node = nodes.pop(); node; node = node.nextSibling){ + if(node.nodeType == 1 && node.tagName.toLowerCase() == "option"){ + if(node.selected){ + ret.push(node.value); + } + }else{ + if(node.nextSibling){ + nodes.push(node.nextSibling); + } + if(node.firstChild){ + nodes.push(node.firstChild); + } + break; + } + } + } + }else{ + ret = inputNode.value; + } + } + } + return ret; // Object + }, + + toObject: function formToObject(/*DOMNode|String*/ formNode){ + // summary: + // Serialize a form node to a JavaScript object. + // description: + // Returns the values encoded in an HTML form as + // string properties in an object which it then returns. Disabled form + // elements, buttons, and other non-value form elements are skipped. + // Multi-select elements are returned as an array of string values. + // formNode: DOMNode|String + // example: + // This form: + // |
+ // | + // | + // | + // | + // |
+ // + // yields this object structure as the result of a call to + // formToObject(): + // + // | { + // | blah: "blah", + // | multi: [ + // | "thud", + // | "thonk" + // | ] + // | }; + + var ret = {}, elems = dom.byId(formNode).elements; + for(var i = 0, l = elems.length; i < l; ++i){ + var item = elems[i], _in = item.name, type = (item.type || "").toLowerCase(); + if(_in && type && exclude.indexOf(type) < 0 && !item.disabled){ + setValue(ret, _in, form.fieldToObject(item)); + if(type == "image"){ + ret[_in + ".x"] = ret[_in + ".y"] = ret[_in].x = ret[_in].y = 0; + } + } + } + return ret; // Object + }, + + toQuery: function formToQuery(/*DOMNode|String*/ formNode){ + // summary: + // Returns a URL-encoded string representing the form passed as either a + // node or string ID identifying the form to serialize + // formNode: DOMNode|String + // returns: String + + return ioq.objectToQuery(form.toObject(formNode)); // String + }, + + toJson: function formToJson(/*DOMNode|String*/ formNode, /*Boolean?*/ prettyPrint){ + // summary: + // Create a serialized JSON string from a form node or string + // ID identifying the form to serialize + // formNode: DOMNode|String + // prettyPrint: Boolean? + // returns: String + + return json.stringify(form.toObject(formNode), null, prettyPrint ? 4 : 0); // String + } + }; + + return form; +}); + +}, +'dojo/_base/Deferred':function(){ +define([ + "./kernel", + "../Deferred", + "../promise/Promise", + "../errors/CancelError", + "../has", + "./lang", + "../when" +], function(dojo, NewDeferred, Promise, CancelError, has, lang, when){ + // module: + // dojo/_base/Deferred + + var mutator = function(){}; + var freeze = Object.freeze || function(){}; + // A deferred provides an API for creating and resolving a promise. + var Deferred = dojo.Deferred = function(/*Function?*/ canceller){ + // summary: + // Deprecated. This module defines the legacy dojo/_base/Deferred API. + // New code should use dojo/Deferred instead. + // description: + // The 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 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 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 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 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 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, canceled, fired, isError, head, nextListener; + var promise = (this.promise = new 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(has("config-useDeferredInstrumentation")){ + if(isError && NewDeferred.instrumentRejected){ + NewDeferred.instrumentRejected(result, !!func); + } + } + if(func){ + try{ + var newResult = func(result); + if (newResult && typeof newResult.then === "function"){ + newResult.then(lang.hitch(listener.deferred, "resolve"), lang.hitch(listener.deferred, "reject"), lang.hitch(listener.deferred, "progress")); + 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); + } + } + } + } + + this.isResolved = promise.isResolved = function(){ + // summary: + // Checks whether the deferred has been resolved. + // returns: Boolean + + return fired == 0; + }; + + this.isRejected = promise.isRejected = function(){ + // summary: + // Checks whether the deferred has been rejected. + // returns: Boolean + + return fired == 1; + }; + + this.isFulfilled = promise.isFulfilled = function(){ + // summary: + // Checks whether the deferred has been resolved or rejected. + // returns: Boolean + + return fired >= 0; + }; + + this.isCanceled = promise.isCanceled = function(){ + // summary: + // Checks whether the deferred has been canceled. + // returns: Boolean + + return canceled; + }; + + // calling resolve will resolve the promise + this.resolve = this.callback = function(value){ + // summary: + // Fulfills the Deferred instance successfully with the provide value + this.fired = 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 = fired = 1; + if(has("config-useDeferredInstrumentation")){ + if(NewDeferred.instrumentRejected){ + NewDeferred.instrumentRejected(error, !!nextListener); + } + } + complete(error); + this.results = [null, 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(callback, errback){ + // summary: + // Adds callback and error callback for this deferred instance. + // callback: Function? + // The callback attached to this deferred object. + // errback: Function? + // The error callback attached to this deferred object. + // returns: + // Returns this deferred object. + this.then(callback, errback, mutator); + return this; // Deferred + }; + // provide the implementation of the promise + promise.then = this.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. + // + // returns: + // Returns a new promise that represents the result of the + // execution of the callback. The callbacks will never affect the original promises value. + // example: + // An example of using a CommonJS compliant promise: + // | asyncComputeTheAnswerToEverything(). + // | then(addTwo). + // | then(printResult, onError); + // | >44 + // + var returnDeferred = progressCallback == mutator ? this : new 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; // Promise + }; + var deferred = this; + promise.cancel = this.cancel = function(){ + // summary: + // Cancels the asynchronous operation + if(!finished){ + var error = canceller && canceller(deferred); + if(!finished){ + if (!(error instanceof Error)){ + error = new CancelError(error); + } + error.log = false; + deferred.reject(error); + } + } + canceled = true; + }; + freeze(promise); + }; + lang.extend(Deferred, { + addCallback: function(/*Function*/ callback){ + // summary: + // Adds successful callback for this deferred instance. + // returns: + // Returns this deferred object. + return this.addCallbacks(lang.hitch.apply(dojo, arguments)); // Deferred + }, + + addErrback: function(/*Function*/ errback){ + // summary: + // Adds error callback for this deferred instance. + // returns: + // Returns this deferred object. + return this.addCallbacks(null, lang.hitch.apply(dojo, arguments)); // Deferred + }, + + addBoth: function(/*Function*/ callback){ + // summary: + // Add handler as both successful callback and error callback for this deferred instance. + // returns: + // Returns this deferred object. + var enclosed = lang.hitch.apply(dojo, arguments); + return this.addCallbacks(enclosed, enclosed); // Deferred + }, + fired: -1 + }); + + Deferred.when = dojo.when = when; + + return Deferred; +}); + +}, +'dojo/Deferred':function(){ +define([ + "./has", + "./_base/lang", + "./errors/CancelError", + "./promise/Promise", + "./promise/instrumentation" +], function(has, lang, CancelError, Promise, instrumentation){ + "use strict"; + + // module: + // dojo/Deferred + + var PROGRESS = 0, + RESOLVED = 1, + REJECTED = 2; + var FULFILLED_ERROR_MESSAGE = "This deferred has already been fulfilled."; + + var freezeObject = Object.freeze || function(){}; + + var signalWaiting = function(waiting, type, result, rejection, deferred){ + if( 1 ){ + if(type === REJECTED && Deferred.instrumentRejected && waiting.length === 0){ + Deferred.instrumentRejected(result, false, rejection, deferred); + } + } + + for(var i = 0; i < waiting.length; i++){ + signalListener(waiting[i], type, result, rejection); + } + }; + + var signalListener = function(listener, type, result, rejection){ + var func = listener[type]; + var deferred = listener.deferred; + if(func){ + try{ + var newResult = func(result); + if(type === PROGRESS){ + if(typeof newResult !== "undefined"){ + signalDeferred(deferred, type, newResult); + } + }else{ + if(newResult && typeof newResult.then === "function"){ + listener.cancel = newResult.cancel; + newResult.then( + // Only make resolvers if they're actually going to be used + makeDeferredSignaler(deferred, RESOLVED), + makeDeferredSignaler(deferred, REJECTED), + makeDeferredSignaler(deferred, PROGRESS)); + return; + } + signalDeferred(deferred, RESOLVED, newResult); + } + }catch(error){ + signalDeferred(deferred, REJECTED, error); + } + }else{ + signalDeferred(deferred, type, result); + } + + if( 1 ){ + if(type === REJECTED && Deferred.instrumentRejected){ + Deferred.instrumentRejected(result, !!func, rejection, deferred.promise); + } + } + }; + + var makeDeferredSignaler = function(deferred, type){ + return function(value){ + signalDeferred(deferred, type, value); + }; + }; + + var signalDeferred = function(deferred, type, result){ + if(!deferred.isCanceled()){ + switch(type){ + case PROGRESS: + deferred.progress(result); + break; + case RESOLVED: + deferred.resolve(result); + break; + case REJECTED: + deferred.reject(result); + break; + } + } + }; + + var Deferred = function(canceler){ + // summary: + // Creates a new deferred. This API is preferred over + // `dojo/_base/Deferred`. + // description: + // Creates a new deferred, as an abstraction over (primarily) + // asynchronous operations. The deferred is the private interface + // that should not be returned to calling code. That's what the + // `promise` is for. See `dojo/promise/Promise`. + // canceler: Function? + // Will be invoked if the deferred is canceled. The canceler + // receives the reason the deferred was canceled as its argument. + // The deferred is rejected with its return value, or a new + // `dojo/errors/CancelError` instance. + + // promise: dojo/promise/Promise + // The public promise object that clients can add callbacks to. + var promise = this.promise = new Promise(); + + var deferred = this; + var fulfilled, result, rejection; + var canceled = false; + var waiting = []; + + if( 1 && Error.captureStackTrace){ + Error.captureStackTrace(deferred, Deferred); + Error.captureStackTrace(promise, Deferred); + } + + this.isResolved = promise.isResolved = function(){ + // summary: + // Checks whether the deferred has been resolved. + // returns: Boolean + + return fulfilled === RESOLVED; + }; + + this.isRejected = promise.isRejected = function(){ + // summary: + // Checks whether the deferred has been rejected. + // returns: Boolean + + return fulfilled === REJECTED; + }; + + this.isFulfilled = promise.isFulfilled = function(){ + // summary: + // Checks whether the deferred has been resolved or rejected. + // returns: Boolean + + return !!fulfilled; + }; + + this.isCanceled = promise.isCanceled = function(){ + // summary: + // Checks whether the deferred has been canceled. + // returns: Boolean + + return canceled; + }; + + this.progress = function(update, strict){ + // summary: + // Emit a progress update on the deferred. + // description: + // Emit a progress update on the deferred. Progress updates + // can be used to communicate updates about the asynchronous + // operation before it has finished. + // update: any + // The progress update. Passed to progbacks. + // strict: Boolean? + // If strict, will throw an error if the deferred has already + // been fulfilled and consequently no progress can be emitted. + // returns: dojo/promise/Promise + // Returns the original promise for the deferred. + + if(!fulfilled){ + signalWaiting(waiting, PROGRESS, update, null, deferred); + return promise; + }else if(strict === true){ + throw new Error(FULFILLED_ERROR_MESSAGE); + }else{ + return promise; + } + }; + + this.resolve = function(value, strict){ + // summary: + // Resolve the deferred. + // description: + // Resolve the deferred, putting it in a success state. + // value: any + // The result of the deferred. Passed to callbacks. + // strict: Boolean? + // If strict, will throw an error if the deferred has already + // been fulfilled and consequently cannot be resolved. + // returns: dojo/promise/Promise + // Returns the original promise for the deferred. + + if(!fulfilled){ + // Set fulfilled, store value. After signaling waiting listeners unset + // waiting. + signalWaiting(waiting, fulfilled = RESOLVED, result = value, null, deferred); + waiting = null; + return promise; + }else if(strict === true){ + throw new Error(FULFILLED_ERROR_MESSAGE); + }else{ + return promise; + } + }; + + var reject = this.reject = function(error, strict){ + // summary: + // Reject the deferred. + // description: + // Reject the deferred, putting it in an error state. + // error: any + // The error result of the deferred. Passed to errbacks. + // strict: Boolean? + // If strict, will throw an error if the deferred has already + // been fulfilled and consequently cannot be rejected. + // returns: dojo/promise/Promise + // Returns the original promise for the deferred. + + if(!fulfilled){ + if( 1 && Error.captureStackTrace){ + Error.captureStackTrace(rejection = {}, reject); + } + signalWaiting(waiting, fulfilled = REJECTED, result = error, rejection, deferred); + waiting = null; + return promise; + }else if(strict === true){ + throw new Error(FULFILLED_ERROR_MESSAGE); + }else{ + return promise; + } + }; + + this.then = promise.then = function(callback, errback, progback){ + // summary: + // Add new callbacks to the deferred. + // description: + // Add new callbacks to the deferred. Callbacks can be added + // before or after the deferred is fulfilled. + // callback: Function? + // Callback to be invoked when the promise is resolved. + // Receives the resolution value. + // errback: Function? + // Callback to be invoked when the promise is rejected. + // Receives the rejection error. + // progback: Function? + // Callback to be invoked when the promise emits a progress + // update. Receives the progress update. + // returns: dojo/promise/Promise + // Returns a new promise for the result of the callback(s). + // This can be used for chaining many asynchronous operations. + + var listener = [progback, callback, errback]; + // Ensure we cancel the promise we're waiting for, or if callback/errback + // have returned a promise, cancel that one. + listener.cancel = promise.cancel; + listener.deferred = new Deferred(function(reason){ + // Check whether cancel is really available, returned promises are not + // required to expose `cancel` + return listener.cancel && listener.cancel(reason); + }); + if(fulfilled && !waiting){ + signalListener(listener, fulfilled, result, rejection); + }else{ + waiting.push(listener); + } + return listener.deferred.promise; + }; + + this.cancel = promise.cancel = function(reason, strict){ + // summary: + // Inform the deferred it may cancel its asynchronous operation. + // description: + // Inform the deferred it may cancel its asynchronous operation. + // The deferred's (optional) canceler is invoked and the + // deferred will be left in a rejected state. Can affect other + // promises that originate with the same deferred. + // reason: any + // A message that may be sent to the deferred's canceler, + // explaining why it's being canceled. + // strict: Boolean? + // If strict, will throw an error if the deferred has already + // been fulfilled and consequently cannot be canceled. + // returns: any + // Returns the rejection reason if the deferred was canceled + // normally. + + if(!fulfilled){ + // Cancel can be called even after the deferred is fulfilled + if(canceler){ + var returnedReason = canceler(reason); + reason = typeof returnedReason === "undefined" ? reason : returnedReason; + } + canceled = true; + if(!fulfilled){ + // Allow canceler to provide its own reason, but fall back to a CancelError + if(typeof reason === "undefined"){ + reason = new CancelError(); + } + reject(reason); + return reason; + }else if(fulfilled === REJECTED && result === reason){ + return reason; + } + }else if(strict === true){ + throw new Error(FULFILLED_ERROR_MESSAGE); + } + }; + + freezeObject(promise); + }; + + Deferred.prototype.toString = function(){ + // returns: String + // Returns `[object Deferred]`. + + return "[object Deferred]"; + }; + + if(instrumentation){ + instrumentation(Deferred); + } + + return Deferred; +}); + +}, +'dojo/errors/CancelError':function(){ +define(["./create"], function(create){ + // module: + // dojo/errors/CancelError + + /*===== + return function(){ + // summary: + // Default error if a promise is canceled without a reason. + }; + =====*/ + + return create("CancelError", null, null, { dojoType: "cancel", log: false }); +}); + +}, +'dojo/errors/create':function(){ +define(["../_base/lang"], function(lang){ + return function(name, ctor, base, props){ + base = base || Error; + + var ErrorCtor = function(message){ + if(base === Error){ + if(Error.captureStackTrace){ + Error.captureStackTrace(this, ErrorCtor); + } + + // Error.call() operates on the returned error + // object rather than operating on |this| + var err = Error.call(this, message), + prop; + + // Copy own properties from err to |this| + for(prop in err){ + if(err.hasOwnProperty(prop)){ + this[prop] = err[prop]; + } + } + + // messsage is non-enumerable in ES5 + this.message = message; + // stack is non-enumerable in at least Firefox + this.stack = err.stack; + }else{ + base.apply(this, arguments); + } + if(ctor){ + ctor.apply(this, arguments); + } + }; + + ErrorCtor.prototype = lang.delegate(base.prototype, props); + ErrorCtor.prototype.name = name; + ErrorCtor.prototype.constructor = ErrorCtor; + + return ErrorCtor; + }; +}); + +}, +'dojo/promise/Promise':function(){ +define([ + "../_base/lang" +], function(lang){ + "use strict"; + + // module: + // dojo/promise/Promise + + function throwAbstract(){ + throw new TypeError("abstract"); + } + + return lang.extend(function Promise(){ + // summary: + // The public interface to a deferred. + // description: + // The public interface to a deferred. All promises in Dojo are + // instances of this class. + }, { + then: function(callback, errback, progback){ + // summary: + // Add new callbacks to the promise. + // description: + // Add new callbacks to the deferred. Callbacks can be added + // before or after the deferred is fulfilled. + // callback: Function? + // Callback to be invoked when the promise is resolved. + // Receives the resolution value. + // errback: Function? + // Callback to be invoked when the promise is rejected. + // Receives the rejection error. + // progback: Function? + // Callback to be invoked when the promise emits a progress + // update. Receives the progress update. + // returns: dojo/promise/Promise + // Returns a new promise for the result of the callback(s). + // This can be used for chaining many asynchronous operations. + + throwAbstract(); + }, + + cancel: function(reason, strict){ + // summary: + // Inform the deferred it may cancel its asynchronous operation. + // description: + // Inform the deferred it may cancel its asynchronous operation. + // The deferred's (optional) canceler is invoked and the + // deferred will be left in a rejected state. Can affect other + // promises that originate with the same deferred. + // reason: any + // A message that may be sent to the deferred's canceler, + // explaining why it's being canceled. + // strict: Boolean? + // If strict, will throw an error if the deferred has already + // been fulfilled and consequently cannot be canceled. + // returns: any + // Returns the rejection reason if the deferred was canceled + // normally. + + throwAbstract(); + }, + + isResolved: function(){ + // summary: + // Checks whether the promise has been resolved. + // returns: Boolean + + throwAbstract(); + }, + + isRejected: function(){ + // summary: + // Checks whether the promise has been rejected. + // returns: Boolean + + throwAbstract(); + }, + + isFulfilled: function(){ + // summary: + // Checks whether the promise has been resolved or rejected. + // returns: Boolean + + throwAbstract(); + }, + + isCanceled: function(){ + // summary: + // Checks whether the promise has been canceled. + // returns: Boolean + + throwAbstract(); + }, + + "finally": function(callback) { + // summary: + // Add a callback to the promise that will fire whether it + // resolves or rejects. + // description: + // Conforms to ES2018's `Promise.prototype.finally`. + // Add a callback to the promise that will fire whether it + // resolves or rejects. No value is passed to the callback. + // Returns a promise that reflects the state of the original promise, + // with two exceptions: + // - If the callback return a promise, the outer promise will wait + // until the returned promise is resolved, then it will resolve + // with the original value. + // - If the callback throws an exception or returns a promise that + // is rejected (or rejects later), the outer promise will reject + // with the inner promise's rejection reason. + // callback: Function? + // Callback to be invoked when the promise is resolved + // or rejected. Doesn't receive any value. + // returns: dojo/promise/Promise + // Returns a new promise that reflects the state of the original promise, + // with two small exceptions (see description). + // + + return this.then(function (value){ + var valueOrPromise = callback(); + if (valueOrPromise && typeof valueOrPromise.then === "function"){ + return valueOrPromise.then(function (){ + return value; + }); + } + return value; + }, function(reason) { + var valueOrPromise = callback(); + if (valueOrPromise && typeof valueOrPromise.then === "function"){ + return valueOrPromise.then(function (){ + throw reason; + }); + } + throw reason; + }); + }, + + always: function(callbackOrErrback){ + // summary: + // Add a callback to be invoked when the promise is resolved + // or rejected. + // callbackOrErrback: Function? + // A function that is used both as a callback and errback. + // returns: dojo/promise/Promise + // Returns a new promise for the result of the callback/errback. + + return this.then(callbackOrErrback, callbackOrErrback); + }, + + "catch": function(errback){ + // summary: + // Add new errbacks to the promise. Follows ECMA specification naming. + // errback: Function? + // Callback to be invoked when the promise is rejected. + // returns: dojo/promise/Promise + // Returns a new promise for the result of the errback. + + return this.then(null, errback); + }, + + otherwise: function(errback){ + // summary: + // Add new errbacks to the promise. + // errback: Function? + // Callback to be invoked when the promise is rejected. + // returns: dojo/promise/Promise + // Returns a new promise for the result of the errback. + + return this.then(null, errback); + }, + + trace: function(){ + return this; + }, + + traceRejected: function(){ + return this; + }, + + toString: function(){ + // returns: string + // Returns `[object Promise]`. + + return "[object Promise]"; + } + }); +}); + +}, +'dojo/promise/instrumentation':function(){ +define([ + "./tracer", + "../has", + "../_base/lang", + "../_base/array" +], function(tracer, has, lang, arrayUtil){ + has.add("config-useDeferredInstrumentation", "report-unhandled-rejections"); + + function logError(error, rejection, deferred){ + if(error && error.log === false){ + return; + } + var stack = ""; + if(error && error.stack){ + stack += error.stack; + } + if(rejection && rejection.stack){ + stack += "\n ----------------------------------------\n rejected" + rejection.stack.split("\n").slice(1).join("\n").replace(/^\s+/, " "); + } + if(deferred && deferred.stack){ + stack += "\n ----------------------------------------\n" + deferred.stack; + } + console.error(error, stack); + } + + function reportRejections(error, handled, rejection, deferred){ + if(!handled){ + logError(error, rejection, deferred); + } + } + + var errors = []; + var activeTimeout = false; + var unhandledWait = 1000; + function trackUnhandledRejections(error, handled, rejection, deferred){ + // try to find the existing tracking object + if(!arrayUtil.some(errors, function(obj){ + if(obj.error === error){ + // found the tracking object for this error + if(handled){ + // if handled, update the state + obj.handled = true; + } + return true; + } + })){ + // no tracking object has been setup, create one + errors.push({ + error: error, + rejection: rejection, + handled: handled, + deferred: deferred, + timestamp: new Date().getTime() + }); + } + + if(!activeTimeout){ + activeTimeout = setTimeout(logRejected, unhandledWait); + } + } + + function logRejected(){ + var now = new Date().getTime(); + var reportBefore = now - unhandledWait; + errors = arrayUtil.filter(errors, function(obj){ + // only report the error if we have waited long enough and + // it hasn't been handled + if(obj.timestamp < reportBefore){ + if(!obj.handled){ + logError(obj.error, obj.rejection, obj.deferred); + } + return false; + } + return true; + }); + + if(errors.length){ + activeTimeout = setTimeout(logRejected, errors[0].timestamp + unhandledWait - now); + }else{ + activeTimeout = false; + } + } + + return function(Deferred){ + // summary: + // Initialize instrumentation for the Deferred class. + // description: + // Initialize instrumentation for the Deferred class. + // Done automatically by `dojo/Deferred` if the + // `deferredInstrumentation` and `useDeferredInstrumentation` + // config options are set. + // + // Sets up `dojo/promise/tracer` to log to the console. + // + // Sets up instrumentation of rejected deferreds so unhandled + // errors are logged to the console. + + var usage = has("config-useDeferredInstrumentation"); + if(usage){ + tracer.on("resolved", lang.hitch(console, "log", "resolved")); + tracer.on("rejected", lang.hitch(console, "log", "rejected")); + tracer.on("progress", lang.hitch(console, "log", "progress")); + + var args = []; + if(typeof usage === "string"){ + args = usage.split(","); + usage = args.shift(); + } + if(usage === "report-rejections"){ + Deferred.instrumentRejected = reportRejections; + }else if(usage === "report-unhandled-rejections" || usage === true || usage === 1){ + Deferred.instrumentRejected = trackUnhandledRejections; + unhandledWait = parseInt(args[0], 10) || unhandledWait; + }else{ + throw new Error("Unsupported instrumentation usage <" + usage + ">"); + } + } + }; +}); + +}, +'dojo/promise/tracer':function(){ +define([ + "../_base/lang", + "./Promise", + "../Evented" +], function(lang, Promise, Evented){ + "use strict"; + + // module: + // dojo/promise/tracer + + /*===== + return { + // summary: + // Trace promise fulfillment. + // description: + // Trace promise fulfillment. Calling `.trace()` or `.traceError()` on a + // promise enables tracing. Will emit `resolved`, `rejected` or `progress` + // events. + + on: function(type, listener){ + // summary: + // Subscribe to traces. + // description: + // See `dojo/Evented#on()`. + // type: String + // `resolved`, `rejected`, or `progress` + // listener: Function + // The listener is passed the traced value and any arguments + // that were used with the `.trace()` call. + } + }; + =====*/ + + var evented = new Evented; + var emit = evented.emit; + evented.emit = null; + // Emit events asynchronously since they should not change the promise state. + function emitAsync(args){ + setTimeout(function(){ + emit.apply(evented, args); + }, 0); + } + + Promise.prototype.trace = function(){ + // summary: + // Trace the promise. + // description: + // Tracing allows you to transparently log progress, + // resolution and rejection of promises, without affecting the + // promise itself. Any arguments passed to `trace()` are + // emitted in trace events. See `dojo/promise/tracer` on how + // to handle traces. + // returns: dojo/promise/Promise + // The promise instance `trace()` is called on. + + var args = lang._toArray(arguments); + this.then( + function(value){ emitAsync(["resolved", value].concat(args)); }, + function(error){ emitAsync(["rejected", error].concat(args)); }, + function(update){ emitAsync(["progress", update].concat(args)); } + ); + return this; + }; + + Promise.prototype.traceRejected = function(){ + // summary: + // Trace rejection of the promise. + // description: + // Tracing allows you to transparently log progress, + // resolution and rejection of promises, without affecting the + // promise itself. Any arguments passed to `trace()` are + // emitted in trace events. See `dojo/promise/tracer` on how + // to handle traces. + // returns: dojo/promise/Promise + // The promise instance `traceRejected()` is called on. + + var args = lang._toArray(arguments); + this.otherwise(function(error){ + emitAsync(["rejected", error].concat(args)); + }); + return this; + }; + + return evented; +}); + +}, +'dojo/Evented':function(){ +define(["./aspect", "./on"], function(aspect, on){ + // module: + // dojo/Evented + + "use strict"; + var after = aspect.after; + function Evented(){ + // summary: + // A class that can be used as a mixin or base class, + // to add on() and emit() methods to a class + // for listening for events and emitting events: + // example: + // | define(["dojo/Evented", "dojo/_base/declare", "dojo/Stateful" + // | ], function(Evented, declare, Stateful){ + // | var EventedStateful = declare([Evented, Stateful], {...}); + // | var instance = new EventedStateful(); + // | instance.on("open", function(event){ + // | ... do something with event + // | }); + // | + // | instance.emit("open", {name:"some event", ...}); + } + Evented.prototype = { + on: function(type, listener){ + return on.parse(this, type, listener, function(target, type){ + return after(target, 'on' + type, listener, true); + }); + }, + emit: function(type, event){ + var args = [this]; + args.push.apply(args, arguments); + return on.emit.apply(on, args); + } + }; + return Evented; +}); + +}, +'dojo/aspect':function(){ +define([], function(){ + + // module: + // dojo/aspect + + "use strict"; + var undefined; + function advise(dispatcher, type, advice, receiveArguments){ + var previous = dispatcher[type]; + var around = type == "around"; + var signal; + if(around){ + var advised = advice(function(){ + return previous.advice(this, arguments); + }); + signal = { + remove: function(){ + if(advised){ + advised = dispatcher = advice = null; + } + }, + advice: function(target, args){ + return advised ? + advised.apply(target, args) : // called the advised function + previous.advice(target, args); // cancelled, skip to next one + } + }; + }else{ + // create the remove handler + signal = { + remove: function(){ + if(signal.advice){ + var previous = signal.previous; + var next = signal.next; + if(!next && !previous){ + delete dispatcher[type]; + }else{ + if(previous){ + previous.next = next; + }else{ + dispatcher[type] = next; + } + if(next){ + next.previous = previous; + } + } + + // remove the advice to signal that this signal has been removed + dispatcher = advice = signal.advice = null; + } + }, + id: dispatcher.nextId++, + advice: advice, + receiveArguments: receiveArguments + }; + } + if(previous && !around){ + if(type == "after"){ + // add the listener to the end of the list + // note that we had to change this loop a little bit to workaround a bizarre IE10 JIT bug + while(previous.next && (previous = previous.next)){} + previous.next = signal; + signal.previous = previous; + }else if(type == "before"){ + // add to beginning + dispatcher[type] = signal; + signal.next = previous; + previous.previous = signal; + } + }else{ + // around or first one just replaces + dispatcher[type] = signal; + } + return signal; + } + function aspect(type){ + return function(target, methodName, advice, receiveArguments){ + var existing = target[methodName], dispatcher; + if(!existing || existing.target != target){ + // no dispatcher in place + target[methodName] = dispatcher = function(){ + var executionId = dispatcher.nextId; + // before advice + var args = arguments; + var before = dispatcher.before; + while(before){ + if(before.advice){ + args = before.advice.apply(this, args) || args; + } + before = before.next; + } + // around advice + if(dispatcher.around){ + var results = dispatcher.around.advice(this, args); + } + // after advice + var after = dispatcher.after; + while(after && after.id < executionId){ + if(after.advice){ + if(after.receiveArguments){ + var newResults = after.advice.apply(this, args); + // change the return value only if a new value was returned + results = newResults === undefined ? results : newResults; + }else{ + results = after.advice.call(this, results, args); + } + } + after = after.next; + } + return results; + }; + if(existing){ + dispatcher.around = {advice: function(target, args){ + return existing.apply(target, args); + }}; + } + dispatcher.target = target; + dispatcher.nextId = dispatcher.nextId || 0; + } + var results = advise((dispatcher || existing), type, advice, receiveArguments); + advice = null; + return results; + }; + } + + // TODOC: after/before/around return object + + var after = aspect("after"); + /*===== + after = function(target, methodName, advice, receiveArguments){ + // summary: + // The "after" export of the aspect module is a function that can be used to attach + // "after" advice to a method. This function will be executed after the original method + // is executed. By default the function will be called with a single argument, the return + // value of the original method, or the the return value of the last executed advice (if a previous one exists). + // The fourth (optional) argument can be set to true to so the function receives the original + // arguments (from when the original method was called) rather than the return value. + // If there are multiple "after" advisors, they are executed in the order they were registered. + // target: Object + // This is the target object + // methodName: String + // This is the name of the method to attach to. + // advice: Function + // This is function to be called after the original method + // receiveArguments: Boolean? + // If this is set to true, the advice function receives the original arguments (from when the original mehtod + // was called) rather than the return value of the original/previous method. + // returns: + // A signal object that can be used to cancel the advice. If remove() is called on this signal object, it will + // stop the advice function from being executed. + }; + =====*/ + + var before = aspect("before"); + /*===== + before = function(target, methodName, advice){ + // summary: + // The "before" export of the aspect module is a function that can be used to attach + // "before" advice to a method. This function will be executed before the original method + // is executed. This function will be called with the arguments used to call the method. + // This function may optionally return an array as the new arguments to use to call + // the original method (or the previous, next-to-execute before advice, if one exists). + // If the before method doesn't return anything (returns undefined) the original arguments + // will be preserved. + // If there are multiple "before" advisors, they are executed in the reverse order they were registered. + // target: Object + // This is the target object + // methodName: String + // This is the name of the method to attach to. + // advice: Function + // This is function to be called before the original method + }; + =====*/ + + var around = aspect("around"); + /*===== + around = function(target, methodName, advice){ + // summary: + // The "around" export of the aspect module is a function that can be used to attach + // "around" advice to a method. The advisor function is immediately executed when + // the around() is called, is passed a single argument that is a function that can be + // called to continue execution of the original method (or the next around advisor). + // The advisor function should return a function, and this function will be called whenever + // the method is called. It will be called with the arguments used to call the method. + // Whatever this function returns will be returned as the result of the method call (unless after advise changes it). + // example: + // If there are multiple "around" advisors, the most recent one is executed first, + // which can then delegate to the next one and so on. For example: + // | around(obj, "foo", function(originalFoo){ + // | return function(){ + // | var start = new Date().getTime(); + // | var results = originalFoo.apply(this, arguments); // call the original + // | var end = new Date().getTime(); + // | console.log("foo execution took " + (end - start) + " ms"); + // | return results; + // | }; + // | }); + // target: Object + // This is the target object + // methodName: String + // This is the name of the method to attach to. + // advice: Function + // This is function to be called around the original method + }; + =====*/ + + return { + // summary: + // provides aspect oriented programming functionality, allowing for + // one to add before, around, or after advice on existing methods. + // example: + // | define(["dojo/aspect"], function(aspect){ + // | var signal = aspect.after(targetObject, "methodName", function(someArgument){ + // | this will be called when targetObject.methodName() is called, after the original function is called + // | }); + // + // example: + // The returned signal object can be used to cancel the advice. + // | signal.remove(); // this will stop the advice from being executed anymore + // | aspect.before(targetObject, "methodName", function(someArgument){ + // | // this will be called when targetObject.methodName() is called, before the original function is called + // | }); + + before: before, + around: around, + after: after + }; +}); + +}, +'dojo/on':function(){ +define(["./has!dom-addeventlistener?:./aspect", "./_base/kernel", "./sniff"], function(aspect, dojo, has){ + + "use strict"; + if( 1 ){ // check to make sure we are in a browser, this module should work anywhere + var major = window.ScriptEngineMajorVersion; + has.add("jscript", major && (major() + ScriptEngineMinorVersion() / 10)); + has.add("event-orientationchange", has("touch") && !has("android")); // TODO: how do we detect this? + has.add("event-stopimmediatepropagation", window.Event && !!window.Event.prototype && !!window.Event.prototype.stopImmediatePropagation); + has.add("event-focusin", function(global, doc, element){ + return 'onfocusin' in element; + }); + + if(has("touch")){ + has.add("touch-can-modify-event-delegate", function(){ + // This feature test checks whether deleting a property of an event delegate works + // for a touch-enabled device. If it works, event delegation can be used as fallback + // for browsers such as Safari in older iOS where deleting properties of the original + // event does not work. + var EventDelegate = function(){}; + EventDelegate.prototype = + document.createEvent("MouseEvents"); // original event + // Attempt to modify a property of an event delegate and check if + // it succeeds. Depending on browsers and on whether dojo/on's + // strict mode is stripped in a Dojo build, there are 3 known behaviors: + // it may either succeed, or raise an error, or fail to set the property + // without raising an error. + try{ + var eventDelegate = new EventDelegate; + eventDelegate.target = null; + return eventDelegate.target === null; + }catch(e){ + return false; // cannot use event delegation + } + }); + } + } + var on = function(target, type, listener, dontFix){ + // summary: + // A function that provides core event listening functionality. With this function + // you can provide a target, event type, and listener to be notified of + // future matching events that are fired. + // target: Element|Object + // This is the target object or DOM element that to receive events from + // type: String|Function + // This is the name of the event to listen for or an extension event type. + // listener: Function + // This is the function that should be called when the event fires. + // returns: Object + // An object with a remove() method that can be used to stop listening for this + // event. + // description: + // To listen for "click" events on a button node, we can do: + // | define(["dojo/on"], function(on){ + // | on(button, "click", clickHandler); + // | ... + // Evented JavaScript objects can also have their own events. + // | var obj = new Evented; + // | on(obj, "foo", fooHandler); + // And then we could publish a "foo" event: + // | on.emit(obj, "foo", {key: "value"}); + // We can use extension events as well. For example, you could listen for a tap gesture: + // | define(["dojo/on", "dojo/gesture/tap", function(on, tap){ + // | on(button, tap, tapHandler); + // | ... + // which would trigger fooHandler. Note that for a simple object this is equivalent to calling: + // | obj.onfoo({key:"value"}); + // If you use on.emit on a DOM node, it will use native event dispatching when possible. + + if(typeof target.on == "function" && typeof type != "function" && !target.nodeType){ + // delegate to the target's on() method, so it can handle it's own listening if it wants (unless it + // is DOM node and we may be dealing with jQuery or Prototype's incompatible addition to the + // Element prototype + return target.on(type, listener); + } + // delegate to main listener code + return on.parse(target, type, listener, addListener, dontFix, this); + }; + on.pausable = function(target, type, listener, dontFix){ + // summary: + // This function acts the same as on(), but with pausable functionality. The + // returned signal object has pause() and resume() functions. Calling the + // pause() method will cause the listener to not be called for future events. Calling the + // resume() method will cause the listener to again be called for future events. + var paused; + var signal = on(target, type, function(){ + if(!paused){ + return listener.apply(this, arguments); + } + }, dontFix); + signal.pause = function(){ + paused = true; + }; + signal.resume = function(){ + paused = false; + }; + return signal; + }; + on.once = function(target, type, listener, dontFix){ + // summary: + // This function acts the same as on(), but will only call the listener once. The + // listener will be called for the first + // event that takes place and then listener will automatically be removed. + var signal = on(target, type, function(){ + // remove this listener + signal.remove(); + // proceed to call the listener + return listener.apply(this, arguments); + }); + return signal; + }; + on.parse = function(target, type, listener, addListener, dontFix, matchesTarget){ + var events; + if(type.call){ + // event handler function + // on(node, touch.press, touchListener); + return type.call(matchesTarget, target, listener); + } + + if(type instanceof Array){ + // allow an array of event names (or event handler functions) + events = type; + }else if(type.indexOf(",") > -1){ + // we allow comma delimited event names, so you can register for multiple events at once + events = type.split(/\s*,\s*/); + } + if(events){ + var handles = []; + var i = 0; + var eventName; + while(eventName = events[i++]){ // intentional assignment + handles.push(on.parse(target, eventName, listener, addListener, dontFix, matchesTarget)); + } + handles.remove = function(){ + for(var i = 0; i < handles.length; i++){ + handles[i].remove(); + } + }; + return handles; + } + return addListener(target, type, listener, dontFix, matchesTarget); + }; + var touchEvents = /^touch/; + function addListener(target, type, listener, dontFix, matchesTarget){ + // event delegation: + var selector = type.match(/(.*):(.*)/); + // if we have a selector:event, the last one is interpreted as an event, and we use event delegation + if(selector){ + type = selector[2]; + selector = selector[1]; + // create the extension event for selectors and directly call it + return on.selector(selector, type).call(matchesTarget, target, listener); + } + // test to see if it a touch event right now, so we don't have to do it every time it fires + if(has("touch")){ + if(touchEvents.test(type)){ + // touch event, fix it + listener = fixTouchListener(listener); + } + if(!has("event-orientationchange") && (type == "orientationchange")){ + //"orientationchange" not supported <= Android 2.1, + //but works through "resize" on window + type = "resize"; + target = window; + listener = fixTouchListener(listener); + } + } + if(addStopImmediate){ + // add stopImmediatePropagation if it doesn't exist + listener = addStopImmediate(listener); + } + // normal path, the target is |this| + if(target.addEventListener){ + // the target has addEventListener, which should be used if available (might or might not be a node, non-nodes can implement this method as well) + // check for capture conversions + var capture = type in captures, + adjustedType = capture ? captures[type] : type; + target.addEventListener(adjustedType, listener, capture); + // create and return the signal + return { + remove: function(){ + target.removeEventListener(adjustedType, listener, capture); + } + }; + } + type = "on" + type; + if(fixAttach && target.attachEvent){ + return fixAttach(target, type, listener); + } + throw new Error("Target must be an event emitter"); + } + on.matches = function(node, selector, context, children, matchesTarget) { + // summary: + // Check if a node match the current selector within the constraint of a context + // node: DOMNode + // The node that originate the event + // selector: String + // The selector to check against + // context: DOMNode + // The context to search in. + // children: Boolean + // Indicates if children elements of the selector should be allowed. This defaults to + // true + // matchesTarget: Object|dojo/query? + // An object with a property "matches" as a function. Default is dojo/query. + // Matching DOMNodes will be done against this function + // The function must return a Boolean. + // It will have 3 arguments: "node", "selector" and "context" + // True is expected if "node" is matching the current "selector" in the passed "context" + // returns: DOMNode? + // The matching node, if any. Else you get false + + // see if we have a valid matchesTarget or default to dojo/query + matchesTarget = matchesTarget && (typeof matchesTarget.matches == "function") ? matchesTarget : dojo.query; + children = children !== false; + // there is a selector, so make sure it matches + if(node.nodeType != 1){ + // text node will fail in native match selector + node = node.parentNode; + } + while(!matchesTarget.matches(node, selector, context)){ + if(node == context || children === false || !(node = node.parentNode) || node.nodeType != 1){ // intentional assignment + return false; + } + } + return node; + }; + on.selector = function(selector, eventType, children){ + // summary: + // Creates a new extension event with event delegation. This is based on + // the provided event type (can be extension event) that + // only calls the listener when the CSS selector matches the target of the event. + // + // The application must require() an appropriate level of dojo/query to handle the selector. + // selector: + // The CSS selector to use for filter events and determine the |this| of the event listener. + // eventType: + // The event to listen for + // children: + // Indicates if children elements of the selector should be allowed. This defaults to + // true + // example: + // | require(["dojo/on", "dojo/mouse", "dojo/query!css2"], function(on, mouse){ + // | on(node, on.selector(".my-class", mouse.enter), handlerForMyHover); + return function(target, listener){ + // if the selector is function, use it to select the node, otherwise use the matches method + var matchesTarget = typeof selector == "function" ? {matches: selector} : this, + bubble = eventType.bubble; + function select(eventTarget){ + return on.matches(eventTarget, selector, target, children, matchesTarget); + } + if(bubble){ + // the event type doesn't naturally bubble, but has a bubbling form, use that, and give it the selector so it can perform the select itself + return on(target, bubble(select), listener); + } + // standard event delegation + return on(target, eventType, function(event){ + // call select to see if we match + var eventTarget = select(event.target); + // if it matches we call the listener + if (eventTarget) { + // We save the matching target into the event, so it can be accessed even when hitching (see #18355) + event.selectorTarget = eventTarget; + return listener.call(eventTarget, event); + } + }); + }; + }; + + function syntheticPreventDefault(){ + this.cancelable = false; + this.defaultPrevented = true; + } + function syntheticStopPropagation(){ + this.bubbles = false; + } + var slice = [].slice, + syntheticDispatch = on.emit = function(target, type, event){ + // summary: + // Fires an event on the target object. + // target: + // The target object to fire the event on. This can be a DOM element or a plain + // JS object. If the target is a DOM element, native event emitting mechanisms + // are used when possible. + // type: + // The event type name. You can emulate standard native events like "click" and + // "mouseover" or create custom events like "open" or "finish". + // event: + // An object that provides the properties for the event. See https://developer.mozilla.org/en/DOM/event.initEvent + // for some of the properties. These properties are copied to the event object. + // Of particular importance are the cancelable and bubbles properties. The + // cancelable property indicates whether or not the event has a default action + // that can be cancelled. The event is cancelled by calling preventDefault() on + // the event object. The bubbles property indicates whether or not the + // event will bubble up the DOM tree. If bubbles is true, the event will be called + // on the target and then each parent successively until the top of the tree + // is reached or stopPropagation() is called. Both bubbles and cancelable + // default to false. + // returns: + // If the event is cancelable and the event is not cancelled, + // emit will return true. If the event is cancelable and the event is cancelled, + // emit will return false. + // details: + // Note that this is designed to emit events for listeners registered through + // dojo/on. It should actually work with any event listener except those + // added through IE's attachEvent (IE8 and below's non-W3C event emitting + // doesn't support custom event types). It should work with all events registered + // through dojo/on. Also note that the emit method does do any default + // action, it only returns a value to indicate if the default action should take + // place. For example, emitting a keypress event would not cause a character + // to appear in a textbox. + // example: + // To fire our own click event + // | require(["dojo/on", "dojo/dom" + // | ], function(on, dom){ + // | on.emit(dom.byId("button"), "click", { + // | cancelable: true, + // | bubbles: true, + // | screenX: 33, + // | screenY: 44 + // | }); + // We can also fire our own custom events: + // | on.emit(dom.byId("slider"), "slide", { + // | cancelable: true, + // | bubbles: true, + // | direction: "left-to-right" + // | }); + // | }); + var args = slice.call(arguments, 2); + var method = "on" + type; + if("parentNode" in target){ + // node (or node-like), create event controller methods + var newEvent = args[0] = {}; + for(var i in event){ + newEvent[i] = event[i]; + } + newEvent.preventDefault = syntheticPreventDefault; + newEvent.stopPropagation = syntheticStopPropagation; + newEvent.target = target; + newEvent.type = type; + event = newEvent; + } + do{ + // call any node which has a handler (note that ideally we would try/catch to simulate normal event propagation but that causes too much pain for debugging) + target[method] && target[method].apply(target, args); + // and then continue up the parent node chain if it is still bubbling (if started as bubbles and stopPropagation hasn't been called) + }while(event && event.bubbles && (target = target.parentNode)); + return event && event.cancelable && event; // if it is still true (was cancelable and was cancelled), return the event to indicate default action should happen + }; + var captures = has("event-focusin") ? {} : {focusin: "focus", focusout: "blur"}; + if(!has("event-stopimmediatepropagation")){ + var stopImmediatePropagation =function(){ + this.immediatelyStopped = true; + this.modified = true; // mark it as modified so the event will be cached in IE + }; + var addStopImmediate = function(listener){ + return function(event){ + if(!event.immediatelyStopped){// check to make sure it hasn't been stopped immediately + event.stopImmediatePropagation = stopImmediatePropagation; + return listener.apply(this, arguments); + } + }; + }; + } + if(has("dom-addeventlistener")){ + // emitter that works with native event handling + on.emit = function(target, type, event){ + if(target.dispatchEvent && document.createEvent){ + // use the native event emitting mechanism if it is available on the target object + // create a generic event + // we could create branch into the different types of event constructors, but + // that would be a lot of extra code, with little benefit that I can see, seems + // best to use the generic constructor and copy properties over, making it + // easy to have events look like the ones created with specific initializers + var ownerDocument = target.ownerDocument || document; + var nativeEvent = ownerDocument.createEvent("HTMLEvents"); + nativeEvent.initEvent(type, !!event.bubbles, !!event.cancelable); + // and copy all our properties over + for(var i in event){ + if(!(i in nativeEvent)){ + nativeEvent[i] = event[i]; + } + } + return target.dispatchEvent(nativeEvent) && nativeEvent; + } + return syntheticDispatch.apply(on, arguments); // emit for a non-node + }; + }else{ + // no addEventListener, basically old IE event normalization + on._fixEvent = function(evt, sender){ + // summary: + // normalizes properties on the event object including event + // bubbling methods, keystroke normalization, and x/y positions + // evt: + // native event object + // sender: + // node to treat as "currentTarget" + if(!evt){ + var w = sender && (sender.ownerDocument || sender.document || sender).parentWindow || window; + evt = w.event; + } + if(!evt){return evt;} + try{ + if(lastEvent && evt.type == lastEvent.type && evt.srcElement == lastEvent.target){ + // should be same event, reuse event object (so it can be augmented); + // accessing evt.srcElement rather than evt.target since evt.target not set on IE until fixup below + evt = lastEvent; + } + }catch(e){ + // will occur on IE on lastEvent.type reference if lastEvent points to a previous event that already + // finished bubbling, but the setTimeout() to clear lastEvent hasn't fired yet + } + if(!evt.target){ // check to see if it has been fixed yet + evt.target = evt.srcElement; + evt.currentTarget = (sender || evt.srcElement); + if(evt.type == "mouseover"){ + evt.relatedTarget = evt.fromElement; + } + if(evt.type == "mouseout"){ + evt.relatedTarget = evt.toElement; + } + if(!evt.stopPropagation){ + evt.stopPropagation = stopPropagation; + evt.preventDefault = preventDefault; + } + switch(evt.type){ + case "keypress": + var c = ("charCode" in evt ? evt.charCode : evt.keyCode); + if (c==10){ + // CTRL-ENTER is CTRL-ASCII(10) on IE, but CTRL-ENTER on Mozilla + c=0; + evt.keyCode = 13; + }else if(c==13||c==27){ + c=0; // Mozilla considers ENTER and ESC non-printable + }else if(c==3){ + c=99; // Mozilla maps CTRL-BREAK to CTRL-c + } + // Mozilla sets keyCode to 0 when there is a charCode + // but that stops the event on IE. + evt.charCode = c; + _setKeyChar(evt); + break; + } + } + return evt; + }; + var lastEvent, IESignal = function(handle){ + this.handle = handle; + }; + IESignal.prototype.remove = function(){ + delete _dojoIEListeners_[this.handle]; + }; + var fixListener = function(listener){ + // this is a minimal function for closing on the previous listener with as few as variables as possible + return function(evt){ + evt = on._fixEvent(evt, this); + var result = listener.call(this, evt); + if(evt.modified){ + // cache the last event and reuse it if we can + if(!lastEvent){ + setTimeout(function(){ + lastEvent = null; + }); + } + lastEvent = evt; + } + return result; + }; + }; + var fixAttach = function(target, type, listener){ + listener = fixListener(listener); + if(((target.ownerDocument ? target.ownerDocument.parentWindow : target.parentWindow || target.window || window) != top || + has("jscript") < 5.8) && + !has("config-_allow_leaks")){ + // IE will leak memory on certain handlers in frames (IE8 and earlier) and in unattached DOM nodes for JScript 5.7 and below. + // Here we use global redirection to solve the memory leaks + if(typeof _dojoIEListeners_ == "undefined"){ + _dojoIEListeners_ = []; + } + var emitter = target[type]; + if(!emitter || !emitter.listeners){ + var oldListener = emitter; + emitter = Function('event', 'var callee = arguments.callee; for(var i = 0; i 1){ + return callback ? callback(valueOrPromise) : valueOrPromise; + }else{ + return new Deferred().resolve(valueOrPromise); + } + }else if(!nativePromise){ + var deferred = new Deferred(valueOrPromise.cancel); + valueOrPromise.then(deferred.resolve, deferred.reject, deferred.progress); + valueOrPromise = deferred.promise; + } + + if(callback || errback || progback){ + return valueOrPromise.then(callback, errback, progback); + } + return valueOrPromise; + }; +}); + +}, +'dojo/_base/json':function(){ +define(["./kernel", "../json"], function(dojo, json){ + +// module: +// dojo/_base/json + +/*===== +return { + // summary: + // This module defines the dojo JSON API. +}; +=====*/ + +dojo.fromJson = function(/*String*/ js){ + // summary: + // Parses a JavaScript expression and returns a JavaScript value. + // description: + // Throws for invalid JavaScript expressions. It does not use a strict JSON parser. It + // always delegates to eval(). The content passed to this method must therefore come + // from a trusted source. + // It is recommend that you use dojo/json's parse function for an + // implementation uses the (faster) native JSON parse when available. + // js: + // a string literal of a JavaScript expression, for instance: + // `'{ "foo": [ "bar", 1, { "baz": "thud" } ] }'` + + return eval("(" + js + ")"); // Object +}; + +/*===== +dojo._escapeString = function(){ + // summary: + // Adds escape sequences for non-visual characters, double quote and + // backslash and surrounds with double quotes to form a valid string + // literal. +}; +=====*/ +dojo._escapeString = json.stringify; // just delegate to json.stringify + +dojo.toJsonIndentStr = "\t"; +dojo.toJson = function(/*Object*/ it, /*Boolean?*/ prettyPrint){ + // 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 is recommend that you use dojo/json's stringify function for an lighter + // and faster implementation that matches the native JSON API and uses the + // native JSON serializer when available. + // 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. + // Note that in 1.6, toJson would serialize undefined, but this no longer supported + // since it is not supported by native JSON serializer. + // 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(). + // Note that if native JSON support is available, it will be used for serialization, + // and native implementations vary on the exact spacing used in pretty printing. + // returns: + // A JSON string serialization of the passed-in object. + // example: + // simple serialization of a trivial object + // | var jsonStr = dojo.toJson({ howdy: "stranger!", isStrange: true }); + // | doh.is('{"howdy":"stranger!","isStrange":true}', jsonStr); + // example: + // a custom serializer for an objects of a particular class: + // | dojo.declare("Furby", null, { + // | furbies: "are strange", + // | furbyCount: 10, + // | __json__: function(){ + // | }, + // | }); + + // use dojo/json + return json.stringify(it, function(key, value){ + if(value){ + var tf = value.__json__||value.json; + if(typeof tf == "function"){ + return tf.call(value); + } + } + return value; + }, prettyPrint && dojo.toJsonIndentStr); // String +}; + +return dojo; +}); + +}, +'dojo/request/watch':function(){ +define([ + './util', + '../errors/RequestTimeoutError', + '../errors/CancelError', + '../_base/array', + '../_base/window', + '../has!host-browser?dom-addeventlistener?:../on:' +], function(util, RequestTimeoutError, CancelError, array, win, on){ + // avoid setting a timer per request. It degrades performance on IE + // something fierece if we don't use unified loops. + var _inFlightIntvl = null, + _inFlight = []; + + function watchInFlight(){ + // summary: + // internal method that checks each inflight XMLHttpRequest to see + // if it has completed or if the timeout situation applies. + + var now = +(new Date); + + // we need manual loop because we often modify _inFlight (and therefore 'i') while iterating + for(var i = 0, dfd; i < _inFlight.length && (dfd = _inFlight[i]); i++){ + var response = dfd.response, + options = response.options; + if((dfd.isCanceled && dfd.isCanceled()) || (dfd.isValid && !dfd.isValid(response))){ + _inFlight.splice(i--, 1); + watch._onAction && watch._onAction(); + }else if(dfd.isReady && dfd.isReady(response)){ + _inFlight.splice(i--, 1); + dfd.handleResponse(response); + watch._onAction && watch._onAction(); + }else if(dfd.startTime){ + // did we timeout? + if(dfd.startTime + (options.timeout || 0) < now){ + _inFlight.splice(i--, 1); + // Cancel the request so the io module can do appropriate cleanup. + dfd.cancel(new RequestTimeoutError('Timeout exceeded', response)); + watch._onAction && watch._onAction(); + } + } + } + + watch._onInFlight && watch._onInFlight(dfd); + + if(!_inFlight.length){ + clearInterval(_inFlightIntvl); + _inFlightIntvl = null; + } + } + + function watch(dfd){ + // summary: + // Watches the io request represented by dfd to see if it completes. + // dfd: Deferred + // The Deferred object to watch. + // response: Object + // The object used as the value of the request promise. + // validCheck: Function + // Function used to check if the IO request is still valid. Gets the dfd + // object as its only argument. + // ioCheck: Function + // Function used to check if basic IO call worked. Gets the dfd + // object as its only argument. + // resHandle: Function + // Function used to process response. Gets the dfd + // object as its only argument. + if(dfd.response.options.timeout){ + dfd.startTime = +(new Date); + } + + if(dfd.isFulfilled()){ + // bail out if the deferred is already fulfilled + return; + } + + _inFlight.push(dfd); + if(!_inFlightIntvl){ + _inFlightIntvl = setInterval(watchInFlight, 50); + } + + // handle sync requests separately from async: + // http://bugs.dojotoolkit.org/ticket/8467 + if(dfd.response.options.sync){ + watchInFlight(); + } + } + + watch.cancelAll = function cancelAll(){ + // summary: + // Cancels all pending IO requests, regardless of IO type + try{ + array.forEach(_inFlight, function(dfd){ + try{ + dfd.cancel(new CancelError('All requests canceled.')); + }catch(e){} + }); + }catch(e){} + }; + + if(win && on && win.doc.attachEvent){ + // Automatically call cancel all io calls on unload in IE + // http://bugs.dojotoolkit.org/ticket/2357 + on(win.global, 'unload', function(){ + watch.cancelAll(); + }); + } + + return watch; +}); + +}, +'dojo/request/util':function(){ +define([ + 'exports', + '../errors/RequestError', + '../errors/CancelError', + '../Deferred', + '../io-query', + '../_base/array', + '../_base/lang', + '../promise/Promise', + '../has' +], function(exports, RequestError, CancelError, Deferred, ioQuery, array, lang, Promise, has){ + + function isArrayBuffer(value) { + return has('native-arraybuffer') && value instanceof ArrayBuffer + } + + function isBlob(value) { + return has('native-blob') && value instanceof Blob + } + + function isElement(value) { + if(typeof Element !== 'undefined') { //all other + return value instanceof Element; + } + + //IE<=7 + return value.nodeType === 1; + } + + function isFormData(value) { + return has('native-formdata') && value instanceof FormData; + } + + function shouldDeepCopy(value) { + return value && + typeof value === 'object' && + !isFormData(value) && + !isElement(value) && + !isBlob(value) && + !isArrayBuffer(value) + } + + exports.deepCopy = function(target, source) { + for (var name in source) { + var tval = target[name], + sval = source[name]; + if (name !== '__proto__' && tval !== sval) { + if (shouldDeepCopy(sval)) { + if (Object.prototype.toString.call(sval) === '[object Date]') { // use this date test to handle crossing frame boundaries + target[name] = new Date(sval); + } else if (lang.isArray(sval)) { + target[name] = exports.deepCopyArray(sval); + } else { + if (tval && typeof tval === 'object') { + exports.deepCopy(tval, sval); + } else { + target[name] = exports.deepCopy({}, sval); + } + } + } else { + target[name] = sval; + } + } + } + return target; + }; + + exports.deepCopyArray = function(source) { + var clonedArray = []; + for (var i = 0, l = source.length; i < l; i++) { + var svalItem = source[i]; + if (typeof svalItem === 'object') { + clonedArray.push(exports.deepCopy({}, svalItem)); + } else { + clonedArray.push(svalItem); + } + } + + return clonedArray; + }; + + exports.deepCreate = function deepCreate(source, properties){ + properties = properties || {}; + var target = lang.delegate(source), + name, value; + + for(name in source){ + value = source[name]; + + if(value && typeof value === 'object'){ + target[name] = exports.deepCreate(value, properties[name]); + } + } + return exports.deepCopy(target, properties); + }; + + var freeze = Object.freeze || function(obj){ return obj; }; + function okHandler(response){ + return freeze(response); + } + function dataHandler (response) { + return response.data !== undefined ? response.data : response.text; + } + + exports.deferred = function deferred(response, cancel, isValid, isReady, handleResponse, last){ + var def = new Deferred(function(reason){ + cancel && cancel(def, response); + + if(!reason || !(reason instanceof RequestError) && !(reason instanceof CancelError)){ + return new CancelError('Request canceled', response); + } + return reason; + }); + + def.response = response; + def.isValid = isValid; + def.isReady = isReady; + def.handleResponse = handleResponse; + + function errHandler(error){ + error.response = response; + throw error; + } + var responsePromise = def.then(okHandler).otherwise(errHandler); + + if(exports.notify){ + responsePromise.then( + lang.hitch(exports.notify, 'emit', 'load'), + lang.hitch(exports.notify, 'emit', 'error') + ); + } + + var dataPromise = responsePromise.then(dataHandler); + + // http://bugs.dojotoolkit.org/ticket/16794 + // The following works around a leak in IE9 through the + // prototype using lang.delegate on dataPromise and + // assigning the result a property with a reference to + // responsePromise. + var promise = new Promise(); + for (var prop in dataPromise) { + if (dataPromise.hasOwnProperty(prop)) { + promise[prop] = dataPromise[prop]; + } + } + promise.response = responsePromise; + freeze(promise); + // End leak fix + + + if(last){ + def.then(function(response){ + last.call(def, response); + }, function(error){ + last.call(def, response, error); + }); + } + + def.promise = promise; + def.then = promise.then; + + return def; + }; + + exports.addCommonMethods = function addCommonMethods(provider, methods){ + array.forEach(methods||['GET', 'POST', 'PUT', 'DELETE'], function(method){ + provider[(method === 'DELETE' ? 'DEL' : method).toLowerCase()] = function(url, options){ + options = lang.delegate(options||{}); + options.method = method; + return provider(url, options); + }; + }); + }; + + exports.parseArgs = function parseArgs(url, options, skipData){ + var data = options.data, + query = options.query; + + if(data && !skipData){ + if(typeof data === 'object' && (!(has('native-xhr2')) || !(isArrayBuffer(data) || isBlob(data) ))){ + options.data = ioQuery.objectToQuery(data); + } + } + + if(query){ + if(typeof query === 'object'){ + query = ioQuery.objectToQuery(query); + } + if(options.preventCache){ + query += (query ? '&' : '') + 'request.preventCache=' + (+(new Date)); + } + }else if(options.preventCache){ + query = 'request.preventCache=' + (+(new Date)); + } + + if(url && query){ + url += (~url.indexOf('?') ? '&' : '?') + query; + } + + return { + url: url, + options: options, + getHeader: function(headerName){ return null; } + }; + }; + + exports.checkStatus = function(stat){ + stat = stat || 0; + return (stat >= 200 && stat < 300) || // allow any 2XX response code + stat === 304 || // or, get it out of the cache + stat === 1223 || // or, Internet Explorer mangled the status code + !stat; // or, we're Titanium/browser chrome/chrome extension requesting a local file + }; +}); + +}, +'dojo/errors/RequestError':function(){ +define(['./create'], function(create){ + // module: + // dojo/errors/RequestError + + /*===== + return function(){ + // summary: + // TODOC + }; + =====*/ + + return create("RequestError", function(message, response){ + this.response = response; + }); +}); + +}, +'dojo/errors/RequestTimeoutError':function(){ +define(['./create', './RequestError'], function(create, RequestError){ + // module: + // dojo/errors/RequestTimeoutError + + /*===== + return function(){ + // summary: + // TODOC + }; + =====*/ + + return create("RequestTimeoutError", null, RequestError, { + dojoType: "timeout" + }); +}); + +}, +'dojo/request/xhr':function(){ +define([ + '../errors/RequestError', + './watch', + './handlers', + './util', + '../has'/*=====, + '../request', + '../_base/declare' =====*/ +], function(RequestError, watch, handlers, util, has/*=====, request, declare =====*/){ + has.add('native-xhr', function(){ + // if true, the environment has a native XHR implementation + return typeof XMLHttpRequest !== 'undefined'; + }); + has.add('dojo-force-activex-xhr', function(){ + return has('activex') && window.location.protocol === 'file:'; + }); + + has.add('native-xhr2', function(){ + if(!has('native-xhr') || has('dojo-force-activex-xhr')){ return; } + var x = new XMLHttpRequest(); + return typeof x['addEventListener'] !== 'undefined' && + (typeof opera === 'undefined' || typeof x['upload'] !== 'undefined'); + }); + + has.add('native-formdata', function(){ + // if true, the environment has a native FormData implementation + return typeof FormData !== 'undefined'; + }); + + has.add('native-blob', function(){ + // if true, the environment has a native Blob implementation + return typeof Blob !== 'undefined'; + }); + + has.add('native-arraybuffer', function(){ + // if true, the environment has a native ArrayBuffer implementation + return typeof ArrayBuffer !== 'undefined'; + }); + + has.add('native-response-type', function(){ + return has('native-xhr') && typeof new XMLHttpRequest().responseType !== 'undefined'; + }); + + has.add('native-xhr2-blob', function(){ + if(!has('native-response-type')){ return; } + var x = new XMLHttpRequest(); + // The URL used here does not have to be reachable as the XHR's `send` method is never called. + // It does need to be parsable/resolvable in all cases, so it should be an absolute URL. + // XMLHttpRequest within a Worker created from a Blob does not support relative URL paths. + x.open('GET', 'https://dojotoolkit.org/', true); + x.responseType = 'blob'; + // will not be set if unsupported + var responseType = x.responseType; + x.abort(); + return responseType === 'blob'; + }); + + // Google Chrome doesn't support "json" response type + // up to version 30, so it's intentionally not included here + var nativeResponseTypes = { + 'blob': has('native-xhr2-blob') ? 'blob' : 'arraybuffer', + 'document': 'document', + 'arraybuffer': 'arraybuffer' + }; + + function handleResponse(response, error){ + var _xhr = response.xhr; + response.status = response.xhr.status; + + try { + // Firefox throws an error when trying to access + // xhr.responseText if response isn't text + response.text = _xhr.responseText; + } catch (e) {} + + if(response.options.handleAs === 'xml'){ + response.data = _xhr.responseXML; + } + + var handleError; + if(error){ + this.reject(error); + }else{ + try{ + handlers(response); + }catch(e){ + handleError = e; + } + if(util.checkStatus(_xhr.status)){ + if(!handleError){ + this.resolve(response); + }else{ + this.reject(handleError); + } + }else{ + if(!handleError){ + error = new RequestError('Unable to load ' + response.url + ' status: ' + _xhr.status, response); + this.reject(error); + }else{ + error = new RequestError('Unable to load ' + response.url + ' status: ' + _xhr.status + + ' and an error in handleAs: transformation of response', response); + this.reject(error); + } + } + } + } + + var isValid, isReady, addListeners, cancel; + if(has('native-xhr2')){ + // Any platform with XHR2 will only use the watch mechanism for timeout. + + isValid = function(response){ + // summary: + // Check to see if the request should be taken out of the watch queue + return !this.isFulfilled(); + }; + cancel = function(dfd, response){ + // summary: + // Canceler for deferred + response.xhr.abort(); + }; + addListeners = function(_xhr, dfd, response, uploadProgress){ + // summary: + // Adds event listeners to the XMLHttpRequest object + function onLoad(evt){ + dfd.handleResponse(response); + } + function onError(evt){ + var _xhr = evt.target; + var error = new RequestError('Unable to load ' + response.url + ' status: ' + _xhr.status, response); + dfd.handleResponse(response, error); + } + + function onProgress(transferType, evt){ + response.transferType = transferType; + if(evt.lengthComputable){ + response.loaded = evt.loaded; + response.total = evt.total; + dfd.progress(response); + } else if(response.xhr.readyState === 3){ + response.loaded = ('loaded' in evt) ? evt.loaded : evt.position; + dfd.progress(response); + } + } + + function onDownloadProgress(evt) { + return onProgress('download', evt); + } + + function onUploadProgress(evt) { + return onProgress('upload', evt); + } + + _xhr.addEventListener('load', onLoad, false); + _xhr.addEventListener('error', onError, false); + _xhr.addEventListener('progress', onDownloadProgress, false); + + if (uploadProgress && _xhr.upload) { + _xhr.upload.addEventListener('progress', onUploadProgress, false); + } + + return function(){ + _xhr.removeEventListener('load', onLoad, false); + _xhr.removeEventListener('error', onError, false); + _xhr.removeEventListener('progress', onDownloadProgress, false); + _xhr.upload.removeEventListener('progress', onUploadProgress, false); + _xhr = null; + }; + }; + }else{ + isValid = function(response){ + return response.xhr.readyState; //boolean + }; + isReady = function(response){ + return 4 === response.xhr.readyState; //boolean + }; + cancel = function(dfd, response){ + // summary: + // canceller function for util.deferred call. + var xhr = response.xhr; + var _at = typeof xhr.abort; + if(_at === 'function' || _at === 'object' || _at === 'unknown'){ + xhr.abort(); + } + }; + } + + function getHeader(headerName){ + return this.xhr.getResponseHeader(headerName); + } + + var undefined, + defaultOptions = { + data: null, + query: null, + sync: false, + method: 'GET' + }; + function xhr(url, options, returnDeferred){ + var isFormData = has('native-formdata') && options && options.data && options.data instanceof FormData; + var response = util.parseArgs( + url, + util.deepCreate(defaultOptions, options), + isFormData + ); + url = response.url; + options = response.options; + var hasNoData = !options.data && options.method !== 'POST' && options.method !== 'PUT'; + + if(has('ie') <= 10){ + // older IE breaks point 9 in http://www.w3.org/TR/XMLHttpRequest/#the-open()-method and sends fragment, so strip it + url = url.split('#')[0]; + } + + var remover, + last = function(){ + remover && remover(); + }; + + //Make the Deferred object for this xhr request. + var dfd = util.deferred( + response, + cancel, + isValid, + isReady, + handleResponse, + last + ); + var _xhr = response.xhr = xhr._create(); + + if(!_xhr){ + // If XHR factory somehow returns nothings, + // cancel the deferred. + dfd.cancel(new RequestError('XHR was not created')); + return returnDeferred ? dfd : dfd.promise; + } + + response.getHeader = getHeader; + + if(addListeners){ + remover = addListeners(_xhr, dfd, response, options.uploadProgress); + } + + // IE11 treats data: undefined different than other browsers + var data = typeof(options.data) === 'undefined' ? null : options.data, + async = !options.sync, + method = options.method; + + try{ + // IE6 won't let you call apply() on the native function. + _xhr.open(method, url, async, options.user || undefined, options.password || undefined); + + if(options.withCredentials){ + _xhr.withCredentials = options.withCredentials; + } + + if(has('native-response-type') && options.handleAs in nativeResponseTypes) { + _xhr.responseType = nativeResponseTypes[options.handleAs]; + } + + var headers = options.headers, + contentType = (isFormData || hasNoData) ? false : 'application/x-www-form-urlencoded'; + if(headers){ + for(var hdr in headers){ + if(hdr.toLowerCase() === 'content-type'){ + contentType = headers[hdr]; + }else if(headers[hdr]){ + //Only add header if it has a value. This allows for instance, skipping + //insertion of X-Requested-With by specifying empty value. + _xhr.setRequestHeader(hdr, headers[hdr]); + } + } + } + + if(contentType && contentType !== false){ + _xhr.setRequestHeader('Content-Type', contentType); + } + if(!headers || !('X-Requested-With' in headers)){ + _xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); + } + + if(util.notify){ + util.notify.emit('send', response, dfd.promise.cancel); + } + _xhr.send(data); + }catch(e){ + dfd.reject(e); + } + + watch(dfd); + _xhr = null; + + return returnDeferred ? dfd : dfd.promise; + } + + /*===== + xhr = function(url, options){ + // summary: + // Sends a request using XMLHttpRequest with the given URL and options. + // url: String + // URL to request + // options: dojo/request/xhr.__Options? + // Options for the request. + // returns: dojo/request.__Promise + }; + xhr.__BaseOptions = declare(request.__BaseOptions, { + // sync: Boolean? + // Whether to make a synchronous request or not. Default + // is `false` (asynchronous). + // data: String|Object|FormData? + // Data to transfer. This is ignored for GET and DELETE + // requests. + // headers: Object? + // Headers to use for the request. + // user: String? + // Username to use during the request. + // password: String? + // Password to use during the request. + // withCredentials: Boolean? + // For cross-site requests, whether to send credentials + // or not. + // uploadProgress: Boolean? + // Upload progress events cause preflighted requests. This + // option enables upload progress event support but also + // causes all requests to be preflighted. + }); + xhr.__MethodOptions = declare(null, { + // method: String? + // The HTTP method to use to make the request. Must be + // uppercase. Default is `"GET"`. + }); + xhr.__Options = declare([xhr.__BaseOptions, xhr.__MethodOptions]); + + xhr.get = function(url, options){ + // summary: + // Send an HTTP GET request using XMLHttpRequest with the given URL and options. + // url: String + // URL to request + // options: dojo/request/xhr.__BaseOptions? + // Options for the request. + // returns: dojo/request.__Promise + }; + xhr.post = function(url, options){ + // summary: + // Send an HTTP POST request using XMLHttpRequest with the given URL and options. + // url: String + // URL to request + // options: dojo/request/xhr.__BaseOptions? + // Options for the request. + // returns: dojo/request.__Promise + }; + xhr.put = function(url, options){ + // summary: + // Send an HTTP PUT request using XMLHttpRequest with the given URL and options. + // url: String + // URL to request + // options: dojo/request/xhr.__BaseOptions? + // Options for the request. + // returns: dojo/request.__Promise + }; + xhr.del = function(url, options){ + // summary: + // Send an HTTP DELETE request using XMLHttpRequest with the given URL and options. + // url: String + // URL to request + // options: dojo/request/xhr.__BaseOptions? + // Options for the request. + // returns: dojo/request.__Promise + }; + =====*/ + xhr._create = function(){ + // summary: + // does the work of portably generating a new XMLHTTPRequest object. + throw new Error('XMLHTTP not available'); + }; + if(has('native-xhr') && !has('dojo-force-activex-xhr')){ + xhr._create = function(){ + return new XMLHttpRequest(); + }; + }else if(has('activex')){ + try{ + new ActiveXObject('Msxml2.XMLHTTP'); + xhr._create = function(){ + return new ActiveXObject('Msxml2.XMLHTTP'); + }; + }catch(e){ + try{ + new ActiveXObject('Microsoft.XMLHTTP'); + xhr._create = function(){ + return new ActiveXObject('Microsoft.XMLHTTP'); + }; + }catch(e){} + } + } + + util.addCommonMethods(xhr); + + return xhr; +}); + +}, +'dojo/request/handlers':function(){ +define([ + '../json', + '../_base/kernel', + '../_base/array', + '../has', + '../selector/_loader' // only included for has() qsa tests +], function(JSON, kernel, array, has){ + has.add('activex', typeof ActiveXObject !== 'undefined'); + has.add('dom-parser', function(global){ + return 'DOMParser' in global; + }); + + var handleXML; + if(has('activex')){ + // GUIDs obtained from http://msdn.microsoft.com/en-us/library/ms757837(VS.85).aspx + var dp = [ + 'Msxml2.DOMDocument.6.0', + 'Msxml2.DOMDocument.4.0', + 'MSXML2.DOMDocument.3.0', + 'MSXML.DOMDocument' // 2.0 + ]; + var lastParser; + + handleXML = function(response){ + var result = response.data; + var text = response.text; + + if(result && has('dom-qsa2.1') && !result.querySelectorAll && has('dom-parser')){ + // http://bugs.dojotoolkit.org/ticket/15631 + // IE9 supports a CSS3 querySelectorAll implementation, but the DOM implementation + // returned by IE9 xhr.responseXML does not. Manually create the XML DOM to gain + // the fuller-featured implementation and avoid bugs caused by the inconsistency + result = new DOMParser().parseFromString(text, 'application/xml'); + } + + function createDocument(p) { + try{ + var dom = new ActiveXObject(p); + dom.async = false; + dom.loadXML(text); + result = dom; + lastParser = p; + }catch(e){ return false; } + return true; + } + + if(!result || !result.documentElement){ + // The creation of an ActiveX object is expensive, so we cache the + // parser type to avoid trying all parser types each time we handle a + // document. There is some concern that some parser types might fail + // depending on the document being parsed. If parsing using the cached + // parser type fails, we do the more expensive operation of finding one + // that works for the given document. + // https://bugs.dojotoolkit.org/ticket/15246 + if(!lastParser || !createDocument(lastParser)) { + array.some(dp, createDocument); + } + } + + return result; + }; + } + + var handleNativeResponse = function(response) { + if(!has('native-xhr2-blob') && response.options.handleAs === 'blob' && typeof Blob !== 'undefined'){ + return new Blob([ response.xhr.response ], { type: response.xhr.getResponseHeader('Content-Type') }); + } + + return response.xhr.response; + } + + var handlers = { + 'javascript': function(response){ + return kernel.eval(response.text || ''); + }, + 'json': function(response){ + return JSON.parse(response.text || null); + }, + 'xml': handleXML, + 'blob': handleNativeResponse, + 'arraybuffer': handleNativeResponse, + 'document': handleNativeResponse + }; + + function handle(response){ + var handler = handlers[response.options.handleAs]; + + response.data = handler ? handler(response) : (response.data || response.text); + + return response; + } + + handle.register = function(name, handler){ + handlers[name] = handler; + }; + + return handle; +}); + +}, +'dojo/selector/_loader':function(){ +define(["../has", "require"], + function(has, require){ + +"use strict"; +if (typeof document !== "undefined") { + var testDiv = document.createElement("div"); + has.add("dom-qsa2.1", !!testDiv.querySelectorAll); + has.add("dom-qsa3", function(){ + // test to see if we have a reasonable native selector engine available + try{ + testDiv.innerHTML = "

"; // test kind of from sizzle + // Safari can't handle uppercase or unicode characters when + // in quirks mode, IE8 can't handle pseudos like :empty + return testDiv.querySelectorAll(".TEST:empty").length == 1; + }catch(e){} + }); +} + +var fullEngine; +var acme = "./acme", lite = "./lite"; +return { + // summary: + // This module handles loading the appropriate selector engine for the given browser + + load: function(id, parentRequire, loaded, config){ + if (config && config.isBuild) { + //Indicate that the optimizer should not wait + //for this resource any more and complete optimization. + //This resource will be resolved dynamically during + //run time in the web browser. + loaded(); + return; + } + + var req = require; + // here we implement the default logic for choosing a selector engine + id = id == "default" ? has("config-selectorEngine") || "css3" : id; + id = id == "css2" || id == "lite" ? lite : + id == "css2.1" ? has("dom-qsa2.1") ? lite : acme : + id == "css3" ? has("dom-qsa3") ? lite : acme : + id == "acme" ? acme : (req = parentRequire) && id; + if(id.charAt(id.length-1) == '?'){ + id = id.substring(0,id.length - 1); + var optionalLoad = true; + } + // the query engine is optional, only load it if a native one is not available or existing one has not been loaded + if(optionalLoad && (has("dom-compliant-qsa") || fullEngine)){ + return loaded(fullEngine); + } + // load the referenced selector engine + req([id], function(engine){ + if(id != "./lite"){ + fullEngine = engine; + } + loaded(engine); + }); + } +}; +}); + +}, +'dojo/main':function(){ +define([ + "./_base/kernel", // kernel.isAsync + "./has", + "require", + "./sniff", + "./_base/lang", + "./_base/array", + "./_base/config", + "./ready", + "./_base/declare", + "./_base/connect", + "./_base/Deferred", + "./_base/json", + "./_base/Color", + "./has!dojo-firebug?./_firebug/firebug", + "./_base/browser", + "./_base/loader" +], function(kernel, has, require, sniff, lang, array, config, ready){ + // module: + // dojo/main + // summary: + // This is the package main module for the dojo package; it loads dojo base appropriate for the execution environment. + + // Load code to fix IE's console + if(config.isDebug){ + require(["./_firebug/firebug"]); + } + + // dojoConfig.require is deprecated; use the loader configuration property deps + 1 || has.add("dojo-config-require", 1); + if( 1 ){ + var deps= config.require; + if(deps){ + // config.require may be dot notation + deps= array.map(lang.isArray(deps) ? deps : [deps], function(item){ return item.replace(/\./g, "/"); }); + if(kernel.isAsync){ + require(deps); + }else{ + // this is a bit janky; in 1.6- dojo is defined before these requires are applied; but in 1.7+ + // dojo isn't defined until returning from this module; this is only a problem in sync mode + // since we're in sync mode, we know we've got our loader with its priority ready queue + ready(1, function(){require(deps);}); + } + } + } + + return kernel; +}); + +}, +'dojo/ready':function(){ +define(["./_base/kernel", "./has", "require", "./domReady", "./_base/lang"], function(dojo, has, require, domReady, lang){ + // module: + // dojo/ready + // note: + // This module should be unnecessary in dojo 2.0 + + var + // truthy if DOMContentLoaded or better (e.g., window.onload fired) has been achieved + isDomReady = 0, + + // The queue of functions waiting to execute as soon as dojo.ready conditions satisfied + loadQ = [], + + // prevent recursion in onLoad + onLoadRecursiveGuard = 0, + + handleDomReady = function(){ + isDomReady = 1; + dojo._postLoad = dojo.config.afterOnLoad = true; + onEvent(); + }, + + onEvent = function(){ + // Called when some state changes: + // - dom ready + // - dojo/domReady has finished processing everything in its queue + // - task added to loadQ + // - require() has finished loading all currently requested modules + // + // Run the functions queued with dojo.ready if appropriate. + + + //guard against recursions into this function + if(onLoadRecursiveGuard){ + return; + } + onLoadRecursiveGuard = 1; + + // Run tasks in queue if require() is finished loading modules, the dom is ready, and there are no + // pending tasks registered via domReady(). + // The last step is necessary so that a user defined dojo.ready() callback is delayed until after the + // domReady() calls inside of dojo. Failure can be seen on dijit/tests/robot/Dialog_ally.html on IE8 + // because the dijit/focus.js domReady() callback doesn't execute until after the test starts running. + while(isDomReady && (!domReady || domReady._Q.length == 0) && (require.idle ? require.idle() : true) && loadQ.length){ + var f = loadQ.shift(); + try{ + f(); + }catch(e){ + // force the dojo.js on("error") handler do display the message + e.info = e.message; + if(require.signal){ + require.signal("error", e); + }else{ + throw e; + } + } + } + + onLoadRecursiveGuard = 0; + }; + + // Check if we should run the next queue operation whenever require() finishes loading modules or domReady + // finishes processing it's queue. + require.on && require.on("idle", onEvent); + if(domReady){ + domReady._onQEmpty = onEvent; + } + + var ready = dojo.ready = dojo.addOnLoad = function(priority, context, callback){ + // summary: + // Add a function to execute on DOM content loaded and all requested modules have arrived and been evaluated. + // In most cases, the `domReady` plug-in should suffice and this method should not be needed. + // + // When called in a non-browser environment, just checks that all requested modules have arrived and been + // evaluated. + // priority: Integer? + // The order in which to exec this callback relative to other callbacks, defaults to 1000 + // context: Object?|Function + // The context in which to run execute callback, or a callback if not using context + // callback: Function? + // The function to execute. + // + // example: + // Simple DOM and Modules ready syntax + // | require(["dojo/ready"], function(ready){ + // | ready(function(){ alert("Dom ready!"); }); + // | }); + // + // example: + // Using a priority + // | require(["dojo/ready"], function(ready){ + // | ready(2, function(){ alert("low priority ready!"); }) + // | }); + // + // example: + // Using context + // | require(["dojo/ready"], function(ready){ + // | ready(foo, function(){ + // | // in here, this == foo + // | }); + // | }); + // + // example: + // Using dojo/hitch style args: + // | require(["dojo/ready"], function(ready){ + // | var foo = { dojoReady: function(){ console.warn(this, "dojo dom and modules ready."); } }; + // | ready(foo, "dojoReady"); + // | }); + + var hitchArgs = lang._toArray(arguments); + if(typeof priority != "number"){ + callback = context; + context = priority; + priority = 1000; + }else{ + hitchArgs.shift(); + } + callback = callback ? + lang.hitch.apply(dojo, hitchArgs) : + function(){ + context(); + }; + callback.priority = priority; + for(var i = 0; i < loadQ.length && priority >= loadQ[i].priority; i++){} + loadQ.splice(i, 0, callback); + onEvent(); + }; + + 1 || has.add("dojo-config-addOnLoad", 1); + if( 1 ){ + var dca = dojo.config.addOnLoad; + if(dca){ + ready[(lang.isArray(dca) ? "apply" : "call")](dojo, dca); + } + } + + if( 1 && dojo.config.parseOnLoad && !dojo.isAsync){ + ready(99, function(){ + if(!dojo.parser){ + dojo.deprecated("Add explicit require(['dojo/parser']);", "", "2.0"); + require(["dojo/parser"]); + } + }); + } + + if(domReady){ + domReady(handleDomReady); + }else{ + handleDomReady(); + } + + return ready; +}); + +}, +'dojo/domReady':function(){ +define(['./global', './has'], function(global, has){ + var doc = document, + readyStates = { 'loaded': 1, 'complete': 1 }, + fixReadyState = typeof doc.readyState != "string", + ready = !!readyStates[doc.readyState], + readyQ = [], + recursiveGuard; + + function domReady(callback){ + // summary: + // Plugin to delay require()/define() callback from firing until the DOM has finished loading. + readyQ.push(callback); + if(ready){ processQ(); } + } + domReady.load = function(id, req, load){ + domReady(load); + }; + + // Export queue so that ready() can check if it's empty or not. + domReady._Q = readyQ; + domReady._onQEmpty = function(){ + // summary: + // Private method overridden by dojo/ready, to notify when everything in the + // domReady queue has been processed. Do not use directly. + // Will be removed in 2.0, along with domReady._Q. + }; + + // For FF <= 3.5 + if(fixReadyState){ doc.readyState = "loading"; } + + function processQ(){ + // Calls all functions in the queue in order, unless processQ() is already running, in which case just return + + if(recursiveGuard){ return; } + recursiveGuard = true; + + while(readyQ.length){ + try{ + (readyQ.shift())(doc); + }catch(err){ + console.error(err, "in domReady callback", err.stack); + } + } + + recursiveGuard = false; + + // Notification for dojo/ready. Remove for 2.0. + // Note that this could add more tasks to the ready queue. + domReady._onQEmpty(); + } + + if(!ready){ + var tests = [], + detectReady = function(evt){ + evt = evt || global.event; + if(ready || (evt.type == "readystatechange" && !readyStates[doc.readyState])){ return; } + + // For FF <= 3.5 + if(fixReadyState){ doc.readyState = "complete"; } + + ready = 1; + processQ(); + }, + on = function(node, event){ + node.addEventListener(event, detectReady, false); + readyQ.push(function(){ node.removeEventListener(event, detectReady, false); }); + }; + + if(!has("dom-addeventlistener")){ + on = function(node, event){ + event = "on" + event; + node.attachEvent(event, detectReady); + readyQ.push(function(){ node.detachEvent(event, detectReady); }); + }; + + var div = doc.createElement("div"); + try{ + if(div.doScroll && global.frameElement === null){ + // the doScroll test is only useful if we're in the top-most frame + tests.push(function(){ + // Derived with permission from Diego Perini's IEContentLoaded + // http://javascript.nwbox.com/IEContentLoaded/ + try{ + div.doScroll("left"); + return 1; + }catch(e){} + }); + } + }catch(e){} + } + + on(doc, "DOMContentLoaded"); + on(global, "load"); + + if("onreadystatechange" in doc){ + on(doc, "readystatechange"); + }else if(!fixReadyState){ + // if the ready state property exists and there's + // no readystatechange event, poll for the state + // to change + tests.push(function(){ + return readyStates[doc.readyState]; + }); + } + + if(tests.length){ + var poller = function(){ + if(ready){ return; } + var i = tests.length; + while(i--){ + if(tests[i]()){ + detectReady("poller"); + return; + } + } + setTimeout(poller, 30); + }; + poller(); + } + } + + return domReady; +}); + +}, +'dojo/_base/declare':function(){ +define(["./kernel", "../has", "./lang"], function(dojo, has, lang){ + // module: + // dojo/_base/declare + + var mix = lang.mixin, op = Object.prototype, opts = op.toString, + xtor, counter = 0, cname = "constructor"; + + if(!has("csp-restrictions")){ + // 'new Function()' is preferable when available since it does not create a closure + xtor = new Function; + }else{ + xtor = function(){}; + } + + 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, g){ + 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 = g; + } + + if(typeof args === "function"){ + // support strict mode + caller = args; + args = a; + a = f; + }else{ + try{ + caller = args.callee; + }catch (e){ + if(e instanceof TypeError){ + // caller was defined in a strict-mode context + err("strict mode inherited() requires the caller function to be passed before arguments", this.declaredClass); + }else{ + throw e; + } + } + } + + name = name || caller.nom; + if(!name){ + err("can't deduce a name to call inherited()", this.declaredClass); + } + f = g = 0; + + 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 no return if a super method was not found + } + + function getInherited(name, args, a){ + if(typeof name === "string"){ + if (typeof args === "function") { + return this.__inherited(name, args, a, true); + } + return this.__inherited(name, args, true); + } + else if (typeof name === "function") { + return this.__inherited(name, args, true); + } + return this.__inherited(name, true); + } + + function inherited__debug(args, a1, a2, a3){ + var f = this.getInherited(args, a1, a2); + if(f){ + return f.apply(this, a3 || a2 || a1 || args); + } + // intentionally no return if a super method was not found + } + + var inheritedImpl = dojo.config.isDebug ? inherited__debug : inherited; + + // 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){ + // add props adding metadata for incoming functions skipping a constructor + for(var name in source){ + if(name != cname && source.hasOwnProperty(name)){ + target[name] = source[name]; + } + } + if(has("bug-for-in-skips-shadowed")){ + for(var extraNames= lang._extraNames, i= extraNames.length; i;){ + name = extraNames[--i]; + if(name != cname && source.hasOwnProperty(name)){ + target[name] = source[name]; + } + } + } + } + + // implementation of safe mixin function + function safeMixin(target, source){ + // summary: + // Mix in properties skipping a constructor and decorating functions + // like it is done by 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 lang.mixin does, + // but it skips a constructor property and decorates functions like + // declare() does. + // + // It is meant to be used with classes and objects produced with + // 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 declare(). + // + // example: + // | var A = declare(null, { + // | m1: function(){ + // | console.log("A.m1"); + // | }, + // | m2: function(){ + // | console.log("A.m2"); + // | } + // | }); + // | var B = 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 + + var name, t; + // 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; + } + } + if(has("bug-for-in-skips-shadowed") && source){ + for(var extraNames= lang._extraNames, i= extraNames.length; i;){ + name = 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){ + declare.safeMixin(this.prototype, source); + return this; + } + + function createSubclass(mixins, props){ + // crack parameters + if(!(mixins instanceof Array || typeof mixins === 'function')){ + props = mixins; + mixins = undefined; + } + + props = props || {}; + mixins = mixins || []; + + return declare([this].concat(mixins), props); + } + + // chained constructor compatible with the legacy 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 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 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 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 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; + } + + function declare(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: dojo/_base/declare.__DeclareCreatedObject + // 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 + // 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 + // 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: + // | 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 = declare(null, { + // | // constructor, properties, and methods go here + // | // ... + // | }); + // | var MyClass1 = declare(MyBase, { + // | // constructor, properties, and methods go here + // | // ... + // | }); + // | var MyClass2 = declare(MyBase, { + // | // constructor, properties, and methods go here + // | // ... + // | }); + // | var MyDiamond = 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 = 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 = declare(null, { + // | "-chains-": { + // | destroy: "before" + // | } + // | }); + // | var B = declare(A, { + // | constructor: function(){ + // | console.log("B.constructor"); + // | }, + // | destroy: function(){ + // | console.log("B.destroy"); + // | } + // | }); + // | var C = 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 = declare(null, { + // | "-chains-": { + // | constructor: "manual" + // | } + // | }); + // | var B = declare(A, { + // | constructor: function(){ + // | // ... + // | // call the base constructor with new parameters + // | this.inherited(arguments, [1, 2, 3]); + // | // ... + // | } + // | }); + // + // example: + // | var A = declare(null, { + // | "-chains-": { + // | m1: "before" + // | }, + // | m1: function(){ + // | console.log("A.m1"); + // | }, + // | m2: function(){ + // | console.log("A.m2"); + // | } + // | }); + // | var B = 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 + + // 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 + if (has("csp-restrictions")) { + ctor = function () {}; + } + else { + ctor = new Function; + } + ctor.superclass = superclass; + ctor.prototype = proto; + superclass = proto.constructor = ctor; + } + }else{ + proto = {}; + } + // add all properties + declare.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-"]); + } + + if(superclass && superclass.prototype && superclass.prototype["-chains-"]) { + chains = mix(chains || {}, superclass.prototype["-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.createSubclass = createSubclass; + ctor.prototype = proto; + proto.constructor = ctor; + + // add "standard" methods to the prototype + proto.getInherited = getInherited; + proto.isInstanceOf = isInstanceOf; + proto.inherited = inheritedImpl; + proto.__inherited = inherited; + + // add name if specified + if(className){ + proto.declaredClass = className; + lang.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 + } + + /*===== + declare.__DeclareCreatedObject = { + // summary: + // dojo/_base/declare() returns a constructor `C`. `new C()` returns an Object with the following + // methods, in addition to the methods and properties specified via the arguments passed to declare(). + + inherited: function(name, caller, 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 + // declare(), and it cannot be determined. + // caller: Function? + // The reference to the calling function. Required only if the + // call to "this.inherited" occurs from within strict-mode code. + // If the caller is omitted within strict-mode code, an error will + // be thrown. + // The best way to obtain a reference to the calling function is to + // use a named function expression (i.e. place a function name + // after the "function" keyword and before the open paren, as in + // "function fn(a, b)"). If the function is parsed as an expression + // and not a statement (i.e. it's not by itself on its own line), + // the function name will only be accessible as an identifier from + // within the body of the function. + // 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 + // 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 = 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 = 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); + // | } + // | }); + // example: + // | "use strict"; + // | // class is defined in strict-mode code, + // | // so caller must be passed before arguments. + // | var B = declare(A, { + // | // using a named function expression with "fn" as the name. + // | method: function fn(a, b) { + // | this.inherited(fn, arguments); + // | } + // | }); + return {}; // Object + }, + + getInherited: function(name, caller, 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 + // declare(), and it cannot be determined. + // caller: Function? + // The caller function. This is required when running in + // strict-mode code. A reference to the caller function + // can be obtained by using a named function expression + // (e.g. function fn(a,b) {...}). + // 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 = 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); + // | } + // | }); + // example: + // | "use strict;" // first line of function or file + // | //... + // | var B = declare(A, { + // | // Using a named function expression with "fn" as the name, + // | // since we're in strict mode. + // | method: function fn(a, b){ + // | var super = this.getInherited(fn, arguments); + // | if(super){ + // | return super.apply(this, arguments); + // | } + // | } + // | }); + return {}; // 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 + // declare() to determine of they support a certain interface or + // not. It models "instanceof" operator. + // + // example: + // | var A = declare(null, { + // | // constructor, properties, and methods go here + // | // ... + // | }); + // | var B = declare(null, { + // | // constructor, properties, and methods go here + // | // ... + // | }); + // | var C = declare([A, B], { + // | // constructor, properties, and methods go here + // | // ... + // | }); + // | var D = 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 + }, + + 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 + // 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 declare(). It is implemented + // using dojo.safeMixin, and it skips a constructor property, + // and properly decorates copied functions. + // + // example: + // | var A = declare(null, { + // | m1: function(){}, + // | s1: "Popokatepetl" + // | }); + // | A.extend({ + // | m1: function(){}, + // | m2: function(){}, + // | f1: true, + // | d1: 42 + // | }); + }, + + createSubclass: function(mixins, props){ + // summary: + // Create a subclass of the declared class from a list of base classes. + // mixins: Function[] + // Specifies a list of bases (the left-most one is the most deepest + // base). + // props: Object? + // An optional object whose properties are copied to the created prototype. + // returns: dojo/_base/declare.__DeclareCreatedObject + // 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. + // + // example: + // | var A = declare(null, { + // | m1: function(){}, + // | s1: "bar" + // | }); + // | var B = declare(null, { + // | m2: function(){}, + // | s2: "foo" + // | }); + // | var C = declare(null, { + // | }); + // | var D1 = A.createSubclass([B, C], { + // | m1: function(){}, + // | d1: 42 + // | }); + // | var d1 = new D1(); + // | + // | // this is equivalent to: + // | var D2 = declare([A, B, C], { + // | m1: function(){}, + // | d1: 42 + // | }); + // | var d2 = new D2(); + } + }; + =====*/ + + // For back-compat, remove for 2.0 + dojo.safeMixin = declare.safeMixin = safeMixin; + dojo.declare = declare; + + return declare; +}); + +}, +'dojo/_base/connect':function(){ +define(["./kernel", "../on", "../topic", "../aspect", "./event", "../mouse", "./sniff", "./lang", "../keys"], function(dojo, on, hub, aspect, eventModule, mouse, has, lang){ +// module: +// dojo/_base/connect + +has.add("events-keypress-typed", function(){ // keypresses should only occur a printable character is hit + var testKeyEvent = {charCode: 0}; + try{ + testKeyEvent = document.createEvent("KeyboardEvent"); + (testKeyEvent.initKeyboardEvent || testKeyEvent.initKeyEvent).call(testKeyEvent, "keypress", true, true, null, false, false, false, false, 9, 3); + }catch(e){} + return testKeyEvent.charCode == 0 && !has("opera"); +}); + +function connect_(obj, event, context, method, dontFix){ + method = lang.hitch(context, method); + if(!obj || !(obj.addEventListener || obj.attachEvent)){ + // it is a not a DOM node and we are using the dojo.connect style of treating a + // method like an event, must go right to aspect + return aspect.after(obj || dojo.global, event, method, true); + } + if(typeof event == "string" && event.substring(0, 2) == "on"){ + event = event.substring(2); + } + if(!obj){ + obj = dojo.global; + } + if(!dontFix){ + switch(event){ + // dojo.connect has special handling for these event types + case "keypress": + event = keypress; + break; + case "mouseenter": + event = mouse.enter; + break; + case "mouseleave": + event = mouse.leave; + break; + } + } + return on(obj, event, method, dontFix); +} + +var _punctMap = { + 106:42, + 111:47, + 186:59, + 187:43, + 188:44, + 189:45, + 190:46, + 191:47, + 192:96, + 219:91, + 220:92, + 221:93, + 222:39, + 229:113 +}; +var evtCopyKey = has("mac") ? "metaKey" : "ctrlKey"; + + +var _synthesizeEvent = function(evt, props){ + var faux = lang.mixin({}, evt, props); + setKeyChar(faux); + // FIXME: would prefer to use lang.hitch: lang.hitch(evt, evt.preventDefault); + // but it throws an error when preventDefault is invoked on Safari + // does Event.preventDefault not support "apply" on Safari? + faux.preventDefault = function(){ evt.preventDefault(); }; + faux.stopPropagation = function(){ evt.stopPropagation(); }; + return faux; +}; +function setKeyChar(evt){ + evt.keyChar = evt.charCode ? String.fromCharCode(evt.charCode) : ''; + evt.charOrCode = evt.keyChar || evt.keyCode; +} +var keypress; +if(has("events-keypress-typed")){ + // this emulates Firefox's keypress behavior where every keydown can correspond to a keypress + var _trySetKeyCode = function(e, code){ + try{ + // squelch errors when keyCode is read-only + // (e.g. if keyCode is ctrl or shift) + return (e.keyCode = code); + }catch(e){ + return 0; + } + }; + keypress = function(object, listener){ + var keydownSignal = on(object, "keydown", function(evt){ + // munge key/charCode + var k=evt.keyCode; + // These are Windows Virtual Key Codes + // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/WinUI/WindowsUserInterface/UserInput/VirtualKeyCodes.asp + var unprintable = (k!=13) && k!=32 && (k!=27||!has("ie")) && (k<48||k>90) && (k<96||k>111) && (k<186||k>192) && (k<219||k>222) && k!=229; + // synthesize keypress for most unprintables and CTRL-keys + if(unprintable||evt.ctrlKey){ + var c = unprintable ? 0 : k; + if(evt.ctrlKey){ + if(k==3 || k==13){ + return listener.call(evt.currentTarget, evt); // IE will post CTRL-BREAK, CTRL-ENTER as keypress natively + }else if(c>95 && c<106){ + c -= 48; // map CTRL-[numpad 0-9] to ASCII + }else if((!evt.shiftKey)&&(c>=65&&c<=90)){ + c += 32; // map CTRL-[A-Z] to lowercase + }else{ + c = _punctMap[c] || c; // map other problematic CTRL combinations to ASCII + } + } + // simulate a keypress event + var faux = _synthesizeEvent(evt, {type: 'keypress', faux: true, charCode: c}); + listener.call(evt.currentTarget, faux); + if(has("ie")){ + _trySetKeyCode(evt, faux.keyCode); + } + } + }); + var keypressSignal = on(object, "keypress", function(evt){ + var c = evt.charCode; + c = c>=32 ? c : 0; + evt = _synthesizeEvent(evt, {charCode: c, faux: true}); + return listener.call(this, evt); + }); + return { + remove: function(){ + keydownSignal.remove(); + keypressSignal.remove(); + } + }; + }; +}else{ + if(has("opera")){ + keypress = function(object, listener){ + return on(object, "keypress", function(evt){ + var c = evt.which; + if(c==3){ + c=99; // Mozilla maps CTRL-BREAK to CTRL-c + } + // can't trap some keys at all, like INSERT and DELETE + // there is no differentiating info between DELETE and ".", or INSERT and "-" + c = c<32 && !evt.shiftKey ? 0 : c; + if(evt.ctrlKey && !evt.shiftKey && c>=65 && c<=90){ + // lowercase CTRL-[A-Z] keys + c += 32; + } + return listener.call(this, _synthesizeEvent(evt, { charCode: c })); + }); + }; + }else{ + keypress = function(object, listener){ + return on(object, "keypress", function(evt){ + setKeyChar(evt); + return listener.call(this, evt); + }); + }; + } +} + +var connect = { + // summary: + // This module defines the dojo.connect API. + // This modules also provides keyboard event handling helpers. + // This module exports an extension event for emulating Firefox's keypress handling. + // However, this extension event exists primarily for backwards compatibility and + // is not recommended. WebKit and IE uses an alternate keypress handling (only + // firing for printable characters, to distinguish from keydown events), and most + // consider the WebKit/IE behavior more desirable. + + _keypress:keypress, + + connect:function(obj, event, context, method, dontFix){ + // summary: + // `dojo.connect` is a deprecated 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, `kernel.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: Object? + // The source object for the event function. + // Defaults to `kernel.global` if null. + // If obj is a DOM node, the connection is delegated + // to the DOM event manager (unless dontFix is true). + // + // event: String + // String name of the event function in obj. + // I.e. identifies a property `obj[event]`. + // + // context: Object|null + // 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, + // kernel.global is used. + // + // method: String|Function + // 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: Boolean? + // 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(typeof a[0] == "string" ? 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(typeof a1 == "string" || typeof a1 == "function" ? a[i++] : null, a[i++]); + // absorb any additional arguments + for(var l=a.length; i= 0){ + s.width = w + u; + } + if(h >= 0){ + s.height = h + u; + } + } + + function isButtonTag(/*DomNode*/ node){ + // summary: + // True if the node is BUTTON or INPUT.type="button". + return node.tagName.toLowerCase() == "button" || + node.tagName.toLowerCase() == "input" && (node.getAttribute("type") || "").toLowerCase() == "button"; // boolean + } + + function usesBorderBox(/*DomNode*/ node){ + // summary: + // True if the node uses border-box layout. + + // We could test the computed style of node to see if a particular box + // has been specified, but there are details and we choose not to bother. + + // TABLE and BUTTON (and INPUT type=button) are always border-box by default. + // If you have assigned a different box to either one via CSS then + // box functions will break. + + return geom.boxModel == "border-box" || node.tagName.toLowerCase() == "table" || isButtonTag(node); // boolean + } + + function getBoundingClientRect(/*DomNode*/ node) { + // summary: + // Gets the bounding client rectangle for a dom node. + // node: DOMNode + + // This will return the result of node.getBoundingClientRect if node is in the dom, and + // {x:0, y:0, width:0, height:0, top:0, right:0, bottom:0, left:0} if it throws an error or the node is not on the dom + // This will handle when IE throws an error or Edge returns an empty object when node is not on the dom + + var retEmpty = { x: 0, y: 0, width: 0, height: 0, top: 0, right: 0, bottom: 0, left: 0 }, + ret; + + try { + ret = node.getBoundingClientRect(); + } catch (e) { + // IE throws an Unspecified Error if the node is not in the dom. Handle this by returning an object with 0 values + return retEmpty; + } + + // Edge returns an empty object if the node is not in the dom. Handle this by returning an object with 0 values + if (typeof ret.left === "undefined") { return retEmpty; } + + return ret; + } + + geom.setContentSize = function setContentSize(/*DomNode*/ node, /*Object*/ box, /*Object*/ computedStyle){ + // summary: + // Sets the size of the node's contents, irrespective of margins, + // padding, or borders. + // node: DOMNode + // box: Object + // hash with optional "w", and "h" properties for "width", and "height" + // respectively. All specified properties should have numeric values in whole pixels. + // computedStyle: Object? + // This parameter accepts computed styles object. + // If this parameter is omitted, the functions will call + // dojo/dom-style.getComputedStyle to get one. It is a better way, calling + // dojo/dom-style.getComputedStyle once, and then pass the reference to this + // computedStyle parameter. Wherever possible, reuse the returned + // object of dojo/dom-style.getComputedStyle(). + + node = dom.byId(node); + var w = box.w, h = box.h; + if(usesBorderBox(node)){ + var pb = geom.getPadBorderExtents(node, computedStyle); + if(w >= 0){ + w += pb.w; + } + if(h >= 0){ + h += pb.h; + } + } + setBox(node, NaN, NaN, w, h); + }; + + var nilExtents = {l: 0, t: 0, w: 0, h: 0}; + + geom.setMarginBox = function setMarginBox(/*DomNode*/ node, /*Object*/ box, /*Object*/ computedStyle){ + // summary: + // sets the size of the node's margin box and placement + // (left/top), irrespective of box model. Think of it as a + // passthrough to setBox that handles box-model vagaries for + // you. + // node: DOMNode + // box: Object + // hash with optional "l", "t", "w", and "h" properties for "left", "right", "width", and "height" + // respectively. All specified properties should have numeric values in whole pixels. + // computedStyle: Object? + // This parameter accepts computed styles object. + // If this parameter is omitted, the functions will call + // dojo/dom-style.getComputedStyle to get one. It is a better way, calling + // dojo/dom-style.getComputedStyle once, and then pass the reference to this + // computedStyle parameter. Wherever possible, reuse the returned + // object of dojo/dom-style.getComputedStyle(). + + node = dom.byId(node); + var s = computedStyle || style.getComputedStyle(node), w = box.w, h = box.h, + // Some elements have special padding, margin, and box-model settings. + // To use box functions you may need to set padding, margin explicitly. + // Controlling box-model is harder, in a pinch you might set dojo/dom-geometry.boxModel. + pb = usesBorderBox(node) ? nilExtents : geom.getPadBorderExtents(node, s), + mb = geom.getMarginExtents(node, s); + if(has("webkit")){ + // on Safari (3.1.2), button nodes with no explicit size have a default margin + // setting an explicit size eliminates the margin. + // We have to swizzle the width to get correct margin reading. + if(isButtonTag(node)){ + var ns = node.style; + if(w >= 0 && !ns.width){ + ns.width = "4px"; + } + if(h >= 0 && !ns.height){ + ns.height = "4px"; + } + } + } + if(w >= 0){ + w = Math.max(w - pb.w - mb.w, 0); + } + if(h >= 0){ + h = Math.max(h - pb.h - mb.h, 0); + } + setBox(node, box.l, box.t, w, h); + }; + + // ============================= + // Positioning + // ============================= + + geom.isBodyLtr = function isBodyLtr(/*Document?*/ doc){ + // summary: + // Returns true if the current language is left-to-right, and false otherwise. + // doc: Document? + // Optional document to query. If unspecified, use win.doc. + // returns: Boolean + + doc = doc || win.doc; + return (win.body(doc).dir || doc.documentElement.dir || "ltr").toLowerCase() == "ltr"; // Boolean + }; + + geom.docScroll = function docScroll(/*Document?*/ doc){ + // summary: + // Returns an object with {node, x, y} with corresponding offsets. + // doc: Document? + // Optional document to query. If unspecified, use win.doc. + // returns: Object + + doc = doc || win.doc; + var node = doc.parentWindow || doc.defaultView; // use UI window, not dojo.global window. TODO: use dojo/window::get() except for circular dependency problem + return "pageXOffset" in node ? {x: node.pageXOffset, y: node.pageYOffset } : + (node = has("quirks") ? win.body(doc) : doc.documentElement) && + {x: geom.fixIeBiDiScrollLeft(node.scrollLeft || 0, doc), y: node.scrollTop || 0 }; + }; + + geom.getIeDocumentElementOffset = function(/*Document?*/ doc){ + // summary: + // Deprecated method previously used for IE6-IE7. Now, just returns `{x:0, y:0}`. + return { + x: 0, + y: 0 + }; + }; + + geom.fixIeBiDiScrollLeft = function fixIeBiDiScrollLeft(/*Integer*/ scrollLeft, /*Document?*/ doc){ + // summary: + // In RTL direction, scrollLeft should be a negative value, but IE + // returns a positive one. All codes using documentElement.scrollLeft + // must call this function to fix this error, otherwise the position + // will offset to right when there is a horizontal scrollbar. + // scrollLeft: Number + // doc: Document? + // Optional document to query. If unspecified, use win.doc. + // returns: Number + + // In RTL direction, scrollLeft should be a negative value, but IE + // returns a positive one. All codes using documentElement.scrollLeft + // must call this function to fix this error, otherwise the position + // will offset to right when there is a horizontal scrollbar. + + doc = doc || win.doc; + var ie = has("ie"); + if(ie && !geom.isBodyLtr(doc)){ + var qk = has("quirks"), + de = qk ? win.body(doc) : doc.documentElement, + pwin = win.global; // TODO: use winUtils.get(doc) after resolving circular dependency b/w dom-geometry.js and dojo/window.js + if(ie == 6 && !qk && pwin.frameElement && de.scrollHeight > de.clientHeight){ + scrollLeft += de.clientLeft; // workaround ie6+strict+rtl+iframe+vertical-scrollbar bug where clientWidth is too small by clientLeft pixels + } + return (ie < 8 || qk) ? (scrollLeft + de.clientWidth - de.scrollWidth) : -scrollLeft; // Integer + } + return scrollLeft; // Integer + }; + + geom.position = function(/*DomNode*/ node, /*Boolean?*/ includeScroll){ + // summary: + // Gets the position and size of the passed element relative to + // the viewport (if includeScroll==false), or relative to the + // document root (if includeScroll==true). + // + // description: + // Returns an object of the form: + // `{ x: 100, y: 300, w: 20, h: 15 }`. + // If includeScroll==true, the x and y values will include any + // document offsets that may affect the position relative to the + // viewport. + // Uses the border-box model (inclusive of border and padding but + // not margin). Does not act as a setter. + // node: DOMNode|String + // includeScroll: Boolean? + // returns: Object + + node = dom.byId(node); + var db = win.body(node.ownerDocument), + ret= getBoundingClientRect(node); + ret = {x: ret.left, y: ret.top, w: ret.right - ret.left, h: ret.bottom - ret.top}; + + if(has("ie") < 9){ + // fixes the position in IE, quirks mode + ret.x -= (has("quirks") ? db.clientLeft + db.offsetLeft : 0); + ret.y -= (has("quirks") ? db.clientTop + db.offsetTop : 0); + } + + // account for document scrolling + // if offsetParent is used, ret value already includes scroll position + // so we may have to actually remove that value if !includeScroll + if(includeScroll){ + var scroll = geom.docScroll(node.ownerDocument); + ret.x += scroll.x; + ret.y += scroll.y; + } + + return ret; // Object + }; + + // random "private" functions wildly used throughout the toolkit + + geom.getMarginSize = function getMarginSize(/*DomNode*/ node, /*Object*/ computedStyle){ + // summary: + // returns an object that encodes the width and height of + // the node's margin box + // node: DOMNode|String + // computedStyle: Object? + // This parameter accepts computed styles object. + // If this parameter is omitted, the functions will call + // dojo/dom-style.getComputedStyle to get one. It is a better way, calling + // dojo/dom-style.getComputedStyle once, and then pass the reference to this + // computedStyle parameter. Wherever possible, reuse the returned + // object of dojo/dom-style.getComputedStyle(). + + node = dom.byId(node); + var me = geom.getMarginExtents(node, computedStyle || style.getComputedStyle(node)); + var size = getBoundingClientRect(node); + return { + w: (size.right - size.left) + me.w, + h: (size.bottom - size.top) + me.h + }; + }; + + geom.normalizeEvent = function(event){ + // summary: + // Normalizes the geometry of a DOM event, normalizing the pageX, pageY, + // offsetX, offsetY, layerX, and layerX properties + // event: Object + if(!("layerX" in event)){ + event.layerX = event.offsetX; + event.layerY = event.offsetY; + } + + if(!("pageX" in event)){ + // FIXME: scroll position query is duped from dojo/_base/html to + // avoid dependency on that entire module. Now that HTML is in + // Base, we should convert back to something similar there. + var se = event.target; + var doc = (se && se.ownerDocument) || document; + // DO NOT replace the following to use dojo/_base/window.body(), in IE, document.documentElement should be used + // here rather than document.body + var docBody = has("quirks") ? doc.body : doc.documentElement; + event.pageX = event.clientX + geom.fixIeBiDiScrollLeft(docBody.scrollLeft || 0, doc); + event.pageY = event.clientY + (docBody.scrollTop || 0); + } + }; + + // TODO: evaluate separate getters/setters for position and sizes? + + return geom; +}); + +}, +'dojo/dom-style':function(){ +define(["./sniff", "./dom", "./_base/window"], function(has, dom, win){ + // module: + // dojo/dom-style + + // ============================= + // Style Functions + // ============================= + + // getComputedStyle drives most of the style code. + // Wherever possible, reuse the returned object. + // + // API functions below that need to access computed styles accept an + // optional computedStyle parameter. + // If this parameter is omitted, the functions will call getComputedStyle themselves. + // This way, calling code can access computedStyle once, and then pass the reference to + // multiple API functions. + + // Although we normally eschew argument validation at this + // level, here we test argument 'node' for (duck)type, + // by testing nodeType, ecause 'document' is the 'parentNode' of 'body' + // it is frequently sent to this function even + // though it is not Element. + var getComputedStyle, style = { + // summary: + // This module defines the core dojo DOM style API. + }; + if(has("webkit")){ + getComputedStyle = function(/*DomNode*/ node){ + var s; + if(node.nodeType == 1){ + var dv = node.ownerDocument.defaultView; + s = dv.getComputedStyle(node, null); + if(!s && node.style){ + node.style.display = ""; + s = dv.getComputedStyle(node, null); + } + } + return s || {}; + }; + }else if(has("ie") && (has("ie") < 9 || has("quirks"))){ + getComputedStyle = function(node){ + // IE (as of 7) doesn't expose Element like sane browsers + // currentStyle can be null on IE8! + return node.nodeType == 1 /* ELEMENT_NODE*/ && node.currentStyle ? node.currentStyle : {}; + }; + }else{ + getComputedStyle = function(node){ + if(node.nodeType === 1 /* ELEMENT_NODE*/){ + var dv = node.ownerDocument.defaultView, + w = dv.opener ? dv : win.global.window; + return w.getComputedStyle(node, null); + } + return {}; + }; + } + style.getComputedStyle = getComputedStyle; + /*===== + style.getComputedStyle = function(node){ + // summary: + // Returns a "computed style" object. + // + // description: + // Gets a "computed style" object which can be used to gather + // information about the current state of the rendered node. + // + // Note that this may behave differently on different browsers. + // Values may have different formats and value encodings across + // browsers. + // + // Note also that this method is expensive. Wherever possible, + // reuse the returned object. + // + // Use the dojo/dom-style.get() method for more consistent (pixelized) + // return values. + // + // node: DOMNode + // A reference to a DOM node. Does NOT support taking an + // ID string for speed reasons. + // example: + // | require(["dojo/dom-style", "dojo/dom"], function(domStyle, dom){ + // | domStyle.getComputedStyle(dom.byId('foo')).borderWidth; + // | }); + // + // example: + // Reusing the returned object, avoiding multiple lookups: + // | require(["dojo/dom-style", "dojo/dom"], function(domStyle, dom){ + // | var cs = domStyle.getComputedStyle(dom.byId("someNode")); + // | var w = cs.width, h = cs.height; + // | }); + return; // CSS2Properties + }; + =====*/ + + var toPixel; + if(!has("ie")){ + toPixel = function(element, value){ + // style values can be floats, client code may want + // to round for integer pixels. + return parseFloat(value) || 0; + }; + }else{ + toPixel = function(element, avalue){ + if(!avalue){ return 0; } + // on IE7, medium is usually 4 pixels + if(avalue == "medium"){ return 4; } + // style values can be floats, client code may + // want to round this value for integer pixels. + if(avalue.slice && avalue.slice(-2) == 'px'){ return parseFloat(avalue); } + var s = element.style, rs = element.runtimeStyle, cs = element.currentStyle, + sLeft = s.left, rsLeft = rs.left; + rs.left = cs.left; + try{ + // 'avalue' may be incompatible with style.left, which can cause IE to throw + // this has been observed for border widths using "thin", "medium", "thick" constants + // those particular constants could be trapped by a lookup + // but perhaps there are more + s.left = avalue; + avalue = s.pixelLeft; + }catch(e){ + avalue = 0; + } + s.left = sLeft; + rs.left = rsLeft; + return avalue; + }; + } + style.toPixelValue = toPixel; + /*===== + style.toPixelValue = function(node, value){ + // summary: + // converts style value to pixels on IE or return a numeric value. + // node: DOMNode + // value: String + // returns: Number + }; + =====*/ + + // FIXME: there opacity quirks on FF that we haven't ported over. Hrm. + + var astr = "DXImageTransform.Microsoft.Alpha"; + var af = function(n, f){ + try{ + return n.filters.item(astr); + }catch(e){ + return f ? {} : null; + } + }; + + var _getOpacity = + has("ie") < 9 || (has("ie") < 10 && has("quirks")) ? function(node){ + try{ + return af(node).Opacity / 100; // Number + }catch(e){ + return 1; // Number + } + } : + function(node){ + return getComputedStyle(node).opacity; + }; + + var _setOpacity = + has("ie") < 9 || (has("ie") < 10 && has("quirks")) ? function(/*DomNode*/ node, /*Number*/ opacity){ + if(opacity === ""){ opacity = 1; } + var ov = opacity * 100, fullyOpaque = opacity === 1; + + // on IE7 Alpha(Filter opacity=100) makes text look fuzzy so disable it altogether (bug #2661), + // but still update the opacity value so we can get a correct reading if it is read later: + // af(node, 1).Enabled = !fullyOpaque; + + if(fullyOpaque){ + node.style.zoom = ""; + if(af(node)){ + node.style.filter = node.style.filter.replace( + new RegExp("\\s*progid:" + astr + "\\([^\\)]+?\\)", "i"), ""); + } + }else{ + node.style.zoom = 1; + if(af(node)){ + af(node, 1).Opacity = ov; + }else{ + node.style.filter += " progid:" + astr + "(Opacity=" + ov + ")"; + } + af(node, 1).Enabled = true; + } + + if(node.tagName.toLowerCase() == "tr"){ + for(var td = node.firstChild; td; td = td.nextSibling){ + if(td.tagName.toLowerCase() == "td"){ + _setOpacity(td, opacity); + } + } + } + return opacity; + } : + function(node, opacity){ + return node.style.opacity = opacity; + }; + + var _pixelNamesCache = { + left: true, top: true + }; + var _pixelRegExp = /margin|padding|width|height|max|min|offset/; // |border + function _toStyleValue(node, type, value){ + //TODO: should we really be doing string case conversion here? Should we cache it? Need to profile! + type = type.toLowerCase(); + + // Adjustments for IE and Edge + if(value == "auto"){ + if(type == "height"){ return node.offsetHeight; } + if(type == "width"){ return node.offsetWidth; } + } + if(type == "fontweight"){ + switch(value){ + case 700: return "bold"; + case 400: + default: return "normal"; + } + } + + if(!(type in _pixelNamesCache)){ + _pixelNamesCache[type] = _pixelRegExp.test(type); + } + return _pixelNamesCache[type] ? toPixel(node, value) : value; + } + + var _floatAliases = {cssFloat: 1, styleFloat: 1, "float": 1}; + + // public API + + style.get = function getStyle(/*DOMNode|String*/ node, /*String?*/ name){ + // summary: + // Accesses styles on a node. + // description: + // Getting the style value uses the computed style for the node, so the value + // will be a calculated value, not just the immediate node.style value. + // Also when getting values, use specific style names, + // like "borderBottomWidth" instead of "border" since compound values like + // "border" are not necessarily reflected as expected. + // If you want to get node dimensions, use `dojo/dom-geometry.getMarginBox()`, + // `dojo/dom-geometry.getContentBox()` or `dojo/dom-geometry.getPosition()`. + // node: DOMNode|String + // id or reference to node to get style for + // name: String? + // the style property to get + // example: + // Passing only an ID or node returns the computed style object of + // the node: + // | require(["dojo/dom-style", "dojo/dom"], function(domStyle, dom){ + // | domStyle.get("thinger"); + // | }); + // example: + // Passing a node and a style property returns the current + // normalized, computed value for that property: + // | require(["dojo/dom-style", "dojo/dom"], function(domStyle, dom){ + // | domStyle.get("thinger", "opacity"); // 1 by default + // | }); + + var n = dom.byId(node), l = arguments.length, op = (name == "opacity"); + if(l == 2 && op){ + return _getOpacity(n); + } + name = _floatAliases[name] ? "cssFloat" in n.style ? "cssFloat" : "styleFloat" : name; + var s = style.getComputedStyle(n); + return (l == 1) ? s : _toStyleValue(n, name, s[name] || n.style[name]); /* CSS2Properties||String||Number */ + }; + + style.set = function setStyle(/*DOMNode|String*/ node, /*String|Object*/ name, /*String?*/ value){ + // summary: + // Sets styles on a node. + // node: DOMNode|String + // id or reference to node to set style for + // name: String|Object + // the style property to set in DOM-accessor format + // ("borderWidth", not "border-width") or an object with key/value + // pairs suitable for setting each property. + // value: String? + // If passed, sets value on the node for style, handling + // cross-browser concerns. When setting a pixel value, + // be sure to include "px" in the value. For instance, top: "200px". + // Otherwise, in some cases, some browsers will not apply the style. + // + // example: + // Passing a node, a style property, and a value changes the + // current display of the node and returns the new computed value + // | require(["dojo/dom-style"], function(domStyle){ + // | domStyle.set("thinger", "opacity", 0.5); // == 0.5 + // | }); + // + // example: + // Passing a node, an object-style style property sets each of the values in turn and returns the computed style object of the node: + // | require(["dojo/dom-style"], function(domStyle){ + // | domStyle.set("thinger", { + // | "opacity": 0.5, + // | "border": "3px solid black", + // | "height": "300px" + // | }); + // | }); + // + // example: + // When the CSS style property is hyphenated, the JavaScript property is camelCased. + // font-size becomes fontSize, and so on. + // | require(["dojo/dom-style", "dojo/dom"], function(domStyle, dom){ + // | domStyle.set("thinger",{ + // | fontSize:"14pt", + // | letterSpacing:"1.2em" + // | }); + // | }); + // + // example: + // dojo/NodeList implements .style() using the same syntax, omitting the "node" parameter, calling + // dojo/dom-style.get() on every element of the list. See: `dojo/query` and `dojo/NodeList` + // | require(["dojo/dom-style", "dojo/query", "dojo/NodeList-dom"], + // | function(domStyle, query){ + // | query(".someClassName").style("visibility","hidden"); + // | // or + // | query("#baz > div").style({ + // | opacity:0.75, + // | fontSize:"13pt" + // | }); + // | }); + + var n = dom.byId(node), l = arguments.length, op = (name == "opacity"); + name = _floatAliases[name] ? "cssFloat" in n.style ? "cssFloat" : "styleFloat" : name; + if(l == 3){ + return op ? _setOpacity(n, value) : n.style[name] = value; // Number + } + for(var x in name){ + style.set(node, x, name[x]); + } + return style.getComputedStyle(n); + }; + + return style; +}); + +}, +'dojo/mouse':function(){ +define(["./_base/kernel", "./on", "./has", "./dom", "./_base/window"], function(dojo, on, has, dom, win){ + + // module: + // dojo/mouse + + has.add("dom-quirks", win.doc && win.doc.compatMode == "BackCompat"); + has.add("events-mouseenter", win.doc && "onmouseenter" in win.doc.createElement("div")); + has.add("events-mousewheel", win.doc && 'onmousewheel' in win.doc); + + var mouseButtons; + if((has("dom-quirks") && has("ie")) || !has("dom-addeventlistener")){ + mouseButtons = { + LEFT: 1, + MIDDLE: 4, + RIGHT: 2, + // helper functions + isButton: function(e, button){ return e.button & button; }, + isLeft: function(e){ return e.button & 1; }, + isMiddle: function(e){ return e.button & 4; }, + isRight: function(e){ return e.button & 2; } + }; + }else{ + mouseButtons = { + LEFT: 0, + MIDDLE: 1, + RIGHT: 2, + // helper functions + isButton: function(e, button){ return e.button == button; }, + isLeft: function(e){ return e.button == 0; }, + isMiddle: function(e){ return e.button == 1; }, + isRight: function(e){ return e.button == 2; } + }; + } + dojo.mouseButtons = mouseButtons; + +/*===== + dojo.mouseButtons = { + // LEFT: Number + // Numeric value of the left mouse button for the platform. + LEFT: 0, + // MIDDLE: Number + // Numeric value of the middle mouse button for the platform. + MIDDLE: 1, + // RIGHT: Number + // Numeric value of the right mouse button for the platform. + RIGHT: 2, + + isButton: function(e, button){ + // summary: + // Checks an event object for a pressed button + // e: Event + // Event object to examine + // button: Number + // The button value (example: dojo.mouseButton.LEFT) + return e.button == button; // Boolean + }, + isLeft: function(e){ + // summary: + // Checks an event object for the pressed left button + // e: Event + // Event object to examine + return e.button == 0; // Boolean + }, + isMiddle: function(e){ + // summary: + // Checks an event object for the pressed middle button + // e: Event + // Event object to examine + return e.button == 1; // Boolean + }, + isRight: function(e){ + // summary: + // Checks an event object for the pressed right button + // e: Event + // Event object to examine + return e.button == 2; // Boolean + } + }; +=====*/ + + function eventHandler(type, selectHandler){ + // emulation of mouseenter/leave with mouseover/out using descendant checking + var handler = function(node, listener){ + return on(node, type, function(evt){ + if(selectHandler){ + return selectHandler(evt, listener); + } + if(!dom.isDescendant(evt.relatedTarget, node)){ + return listener.call(this, evt); + } + }); + }; + handler.bubble = function(select){ + return eventHandler(type, function(evt, listener){ + // using a selector, use the select function to determine if the mouse moved inside the selector and was previously outside the selector + var target = select(evt.target); + var relatedTarget = evt.relatedTarget; + if(target && (target != (relatedTarget && relatedTarget.nodeType == 1 && select(relatedTarget)))){ + return listener.call(target, evt); + } + }); + }; + return handler; + } + var wheel; + if(has("events-mousewheel")){ + wheel = 'mousewheel'; + }else{ //firefox + wheel = function(node, listener){ + return on(node, 'DOMMouseScroll', function(evt){ + evt.wheelDelta = -evt.detail; + listener.call(this, evt); + }); + }; + } + return { + // summary: + // This module provide mouse event handling utility functions and exports + // mouseenter and mouseleave event emulation. + // example: + // To use these events, you register a mouseenter like this: + // | define(["dojo/on", "dojo/mouse"], function(on, mouse){ + // | on(targetNode, mouse.enter, function(event){ + // | dojo.addClass(targetNode, "highlighted"); + // | }); + // | on(targetNode, mouse.leave, function(event){ + // | dojo.removeClass(targetNode, "highlighted"); + // | }); + + _eventHandler: eventHandler, // for dojo/touch + + // enter: Synthetic Event + // This is an extension event for the mouseenter that IE provides, emulating the + // behavior on other browsers. + enter: eventHandler("mouseover"), + + // leave: Synthetic Event + // This is an extension event for the mouseleave that IE provides, emulating the + // behavior on other browsers. + leave: eventHandler("mouseout"), + + // wheel: Normalized Mouse Wheel Event + // This is an extension event for the mousewheel that non-Mozilla browsers provide, + // emulating the behavior on Mozilla based browsers. + wheel: wheel, + + isLeft: mouseButtons.isLeft, + /*===== + isLeft: function(){ + // summary: + // Test an event object (from a mousedown event) to see if the left button was pressed. + }, + =====*/ + + isMiddle: mouseButtons.isMiddle, + /*===== + isMiddle: function(){ + // summary: + // Test an event object (from a mousedown event) to see if the middle button was pressed. + }, + =====*/ + + isRight: mouseButtons.isRight + /*===== + , isRight: function(){ + // summary: + // Test an event object (from a mousedown event) to see if the right button was pressed. + } + =====*/ + }; +}); + +}, +'dojo/keys':function(){ +define(["./_base/kernel", "./sniff"], function(dojo, has){ + + // module: + // dojo/keys + + return dojo.keys = { + // summary: + // Definitions for common key values. Client code should test keyCode against these named constants, + // as the actual codes can vary by browser. + + BACKSPACE: 8, + TAB: 9, + CLEAR: 12, + ENTER: 13, + SHIFT: 16, + CTRL: 17, + ALT: 18, + META: has("webkit") ? 91 : 224, // the apple key on macs + PAUSE: 19, + CAPS_LOCK: 20, + ESCAPE: 27, + SPACE: 32, + PAGE_UP: 33, + PAGE_DOWN: 34, + END: 35, + HOME: 36, + LEFT_ARROW: 37, + UP_ARROW: 38, + RIGHT_ARROW: 39, + DOWN_ARROW: 40, + INSERT: 45, + DELETE: 46, + HELP: 47, + LEFT_WINDOW: 91, + RIGHT_WINDOW: 92, + SELECT: 93, + NUMPAD_0: 96, + NUMPAD_1: 97, + NUMPAD_2: 98, + NUMPAD_3: 99, + NUMPAD_4: 100, + NUMPAD_5: 101, + NUMPAD_6: 102, + NUMPAD_7: 103, + NUMPAD_8: 104, + NUMPAD_9: 105, + NUMPAD_MULTIPLY: 106, + NUMPAD_PLUS: 107, + NUMPAD_ENTER: 108, + NUMPAD_MINUS: 109, + NUMPAD_PERIOD: 110, + NUMPAD_DIVIDE: 111, + F1: 112, + F2: 113, + F3: 114, + F4: 115, + F5: 116, + F6: 117, + F7: 118, + F8: 119, + F9: 120, + F10: 121, + F11: 122, + F12: 123, + F13: 124, + F14: 125, + F15: 126, + NUM_LOCK: 144, + SCROLL_LOCK: 145, + UP_DPAD: 175, + DOWN_DPAD: 176, + LEFT_DPAD: 177, + RIGHT_DPAD: 178, + // virtual key mapping + copyKey: has("mac") && !has("air") ? (has("safari") ? 91 : 224 ) : 17 + }; +}); + +}, +'dojo/_base/Color':function(){ +define(["./kernel", "./lang", "./array", "./config"], function(dojo, lang, ArrayUtil, config){ + + var Color = dojo.Color = function(/*Array|String|Object*/ color){ + // summary: + // Takes a named string, hex string, array of rgb or rgba values, + // an object with r, g, b, and a properties, or another `Color` object + // and creates a new Color instance to work from. + // + // example: + // Work with a Color instance: + // | require(["dojo/_base/color"], function(Color){ + // | var c = new Color(); + // | c.setColor([0,0,0]); // black + // | var hex = c.toHex(); // #000000 + // | }); + // + // example: + // Work with a node's color: + // | + // | require(["dojo/_base/color", "dojo/dom-style"], function(Color, domStyle){ + // | var color = domStyle("someNode", "backgroundColor"); + // | var n = new Color(color); + // | // adjust the color some + // | n.r *= .5; + // | console.log(n.toString()); // rgb(128, 255, 255); + // | }); + if(color){ this.setColor(color); } + }; + + // FIXME: + // there's got to be a more space-efficient way to encode or discover + // these!! Use hex? + Color.named = { + // summary: + // Dictionary list of all CSS named colors, by name. Values are 3-item arrays with corresponding RG and B values. + "black": [0,0,0], + "silver": [192,192,192], + "gray": [128,128,128], + "white": [255,255,255], + "maroon": [128,0,0], + "red": [255,0,0], + "purple": [128,0,128], + "fuchsia":[255,0,255], + "green": [0,128,0], + "lime": [0,255,0], + "olive": [128,128,0], + "yellow": [255,255,0], + "navy": [0,0,128], + "blue": [0,0,255], + "teal": [0,128,128], + "aqua": [0,255,255], + "transparent": config.transparentColor || [0,0,0,0] + }; + + lang.extend(Color, { + r: 255, g: 255, b: 255, a: 1, + _set: function(r, g, b, a){ + var t = this; t.r = r; t.g = g; t.b = b; t.a = a; + }, + setColor: function(/*Array|String|Object*/ color){ + // summary: + // Takes a named string, hex string, array of rgb or rgba values, + // an object with r, g, b, and a properties, or another `Color` object + // and sets this color instance to that value. + // + // example: + // | require(["dojo/_base/color"], function(Color){ + // | var c = new Color(); // no color + // | c.setColor("#ededed"); // greyish + // | }); + if(lang.isString(color)){ + Color.fromString(color, this); + }else if(lang.isArray(color)){ + Color.fromArray(color, this); + }else{ + this._set(color.r, color.g, color.b, color.a); + if(!(color instanceof Color)){ this.sanitize(); } + } + return this; // Color + }, + sanitize: function(){ + // summary: + // Ensures the object has correct attributes + // description: + // the default implementation does nothing, include dojo.colors to + // augment it with real checks + return this; // Color + }, + toRgb: function(){ + // summary: + // Returns 3 component array of rgb values + // example: + // | require(["dojo/_base/color"], function(Color){ + // | var c = new Color("#000000"); + // | console.log(c.toRgb()); // [0,0,0] + // | }); + var t = this; + return [t.r, t.g, t.b]; // Array + }, + toRgba: function(){ + // summary: + // Returns a 4 component array of rgba values from the color + // represented by this object. + var t = this; + return [t.r, t.g, t.b, t.a]; // Array + }, + toHex: function(){ + // summary: + // Returns a CSS color string in hexadecimal representation + // example: + // | require(["dojo/_base/color"], function(Color){ + // | console.log(new Color([0,0,0]).toHex()); // #000000 + // | }); + var arr = ArrayUtil.map(["r", "g", "b"], function(x){ + var s = this[x].toString(16); + return s.length < 2 ? "0" + s : s; + }, this); + return "#" + arr.join(""); // String + }, + toCss: function(/*Boolean?*/ includeAlpha){ + // summary: + // Returns a css color string in rgb(a) representation + // example: + // | require(["dojo/_base/color"], function(Color){ + // | var c = new Color("#FFF").toCss(); + // | console.log(c); // rgb('255','255','255') + // | }); + var t = this, rgb = t.r + ", " + t.g + ", " + t.b; + return (includeAlpha ? "rgba(" + rgb + ", " + t.a : "rgb(" + rgb) + ")"; // String + }, + toString: function(){ + // summary: + // Returns a visual representation of the color + return this.toCss(true); // String + } + }); + + Color.blendColors = dojo.blendColors = function( + /*Color*/ start, + /*Color*/ end, + /*Number*/ weight, + /*Color?*/ obj + ){ + // summary: + // Blend colors end and start with weight from 0 to 1, 0.5 being a 50/50 blend, + // can reuse a previously allocated Color object for the result + var t = obj || new Color(); + t.r = Math.round(start.r + (end.r - start.r) * weight); + t.g = Math.round(start.g + (end.g - start.g) * weight); + t.b = Math.round(start.b + (end.b - start.b) * weight); + t.a = start.a + (end.a - start.a) * weight; + return t.sanitize(); // Color + }; + + Color.fromRgb = dojo.colorFromRgb = function(/*String*/ color, /*Color?*/ obj){ + // summary: + // Returns a `Color` instance from a string of the form + // "rgb(...)" or "rgba(...)". Optionally accepts a `Color` + // object to update with the parsed value and return instead of + // creating a new object. + // returns: + // A Color object. If obj is passed, it will be the return value. + var m = color.toLowerCase().match(/^rgba?\(([\s\.,0-9]+)\)/); + return m && Color.fromArray(m[1].split(/\s*,\s*/), obj); // Color + }; + + Color.fromHex = dojo.colorFromHex = function(/*String*/ color, /*Color?*/ obj){ + // summary: + // Converts a hex string with a '#' prefix to a color object. + // Supports 12-bit #rgb shorthand. Optionally accepts a + // `Color` object to update with the parsed value. + // + // returns: + // A Color object. If obj is passed, it will be the return value. + // + // example: + // | require(["dojo/_base/color"], function(Color){ + // | var thing = new Color().fromHex("#ededed"); // grey, longhand + // | var thing2 = new Color().fromHex("#000"); // black, shorthand + // | }); + var t = obj || new Color(), + bits = (color.length == 4) ? 4 : 8, + mask = (1 << bits) - 1; + color = Number("0x" + color.substr(1)); + if(isNaN(color)){ + return null; // Color + } + ArrayUtil.forEach(["b", "g", "r"], function(x){ + var c = color & mask; + color >>= bits; + t[x] = bits == 4 ? 17 * c : c; + }); + t.a = 1; + return t; // Color + }; + + Color.fromArray = dojo.colorFromArray = function(/*Array*/ a, /*Color?*/ obj){ + // summary: + // Builds a `Color` from a 3 or 4 element array, mapping each + // element in sequence to the rgb(a) values of the color. + // example: + // | require(["dojo/_base/color"], function(Color){ + // | var myColor = new Color().fromArray([237,237,237,0.5]); // grey, 50% alpha + // | }); + // returns: + // A Color object. If obj is passed, it will be the return value. + var t = obj || new Color(); + t._set(Number(a[0]), Number(a[1]), Number(a[2]), Number(a[3])); + if(isNaN(t.a)){ t.a = 1; } + return t.sanitize(); // Color + }; + + Color.fromString = dojo.colorFromString = function(/*String*/ str, /*Color?*/ obj){ + // summary: + // Parses `str` for a color value. Accepts hex, rgb, and rgba + // style color values. + // description: + // Acceptable input values for str may include arrays of any form + // accepted by dojo.colorFromArray, hex strings such as "#aaaaaa", or + // rgb or rgba strings such as "rgb(133, 200, 16)" or "rgba(10, 10, + // 10, 50)" + // returns: + // A Color object. If obj is passed, it will be the return value. + var a = Color.named[str]; + return a && Color.fromArray(a, obj) || Color.fromRgb(str, obj) || Color.fromHex(str, obj); // Color + }; + + return Color; +}); + +}, +'dojo/_base/browser':function(){ +if(require.has){ + require.has.add("config-selectorEngine", "acme"); +} +define([ + "../ready", + "./kernel", + "./connect", // until we decide if connect is going back into non-browser environments + "./unload", + "./window", + "./event", + "./html", + "./NodeList", + "../query", + "./xhr", + "./fx"], function(dojo){ + + // module: + // dojo/_base/browser + + /*===== + return { + // summary: + // This module causes the browser-only base modules to be loaded. + }; + =====*/ + + return dojo; +}); + +}, +'dojo/_base/unload':function(){ +define(["./kernel", "./lang", "../on"], function(dojo, lang, on){ + +// module: +// dojo/unload + +var win = window; + +var unload = { + // summary: + // This module contains the document and window unload detection API. + // This module is deprecated. Use on(window, "unload", func) + // and on(window, "beforeunload", func) instead. + + addOnWindowUnload: function(/*Object|Function?*/ obj, /*String|Function?*/ functionName){ + // summary: + // Registers a function to be triggered when window.onunload fires. + // Deprecated, use on(window, "unload", lang.hitch(obj, functionName)) instead. + // 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 + // destroy "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 + // addOnUnload() if you need to modify the DOM or do + // heavy JavaScript work since it fires at the equivalent of + // the page's "onbeforeunload" event. + // example: + // | var afunc = function() {console.log("global function");}; + // | require(["dojo/_base/unload"], function(unload) { + // | var foo = {bar: function(){ console.log("bar unloading...");}, + // | data: "mydata"}; + // | unload.addOnWindowUnload(afunc); + // | unload.addOnWindowUnload(foo, "bar"); + // | unload.addOnWindowUnload(foo, function(){console.log("", this.data);}); + // | }); + + if (!dojo.windowUnloaded){ + on(win, "unload", (dojo.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 + // addOnWindowUnload(). This behavior started in Dojo 1.3. + // Previous versions always triggered windowUnloaded(). See + // addOnWindowUnload for more info. + })); + } + on(win, "unload", lang.hitch(obj, functionName)); + }, + + addOnUnload: function(/*Object?|Function?*/ obj, /*String|Function?*/ functionName){ + // summary: + // Registers a function to be triggered when the page unloads. + // Deprecated, use on(window, "beforeunload", lang.hitch(obj, functionName)) instead. + // description: + // The first time that addOnUnload is called Dojo will + // register a page listener to trigger your unload handler + // with. + // + // In a browser environment, 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: + // | var afunc = function() {console.log("global function");}; + // | require(["dojo/_base/unload"], function(unload) { + // | var foo = {bar: function(){ console.log("bar unloading...");}, + // | data: "mydata"}; + // | unload.addOnUnload(afunc); + // | unload.addOnUnload(foo, "bar"); + // | unload.addOnUnload(foo, function(){console.log("", this.data);}); + // | }); + + on(win, "beforeunload", lang.hitch(obj, functionName)); + } +}; + +dojo.addOnWindowUnload = unload.addOnWindowUnload; +dojo.addOnUnload = unload.addOnUnload; + +return unload; + +}); + +}, +'dojo/_base/html':function(){ +define(["./kernel", "../dom", "../dom-style", "../dom-attr", "../dom-prop", "../dom-class", "../dom-construct", "../dom-geometry"], function(dojo, dom, style, attr, prop, cls, ctr, geom){ + // module: + // dojo/dom + + /*===== + return { + // summary: + // This module is a stub for the core dojo DOM API. + }; + =====*/ + + // mix-in dom + dojo.byId = dom.byId; + dojo.isDescendant = dom.isDescendant; + dojo.setSelectable = dom.setSelectable; + + // mix-in dom-attr + dojo.getAttr = attr.get; + dojo.setAttr = attr.set; + dojo.hasAttr = attr.has; + dojo.removeAttr = attr.remove; + dojo.getNodeProp = attr.getNodeProp; + + dojo.attr = function(node, name, value){ + // summary: + // Gets or sets an attribute on an HTML element. + // description: + // Handles normalized getting and setting of attributes on DOM + // Nodes. If 2 arguments are passed, and a the second argument is a + // string, acts as a getter. + // + // If a third argument is passed, or if the second argument is a + // map of attributes, acts as a setter. + // + // When passing functions as values, note that they will not be + // directly assigned to slots on the node, but rather the default + // behavior will be removed and the new behavior will be added + // using `dojo.connect()`, meaning that event handler properties + // will be normalized and that some caveats with regards to + // non-standard behaviors for onsubmit apply. Namely that you + // should cancel form submission using `dojo.stopEvent()` on the + // passed event object instead of returning a boolean value from + // the handler itself. + // node: DOMNode|String + // id or reference to the element to get or set the attribute on + // name: String|Object + // the name of the attribute to get or set. + // value: String? + // The value to set for the attribute + // returns: + // when used as a getter, the value of the requested attribute + // or null if that attribute does not have a specified or + // default value; + // + // when used as a setter, the DOM node + // + // example: + // | // get the current value of the "foo" attribute on a node + // | dojo.attr(dojo.byId("nodeId"), "foo"); + // | // or we can just pass the id: + // | dojo.attr("nodeId", "foo"); + // + // example: + // | // use attr() to set the tab index + // | dojo.attr("nodeId", "tabIndex", 3); + // | + // + // example: + // Set multiple values at once, including event handlers: + // | dojo.attr("formId", { + // | "foo": "bar", + // | "tabIndex": -1, + // | "method": "POST", + // | "onsubmit": function(e){ + // | // stop submitting the form. Note that the IE behavior + // | // of returning true or false will have no effect here + // | // since our handler is connect()ed to the built-in + // | // onsubmit behavior and so we need to use + // | // dojo.stopEvent() to ensure that the submission + // | // doesn't proceed. + // | dojo.stopEvent(e); + // | + // | // submit the form with Ajax + // | dojo.xhrPost({ form: "formId" }); + // | } + // | }); + // + // example: + // Style is s special case: Only set with an object hash of styles + // | dojo.attr("someNode",{ + // | id:"bar", + // | style:{ + // | width:"200px", height:"100px", color:"#000" + // | } + // | }); + // + // example: + // Again, only set style as an object hash of styles: + // | var obj = { color:"#fff", backgroundColor:"#000" }; + // | dojo.attr("someNode", "style", obj); + // | + // | // though shorter to use `dojo.style()` in this case: + // | dojo.style("someNode", obj); + + if(arguments.length == 2){ + return attr[typeof name == "string" ? "get" : "set"](node, name); + } + return attr.set(node, name, value); + }; + + // mix-in dom-class + dojo.hasClass = cls.contains; + dojo.addClass = cls.add; + dojo.removeClass = cls.remove; + dojo.toggleClass = cls.toggle; + dojo.replaceClass = cls.replace; + + // mix-in dom-construct + dojo._toDom = dojo.toDom = ctr.toDom; + dojo.place = ctr.place; + dojo.create = ctr.create; + dojo.empty = function(node){ ctr.empty(node); }; + dojo._destroyElement = dojo.destroy = function(node){ ctr.destroy(node); }; + + // mix-in dom-geometry + dojo._getPadExtents = dojo.getPadExtents = geom.getPadExtents; + dojo._getBorderExtents = dojo.getBorderExtents = geom.getBorderExtents; + dojo._getPadBorderExtents = dojo.getPadBorderExtents = geom.getPadBorderExtents; + dojo._getMarginExtents = dojo.getMarginExtents = geom.getMarginExtents; + dojo._getMarginSize = dojo.getMarginSize = geom.getMarginSize; + dojo._getMarginBox = dojo.getMarginBox = geom.getMarginBox; + dojo.setMarginBox = geom.setMarginBox; + dojo._getContentBox = dojo.getContentBox = geom.getContentBox; + dojo.setContentSize = geom.setContentSize; + dojo._isBodyLtr = dojo.isBodyLtr = geom.isBodyLtr; + dojo._docScroll = dojo.docScroll = geom.docScroll; + dojo._getIeDocumentElementOffset = dojo.getIeDocumentElementOffset = geom.getIeDocumentElementOffset; + dojo._fixIeBiDiScrollLeft = dojo.fixIeBiDiScrollLeft = geom.fixIeBiDiScrollLeft; + dojo.position = geom.position; + + dojo.marginBox = function marginBox(/*DomNode|String*/node, /*Object?*/box){ + // summary: + // Getter/setter for the margin-box of node. + // description: + // Getter/setter for the margin-box of node. + // Returns an object in the expected format of box (regardless + // if box is passed). The object might look like: + // `{ l: 50, t: 200, w: 300: h: 150 }` + // for a node offset from its parent 50px to the left, 200px from + // the top with a margin width of 300px and a margin-height of + // 150px. + // node: + // id or reference to DOM Node to get/set box for + // box: + // If passed, denotes that dojo.marginBox() should + // update/set the margin box for node. Box is an object in the + // above format. All properties are optional if passed. + // example: + // Retrieve the margin box of a passed node + // | var box = dojo.marginBox("someNodeId"); + // | console.dir(box); + // + // example: + // Set a node's margin box to the size of another node + // | var box = dojo.marginBox("someNodeId"); + // | dojo.marginBox("someOtherNode", box); + return box ? geom.setMarginBox(node, box) : geom.getMarginBox(node); // Object + }; + + dojo.contentBox = function contentBox(/*DomNode|String*/node, /*Object?*/box){ + // summary: + // Getter/setter for the content-box of node. + // description: + // Returns an object in the expected format of box (regardless if box is passed). + // The object might look like: + // `{ l: 50, t: 200, w: 300: h: 150 }` + // for a node offset from its parent 50px to the left, 200px from + // the top with a content width of 300px and a content-height of + // 150px. Note that the content box may have a much larger border + // or margin box, depending on the box model currently in use and + // CSS values set/inherited for node. + // While the getter will return top and left values, the + // setter only accepts setting the width and height. + // node: + // id or reference to DOM Node to get/set box for + // box: + // If passed, denotes that dojo.contentBox() should + // update/set the content box for node. Box is an object in the + // above format, but only w (width) and h (height) are supported. + // All properties are optional if passed. + return box ? geom.setContentSize(node, box) : geom.getContentBox(node); // Object + }; + + dojo.coords = function(/*DomNode|String*/node, /*Boolean?*/includeScroll){ + // summary: + // Deprecated: Use position() for border-box x/y/w/h + // or marginBox() for margin-box w/h/l/t. + // + // Returns an object that measures margin-box (w)idth/(h)eight + // and absolute position x/y of the border-box. Also returned + // is computed (l)eft and (t)op values in pixels from the + // node's offsetParent as returned from marginBox(). + // Return value will be in the form: + //| { l: 50, t: 200, w: 300: h: 150, x: 100, y: 300 } + // Does not act as a setter. If includeScroll is passed, the x and + // y params are affected as one would expect in dojo.position(). + dojo.deprecated("dojo.coords()", "Use dojo.position() or dojo.marginBox()."); + node = dom.byId(node); + var s = style.getComputedStyle(node), mb = geom.getMarginBox(node, s); + var abs = geom.position(node, includeScroll); + mb.x = abs.x; + mb.y = abs.y; + return mb; // Object + }; + + // mix-in dom-prop + dojo.getProp = prop.get; + dojo.setProp = prop.set; + + dojo.prop = function(/*DomNode|String*/node, /*String|Object*/name, /*String?*/value){ + // summary: + // Gets or sets a property on an HTML element. + // description: + // Handles normalized getting and setting of properties on DOM + // Nodes. If 2 arguments are passed, and a the second argument is a + // string, acts as a getter. + // + // If a third argument is passed, or if the second argument is a + // map of attributes, acts as a setter. + // + // When passing functions as values, note that they will not be + // directly assigned to slots on the node, but rather the default + // behavior will be removed and the new behavior will be added + // using `dojo.connect()`, meaning that event handler properties + // will be normalized and that some caveats with regards to + // non-standard behaviors for onsubmit apply. Namely that you + // should cancel form submission using `dojo.stopEvent()` on the + // passed event object instead of returning a boolean value from + // the handler itself. + // node: + // id or reference to the element to get or set the property on + // name: + // the name of the property to get or set. + // value: + // The value to set for the property + // returns: + // when used as a getter, the value of the requested property + // or null if that attribute does not have a specified or + // default value; + // + // when used as a setter, the DOM node + // + // example: + // | // get the current value of the "foo" property on a node + // | dojo.prop(dojo.byId("nodeId"), "foo"); + // | // or we can just pass the id: + // | dojo.prop("nodeId", "foo"); + // + // example: + // | // use prop() to set the tab index + // | dojo.prop("nodeId", "tabIndex", 3); + // | + // + // example: + // Set multiple values at once, including event handlers: + // | dojo.prop("formId", { + // | "foo": "bar", + // | "tabIndex": -1, + // | "method": "POST", + // | "onsubmit": function(e){ + // | // stop submitting the form. Note that the IE behavior + // | // of returning true or false will have no effect here + // | // since our handler is connect()ed to the built-in + // | // onsubmit behavior and so we need to use + // | // dojo.stopEvent() to ensure that the submission + // | // doesn't proceed. + // | dojo.stopEvent(e); + // | + // | // submit the form with Ajax + // | dojo.xhrPost({ form: "formId" }); + // | } + // | }); + // + // example: + // Style is s special case: Only set with an object hash of styles + // | dojo.prop("someNode",{ + // | id:"bar", + // | style:{ + // | width:"200px", height:"100px", color:"#000" + // | } + // | }); + // + // example: + // Again, only set style as an object hash of styles: + // | var obj = { color:"#fff", backgroundColor:"#000" }; + // | dojo.prop("someNode", "style", obj); + // | + // | // though shorter to use `dojo.style()` in this case: + // | dojo.style("someNode", obj); + + if(arguments.length == 2){ + return prop[typeof name == "string" ? "get" : "set"](node, name); + } + // setter + return prop.set(node, name, value); + }; + + // mix-in dom-style + dojo.getStyle = style.get; + dojo.setStyle = style.set; + dojo.getComputedStyle = style.getComputedStyle; + dojo.__toPixelValue = dojo.toPixelValue = style.toPixelValue; + + dojo.style = function(node, name, value){ + // summary: + // Accesses styles on a node. If 2 arguments are + // passed, acts as a getter. If 3 arguments are passed, acts + // as a setter. + // description: + // Getting the style value uses the computed style for the node, so the value + // will be a calculated value, not just the immediate node.style value. + // Also when getting values, use specific style names, + // like "borderBottomWidth" instead of "border" since compound values like + // "border" are not necessarily reflected as expected. + // If you want to get node dimensions, use `dojo.marginBox()`, + // `dojo.contentBox()` or `dojo.position()`. + // node: DOMNode|String + // id or reference to node to get/set style for + // name: String|Object? + // the style property to set in DOM-accessor format + // ("borderWidth", not "border-width") or an object with key/value + // pairs suitable for setting each property. + // value: String? + // If passed, sets value on the node for style, handling + // cross-browser concerns. When setting a pixel value, + // be sure to include "px" in the value. For instance, top: "200px". + // Otherwise, in some cases, some browsers will not apply the style. + // returns: + // when used as a getter, return the computed style of the node if passing in an ID or node, + // or return the normalized, computed value for the property when passing in a node and a style property + // example: + // Passing only an ID or node returns the computed style object of + // the node: + // | dojo.style("thinger"); + // example: + // Passing a node and a style property returns the current + // normalized, computed value for that property: + // | dojo.style("thinger", "opacity"); // 1 by default + // + // example: + // Passing a node, a style property, and a value changes the + // current display of the node and returns the new computed value + // | dojo.style("thinger", "opacity", 0.5); // == 0.5 + // + // example: + // Passing a node, an object-style style property sets each of the values in turn and returns the computed style object of the node: + // | dojo.style("thinger", { + // | "opacity": 0.5, + // | "border": "3px solid black", + // | "height": "300px" + // | }); + // + // example: + // When the CSS style property is hyphenated, the JavaScript property is camelCased. + // font-size becomes fontSize, and so on. + // | dojo.style("thinger",{ + // | fontSize:"14pt", + // | letterSpacing:"1.2em" + // | }); + // + // example: + // dojo/NodeList implements .style() using the same syntax, omitting the "node" parameter, calling + // dojo.style() on every element of the list. See: `dojo/query` and `dojo/NodeList` + // | dojo.query(".someClassName").style("visibility","hidden"); + // | // or + // | dojo.query("#baz > div").style({ + // | opacity:0.75, + // | fontSize:"13pt" + // | }); + + switch(arguments.length){ + case 1: + return style.get(node); + case 2: + return style[typeof name == "string" ? "get" : "set"](node, name); + } + // setter + return style.set(node, name, value); + }; + + return dojo; +}); + +}, +'dojo/dom-attr':function(){ +define(["exports", "./sniff", "./_base/lang", "./dom", "./dom-style", "./dom-prop"], + function(exports, has, lang, dom, style, prop){ + // module: + // dojo/dom-attr + // summary: + // This module defines the core dojo DOM attributes API. + + // TODOC: summary not showing up in output see https://github.com/csnover/js-doc-parse/issues/42 + + // ============================= + // Element attribute Functions + // ============================= + + // This module will be obsolete soon. Use dojo/prop instead. + + // dojo/dom-attr.get() should conform to http://www.w3.org/TR/DOM-Level-2-Core/ + + // attribute-related functions (to be obsolete soon) + var forcePropNames = { + innerHTML: 1, + textContent:1, + className: 1, + htmlFor: has("ie") ? 1 : 0, + value: 1 + }, + attrNames = { + // original attribute names + classname: "class", + htmlfor: "for", + // for IE + tabindex: "tabIndex", + readonly: "readOnly" + }; + + function _hasAttr(node, name){ + var attr = node.getAttributeNode && node.getAttributeNode(name); + return !!attr && attr.specified; // Boolean + } + + // There is a difference in the presence of certain properties and their default values + // between browsers. For example, on IE "disabled" is present on all elements, + // but it is value is "false"; "tabIndex" of
returns 0 by default on IE, yet other browsers + // can return -1. + + exports.has = function hasAttr(/*DOMNode|String*/ node, /*String*/ name){ + // summary: + // Returns true if the requested attribute is specified on the + // given element, and false otherwise. + // node: DOMNode|String + // id or reference to the element to check + // name: String + // the name of the attribute + // returns: Boolean + // true if the requested attribute is specified on the + // given element, and false otherwise + + var lc = name.toLowerCase(); + return !!forcePropNames[prop.names[lc] || name] || _hasAttr(dom.byId(node), attrNames[lc] || name); // Boolean + }; + + exports.get = function getAttr(/*DOMNode|String*/ node, /*String*/ name){ + // summary: + // Gets an attribute on an HTML element. + // description: + // Handles normalized getting of attributes on DOM Nodes. + // node: DOMNode|String + // id or reference to the element to get the attribute on + // name: String + // the name of the attribute to get. + // returns: + // the value of the requested attribute or null if that attribute does not have a specified or + // default value; + // + // example: + // | // get the current value of the "foo" attribute on a node + // | require(["dojo/dom-attr", "dojo/dom"], function(domAttr, dom){ + // | domAttr.get(dom.byId("nodeId"), "foo"); + // | // or we can just pass the id: + // | domAttr.get("nodeId", "foo"); + // | }); + // | + + node = dom.byId(node); + var lc = name.toLowerCase(), + propName = prop.names[lc] || name, + forceProp = forcePropNames[propName], + value = node[propName]; // should we access this attribute via a property or via getAttribute()? + + if(forceProp && typeof value != "undefined"){ + // node's property + return value; // Anything + } + + if(propName == "textContent"){ + return prop.get(node, propName); + } + + if(propName != "href" && (typeof value == "boolean" || lang.isFunction(value))){ + // node's property + return value; // Anything + } + // node's attribute + // we need _hasAttr() here to guard against IE returning a default value + var attrName = attrNames[lc] || name; + return _hasAttr(node, attrName) ? node.getAttribute(attrName) : null; // Anything + }; + + exports.set = function setAttr(/*DOMNode|String*/ node, /*String|Object*/ name, /*String?*/ value){ + // summary: + // Sets an attribute on an HTML element. + // description: + // Handles normalized setting of attributes on DOM Nodes. + // + // When passing functions as values, note that they will not be + // directly assigned to slots on the node, but rather the default + // behavior will be removed and the new behavior will be added + // using `dojo.connect()`, meaning that event handler properties + // will be normalized and that some caveats with regards to + // non-standard behaviors for onsubmit apply. Namely that you + // should cancel form submission using `dojo.stopEvent()` on the + // passed event object instead of returning a boolean value from + // the handler itself. + // node: DOMNode|String + // id or reference to the element to set the attribute on + // name: String|Object + // the name of the attribute to set, or a hash of key-value pairs to set. + // value: String? + // the value to set for the attribute, if the name is a string. + // returns: + // the DOM node + // + // example: + // | // use attr() to set the tab index + // | require(["dojo/dom-attr"], function(domAttr){ + // | domAttr.set("nodeId", "tabIndex", 3); + // | }); + // + // example: + // Set multiple values at once, including event handlers: + // | require(["dojo/dom-attr"], + // | function(domAttr){ + // | domAttr.set("formId", { + // | "foo": "bar", + // | "tabIndex": -1, + // | "method": "POST" + // | } + // | }); + + node = dom.byId(node); + if(arguments.length == 2){ // inline'd type check + // the object form of setter: the 2nd argument is a dictionary + for(var x in name){ + exports.set(node, x, name[x]); + } + return node; // DomNode + } + var lc = name.toLowerCase(), + propName = prop.names[lc] || name, + forceProp = forcePropNames[propName]; + if(propName == "style" && typeof value != "string"){ // inline'd type check + // special case: setting a style + style.set(node, value); + return node; // DomNode + } + if(forceProp || typeof value == "boolean" || lang.isFunction(value)){ + return prop.set(node, name, value); + } + // node's attribute + node.setAttribute(attrNames[lc] || name, value); + return node; // DomNode + }; + + exports.remove = function removeAttr(/*DOMNode|String*/ node, /*String*/ name){ + // summary: + // Removes an attribute from an HTML element. + // node: DOMNode|String + // id or reference to the element to remove the attribute from + // name: String + // the name of the attribute to remove + + dom.byId(node).removeAttribute(attrNames[name.toLowerCase()] || name); + }; + + exports.getNodeProp = function getNodeProp(/*DomNode|String*/ node, /*String*/ name){ + // summary: + // Returns an effective value of a property or an attribute. + // node: DOMNode|String + // id or reference to the element to remove the attribute from + // name: String + // the name of the attribute + // returns: + // the value of the attribute + + node = dom.byId(node); + var lc = name.toLowerCase(), propName = prop.names[lc] || name; + if((propName in node) && propName != "href"){ + // node's property + return node[propName]; // Anything + } + // node's attribute + var attrName = attrNames[lc] || name; + return _hasAttr(node, attrName) ? node.getAttribute(attrName) : null; // Anything + }; +}); + +}, +'dojo/dom-prop':function(){ +define(["exports", "./_base/kernel", "./sniff", "./_base/lang", "./dom", "./dom-style", "./dom-construct", "./_base/connect"], + function(exports, dojo, has, lang, dom, style, ctr, conn){ + // module: + // dojo/dom-prop + // summary: + // This module defines the core dojo DOM properties API. + + // TODOC: summary not showing up in output, see https://github.com/csnover/js-doc-parse/issues/42 + + // ============================= + // Element properties Functions + // ============================= + + // helper to connect events + var _evtHdlrMap = {}, _ctr = 1, _attrId = dojo._scopeName + "attrid"; + has.add('dom-textContent', function (global, doc, element) { return 'textContent' in element; }); + + exports.names = { + // properties renamed to avoid clashes with reserved words + "class": "className", + "for": "htmlFor", + // properties written as camelCase + tabindex: "tabIndex", + readonly: "readOnly", + colspan: "colSpan", + frameborder: "frameBorder", + rowspan: "rowSpan", + textcontent: "textContent", + valuetype: "valueType" + }; + + function getText(/*DOMNode*/node){ + // summary: + // recursion method for get('textContent') to use. Gets text value for a node. + // description: + // Juse uses nodedValue so things like
tags do not end up in + // the text as any sort of line return. + var text = "", ch = node.childNodes; + for(var i = 0, n; n = ch[i]; i++){ + //Skip comments. + if(n.nodeType != 8){ + if(n.nodeType == 1){ + text += getText(n); + }else{ + text += n.nodeValue; + } + } + } + return text; + } + + exports.get = function getProp(/*DOMNode|String*/ node, /*String*/ name){ + // summary: + // Gets a property on an HTML element. + // description: + // Handles normalized getting of properties on DOM nodes. + // + // node: DOMNode|String + // id or reference to the element to get the property on + // name: String + // the name of the property to get. + // returns: + // the value of the requested property or its default value + // + // example: + // | // get the current value of the "foo" property on a node + // | require(["dojo/dom-prop", "dojo/dom"], function(domProp, dom){ + // | domProp.get(dom.byId("nodeId"), "foo"); + // | // or we can just pass the id: + // | domProp.get("nodeId", "foo"); + // | }); + + node = dom.byId(node); + var lc = name.toLowerCase(), propName = exports.names[lc] || name; + + if(propName == "textContent" && !has("dom-textContent")){ + return getText(node); + } + + return node[propName]; // Anything + }; + + exports.set = function setProp(/*DOMNode|String*/ node, /*String|Object*/ name, /*String?*/ value){ + // summary: + // Sets a property on an HTML element. + // description: + // Handles normalized setting of properties on DOM nodes. + // + // When passing functions as values, note that they will not be + // directly assigned to slots on the node, but rather the default + // behavior will be removed and the new behavior will be added + // using `dojo.connect()`, meaning that event handler properties + // will be normalized and that some caveats with regards to + // non-standard behaviors for onsubmit apply. Namely that you + // should cancel form submission using `dojo.stopEvent()` on the + // passed event object instead of returning a boolean value from + // the handler itself. + // node: DOMNode|String + // id or reference to the element to set the property on + // name: String|Object + // the name of the property to set, or a hash object to set + // multiple properties at once. + // value: String? + // The value to set for the property + // returns: + // the DOM node + // + // example: + // | // use prop() to set the tab index + // | require(["dojo/dom-prop"], function(domProp){ + // | domProp.set("nodeId", "tabIndex", 3); + // | }); + // + // example: + // Set multiple values at once, including event handlers: + // | require(["dojo/dom-prop"], function(domProp){ + // | domProp.set("formId", { + // | "foo": "bar", + // | "tabIndex": -1, + // | "method": "POST", + // | }); + // | }); + + node = dom.byId(node); + var l = arguments.length; + if(l == 2 && typeof name != "string"){ // inline'd type check + // the object form of setter: the 2nd argument is a dictionary + for(var x in name){ + exports.set(node, x, name[x]); + } + return node; // DomNode + } + var lc = name.toLowerCase(), propName = exports.names[lc] || name; + if(propName == "style" && typeof value != "string"){ // inline'd type check + // special case: setting a style + style.set(node, value); + return node; // DomNode + } + if(propName == "innerHTML"){ + // special case: assigning HTML + // the hash lists elements with read-only innerHTML on IE + if(has("ie") && node.tagName.toLowerCase() in {col: 1, colgroup: 1, + table: 1, tbody: 1, tfoot: 1, thead: 1, tr: 1, title: 1}){ + ctr.empty(node); + node.appendChild(ctr.toDom(value, node.ownerDocument)); + }else{ + node[propName] = value; + } + return node; // DomNode + } + if(propName == "textContent" && !has("dom-textContent")) { + ctr.empty(node); + node.appendChild(node.ownerDocument.createTextNode(value)); + return node; + } + if(lang.isFunction(value)){ + // special case: assigning an event handler + // clobber if we can + var attrId = node[_attrId]; + if(!attrId){ + attrId = _ctr++; + node[_attrId] = attrId; + } + if(!_evtHdlrMap[attrId]){ + _evtHdlrMap[attrId] = {}; + } + var h = _evtHdlrMap[attrId][propName]; + if(h){ + //h.remove(); + conn.disconnect(h); + }else{ + try{ + delete node[propName]; + }catch(e){} + } + // ensure that event objects are normalized, etc. + if(value){ + //_evtHdlrMap[attrId][propName] = on(node, propName, value); + _evtHdlrMap[attrId][propName] = conn.connect(node, propName, value); + }else{ + node[propName] = null; + } + return node; // DomNode + } + node[propName] = value; + return node; // DomNode + }; +}); + +}, +'dojo/dom-construct':function(){ +define(["exports", "./_base/kernel", "./sniff", "./_base/window", "./dom", "./dom-attr"], + function(exports, dojo, has, win, dom, attr){ + // module: + // dojo/dom-construct + // summary: + // This module defines the core dojo DOM construction API. + + // TODOC: summary not showing up in output, see https://github.com/csnover/js-doc-parse/issues/42 + + // support stuff for toDom() + var tagWrap = { + option: ["select"], + tbody: ["table"], + thead: ["table"], + tfoot: ["table"], + tr: ["table", "tbody"], + td: ["table", "tbody", "tr"], + th: ["table", "thead", "tr"], + legend: ["fieldset"], + caption: ["table"], + colgroup: ["table"], + col: ["table", "colgroup"], + li: ["ul"] + }, + reTag = /<\s*([\w\:]+)/, + masterNode = {}, masterNum = 0, + masterName = "__" + dojo._scopeName + "ToDomId"; + + // generate start/end tag strings to use + // for the injection for each special tag wrap case. + for(var param in tagWrap){ + if(tagWrap.hasOwnProperty(param)){ + var tw = tagWrap[param]; + tw.pre = param == "option" ? '